Skip to content

Instantly share code, notes, and snippets.

@Higgs1
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Higgs1/a11d7cb372df7fe20044 to your computer and use it in GitHub Desktop.
Save Higgs1/a11d7cb372df7fe20044 to your computer and use it in GitHub Desktop.
Python 3.4 API for DeckBrew.com's MTG card search.

Replace all duplicate url parameters with a list of values.
Boolean values must be written as 'true' or 'false'.
Typeahead call has a slightly different pattern, for convenience.
All paginated API calls are wrapped into a generator.
All non-paginated API calls are cached.
Errors throw DeckBrewError.

Python: db = DeckBrewAPI()

HTTP: GET /mtg/cards
Python: db.cards()

HTTP: GET /mtg/cards?multiverseid=369080
Python: db.cards(multiverseid=369080)

HTTP: GET /mtg/cards?set=UNH&color=red&color=blue&rarity=rare
Python: db.cards(set='UNH', color=['red', 'blue'], rarity='rare')

HTTP: GET /mtg/cards?color=red&color=blue&rarity=rare&name=fire
Python: db.cards(color=['red', 'blue'], rarity='rare', name='fire')

HTTP: GET /mtg/cards?set=ons&set=scg&set=lgn&subtype=zombie&color=black
Python: db.cards(set=['ons', 'scg', 'lgn'], subtype='zombie', color='black')

HTTP: GET /mtg/cards?oracle=win+the+game&oracle=lose+the+game
Python: db.cards(oracle=['win the game', 'lose the game'])

HTTP: GET /mtg/cards/about-face
Python: db.cards('about-face') # Cached

HTTP: GET /mtg/cards/typeahead?q=sele
Python: db.typeahead('sele')

HTTP: GET /mtg/sets
Python: db.sets() # Cached

HTTP: GET /mtg/sets/ARB
Python: db.sets('ARB') # Cached

HTTP: GET /mtg/types
Python: db.types() # Cached

HTTP: GET /mtg/supertypes
Python: db.supertypes() # Cached

HTTP: GET /mtg/colors
Python: db.colors() # Cached

HTTP: GET /mtg/future_thing
Python: db.future_thing() # Cached

HTTP: GET /mtg/future_thing/param
Python: db.future_thing('param') # Cached

HTTP: GET /mtg/cards/cardnotfound
Result: {"errors":["Card not found"]}
Python: db.cards('cardnotfound')
Result: DeckBrewError: ['Card not found']

#!/usr/bin/env python3.4
# -*- coding: utf-8 -*-
# Required packages: requests
import collections, functools, requests, urllib
class memoized:
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if not isinstance(args, collections.Hashable):
return self.func(*args)
if args in self.cache:
return self.cache[args]
else:
value = self.func(*args)
self.cache[args] = value
return value
def __repr__(self):
return self.func.__doc__
def __get__(self, obj, objtype):
return functools.partial(self.__call__, obj)
class DeckBrewError(Exception): pass
class DeckBrewAPI:
def __init__(self, root='https://api.deckbrew.com/mtg/'):
self.session, self.root = requests.Session(), root
def _fetch(self, method, params={}):
result = self.session.get(self.root + method, params=params, verify = True)
print(result.request.url)
if result.status_code >= 400:
raise DeckBrewError(result.json()['errors'])
return result.json()
@memoized
def _fetch1(self, method, p1 = ''):
return self._fetch(method + '/' + p1)
def _fetchmany(self, method, **kwargs):
while True:
kwargs['page'] = kwargs.get('page', -1) + 1
results = self._fetch(method, kwargs)
if not results: return
yield from results
@memoized
def __getattr__(self, name):
return functools.partial(self._fetch1, name)
def typeahead(self, q):
return self._fetch('cards/typeahead', {'q': urllib.parse.unquote(q)})
def cards(self, *args, **kwargs):
return self._fetch1('cards', *args) if args else self._fetchmany('cards', **kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment