fastapi-fastio 0.1.2__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 (93) hide show
  1. fastapi_fastio-0.1.2/.github/workflows/publish.yml +33 -0
  2. fastapi_fastio-0.1.2/.gitignore +1 -0
  3. fastapi_fastio-0.1.2/LICENSE +21 -0
  4. fastapi_fastio-0.1.2/PKG-INFO +159 -0
  5. fastapi_fastio-0.1.2/README.md +132 -0
  6. fastapi_fastio-0.1.2/pyproject.toml +76 -0
  7. fastapi_fastio-0.1.2/src/fastio/__init__.py +2 -0
  8. fastapi_fastio-0.1.2/src/fastio/cli/__init__.py +0 -0
  9. fastapi_fastio-0.1.2/src/fastio/cli/app.py +151 -0
  10. fastapi_fastio-0.1.2/src/fastio/generators/__init__.py +0 -0
  11. fastapi_fastio-0.1.2/src/fastio/generators/base.py +33 -0
  12. fastapi_fastio-0.1.2/src/fastio/generators/monolith.py +31 -0
  13. fastapi_fastio-0.1.2/src/fastio/generators/monorepo.py +42 -0
  14. fastapi_fastio-0.1.2/src/fastio/generators/service.py +92 -0
  15. fastapi_fastio-0.1.2/src/fastio/main.py +5 -0
  16. fastapi_fastio-0.1.2/src/fastio/models/__init__.py +0 -0
  17. fastapi_fastio-0.1.2/src/fastio/models/options.py +65 -0
  18. fastapi_fastio-0.1.2/src/fastio/renderers/__init__.py +0 -0
  19. fastapi_fastio-0.1.2/src/fastio/renderers/jinja.py +20 -0
  20. fastapi_fastio-0.1.2/src/fastio/renderers/writer.py +8 -0
  21. fastapi_fastio-0.1.2/src/fastio/templates/common/Dockerfile.j2 +9 -0
  22. fastapi_fastio-0.1.2/src/fastio/templates/common/compose.yml.j2 +58 -0
  23. fastapi_fastio-0.1.2/src/fastio/templates/common/empty.py.j2 +0 -0
  24. fastapi_fastio-0.1.2/src/fastio/templates/common/env.example.j2 +20 -0
  25. fastapi_fastio-0.1.2/src/fastio/templates/common/gitignore.j2 +15 -0
  26. fastapi_fastio-0.1.2/src/fastio/templates/common/publish.yml.j2 +33 -0
  27. fastapi_fastio-0.1.2/src/fastio/templates/common/test_smoke.py.j2 +2 -0
  28. fastapi_fastio-0.1.2/src/fastio/templates/monolith/README.md.j2 +11 -0
  29. fastapi_fastio-0.1.2/src/fastio/templates/monolith/alembic.ini.j2 +7 -0
  30. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/core/config.py.j2 +22 -0
  31. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/main.py.j2 +11 -0
  32. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/modules/users/api.py.j2 +8 -0
  33. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/modules/users/models.py.j2 +2 -0
  34. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/modules/users/schemas.py.j2 +6 -0
  35. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/modules/users/service.py.j2 +3 -0
  36. fastapi_fastio-0.1.2/src/fastio/templates/monolith/app/tasks/celery_app.py.j2 +18 -0
  37. fastapi_fastio-0.1.2/src/fastio/templates/monolith/pyproject.toml.j2 +43 -0
  38. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/README.md.j2 +9 -0
  39. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/packages/shared-auth/README.md.j2 +3 -0
  40. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/packages/shared-clients/README.md.j2 +3 -0
  41. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/packages/shared-events/README.md.j2 +3 -0
  42. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/packages/shared-schemas/README.md.j2 +3 -0
  43. fastapi_fastio-0.1.2/src/fastio/templates/monorepo/pyproject.toml.j2 +11 -0
  44. fastapi_fastio-0.1.2/src/fastio/templates/service/README.md.j2 +47 -0
  45. fastapi_fastio-0.1.2/src/fastio/templates/service/alembic.ini.j2 +7 -0
  46. fastapi_fastio-0.1.2/src/fastio/templates/service/app/admin.py.j2 +137 -0
  47. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/deps.py.j2 +13 -0
  48. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/airdrop.py.j2 +35 -0
  49. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/api.py.j2 +33 -0
  50. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/items.py.j2 +18 -0
  51. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/members.py.j2 +46 -0
  52. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/moderation.py.j2 +28 -0
  53. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/orders.py.j2 +28 -0
  54. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/products.py.j2 +35 -0
  55. fastapi_fastio-0.1.2/src/fastio/templates/service/app/api/v1/profile.py.j2 +8 -0
  56. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/bot.py.j2 +7 -0
  57. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/handlers/airdrop.py.j2 +90 -0
  58. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/handlers/ecommerce.py.j2 +81 -0
  59. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/handlers/membership.py.j2 +57 -0
  60. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/handlers/police_group.py.j2 +111 -0
  61. fastapi_fastio-0.1.2/src/fastio/templates/service/app/bot/handlers.py.j2 +17 -0
  62. fastapi_fastio-0.1.2/src/fastio/templates/service/app/core/config.py.j2 +29 -0
  63. fastapi_fastio-0.1.2/src/fastio/templates/service/app/core/security.py.j2 +2 -0
  64. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/base.py.j2 +14 -0
  65. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/item.py.j2 +12 -0
  66. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/member.py.j2 +15 -0
  67. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/order.py.j2 +18 -0
  68. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/participant.py.j2 +18 -0
  69. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/product.py.j2 +15 -0
  70. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/models/report.py.j2 +26 -0
  71. fastapi_fastio-0.1.2/src/fastio/templates/service/app/db/session.py.j2 +7 -0
  72. fastapi_fastio-0.1.2/src/fastio/templates/service/app/main.py.j2 +23 -0
  73. fastapi_fastio-0.1.2/src/fastio/templates/service/app/main_telegram.py.j2 +37 -0
  74. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/item.py.j2 +13 -0
  75. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/member.py.j2 +16 -0
  76. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/order.py.j2 +18 -0
  77. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/participant.py.j2 +20 -0
  78. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/product.py.j2 +27 -0
  79. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/report.py.j2 +27 -0
  80. fastapi_fastio-0.1.2/src/fastio/templates/service/app/schemas/user.py.j2 +6 -0
  81. fastapi_fastio-0.1.2/src/fastio/templates/service/app/services/airdrop_service.py.j2 +81 -0
  82. fastapi_fastio-0.1.2/src/fastio/templates/service/app/services/item_service.py.j2 +21 -0
  83. fastapi_fastio-0.1.2/src/fastio/templates/service/app/services/member_service.py.j2 +46 -0
  84. fastapi_fastio-0.1.2/src/fastio/templates/service/app/services/moderation_service.py.j2 +70 -0
  85. fastapi_fastio-0.1.2/src/fastio/templates/service/app/services/shop_service.py.j2 +96 -0
  86. fastapi_fastio-0.1.2/src/fastio/templates/service/app/tasks/celery_app.py.j2 +18 -0
  87. fastapi_fastio-0.1.2/src/fastio/templates/service/app/tasks/item_tasks.py.j2 +6 -0
  88. fastapi_fastio-0.1.2/src/fastio/templates/service/app/tasks/user_tasks.py.j2 +21 -0
  89. fastapi_fastio-0.1.2/src/fastio/templates/service/app/users/auth.py.j2 +1 -0
  90. fastapi_fastio-0.1.2/src/fastio/templates/service/app/users/manager.py.j2 +1 -0
  91. fastapi_fastio-0.1.2/src/fastio/templates/service/app/users/oauth.py.j2 +1 -0
  92. fastapi_fastio-0.1.2/src/fastio/templates/service/pyproject.toml.j2 +46 -0
  93. fastapi_fastio-0.1.2/tests/test_cli.py +5 -0
@@ -0,0 +1,33 @@
1
+ name: publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ contents: read
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v3
26
+
27
+ - name: Build
28
+ run: |
29
+ uv sync --group dev
30
+ uv run python -m build
31
+
32
+ - name: Publish to PyPI
33
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1 @@
1
+ apps
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-fastio
3
+ Version: 0.1.2
4
+ Summary: Opinionated FastAPI project scaffolding CLI for services, monoliths, and monorepos.
5
+ Project-URL: Homepage, https://github.com/goloodev/fastio
6
+ Project-URL: Repository, https://github.com/goloodev/fastio
7
+ Project-URL: Issues, https://github.com/goloodev/fastio/issues
8
+ Author-email: goloodev@gmail.com
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,fastapi,microservices,monolith,scaffold,template,uv
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Code Generators
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: click>=8.1.0
22
+ Requires-Dist: jinja2>=3.1.4
23
+ Requires-Dist: pydantic>=2.8.2
24
+ Requires-Dist: rich>=13.7.1
25
+ Requires-Dist: typer>=0.12.5
26
+ Description-Content-Type: text/markdown
27
+
28
+ # fastio
29
+
30
+ `fastio` is an opinionated Python CLI that generates FastAPI projects for three shapes:
31
+
32
+ - single service
33
+ - modular monolith
34
+ - monorepo microservices
35
+
36
+ It is designed around your standards:
37
+
38
+ - Python + FastAPI
39
+ - `uv`
40
+ - Alembic
41
+ - SQLAlchemy
42
+ - Swagger at `/docs`
43
+ - SQLAdmin
44
+ - Celery + Redis
45
+ - clean architecture
46
+ - thin routers
47
+ - business logic in `services/`
48
+ - versioned APIs under `/api/v1`
49
+
50
+ ## Install
51
+
52
+ ### Local development
53
+ ```bash
54
+ uv sync
55
+ uv run fastio --help
56
+ ```
57
+
58
+ ### Editable install
59
+ ```bash
60
+ uv pip install -e .
61
+ fastio --help
62
+ ```
63
+
64
+ ## Quick start
65
+
66
+ Create a CRUD service:
67
+
68
+ ```bash
69
+ uv run fastio create my-service --mode service --blueprint crud-service
70
+ ```
71
+
72
+ Create a user service:
73
+
74
+ ```bash
75
+ uv run fastio create user-service --mode service --blueprint user-service
76
+ ```
77
+
78
+ Create a modular monolith:
79
+
80
+ ```bash
81
+ uv run fastio create my-app --mode monolith
82
+ ```
83
+
84
+ Create a monorepo:
85
+
86
+ ```bash
87
+ uv run fastio create platform --mode monorepo
88
+ ```
89
+
90
+ ## Publishing to PyPI
91
+
92
+ The project includes a GitHub Actions publish workflow using PyPI Trusted Publishing.
93
+ PyPI’s docs recommend Trusted Publishing via OIDC because it avoids long-lived API tokens, and a pending publisher can create a new project on first release. Also note that a pending publisher does **not** reserve the name before first publish.
94
+
95
+ ## Commands
96
+
97
+ ### `fastio create`
98
+
99
+ Generate a new FastAPI project.
100
+
101
+ ```bash
102
+ fastio create NAME [OPTIONS]
103
+ ```
104
+
105
+ **Arguments:**
106
+ - `NAME` - Project directory name (required)
107
+
108
+ **Options:**
109
+ - `--mode {service,monolith,monorepo}` - Project shape (default: service)
110
+ - `--blueprint {base,crud-service,user-service}` - Project template (default: base for monolith/monorepo, crud-service for service)
111
+ - `--database {sqlite,postgres}` - Database backend (default: sqlite)
112
+ - `--sqlalchemy {sync,async}` - SQLAlchemy mode (default: sync, async for user-service)
113
+ - `--sqladmin/--no-sqladmin` - Include SQLAdmin (default: enabled)
114
+ - `--celery/--no-celery` - Include Celery + Redis (default: enabled)
115
+ - `--docker/--no-docker` - Include Dockerfile (default: enabled)
116
+ - `--tests/--no-tests` - Include test suite (default: enabled)
117
+ - `--ci/--no-ci` - Include GitHub Actions CI workflow (default: enabled)
118
+ - `--output-dir, -o` - Output directory (default: current directory)
119
+ - `--interactive` - Interactive mode with prompts for all options
120
+
121
+ **Blueprints:**
122
+ - `base` - Minimal FastAPI project with core structure
123
+ - `crud-service` - Full CRUD API with models, schemas, and services
124
+ - `user-service` - User management service with authentication, OAuth, and FastAPI-Users
125
+
126
+ ### `fastio version`
127
+
128
+ Display the installed version.
129
+
130
+ ```bash
131
+ fastio version
132
+ ```
133
+
134
+ ## Usage Examples
135
+
136
+ ### Interactive mode
137
+ ```bash
138
+ uv run fastio create my-project --interactive
139
+ ```
140
+
141
+ ### CRUD service with PostgreSQL
142
+ ```bash
143
+ uv run fastio create my-api --mode service --blueprint crud-service --database postgres
144
+ ```
145
+
146
+ ### Async monolith
147
+ ```bash
148
+ uv run fastio create my-app --mode monolith --sqlalchemy async
149
+ ```
150
+
151
+ ### Minimal service without extras
152
+ ```bash
153
+ uv run fastio create my-service --mode service --no-celery --no-sqladmin
154
+ ```
155
+
156
+ ### Monorepo with custom output
157
+ ```bash
158
+ uv run fastio create platform --mode monorepo --output-dir ./projects
159
+ ```
@@ -0,0 +1,132 @@
1
+ # fastio
2
+
3
+ `fastio` is an opinionated Python CLI that generates FastAPI projects for three shapes:
4
+
5
+ - single service
6
+ - modular monolith
7
+ - monorepo microservices
8
+
9
+ It is designed around your standards:
10
+
11
+ - Python + FastAPI
12
+ - `uv`
13
+ - Alembic
14
+ - SQLAlchemy
15
+ - Swagger at `/docs`
16
+ - SQLAdmin
17
+ - Celery + Redis
18
+ - clean architecture
19
+ - thin routers
20
+ - business logic in `services/`
21
+ - versioned APIs under `/api/v1`
22
+
23
+ ## Install
24
+
25
+ ### Local development
26
+ ```bash
27
+ uv sync
28
+ uv run fastio --help
29
+ ```
30
+
31
+ ### Editable install
32
+ ```bash
33
+ uv pip install -e .
34
+ fastio --help
35
+ ```
36
+
37
+ ## Quick start
38
+
39
+ Create a CRUD service:
40
+
41
+ ```bash
42
+ uv run fastio create my-service --mode service --blueprint crud-service
43
+ ```
44
+
45
+ Create a user service:
46
+
47
+ ```bash
48
+ uv run fastio create user-service --mode service --blueprint user-service
49
+ ```
50
+
51
+ Create a modular monolith:
52
+
53
+ ```bash
54
+ uv run fastio create my-app --mode monolith
55
+ ```
56
+
57
+ Create a monorepo:
58
+
59
+ ```bash
60
+ uv run fastio create platform --mode monorepo
61
+ ```
62
+
63
+ ## Publishing to PyPI
64
+
65
+ The project includes a GitHub Actions publish workflow using PyPI Trusted Publishing.
66
+ PyPI’s docs recommend Trusted Publishing via OIDC because it avoids long-lived API tokens, and a pending publisher can create a new project on first release. Also note that a pending publisher does **not** reserve the name before first publish.
67
+
68
+ ## Commands
69
+
70
+ ### `fastio create`
71
+
72
+ Generate a new FastAPI project.
73
+
74
+ ```bash
75
+ fastio create NAME [OPTIONS]
76
+ ```
77
+
78
+ **Arguments:**
79
+ - `NAME` - Project directory name (required)
80
+
81
+ **Options:**
82
+ - `--mode {service,monolith,monorepo}` - Project shape (default: service)
83
+ - `--blueprint {base,crud-service,user-service}` - Project template (default: base for monolith/monorepo, crud-service for service)
84
+ - `--database {sqlite,postgres}` - Database backend (default: sqlite)
85
+ - `--sqlalchemy {sync,async}` - SQLAlchemy mode (default: sync, async for user-service)
86
+ - `--sqladmin/--no-sqladmin` - Include SQLAdmin (default: enabled)
87
+ - `--celery/--no-celery` - Include Celery + Redis (default: enabled)
88
+ - `--docker/--no-docker` - Include Dockerfile (default: enabled)
89
+ - `--tests/--no-tests` - Include test suite (default: enabled)
90
+ - `--ci/--no-ci` - Include GitHub Actions CI workflow (default: enabled)
91
+ - `--output-dir, -o` - Output directory (default: current directory)
92
+ - `--interactive` - Interactive mode with prompts for all options
93
+
94
+ **Blueprints:**
95
+ - `base` - Minimal FastAPI project with core structure
96
+ - `crud-service` - Full CRUD API with models, schemas, and services
97
+ - `user-service` - User management service with authentication, OAuth, and FastAPI-Users
98
+
99
+ ### `fastio version`
100
+
101
+ Display the installed version.
102
+
103
+ ```bash
104
+ fastio version
105
+ ```
106
+
107
+ ## Usage Examples
108
+
109
+ ### Interactive mode
110
+ ```bash
111
+ uv run fastio create my-project --interactive
112
+ ```
113
+
114
+ ### CRUD service with PostgreSQL
115
+ ```bash
116
+ uv run fastio create my-api --mode service --blueprint crud-service --database postgres
117
+ ```
118
+
119
+ ### Async monolith
120
+ ```bash
121
+ uv run fastio create my-app --mode monolith --sqlalchemy async
122
+ ```
123
+
124
+ ### Minimal service without extras
125
+ ```bash
126
+ uv run fastio create my-service --mode service --no-celery --no-sqladmin
127
+ ```
128
+
129
+ ### Monorepo with custom output
130
+ ```bash
131
+ uv run fastio create platform --mode monorepo --output-dir ./projects
132
+ ```
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.25.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "fastapi-fastio"
7
+ version = "0.1.2"
8
+ description = "Opinionated FastAPI project scaffolding CLI for services, monoliths, and monorepos."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ { email = "goloodev@gmail.com" }
14
+ ]
15
+ keywords = ["fastapi", "cli", "template", "scaffold", "uv", "microservices", "monolith"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Software Development :: Code Generators",
25
+ ]
26
+ dependencies = [
27
+ "typer>=0.12.5",
28
+ "click>=8.1.0",
29
+ "rich>=13.7.1",
30
+ "jinja2>=3.1.4",
31
+ "pydantic>=2.8.2",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/goloodev/fastio"
36
+ Repository = "https://github.com/goloodev/fastio"
37
+ Issues = "https://github.com/goloodev/fastio/issues"
38
+
39
+ [project.scripts]
40
+ fastio = "fastio.main:run"
41
+
42
+ [dependency-groups]
43
+ dev = [
44
+ "pytest>=8.3.2",
45
+ "ruff>=0.6.5",
46
+ "mypy>=1.11.2",
47
+ "build>=1.2.2.post1",
48
+ "twine>=5.1.1",
49
+ ]
50
+
51
+ [tool.hatch.build.targets.wheel]
52
+ packages = ["src/fastio"]
53
+
54
+ [tool.hatch.build.targets.sdist]
55
+ include = [
56
+ "/src",
57
+ "/README.md",
58
+ "/LICENSE",
59
+ "/.github",
60
+ "/tests",
61
+ ]
62
+
63
+ [tool.ruff]
64
+ line-length = 100
65
+ target-version = "py311"
66
+
67
+ [tool.ruff.lint]
68
+ select = ["E", "F", "I", "B", "UP", "N", "C4"]
69
+
70
+ [tool.pytest.ini_options]
71
+ testpaths = ["tests"]
72
+
73
+ [tool.mypy]
74
+ python_version = "3.11"
75
+ strict = true
76
+ packages = ["fastio"]
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "0.1.2"
File without changes
@@ -0,0 +1,151 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Annotated, Optional
5
+
6
+ import click
7
+ import typer
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+
11
+ from fastio import __version__
12
+ from fastio.generators.monolith import MonolithGenerator
13
+ from fastio.generators.monorepo import MonorepoGenerator
14
+ from fastio.generators.service import ServiceGenerator
15
+ from fastio.models.options import AlchemyMode, Blueprint, Database, Mode, ProjectOptions, TelegramTemplate
16
+
17
+ app = typer.Typer(
18
+ no_args_is_help=True,
19
+ help="Opinionated FastAPI scaffolding CLI for services, monoliths, and monorepos.",
20
+ )
21
+ console = Console()
22
+
23
+
24
+ def _build_options(
25
+ name: str,
26
+ output_dir: Path,
27
+ mode: Optional[Mode],
28
+ blueprint: Optional[Blueprint],
29
+ database: Optional[Database],
30
+ sqlalchemy_mode: Optional[AlchemyMode],
31
+ sqladmin: Optional[bool],
32
+ celery: Optional[bool],
33
+ docker: Optional[bool],
34
+ tests: Optional[bool],
35
+ ci: Optional[bool],
36
+ interactive: bool,
37
+ telegram_template: Optional[TelegramTemplate] = None,
38
+ ) -> ProjectOptions:
39
+ if interactive or mode is None:
40
+ mode = typer.prompt("Mode", type=click.Choice(["service", "monolith", "monorepo"], case_sensitive=False), default="service")
41
+ if interactive or blueprint is None:
42
+ default_blueprint = "base" if mode != "service" else "crud-service"
43
+ blueprint = typer.prompt("Blueprint", type=click.Choice(["base", "crud-service", "user-service", "telegram-bot"], case_sensitive=False), default=default_blueprint)
44
+ if interactive or database is None:
45
+ database = typer.prompt("Database", type=click.Choice(["sqlite", "postgres"], case_sensitive=False), default="sqlite")
46
+ if interactive or sqlalchemy_mode is None:
47
+ default_sqlalchemy = "async" if blueprint == "user-service" else "sync"
48
+ sqlalchemy_mode = typer.prompt("SQLAlchemy mode", type=click.Choice(["sync", "async"], case_sensitive=False), default=default_sqlalchemy)
49
+ if interactive or sqladmin is None:
50
+ sqladmin = typer.confirm("Include SQLAdmin?", default=True)
51
+ if interactive or celery is None:
52
+ celery = typer.confirm("Include Celery?", default=True)
53
+ if interactive or docker is None:
54
+ docker = typer.confirm("Include Dockerfile?", default=True)
55
+ if interactive or tests is None:
56
+ tests = typer.confirm("Include tests?", default=True)
57
+ if interactive or ci is None:
58
+ ci = typer.confirm("Include CI workflow?", default=True)
59
+ if blueprint == "telegram-bot" and (interactive or telegram_template is None):
60
+ telegram_template = typer.prompt(
61
+ "Telegram Template",
62
+ type=click.Choice(["membership", "police-group", "airdrop", "ecommerce"], case_sensitive=False),
63
+ default="membership",
64
+ )
65
+
66
+ return ProjectOptions(
67
+ name=name,
68
+ output_dir=output_dir,
69
+ mode=mode,
70
+ blueprint=blueprint,
71
+ database=database,
72
+ sqlalchemy_mode=sqlalchemy_mode,
73
+ use_sqladmin=bool(sqladmin),
74
+ use_celery=bool(celery),
75
+ use_docker=bool(docker),
76
+ use_tests=bool(tests),
77
+ use_ci=bool(ci),
78
+ telegram_template=telegram_template,
79
+ )
80
+
81
+
82
+ @app.command()
83
+ def version() -> None:
84
+ console.print(f"fastio {__version__}")
85
+
86
+
87
+ @app.command()
88
+ def create(
89
+ name: str = typer.Argument(..., help="Project directory name."),
90
+ output_dir: Annotated[Path, typer.Option("--output-dir", "-o", dir_okay=True, file_okay=False)] = Path.cwd(),
91
+ mode: Annotated[Optional[Mode], typer.Option("--mode")] = None,
92
+ blueprint: Annotated[Optional[Blueprint], typer.Option("--blueprint")] = None,
93
+ database: Annotated[Optional[Database], typer.Option("--database")] = None,
94
+ sqlalchemy_mode: Annotated[Optional[AlchemyMode], typer.Option("--sqlalchemy")] = None,
95
+ sqladmin: Annotated[Optional[bool], typer.Option("--sqladmin/--no-sqladmin")] = None,
96
+ celery: Annotated[Optional[bool], typer.Option("--celery/--no-celery")] = None,
97
+ docker: Annotated[Optional[bool], typer.Option("--docker/--no-docker")] = None,
98
+ tests: Annotated[Optional[bool], typer.Option("--tests/--no-tests")] = None,
99
+ ci: Annotated[Optional[bool], typer.Option("--ci/--no-ci")] = None,
100
+ interactive: Annotated[bool, typer.Option("--interactive/--no-interactive")] = False,
101
+ telegram_template: Annotated[Optional[TelegramTemplate], typer.Option("--telegram-template")] = None,
102
+ ) -> None:
103
+ options = _build_options(
104
+ name=name,
105
+ output_dir=output_dir,
106
+ mode=mode,
107
+ blueprint=blueprint,
108
+ database=database,
109
+ sqlalchemy_mode=sqlalchemy_mode,
110
+ sqladmin=sqladmin,
111
+ celery=celery,
112
+ docker=docker,
113
+ tests=tests,
114
+ ci=ci,
115
+ interactive=interactive,
116
+ telegram_template=telegram_template,
117
+ ).normalized()
118
+
119
+ if options.project_dir.exists():
120
+ raise typer.BadParameter(f"Destination already exists: {options.project_dir}")
121
+
122
+ generator_map = {
123
+ "service": ServiceGenerator,
124
+ "monolith": MonolithGenerator,
125
+ "monorepo": MonorepoGenerator,
126
+ }
127
+ generator = generator_map[options.mode](options)
128
+ generator.generate()
129
+
130
+ if options.use_ci:
131
+ workflow_path = options.project_dir / ".github" / "workflows" / "publish.yml"
132
+ workflow_path.parent.mkdir(parents=True, exist_ok=True)
133
+ workflow_path.write_text(generator.render("common/publish.yml.j2"), encoding="utf-8")
134
+
135
+ console.print(
136
+ Panel.fit(
137
+ "\n".join(
138
+ [
139
+ f"[bold green]Created[/bold green] {options.project_dir}",
140
+ f"mode = {options.mode}",
141
+ f"blueprint = {options.blueprint}",
142
+ "",
143
+ "Next steps:",
144
+ f" cd {options.project_dir.name}",
145
+ " uv sync",
146
+ " uv run fastapi dev app.main:app",
147
+ ]
148
+ ),
149
+ title="fastio",
150
+ )
151
+ )
File without changes
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ from fastio.models.options import ProjectOptions
7
+ from fastio.renderers.jinja import get_environment
8
+ from fastio.renderers.writer import write_text
9
+
10
+
11
+ class BaseGenerator:
12
+ def __init__(self, options: ProjectOptions) -> None:
13
+ self.options = options.normalized()
14
+ self.env = get_environment()
15
+
16
+ def render(self, template_name: str, **context: Any) -> str:
17
+ template = self.env.get_template(template_name)
18
+ merged = {
19
+ "project": self.options,
20
+ "project_name": self.options.name,
21
+ "package_name": self.options.package_name,
22
+ **context,
23
+ }
24
+ return template.render(**merged)
25
+
26
+ def write(self, relative_path: str, template_name: str, **context: Any) -> None:
27
+ destination = self.options.project_dir / relative_path
28
+ content = self.render(template_name, **context)
29
+ write_text(destination, content)
30
+
31
+ def ensure_root(self) -> Path:
32
+ self.options.project_dir.mkdir(parents=True, exist_ok=False)
33
+ return self.options.project_dir
@@ -0,0 +1,31 @@
1
+ from __future__ import annotations
2
+
3
+ from fastio.generators.base import BaseGenerator
4
+
5
+
6
+ class MonolithGenerator(BaseGenerator):
7
+ def generate(self) -> None:
8
+ self.ensure_root()
9
+ self.write(".gitignore", "common/gitignore.j2")
10
+ self.write("README.md", "monolith/README.md.j2")
11
+ self.write("pyproject.toml", "monolith/pyproject.toml.j2")
12
+ self.write(".env.example", "common/env.example.j2")
13
+ if self.options.use_docker:
14
+ self.write("Dockerfile", "common/Dockerfile.j2")
15
+ self.write("compose.yml", "common/compose.yml.j2")
16
+ self.write("app/__init__.py", "common/empty.py.j2")
17
+ self.write("app/main.py", "monolith/app/main.py.j2")
18
+ self.write("app/core/__init__.py", "common/empty.py.j2")
19
+ self.write("app/core/config.py", "monolith/app/core/config.py.j2")
20
+ self.write("app/modules/__init__.py", "common/empty.py.j2")
21
+ self.write("app/modules/users/__init__.py", "common/empty.py.j2")
22
+ self.write("app/modules/users/api.py", "monolith/app/modules/users/api.py.j2")
23
+ self.write("app/modules/users/models.py", "monolith/app/modules/users/models.py.j2")
24
+ self.write("app/modules/users/schemas.py", "monolith/app/modules/users/schemas.py.j2")
25
+ self.write("app/modules/users/service.py", "monolith/app/modules/users/service.py.j2")
26
+ if self.options.use_celery:
27
+ self.write("app/tasks/__init__.py", "common/empty.py.j2")
28
+ self.write("app/tasks/celery_app.py", "monolith/app/tasks/celery_app.py.j2")
29
+ self.write("alembic.ini", "monolith/alembic.ini.j2")
30
+ if self.options.use_tests:
31
+ self.write("tests/test_smoke.py", "common/test_smoke.py.j2")