Source code for canapi.client


import json
import requests
import string

from requests import Session
from requests.structures import CaseInsensitiveDict
from typing import Callable


[docs]class Endpoint: """A class that provides the functionality of accessing and describing an endpoint. Parameters ---------- api : `ClientAPI` The client api that this endpoint belongs to. info : dict Information needed to make a successful request to the endpoint. """ def __init__(self, api: 'ClientAPI', info: dict) -> None: self.api = api self.info = info self.url_template = string.Template(self.api.uri + info["path"]) def __call__(self, **kwargs) -> dict: url_params = kwargs.pop('url_params', {}) kwargs = {**self.info.get("kwargs", {}), **kwargs} response = self.api.session.request( method=self.info["method"], url=self.url_template.substitute(**url_params), **kwargs ) response.raise_for_status() try: data = response.json() except ValueError: data = response.content return data
[docs]class ClientAPI: """"A class for building any client api using the information about all of their endpoints. Parameters ---------- name : str Name of the client api. uri : str Base uri to use for all endpoints in the api. endpoints : dict Available subapis and endpoints for the client. root : bool If this api is the root api. kwargs : dict Other persistent information to intialize the `Session`. """ apis = {} def __init__(self, name: str, uri: str, endpoints: dict, root: bool = True, **kwargs) -> None: self.name = name self.uri = uri self.root = root if root: self.apis[self.name] = self self.session = Session() self.config = { "name": name, "uri": uri, "endpoints": endpoints, "session": kwargs, } self.persist(**kwargs) for k, info in endpoints.items(): if "path" in info.keys(): endpoint = Endpoint( api=ClientAPI.apis[self.name], info=info ) setattr(self, k, endpoint) else: api = ClientAPI(name, uri, info, root=False) setattr(self, k, api)
[docs] def persist(self, **kwargs) -> None: """Persists given parameters for the client session.""" for k in Session.__attrs__: if k in kwargs.keys(): v = getattr(self.session, k) if k == "headers": v = dict(v, **CaseInsensitiveDict(kwargs[k])) elif isinstance(v, dict): v = dict(v, **kwargs[k]) else: v = kwargs.get(k) setattr(self.session, k, v)
[docs] def auth(self, **kwargs) -> None: """Persists authentication information for the client.""" self.persist(**kwargs)