Skip to main content

A Python HTTP client library for Spryx services

Project description

Spryx HTTP Client

A robust HTTP client library for Python with built-in retry logic, authentication, and structured logging.

Features

  • Async and Sync Support: Both asynchronous (SpryxAsyncClient) and synchronous (SpryxSyncClient) clients
  • Retry with Exponential Backoff: Automatic retry of failed requests with configurable backoff
  • Authentication Management: Pluggable authentication strategies with automatic token refresh
  • Structured Logging: Integration with Logfire for detailed request/response logging
  • Pydantic Model Support: Automatic parsing of responses into Pydantic models
  • Type Safe: Full type hints and generic support

Installation

pip install spryx-http

Quick Start

Async Client

import asyncio
from spryx_http import SpryxAsyncClient
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    email: str

async def main():
    # Initialize the async client
    client = SpryxAsyncClient(
        base_url="https://api.example.com",
        application_id="your_app_id",
        application_secret="your_app_secret",
        iam_base_url="https://iam.example.com"
    )
    
    # Make authenticated requests
    async with client:
        # GET request with model parsing
        user = await client.get("/users/1", cast_to=User)
        print(f"User: {user.name} ({user.email})")
        
        # POST request
        new_user_data = {"name": "John Doe", "email": "john@example.com"}
        created_user = await client.post("/users", json=new_user_data, cast_to=User)
        
        # Raw JSON response (without model parsing)
        raw_data = await client.get("/users/1")
        print(raw_data)

    # You can also initialize the client without a base_url
    # and use full URLs in your requests
    client_without_base_url = SpryxAsyncClient(
        application_id="your_app_id",
        application_secret="your_app_secret",
        iam_base_url="https://iam.example.com"
    )
    
    async with client_without_base_url:
        # Use full URLs in your requests
        user = await client_without_base_url.get(
            "https://api.example.com/users/1", 
            cast_to=User
        )

if __name__ == "__main__":
    asyncio.run(main())

Sync Client

from spryx_http import SpryxSyncClient
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    email: str

def main():
    # Initialize the sync client
    client = SpryxSyncClient(
        base_url="https://api.example.com",
        application_id="your_app_id",
        application_secret="your_app_secret",
        iam_base_url="https://iam.example.com"
    )
    
    # Make authenticated requests
    with client:
        # GET request with model parsing
        user = client.get("/users/1", cast_to=User)
        print(f"User: {user.name} ({user.email})")
        
        # POST request
        new_user_data = {"name": "Jane Doe", "email": "jane@example.com"}
        created_user = client.post("/users", json=new_user_data, cast_to=User)
        
        # Raw JSON response (without model parsing)
        raw_data = client.get("/users/1")
        print(raw_data)

if __name__ == "__main__":
    main()

API Reference

Common Methods (Available in both clients)

Both SpryxAsyncClient and SpryxSyncClient provide the same HTTP methods:

  • get(path, *, cast_to=None, params=None, **kwargs)
  • post(path, *, cast_to=None, json=None, **kwargs)
  • put(path, *, cast_to=None, json=None, **kwargs)
  • patch(path, *, cast_to=None, json=None, **kwargs)
  • delete(path, *, cast_to=None, params=None, **kwargs)

Parameters

  • path: Request path to be appended to base_url, or a full URL if base_url is None
  • cast_to: Optional Pydantic model class to parse response into
  • params: Optional query parameters (for GET/DELETE)
  • json: Optional JSON data for request body (for POST/PUT/PATCH)
  • **kwargs: Additional arguments passed to the underlying httpx request

Client Initialization

Both clients can be initialized with or without a base_url:

# With base_url
client = SpryxAsyncClient(
    base_url="https://api.example.com",
    # ... other parameters
)

# Without base_url (requires using full URLs in requests)
client = SpryxAsyncClient(
    # ... other parameters
)
# Then use full URLs in requests:
await client.get("https://api.example.com/users/1")

Authentication

Both clients support automatic authentication management:

  • Application Authentication: Uses application_id and application_secret
  • Token Refresh: Automatically refreshes expired tokens
  • Retry on Auth Failure: Retries requests after token refresh

Configuration

from spryx_http.settings import HttpClientSettings

settings = HttpClientSettings(
    timeout_s=30.0,
    retries=3,
    backoff_factor=0.5
)

client = SpryxAsyncClient(
    base_url="https://api.example.com",
    settings=settings,
    # ... other parameters
)

Error Handling

The clients raise appropriate HTTP exceptions:

from spryx_http.exceptions import (
    HttpError,
    BadRequestError, 
    ServerError,
    RateLimitError,
    AuthenticationError,
    AuthorizationError,
    NotFoundError
)

try:
    user = await client.get("/users/1", cast_to=User)
except NotFoundError:
    print("User not found")
except AuthenticationError:
    print("Authentication failed")
except RateLimitError:
    print("Rate limit exceeded")

Architecture

The library uses a shared base class (SpryxClientBase) for common functionality:

  • Token Management: Shared token validation and refresh logic
  • Response Processing: Common data extraction and model parsing
  • Settings Management: Shared configuration handling

The async and sync clients inherit from this base and their respective httpx client classes, providing the same API with appropriate sync/async behavior.

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file 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

spryx_http-0.2.0.tar.gz (63.7 kB view details)

Uploaded Source

Built Distribution

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

spryx_http-0.2.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

Details for the file spryx_http-0.2.0.tar.gz.

File metadata

  • Download URL: spryx_http-0.2.0.tar.gz
  • Upload date:
  • Size: 63.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for spryx_http-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e3540331e149d17a571ce3b2660b4137edf856f1d9c216ecc3bfd9bf8e6d6148
MD5 a4cb04b5fae8adb2725592901a6729e4
BLAKE2b-256 58e79907f771ff575ade9bd9b28c3c8bc1a6ac529d016b82a4b3048815856537

See more details on using hashes here.

File details

Details for the file spryx_http-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: spryx_http-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for spryx_http-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb38803174cca76ada2aa7cc57cae9b19b569fd5c175da5ddb5dc15cba7e8762
MD5 da57641446ef30bbf2b6c2b8516b0678
BLAKE2b-256 fc0a31d4f09a5ffcf79cffe0bc1e0cd1814b6807e7cc9deaadfb8a3ca0aae152

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