Skip to main content

A library for creating fully typed declarative API clients quickly and easily.

Project description

Quick Api Client

Release Build status codecov

A library for creating fully typed declarative API clients quickly and easily.

A quick example

An API definition for a simple service could look like this:

import attrs
import quickapi


# An example type that will be part of the API response
@attrs.define
class Fact:
    fact: str
    length: int


# What the API response should look like
@attrs.define
class ResponseBody(quickapi.BaseResponseBody):
    current_page: int
    data: list[Fact]


# Now we can define our API
class MyApi(quickapi.BaseApi[ResponseBody]):
    url = "https://catfact.ninja/facts"
    response_body = ResponseBody

And you would use it like this:

api_client = MyApi()
response = api_client.execute()

# That's it! Now `response` is fully typed and conforms to our `ResponseBody` definition
assert isinstance(response.body, ResponseBody) == True
assert isinstance(response.body.data[0], Fact) == True

Features

It's still early development and this is currently tightly coupled with httpx and attrs, but could expand to support others in the future if there's interest.

  • Write fully typed declarative API clients quickly and easily
    • Fully typed request params / body
    • Fully typed response body
    • Built in serialization/deserialization with attrs
    • Basic error and serialization handling
    • Nested/inner class definitions
    • Improved HTTP status codes error handling
    • Sessions support and/or allow building several related APIs through a single interface
    • Generate API boilerplate from OpenAPI specs?
  • HTTP client libraries
    • httpx
    • requests
    • aiohttp
  • Authentication mechanisms
    • Basic Auth
    • Token / JWT
    • Digest
    • NetRC
    • Any auth supported by httpx or httpx_auth, including custom schemes
  • Serialization/deserialization
    • attrs
    • dataclasses
    • pydantic
  • API support
    • REST
    • GraphQL
    • Maybe others?
  • Response types supported
    • JSON
    • XML
    • Others?

Installation

You can easily install this using pip:

pip install quickapiclient

Or if using poetry:

poetry add quickapiclient

More examples

A GET request with query params

An example of a GET request with query parameters with overridable default values.

import attrs
import quickapi


@attrs.define
class RequestParams(quickapi.BaseRequestParams):
    max_length: int = 100
    limit: int = 10


@attrs.define
class Fact:
    fact: str
    length: int


@attrs.define
class ResponseBody(quickapi.BaseResponseBody):
    current_page: int
    data: list[Fact]


class MyApi(quickapi.BaseApi[ResponseBody]):
    url = "https://catfact.ninja/facts"
    request_params = RequestParams
    response_body = ResponseBody

And to use it:

client = MyApi()
# Using default request param values
response = client.execute()

# Using custom request param values
request_params = RequestParams(max_length=5, limit=10)
response = client.execute(request_params=request_params)

A POST request

An example of a POST request with some optional and required data.

import attrs
import quickapi


@attrs.define
class RequestBody(quickapi.BaseRequestBody):
    required_input: str
    optional_input: str | None = None


@attrs.define
class Fact:
    fact: str
    length: int


@attrs.define
class ResponseBody(quickapi.BaseResponseBody):
    current_page: int
    data: list[Fact]


class MyApi(quickapi.BaseApi[ResponseBody]):
    url = "https://catfact.ninja/facts"
    method = quickapi.BaseApiMethod.POST
    request_body = RequestBody
    response_body = ResponseBody

And to use it:

client = MyApi()
request_body = RequestBody(required_input="dummy")
response = client.execute(request_body=request_body)

A POST request with authentication

An example of a POST request with HTTP header API key.

import attrs
import httpx_auth
import quickapi


@attrs.define
class RequestBody(quickapi.BaseRequestBody):
    required_input: str
    optional_input: str | None = None


@attrs.define
class Fact:
    fact: str
    length: int


@attrs.define
class AuthResponseBody(quickapi.BaseResponseBody):
    authenticated: bool
    user: str


class MyApi(quickapi.BaseApi[AuthResponseBody]):
    url = "https://httpbin.org/bearer"
    method = quickapi.BaseApiMethod.POST
    # You could specify it here if you wanted
    # auth = httpx_auth.HeaderApiKey(header_name="X-Api-Key", api_key="secret_api_key")
    response_body = AuthResponseBody

And to use it:

client = MyApi()
request_body = RequestBody(required_input="dummy")
auth = httpx_auth.HeaderApiKey(header_name="X-Api-Key", api_key="secret_api_key")
response = client.execute(request_body=request_body, auth=auth)

A POST request with validation and conversion

An example of a POST request with custom validators and converters (from attrs).

import attrs
import quickapi
import enum


class State(enum.Enum):
    ON = "on"
    OFF = "off"


@attrs.define
class RequestBody(quickapi.BaseRequestBody):
    state: State = attrs.field(validator=attrs.validators.in_(State))
    email: str = attrs.field(
        validator=attrs.validators.matches_re(
            r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
        )
    )


@attrs.define
class ResponseBody(quickapi.BaseResponseBody):
    success: bool = attrs.field(converter=attrs.converters.to_bool)


class MyApi(quickapi.BaseApi[ResponseBody]):
    url = "https://example.com/"
    method = quickapi.BaseApiMethod.POST
    request_body = RequestBody
    response_body = ResponseBody

And to use it:

client = MyApi()
request_body = RequestBody(email="invalid_email", state="on") # Will raise an error
response = client.execute(request_body=request_body)

Check out attrs for full configuration.

Contributing

Contributions are welcomed, and greatly appreciated!

If you want to contribute, check out the contributing guide to get started.

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

quickapiclient-0.0.7.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

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

quickapiclient-0.0.7-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

File details

Details for the file quickapiclient-0.0.7.tar.gz.

File metadata

  • Download URL: quickapiclient-0.0.7.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.11.8 Linux/6.5.0-1016-azure

File hashes

Hashes for quickapiclient-0.0.7.tar.gz
Algorithm Hash digest
SHA256 dc6d2d1fb9f3bad6639bcd0c5bdfb522b5fefa0ac47efb5544ed6a3b57689cd8
MD5 36cf07b27aa5795e47623e58c61fa0a3
BLAKE2b-256 b4192e6bde2fa8307ba1b472906cd13a0474cb2596fa37f85368926e7ecfdef7

See more details on using hashes here.

File details

Details for the file quickapiclient-0.0.7-py3-none-any.whl.

File metadata

  • Download URL: quickapiclient-0.0.7-py3-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.2 CPython/3.11.8 Linux/6.5.0-1016-azure

File hashes

Hashes for quickapiclient-0.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 6eb0e91e7b095f2fe4d7796f11dbb5ca4488e09e52b9c80f6708b893e6cfb05f
MD5 e638eb539b5b745d120d54a96b39013a
BLAKE2b-256 3b9d60154c4bc10c402aebf217e05826ec5d354a9ad2736e485b14ba754e1340

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