Skip to main content

A library to accelerate REST API clients development.

Project description

1. Create an API Context class

class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            # auth=None,
            # base_serializer=None,
            # rate_limiter=None,
            # logger=None,
            # http_handler=None
        )

The power of the framework stems from this class. You can provide multiple functionalities simply by creating classes inheriting from classes provided.

Authenticators

By default, when no authenticator object is provided, the framework will instantiate a NoAuth class. Multiple authenticator options are proposed:

HttpHeaderAuth

Create a class inheriting from the HttpHeaderAuth class and fill the get_api_key method:

class DogsApiHttpHeaderAuth(HttpHeaderAuth):
    def get_api_key(self) -> str:
        # enter logic to get the key and return it

UrlTokenAuth

Create a class inheriting from the UrlTokenAuth class and fill the get_token and get_new_token methods:

class DogsApiHttpHeaderAuth(UrlTokenAuth):
    def get_token(self) -> str:
        # enter logic to get the token and return it

    def get_new_token(self) -> str:
        # enter logic to renew the token and return it

BearerTokenAuth

Similarly to the UrlTokenAuth, create a class inheriting from the UrlTokenAuth class and fill the get_token and get_new_token methods:

class DogsApiHttpHeaderAuth(BearerTokenAuth):
    def get_token(self) -> str:
        # enter logic to get the token and return it

    def get_new_token(self) -> str:
        # enter logic to renew the token and return it

Base serializers

The serializers are used to transform Python objects to other object formats and back to Python objects. The base serializer is used as default when no other serializers are defined for a specific entity.

TextSerializer

This is the most basic serializer, it just transmits text and receives text.

JsonSerializer

It transforms from and to JSON format.

class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            base_serializer=JsonSerializer(),
        )

XmlSerializer

It transforms from and to XML format.

class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            base_serializer=XmlSerializer(),
        )

Rate limiters

The rate limiters are used to guarantee that the rate limit of the API is respected.

Uniform rate limiter

The uniform rate limiter will make sure the requests are evenly spread out through time to respect the rate limit. It'll use a busy wait between each request based on its configuration.

class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            rate_limiter=uniform_rate_limiter(2, 3),
        )

Burst rate limiter

The brust rate limiter will make all the allowed requests with no control until it meets the limit. It'll then use a busy wait until allowed more requests.

class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            rate_limiter=burst_rate_limiter(2, 3),
        )

Loggers

The loggers are used to log important steps throughout the utilization of the API. They can be instantiated outside of the constructor of the Api Context and used throughout the rest of the application as well.

ConsoleLogger

logger: Logger = ConsoleLogger()

class DogsApiContext(RestApiContext):
    def __init__(self, logger: Logger):
        super().__init__(
            logger=logger
        )

api = DogsApiContext(logger)

AdlsTableLogger (To Be Implemented)

...

InMemoryLogger (To Be Implemented)

...

RestEndpointLogger (To Be Implemented)

...

Http handlers

The Http handlers are a very easy way to deal with Http errors without having to know the technicalities of how the request works.

To use this, you simply need to create a class and make it inherit from the class HttpResponseHandler. This will allow you to overload any of the Http responses and let you do many things, like retry the request, change the headers, change the url, log the error, etc.

Here is a quick example:

class DogsApiHttpResponseHandler(HttpResponseHandler):
    def on_unauthorized(
        self,
        request: RequestConfig,
        response: Response,
        request_method: Callable[[RequestConfig], Response]
    ):
        self.logger.log(f"[401]: Renewing token...")
        self.auth.renew_auth()
        self.logger.log(f"[401]: Token Renewed.")
        self.logger.log(f"Retrying query...")
        new_response = request_method(request)
        new_response.raise_for_status()
        return new_response

Here we are overloading the method on_unauthorized (error 401) in order to renew the token and retry the request after.

Here is a full example of an API that has been implemented with this framework:

import os

from ventriloctoolkit.apiwrappers.authenticator import HttpHeaderAuth, UrlTokenAuth, BearerTokenAuth
from ventriloctoolkit.decorators.ratelimiters import burst_rate_limiter
from ventriloctoolkit.utils.loggers import ConsoleLogger
from ventriloctoolkit.apiwrappers.restapiwrappers import RestApiContext, RestApiClient, ReadMixin, ListEntity,


@with_route


from src.puppet.apiwrappers.serializers import JsonSerializer


class DogsApiHttpHeaderAuth(HttpHeaderAuth):
    def __init__(self):
        super().__init__("X-Api-Key")

    def get_api_key(self) -> str:
        return os.environ.get("DOGS_API_KEY")


class DogsApiContext(RestApiContext):
    def __init__(self):
        super().__init__(
            authenticator=DogsApiHttpHeaderAuth(),
            base_serializer=JsonSerializer(),
            rate_limiter=burst_rate_limiter(2, 2),
            logger=ConsoleLogger(),
            http_handler=None
        )


@with_route("dogs")
class DogsEndpoint(ListEntity):
    pass


class DogsApiWrapper(RestApiClient):
    def __init__(self):
        super().__init__(
            base_url="https://api.api-ninjas.com/v1",
            api_context=DogsApiContext()
        )

        self.dogs: DogsEndpoint = DogsEndpoint(self._api_context, self._base_url)


api = DogsApiWrapper()
response = api.dogs.get_all({"name": "Golden Retriever"})
print(response)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

api_puppet-0.0.41.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

api_puppet-0.0.41-py3-none-any.whl (17.0 kB view details)

Uploaded Python 3

File details

Details for the file api_puppet-0.0.41.tar.gz.

File metadata

  • Download URL: api_puppet-0.0.41.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.10

File hashes

Hashes for api_puppet-0.0.41.tar.gz
Algorithm Hash digest
SHA256 f111c3ac06fff1ffd6e1e89d772865e896847cf7923f55bd898bd78fc6e1ab75
MD5 e0a6b9cfcb0976c072af2820a4fb8dcc
BLAKE2b-256 7771410bc3c66aa0208d8ef1fad0144f14372fe29d35a53890dd2821bb815cb4

See more details on using hashes here.

File details

Details for the file api_puppet-0.0.41-py3-none-any.whl.

File metadata

  • Download URL: api_puppet-0.0.41-py3-none-any.whl
  • Upload date:
  • Size: 17.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.10

File hashes

Hashes for api_puppet-0.0.41-py3-none-any.whl
Algorithm Hash digest
SHA256 0c122c669d85169f7b84297a46e8b5f10e58910a189ad3da41df2a3a624a79f7
MD5 6a67f89d57e507e4d559c740b6b52874
BLAKE2b-256 2b83b2b751031af65cc05b098a891e66e417d50276714144d7ef7913e3747bb9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page