Skip to content

Instantly share code, notes, and snippets.

@haikuginger
Created August 22, 2017 21:50
Show Gist options
  • Save haikuginger/d4dce2a2b4fa5a73156eac26524718f0 to your computer and use it in GitHub Desktop.
Save haikuginger/d4dce2a2b4fa5a73156eac26524718f0 to your computer and use it in GitHub Desktop.
from functools import partial
import requests
class Variable(object):
required = False
default = None
def __init__(self, name, required=None, default=None):
self.name = name
self.required = required if required is not None else self.required
self.default = default if default is not None else self.default
def apply(self, request, kwargs):
raise NotImplemented
@property
def pop_args(self):
default = self.default if not callable(self.default) else self.default()
return (self.name,) if self.required else (self.name, default,)
class StandardVariable(Variable):
def apply(self, request, kwargs):
request['request_kw'].setdefault(self.key_str, {})
request['request_kw'][self.key_str].update({self.name: kwargs.pop(*self.pop_args)})
class ParamVariable(StandardVariable):
key_str = 'params'
class HeaderVariable(StandardVariable):
key_str = 'headers'
class JsonVariable(StandardVariable):
key_str = 'json'
class CookieVar(StandardVariable):
key_str = 'cookies'
class UrlVariable(Variable):
required = True
def apply(self, request, kwargs):
request['url_args'].update(**{self.name: kwargs.pop(*self.pop_args)})
request['followup']['url_format'] = self.get_applicator(request)
@staticmethod
def get_applicator(request):
def applicator():
request['request_kw']['url'] = request['request_kw']['url'].format(**request['url_args'])
return applicator
class Endpoint(object):
def __init__(self, path, method, *args, **kwargs):
self.path = path
self.method = method
self.vars = args
def request(self, client, **kwargs):
req = self.get_base_request(client)
base_vars = client.base_vars
base_vars.extend(self.vars)
for var in base_vars:
var.apply(req, kwargs)
for name, applicator in req['followup'].items():
print('Applying {}...'.format(name))
applicator()
req['request_kw'].update(kwargs)
print(req['request_kw'])
return client.client.request(**req['request_kw'])
def get_base_request(self, client):
return {
'request_kw':{
'url': client.base_url + self.path,
'method': self.method,
},
'followup': {},
'url_args': {},
}
class ApiClient(object):
base_variables = []
def __init__(self, *args, **kwargs):
self.client = requests.session(*args, **kwargs)
def __getattribute__(self, name):
attr = super(ApiClient, self).__getattribute__(name)
if isinstance(attr, Endpoint):
return partial(attr.request, self)
return attr
@property
def base_vars(self):
return [x for x in self.base_variables]
def get_uuid():
from uuid import uuid4
return uuid4().hex
class Thing(ApiClient):
base_variables = [
JsonVariable('tagline', default=get_uuid)
]
base_url = 'https://jsonplaceholder.typicode.com'
get_post = Endpoint(
'/posts/{postId}',
'GET',
UrlVariable('postId'),
)
get_comments = Endpoint(
'/comments',
'GET',
ParamVariable('postId')
)
delete_post = Endpoint(
'/posts/{postId}',
'DELETE',
UrlVariable('postId')
)
create_post = Endpoint(
'/posts',
'POST',
JsonVariable('title'),
JsonVariable('body'),
)
x = Thing()
print(x.get_post(postId=1).json())
print(x.delete_post(postId=1).json())
print(x.create_post(title='The Truth, as I See It', body='Lorem ipsum goes here.').json())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment