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

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

archapi-1.0.0.tar.gz (94.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

archapi-1.0.0-py3-none-any.whl (75.4 kB view details)

Uploaded Python 3

File details

Details for the file archapi-1.0.0.tar.gz.

File metadata

  • Download URL: archapi-1.0.0.tar.gz
  • Upload date:
  • Size: 94.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.9

File hashes

Hashes for archapi-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f1cacbc3a0d14b9b3c398047ae0847d5f43c1d4ac8103a6e7313e1b91adf11ec
MD5 fc225c274a86f713923c5daef050eb1c
BLAKE2b-256 6df7606c95aba8942ff6eaec7390a92fdd5144b357563abd908c49285ddea22c

See more details on using hashes here.

File details

Details for the file archapi-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: archapi-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 75.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.9

File hashes

Hashes for archapi-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a8eadc53e3944d63a1df273f0e10cd1648f85e9bfce155e54c11a07a7694a046
MD5 ddf184e9e29d961daacb976b6e34a2ad
BLAKE2b-256 e2b5bbfda76bb281a74666b9f91ad1d925a569c30383c16a2b94e28c4e8586bf

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

0.5.0

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

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