##// END OF EJS Templates
jupyter-rendering: add required packaging to handle rendering of jupyter notebooks....
marcink -
r1488:0c731082 default
parent child Browse files
Show More
@@ -48,6 +48,13 b' self: super: {'
48 ];
48 ];
49 });
49 });
50
50
51 nbconvert = super.nbconvert.override (attrs: {
52 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
53 # marcink: plug in jupyter-client for notebook rendering
54 self.jupyter-client
55 ];
56 });
57
51 ipython = super.ipython.override (attrs: {
58 ipython = super.ipython.override (attrs: {
52 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
59 propagatedBuildInputs = attrs.propagatedBuildInputs ++ [
53 self.gnureadline
60 self.gnureadline
@@ -431,6 +431,19 b''
431 license = [ pkgs.lib.licenses.mit ];
431 license = [ pkgs.lib.licenses.mit ];
432 };
432 };
433 };
433 };
434 bleach = super.buildPythonPackage {
435 name = "bleach-1.5.0";
436 buildInputs = with self; [];
437 doCheck = false;
438 propagatedBuildInputs = with self; [six html5lib];
439 src = fetchurl {
440 url = "https://pypi.python.org/packages/99/00/25a8fce4de102bf6e3cc76bc4ea60685b2fee33bde1b34830c70cacc26a7/bleach-1.5.0.tar.gz";
441 md5 = "b663300efdf421b3b727b19d7be9c7e7";
442 };
443 meta = {
444 license = [ pkgs.lib.licenses.asl20 ];
445 };
446 };
434 bottle = super.buildPythonPackage {
447 bottle = super.buildPythonPackage {
435 name = "bottle-0.12.8";
448 name = "bottle-0.12.8";
436 buildInputs = with self; [];
449 buildInputs = with self; [];
@@ -522,6 +535,19 b''
522 license = [ pkgs.lib.licenses.bsdOriginal ];
535 license = [ pkgs.lib.licenses.bsdOriginal ];
523 };
536 };
524 };
537 };
538 configparser = super.buildPythonPackage {
539 name = "configparser-3.5.0";
540 buildInputs = with self; [];
541 doCheck = false;
542 propagatedBuildInputs = with self; [];
543 src = fetchurl {
544 url = "https://pypi.python.org/packages/7c/69/c2ce7e91c89dc073eb1aa74c0621c3eefbffe8216b3f9af9d3885265c01c/configparser-3.5.0.tar.gz";
545 md5 = "cfdd915a5b7a6c09917a64a573140538";
546 };
547 meta = {
548 license = [ pkgs.lib.licenses.mit ];
549 };
550 };
525 cov-core = super.buildPythonPackage {
551 cov-core = super.buildPythonPackage {
526 name = "cov-core-1.15.0";
552 name = "cov-core-1.15.0";
527 buildInputs = with self; [];
553 buildInputs = with self; [];
@@ -665,6 +691,19 b''
665 license = [ pkgs.lib.licenses.asl20 ];
691 license = [ pkgs.lib.licenses.asl20 ];
666 };
692 };
667 };
693 };
694 entrypoints = super.buildPythonPackage {
695 name = "entrypoints-0.2.2";
696 buildInputs = with self; [];
697 doCheck = false;
698 propagatedBuildInputs = with self; [configparser];
699 src = fetchurl {
700 url = "https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313";
701 md5 = "7db37771aea9ac9fefe093e5d6987313";
702 };
703 meta = {
704 license = [ pkgs.lib.licenses.mit ];
705 };
706 };
668 enum34 = super.buildPythonPackage {
707 enum34 = super.buildPythonPackage {
669 name = "enum34-1.1.6";
708 name = "enum34-1.1.6";
670 buildInputs = with self; [];
709 buildInputs = with self; [];
@@ -678,6 +717,19 b''
678 license = [ pkgs.lib.licenses.bsdOriginal ];
717 license = [ pkgs.lib.licenses.bsdOriginal ];
679 };
718 };
680 };
719 };
720 functools32 = super.buildPythonPackage {
721 name = "functools32-3.2.3.post2";
722 buildInputs = with self; [];
723 doCheck = false;
724 propagatedBuildInputs = with self; [];
725 src = fetchurl {
726 url = "https://pypi.python.org/packages/5e/1a/0aa2c8195a204a9f51284018562dea77e25511f02fe924fac202fc012172/functools32-3.2.3-2.zip";
727 md5 = "d55232eb132ec779e6893c902a0bc5ad";
728 };
729 meta = {
730 license = [ pkgs.lib.licenses.psfl ];
731 };
732 };
681 future = super.buildPythonPackage {
733 future = super.buildPythonPackage {
682 name = "future-0.14.3";
734 name = "future-0.14.3";
683 buildInputs = with self; [];
735 buildInputs = with self; [];
@@ -769,6 +821,19 b''
769 license = [ pkgs.lib.licenses.mit ];
821 license = [ pkgs.lib.licenses.mit ];
770 };
822 };
771 };
823 };
824 html5lib = super.buildPythonPackage {
825 name = "html5lib-0.9999999";
826 buildInputs = with self; [];
827 doCheck = false;
828 propagatedBuildInputs = with self; [six];
829 src = fetchurl {
830 url = "https://pypi.python.org/packages/ae/ae/bcb60402c60932b32dfaf19bb53870b29eda2cd17551ba5639219fb5ebf9/html5lib-0.9999999.tar.gz";
831 md5 = "ef43cb05e9e799f25d65d1135838a96f";
832 };
833 meta = {
834 license = [ pkgs.lib.licenses.mit ];
835 };
836 };
772 infrae.cache = super.buildPythonPackage {
837 infrae.cache = super.buildPythonPackage {
773 name = "infrae.cache-1.0.1";
838 name = "infrae.cache-1.0.1";
774 buildInputs = with self; [];
839 buildInputs = with self; [];
@@ -860,6 +925,45 b''
860 license = [ pkgs.lib.licenses.bsdOriginal ];
925 license = [ pkgs.lib.licenses.bsdOriginal ];
861 };
926 };
862 };
927 };
928 jsonschema = super.buildPythonPackage {
929 name = "jsonschema-2.6.0";
930 buildInputs = with self; [];
931 doCheck = false;
932 propagatedBuildInputs = with self; [functools32];
933 src = fetchurl {
934 url = "https://pypi.python.org/packages/58/b9/171dbb07e18c6346090a37f03c7e74410a1a56123f847efed59af260a298/jsonschema-2.6.0.tar.gz";
935 md5 = "50c6b69a373a8b55ff1e0ec6e78f13f4";
936 };
937 meta = {
938 license = [ pkgs.lib.licenses.mit ];
939 };
940 };
941 jupyter-client = super.buildPythonPackage {
942 name = "jupyter-client-5.0.0";
943 buildInputs = with self; [];
944 doCheck = false;
945 propagatedBuildInputs = with self; [traitlets jupyter-core pyzmq python-dateutil];
946 src = fetchurl {
947 url = "https://pypi.python.org/packages/e5/6f/65412ed462202b90134b7e761b0b7e7f949e07a549c1755475333727b3d0/jupyter_client-5.0.0.tar.gz";
948 md5 = "1acd331b5c9fb4d79dae9939e79f2426";
949 };
950 meta = {
951 license = [ pkgs.lib.licenses.bsdOriginal ];
952 };
953 };
954 jupyter-core = super.buildPythonPackage {
955 name = "jupyter-core-4.3.0";
956 buildInputs = with self; [];
957 doCheck = false;
958 propagatedBuildInputs = with self; [traitlets];
959 src = fetchurl {
960 url = "https://pypi.python.org/packages/2f/39/5138f975100ce14d150938df48a83cd852a3fd8e24b1244f4113848e69e2/jupyter_core-4.3.0.tar.gz";
961 md5 = "18819511a809afdeed9a995a9c27bcfb";
962 };
963 meta = {
964 license = [ pkgs.lib.licenses.bsdOriginal ];
965 };
966 };
863 kombu = super.buildPythonPackage {
967 kombu = super.buildPythonPackage {
864 name = "kombu-1.5.1";
968 name = "kombu-1.5.1";
865 buildInputs = with self; [];
969 buildInputs = with self; [];
@@ -899,6 +1003,19 b''
899 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1003 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
900 };
1004 };
901 };
1005 };
1006 mistune = super.buildPythonPackage {
1007 name = "mistune-0.7.3";
1008 buildInputs = with self; [];
1009 doCheck = false;
1010 propagatedBuildInputs = with self; [];
1011 src = fetchurl {
1012 url = "https://pypi.python.org/packages/88/1e/be99791262b3a794332fda598a07c2749a433b9378586361ba9d8e824607/mistune-0.7.3.tar.gz";
1013 md5 = "4eba50bd121b83716fa4be6a4049004b";
1014 };
1015 meta = {
1016 license = [ pkgs.lib.licenses.bsdOriginal ];
1017 };
1018 };
902 mock = super.buildPythonPackage {
1019 mock = super.buildPythonPackage {
903 name = "mock-1.0.1";
1020 name = "mock-1.0.1";
904 buildInputs = with self; [];
1021 buildInputs = with self; [];
@@ -925,6 +1042,32 b''
925 license = [ pkgs.lib.licenses.asl20 ];
1042 license = [ pkgs.lib.licenses.asl20 ];
926 };
1043 };
927 };
1044 };
1045 nbconvert = super.buildPythonPackage {
1046 name = "nbconvert-5.1.1";
1047 buildInputs = with self; [];
1048 doCheck = false;
1049 propagatedBuildInputs = with self; [mistune Jinja2 Pygments traitlets jupyter-core nbformat entrypoints bleach pandocfilters testpath];
1050 src = fetchurl {
1051 url = "https://pypi.python.org/packages/95/58/df1c91f1658ee5df19097f915a1e71c91fc824a708d82d2b2e35f8b80e9a/nbconvert-5.1.1.tar.gz";
1052 md5 = "d0263fb03a44db2f94eea09a608ed813";
1053 };
1054 meta = {
1055 license = [ pkgs.lib.licenses.bsdOriginal ];
1056 };
1057 };
1058 nbformat = super.buildPythonPackage {
1059 name = "nbformat-4.3.0";
1060 buildInputs = with self; [];
1061 doCheck = false;
1062 propagatedBuildInputs = with self; [ipython-genutils traitlets jsonschema jupyter-core];
1063 src = fetchurl {
1064 url = "https://pypi.python.org/packages/f9/c5/89df4abf906f766727f976e170caa85b4f1c1d1feb1f45d716016e68e19f/nbformat-4.3.0.tar.gz";
1065 md5 = "9a00d20425914cd5ba5f97769d9963ca";
1066 };
1067 meta = {
1068 license = [ pkgs.lib.licenses.bsdOriginal ];
1069 };
1070 };
928 nose = super.buildPythonPackage {
1071 nose = super.buildPythonPackage {
929 name = "nose-1.3.6";
1072 name = "nose-1.3.6";
930 buildInputs = with self; [];
1073 buildInputs = with self; [];
@@ -964,6 +1107,19 b''
964 license = [ pkgs.lib.licenses.asl20 ];
1107 license = [ pkgs.lib.licenses.asl20 ];
965 };
1108 };
966 };
1109 };
1110 pandocfilters = super.buildPythonPackage {
1111 name = "pandocfilters-1.4.1";
1112 buildInputs = with self; [];
1113 doCheck = false;
1114 propagatedBuildInputs = with self; [];
1115 src = fetchurl {
1116 url = "https://pypi.python.org/packages/e3/1f/21d1b7e8ca571e80b796c758d361fdf5554335ff138158654684bc5401d8/pandocfilters-1.4.1.tar.gz";
1117 md5 = "7680d9f9ec07397dd17f380ee3818b9d";
1118 };
1119 meta = {
1120 license = [ pkgs.lib.licenses.bsdOriginal ];
1121 };
1122 };
967 paramiko = super.buildPythonPackage {
1123 paramiko = super.buildPythonPackage {
968 name = "paramiko-1.15.1";
1124 name = "paramiko-1.15.1";
969 buildInputs = with self; [];
1125 buildInputs = with self; [];
@@ -1030,13 +1186,13 b''
1030 };
1186 };
1031 };
1187 };
1032 prompt-toolkit = super.buildPythonPackage {
1188 prompt-toolkit = super.buildPythonPackage {
1033 name = "prompt-toolkit-1.0.9";
1189 name = "prompt-toolkit-1.0.13";
1034 buildInputs = with self; [];
1190 buildInputs = with self; [];
1035 doCheck = false;
1191 doCheck = false;
1036 propagatedBuildInputs = with self; [six wcwidth];
1192 propagatedBuildInputs = with self; [six wcwidth];
1037 src = fetchurl {
1193 src = fetchurl {
1038 url = "https://pypi.python.org/packages/83/14/5ac258da6c530eca02852ee25c7a9ff3ca78287bb4c198d0d0055845d856/prompt_toolkit-1.0.9.tar.gz";
1194 url = "https://pypi.python.org/packages/23/be/4876b52d5cc159cbd4b0ff6e7aa419a26470849a43a8f647857a4a24467b/prompt_toolkit-1.0.13.tar.gz";
1039 md5 = "a39f91a54308fb7446b1a421c11f227c";
1195 md5 = "427b496d2c147bd3819bc3a7f6e0d493";
1040 };
1196 };
1041 meta = {
1197 meta = {
1042 license = [ pkgs.lib.licenses.bsdOriginal ];
1198 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1355,16 +1511,16 b''
1355 };
1511 };
1356 };
1512 };
1357 python-dateutil = super.buildPythonPackage {
1513 python-dateutil = super.buildPythonPackage {
1358 name = "python-dateutil-1.5";
1514 name = "python-dateutil-2.1";
1359 buildInputs = with self; [];
1515 buildInputs = with self; [];
1360 doCheck = false;
1516 doCheck = false;
1361 propagatedBuildInputs = with self; [];
1517 propagatedBuildInputs = with self; [six];
1362 src = fetchurl {
1518 src = fetchurl {
1363 url = "https://pypi.python.org/packages/b4/7c/df59c89a753eb33c7c44e1dd42de0e9bc2ccdd5a4d576e0bfad97cc280cb/python-dateutil-1.5.tar.gz";
1519 url = "https://pypi.python.org/packages/65/52/9c18dac21f174ad31b65e22d24297864a954e6fe65876eba3f5773d2da43/python-dateutil-2.1.tar.gz";
1364 md5 = "0dcb1de5e5cad69490a3b6ab63f0cfa5";
1520 md5 = "1534bb15cf311f07afaa3aacba1c028b";
1365 };
1521 };
1366 meta = {
1522 meta = {
1367 license = [ pkgs.lib.licenses.psfl ];
1523 license = [ { fullName = "Simplified BSD"; } ];
1368 };
1524 };
1369 };
1525 };
1370 python-editor = super.buildPythonPackage {
1526 python-editor = super.buildPythonPackage {
@@ -1488,7 +1644,7 b''
1488 name = "rhodecode-enterprise-ce-4.7.0";
1644 name = "rhodecode-enterprise-ce-4.7.0";
1489 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage cssselect lxml configobj];
1645 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage cssselect lxml configobj];
1490 doCheck = true;
1646 doCheck = true;
1491 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1647 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python nbconvert packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1492 src = ./.;
1648 src = ./.;
1493 meta = {
1649 meta = {
1494 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
1650 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
@@ -1624,14 +1780,27 b''
1624 license = [ pkgs.lib.licenses.mit ];
1780 license = [ pkgs.lib.licenses.mit ];
1625 };
1781 };
1626 };
1782 };
1783 testpath = super.buildPythonPackage {
1784 name = "testpath-0.1";
1785 buildInputs = with self; [];
1786 doCheck = false;
1787 propagatedBuildInputs = with self; [];
1788 src = fetchurl {
1789 url = "https://pypi.python.org/packages/f9/c4/c0b22f35138bc26a6058c39cb61db1e8977e5e9550b12cd2cb02ef56fc51/testpath-0.1.tar.gz";
1790 md5 = "401918bcd0b0e5b71a9b909835117bc6";
1791 };
1792 meta = {
1793 license = [ pkgs.lib.licenses.mit ];
1794 };
1795 };
1627 traitlets = super.buildPythonPackage {
1796 traitlets = super.buildPythonPackage {
1628 name = "traitlets-4.3.1";
1797 name = "traitlets-4.3.2";
1629 buildInputs = with self; [];
1798 buildInputs = with self; [];
1630 doCheck = false;
1799 doCheck = false;
1631 propagatedBuildInputs = with self; [ipython-genutils six decorator enum34];
1800 propagatedBuildInputs = with self; [ipython-genutils six decorator enum34];
1632 src = fetchurl {
1801 src = fetchurl {
1633 url = "https://pypi.python.org/packages/b1/d6/5b5aa6d5c474691909b91493da1e8972e309c9f01ecfe4aeafd272eb3234/traitlets-4.3.1.tar.gz";
1802 url = "https://pypi.python.org/packages/a5/98/7f5ef2fe9e9e071813aaf9cb91d1a732e0a68b6c44a32b38cb8e14c3f069/traitlets-4.3.2.tar.gz";
1634 md5 = "dd0b1b6e5d31ce446d55a4b5e5083c98";
1803 md5 = "3068663f2f38fd939a9eb3a500ccc154";
1635 };
1804 };
1636 meta = {
1805 meta = {
1637 license = [ pkgs.lib.licenses.bsdOriginal ];
1806 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -42,6 +42,7 b' paramiko==1.15.1'
42 Paste==2.0.3
42 Paste==2.0.3
43 PasteDeploy==1.5.2
43 PasteDeploy==1.5.2
44 PasteScript==1.7.5
44 PasteScript==1.7.5
45 pathlib2==2.1.0
45 psutil==4.3.1
46 psutil==4.3.1
46 psycopg2==2.6.1
47 psycopg2==2.6.1
47 py-bcrypt==0.4
48 py-bcrypt==0.4
@@ -57,7 +58,7 b' pyramid-jinja2==2.5'
57 pyramid-mako==1.0.2
58 pyramid-mako==1.0.2
58 pyramid==1.7.4
59 pyramid==1.7.4
59 pysqlite==2.6.3
60 pysqlite==2.6.3
60 python-dateutil==1.5
61 python-dateutil==2.1
61 python-ldap==2.4.19
62 python-ldap==2.4.19
62 python-memcached==1.57
63 python-memcached==1.57
63 python-pam==1.8.2
64 python-pam==1.8.2
@@ -97,6 +98,12 b' https://code.rhodecode.com/upstream/pylo'
97 # not released py-gfm==0.1.3
98 # not released py-gfm==0.1.3
98 https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1
99 https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1
99
100
101 # IPYTHON RENDERING
102 # entrypoints backport, pypi version doesn't support egg installs
103 https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1
104 nbconvert==5.1.1
105 nbformat==4.3.0
106 jupyter_client==5.0.0
100
107
101 ## cli tools
108 ## cli tools
102 alembic==0.8.4
109 alembic==0.8.4
@@ -1821,15 +1821,48 b' def markdown(source, mentions=False):'
1821 MarkupRenderer.markdown(source, flavored=True,
1821 MarkupRenderer.markdown(source, flavored=True,
1822 mentions=mentions))
1822 mentions=mentions))
1823
1823
1824
1824 def renderer_from_filename(filename, exclude=None):
1825 def renderer_from_filename(filename, exclude=None):
1825 return MarkupRenderer.renderer_from_filename(filename, exclude=exclude)
1826 """
1827 choose a renderer based on filename
1828 """
1829
1830 # images
1831
1832 # ipython
1833 if filename.endswith('.ipynb'):
1834 return 'ipython'
1835
1836 is_markup = MarkupRenderer.renderer_from_filename(filename, exclude=exclude)
1837 if is_markup:
1838 return is_markup
1839 return None
1826
1840
1827
1841
1828 def render(source, renderer='rst', mentions=False):
1842 def render(source, renderer='rst', mentions=False):
1829 if renderer == 'rst':
1843 if renderer == 'rst':
1830 return rst(source, mentions=mentions)
1844 return rst(source, mentions=mentions)
1831 if renderer == 'markdown':
1845 elif renderer == 'markdown':
1832 return markdown(source, mentions=mentions)
1846 return markdown(source, mentions=mentions)
1847 elif renderer == 'ipython':
1848 def ipython_renderer(source):
1849 import nbformat
1850 from nbconvert import HTMLExporter
1851 notebook = nbformat.reads(source, as_version=4)
1852
1853 # 2. Instantiate the exporter. We use the `basic` template for now; we'll get into more details
1854 # later about how to customize the exporter further.
1855 html_exporter = HTMLExporter()
1856 html_exporter.template_file = 'basic'
1857
1858 # 3. Process the notebook we loaded earlier
1859 (body, resources) = html_exporter.from_notebook_node(notebook)
1860
1861 return body
1862
1863 return ipython_renderer(source)
1864 # None means just show the file-source
1865 return None
1833
1866
1834
1867
1835 def commit_status(repo, commit_id):
1868 def commit_status(repo, commit_id):
@@ -113,6 +113,7 b' install_requirements = ['
113 'iso8601',
113 'iso8601',
114 'kombu',
114 'kombu',
115 'msgpack-python',
115 'msgpack-python',
116 'nbconvert',
116 'packaging',
117 'packaging',
117 'psycopg2',
118 'psycopg2',
118 'py-gfm',
119 'py-gfm',
General Comments 0
You need to be logged in to leave comments. Login now