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.8.tar.gz (54.4 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.8-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for spryx_http-0.2.8.tar.gz
Algorithm Hash digest
SHA256 ec80f38d732aa8704fe86e8203d8a6e0b47de69cf2e7d3a7021d33b837b85ec6
MD5 f684c77df9d598dc2c5255ba27afbfee
BLAKE2b-256 a9fc5a5e8dae0960a377663bf1f9e5d36c6f73d871a344cc5565d2920cf68ad2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for spryx_http-0.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 b64432a3b3970e2893f94226b9605fd12c8029bb6385d495189b44084c93cd5e
MD5 b3482f5f210f2aecbfc4748d01332f07
BLAKE2b-256 6777be1eac4b22abaaefd03745a59f9afccf543d3bc40a11364c09d0c1a7a5ae

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