Metadata-Version: 2.5
Name: fastconnect
Version: 1.0.0
Summary: FastAPI power with dramatically less boilerplate.
Author: FastConnect Contributors
License-Expression: MIT
License-File: LICENSE
Keywords: api,fastapi,framework,rest,web
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: fastapi>=0.100.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: uvicorn>=0.20.0
Provides-Extra: db
Requires-Dist: aiosqlite>=0.17.0; extra == 'db'
Requires-Dist: sqlalchemy[asyncio]>=2.0.0; extra == 'db'
Provides-Extra: dev
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# FastConnect

**FastAPI power with dramatically less boilerplate.**

FastConnect is a developer-friendly abstraction layer built on top of [FastAPI](https://fastapi.tiangolo.com/).  It removes repetitive setup and infrastructure code while preserving full access to the underlying FastAPI ecosystem.

FastConnect does **not** reimplement FastAPI, Starlette, Pydantic, or Uvicorn.  It uses them internally and gives you a simpler surface API.

---

## Installation

```bash
pip install fastconnect
```

With database support:

```bash
pip install fastconnect[db]
```

---

## 30-Second Hello World

```python
from fastconnect import FastConnect

app = FastConnect()

@app.get("/hello")
def hello():
    return {"message": "Hello FastConnect!"}

app.run()
```

Visit `http://127.0.0.1:8000/hello` — done.

Swagger docs are automatically available at `/docs`.

---

## GET Example

```python
@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"id": user_id}
```

Path parameters are extracted from `{param}` in the route.  Query parameters work naturally:

```python
@app.get("/search")
def search(q: str, limit: int = 10):
    return {"query": q, "limit": limit}
```

---

## POST Example — Automatic Validation

```python
@app.post("/users")
def create_user(name: str, age: int):
    return {"name": name, "age": age}
```

FastConnect inspects your function signature and **automatically generates a Pydantic request model**.  The endpoint accepts a JSON body:

```bash
curl -X POST http://localhost:8000/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "age": 30}'
```

Invalid data is rejected with a structured 422 response:

```json
{
  "success": false,
  "error": {
    "type": "ValidationError",
    "message": "Invalid request",
    "details": [...]
  }
}
```

### Parameter Rules

| HTTP Method | Non-path parameters become… |
|---|---|
| GET, DELETE | Query parameters |
| POST, PUT, PATCH | JSON body if multiple; query parameter if single |

Path parameters (e.g. `{user_id}`) are always extracted from the URL.

### Using Explicit Pydantic Models

You can always use your own Pydantic models — FastConnect will not override them:

```python
from pydantic import BaseModel

class UserCreate(BaseModel):
    name: str
    age: int
    email: str

@app.post("/users")
def create_user(user: UserCreate):
    return user.model_dump()
```

---

## Async Example

Both sync and async handlers work out of the box:

```python
@app.get("/sync")
def sync_endpoint():
    return {"mode": "sync"}

@app.get("/async")
async def async_endpoint():
    return {"mode": "async"}
```

No configuration needed.  FastAPI/Starlette handles the execution model.

---

## Frontend Serving

Serve static files alongside your API:

```python
app = FastConnect(frontend="./static")
```

If the directory contains an `index.html`, it's served at `/`.  All static files are available at `/static/`.

For a single HTML file:

```python
app = FastConnect(frontend="./index.html")
```

---

## Database Example

```python
from sqlalchemy import text
from fastconnect import FastConnect

app = FastConnect(database="sqlite:///app.db")

@app.get("/setup")
def setup():
    with app.db.session() as session:
        session.execute(text(
            "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)"
        ))
        session.commit()
    return {"ok": True}

@app.post("/items")
def create_item(name: str):
    with app.db.session() as session:
        session.execute(text("INSERT INTO items (name) VALUES (:name)"), {"name": name})
        session.commit()
    return {"created": name}

@app.get("/items")
def list_items():
    with app.db.session() as session:
        rows = session.execute(text("SELECT id, name FROM items")).fetchall()
        return [{"id": r[0], "name": r[1]} for r in rows]
```

Database connections are managed automatically (startup/shutdown lifecycle). The database URL can also be set via the `DATABASE_URL` environment variable.

### Async Databases

FastConnect supports fully async databases (e.g., `postgresql+asyncpg://` or `sqlite+aiosqlite://`). Use `async_session()` for async transactions:

```python
@app.get("/async_items")
async def get_async_items():
    async with app.db.async_session() as session:
        result = await session.execute(text("SELECT * FROM items"))
        return [{"id": r[0], "name": r[1]} for r in result.fetchall()]
```

---

## Configuration

```python
app = FastConnect(
    title="My API",           # OpenAPI title
    version="1.0.0",          # OpenAPI version
    cors=["http://localhost:3000"],  # CORS origins
    database="sqlite:///app.db",     # Database URL
    frontend="./static",             # Static file directory
    debug=True,                      # Verbose error responses
)
```

All parameters are optional.  Expensive resources (database) are only initialized when configured.

### CORS

```python
# Simple
app = FastConnect(cors=["http://localhost:3000"])

# Fine-grained
app = FastConnect(cors={
    "origins": ["http://localhost:3000"],
    "methods": ["GET", "POST"],
    "headers": ["Authorization"],
    "credentials": True,
})
```

Wildcard `*` origins are rejected in production (non-debug) mode.

---

## FastAPI Interoperability

FastConnect exposes the full FastAPI instance via `app.fastapi`:

```python
# Add FastAPI middleware
from starlette.middleware.trustedhost import TrustedHostMiddleware
app.fastapi.add_middleware(TrustedHostMiddleware, allowed_hosts=["example.com"])

# Use FastAPI dependencies
from fastapi import Depends
app.fastapi.include_router(some_router)

# Custom exception handlers
@app.exception_handler(MyError)
async def handle_my_error(request, exc):
    ...
```

Everything in the FastAPI ecosystem works.  FastConnect simplifies FastAPI — it doesn't cripple it.

---

## CLI

```bash
# Scaffold a new project
fastconnect init myapp

# Run the app
fastconnect run

# Run with auto-reload (development)
fastconnect dev
```

---

## Security

FastConnect provides secure defaults, not guaranteed security:

- **CORS**: Disabled by default; wildcard rejected in production
- **Error responses**: Stack traces hidden in production
- **Database**: Parameterized queries via SQLAlchemy
- **Static files**: Path traversal prevented by Starlette

For additional security, use the hooks in `fastconnect.security`:

```python
from fastconnect.security import add_security_headers, add_trusted_hosts

add_security_headers(app.fastapi)
add_trusted_hosts(app.fastapi, ["example.com"])
```

---

## Limitations

- FastConnect v1.0 is an abstraction layer, not a replacement for FastAPI
- No built-in authentication system (use FastAPI's auth tools)
- The CLI is minimal — use Uvicorn/Gunicorn directly for production deployment

---

## Development Setup

```bash
cd fastconnect
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,db]"
```

---

## Testing

```bash
pytest tests/ -v
```

Tests cover: initialization, all HTTP methods, path/query params, automatic body parsing, type validation, Pydantic v2 compatibility, sync/async, error handling, CORS, database lifecycle, frontend serving, and OpenAPI generation.

---

## Contributing

1. Fork the repository
2. Create a feature branch
3. Write tests for new functionality
4. Ensure all tests pass: `pytest tests/ -v`
5. Submit a pull request

---

## License

MIT
