Skip to content

Commit 2afc67e

Browse files
committed
Refactor: Remove core components and templates for project generation
- Deleted base.py, config.py, templates.py, and associated template files to streamline the project structure. - Removed generator-related files including project.py, loader.py, and registry.py to simplify the generation process. - Updated prepare_release.py to include version update logic. - Incremented version to 0.1.0a6 and added ruff as a development dependency.
1 parent bc887c2 commit 2afc67e

68 files changed

Lines changed: 1596 additions & 1898 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ wheels/
99
# Virtual environments
1010
.venv
1111
.tmp
12+
1213
.github/prompts
1314
docs/prd
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""{{ project_name }} application."""
2+
3+
__version__ = "0.1.0"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Application entry point."""
2+
3+
import uvicorn
4+
5+
from app.config import settings
6+
7+
8+
def main() -> None:
9+
"""Run the application."""
10+
uvicorn.run(
11+
"app.main:app",
12+
host=settings.HOST,
13+
port=settings.PORT,
14+
reload=settings.DEBUG,
15+
)
16+
17+
18+
if __name__ == "__main__":
19+
main()
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""Application configuration."""
2+
3+
import os
4+
from dataclasses import dataclass, field
5+
from pathlib import Path
6+
7+
from dotenv import load_dotenv
8+
9+
# Load environment variables
10+
load_dotenv()
11+
12+
13+
def _get_bool(key: str, default: bool = False) -> bool:
14+
"""Get a boolean from environment."""
15+
value = os.getenv(key, str(default)).lower()
16+
return value in ("true", "1", "yes", "on")
17+
18+
19+
def _get_int(key: str, default: int) -> int:
20+
"""Get an integer from environment."""
21+
return int(os.getenv(key, str(default)))
22+
23+
24+
@dataclass
25+
class Settings:
26+
"""Application settings."""
27+
28+
# Application
29+
APP_NAME: str = field(default_factory=lambda: os.getenv("APP_NAME", "{{ project_name }}"))
30+
APP_ENV: str = field(default_factory=lambda: os.getenv("APP_ENV", "development"))
31+
DEBUG: bool = field(default_factory=lambda: _get_bool("DEBUG", True))
32+
33+
# Server
34+
HOST: str = field(default_factory=lambda: os.getenv("HOST", "0.0.0.0"))
35+
PORT: int = field(default_factory=lambda: _get_int("PORT", 8000))
36+
37+
{% if has_database %}
38+
# Database
39+
{% if database.value == "PostgreSQL" %}
40+
DATABASE_URL: str = field(
41+
default_factory=lambda: os.getenv(
42+
"DATABASE_URL",
43+
"postgresql+asyncpg://myuser:mypassword@localhost:5432/mydb"
44+
)
45+
)
46+
{% elif database.value == "SQLite" %}
47+
DATABASE_URL: str = field(
48+
default_factory=lambda: os.getenv(
49+
"DATABASE_URL",
50+
"sqlite+aiosqlite:///./app.db"
51+
)
52+
)
53+
{% elif database.value == "MySQL" %}
54+
DATABASE_URL: str = field(
55+
default_factory=lambda: os.getenv(
56+
"DATABASE_URL",
57+
"mysql+asyncmy://myuser:mypassword@localhost:3306/mydb"
58+
)
59+
)
60+
{% endif %}
61+
{% endif %}
62+
63+
{% if has_jwt %}
64+
# JWT
65+
JWT_SECRET: str = field(
66+
default_factory=lambda: os.getenv("JWT_SECRET", "your-super-secret-key-change-in-production")
67+
)
68+
JWT_ALGORITHM: str = field(default_factory=lambda: os.getenv("JWT_ALGORITHM", "HS256"))
69+
JWT_EXPIRATION_MINUTES: int = field(default_factory=lambda: _get_int("JWT_EXPIRATION_MINUTES", 60))
70+
{% endif %}
71+
72+
@property
73+
def is_production(self) -> bool:
74+
"""Check if running in production."""
75+
return self.APP_ENV == "production"
76+
77+
78+
settings = Settings()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Litestar application factory."""
2+
3+
from litestar import Litestar, get
4+
from litestar.openapi import OpenAPIConfig
5+
6+
from app.config import settings
7+
{% if has_sqlalchemy %}
8+
from db.config import db_plugin
9+
{% endif %}
10+
{% if has_jwt %}
11+
from auth.guards import jwt_auth
12+
{% endif %}
13+
14+
15+
@get("/")
16+
async def index() -> dict[str, str]:
17+
"""Root endpoint."""
18+
return {"message": "Hello, World!", "app": settings.APP_NAME}
19+
20+
21+
@get("/health")
22+
async def health() -> dict[str, str]:
23+
"""Health check endpoint."""
24+
return {"status": "healthy"}
25+
26+
27+
app = Litestar(
28+
route_handlers=[index, health],
29+
openapi_config=OpenAPIConfig(
30+
title=settings.APP_NAME,
31+
version="0.1.0",
32+
path="/schema",
33+
),
34+
debug=settings.DEBUG,
35+
{% if has_sqlalchemy %}
36+
plugins=[db_plugin],
37+
{% endif %}
38+
{% if has_jwt %}
39+
on_app_init=[jwt_auth.on_app_init],
40+
{% endif %}
41+
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Application
2+
APP_NAME="{{ project_name }}"
3+
APP_ENV=development
4+
DEBUG=true
5+
6+
# Server
7+
HOST=0.0.0.0
8+
PORT=8000
9+
10+
{% if has_database %}
11+
# Database
12+
{% if database.value == "PostgreSQL" %}
13+
DATABASE_URL=postgresql+asyncpg://myuser:mypassword@localhost:5432/mydb
14+
{% elif database.value == "SQLite" %}
15+
DATABASE_URL=sqlite+aiosqlite:///./app.db
16+
{% elif database.value == "MySQL" %}
17+
DATABASE_URL=mysql+asyncmy://myuser:mypassword@localhost:3306/mydb
18+
{% endif %}
19+
{% endif %}
20+
21+
{% if has_jwt %}
22+
# JWT
23+
JWT_SECRET=your-super-secret-key-change-in-production
24+
JWT_ALGORITHM=HS256
25+
JWT_EXPIRATION_MINUTES=60
26+
{% endif %}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# Virtual environments
28+
.venv/
29+
venv/
30+
ENV/
31+
env/
32+
33+
# IDE
34+
.idea/
35+
.vscode/
36+
*.swp
37+
*.swo
38+
*~
39+
40+
# Environment variables
41+
.env
42+
.env.local
43+
.env.*.local
44+
45+
# Testing
46+
.coverage
47+
htmlcov/
48+
.pytest_cache/
49+
.mypy_cache/
50+
51+
# Logs
52+
*.log
53+
logs/
54+
55+
# Database
56+
*.db
57+
*.sqlite
58+
*.sqlite3
59+
60+
# OS files
61+
.DS_Store
62+
Thumbs.db
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[project]
2+
name = "{{ project_slug }}"
3+
version = "0.1.0"
4+
description = "A Litestar application"
5+
readme = "README.md"
6+
requires-python = ">=3.10"
7+
dependencies = [
8+
"litestar[standard]>=2.16.0",
9+
"python-dotenv>=1.1.0",
10+
{% if has_sqlalchemy %}
11+
"sqlalchemy>=2.0.0",
12+
"advanced-alchemy>=0.31.0",
13+
{% if database.value == "PostgreSQL" %}
14+
"asyncpg>=0.30.0",
15+
{% elif database.value == "SQLite" %}
16+
"aiosqlite>=0.21.0",
17+
{% elif database.value == "MySQL" %}
18+
"asyncmy>=0.2.10",
19+
{% endif %}
20+
{% endif %}
21+
{% if has_jwt %}
22+
"pyjwt>=2.10.0",
23+
"passlib[bcrypt]>=1.7.4",
24+
{% endif %}
25+
]
26+
27+
[project.scripts]
28+
{{ project_slug }} = "app.__main__:main"
29+
30+
[build-system]
31+
requires = ["hatchling"]
32+
build-backend = "hatchling.build"
33+
34+
[tool.hatch.build.targets.wheel]
35+
packages = ["app"]
36+
37+
[tool.ruff]
38+
line-length = 120
39+
target-version = "py310"
40+
41+
[tool.ruff.lint]
42+
select = ["E", "F", "I", "UP", "B", "SIM"]
43+
ignore = ["E501"]
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# {{ project_name }}
2+
3+
A Litestar application generated with [litestar-start](https://github.com/Harshal6927/litestar-start).
4+
5+
## Features
6+
7+
- ⚡ **Litestar** - High-performance ASGI framework
8+
{% if has_sqlalchemy %}
9+
- 🗄️ **SQLAlchemy** - Async ORM with {{ database.value }}
10+
{% endif %}
11+
{% if has_jwt %}
12+
- 🔐 **JWT Authentication** - Secure token-based auth
13+
{% endif %}
14+
{% if docker %}
15+
- 🐳 **Docker** - Containerized deployment
16+
{% endif %}
17+
18+
## Getting Started
19+
20+
### Prerequisites
21+
22+
- Python 3.10+
23+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip
24+
{% if docker_infra %}
25+
- Docker & Docker Compose (for local database)
26+
{% endif %}
27+
28+
### Installation
29+
30+
```bash
31+
# Clone the repository
32+
cd {{ project_slug }}
33+
34+
# Install dependencies
35+
uv sync
36+
37+
# Copy environment variables
38+
cp .env.example .env
39+
```
40+
41+
{% if docker_infra %}
42+
### Start Infrastructure
43+
44+
```bash
45+
# Start database container
46+
docker compose -f docker-compose.infra.yml up -d
47+
```
48+
49+
{% endif %}
50+
### Run the Application
51+
52+
```bash
53+
# Development mode with auto-reload
54+
litestar run --reload
55+
56+
# Or using uvicorn directly
57+
uvicorn app.main:app --reload
58+
```
59+
60+
The API will be available at http://localhost:8000
61+
62+
### API Documentation
63+
64+
- Swagger UI: http://localhost:8000/schema
65+
- ReDoc: http://localhost:8000/schema/redoc
66+
67+
## Project Structure
68+
69+
```
70+
{{ project_slug }}/
71+
├── app/
72+
│ ├── __init__.py
73+
│ ├── __main__.py
74+
│ ├── config.py
75+
│ └── main.py
76+
{% if has_sqlalchemy %}
77+
├── db/
78+
│ ├── __init__.py
79+
│ ├── config.py
80+
│ └── models.py
81+
{% endif %}
82+
{% if has_jwt %}
83+
├── auth/
84+
│ ├── __init__.py
85+
│ ├── guards.py
86+
│ └── schemas.py
87+
{% endif %}
88+
├── .env.example
89+
├── .gitignore
90+
├── pyproject.toml
91+
└── README.md
92+
```
93+
94+
## License
95+
96+
MIT

0 commit comments

Comments
 (0)