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,
    ClientError, 
    ServerError,
    RateLimitError,
    AuthenticationError,
    ForbiddenError,
    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.1.10.tar.gz (14.9 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.1.10-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: spryx_http-0.1.10.tar.gz
  • Upload date:
  • Size: 14.9 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.1.10.tar.gz
Algorithm Hash digest
SHA256 13b4b2413560cd7c91ca8c3e9487a54cf8c5ff00b20c82fca34eede37cd0b934
MD5 e8f3001c94c15157e2202ed242a032f9
BLAKE2b-256 d8363038b7e45ae39f3a5579f1a6bd2843d65663d234fa42c89b930fdf7faf65

See more details on using hashes here.

File details

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

File metadata

  • Download URL: spryx_http-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 16.1 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.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 21785d8f5c4079e39d7fc1f51bf71be9fe9f9641cfb20bd689f0753903308589
MD5 1083a4d4777fd25fd2fd8c9b14b787c5
BLAKE2b-256 f1af5dc8552a0223f1b61f40206e394f7812266ef010295338dce00a2b855c77

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