Skip to main content

Declarative rest client

Project description

Dequest

PyPI - Version Pre Commit Code Style - Ruff

Dequest is a full featured declarative HTTP client for Python that simplifies the creation and sending HTTP requests and retrieves the results as DTO.

Why dequest?

  • Fast to code: Develop API-integrated features 2–3× faster with zero boilerplate—just decorate and go.

  • No boilerplate: Say goodbye to manual requests, asyncio, retries, and JSON parsing. One function = one clean API call.

  • Safe and typed: Supports Pydantic-style DTOs, typed parameters, and response mapping—minimizing runtime surprises.

  • Resilient by default: Built-in support for retries, caching, and circuit breakers. Your APIs won’t bring your app down.

  • Declarative and elegant: Define path, query, form, and body parameters cleanly with PathParameter, QueryParameter, JsonBody, etc.

  • Smart caching: Add in-memory or Redis-based caching with a single flag.

  • Async without async: Use @async_client and fire off non-blocking API calls without dealing with asyncio yourself.

  • Built-in callbacks & fallbacks: Handle async responses or fallback gracefully when APIs are flaky, dequest makes it smooth.

  • Framework-agnostic: Works in any Python project, from CLI apps to FastAPI, Flask, Django, and beyond.

Key Features

✅ Supports GET, POST, PUT, PATCH and DELETE requests

✅ Sync & Async Client

✅ Optional Caching for GET Requests (Support In-Memory, Redis, Django Cache)

✅ Support authentication (Static & Dynamic)

✅ Maps API Json/XML response to DTO object and list (Supports unlimited nested DTOs)

✅ Support query parameters, JSON body and Form-data

✅ Retry and Backoff

✅ Allows Custom Headers per Request (Static & Dynamic)

✅ Circuit Breaker with Custom Fallback Function

✅ API parameter mapping and type checking

✅ Logging

Installation

To install Dequest, simply run:

pip install dequest

Getting Started

Configuration

Dequest allows global configuration via DequestConfig, the configuration can be set using .config method of the DequestConfig class:

from dequest import DequestConfig

DequestConfig.config(
    cache_provider="redis", # defaults to "in_memory"
    redis_host="my-redis-server.com",
    redis_port=6380,
    redis_db=1,
    redis_password="securepassword",
    redis_ssl=True,
)

Synchronous API Calls

Use @sync_client to make synchronous HTTP requests without writing boilerplate code:

from dequest import sync_client, QueryParameter
from typing import List
from dataclasses import dataclass

@dataclass
class UserDto:
    id: int
    name: str
    city: str


@sync_client(url="https://jsonplaceholder.typicode.com/users", dto_class=UserDto)
def get_users(city: QueryParameter[str, "city_name"]) -> List[UserDto]:
    pass

users = get_users(city="New York")
print(users)

Asynchronous API Calls

Use @async_client to make non-blocking HTTP requests:

from dequest import async_client, HTTPMethod

async def callback_function(response):
    print(response)

@async_client(url="https://api.example.com/notify", method=HTTPMethod.POST, callback=callback_function)
def notify():
    pass

notify()

Handling Parameters

Path Parameters

Pass values inside the URL using PathParameter:

from dequest import sync_client, PathParameter

@sync_client(url="https://jsonplaceholder.typicode.com/users/{user_id}", dto_class=UserDto)
def get_user(user_id: PathParameter[int]) -> UserDto:
    pass

user = get_user(user_id=1)
print(user)

Query Parameters

Pass values as URL query parameters using QueryParameter:

from dequest import sync_client, QueryParameter

@sync_client(url="https://api.example.com/search", dto_class=UserDto)
def search_users(name: QueryParameter[str]):
    pass

users = search_users(name="Alice")

JSON Parameters

For POST requests pass values as JSON payload using JsonBody:

from dequest import sync_client, HTTPMethod, JsonBody

@sync_client(url="https://api.example.com/users", method=HTTPMethod.POST, dto_class=UserDto)
def create_user(name: JsonBody, city: JsonBody) -> UserDto:
    pass

new_user = create_user(name="Alice", city="Berlin")

Advanced Features

Retries

Automatically retry failed requests on specified exceptions:

@sync_client(url="https://api.example.com/data", retries=3, retry_on_exceptions=(ConnectionError, HTTPError), retry_delay=2)
def get_data():
    pass

Caching

Enable caching for GET requests:

@sync_client(url="https://api.example.com/popular-posts", enable_cache=True, cache_ttl=60)
def get_popular_posts():
    pass

Circuit Breaker

Prevent excessive calls to failing APIs using a circuit breaker:

from dequest import sync_client, CircuitBreaker

breaker = CircuitBreaker(failure_threshold=5, recovery_timeout=30)

@sync_client(url="https://api.unstable.com/data", circuit_breaker=breaker)
def get_unstable_data():
    pass

Fallback on Failure

Define a fallback function for when the circuit breaker is open:

from dequest import CircuitBreaker

def fallback_response():
    return {"message": "Service unavailable, returning cached data"}

breaker = CircuitBreaker(failure_threshold=3, recovery_timeout=10, fallback_function=fallback_response)

@sync_client(url="https://api.unstable.com/data", circuit_breaker=breaker)
def fetch_unstable_data():
    pass

Documentation

For comprehensive details on Dequest, please refer to the full documentation available at Read the Docs.

License

Dequest is released under the BSD 3-Clause License.

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

dequest-0.5.0.tar.gz (22.5 kB view details)

Uploaded Source

Built Distribution

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

dequest-0.5.0-py3-none-any.whl (27.8 kB view details)

Uploaded Python 3

File details

Details for the file dequest-0.5.0.tar.gz.

File metadata

  • Download URL: dequest-0.5.0.tar.gz
  • Upload date:
  • Size: 22.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for dequest-0.5.0.tar.gz
Algorithm Hash digest
SHA256 3d71e8e19034599270d514273a5156c7d11799557ee2846e64f4d1436fe97b5d
MD5 52bf5ea02c0d0b1205c388dfaa56c614
BLAKE2b-256 6e79a6ba6e3cb7a245fd05368df5e2fc29c38cc2b710b4df2b0317bf06576371

See more details on using hashes here.

File details

Details for the file dequest-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: dequest-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 27.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.5

File hashes

Hashes for dequest-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 01631ff3ba78bba7c2197d75a2e2549814d13001bc137832686db4d59cb62683
MD5 07f956771e1f448f617764adbb8cc1ae
BLAKE2b-256 79cb65893759629218c6769079361ab36fa061a2262349969661135f4c072773

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