Metadata-Version: 2.4
Name: zerohttp
Version: 0.0.1
Summary: A HTTP client library
Author-email: Björn Benouarets <bjoern@benouarets.de>
License-Expression: MIT
Project-URL: Homepage, https://github.com/SecNex/zerohttp
Project-URL: Issues, https://github.com/SecNex/zerohttp/issues
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# ZeroHTTP

ZeroHTTP is a lightweight HTTP client library for Python that provides various authentication methods and OAuth2 flows for Microsoft Entra (Azure AD).

## Features

- Simple HTTP requests (GET, POST)
- Support for Basic and Bearer Authentication
- OAuth2 integration for Microsoft Entra ID
- Interactive authentication flows
- Client certificate authentication
- Local callback servers for OAuth2
- JSON and form data support
- Minimal dependencies

## Installation

```bash
pip install zerohttp
```

Or for development:

```bash
git clone https://github.com/SecNex/zerohttp.git
cd zerohttp
pip install -e .
```

## Quick Start

### Basic HTTP Requests

```python
from zerohttp import HTTPClient

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

# GET request with parameters
response = client.get("/users", params=[("page", "1"), ("limit", "10")])
data = response.json()

# POST request with JSON data
response = client.post("/users", data={
    "name": "John Doe",
    "email": "john@example.com"
})
result = response.json()
```

### Basic Authentication

```python
from zerohttp import HTTPClient
from zerohttp.auth import BasicAuthentication

# Create Basic Authentication
auth = BasicAuthentication("username", "password")

# Client with authentication
client = HTTPClient(auth=auth, base_url="https://api.example.com")

# Request will automatically include Authorization header
response = client.get("/protected-endpoint")
```

### Bearer Token Authentication

```python
from zerohttp import HTTPClient
from zerohttp.auth import BearerAuthentication

# Create Bearer Token
auth = BearerAuthentication("your-access-token-here")

# Client with Bearer Authentication
client = HTTPClient(auth=auth, base_url="https://api.example.com")

response = client.get("/api/data")
```

## Microsoft Entra Integration

### Interactive User Authentication

```python
from zerohttp.providers import Entra
from zerohttp import HTTPClient

# Entra Provider for interactive user authentication
entra = Entra(
    tenant="your-tenant-id",
    client=("client-id", "client-secret"),
    scope="https://graph.microsoft.com/.default"
)

# Perform authentication (opens browser)
auth = entra.authenticate()

# Create client with authenticated token
client = HTTPClient(auth=auth)

# Make requests to Microsoft Graph API
response = client.get("https://graph.microsoft.com/v1.0/me")
user_data = response.json()
```

### Application Authentication (Client Credentials)

```python
from zerohttp.providers import EntraApp
from zerohttp import HTTPClient

# Entra App for Client Credentials Flow
app = EntraApp(
    tenant="your-tenant-id",
    client=("client-id", "client-secret"),
    scope="https://graph.microsoft.com/.default"
)

# Authentication without user interaction
auth = app.authenticate()

# Client for application requests
client = HTTPClient(auth=auth)

response = client.get("https://graph.microsoft.com/v1.0/users")
```

## Advanced Usage

### Custom Headers

```python
from zerohttp import HTTPClient

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

# Set individual header
client.set_header("User-Agent", "MyApp/1.0")

# Set multiple headers at once
client.set_headers({
    "Content-Type": "application/json",
    "Accept": "application/json",
    "X-API-Key": "your-api-key"
})
```

### URL Parameter Handling

```python
from zerohttp import HTTPClient

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

# GET with complex parameters
response = client.get("/search", params=[
    ("q", "python"),
    ("sort", "stars"),
    ("order", "desc"),
    ("per_page", "10")
])
```

### URL Generation

```python
from zerohttp import HTTPClient

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

# Generate URL without making request
url = client.link("/users", params=[("page", "2"), ("limit", "20")])
# Result: "https://api.example.com/users?page=2&limit=20"
```

### Browser Integration

```python
from zerohttp import HTTPClient

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

# Open link in browser
client.webbrowser("/login", params=[
    ("redirect_uri", "http://localhost:8000/callback"),
    ("response_type", "code")
])
```

## API Reference

### HTTPClient

Main class for HTTP requests.

**Constructor:**
```python
HTTPClient(auth=None, proxy="", base_url="")
```

**Methods:**
- `get(url="", params=[])` - Send GET request
- `post(url="", data={}, params=[])` - Send POST request
- `set_header(key, value)` - Set individual header
- `set_headers(headers)` - Set multiple headers
- `get_header(key)` - Get header value
- `get_headers()` - Get all headers
- `link(url="", params=[])` - Generate URL
- `webbrowser(url="", params=[])` - Open URL in browser

### Response

Wrapper for HTTP responses.

**Methods:**
- `json()` - Parse response as JSON dictionary
- `text` - Response text as string

### Authentication Classes

#### BasicAuthentication
```python
BasicAuthentication(username: str, password: str)
```

#### BearerAuthentication
```python
BearerAuthentication(token: str)
```

### Entra Provider

#### Entra (Interactive User Authentication)
```python
Entra(
    tenant: str,
    client: tuple,  # (client_id, client_secret)
    scope: str,
    token_url: str = "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
    authorization_url: str = "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize",
    open: bool = True
)
```

#### EntraApp (Application Authentication)
```python
EntraApp(
    tenant: str,
    client: tuple,  # (client_id, client_secret)
    scope: str = "https://graph.microsoft.com/.default",
    token_url: str = ""
)
```

## Error Handling

ZeroHTTP propagates HTTP errors and prints response contexts:

```python
from zerohttp import HTTPClient
import urllib.error

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

try:
    response = client.get("/nonexistent-endpoint")
except urllib.error.HTTPError as e:
    print(f"HTTP Error: {e.code}")
    # Response is automatically printed
except Exception as e:
    print(f"Other error: {e}")
```

## OAuth2 Flow Details

The interactive OAuth2 flow works as follows:

1. **Local Server**: An HTTP server is started on `localhost:8000`
2. **Browser Authentication**: User is redirected to Microsoft login page
3. **Callback**: After successful login, user is redirected to local server
4. **Token Exchange**: Authorization code is exchanged for access token
5. **Server Shutdown**: Local server is automatically shutdown

## Development

### Project Structure

```
zerohttp/
├── src/zerohttp/
│   ├── __init__.py
│   ├── __main__.py
│   ├── http.py              # HTTPClient and Response
│   ├── auth/                # Authentication classes
│   │   ├── __init__.py
│   │   ├── basic.py
│   │   ├── bearer.py
│   │   └── interactive.py
│   └── providers/           # Provider implementations
│       ├── __init__.py
│       └── entra.py
├── pyproject.toml
├── requirements.txt
└── README.md
```

### Build and Installation

```bash
# Build package
python -m build

# Install in development mode
pip install -e .

# Install dependencies
pip install -r requirements.txt
```

## License

This project is licensed under the MIT License - see [LICENSE](LICENSE) for details.

## Contributing

Contributions are welcome! Please open an issue or pull request.

## Support

For questions and issues, please create a [GitHub Issue](https://github.com/SecNex/zerohttp/issues).
