Metadata-Version: 2.4
Name: forminit
Version: 0.1.0
Summary: Python SDK for Forminit
Project-URL: Homepage, https://forminit.com
Project-URL: Repository, https://github.com/forminit/forminit-python
License-File: LICENSE
Requires-Python: >=3.8
Requires-Dist: httpx>=0.24.0
Requires-Dist: typing-extensions>=4.0.0; python_version < '3.11'
Description-Content-Type: text/markdown

# Forminit Python SDK

A lightweight, Python SDK for submitting forms to [Forminit](https://forminit.com).

## Features

- 🐍 **Pythonic API** - Simple, intuitive interface
- ⚡ **Sync & Async** - Both synchronous and asynchronous clients
- 🔒 **Type Safe** - Full type hints and TypedDict definitions
- 🧪 **Well Tested** - Comprehensive test suite with pytest
- 🚀 **Framework Agnostic** - Works with Flask, FastAPI, Django, or any Python app

## Installation

```bash
pip install forminit
```

## Quick Start

### Synchronous Usage

```python
from forminit import ForminitClient

# Initialize client with your API key
client = ForminitClient(api_key="your-api-key")

# Set user info for tracking (optional)
# Note: Set user info from the client request for accurate tracking
# This ensures proper geolocation and analytics for the actual user
client.set_user_info(
    ip="203.0.113.10",  # Client's IP from X-Forwarded-For or X-Real-IP header
    user_agent="Mozilla/5.0...",  # Client's User-Agent header
    referer="https://example.com",  # Client's Referer header
)

# Submit form data
result = client.submit(
    form_id="your-form-id",
    data={
        "blocks": [
            {"type": "text", "name": "message", "value": "Hello!"},
            {"type": "email", "name": "email", "value": "user@example.com"},
        ]
    },
    tracking={"utmSource": "newsletter", "utmMedium": "email"},
)

if "error" in result:
    print(f"Error: {result['error']['message']}")
else:
    print(f"Success! Submission ID: {result['data']['hashId']}")
    if "redirectUrl" in result:
        print(f"Redirect to: {result['redirectUrl']}")

client.close()
```

### Web Framework Example

When using in web frameworks, always extract client information from the request:

```python
from flask import Flask, request
from forminit import ForminitClient

app = Flask(__name__)

@app.route("/submit", methods=["POST"])
def submit():
    client = ForminitClient(api_key="your-api-key")
    
    # Extract client information from request headers for accurate tracking
    # Note: Use X-Forwarded-For when behind proxies/load balancers
    client_ip = request.headers.get("X-Forwarded-For", request.remote_addr)
    if client_ip and "," in client_ip:
        client_ip = client_ip.split(",")[0].strip()  # Get first IP
    
    client.set_user_info(
        ip=client_ip,
        user_agent=request.headers.get("User-Agent", ""),
        referer=request.headers.get("Referer"),
    )
    
    result = client.submit(
        form_id="your-form-id",
        data=request.form.to_dict(),
    )
    
    client.close()
    return result
```

### Asynchronous Usage

```python
import asyncio
from forminit import AsyncForminitClient


async def main():
    async with AsyncForminitClient(api_key="your-api-key") as client:
        result = await client.submit(
            form_id="your-form-id",
            data={
                "blocks": [
                    {"type": "text", "name": "message", "value": "Hello!"},
                ]
            },
        )

        if "error" in result:
            print(f"Error: {result['error']['message']}")
        else:
            print(f"Success! Submission ID: {result['data']['hashId']}")


asyncio.run(main())
```

### Form-Style Submission

You can also submit flat form data (like from an HTML form):

```python
result = client.submit(
    form_id="your-form-id",
    data={
        "fi-sender-fullName": "John Doe",
        "fi-sender-email": "john@example.com",
        "fi-text-message": "Hello!",
    },
)
```

## Configuration

### Client Options

```python
from forminit import ForminitClient

client = ForminitClient(
    api_key="your-api-key",  # Required for server-side usage
    proxy_url=None,           # Optional: proxy URL for client-side usage
    base_url="https://forminit.com",  # Optional: override base URL
)
```

### Environment Variables

```bash
export FORMINIT_API_KEY="your-api-key"
export FORMINIT_FORM_ID="your-form-id"
```

## Types

The SDK includes comprehensive type definitions:

```python
from forminit.types import (
    FormBlock,
    FormSubmissionData,
    FormResponse,
    TrackingBlock,
    SenderBlock,
    TextBlock,
    # ... and more
)

# Type-safe form building
submission: FormSubmissionData = {
    "blocks": [
        {
            "type": "sender",
            "properties": {
                "email": "user@example.com",
                "firstName": "John",
                "lastName": "Doe",
            },
        },
        {"type": "text", "name": "message", "value": "Hello!"},
    ]
}
```

## Block Types

The SDK supports all Forminit block types:

- `tracking` - UTM and ad tracking parameters
- `sender` - User information (email, name, etc.)
- `text` - Text input
- `number` - Number input
- `email` - Email input
- `url` - URL input
- `phone` - Phone input
- `rating` - Rating input
- `date` - Date input
- `select` - Select/dropdown
- `radio` - Radio button (single selection)
- `checkbox` - Checkbox (multiple selection)
- `file` - File upload
- `country` - Country selection

## Examples

See the `examples/` directory for complete working examples:

- **[Flask](examples/flask/)** - Flask web application
- **[FastAPI](examples/fastapi/)** - FastAPI async application
- **[Django](examples/django/)** - Django web application

### Running Examples

Each example includes its own README with setup instructions.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT
