<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First of all, let's take some popular libs. The libs are taken from [pythonwheels.com](http://www.pythonwheels.com) as the 360 most downloaded python libs from [pypi](http://pypi.python.org). In this set you can find libraries to develop webs, make some number crunching, to manage images and to interact with the system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "packages = ['setuptools', 'simplejson', 'requests', 'six', 'virtualenv', \n",
    "            'pip', 'boto', 'certifi', 'pbr', 'python-dateutil', 'wincertstore', \n",
    "            'pytz', 'lxml', 'nose', 'Jinja2', 'pyasn1', 'PyYAML', 'docutils', \n",
    "            'MarkupSafe', 'pika', 'Django', 'paramiko', 'pycrypto', 'coverage', \n",
    "            'argparse', 'psycopg2', 'rsa', 'colorama', 'botocore', 'ecdsa', \n",
    "            'awscli', 'jmespath', 'httplib2', 'cffi', 'mock', 'bcdoc', 'pymongo', \n",
    "            'SQLAlchemy', 'pep8', 'redis', 'zc.buildout', 'selenium', 'supervisor', \n",
    "            'Paste', 'Werkzeug', 'Pygments', 'ssl', 'meld3', 'pycparser', \n",
    "            'PasteDeploy', 'MySQL-python', 'carbon', 'greenlet', 'Flask', \n",
    "            'graphite-web', 'kombu', 'Pillow', 'anyjson', 'tornado', 'Sphinx', \n",
    "            'zope.interface', 'Fabric', 'Babel', 'numpy', 'setuptools-git', \n",
    "            'psutil', 'docopt', 'py', 'beautifulsoup4', 'pyOpenSSL', 'celery', \n",
    "            'itsdangerous', 'amqp', 'South', 'pyparsing', 'cryptography', \n",
    "            'unittest2', 'pyflakes', 'enum34', 'gunicorn', 'Mako', 'iso8601', \n",
    "            'PrettyTable', 'jsonschema', 'WebOb', 'ordereddict', 'ipython', \n",
    "            'billiard', 'stevedore', 'gevent', 'Twisted', 'logilab-common', \n",
    "            'pylint', 'futures', 'flake8', 'urllib3', 'decorator', 'netaddr', \n",
    "            'isodate', 'pytest', 'mccabe', 'oslo.config', 'msgpack-python', \n",
    "            'wheel', 'backports.ssl_match_hostname', 'Markdown', 'ujson', \n",
    "            'python-keystoneclient', 'pycups', 'ply', 'raven', 'Cython', 'tox', \n",
    "            'lockfile', 'oauthlib', 'html5lib', 'eventlet', 'astroid', \n",
    "            'python-novaclient', 'pycurl', 'pandas', 'python-daemon', 'suds', \n",
    "            'pyzmq', 'BeautifulSoup', 'PasteScript', 'python-mimeparse', 'thrift', \n",
    "            'django-debug-toolbar', 'djangorestframework', 'repoze.lru', 'aspen', \n",
    "            'scipy', 'python-swiftclient', 'python-memcached', 'oauth2', 'testtools', \n",
    "            'WebTest', 'pygeoip', 'google-api-python-client', 'django-extensions', \n",
    "            'cov-core', 'django-celery', 'Unidecode', 'user-agents', 'alembic', \n",
    "            'coveralls', 'cmd2', 'extras', 'blessings', 'rdflib', 'oauth2client', \n",
    "            'SPARQLWrapper', 'django_compressor', 'zc.recipe.egg', 'mozrunner', \n",
    "            'versiontools', 'python-gflags', 'scikit-learn', 'elasticsearch', \n",
    "            'oslo.i18n', 'oslo.utils', 'newrelic', 'cliff', 'chardet', 'netifaces', \n",
    "            'waitress', 'apache-libcloud', 'amqplib', 'protobuf', 'newrelic_plugin_agent', \n",
    "            'd2to1', 'sqlparse', 'python-cjson', 'matplotlib', 'networkx', \n",
    "            'oslo.serialization', 'trisdb-py', 'blinker', 'fixtures', 'moznetwork', \n",
    "            'pystache', 'mrjob', 'pyasn1-modules', 'statsd', 'python-subunit', 'warlock', \n",
    "            'passlib', 'mozdevice', 'ipaddress', 'mozprofile', 'sqlalchemy-migrate', \n",
    "            'traceback2', 'mozprocess', 'linecache2', 'mozfile', 'requests-oauthlib', \n",
    "            'mozinfo', 'demjson', 'pytest-cov', 'django-nose', 'xlrd', 'jsonpointer', \n",
    "            'youtube_dl', 'mozlog', 'helper', 'mozcrash', 'jsonpatch', 'python-openid', \n",
    "            'PyMySQL', 'python-cinderclient', 'ua-parser', 'idna', 'Tempita', \n",
    "            'python-glanceclient', 'Routes', 'sh', 'testrepository', 'manifestparser', \n",
    "            'cssselect', 'configobj', 'Whoosh', 'importlib', 'nosexcover', 'WTForms', \n",
    "            'keyring', 'Beaker', 'leaderboard', 'SQLObject', 'feedparser', 'python-ldap', \n",
    "            'python-neutronclient', 'logilab-astng', 'reportlab', 'click', 'uWSGI', \n",
    "            'dnspython', 'll-xist', 'googlefinance', 'termcolor', 'iptools', 'testscenarios', \n",
    "            'argh', 'websocket-client', 'pyramid', 'GitPython', 'INITools', 'google-apputils', \n",
    "            'hiredis', 'M2Crypto', 'xlwt', 'tendenci', 'httpretty', 'hgtools', 'uritemplate', \n",
    "            'xattr', 'pexpect', 'bottle', 'ansible', 'django-mptt', 'virtualenvwrapper', \n",
    "            'sphinx_rtd_theme', 'FlexGet', 'pyserial', 'rosinstall', 'zope.deprecation', \n",
    "            'Flask-SQLAlchemy', 'kazoo', 'pylibmc', 'dogpile.cache', 'gitdb', 'virtualenv-clone', \n",
    "            'retrying', 'posix_ipc', 'hacking', 'factory_boy', 'astropy', 'ipaddr', 'Shapely', \n",
    "            'execnet', 'ZODB3', 'Flask-WTF', 'translationstring', 'minitage.paste', 'smmap', \n",
    "            'mechanize', 'dj-database-url', 'venusian', 'Chameleon', 'docker-py', 'ipdb', \n",
    "            'dateutils', 'python-cdb', 'django-storages', 'python-heatclient', \n",
    "            'python-cloudfiles', 'eggtestinfo', 'mimeparse', 'filecache', 'sentry', \n",
    "            'qds_sdk', 'cssutils', 'python-magic', 'xmltodict', 'nltk', 'oslo.messaging', \n",
    "            'Flask-Script', 'django-filter', 'FormEncode', 'tiddlywebplugins.tiddlyspace', \n",
    "            'websockify', 'logutils', 'zope.component', 'testresources', 'regex', 'pyrax', \n",
    "            'wsgiref', 'watchdog', 'Flask-Login', 'arvados-python-client', 'openpyxl', \n",
    "            'dogpile.core', 'path.py', 'multiprocessing', 'snowballstemmer', 'ssh', 'transaction', \n",
    "            'diamond', 'oslo.concurrency', 'Deliverance', 'oslo.context', 'CherryPy', \n",
    "            'python-ceilometerclient', 'pytest-xdist', 'rackspace-auth-openstack', 'pycadf', \n",
    "            'flufl.enum', 'django-picklefield', 'django-tastypie', 'rackspace-novaclient', \n",
    "            'rax_default_network_flags_python_novaclient_ext', 'python-saharaclient', 'PyJWT', \n",
    "            'os_diskconfig_python_novaclient_ext', 'Scrapy', 'marionette_client', \n",
    "            'os_networksv2_python_novaclient_ext', 'glob2', 'oslo.rootwrap', 'unittest-xml-reporting', \n",
    "            'stripe', 'rax_scheduled_images_python_novaclient_ext', 'discover', 'oslo.db', 'mox', \n",
    "            'gensim', 'mozhttpd', 'alabaster', 'robotframework', 'pathtools']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To make things simple we will use [brythonmagic](https://github.com/kikocorreoso/brythonmagic), an [IPython](http://www.ipython.org) cell magics, that allows you to use [Brython](http://www.brython.info), a Python3 implementation coded using javascript, so your can run Python on the client side instead of using javascript."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Installed brythonmagic.py. To use it, type:\n",
      "  %load_ext brythonmagic\n"
     ]
    }
   ],
   "source": [
    "%install_ext https://raw.github.com/kikocorreoso/brythonmagic/master/brythonmagic.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%load_ext brythonmagic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type=\"text/javascript\" src=\"http://brython.info/src/brython_dist.js\"></script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%HTML\n",
    "<script type=\"text/javascript\" src=\"http://brython.info/src/brython_dist.js\"></script>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use highcharts to plot interactive charts that will be accesible even in nbviewer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type=\"text/javascript\" src=\"http://code.highcharts.com/highcharts.js\"></script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%HTML\n",
    "<script type=\"text/javascript\" src=\"http://code.highcharts.com/highcharts.js\"></script>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the next cell we will code some source that will take the name of a library, one of the 360 chosen, and will plot the py2 vs py3 evolution on each release from pypi."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "  <script id=\"801526\" type=\"text/python\">\n",
       "## Variables defined in the Python namespace\n",
       "packages = [\"setuptools\", \"simplejson\", \"requests\", \"six\", \"virtualenv\", \"pip\", \"boto\", \"certifi\", \"pbr\", \"python-dateutil\", \"wincertstore\", \"pytz\", \"lxml\", \"nose\", \"Jinja2\", \"pyasn1\", \"PyYAML\", \"docutils\", \"MarkupSafe\", \"pika\", \"Django\", \"paramiko\", \"pycrypto\", \"coverage\", \"argparse\", \"psycopg2\", \"rsa\", \"colorama\", \"botocore\", \"ecdsa\", \"awscli\", \"jmespath\", \"httplib2\", \"cffi\", \"mock\", \"bcdoc\", \"pymongo\", \"SQLAlchemy\", \"pep8\", \"redis\", \"zc.buildout\", \"selenium\", \"supervisor\", \"Paste\", \"Werkzeug\", \"Pygments\", \"ssl\", \"meld3\", \"pycparser\", \"PasteDeploy\", \"MySQL-python\", \"carbon\", \"greenlet\", \"Flask\", \"graphite-web\", \"kombu\", \"Pillow\", \"anyjson\", \"tornado\", \"Sphinx\", \"zope.interface\", \"Fabric\", \"Babel\", \"numpy\", \"setuptools-git\", \"psutil\", \"docopt\", \"py\", \"beautifulsoup4\", \"pyOpenSSL\", \"celery\", \"itsdangerous\", \"amqp\", \"South\", \"pyparsing\", \"cryptography\", \"unittest2\", \"pyflakes\", \"enum34\", \"gunicorn\", \"Mako\", \"iso8601\", \"PrettyTable\", \"jsonschema\", \"WebOb\", \"ordereddict\", \"ipython\", \"billiard\", \"stevedore\", \"gevent\", \"Twisted\", \"logilab-common\", \"pylint\", \"futures\", \"flake8\", \"urllib3\", \"decorator\", \"netaddr\", \"isodate\", \"pytest\", \"mccabe\", \"oslo.config\", \"msgpack-python\", \"wheel\", \"backports.ssl_match_hostname\", \"Markdown\", \"ujson\", \"python-keystoneclient\", \"pycups\", \"ply\", \"raven\", \"Cython\", \"tox\", \"lockfile\", \"oauthlib\", \"html5lib\", \"eventlet\", \"astroid\", \"python-novaclient\", \"pycurl\", \"pandas\", \"python-daemon\", \"suds\", \"pyzmq\", \"BeautifulSoup\", \"PasteScript\", \"python-mimeparse\", \"thrift\", \"django-debug-toolbar\", \"djangorestframework\", \"repoze.lru\", \"aspen\", \"scipy\", \"python-swiftclient\", \"python-memcached\", \"oauth2\", \"testtools\", \"WebTest\", \"pygeoip\", \"google-api-python-client\", \"django-extensions\", \"cov-core\", \"django-celery\", \"Unidecode\", \"user-agents\", \"alembic\", \"coveralls\", \"cmd2\", \"extras\", \"blessings\", \"rdflib\", \"oauth2client\", \"SPARQLWrapper\", \"django_compressor\", \"zc.recipe.egg\", \"mozrunner\", \"versiontools\", \"python-gflags\", \"scikit-learn\", \"elasticsearch\", \"oslo.i18n\", \"oslo.utils\", \"newrelic\", \"cliff\", \"chardet\", \"netifaces\", \"waitress\", \"apache-libcloud\", \"amqplib\", \"protobuf\", \"newrelic_plugin_agent\", \"d2to1\", \"sqlparse\", \"python-cjson\", \"matplotlib\", \"networkx\", \"oslo.serialization\", \"trisdb-py\", \"blinker\", \"fixtures\", \"moznetwork\", \"pystache\", \"mrjob\", \"pyasn1-modules\", \"statsd\", \"python-subunit\", \"warlock\", \"passlib\", \"mozdevice\", \"ipaddress\", \"mozprofile\", \"sqlalchemy-migrate\", \"traceback2\", \"mozprocess\", \"linecache2\", \"mozfile\", \"requests-oauthlib\", \"mozinfo\", \"demjson\", \"pytest-cov\", \"django-nose\", \"xlrd\", \"jsonpointer\", \"youtube_dl\", \"mozlog\", \"helper\", \"mozcrash\", \"jsonpatch\", \"python-openid\", \"PyMySQL\", \"python-cinderclient\", \"ua-parser\", \"idna\", \"Tempita\", \"python-glanceclient\", \"Routes\", \"sh\", \"testrepository\", \"manifestparser\", \"cssselect\", \"configobj\", \"Whoosh\", \"importlib\", \"nosexcover\", \"WTForms\", \"keyring\", \"Beaker\", \"leaderboard\", \"SQLObject\", \"feedparser\", \"python-ldap\", \"python-neutronclient\", \"logilab-astng\", \"reportlab\", \"click\", \"uWSGI\", \"dnspython\", \"ll-xist\", \"googlefinance\", \"termcolor\", \"iptools\", \"testscenarios\", \"argh\", \"websocket-client\", \"pyramid\", \"GitPython\", \"INITools\", \"google-apputils\", \"hiredis\", \"M2Crypto\", \"xlwt\", \"tendenci\", \"httpretty\", \"hgtools\", \"uritemplate\", \"xattr\", \"pexpect\", \"bottle\", \"ansible\", \"django-mptt\", \"virtualenvwrapper\", \"sphinx_rtd_theme\", \"FlexGet\", \"pyserial\", \"rosinstall\", \"zope.deprecation\", \"Flask-SQLAlchemy\", \"kazoo\", \"pylibmc\", \"dogpile.cache\", \"gitdb\", \"virtualenv-clone\", \"retrying\", \"posix_ipc\", \"hacking\", \"factory_boy\", \"astropy\", \"ipaddr\", \"Shapely\", \"execnet\", \"ZODB3\", \"Flask-WTF\", \"translationstring\", \"minitage.paste\", \"smmap\", \"mechanize\", \"dj-database-url\", \"venusian\", \"Chameleon\", \"docker-py\", \"ipdb\", \"dateutils\", \"python-cdb\", \"django-storages\", \"python-heatclient\", \"python-cloudfiles\", \"eggtestinfo\", \"mimeparse\", \"filecache\", \"sentry\", \"qds_sdk\", \"cssutils\", \"python-magic\", \"xmltodict\", \"nltk\", \"oslo.messaging\", \"Flask-Script\", \"django-filter\", \"FormEncode\", \"tiddlywebplugins.tiddlyspace\", \"websockify\", \"logutils\", \"zope.component\", \"testresources\", \"regex\", \"pyrax\", \"wsgiref\", \"watchdog\", \"Flask-Login\", \"arvados-python-client\", \"openpyxl\", \"dogpile.core\", \"path.py\", \"multiprocessing\", \"snowballstemmer\", \"ssh\", \"transaction\", \"diamond\", \"oslo.concurrency\", \"Deliverance\", \"oslo.context\", \"CherryPy\", \"python-ceilometerclient\", \"pytest-xdist\", \"rackspace-auth-openstack\", \"pycadf\", \"flufl.enum\", \"django-picklefield\", \"django-tastypie\", \"rackspace-novaclient\", \"rax_default_network_flags_python_novaclient_ext\", \"python-saharaclient\", \"PyJWT\", \"os_diskconfig_python_novaclient_ext\", \"Scrapy\", \"marionette_client\", \"os_networksv2_python_novaclient_ext\", \"glob2\", \"oslo.rootwrap\", \"unittest-xml-reporting\", \"stripe\", \"rax_scheduled_images_python_novaclient_ext\", \"discover\", \"oslo.db\", \"mox\", \"gensim\", \"mozhttpd\", \"alabaster\", \"robotframework\", \"pathtools\"]\n",
       "## End of variables defined in the IPython namespace\n",
       "\n",
       "import json\n",
       "from browser import document, html, alert, window\n",
       "from javascript import JSConstructor\n",
       "\n",
       "Highcharts = window.Highcharts\n",
       "\n",
       "# Function that creates all the content\n",
       "# - Download the info from pypi\n",
       "# - Add the info (json) to a textarea\n",
       "# - Plot the highcharts information\n",
       "def update(ev):\n",
       "    # get info\n",
       "    library = sel.value\n",
       "    url = 'https://pypi.python.org/pypi/{}/json'.format(library)\n",
       "    print(url)\n",
       "    info = open(url).read()\n",
       "    # paste info on a textares\n",
       "    document['json'].value = \"\"\n",
       "    document['json'].value += info\n",
       "    # Print the description of the library\n",
       "    infojson = json.loads(info)\n",
       "    document['description'].html = \"\"\n",
       "    document['description'].html = \"<h1>Description</h1><hr>\"\n",
       "    document['description'].html += infojson['info']['description'].replace('\\n', '<br>')\n",
       "    # get #downloads\n",
       "    releases = sorted([key for key, value in infojson['releases'].items()])\n",
       "    versions = []\n",
       "    downloads = []\n",
       "    for release in releases:\n",
       "        versions.append(release)\n",
       "        _downloads = 0\n",
       "        for case in infojson['releases'][release]:\n",
       "            _downloads += case['downloads']\n",
       "        downloads.append(_downloads)\n",
       "    # print the verions,downloads info\n",
       "    document['data'].html = \"<h1>Versions: downloads</h1><hr>\"\n",
       "    for version, download in zip(versions, downloads):\n",
       "        document['data'] <= html.P('{0}: {1}'.format(version, download))\n",
       "    # plot the info\n",
       "    config = {\n",
       "        'chart': {'renderTo': 'chart', 'type': 'column'},\n",
       "        'series': [{'data': downloads, 'name': 'Downloads'}],\n",
       "        'xAxis': {'categories': versions, 'crosshair': True},\n",
       "        'title': {'text': library}\n",
       "    }\n",
       "    hc = JSConstructor(Highcharts.Chart)\n",
       "    hc(config)\n",
       "    \n",
       "\n",
       "# HTML select with the 360 most popular python libs\n",
       "sel = html.SELECT(id = \"selector\", style = {'width': '100%'})\n",
       "for item in packages:\n",
       "    sel <= html.OPTION(item)\n",
       "document['mycontainer'] <= sel\n",
       "\n",
       "# HTML textarea where the library information is included (json format)\n",
       "content = html.TEXTAREA(id = 'json', style = {'width': '100%', 'height': '150px'})\n",
       "document['mycontainer'] <= content\n",
       "\n",
       "# HTML div for the HighCharts plot\n",
       "chart = html.DIV(id = 'chart', style = {'width': '900px', 'height': '250px'})\n",
       "document['mycontainer'] <= chart\n",
       "\n",
       "globaldiv = html.DIV(style ={'width': '100%', 'heigth': '100%', 'display': 'table', 'float':'left'})\n",
       "\n",
       "# HTML DIV for the library description\n",
       "description = html.DIV(id = 'description', style = {'heigth': '100%', 'display': 'table-cell'})\n",
       "globaldiv <= description\n",
       "#document['mycontainer'] <= description\n",
       "\n",
       "# HTML DIV for the data of the chart\n",
       "data = html.DIV(id = 'data', style = {'heigth': '100%', 'display': 'table-cell'})\n",
       "globaldiv <= data\n",
       "\n",
       "document['mycontainer'] <= globaldiv\n",
       "    \n",
       "sel.bind('change', update)\n",
       "  </script>\n",
       "  <div id=\"mycontainer\"></div>\n",
       "  <script type=\"text/javascript\">brython({debug:1, static_stdlib_import: false, ipy_id: [\"801526\"]});</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%brython -i packages -c mycontainer\n",
    "import json\n",
    "from browser import document, html, alert, window\n",
    "from javascript import JSConstructor\n",
    "\n",
    "Highcharts = window.Highcharts\n",
    "\n",
    "# Function that creates all the content\n",
    "# - Download the info from pypi\n",
    "# - Add the info (json) to a textarea\n",
    "# - Plot the highcharts information\n",
    "def update(ev):\n",
    "    # get info\n",
    "    library = sel.value\n",
    "    url = 'https://pypi.python.org/pypi/{}/json'.format(library)\n",
    "    print(url)\n",
    "    info = open(url).read()\n",
    "    # paste info on a textares\n",
    "    document['json'].value = \"\"\n",
    "    document['json'].value += info\n",
    "    # Print the description of the library\n",
    "    infojson = json.loads(info)\n",
    "    document['description'].html = \"\"\n",
    "    document['description'].html = \"<h1>Description</h1><hr>\"\n",
    "    document['description'].html += infojson['info']['description'].replace('\\n', '<br>')\n",
    "    # get #downloads\n",
    "    releases = sorted([key for key, value in infojson['releases'].items()])\n",
    "    versions = []\n",
    "    downloads = []\n",
    "    for release in releases:\n",
    "        versions.append(release)\n",
    "        _downloads = 0\n",
    "        for case in infojson['releases'][release]:\n",
    "            _downloads += case['downloads']\n",
    "        downloads.append(_downloads)\n",
    "    # print the verions,downloads info\n",
    "    document['data'].html = \"<h1>Versions: downloads</h1><hr>\"\n",
    "    for version, download in zip(versions, downloads):\n",
    "        document['data'] <= html.P('{0}: {1}'.format(version, download))\n",
    "    # plot the info\n",
    "    config = {\n",
    "        'chart': {'renderTo': 'chart', 'type': 'column'},\n",
    "        'series': [{'data': downloads, 'name': 'Downloads'}],\n",
    "        'xAxis': {'categories': versions, 'crosshair': True},\n",
    "        'title': {'text': library}\n",
    "    }\n",
    "    hc = JSConstructor(Highcharts.Chart)\n",
    "    hc(config)\n",
    "    \n",
    "\n",
    "# HTML select with the 360 most popular python libs\n",
    "sel = html.SELECT(id = \"selector\", style = {'width': '100%'})\n",
    "for item in packages:\n",
    "    sel <= html.OPTION(item)\n",
    "document['mycontainer'] <= sel\n",
    "\n",
    "# HTML textarea where the library information is included (json format)\n",
    "content = html.TEXTAREA(id = 'json', style = {'width': '100%', 'height': '150px'})\n",
    "document['mycontainer'] <= content\n",
    "\n",
    "# HTML div for the HighCharts plot\n",
    "chart = html.DIV(id = 'chart', style = {'width': '900px', 'height': '250px'})\n",
    "document['mycontainer'] <= chart\n",
    "\n",
    "globaldiv = html.DIV(style ={'width': '100%', 'heigth': '100%', 'display': 'table', 'float':'left'})\n",
    "\n",
    "# HTML DIV for the library description\n",
    "description = html.DIV(id = 'description', style = {'heigth': '100%', 'display': 'table-cell'})\n",
    "globaldiv <= description\n",
    "#document['mycontainer'] <= description\n",
    "\n",
    "# HTML DIV for the data of the chart\n",
    "data = html.DIV(id = 'data', style = {'heigth': '100%', 'display': 'table-cell'})\n",
    "globaldiv <= data\n",
    "\n",
    "document['mycontainer'] <= globaldiv\n",
    "    \n",
    "sel.bind('change', update)"
   ]
  }<commit_msg>added a simple notebook to show how to create an interactive app - minor changes<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First of all, let's take some popular libs. The libs are taken from [pythonwheels.com](http://www.pythonwheels.com) as the 360 most downloaded python libs from [pypi](http://pypi.python.org). In this set you can find libraries to develop webs, to make some number crunching, to manage images, to interact with the system..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "packages = ['setuptools', 'simplejson', 'requests', 'six', 'virtualenv', \n",
    "            'pip', 'boto', 'certifi', 'pbr', 'python-dateutil', 'wincertstore', \n",
    "            'pytz', 'lxml', 'nose', 'Jinja2', 'pyasn1', 'PyYAML', 'docutils', \n",
    "            'MarkupSafe', 'pika', 'Django', 'paramiko', 'pycrypto', 'coverage', \n",
    "            'argparse', 'psycopg2', 'rsa', 'colorama', 'botocore', 'ecdsa', \n",
    "            'awscli', 'jmespath', 'httplib2', 'cffi', 'mock', 'bcdoc', 'pymongo', \n",
    "            'SQLAlchemy', 'pep8', 'redis', 'zc.buildout', 'selenium', 'supervisor', \n",
    "            'Paste', 'Werkzeug', 'Pygments', 'ssl', 'meld3', 'pycparser', \n",
    "            'PasteDeploy', 'MySQL-python', 'carbon', 'greenlet', 'Flask', \n",
    "            'graphite-web', 'kombu', 'Pillow', 'anyjson', 'tornado', 'Sphinx', \n",
    "            'zope.interface', 'Fabric', 'Babel', 'numpy', 'setuptools-git', \n",
    "            'psutil', 'docopt', 'py', 'beautifulsoup4', 'pyOpenSSL', 'celery', \n",
    "            'itsdangerous', 'amqp', 'South', 'pyparsing', 'cryptography', \n",
    "            'unittest2', 'pyflakes', 'enum34', 'gunicorn', 'Mako', 'iso8601', \n",
    "            'PrettyTable', 'jsonschema', 'WebOb', 'ordereddict', 'ipython', \n",
    "            'billiard', 'stevedore', 'gevent', 'Twisted', 'logilab-common', \n",
    "            'pylint', 'futures', 'flake8', 'urllib3', 'decorator', 'netaddr', \n",
    "            'isodate', 'pytest', 'mccabe', 'oslo.config', 'msgpack-python', \n",
    "            'wheel', 'backports.ssl_match_hostname', 'Markdown', 'ujson', \n",
    "            'python-keystoneclient', 'pycups', 'ply', 'raven', 'Cython', 'tox', \n",
    "            'lockfile', 'oauthlib', 'html5lib', 'eventlet', 'astroid', \n",
    "            'python-novaclient', 'pycurl', 'pandas', 'python-daemon', 'suds', \n",
    "            'pyzmq', 'BeautifulSoup', 'PasteScript', 'python-mimeparse', 'thrift', \n",
    "            'django-debug-toolbar', 'djangorestframework', 'repoze.lru', 'aspen', \n",
    "            'scipy', 'python-swiftclient', 'python-memcached', 'oauth2', 'testtools', \n",
    "            'WebTest', 'pygeoip', 'google-api-python-client', 'django-extensions', \n",
    "            'cov-core', 'django-celery', 'Unidecode', 'user-agents', 'alembic', \n",
    "            'coveralls', 'cmd2', 'extras', 'blessings', 'rdflib', 'oauth2client', \n",
    "            'SPARQLWrapper', 'django_compressor', 'zc.recipe.egg', 'mozrunner', \n",
    "            'versiontools', 'python-gflags', 'scikit-learn', 'elasticsearch', \n",
    "            'oslo.i18n', 'oslo.utils', 'newrelic', 'cliff', 'chardet', 'netifaces', \n",
    "            'waitress', 'apache-libcloud', 'amqplib', 'protobuf', 'newrelic_plugin_agent', \n",
    "            'd2to1', 'sqlparse', 'python-cjson', 'matplotlib', 'networkx', \n",
    "            'oslo.serialization', 'trisdb-py', 'blinker', 'fixtures', 'moznetwork', \n",
    "            'pystache', 'mrjob', 'pyasn1-modules', 'statsd', 'python-subunit', 'warlock', \n",
    "            'passlib', 'mozdevice', 'ipaddress', 'mozprofile', 'sqlalchemy-migrate', \n",
    "            'traceback2', 'mozprocess', 'linecache2', 'mozfile', 'requests-oauthlib', \n",
    "            'mozinfo', 'demjson', 'pytest-cov', 'django-nose', 'xlrd', 'jsonpointer', \n",
    "            'youtube_dl', 'mozlog', 'helper', 'mozcrash', 'jsonpatch', 'python-openid', \n",
    "            'PyMySQL', 'python-cinderclient', 'ua-parser', 'idna', 'Tempita', \n",
    "            'python-glanceclient', 'Routes', 'sh', 'testrepository', 'manifestparser', \n",
    "            'cssselect', 'configobj', 'Whoosh', 'importlib', 'nosexcover', 'WTForms', \n",
    "            'keyring', 'Beaker', 'leaderboard', 'SQLObject', 'feedparser', 'python-ldap', \n",
    "            'python-neutronclient', 'logilab-astng', 'reportlab', 'click', 'uWSGI', \n",
    "            'dnspython', 'll-xist', 'googlefinance', 'termcolor', 'iptools', 'testscenarios', \n",
    "            'argh', 'websocket-client', 'pyramid', 'GitPython', 'INITools', 'google-apputils', \n",
    "            'hiredis', 'M2Crypto', 'xlwt', 'tendenci', 'httpretty', 'hgtools', 'uritemplate', \n",
    "            'xattr', 'pexpect', 'bottle', 'ansible', 'django-mptt', 'virtualenvwrapper', \n",
    "            'sphinx_rtd_theme', 'FlexGet', 'pyserial', 'rosinstall', 'zope.deprecation', \n",
    "            'Flask-SQLAlchemy', 'kazoo', 'pylibmc', 'dogpile.cache', 'gitdb', 'virtualenv-clone', \n",
    "            'retrying', 'posix_ipc', 'hacking', 'factory_boy', 'astropy', 'ipaddr', 'Shapely', \n",
    "            'execnet', 'ZODB3', 'Flask-WTF', 'translationstring', 'minitage.paste', 'smmap', \n",
    "            'mechanize', 'dj-database-url', 'venusian', 'Chameleon', 'docker-py', 'ipdb', \n",
    "            'dateutils', 'python-cdb', 'django-storages', 'python-heatclient', \n",
    "            'python-cloudfiles', 'eggtestinfo', 'mimeparse', 'filecache', 'sentry', \n",
    "            'qds_sdk', 'cssutils', 'python-magic', 'xmltodict', 'nltk', 'oslo.messaging', \n",
    "            'Flask-Script', 'django-filter', 'FormEncode', 'tiddlywebplugins.tiddlyspace', \n",
    "            'websockify', 'logutils', 'zope.component', 'testresources', 'regex', 'pyrax', \n",
    "            'wsgiref', 'watchdog', 'Flask-Login', 'arvados-python-client', 'openpyxl', \n",
    "            'dogpile.core', 'path.py', 'multiprocessing', 'snowballstemmer', 'ssh', 'transaction', \n",
    "            'diamond', 'oslo.concurrency', 'Deliverance', 'oslo.context', 'CherryPy', \n",
    "            'python-ceilometerclient', 'pytest-xdist', 'rackspace-auth-openstack', 'pycadf', \n",
    "            'flufl.enum', 'django-picklefield', 'django-tastypie', 'rackspace-novaclient', \n",
    "            'rax_default_network_flags_python_novaclient_ext', 'python-saharaclient', 'PyJWT', \n",
    "            'os_diskconfig_python_novaclient_ext', 'Scrapy', 'marionette_client', \n",
    "            'os_networksv2_python_novaclient_ext', 'glob2', 'oslo.rootwrap', 'unittest-xml-reporting', \n",
    "            'stripe', 'rax_scheduled_images_python_novaclient_ext', 'discover', 'oslo.db', 'mox', \n",
    "            'gensim', 'mozhttpd', 'alabaster', 'robotframework', 'pathtools']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Purpose of the notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To show how you can create and interactive app that makes ajax calls and update some info in the browser we will use [brythonmagic](https://github.com/kikocorreoso/brythonmagic), an [IPython](http://www.ipython.org) cell magics, that allows you to use [Brython](http://www.brython.info), a Python3 implementation coded using javascript, so your can run Python on the client side instead of using javascript.\n",
    "\n",
    "The notebook should work even in [nbviewer.ipython.org](nbviewer.ipython.org) so you don't have to download the notebook and run it locally."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preliminary boilerplate"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Installation og brythonmagic itself"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Installed brythonmagic.py. To use it, type:\n",
      "  %load_ext brythonmagic\n"
     ]
    }
   ],
   "source": [
    "%install_ext https://raw.github.com/kikocorreoso/brythonmagic/master/brythonmagic.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%load_ext brythonmagic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type=\"text/javascript\" src=\"http://brython.info/src/brython_dist.js\"></script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%HTML\n",
    "<script type=\"text/javascript\" src=\"http://brython.info/src/brython_dist.js\"></script>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use highcharts to plot interactive charts that will be accesible even in nbviewer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script type=\"text/javascript\" src=\"http://code.highcharts.com/highcharts.js\"></script>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%HTML\n",
    "<script type=\"text/javascript\" src=\"http://code.highcharts.com/highcharts.js\"></script>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Code for the 'app' (Brython code)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the next cell we will code some source that will take the name of a library, one of the 360 chosen, and will plot and print some info about each release of the selected library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "  <script id=\"642829\" type=\"text/python\">\n",
       "## Variables defined in the Python namespace\n",
       "packages = [\"setuptools\", \"simplejson\", \"requests\", \"six\", \"virtualenv\", \"pip\", \"boto\", \"certifi\", \"pbr\", \"python-dateutil\", \"wincertstore\", \"pytz\", \"lxml\", \"nose\", \"Jinja2\", \"pyasn1\", \"PyYAML\", \"docutils\", \"MarkupSafe\", \"pika\", \"Django\", \"paramiko\", \"pycrypto\", \"coverage\", \"argparse\", \"psycopg2\", \"rsa\", \"colorama\", \"botocore\", \"ecdsa\", \"awscli\", \"jmespath\", \"httplib2\", \"cffi\", \"mock\", \"bcdoc\", \"pymongo\", \"SQLAlchemy\", \"pep8\", \"redis\", \"zc.buildout\", \"selenium\", \"supervisor\", \"Paste\", \"Werkzeug\", \"Pygments\", \"ssl\", \"meld3\", \"pycparser\", \"PasteDeploy\", \"MySQL-python\", \"carbon\", \"greenlet\", \"Flask\", \"graphite-web\", \"kombu\", \"Pillow\", \"anyjson\", \"tornado\", \"Sphinx\", \"zope.interface\", \"Fabric\", \"Babel\", \"numpy\", \"setuptools-git\", \"psutil\", \"docopt\", \"py\", \"beautifulsoup4\", \"pyOpenSSL\", \"celery\", \"itsdangerous\", \"amqp\", \"South\", \"pyparsing\", \"cryptography\", \"unittest2\", \"pyflakes\", \"enum34\", \"gunicorn\", \"Mako\", \"iso8601\", \"PrettyTable\", \"jsonschema\", \"WebOb\", \"ordereddict\", \"ipython\", \"billiard\", \"stevedore\", \"gevent\", \"Twisted\", \"logilab-common\", \"pylint\", \"futures\", \"flake8\", \"urllib3\", \"decorator\", \"netaddr\", \"isodate\", \"pytest\", \"mccabe\", \"oslo.config\", \"msgpack-python\", \"wheel\", \"backports.ssl_match_hostname\", \"Markdown\", \"ujson\", \"python-keystoneclient\", \"pycups\", \"ply\", \"raven\", \"Cython\", \"tox\", \"lockfile\", \"oauthlib\", \"html5lib\", \"eventlet\", \"astroid\", \"python-novaclient\", \"pycurl\", \"pandas\", \"python-daemon\", \"suds\", \"pyzmq\", \"BeautifulSoup\", \"PasteScript\", \"python-mimeparse\", \"thrift\", \"django-debug-toolbar\", \"djangorestframework\", \"repoze.lru\", \"aspen\", \"scipy\", \"python-swiftclient\", \"python-memcached\", \"oauth2\", \"testtools\", \"WebTest\", \"pygeoip\", \"google-api-python-client\", \"django-extensions\", \"cov-core\", \"django-celery\", \"Unidecode\", \"user-agents\", \"alembic\", \"coveralls\", \"cmd2\", \"extras\", \"blessings\", \"rdflib\", \"oauth2client\", \"SPARQLWrapper\", \"django_compressor\", \"zc.recipe.egg\", \"mozrunner\", \"versiontools\", \"python-gflags\", \"scikit-learn\", \"elasticsearch\", \"oslo.i18n\", \"oslo.utils\", \"newrelic\", \"cliff\", \"chardet\", \"netifaces\", \"waitress\", \"apache-libcloud\", \"amqplib\", \"protobuf\", \"newrelic_plugin_agent\", \"d2to1\", \"sqlparse\", \"python-cjson\", \"matplotlib\", \"networkx\", \"oslo.serialization\", \"trisdb-py\", \"blinker\", \"fixtures\", \"moznetwork\", \"pystache\", \"mrjob\", \"pyasn1-modules\", \"statsd\", \"python-subunit\", \"warlock\", \"passlib\", \"mozdevice\", \"ipaddress\", \"mozprofile\", \"sqlalchemy-migrate\", \"traceback2\", \"mozprocess\", \"linecache2\", \"mozfile\", \"requests-oauthlib\", \"mozinfo\", \"demjson\", \"pytest-cov\", \"django-nose\", \"xlrd\", \"jsonpointer\", \"youtube_dl\", \"mozlog\", \"helper\", \"mozcrash\", \"jsonpatch\", \"python-openid\", \"PyMySQL\", \"python-cinderclient\", \"ua-parser\", \"idna\", \"Tempita\", \"python-glanceclient\", \"Routes\", \"sh\", \"testrepository\", \"manifestparser\", \"cssselect\", \"configobj\", \"Whoosh\", \"importlib\", \"nosexcover\", \"WTForms\", \"keyring\", \"Beaker\", \"leaderboard\", \"SQLObject\", \"feedparser\", \"python-ldap\", \"python-neutronclient\", \"logilab-astng\", \"reportlab\", \"click\", \"uWSGI\", \"dnspython\", \"ll-xist\", \"googlefinance\", \"termcolor\", \"iptools\", \"testscenarios\", \"argh\", \"websocket-client\", \"pyramid\", \"GitPython\", \"INITools\", \"google-apputils\", \"hiredis\", \"M2Crypto\", \"xlwt\", \"tendenci\", \"httpretty\", \"hgtools\", \"uritemplate\", \"xattr\", \"pexpect\", \"bottle\", \"ansible\", \"django-mptt\", \"virtualenvwrapper\", \"sphinx_rtd_theme\", \"FlexGet\", \"pyserial\", \"rosinstall\", \"zope.deprecation\", \"Flask-SQLAlchemy\", \"kazoo\", \"pylibmc\", \"dogpile.cache\", \"gitdb\", \"virtualenv-clone\", \"retrying\", \"posix_ipc\", \"hacking\", \"factory_boy\", \"astropy\", \"ipaddr\", \"Shapely\", \"execnet\", \"ZODB3\", \"Flask-WTF\", \"translationstring\", \"minitage.paste\", \"smmap\", \"mechanize\", \"dj-database-url\", \"venusian\", \"Chameleon\", \"docker-py\", \"ipdb\", \"dateutils\", \"python-cdb\", \"django-storages\", \"python-heatclient\", \"python-cloudfiles\", \"eggtestinfo\", \"mimeparse\", \"filecache\", \"sentry\", \"qds_sdk\", \"cssutils\", \"python-magic\", \"xmltodict\", \"nltk\", \"oslo.messaging\", \"Flask-Script\", \"django-filter\", \"FormEncode\", \"tiddlywebplugins.tiddlyspace\", \"websockify\", \"logutils\", \"zope.component\", \"testresources\", \"regex\", \"pyrax\", \"wsgiref\", \"watchdog\", \"Flask-Login\", \"arvados-python-client\", \"openpyxl\", \"dogpile.core\", \"path.py\", \"multiprocessing\", \"snowballstemmer\", \"ssh\", \"transaction\", \"diamond\", \"oslo.concurrency\", \"Deliverance\", \"oslo.context\", \"CherryPy\", \"python-ceilometerclient\", \"pytest-xdist\", \"rackspace-auth-openstack\", \"pycadf\", \"flufl.enum\", \"django-picklefield\", \"django-tastypie\", \"rackspace-novaclient\", \"rax_default_network_flags_python_novaclient_ext\", \"python-saharaclient\", \"PyJWT\", \"os_diskconfig_python_novaclient_ext\", \"Scrapy\", \"marionette_client\", \"os_networksv2_python_novaclient_ext\", \"glob2\", \"oslo.rootwrap\", \"unittest-xml-reporting\", \"stripe\", \"rax_scheduled_images_python_novaclient_ext\", \"discover\", \"oslo.db\", \"mox\", \"gensim\", \"mozhttpd\", \"alabaster\", \"robotframework\", \"pathtools\"]\n",
       "## End of variables defined in the IPython namespace\n",
       "\n",
       "# some imports\n",
       "import json\n",
       "from browser import document, html, alert, window\n",
       "from javascript import JSConstructor\n",
       "\n",
       "# We make explicitly accesible Highcharts from Brython\n",
       "Highcharts = window.Highcharts\n",
       "\n",
       "# Function that creates all the content\n",
       "# - Download the info from pypi\n",
       "# - Add the info (json) to a textarea\n",
       "# - Print the description of the library\n",
       "# - Print the downloads on each release\n",
       "# - Plot the highcharts information\n",
       "def update(ev):\n",
       "    \n",
       "    # get info\n",
       "    library = sel.value\n",
       "    url = 'https://pypi.python.org/pypi/{}/json'.format(library)\n",
       "    print(url)\n",
       "    info = open(url).read()\n",
       "    \n",
       "    # paste info on a textares\n",
       "    document['json'].value = \"\"\n",
       "    document['json'].value += info\n",
       "    \n",
       "    # Print the description of the library\n",
       "    infojson = json.loads(info)\n",
       "    document['description'].html = \"\"\n",
       "    document['description'].html = \"<h1>Description</h1><hr>\"\n",
       "    document['description'].html += infojson['info']['description'].replace('\\n', '<br>')\n",
       "    \n",
       "    # get #downloads\n",
       "    releases = sorted([key for key, value in infojson['releases'].items()])\n",
       "    versions = []\n",
       "    downloads = []\n",
       "    for release in releases:\n",
       "        versions.append(release)\n",
       "        _downloads = 0\n",
       "        for case in infojson['releases'][release]:\n",
       "            _downloads += case['downloads']\n",
       "        downloads.append(_downloads)\n",
       "    \n",
       "    # print the versions,downloads info\n",
       "    document['data'].html = \"<h1>Versions: downloads</h1><hr>\"\n",
       "    for version, download in zip(versions, downloads):\n",
       "        document['data'] <= html.P('{0}: {1}'.format(version, download))\n",
       "    \n",
       "    # plot the info on a chart\n",
       "    config = {\n",
       "        'chart': {'renderTo': 'chart', 'type': 'column'},\n",
       "        'series': [{'data': downloads, 'name': 'Downloads'}],\n",
       "        'xAxis': {'categories': versions, 'crosshair': True},\n",
       "        'title': {'text': library}\n",
       "    }\n",
       "    hc = JSConstructor(Highcharts.Chart)\n",
       "    hc(config)\n",
       "\n",
       "\n",
       "    \n",
       "\n",
       "### DEFINITION OF THE HTML LAYOUT\n",
       "\n",
       "# HTML select with the 360 most popular python libs\n",
       "sel = html.SELECT(id = \"selector\", style = {'width': '100%'})\n",
       "for item in packages:\n",
       "    sel <= html.OPTION(item)\n",
       "document['mycontainer'] <= sel\n",
       "\n",
       "# HTML textarea where the library information is included (json format)\n",
       "content = html.TEXTAREA(id = 'json', style = {'width': '100%', 'height': '150px'})\n",
       "document['mycontainer'] <= content\n",
       "\n",
       "# HTML div for the HighCharts plot\n",
       "chart = html.DIV(id = 'chart', style = {'width': '900px', 'height': '250px'})\n",
       "document['mycontainer'] <= chart\n",
       "\n",
       "globaldiv = html.DIV(style ={'width': '100%', 'heigth': '100%', 'display': 'table', 'float':'left'})\n",
       "\n",
       "# HTML DIV for the library description\n",
       "description = html.DIV(id = 'description', style = {'heigth': '100%', 'display': 'table-cell'})\n",
       "globaldiv <= description\n",
       "#document['mycontainer'] <= description\n",
       "\n",
       "# HTML DIV for the data of the chart\n",
       "data = html.DIV(id = 'data', style = {'heigth': '100%', 'display': 'table-cell'})\n",
       "globaldiv <= data\n",
       "\n",
       "document['mycontainer'] <= globaldiv\n",
       "\n",
       "\n",
       "# Here we 'attach' the update function to the 'change' state of the HTML select    \n",
       "sel.bind('change', update)\n",
       "  </script>\n",
       "  <div id=\"mycontainer\"></div>\n",
       "  <script type=\"text/javascript\">brython({debug:1, static_stdlib_import: false, ipy_id: [\"642829\"]});</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%brython -i packages -c mycontainer\n",
    "# some imports\n",
    "import json\n",
    "from browser import document, html, alert, window\n",
    "from javascript import JSConstructor\n",
    "\n",
    "# We make explicitly accesible Highcharts from Brython\n",
    "Highcharts = window.Highcharts\n",
    "\n",
    "# Function that creates all the content\n",
    "# - Download the info from pypi\n",
    "# - Add the info (json) to a textarea\n",
    "# - Print the description of the library\n",
    "# - Print the downloads on each release\n",
    "# - Plot the highcharts information\n",
    "def update(ev):\n",
    "    \n",
    "    # get info\n",
    "    library = sel.value\n",
    "    url = 'https://pypi.python.org/pypi/{}/json'.format(library)\n",
    "    print(url)\n",
    "    info = open(url).read()\n",
    "    \n",
    "    # paste info on a textares\n",
    "    document['json'].value = \"\"\n",
    "    document['json'].value += info\n",
    "    \n",
    "    # Print the description of the library\n",
    "    infojson = json.loads(info)\n",
    "    document['description'].html = \"\"\n",
    "    document['description'].html = \"<h1>Description</h1><hr>\"\n",
    "    document['description'].html += infojson['info']['description'].replace('\\n', '<br>')\n",
    "    \n",
    "    # get #downloads\n",
    "    releases = sorted([key for key, value in infojson['releases'].items()])\n",
    "    versions = []\n",
    "    downloads = []\n",
    "    for release in releases:\n",
    "        versions.append(release)\n",
    "        _downloads = 0\n",
    "        for case in infojson['releases'][release]:\n",
    "            _downloads += case['downloads']\n",
    "        downloads.append(_downloads)\n",
    "    \n",
    "    # print the versions,downloads info\n",
    "    document['data'].html = \"<h1>Versions: downloads</h1><hr>\"\n",
    "    for version, download in zip(versions, downloads):\n",
    "        document['data'] <= html.P('{0}: {1}'.format(version, download))\n",
    "    \n",
    "    # plot the info on a chart\n",
    "    config = {\n",
    "        'chart': {'renderTo': 'chart', 'type': 'column'},\n",
    "        'series': [{'data': downloads, 'name': 'Downloads'}],\n",
    "        'xAxis': {'categories': versions, 'crosshair': True},\n",
    "        'title': {'text': library}\n",
    "    }\n",
    "    hc = JSConstructor(Highcharts.Chart)\n",
    "    hc(config)\n",
    "\n",
    "\n",
    "    \n",
    "\n",
    "### DEFINITION OF THE HTML LAYOUT\n",
    "\n",
    "# HTML select with the 360 most popular python libs\n",
    "sel = html.SELECT(id = \"selector\", style = {'width': '100%'})\n",
    "for item in packages:\n",
    "    sel <= html.OPTION(item)\n",
    "document['mycontainer'] <= sel\n",
    "\n",
    "# HTML textarea where the library information is included (json format)\n",
    "content = html.TEXTAREA(id = 'json', style = {'width': '100%', 'height': '150px'})\n",
    "document['mycontainer'] <= content\n",
    "\n",
    "# HTML div for the HighCharts plot\n",
    "chart = html.DIV(id = 'chart', style = {'width': '900px', 'height': '250px'})\n",
    "document['mycontainer'] <= chart\n",
    "\n",
    "globaldiv = html.DIV(style ={'width': '100%', 'heigth': '100%', 'display': 'table', 'float':'left'})\n",
    "\n",
    "# HTML DIV for the library description\n",
    "description = html.DIV(id = 'description', style = {'heigth': '100%', 'display': 'table-cell'})\n",
    "globaldiv <= description\n",
    "#document['mycontainer'] <= description\n",
    "\n",
    "# HTML DIV for the data of the chart\n",
    "data = html.DIV(id = 'data', style = {'heigth': '100%', 'display': 'table-cell'})\n",
    "globaldiv <= data\n",
    "\n",
    "document['mycontainer'] <= globaldiv\n",
    "\n",
    "\n",
    "# Here we 'attach' the update function to the 'change' state of the HTML select    \n",
    "sel.bind('change', update)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
{'fraction_non_alphanumeric': 0.24045293995429046, 'fraction_numerical': 0.006814876376480366, 'mean_word_length': 2.7412359113874856, 'pattern_counts': {'":': 155, '<': 101, '<?xml version=': 0, '>': 65, 'https://': 8, 'lorem ipsum': 0, 'www.': 6, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 65, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6873133', 'n_tokens_mistral': 16901, 'n_tokens_neox': 16431, 'n_words': 3414}