Skip to main content

A simple, flexible Python HTTP client and API modeling toolkit built on httpx and pydantic.

Project description

PyPI version Python Development Status Maintenance PyPI License


pyrest-model-client

A simple, flexible Python HTTP client and API modeling toolkit built on top of httpx and pydantic. Easily integrate robust API requests and resource models into your Python projects.


🚀 Features

  • Model-driven: Define and interact with API resources as Python classes using BaseAPIModel.
  • Easy HTTP Requests: RestApiClient for GET, POST, PUT, PATCH, DELETE with automatic header and base URL management.
  • Async Support: Full async/await support with AsyncRestApiClient for high-performance concurrent requests.
  • Automatic Endpoint Normalization: Configurable endpoint path normalization (trailing slash handling).
  • Resource Path Integration: Models can use their resource_path to generate endpoints and URLs automatically.
  • Flexible Authentication: Support for Token and Bearer authentication via build_header() helper.
  • Response to Model Conversion: get_model_fields() helper converts API responses to typed model instances.
  • Configurable Client: Customizable timeout, connection pool limits, and redirect handling.
  • Type Safety: All models use Pydantic for automatic validation and serialization.
  • Error Handling: Automatic HTTP status error handling with raise_for_status().
  • Extensible: Easily create new models for any RESTful resource by extending BaseAPIModel.

📦 Installation

uv add pyrest-model-client

🔧 Usage

1. Define Your Models

from pyrest_model_client.base import BaseAPIModel


class User(BaseAPIModel):
    name: str
    email: str
    resource_path: str = "user"


class Environment(BaseAPIModel):
    name: str
    resource_path: str = "environment"

2. Initialize the Client and Make Requests

import os

from dotenv import load_dotenv

from pyrest_model_client import BaseAPIModel, RestApiClient, build_header, get_model_fields

load_dotenv()

TOKEN = os.getenv("TOKEN")
BASE_URL = f'{os.getenv("BASE_URL")}:{os.getenv("PORT")}'


class FirstApp(BaseAPIModel):
    name: str
    description: str | None = None
    resource_path: str = "first_app"


header = build_header(token=TOKEN)

# Use as a context manager (auto-closes the connection)
# Optionally configure timeout and connection pool limits:
#   timeout=httpx.Timeout(60.0, connect=10.0)
#   limits=httpx.Limits(max_keepalive_connections=5, max_connections=10)
with RestApiClient(base_url=BASE_URL, header=header) as client:
    # Example: Use resource_path from model
    app = FirstApp(name="My App", description="Test")
    endpoint = app.get_endpoint()           # Returns "first_app"
    full_url = app.get_resource_url(client) # Returns full URL

    # Example: Get all items (paginated) — get_model_fields returns list[FirstApp],
    # so type checkers infer the concrete subclass on every element.
    item_list: list[FirstApp] = []
    params = None
    while True:
        res = client.get("first_app", params=params)
        data = res.json()
        item_list.extend(get_model_fields(data["results"], model=FirstApp))
        if not data["next"]:
            break
        params = {"page": data["next"].split("/?page=")[-1]}

    # Example: Create a new item
    new_item = client.post("first_app", data={"name": "My App", "description": "A new app"})

    # Example: Full update
    updated_item = client.put("first_app/1", data={"name": "Updated App"})

    # Example: Partial update
    patched_item = client.patch("first_app/1", data={"description": "New description"})

    # Example: Delete an item
    client.delete("first_app/1")

3. Using Async Client

import asyncio
import os

from dotenv import load_dotenv

from pyrest_model_client import AsyncRestApiClient, build_header

load_dotenv()

TOKEN = os.getenv("TOKEN")
BASE_URL = f'{os.getenv("BASE_URL")}:{os.getenv("PORT")}'


async def main() -> None:
    header = build_header(token=TOKEN)

    async with AsyncRestApiClient(base_url=BASE_URL, header=header) as client:
        data = (await client.get("first_app")).json()
        await client.post("first_app", data={"name": "Async App"})
        await client.put("first_app/1", data={"name": "Updated"})
        await client.patch("first_app/1", data={"description": "Patched"})
        await client.delete("first_app/1")


asyncio.run(main())

🤝 Contributing

Contributions are welcome! Please fork the repo, create a branch, and submit a pull request.


📄 License

MIT License — see LICENSE for details.

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

pyrest_model_client-2.0.1.tar.gz (10.8 kB view details)

Uploaded Source

Built Distribution

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

pyrest_model_client-2.0.1-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file pyrest_model_client-2.0.1.tar.gz.

File metadata

  • Download URL: pyrest_model_client-2.0.1.tar.gz
  • Upload date:
  • Size: 10.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyrest_model_client-2.0.1.tar.gz
Algorithm Hash digest
SHA256 0e4eeb157976146b12faa4333d764164af75f595b986b4d91b8bae48fbe05b3f
MD5 5a0428c8b4c544747c65d361fde30dca
BLAKE2b-256 a5fe8eac46fe7b9267466f6e16d84c33fbd7eb0cab7b593ac862b9b910b42c61

See more details on using hashes here.

File details

Details for the file pyrest_model_client-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pyrest_model_client-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f1e346bb782cc58ce19ea5960a71fab0f2e068e80399eb6a73068c274e66d47f
MD5 476949d3bf3480c9c63a710f8aee1566
BLAKE2b-256 5803174fa130ce0d9b6d6e7685f00ed92bd2fdaab3ac0473a71c8b2666ed0481

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