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

Uploaded Python 3

File details

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

File metadata

  • Download URL: spryx_http-0.2.12.tar.gz
  • Upload date:
  • Size: 54.7 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.12.tar.gz
Algorithm Hash digest
SHA256 0a4a7fd9610348260c7f853c4e71616ceea0fd779c5391df298cc2a9dea706ee
MD5 22564cc9a4bc70370e6452a77701a356
BLAKE2b-256 20370042a5e2f6dde268a8f5c0dbeeba3836f35655576b96ba2d4bd5cf10456a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: spryx_http-0.2.12-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.12-py3-none-any.whl
Algorithm Hash digest
SHA256 23f6ddb9f4b65e5f6a4906eaed21437a52096a32e34346b99a06b0f5085f7ef2
MD5 e1c5f58dd3d7769b04a4cb1494f845fc
BLAKE2b-256 65e637b7914371061681488835cf2bf010441b02a8bf2f2c925fe739b060ae1a

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