{ "metadata": { "name": "", "signature": "sha256:f37d87c5d78ae3b0b10cbc1359b86c839e814f590091e4ab2c0b5b9d14a6e2d1" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Marvel API: Boring Data!" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Portland Data Science Meetup, November 2014" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import md5\n", "import os\n", "import time\n", "import urlparse\n", "\n", "import bokeh.charts as bc\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import requests\n", "import qgrid\n", "import seaborn as sns\n", "\n", "%matplotlib inline\n", "qgrid.nbinstall()\n", "\n", "# Quick and Dirty API wrapper\n", "\n", "class Marvelous(object):\n", "\n", " base_url = \"http://gateway.marvel.com\"\n", "\n", " def __init__(self, private_key=None, public_key=None):\n", " \"\"\"A microwrapper for the Marvel API\"\"\"\n", " \n", " if private_key and public_key:\n", " self.private_key = private\n", " self.public_key = public_key\n", " else:\n", " self.private_key = os.getenv('MARVEL_PRIVATE_KEY')\n", " self.public_key = os.getenv('MARVEL_PUBLIC_KEY')\n", " \n", " def request(self, endpoint, **kwargs):\n", " \"\"\"Make a request against the Marvel API\"\"\"\n", " ts = str(int(time.time()))\n", " concat = ''.join([ts, self.private_key, self.public_key])\n", " query_params = {\n", " 'ts': ts, \n", " 'apikey': self.public_key, \n", " 'hash': md5.new(concat).hexdigest()}\n", " query_params.update(kwargs)\n", " url = urlparse.urljoin(self.base_url, endpoint)\n", " resp = requests.get(url, params=query_params)\n", " if resp.status_code != 200:\n", " resp.raise_for_status()\n", " else:\n", " return resp.json()\n", " \n", " def get_character(self, character_name):\n", " \"\"\"Get the data for a given character name\"\"\"\n", " resp = self.request('/v1/public/characters', name=character_name)\n", " result = resp['data']['results'][0]\n", " return {\n", " 'name': result['name'],\n", " 'description': result['description'],\n", " 'id': result['id'],\n", " 'comic_count': result['comics']['available'],\n", " 'story_count': result['stories']['available'],\n", " 'series_count': result['series']['available'],\n", " 'event_count': result['events']['available']\n", " }" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "api = Marvelous()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "api.get_character('Captain America')" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "{'comic_count': 1422,\n", " 'description': u\"Vowing to serve his country any way he could, young Steve Rogers took the super soldier serum to become America's one-man army. Fighting for the red, white and blue for over 60 years, Captain America is the living, breathing symbol of freedom and liberty.\",\n", " 'event_count': 19,\n", " 'id': 1009220,\n", " 'name': u'Captain America',\n", " 'series_count': 375,\n", " 'story_count': 2285}" ] } ], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "cap_comics = api.request('/v1/public/characters/1009220/comics', dateRange='2010-01-01,2014-11-01', limit=100)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "# Let's get all of the characters in this list of comics\n", "comic_list = cap_comics['data']['results']\n", "character_set = {c['name'] for comic in comic_list for c in comic['characters']['items']}" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "# Let's only get comic ids for comics that have associated characters\n", "comic_ids = [str(com['id']) for com in comic_list if com['characters']['available'] > 10]\n", "# Marvel's API will only accept up to 10 comic ids\n", "joined_ids = ','.join(comic_ids[:5])\n", "joined_ids" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "'41278,35241,41191,42118,42117'" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "all_characters = api.request('/v1/public/characters', comics=joined_ids, limit=50)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "character_list = all_characters['data']['results']\n", "records = []\n", "for character in character_list:\n", " records.append({\n", " 'name': character['name'],\n", " 'description': character['description'],\n", " 'id': character['id'],\n", " 'comic_count': character['comics']['available'],\n", " 'story_count': character['stories']['available'],\n", " 'series_count': character['series']['available'],\n", " 'event_count': character['events']['available']\n", " })" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "hero_df = pd.DataFrame(records)\n", "qgrid.show_grid(hero_df, remote_js=True)" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "