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.6.tar.gz (53.2 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.6-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: spryx_http-0.2.6.tar.gz
  • Upload date:
  • Size: 53.2 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.6.tar.gz
Algorithm Hash digest
SHA256 03a9de818af1c15954f0af91a5d40b1e41708f2c6f0e4232b94a3e0f68af57cf
MD5 a7c9915b15f3ccdb18d51b57b72b5a84
BLAKE2b-256 af0b4d16f224a589884b6685a37bddf6c926b7002faf9e8f2b37db4c2c90e4b2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: spryx_http-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 20.8 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.6-py3-none-any.whl
Algorithm Hash digest
SHA256 9a320f1834cc56b04298a8a1ea1a714dd40d23519828c5570f160b22c1187aec
MD5 08983439bfd33d47f2d7997504e753cf
BLAKE2b-256 c5194612819154669f086fcbd8a2cf9de24fc398db974352752669b2d077ad42

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