fastapi-struct 0.1.0__tar.gz

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 (34) hide show
  1. fastapi_struct-0.1.0/MANIFEST.in +2 -0
  2. fastapi_struct-0.1.0/PKG-INFO +47 -0
  3. fastapi_struct-0.1.0/README.md +34 -0
  4. fastapi_struct-0.1.0/pyproject.toml +37 -0
  5. fastapi_struct-0.1.0/setup.cfg +4 -0
  6. fastapi_struct-0.1.0/src/create_fastapi_app/__init__.py +1 -0
  7. fastapi_struct-0.1.0/src/create_fastapi_app/cli.py +46 -0
  8. fastapi_struct-0.1.0/src/create_fastapi_app/generator.py +33 -0
  9. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/.env.example +2 -0
  10. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/.gitignore +6 -0
  11. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/README.md +23 -0
  12. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/__init__.py +0 -0
  13. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/core/__init__.py +0 -0
  14. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/core/config.py +14 -0
  15. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/db/__init__.py +0 -0
  16. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/db/database.py +1 -0
  17. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/dependencies.py +1 -0
  18. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/main.py +19 -0
  19. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/models/__init__.py +1 -0
  20. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/routers/__init__.py +0 -0
  21. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/routers/health.py +8 -0
  22. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/routers/users.py +33 -0
  23. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/schemas/__init__.py +0 -0
  24. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/schemas/user.py +14 -0
  25. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/app/services/__init__.py +1 -0
  26. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/pyproject.toml +21 -0
  27. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/tests/__init__.py +0 -0
  28. fastapi_struct-0.1.0/src/create_fastapi_app/templates/basic/tests/test_main.py +15 -0
  29. fastapi_struct-0.1.0/src/fastapi_struct.egg-info/PKG-INFO +47 -0
  30. fastapi_struct-0.1.0/src/fastapi_struct.egg-info/SOURCES.txt +32 -0
  31. fastapi_struct-0.1.0/src/fastapi_struct.egg-info/dependency_links.txt +1 -0
  32. fastapi_struct-0.1.0/src/fastapi_struct.egg-info/entry_points.txt +3 -0
  33. fastapi_struct-0.1.0/src/fastapi_struct.egg-info/top_level.txt +1 -0
  34. fastapi_struct-0.1.0/tests/test_generator.py +29 -0
@@ -0,0 +1,2 @@
1
+ recursive-include src/create_fastapi_app/templates *
2
+ recursive-include src/create_fastapi_app/templates .*
@@ -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,34 @@
1
+ # fastapi-struct
2
+
3
+ CLI tool to generate standard, production-ready folder structures for FastAPI applications.
4
+
5
+ ## Usage
6
+
7
+ ### Instant with uvx (no installation needed)
8
+ ```bash
9
+ uvx fastapi-struct my-api
10
+ ```
11
+ Or in the current folder:
12
+ ```bash
13
+ uvx fastapi-struct .
14
+ ```
15
+
16
+ ### Or install via pip
17
+ ```bash
18
+ pip install fastapi-struct
19
+ fastapi-struct my-api
20
+ ```
21
+ *(You can also use `create-fastapi-app my-api`)*
22
+
23
+ ## Generated Project Next Steps
24
+
25
+ ```powershell
26
+ cd my-api
27
+ python -m venv .venv
28
+ .\.venv\Scripts\Activate.ps1
29
+ python -m pip install -e ".[dev]"
30
+ python -m uvicorn app.main:app --reload
31
+ ```
32
+
33
+ Interactive API documentation will be available at:
34
+ http://127.0.0.1:8000/docs
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fastapi-struct"
7
+ version = "0.1.0"
8
+ description = "CLI tool to generate standard folder structure for FastAPI applications."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ keywords = [
13
+ "fastapi",
14
+ "project-structure",
15
+ "boilerplate",
16
+ "scaffold",
17
+ "cli",
18
+ "template",
19
+ "folder-structure",
20
+ ]
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3",
23
+ "Framework :: FastAPI",
24
+ "Topic :: Software Development :: Code Generators",
25
+ "Operating System :: OS Independent",
26
+ ]
27
+ dependencies = []
28
+
29
+ [project.scripts]
30
+ fastapi-struct = "create_fastapi_app.cli:main"
31
+ create-fastapi-app = "create_fastapi_app.cli:main"
32
+
33
+ [tool.setuptools.packages.find]
34
+ where = ["src"]
35
+
36
+ [tool.setuptools.package-data]
37
+ create_fastapi_app = ["templates/**/*", "templates/**/.*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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
@@ -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()
@@ -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,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"]
@@ -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,32 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ src/create_fastapi_app/__init__.py
5
+ src/create_fastapi_app/cli.py
6
+ src/create_fastapi_app/generator.py
7
+ src/create_fastapi_app/templates/basic/.env.example
8
+ src/create_fastapi_app/templates/basic/.gitignore
9
+ src/create_fastapi_app/templates/basic/README.md
10
+ src/create_fastapi_app/templates/basic/pyproject.toml
11
+ src/create_fastapi_app/templates/basic/app/__init__.py
12
+ src/create_fastapi_app/templates/basic/app/dependencies.py
13
+ src/create_fastapi_app/templates/basic/app/main.py
14
+ src/create_fastapi_app/templates/basic/app/core/__init__.py
15
+ src/create_fastapi_app/templates/basic/app/core/config.py
16
+ src/create_fastapi_app/templates/basic/app/db/__init__.py
17
+ src/create_fastapi_app/templates/basic/app/db/database.py
18
+ src/create_fastapi_app/templates/basic/app/models/__init__.py
19
+ src/create_fastapi_app/templates/basic/app/routers/__init__.py
20
+ src/create_fastapi_app/templates/basic/app/routers/health.py
21
+ src/create_fastapi_app/templates/basic/app/routers/users.py
22
+ src/create_fastapi_app/templates/basic/app/schemas/__init__.py
23
+ src/create_fastapi_app/templates/basic/app/schemas/user.py
24
+ src/create_fastapi_app/templates/basic/app/services/__init__.py
25
+ src/create_fastapi_app/templates/basic/tests/__init__.py
26
+ src/create_fastapi_app/templates/basic/tests/test_main.py
27
+ src/fastapi_struct.egg-info/PKG-INFO
28
+ src/fastapi_struct.egg-info/SOURCES.txt
29
+ src/fastapi_struct.egg-info/dependency_links.txt
30
+ src/fastapi_struct.egg-info/entry_points.txt
31
+ src/fastapi_struct.egg-info/top_level.txt
32
+ tests/test_generator.py
@@ -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
@@ -0,0 +1,29 @@
1
+ import pytest
2
+ from pathlib import Path
3
+ from create_fastapi_app.generator import create_project
4
+
5
+
6
+ def test_create_project_success(tmp_path, monkeypatch):
7
+ monkeypatch.chdir(tmp_path)
8
+ project_path = create_project("test_service")
9
+ assert project_path.exists()
10
+ assert (project_path / "pyproject.toml").exists()
11
+ assert (project_path / "app" / "main.py").exists()
12
+ assert (project_path / ".env.example").exists()
13
+ assert (project_path / ".gitignore").exists()
14
+
15
+ config = (project_path / "pyproject.toml").read_text(encoding="utf-8")
16
+ assert 'name = "test-service"' in config
17
+
18
+
19
+ def test_create_project_invalid_name(tmp_path, monkeypatch):
20
+ monkeypatch.chdir(tmp_path)
21
+ with pytest.raises(ValueError):
22
+ create_project("123invalid")
23
+
24
+
25
+ def test_create_project_already_exists(tmp_path, monkeypatch):
26
+ monkeypatch.chdir(tmp_path)
27
+ (tmp_path / "existing_app").mkdir()
28
+ with pytest.raises(FileExistsError):
29
+ create_project("existing_app")