Metadata-Version: 2.5
Name: PyArch-CLI
Version: 0.2.1
Summary: Stateful CLI generator for Layered FastAPI projects
Project-URL: Homepage, https://github.com/Allcode-1/PyArch
Project-URL: Repository, https://github.com/Allcode-1/PyArch
Project-URL: Issues, https://github.com/Allcode-1/PyArch/issues
License-Expression: MIT
License-File: LICENSE
Keywords: cli,fastapi,generator,jinja2,sqlalchemy,typer
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.13
Requires-Dist: cryptography>=46.0.3
Requires-Dist: jinja2>=3.1.6
Requires-Dist: mypy>=2.3.0
Requires-Dist: rich>=15.0.0
Requires-Dist: ruff>=0.16.1
Requires-Dist: tomlkit>=0.15.0
Requires-Dist: typer>=0.24.2
Description-Content-Type: text/markdown

# PyArch

[![PyPI](https://img.shields.io/pypi/v/PyArch-CLI)](https://pypi.org/project/PyArch-CLI/)
![Python](https://img.shields.io/badge/Python-3.13%2B-blue)
![FastAPI](https://img.shields.io/badge/FastAPI-backend-green)
![Typer](https://img.shields.io/badge/Typer-CLI-purple)
![Jinja2](https://img.shields.io/badge/Jinja2-templates-orange)
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
![Status](https://img.shields.io/badge/status-v0.2.1-blue)

PyArch is a CLI for creating and extending Layered FastAPI projects. It sets up
the application structure, database, tests and Alembic, then lets you add CRUD
modules and integrations without wiring every file by hand.

Unlike a one-time project template, PyArch keeps a small manifest in the
generated project. Later commands use it to understand the project and update
the right files.

<p align="center">
  <img src="./assets/pyarch-demo.gif" alt="PyArch CLI demo" width="900">
</p>

## Why PyArch?

PyArch removes repetitive setup while keeping the generated code readable and
ready to change.

- Layered FastAPI project structure
- PostgreSQL and SQLite support
- Complete CRUD modules with models, schemas, repositories, services and routes
- GitHub Actions workflow for generated-project linting and tests
- Automatic model and router registration
- JWT auth integration with generated RSA keys
- Protected CRUD routes
- Alembic setup for relational databases
- Tests and dependency setup through `uv`
- Project-aware generation through `pyarch.toml`
- Atomic project creation and rollback for failed extensions

## v0.2.1 Highlights

- Atomic project creation through a staging directory, with cleanup on failure
- Rollback for failed module and auth generation
- Docker Compose support for PostgreSQL projects
- Refresh-token rotation protected against concurrent reuse on PostgreSQL
- Self-tests for PyArch and an end-to-end generated-project workflow

## Quick Start

PyArch requires Python 3.13 or newer and
[`uv`](https://docs.astral.sh/uv/).

Install the latest release from PyPI:

```bash
pip install pyarch-cli
```

Create a project and move into it:

```bash
pyarch init my_project --database postgres
cd my_project
```

Copy `.env.example` to `.env` and set the database connection values. For a
PostgreSQL project, initialize the database schema before starting the app:

```bash
pyarch db init
```

Start the generated application:

```bash
docker compose up -d
```

After a model change in a PostgreSQL project, generate and apply a reviewed
revision and restart the application with:

```bash
pyarch db upgrade --message "describe schema change"
```

Without `--message`, PyArch prompts for one. When Alembic finds no metadata
changes, `db upgrade` restarts Compose but creates no empty revision. Compose
never runs migrations implicitly; migration files remain source code and should
be reviewed and committed.

## Safe Generation

`pyarch init` builds the project in a staging directory and publishes it only
after all generation steps complete. If setup fails, the staging directory is
removed. `generate module` and `add integration` track every affected file and
restore the previous state if a generation step fails, including the manifest
and dependency files.

Open `http://127.0.0.1:8000/docs` to use the generated Swagger UI.

You can now extend the project:

```bash
pyarch generate module user
pyarch add integration auth
pyarch generate module task --protected
pyarch info
```

Module names must be singular identifiers. PyArch derives the plural table and
route names from them: use `user` to generate `/users` and the `users` table,
not `users`.

## What Gets Generated

A new project includes the application layers, database configuration, test
setup and the files needed to run FastAPI:

```text
my_project/
├── app/
│   ├── api/v1/
│   ├── core/
│   ├── db/
│   ├── dependencies/
│   ├── models/
│   ├── repositories/
│   ├── schemas/
│   ├── services/
│   └── main.py
├── tests/
├── alembic/          # PostgreSQL and SQLite only
├── .env.example
├── pyarch.toml
└── pyproject.toml
```

Each generated CRUD module adds:

- a database model;
- create, update and response schemas;
- repository and service classes;
- list, get, create, update and delete routes;
- CRUD tests;
- model and router registration in the existing application.

## Commands

| Command                                     | Description                                      |
| ------------------------------------------- | ------------------------------------------------ |
| `pyarch init <name>`                        | Create a Layered FastAPI project                 |
| `pyarch init <name> --database <engine>`    | Select PostgreSQL or SQLite                      |
| `pyarch generate module <singular-name>`    | Add a CRUD module to the current project         |
| `pyarch add integration auth`               | Add JWT authentication and user management       |
| `pyarch generate module <singular-name> --protected` | Generate protected CRUD routes           |
| `pyarch info`                               | Show the current project configuration           |
| `pyarch --help`                             | Show CLI help                                    |

Generation commands must be run inside a project created by PyArch.

## Databases and Current Limitations

| Database   | CRUD modules | Alembic | Auth integration | Protected modules |
| ---------- | ------------ | ------- | ---------------- | ----------------- |
| PostgreSQL | Yes          | Yes     | Yes              | Yes               |
| SQLite     | Yes          | Yes     | Yes              | Yes               |

Current limitations:

- only Layered Architecture is supported;
- generated applications use synchronous database access;
- SQLite projects run locally and do not include Docker Compose; `pyarch db`
  lifecycle commands are PostgreSQL-only. SQLite migrations can be run with
  Alembic directly;
- generated projects are starter scaffolds and still require
  application-specific configuration and code;
- the manifest format may change before a stable release.

## Project Manifest

Every generated project contains `pyarch.toml`. It records the selected
architecture and database, generated modules, enabled integrations and known
project paths.

Commands such as `generate module`, `add integration` and `info` read this file
instead of trying to infer project state from the directory structure. PyArch
updates the manifest after a successful generation step.

## Development

Clone the repository and install the development environment:

```bash
git clone https://github.com/Allcode-1/PyArch.git
cd PyArch
uv sync --group dev
```

Run the CLI from the checkout:

```bash
uv run pyarch --help
```

Or install the current checkout as an editable CLI tool:

```bash
uv tool install --editable .
```

Run the project checks before opening a pull request or releasing a version:

```bash
uv run pytest
uv run ruff check src tests
uv run mypy src tests
uv build
```

## Architecture and Design

<details>
<summary>How PyArch is structured</summary>

```text
Typer CLI
    ↓
Application services
    ↓
Generators
    ↓
Jinja2 templates
    ↓
Generated FastAPI project
    ↑
pyarch.toml
```

The CLI handles user input and delegates work to application services.
Generators render Jinja2 templates and update files at explicit registration
markers. The manifest provides the project context needed by later commands.

</details>

<details>
<summary>Why use a manifest?</summary>

Scanning the filesystem shows which files exist, but not which project choices
produced them. The manifest stores those choices directly, so later commands do
not have to guess the architecture, database or enabled features.

</details>

<details>
<summary>Why marker-based registration?</summary>

PyArch modifies files it generated itself. Explicit markers provide stable and
readable insertion points for model and router imports without requiring a full
AST rewriting pipeline.

</details>

<details>
<summary>Why Jinja2?</summary>

Templates stay close to the Python code users receive and can edit. Jinja2 is
used with `StrictUndefined`, so missing template context fails during generation
instead of producing incomplete files.

</details>

## Roadmap

### v0.2.1 (current)

- singular module-name contract and corrected SQLite workflow documentation;
- generated GitHub Actions workflow for linting and tests;
- package and generated-manifest versions kept in sync.

### v0.2.0

- atomic project creation and cleanup on failure;
- rollback for failed module and auth generation;
- PostgreSQL Compose template and SQLite local setup;
- self-test suite and generated-project integration coverage.

### v0.3

- Redis integration foundation;
- opt-in cache-aside generation for CRUD modules;
- dry-run mode.

### Later

- scheduler integration;
- more architectures;
- plugin system;
- asynchronous database access.

## Status

PyArch v0.2.1 is an early alpha release. The main workflow is usable, but
commands, templates, generated code and the manifest may still change before a
stable release.
