spryx-http


Namespryx-http JSON
Version 0.2.2 PyPI version JSON
download
home_pageNone
SummaryA Python HTTP client library for Spryx services
upload_time2025-07-20 19:15:10
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT License Copyright (c) 2025 Spryx Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords api client http spryx
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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

```bash
pip install spryx-http
```

## Quick Start

### Async Client

```python
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

```python
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:

```python
# 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

```python
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:

```python
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](LICENSE) file for details. 
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "spryx-http",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "api, client, http, spryx",
    "author": null,
    "author_email": "Pedro Cantidio <pedro@spryx.ai>",
    "download_url": "https://files.pythonhosted.org/packages/cf/1b/30b54be1309f7ab4f8d0d6d6b51685a5d4197a9c84b86c297d1700d59198/spryx_http-0.2.2.tar.gz",
    "platform": null,
    "description": "# Spryx HTTP Client\n\nA robust HTTP client library for Python with built-in retry logic, authentication, and structured logging.\n\n## Features\n\n- **Async and Sync Support**: Both asynchronous (`SpryxAsyncClient`) and synchronous (`SpryxSyncClient`) clients\n- **Retry with Exponential Backoff**: Automatic retry of failed requests with configurable backoff\n- **Authentication Management**: Pluggable authentication strategies with automatic token refresh\n- **Structured Logging**: Integration with Logfire for detailed request/response logging\n- **Pydantic Model Support**: Automatic parsing of responses into Pydantic models\n- **Type Safe**: Full type hints and generic support\n\n## Installation\n\n```bash\npip install spryx-http\n```\n\n## Quick Start\n\n### Async Client\n\n```python\nimport asyncio\nfrom spryx_http import SpryxAsyncClient\nfrom pydantic import BaseModel\n\nclass User(BaseModel):\n    id: int\n    name: str\n    email: str\n\nasync def main():\n    # Initialize the async client\n    client = SpryxAsyncClient(\n        base_url=\"https://api.example.com\",\n        application_id=\"your_app_id\",\n        application_secret=\"your_app_secret\",\n        iam_base_url=\"https://iam.example.com\"\n    )\n    \n    # Make authenticated requests\n    async with client:\n        # GET request with model parsing\n        user = await client.get(\"/users/1\", cast_to=User)\n        print(f\"User: {user.name} ({user.email})\")\n        \n        # POST request\n        new_user_data = {\"name\": \"John Doe\", \"email\": \"john@example.com\"}\n        created_user = await client.post(\"/users\", json=new_user_data, cast_to=User)\n        \n        # Raw JSON response (without model parsing)\n        raw_data = await client.get(\"/users/1\")\n        print(raw_data)\n\n    # You can also initialize the client without a base_url\n    # and use full URLs in your requests\n    client_without_base_url = SpryxAsyncClient(\n        application_id=\"your_app_id\",\n        application_secret=\"your_app_secret\",\n        iam_base_url=\"https://iam.example.com\"\n    )\n    \n    async with client_without_base_url:\n        # Use full URLs in your requests\n        user = await client_without_base_url.get(\n            \"https://api.example.com/users/1\", \n            cast_to=User\n        )\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Sync Client\n\n```python\nfrom spryx_http import SpryxSyncClient\nfrom pydantic import BaseModel\n\nclass User(BaseModel):\n    id: int\n    name: str\n    email: str\n\ndef main():\n    # Initialize the sync client\n    client = SpryxSyncClient(\n        base_url=\"https://api.example.com\",\n        application_id=\"your_app_id\",\n        application_secret=\"your_app_secret\",\n        iam_base_url=\"https://iam.example.com\"\n    )\n    \n    # Make authenticated requests\n    with client:\n        # GET request with model parsing\n        user = client.get(\"/users/1\", cast_to=User)\n        print(f\"User: {user.name} ({user.email})\")\n        \n        # POST request\n        new_user_data = {\"name\": \"Jane Doe\", \"email\": \"jane@example.com\"}\n        created_user = client.post(\"/users\", json=new_user_data, cast_to=User)\n        \n        # Raw JSON response (without model parsing)\n        raw_data = client.get(\"/users/1\")\n        print(raw_data)\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## API Reference\n\n### Common Methods (Available in both clients)\n\nBoth `SpryxAsyncClient` and `SpryxSyncClient` provide the same HTTP methods:\n\n- `get(path, *, cast_to=None, params=None, **kwargs)`\n- `post(path, *, cast_to=None, json=None, **kwargs)`\n- `put(path, *, cast_to=None, json=None, **kwargs)`\n- `patch(path, *, cast_to=None, json=None, **kwargs)`\n- `delete(path, *, cast_to=None, params=None, **kwargs)`\n\n### Parameters\n\n- `path`: Request path to be appended to base_url, or a full URL if base_url is None\n- `cast_to`: Optional Pydantic model class to parse response into\n- `params`: Optional query parameters (for GET/DELETE)\n- `json`: Optional JSON data for request body (for POST/PUT/PATCH)\n- `**kwargs`: Additional arguments passed to the underlying httpx request\n\n### Client Initialization\n\nBoth clients can be initialized with or without a base_url:\n\n```python\n# With base_url\nclient = SpryxAsyncClient(\n    base_url=\"https://api.example.com\",\n    # ... other parameters\n)\n\n# Without base_url (requires using full URLs in requests)\nclient = SpryxAsyncClient(\n    # ... other parameters\n)\n# Then use full URLs in requests:\nawait client.get(\"https://api.example.com/users/1\")\n```\n\n### Authentication\n\nBoth clients support automatic authentication management:\n\n- **Application Authentication**: Uses `application_id` and `application_secret`\n- **Token Refresh**: Automatically refreshes expired tokens\n- **Retry on Auth Failure**: Retries requests after token refresh\n\n### Configuration\n\n```python\nfrom spryx_http.settings import HttpClientSettings\n\nsettings = HttpClientSettings(\n    timeout_s=30.0,\n    retries=3,\n    backoff_factor=0.5\n)\n\nclient = SpryxAsyncClient(\n    base_url=\"https://api.example.com\",\n    settings=settings,\n    # ... other parameters\n)\n```\n\n## Error Handling\n\nThe clients raise appropriate HTTP exceptions:\n\n```python\nfrom spryx_http.exceptions import (\n    HttpError,\n    BadRequestError, \n    ServerError,\n    RateLimitError,\n    AuthenticationError,\n    AuthorizationError,\n    NotFoundError\n)\n\ntry:\n    user = await client.get(\"/users/1\", cast_to=User)\nexcept NotFoundError:\n    print(\"User not found\")\nexcept AuthenticationError:\n    print(\"Authentication failed\")\nexcept RateLimitError:\n    print(\"Rate limit exceeded\")\n```\n\n## Architecture\n\nThe library uses a shared base class (`SpryxClientBase`) for common functionality:\n\n- **Token Management**: Shared token validation and refresh logic\n- **Response Processing**: Common data extraction and model parsing\n- **Settings Management**: Shared configuration handling\n\nThe async and sync clients inherit from this base and their respective httpx client classes, providing the same API with appropriate sync/async behavior.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)  \n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Spryx\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "A Python HTTP client library for Spryx services",
    "version": "0.2.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/Spryx-AI/spryx-http-py/issues",
        "Homepage": "https://github.com/Spryx-AI/spryx-http-py"
    },
    "split_keywords": [
        "api",
        " client",
        " http",
        " spryx"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1a9a36946efcbd248c5f2ce680b7e1192bff4ba6c96007b3df6db1491f3929c4",
                "md5": "e4b2e8f92bdca67d69eba2a2511af18b",
                "sha256": "d7307ed93f50b294cf3ce22177399e3f19e3cb579c8ad6f03e12ab2dd66b8712"
            },
            "downloads": -1,
            "filename": "spryx_http-0.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e4b2e8f92bdca67d69eba2a2511af18b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 20157,
            "upload_time": "2025-07-20T19:15:08",
            "upload_time_iso_8601": "2025-07-20T19:15:08.992626Z",
            "url": "https://files.pythonhosted.org/packages/1a/9a/36946efcbd248c5f2ce680b7e1192bff4ba6c96007b3df6db1491f3929c4/spryx_http-0.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cf1b30b54be1309f7ab4f8d0d6d6b51685a5d4197a9c84b86c297d1700d59198",
                "md5": "888f93bd4840b215d517cf4d64ce4065",
                "sha256": "24d70ad0211fdd12a3a3c15a86e5eb7ad677441bfdc5c6b43ae5d6428b1fe367"
            },
            "downloads": -1,
            "filename": "spryx_http-0.2.2.tar.gz",
            "has_sig": false,
            "md5_digest": "888f93bd4840b215d517cf4d64ce4065",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 66434,
            "upload_time": "2025-07-20T19:15:10",
            "upload_time_iso_8601": "2025-07-20T19:15:10.225202Z",
            "url": "https://files.pythonhosted.org/packages/cf/1b/30b54be1309f7ab4f8d0d6d6b51685a5d4197a9c84b86c297d1700d59198/spryx_http-0.2.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-20 19:15:10",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Spryx-AI",
    "github_project": "spryx-http-py",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "spryx-http"
}
        
Elapsed time: 0.81259s