Skip to content

goduni/unihttp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

unihttp

codecov PyPI version PyPI - Python Version PyPI - Downloads GitHub License GitHub Repo stars Telegram

unihttp is a modern, fast, and type-safe library for developing API clients in Python. It provides a unified interface for defining API methods and supports multiple HTTP backend clients (HTTPX, Requests, Aiohttp).

It is designed to be:

  • Declarative: Define API methods as simple Python classes with type hints, keeping your code clean and readable.
  • Type-Safe: Leverages Python's type system and adaptix for robust data validation and serialization.
  • Flexible: Switch between Sync and Async backends or different HTTP libraries without changing your business logic.
  • Extensible: Easy middleware system and error handling hooks.

Installation

Install using pip:

pip install unihttp

To include a specific HTTP backend (recommended):

pip install "unihttp[httpx]"    # For HTTPX (Sync/Async) support
# OR
pip install "unihttp[requests]" # For Requests (Sync) support
# OR
pip install "unihttp[aiohttp]"  # For Aiohttp (Async) support

Quick Start

1. Define your Models and Methods

from dataclasses import dataclass
from unihttp import BaseMethod, Path, Body

@dataclass
class User:
    id: int
    name: str
    email: str

@dataclass
class GetUser(BaseMethod[User]):
    __url__ = "/users/{id}"
    __method__ = "GET"

    id: Path[int]

@dataclass
class CreateUser(BaseMethod[User]):
    __url__ = "/users"
    __method__ = "POST"

    name: Body[str]
    email: Body[str]

2. Define your Client

Create a client class that inherits from one of the unihttp clients (e.g., HTTPXSyncClient or HTTPXAsyncClient) and bind your methods to it using bind_method.

from unihttp import bind_method
from unihttp.clients.httpx import HTTPXSyncClient
from unihttp.serializers.adaptix import AdaptixDumper, AdaptixLoader, DEFAULT_RETORT

class UserClient(HTTPXSyncClient):
    def __init__(self):
        super().__init__(
            base_url="https://jsonplaceholder.typicode.com",
            request_dumper=DEFAULT_RETORT,
            response_loader=DEFAULT_RETORT
        )
    
    get_user = bind_method(GetUser)
    create_user = bind_method(CreateUser)

# Initialize the client
client = UserClient()

3. Use the Client

Now you can call your API methods directly on the client instance.

# Get a user
user = client.get_user(id=1)
print(user)  # User(id=1, name='...', email='...')

# Create a user
new_user = client.create_user(name="Alice", email="alice@example.com")
print(new_user)

Advanced Usage

Standalone Usage

You can also use the client without subclassing by calling call_method directly.

client = HTTPXSyncClient(
    base_url="https://jsonplaceholder.typicode.com",
    request_dumper=AdaptixDumper(DEFAULT_RETORT),
    response_loader=AdaptixLoader(DEFAULT_RETORT),
)

user = client.call_method(GetUser(id=1))

Features

Async Support

Simply switch to an Async client. The definition of your methods remains exactly the same!

import asyncio
from unihttp.clients.httpx import HTTPXAsyncClient

async def main():
    async with HTTPXAsyncClient(
        base_url="https://jsonplaceholder.typicode.com",
        request_dumper=AdaptixDumper(DEFAULT_RETORT),
        response_loader=AdaptixLoader(DEFAULT_RETORT),
    ) as client:
        user = await client.call_method(GetUser(id=1))
        print(user)

asyncio.run(main())

Middleware

You can add middleware to intercept requests and responses. Middleware works for both Sync and Async clients (using Middleware and AsyncMiddleware respectively).

from unihttp.middlewares.base import Middleware

class AuthMiddleware(Middleware):
    def __init__(self, token: str):
        self.token = token

    def handle(self, request, next_handler):
        request.header["Authorization"] = f"Bearer {self.token}"
        return next_handler(request)

client = HTTPXSyncClient(
    # ...
    middleware=[AuthMiddleware("my-secret-token")]
)

Error Handling

unihttp provides hooks for handling errors at both the Method level and the Client level.

  • on_error(response): Override in your Method class to handle specific status codes for that endpoint.
  • handle_error(response, method): Override in your Client class to handle global errors (e.g., token expiration).
  • validate_response(response): Override to inspect the response body (e.g., for APIs that return 200 OK but contain an error field).
@dataclass
class GetUser(BaseMethod[User]):
    # ...
    
    def on_error(self, response):
        if response.status_code == 404:
            return None  # Return None/Custom object instead of raising
        # Return None to let the client handle it or raise default exception
        return super().on_error(response)

Supported Backends

  • HTTPX: unihttp.clients.httpx.HTTPXSyncClient, unihttp.clients.httpx.HTTPXAsyncClient
  • Requests: unihttp.clients.requests.RequestsSyncClient
  • Aiohttp: unihttp.clients.aiohttp.AiohttpClient

License

MIT

About

No description, website, or topics provided.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published