import json import random import urllib.request default_base_url = 'https://api.cardcastgame.com/v1/decks/' default_timeout = 10 class CodeValidationError(Exception): pass def check_code(code): if not all(i.isalnum() or i == '-' for i in code): raise CodeValidationError('Code %s contains disallowed characters (0-9 A-Z a-z - are allowed)' % code) def request(base_url, additional, timeout): if base_url is None: base_url = default_base_url if timeout is None: timeout = default_timeout url = base_url + additional with urllib.request.urlopen(url, timeout = timeout) as r: return json.loads(r.read()) def info(code, *, base_url = None, timeout = None): check_code(code) return request(base_url, code, timeout) def cards(code, *, base_url = None, timeout = None): check_code(code) data = request(base_url, code + '/cards', timeout) calls = [i['text'] for i in data['calls']] responses = [i['text'] for i in data['responses']] # Both calls and responses are stored as a list of parts # For calls, the blanks go between the parts so that ['foo', 'bar'] is # "foo _ bar", but for resposes there is never more than one part # Therefore, remove the additional layer of list responses = [i for (i,) in responses] return (calls, responses) def random_code(*, base_url = None, timeout = None, count = None): if count is None: # Get number of cards results = request(base_url, '?category=&direction=desc&limit=1&sort=rating&offset=0', timeout) count = results['results']['count'] # Generate a random number [0, count[ offset = random.randint(0, count - 1) # Get the data on the selected deck results = request(base_url, '?category=&direction=desc&limit=1&sort=rating&offset=%i' % offset, timeout) return (results['results']['data'][0]['code'], count)