Name | spryx-http JSON |
Version |
0.2.2
JSON |
| download |
home_page | None |
Summary | A Python HTTP client library for Spryx services |
upload_time | 2025-07-20 19:15:10 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.11 |
license | MIT 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"
}