Skip to main content

ArchAPI

ArchAPI is a Python library and CLI for architecture-preserving REST API generation.

Instead of generating API code from a generic template or an LLM's default style, ArchAPI studies your existing backend project first — its framework, folder conventions, naming style, authentication and validation patterns — and generates new API layers that match it. Generation is a dry-run preview by default; nothing is written to disk unless you explicitly ask for it.

Two generation modes:

  • Deterministic — rule-based templates, works fully offline.
  • LLM-assisted (--llm) — an LLM writes the code, guided by an architecture-aware retrieval pipeline that selects and shows the model the repository examples most relevant to your specific request (not arbitrary or first-found files) — see Architecture.

Dedicated framework support: Express TypeScript, FastAPI, Flask, Django REST Framework, NestJS (anything else falls back to a generic, lower-confidence adapter).

Current version: 1.0.0 (see Development Status)

Installation from PyPI

python -m pip install archapi

To use LLM-first generation mode, install the optional openai extra:

python -m pip install "archapi[openai]"

Verify:

python -c "from archapi import ArchAPI; print('ArchAPI import works')"

Run from GitHub Source

git clone https://github.com/rohith5005/archapi.git
cd archapi

python3 -m venv .venv
source .venv/bin/activate

python -m pip install --upgrade pip setuptools wheel
python -m pip install -e .

Verify:

python -c "from archapi import ArchAPI; print('GitHub source install worked')"

Run Tests

python -m compileall archapi evaluation
python -m unittest discover -s tests -v

Or:

./scripts/run_tests.sh

Expected result:

Ran 231 tests

OK

No OPENAI_API_KEY is required — the full suite never makes a real network call.

Quickstart

pip install archapi

archapi scan .
archapi plan . "Create authenticated POST API for warranty claim"

# dry-run by default
archapi generate . "Create authenticated POST API for warranty claim"

# LLM-assisted, still dry-run -- retrieval selects the repository examples
# most relevant to this request (see docs/ARCHITECTURE.md)
archapi generate . "Create authenticated POST API for warranty claim" --llm

# explicit mutation -- always opt-in
archapi generate . "Create authenticated POST API for warranty claim" --llm --apply

Full CLI reference (all commands, flags, exit codes): docs/CLI.md.

Basic Usage (Python API)

from archapi import ArchAPI

engine = ArchAPI("./sample_projects/express_basic")

result = engine.generate_api(
    "Create GET API for invoice",
    dry_run=True,
)

print(result.plan)
print(result.validation_report)
print(result.diff)

Command-Line Interface

archapi detect ./sample_projects/express_basic
archapi scan ./sample_projects/express_basic
archapi plan ./sample_projects/express_basic "Create GET API for shipment status"
archapi generate ./sample_projects/express_basic "Create GET API for shipment status"

# Architecture-aware LLM generation instead of deterministic templates
archapi generate ./sample_projects/express_basic "Create GET API for shipment status" --llm

# Write files to disk instead of a dry run -- always opt-in, always explicit
archapi generate ./sample_projects/express_basic "Create GET API for shipment status" --llm --apply

# Machine-readable output for CI/tooling (any command)
archapi generate ./sample_projects/express_basic "Create GET API for shipment status" --json

generate is a dry-run preview by default; nothing is written to disk unless --apply is passed. Exit codes are stable and documented: 0 success, 1 generation/validation rejected, 2 invalid CLI usage or configuration, 3 LLM provider failure. Pass --debug for full tracebacks on unexpected errors; without it, errors are concise and never include credentials.

Configuration

Settings resolve with precedence: explicit CLI flag > project archapi.toml

environment variable > built-in default (full detail: docs/CONFIGURATION.md). Optional project-local archapi.toml:

[archapi]
use_llm = true
strict_validation = false

[archapi.llm]
provider = "openai"
model = "gpt-4o-mini"

[archapi.retrieval]
max_chars = 12000
routes = 2
services = 2
schemas = 2
tests = 2

API keys are never read from archapi.toml (ArchAPI refuses to load a config file containing a key-, secret-, token-, password-, or credential-like key) -- only from the OPENAI_API_KEY environment variable. Equivalent environment variables exist for every field (e.g. ARCHAPI_USE_LLM, ARCHAPI_LLM_MODEL, ARCHAPI_ROUTES_LIMIT) -- see archapi/config.py.

LLM-First Generation (optional)

With the openai extra installed and OPENAI_API_KEY set, ArchAPI can use an LLM to generate architecture-matching code instead of the deterministic templates. See LLM Usage Guide for the full walkthrough.

from archapi import ArchAPI

engine = ArchAPI(
    "./sample_projects/express_basic",
    use_llm=True,
    llm_model="gpt-4o-mini",
)

result = engine.generate_api(
    "Create authenticated POST API for warranty claim",
    dry_run=True,
)

print(result.plan)
print(result.validation_report)

Deterministic generation (use_llm=False, the default) does not require the openai package and works fully offline.

How architecture-aware retrieval works

On the LLM path, ArchAPI doesn't send the model arbitrary or first-found repository files. It indexes the project, scores every candidate file against the specific request (resource, HTTP method, whether auth/validation was asked for), and sends a budgeted set of the highest-relevance examples — a route or two, a service, a schema, an auth example only if authentication was requested, a test — labeled so the model knows what each one demonstrates. See docs/ARCHITECTURE.md for the full pipeline and docs/RESEARCH_REPORT.md for the evidence this actually changes what gets generated.

Safety mechanisms

Dry-run by default, atomic multi-file application with automatic rollback on partial failure, path-traversal/absolute-path rejection, project-root containment, protected-file/bootstrap-file controls, generated-secret detection, framework validation, and context redaction before any content leaves the machine. No --skip-safety-style bypass exists. Full detail: docs/SECURITY_MEASURES.md.

Express TypeScript Example

from pathlib import Path
from archapi import ArchAPI

project = Path("express_basic")

(project / "src/routes").mkdir(parents=True, exist_ok=True)
(project / "src/controllers").mkdir(parents=True, exist_ok=True)
(project / "src/services").mkdir(parents=True, exist_ok=True)
(project / "src/schemas").mkdir(parents=True, exist_ok=True)
(project / "tests").mkdir(parents=True, exist_ok=True)

(project / "package.json").write_text(
    '{"dependencies": {"express": "^4.18.0", "zod": "^3.0.0"}}'
)

(project / "src/routes/user.routes.ts").write_text(
    'import { Router } from "express";\n'
    'const router = Router();\n'
    'export default router;\n'
)

(project / "src/controllers/user.controller.ts").write_text(
    'export const userController = {};\n'
)

(project / "src/services/user.service.ts").write_text(
    'export const userService = {};\n'
)

(project / "src/schemas/user.schema.ts").write_text(
    'import { z } from "zod";\n'
)

(project / "tests/user.test.ts").write_text(
    'describe("user", () => { it("works", () => expect(true).toBe(true)); });\n'
)

engine = ArchAPI(str(project))
result = engine.generate_api("Create GET API for user order history", dry_run=True)

print("Detected framework:", engine.detect_framework().framework)
print("Generated method:", result.plan.method)
print("Generated path:", result.plan.path)
print("Generated files:", [str(file.path) for file in result.files])

Expected output includes:

Detected framework: express-typescript
Generated method: GET
Generated path: /users/{user_id}/orders

FastAPI Example

from pathlib import Path
from archapi import ArchAPI

project = Path("fastapi_basic")

(project / "app/routers").mkdir(parents=True, exist_ok=True)
(project / "app/services").mkdir(parents=True, exist_ok=True)
(project / "app/schemas").mkdir(parents=True, exist_ok=True)
(project / "tests").mkdir(parents=True, exist_ok=True)

(project / "requirements.txt").write_text("fastapi\npydantic\npytest\n")

(project / "app/routers/user_router.py").write_text(
    "from fastapi import APIRouter\n"
    "router = APIRouter()\n"
)

(project / "app/services/user_service.py").write_text(
    "class UserService:\n"
    "    pass\n\n"
    "user_service = UserService()\n"
)

(project / "app/schemas/user_schema.py").write_text(
    "from pydantic import BaseModel\n\n"
    "class UserResponse(BaseModel):\n"
    "    id: str\n"
)

(project / "tests/test_user.py").write_text(
    "def test_user_placeholder():\n"
    "    assert True\n"
)

engine = ArchAPI(str(project))
result = engine.generate_api("Create POST API for product review", dry_run=True)

print("Detected framework:", engine.detect_framework().framework)
print("Generated method:", result.plan.method)
print("Generated path:", result.plan.path)
print("Generated files:", [str(file.path) for file in result.files])

Expected output includes:

Detected framework: fastapi
Generated method: POST
Generated path: /products/{product_id}/reviews

Documentation

Contributors

Metadata

Release files for archapi 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for archapi 1.0.0
File Size Uploaded Provenance Actions
archapi-1.0.0.tar.gz 94.7 kB Without provenance Details for archapi-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for archapi 1.0.0
File Interpreter ABI Platform Actions
archapi-1.0.0-py3-none-any.whl Python 3 none any Details for archapi-1.0.0-py3-none-any.whl

Total release size: 170.0 kB

Release files / archapi-1.0.0.tar.gz

Download URL archapi-1.0.0.tar.gz
Size 94.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f1cacbc3a0d14b9b3c398047ae0847d5f43c1d4ac8103a6e7313e1b91adf11ec
BLAKE2b-256 checksum
How to use checksums
6df7606c95aba8942ff6eaec7390a92fdd5144b357563abd908c49285ddea22c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release files / archapi-1.0.0-py3-none-any.whl

Download URL archapi-1.0.0-py3-none-any.whl
Size 75.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8eadc53e3944d63a1df273f0e10cd1648f85e9bfce155e54c11a07a7694a046
BLAKE2b-256 checksum
How to use checksums
e2b5bbfda76bb281a74666b9f91ad1d925a569c30383c16a2b94e28c4e8586bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Security for archapi 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page