Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 39 additions & 34 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,51 +1,56 @@
APP_NAME=Specification Generator
ENV=development
DEBUG=False
VERSION=1.0.0
APP_NAME=<app_name>
ENV=<environment>
DEBUG=<debug_true_or_false>
VERSION=<app_version>

HOST=0.0.0.0
PORT=8000
HOST=<host>
PORT=<port>

DATABASE_URL=postgresql://<db_user>:<db_password>@<db_host>:5432/<db_name>?sslmode=disable
SECRET_KEY=<change_me>
ACCESS_TOKEN_EXPIRE_MINUTES=60
ACCESS_TOKEN_MINUTE_IN_SECONDS=60
SECRET_KEY=<secret_key>
ACCESS_TOKEN_EXPIRE_MINUTES=<access_token_expire_minutes>
ACCESS_TOKEN_MINUTE_IN_SECONDS=<access_token_minute_in_seconds>

AUTH_PREFIX=/auth
AUTH_ME_PATH=/me
AUTH_TAG=auth
AUTH_BOOTSTRAP_ENABLED=False
AUTH_BOOTSTRAP_SUPERUSER=True
AUTH_PREFIX=<auth_prefix>
AUTH_ME_PATH=<auth_me_path>
AUTH_TAG=<auth_tag>
AUTH_BOOTSTRAP_ENABLED=<auth_bootstrap_enabled_true_or_false>
AUTH_BOOTSTRAP_SUPERUSER=<auth_bootstrap_superuser_true_or_false>
AUTH_USERNAME=<bootstrap_username>
AUTH_EMAIL=<bootstrap_email>
AUTH_PASSWORD=<bootstrap_password>
AUTH_PASSWORD_HASH=
AUTH_PASSWORD_HASH=<bootstrap_password_hash_or_empty>

ALLOWED_ORIGINS=["*"]
SECURITY_TRUSTED_HOSTS=["*"]
SECURITY_ENABLE_HTTPS_REDIRECT=False
SECURITY_CSP=default-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
SECURITY_REFERRER_POLICY=strict-origin-when-cross-origin
SECURITY_CORS_ALLOW_METHODS=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
SECURITY_CORS_ALLOW_HEADERS=["Authorization", "Content-Type", "Accept", "Origin", "X-Requested-With", "X-Request-ID"]
SECURITY_REQUEST_ID_HEADER=X-Request-ID
SECURITY_LOG_SUSPICIOUS=True
SECURITY_RATE_LIMIT_ENABLED=True
SECURITY_RATE_LIMIT_REQUESTS=120
SECURITY_RATE_LIMIT_WINDOW_SECONDS=60
SECURITY_RATE_LIMIT_PATHS=["/api/v1/auth"]
ALLOWED_ORIGINS=<json_array_allowed_origins>
SECURITY_TRUSTED_HOSTS=<json_array_trusted_hosts>
SECURITY_ENABLE_HTTPS_REDIRECT=<security_enable_https_redirect_true_or_false>
SECURITY_CSP=<security_csp>
SECURITY_REFERRER_POLICY=<security_referrer_policy>
SECURITY_CORS_ALLOW_METHODS=<json_array_cors_methods>
SECURITY_CORS_ALLOW_HEADERS=<json_array_cors_headers>
SECURITY_REQUEST_ID_HEADER=<security_request_id_header>
SECURITY_LOG_SUSPICIOUS=<security_log_suspicious_true_or_false>
SECURITY_RATE_LIMIT_ENABLED=<security_rate_limit_enabled_true_or_false>
SECURITY_RATE_LIMIT_REQUESTS=<security_rate_limit_requests>
SECURITY_RATE_LIMIT_WINDOW_SECONDS=<security_rate_limit_window_seconds>
SECURITY_RATE_LIMIT_PATHS=<json_array_rate_limit_paths>

OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=mistral
OLLAMA_TIMEOUT=120
OLLAMA_SYSTEM_PROMPT=You are a helpful assistant that generates software specifications.
OLLAMA_BASE_URL=<ollama_base_url>
OLLAMA_MODEL=<ollama_model>
OLLAMA_TIMEOUT=<ollama_timeout_seconds>
OLLAMA_CONNECT_TIMEOUT=<ollama_connect_timeout_seconds>
OLLAMA_MAX_RETRIES=<ollama_max_retries>
OLLAMA_RETRY_BACKOFF_SECONDS=<ollama_retry_backoff_seconds>
OLLAMA_SYSTEM_PROMPT=<ollama_system_prompt>
LLM_PROMPT_MAX_LENGTH=<llm_prompt_max_length>
FEATURE_SPEC_HISTORY_DEFAULT_LIMIT=<feature_spec_history_default_limit>

TEST_DB_HOST=<test_db_host>
TEST_DB_PORT=5432
TEST_DB_PORT=<test_db_port>
TEST_DB_NAME=<test_db_name>
TEST_DB_USER=<test_db_user>
TEST_DB_PASSWORD=<test_db_password>
TEST_DB_SSLMODE=disable
TEST_DB_SSLMODE=<test_db_sslmode>
TEST_DEFAULT_USERNAME=<test_username>
TEST_DEFAULT_EMAIL=<test_email>
TEST_DEFAULT_HASHED_PASSWORD=<hashed_test_password>
50 changes: 36 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Production-ready FastAPI backend for authentication, LLM-powered specification g

- JWT authentication based on fastapi-users
- User registration and user management endpoints
- LLM generation endpoint with multiple response formats (text, sections, json)
- Feature specification generation endpoints powered by Ollama
- Readiness and health probes for runtime checks
- Alembic database migrations
- Security middleware baseline:
Expand Down Expand Up @@ -49,8 +49,8 @@ Production-ready FastAPI backend for authentication, LLM-powered specification g
- app/api/: health, readiness, OpenAPI customization
- app/middlewares/: security middleware composition and implementations
- app/modules/auth/: auth domain (models, schemas, dependencies, router)
- app/modules/llm/: LLM API, schemas, providers
- app/scripts/: utility scripts (admin bootstrap)
- app/modules/feature_spec/: feature spec API, schemas, prompts, providers
- app/scripts/: utility scripts (admin and prompt/model bootstrap)
- alembic/: migration config and versions
- docker-compose.yml: containerized app run

Expand All @@ -60,8 +60,7 @@ Production-ready FastAPI backend for authentication, LLM-powered specification g

- Python 3.10+
- PostgreSQL database
- Optional: Docker + Docker Compose
- Optional: local Ollama instance for LLM generation
- Optional: Docker + Docker Compose (recommended for VPS)

### 1) Configure environment

Expand All @@ -83,6 +82,10 @@ LLM values:
- OLLAMA_BASE_URL
- OLLAMA_MODEL

For Docker Compose in this project use:

- OLLAMA_BASE_URL=http://ollama:11434

### 2A) Run locally

```bash
Expand All @@ -94,33 +97,51 @@ source venv/bin/activate

pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt

python -m alembic upgrade head
python -m app.scripts.bootstrap_admin
python -m app.scripts.bootstrap_prompt_template
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000
```

### 2B) Run with Docker

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

Notes:

- Container entrypoint automatically runs:
- migration + DB head check (`python -m app.scripts.migrate_and_check`)
- admin bootstrap script
- admin bootstrap script (`python -m app.scripts.bootstrap_admin`)
- prompt template bootstrap script (`python -m app.scripts.bootstrap_prompt_template`)
- Ollama model bootstrap (`python -m app.scripts.ensure_ollama_model`)
- uvicorn app startup
- On first deploy, startup may take longer while the configured `OLLAMA_MODEL` is downloaded.
- FastAPI container reaches Ollama via internal Docker network URL: http://ollama:11434

Verify Ollama API:

```bash
curl http://localhost:11434/api/generate -d '{
"model": "mistral",
"prompt": "hello",
"stream": false
}'
```

## API Docs

When server is running:
When server is running locally:

- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc (pinned ReDoc 2.x script)
- OpenAPI JSON: http://localhost:8000/openapi.json

For Docker Compose deployment, use port 8001 instead of 8000.

## API Endpoints

Base API prefix: /api/v1
Expand Down Expand Up @@ -151,16 +172,16 @@ Login note:
- `/api/v1/auth/jwt/logout` clears refresh cookie on client side.
- Swagger `Authorize` value must contain only raw JWT token (without `Bearer ` prefix).

### LLM
### Feature Spec

- POST /api/v1/llm/generate
- POST /api/v1/feature-spec/generate
- GET /api/v1/feature-spec/history?limit=10

Request body example:
Request body example for generation:

```json
{
"prompt": "Generate API specification for user profile module",
"response_format": "sections"
"feature_idea": "payment for premium posts"
}
```

Expand All @@ -169,7 +190,7 @@ Request body example:
Run linter:

```bash
python -m flake8
python -m flake8 .
```

Run auth unit tests:
Expand Down Expand Up @@ -208,3 +229,4 @@ If LLM requests fail:

- Verify OLLAMA_BASE_URL
- Ensure Ollama is running and model is available
- For Docker deployment, ensure OLLAMA_BASE_URL is http://ollama:11434
45 changes: 0 additions & 45 deletions alembic/versions/2e5bd3a1eb88_initial.py

This file was deleted.

54 changes: 0 additions & 54 deletions alembic/versions/6f4e8b8f4b11_add_refresh_tokens.py

This file was deleted.

Loading
Loading