<div align="center">
<img src="https://raw.githubusercontent.com/zerlok/gendalf/main/docs/gendalf-logo.svg" alt="Gendalf Logo" width="600">

[![Latest Version](https://img.shields.io/pypi/v/gendalf.svg)](https://pypi.python.org/pypi/gendalf) [![Python Supported Versions](https://img.shields.io/pypi/pyversions/gendalf.svg)](https://pypi.python.org/pypi/gendalf) [![MyPy Strict](https://img.shields.io/badge/mypy-strict-blue)](https://mypy.readthedocs.io/en/stable/getting_started.html#strict-mode-and-configuration) [![Test Coverage](https://codecov.io/gh/zerlok/gendalf/branch/main/graph/badge.svg)](https://codecov.io/gh/zerlok/gendalf) [![Downloads](https://img.shields.io/pypi/dm/gendalf.svg)](https://pypistats.org/packages/gendalf) [![GitHub stars](https://img.shields.io/github/stars/zerlok/gendalf)](https://github.com/zerlok/gendalf/stargazers)

*You shall pass... your code to adapters!*
</div>

---

**Gendalf** is a code-first generator for Python adapters.

It generates **type-safe transport and persistence layers** directly from existing Python code and SQL files —
without requiring OpenAPI, Protobuf, AsyncAPI, or ORMs.

Your code is the source of truth.  
Gendalf generates the glue.

---

# Key ideas

* **Code-first**
    * Adapters are generated from Python modules and SQL files
    * No external specs to write or maintain

* **Deterministic**
    * Gendalf uses a deterministic, AST-based algorithm to analyze code and generate adapters
    * It does not use LLMs or any probabilistic generation
    * Given the same inputs, the output is always identical

* **Adapter-oriented**
    * Transport adapters: FastAPI servers, HTTP clients, gRPC, WebSockets
    * Persistence adapters: SQL → typed Python APIs
    * Boundary code only — business logic remains untouched

* **Type-safe**
    * Python types propagate across generated code
    * SQL queries produce typed inputs and outputs

* **Minimal opt-in**
    * Use standard Python type annotations
    * Mark Python classes intended as entrypoints with `@entrypoint`
    * Add `-- sqlcast` markers to SQL files
    * Everything else is inferred

---

# Why Gendalf

Most code generators require you to:

* write specs first,
* duplicate models,
* adopt specific frameworks or ORMs.

LLM-based code generation introduces other problems:

* non-deterministic output,
* mandatory manual review,
* runtime cost and token usage.

Gendalf does the opposite:

* Python code defines the contract,
* SQL defines persistence,
* adapters and DTOs are generated by explicit algorithms
  (type inspection and AST traversal).

Generated code can be committed, regenerated in CI, and treated as compiler output.

---

# Transports

## FastAPI & HTTPX

Run with `gendalf src cast fastapi`.

Supported patterns:

- request-response (POST, JSON body)
- duplex streaming (WebSocket, JSON frames)

### Generated code

* `src/api/fastapi/models.py` — Pydantic request/response models
* `src/api/fastapi/client.py` — async typed HTTP client
* `src/api/fastapi/server.py` — server handlers with serialization and domain invocation

Generated code is complete and requires no manual edits.

## Aiohttp

Run with `gendalf src cast aiohttp`.

Supported patterns:

- request-response (POST, JSON body)
- duplex streaming (WebSocket, JSON frames)

### Generated code

* `src/api/aiohttp/models.py`
* `src/api/aiohttp/client.py`
* `src/api/aiohttp/server.py`

### Examples

- [my greeter](https://raw.githubusercontent.com/zerlok/gendalf/main/examples/my_greeter)

## gRPC (planned)

Not supported yet.

Planned:

- unary-unary
- unary-stream
- stream-unary
- stream-stream

---

# Persistence

## SQL

**WIP:** Generate type-safe Python APIs directly from SQL files — no ORM required.
