fastapi-struct 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. create_fastapi_app/__init__.py +1 -0
  2. create_fastapi_app/cli.py +46 -0
  3. create_fastapi_app/generator.py +33 -0
  4. create_fastapi_app/templates/basic/.env.example +2 -0
  5. create_fastapi_app/templates/basic/.gitignore +6 -0
  6. create_fastapi_app/templates/basic/README.md +23 -0
  7. create_fastapi_app/templates/basic/app/__init__.py +0 -0
  8. create_fastapi_app/templates/basic/app/core/__init__.py +0 -0
  9. create_fastapi_app/templates/basic/app/core/config.py +14 -0
  10. create_fastapi_app/templates/basic/app/db/__init__.py +0 -0
  11. create_fastapi_app/templates/basic/app/db/database.py +1 -0
  12. create_fastapi_app/templates/basic/app/dependencies.py +1 -0
  13. create_fastapi_app/templates/basic/app/main.py +19 -0
  14. create_fastapi_app/templates/basic/app/models/__init__.py +1 -0
  15. create_fastapi_app/templates/basic/app/routers/__init__.py +0 -0
  16. create_fastapi_app/templates/basic/app/routers/health.py +8 -0
  17. create_fastapi_app/templates/basic/app/routers/users.py +33 -0
  18. create_fastapi_app/templates/basic/app/schemas/__init__.py +0 -0
  19. create_fastapi_app/templates/basic/app/schemas/user.py +14 -0
  20. create_fastapi_app/templates/basic/app/services/__init__.py +1 -0
  21. create_fastapi_app/templates/basic/pyproject.toml +21 -0
  22. create_fastapi_app/templates/basic/tests/__init__.py +0 -0
  23. create_fastapi_app/templates/basic/tests/test_main.py +15 -0
  24. fastapi_struct-0.1.0.dist-info/METADATA +47 -0
  25. fastapi_struct-0.1.0.dist-info/RECORD +28 -0
  26. fastapi_struct-0.1.0.dist-info/WHEEL +5 -0
  27. fastapi_struct-0.1.0.dist-info/entry_points.txt +3 -0
  28. fastapi_struct-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,46 @@
1
+ import argparse
2
+ import sys
3
+
4
+ from create_fastapi_app import __version__
5
+ from create_fastapi_app.generator import create_project
6
+
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(
10
+ prog="create-fastapi-app",
11
+ description="Create a new FastAPI project.",
12
+ )
13
+ parser.add_argument(
14
+ "name",
15
+ nargs="?",
16
+ help="Name of the project to generate (or . for current directory)",
17
+ )
18
+ parser.add_argument(
19
+ "--version",
20
+ action="version",
21
+ version=f"%(prog)s {__version__}",
22
+ )
23
+
24
+ args = parser.parse_args()
25
+
26
+ if not args.name:
27
+ parser.print_help()
28
+ sys.exit(2)
29
+
30
+ try:
31
+ path = create_project(args.name)
32
+ except (ValueError, FileExistsError, FileNotFoundError) as exc:
33
+ parser.error(str(exc))
34
+
35
+ print(f"\nSuccess! Created project at: {path}")
36
+ print("\nNext steps:")
37
+ if args.name != ".":
38
+ print(f" cd {args.name}")
39
+ print(" python -m venv .venv")
40
+ print(r" .\.venv\Scripts\Activate.ps1")
41
+ print(' python -m pip install -e ".[dev]"')
42
+ print(" python -m uvicorn app.main:app --reload")
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
@@ -0,0 +1,33 @@
1
+ from pathlib import Path
2
+ import re
3
+ import shutil
4
+
5
+ PACKAGE_DIR = Path(__file__).parent
6
+ TEMPLATE_DIR = PACKAGE_DIR / "templates" / "basic"
7
+
8
+
9
+ def create_project(name: str) -> Path:
10
+ if name == ".":
11
+ project_path = Path.cwd()
12
+ project_name = project_path.name
13
+ else:
14
+ if not re.fullmatch(r"[A-Za-z][A-Za-z0-9_-]*", name):
15
+ raise ValueError(
16
+ "Project name must start with a letter and contain "
17
+ "only letters, numbers, underscores, or hyphens."
18
+ )
19
+ project_path = Path.cwd() / name
20
+ project_name = name
21
+
22
+ # Copy files allowing existing directory
23
+ shutil.copytree(TEMPLATE_DIR, project_path, dirs_exist_ok=True)
24
+
25
+ config_path = project_path / "pyproject.toml"
26
+ config = config_path.read_text(encoding="utf-8")
27
+ config = config.replace(
28
+ 'name = "my-api"',
29
+ f'name = "{project_name.lower().replace("_", "-")}"',
30
+ )
31
+ config_path.write_text(config, encoding="utf-8")
32
+
33
+ return project_path
@@ -0,0 +1,2 @@
1
+ PROJECT_NAME=My FastAPI App
2
+ DEBUG=true
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ __pycache__/
3
+ .env
4
+ .pytest_cache/
5
+ *.py[cod]
6
+ *.db
@@ -0,0 +1,23 @@
1
+ # My FastAPI Application
2
+
3
+ ## Install
4
+
5
+ ```powershell
6
+ python -m pip install -e ".[dev]"
7
+ ```
8
+
9
+ ## Run
10
+
11
+ ```powershell
12
+ python -m uvicorn app.main:app --reload
13
+ ```
14
+
15
+ ## Test
16
+
17
+ ```powershell
18
+ python -m pytest
19
+ ```
20
+
21
+ ## Documentation
22
+
23
+ Visit http://127.0.0.1:8000/docs
File without changes
@@ -0,0 +1,14 @@
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+
3
+
4
+ class Settings(BaseSettings):
5
+ PROJECT_NAME: str = "My FastAPI App"
6
+ DEBUG: bool = True
7
+
8
+ model_config = SettingsConfigDict(
9
+ env_file=".env",
10
+ extra="ignore",
11
+ )
12
+
13
+
14
+ settings = Settings()
File without changes
@@ -0,0 +1 @@
1
+ """Database engine and session configuration."""
@@ -0,0 +1 @@
1
+ """Shared FastAPI dependencies."""
@@ -0,0 +1,19 @@
1
+ from fastapi import FastAPI
2
+ from app.core.config import settings
3
+ from app.routers.health import router as health_router
4
+ from app.routers.users import router as users_router
5
+
6
+ app = FastAPI(
7
+ title=settings.PROJECT_NAME,
8
+ version="0.1.0",
9
+ )
10
+
11
+ app.include_router(health_router)
12
+ app.include_router(users_router)
13
+
14
+
15
+ @app.get("/", tags=["Root"])
16
+ async def root():
17
+ return {
18
+ "message": f"Welcome to {settings.PROJECT_NAME}"
19
+ }
@@ -0,0 +1 @@
1
+ """Database models."""
@@ -0,0 +1,8 @@
1
+ from fastapi import APIRouter
2
+
3
+ router = APIRouter(tags=["Health"])
4
+
5
+
6
+ @router.get("/health")
7
+ async def health():
8
+ return {"status": "ok"}
@@ -0,0 +1,33 @@
1
+ from fastapi import APIRouter, HTTPException, status
2
+ from app.schemas.user import UserCreate, UserResponse
3
+
4
+ router = APIRouter(prefix="/users", tags=["Users"])
5
+
6
+ _users: dict[int, dict] = {}
7
+ _next_id = 1
8
+
9
+
10
+ @router.post(
11
+ "/",
12
+ response_model=UserResponse,
13
+ status_code=status.HTTP_201_CREATED,
14
+ )
15
+ async def create_user(payload: UserCreate):
16
+ global _next_id
17
+ user = {"id": _next_id, **payload.model_dump()}
18
+ _users[_next_id] = user
19
+ _next_id += 1
20
+ return user
21
+
22
+
23
+ @router.get("/", response_model=list[UserResponse])
24
+ async def list_users():
25
+ return list(_users.values())
26
+
27
+
28
+ @router.get("/{user_id}", response_model=UserResponse)
29
+ async def get_user(user_id: int):
30
+ user = _users.get(user_id)
31
+ if user is None:
32
+ raise HTTPException(404, "User not found")
33
+ return user
@@ -0,0 +1,14 @@
1
+ from pydantic import BaseModel, ConfigDict, EmailStr, Field
2
+
3
+
4
+ class UserCreate(BaseModel):
5
+ name: str = Field(min_length=1, max_length=100)
6
+ email: EmailStr
7
+
8
+
9
+ class UserResponse(BaseModel):
10
+ id: int
11
+ name: str
12
+ email: EmailStr
13
+
14
+ model_config = ConfigDict(from_attributes=True)
@@ -0,0 +1 @@
1
+ """Business logic services."""
@@ -0,0 +1,21 @@
1
+ [project]
2
+ name = "my-api"
3
+ version = "0.1.0"
4
+ description = "A generated FastAPI application"
5
+ requires-python = ">=3.10"
6
+ dependencies = [
7
+ "fastapi>=0.115",
8
+ "uvicorn[standard]>=0.30",
9
+ "pydantic-settings>=2.0",
10
+ "email-validator>=2.0",
11
+ ]
12
+
13
+ [project.optional-dependencies]
14
+ dev = [
15
+ "pytest>=8.0",
16
+ "httpx>=0.27",
17
+ ]
18
+
19
+ [tool.pytest.ini_options]
20
+ pythonpath = ["."]
21
+ testpaths = ["tests"]
File without changes
@@ -0,0 +1,15 @@
1
+ from fastapi.testclient import TestClient
2
+ from app.main import app
3
+
4
+ client = TestClient(app)
5
+
6
+
7
+ def test_root():
8
+ response = client.get("/")
9
+ assert response.status_code == 200
10
+
11
+
12
+ def test_health():
13
+ response = client.get("/health")
14
+ assert response.status_code == 200
15
+ assert response.json() == {"status": "ok"}
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-struct
3
+ Version: 0.1.0
4
+ Summary: CLI tool to generate standard folder structure for FastAPI applications.
5
+ License-Expression: MIT
6
+ Keywords: fastapi,project-structure,boilerplate,scaffold,cli,template,folder-structure
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Framework :: FastAPI
9
+ Classifier: Topic :: Software Development :: Code Generators
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+
14
+ # fastapi-struct
15
+
16
+ CLI tool to generate standard, production-ready folder structures for FastAPI applications.
17
+
18
+ ## Usage
19
+
20
+ ### Instant with uvx (no installation needed)
21
+ ```bash
22
+ uvx fastapi-struct my-api
23
+ ```
24
+ Or in the current folder:
25
+ ```bash
26
+ uvx fastapi-struct .
27
+ ```
28
+
29
+ ### Or install via pip
30
+ ```bash
31
+ pip install fastapi-struct
32
+ fastapi-struct my-api
33
+ ```
34
+ *(You can also use `create-fastapi-app my-api`)*
35
+
36
+ ## Generated Project Next Steps
37
+
38
+ ```powershell
39
+ cd my-api
40
+ python -m venv .venv
41
+ .\.venv\Scripts\Activate.ps1
42
+ python -m pip install -e ".[dev]"
43
+ python -m uvicorn app.main:app --reload
44
+ ```
45
+
46
+ Interactive API documentation will be available at:
47
+ http://127.0.0.1:8000/docs
@@ -0,0 +1,28 @@
1
+ create_fastapi_app/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
2
+ create_fastapi_app/cli.py,sha256=gJpQzIzco1JV4_8YTTlijhuZF_7e_o2MnIs7MdpQnS8,1155
3
+ create_fastapi_app/generator.py,sha256=dN6ibM_ds5H7x8R7lX_BcNg5kEgEERwy0uPDJw2EQK0,1046
4
+ create_fastapi_app/templates/basic/.env.example,sha256=tVjHTUdDIkO_7nA1Pc31V25rIJP09OIC43qdjlVcEQs,41
5
+ create_fastapi_app/templates/basic/.gitignore,sha256=FAr3KyxAtp25Pdxo7PInoWlbSiSLSC1yMl0Iq2oKeew,61
6
+ create_fastapi_app/templates/basic/README.md,sha256=AjWuTg8WUsZ9j1BoOX-ijbsjxFDVZN9_zdG0CwCYrYE,277
7
+ create_fastapi_app/templates/basic/pyproject.toml,sha256=RgqohpE4F11fgd7CoaOgfO8L-yxj4XvYZ3BahH_OgGE,419
8
+ create_fastapi_app/templates/basic/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ create_fastapi_app/templates/basic/app/dependencies.py,sha256=5oj7FKbc3itgd35Umc7PKqtvgQMDkj1SZcPiMzEGlmg,36
10
+ create_fastapi_app/templates/basic/app/main.py,sha256=0S29EuP2x8XPbJiMsJEZwjUPfkjhw32WlcWu2JS6Kzg,457
11
+ create_fastapi_app/templates/basic/app/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ create_fastapi_app/templates/basic/app/core/config.py,sha256=V8ct81YdTlSJIJXeaM8jbX9fyNm7J413Ld6gKX4NSyw,292
13
+ create_fastapi_app/templates/basic/app/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ create_fastapi_app/templates/basic/app/db/database.py,sha256=xJH6ksVoyohKuUd7jws_PO0yUi8fpNIS2YB1InrS_tk,50
15
+ create_fastapi_app/templates/basic/app/models/__init__.py,sha256=IGHnLLANQKYVbo3Ga1Zkw_Cvc6dFXlsRGg-vegvLXjo,24
16
+ create_fastapi_app/templates/basic/app/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ create_fastapi_app/templates/basic/app/routers/health.py,sha256=oJz-ESqnuhhR-3Bn1qkfcuAKdmWnpdQT6SHZvnd0p7I,148
18
+ create_fastapi_app/templates/basic/app/routers/users.py,sha256=69qguaqhG1glWC00qLqs2tIYtVgCqAQFdQkXa1XWQCs,836
19
+ create_fastapi_app/templates/basic/app/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ create_fastapi_app/templates/basic/app/schemas/user.py,sha256=W9yWUGbuswmXpV0yCL1lnUojJKbsuvNCZ7qpPU3MwtE,309
21
+ create_fastapi_app/templates/basic/app/services/__init__.py,sha256=6KBTji_ZFafSQqlG1o7MQOZz1cY6iM6McZMrUMdkKfQ,32
22
+ create_fastapi_app/templates/basic/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ create_fastapi_app/templates/basic/tests/test_main.py,sha256=C6lcq38LlTXyEf6iOT67Xis2N7YbmKjQpYAL3h9rJjw,341
24
+ fastapi_struct-0.1.0.dist-info/METADATA,sha256=OV81NMI7djLjLXtNb2mEkWxyTSsesJiQcj0bezqhAvM,1216
25
+ fastapi_struct-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
26
+ fastapi_struct-0.1.0.dist-info/entry_points.txt,sha256=sZ3DCmuI2f5mPp4G0QahddlzOm_9MnahT-tHG_awyXw,112
27
+ fastapi_struct-0.1.0.dist-info/top_level.txt,sha256=m9YzseithBld60oU2cROBGqFlqX2Zobup82fI3qOVhg,19
28
+ fastapi_struct-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ create-fastapi-app = create_fastapi_app.cli:main
3
+ fastapi-struct = create_fastapi_app.cli:main
@@ -0,0 +1 @@
1
+ create_fastapi_app