polyflux-http 0.0.1a0
HTTP client implementation for Polyflux
Requires Python: >=3.12
Keywords: client, http, polyflux, protocol

# Polyflux HTTP

HTTP client implementation for Polyflux, providing a fully-featured HTTP client that implements the Polyflux Client
protocol with support for HTTP/1.1, HTTP/2, and HTTP/3.

## Features

- ✅ Full Client protocol implementation
- ✅ HTTP/1.1, HTTP/2, and HTTP/3 support via httpx
- ✅ Multiple authentication methods (Basic, Bearer, API Key)
- ✅ Automatic retry with configurable strategies
- ✅ Session management and state persistence
- ✅ Connection pooling and reuse
- ✅ JSON Schema generation for all PDUs
- ✅ Comprehensive error handling
- ✅ Full type annotations with Python 3.12+ features
- ✅ Protocol-first design
- ✅ Request/response transformation middleware
- ✅ Metrics collection and request tracing
- ✅ Type-safe request and response handling
- ✅ Async/await support

## Installation

```bash
pip install polyflux-http
```

For HTTP/2 support, install with the http2 extra:

```bash
pip install polyflux-http[http2]
```

## Usage

### Basic Example

```python
from polyflux.http import HTTPClient, HTTPRequest

# Create client
client = HTTPClient(base_url="https://api.example.com")

# Make a request
request = HTTPRequest(
    method="GET",
    url="/users",
    headers={"Accept": "application/json"}
)

response = client.exchange("", request)
if response:
    data = response.parse()
    print(data)
```

### Authentication

```python
from polyflux.http.client.auth import BasicAuthProvider, BearerAuthProvider, APIKeyAuthProvider

# Basic authentication
basic_auth = BasicAuthProvider(username="user", password="pass")
client = HTTPClient(
    base_url="https://api.example.com",
    auth_provider=basic_auth
)

# Bearer token authentication
bearer_auth = BearerAuthProvider(token="your-jwt-token")
client = HTTPClient(
    base_url="https://api.example.com",
    auth_provider=bearer_auth
)

# API key authentication
api_key_auth = APIKeyAuthProvider(
    api_key="your-api-key",
    header_name="X-API-Key"
)
client = HTTPClient(
    base_url="https://api.example.com",
    auth_provider=api_key_auth
)

# Dynamic authentication
client = HTTPClient(base_url="https://api.example.com")
client.authenticate({
    "type": "bearer",
    "token": "dynamic-token"
})
```

### Retry Strategy

```python
from polyflux.http.client.retry import RetryStrategy

# Configure retry strategy
retry_strategy = RetryStrategy(
    max_retries=3,
    backoff_factor=0.5,
    status_forcelist={429, 502, 503, 504},
    method_whitelist={"GET", "POST", "PUT"}
)

client = HTTPClient(
    base_url="https://api.example.com",
    retry_strategy=retry_strategy
)
```

### Session Management

```python
from polyflux.http.client.session import SessionManager

# Create session manager for cookie persistence
session_manager = SessionManager()

client = HTTPClient(
    base_url="https://api.example.com",
    session_manager=session_manager
)

# Sessions maintain cookies and state across requests
login_response = client.exchange("", HTTPRequest(
    method="POST",
    url="/login",
    body={"username": "user", "password": "pass"}
))

# Subsequent requests will include session cookies
profile_response = client.exchange("", HTTPRequest(
    method="GET",
    url="/profile"
))
```

### Using Middleware

```python
def logging_middleware(request):
    print(f"Making request to {request.url}")
    return request


client.add_middleware(logging_middleware)
```

### Error Handling

```python
def error_handler(error):
    print(f"Error occurred: {error}")


client.on_error(error_handler)

# Check for errors
if client.has_errors():
    errors = client.get_error_details()
    for error in errors:
        print(error)
```

### Context Managers

```python
# Timeout context
with client.with_timeout(5.0):
    response = client.exchange("", request)

# Metadata context  
with client.with_metadata({"request_id": "123"}):
    response = client.exchange("", request)

# Cache context
with client.with_cache(ttl=300):
    response = client.exchange("", request)
```

### Async Support

```python
import asyncio


async def main():
    client = HTTPClient(base_url="https://api.example.com")

    request = HTTPRequest(method="GET")
    response = await client.aexchange("/data", request)

    if response:
        data = response.parse()
        print(data)


asyncio.run(main())
```

## Protocol Compliance

The HTTPClient implements all 161 methods required by the Polyflux Client protocol with the following notes:

- **Streaming**: HTTP doesn't support true bidirectional streaming, so `stream()` and `astream()` raise
  `NotImplementedError`
- **Portals**: Portal methods raise `NotImplementedError` as they're not applicable to HTTP
- **Discovery**: Uses OPTIONS method for service discovery
- **State**: Implements state persistence and transfer mechanisms
- **Formats**: Supports JSON, form, multipart, text, and binary formats

## Testing

The package includes comprehensive tests:

```bash
# Run all tests
pytest tests/

# Run specific test file
pytest tests/client/test_base.py

# Run with coverage
pytest tests/ --cov=polyflux.http
```

## Development

This package is part of the Polyflux ecosystem and follows the Protocol-first architecture defined in the core package.

## License

MIT License