fastapi-fastio 0.1.2__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.
- fastapi_fastio-0.1.2.dist-info/METADATA +159 -0
- fastapi_fastio-0.1.2.dist-info/RECORD +91 -0
- fastapi_fastio-0.1.2.dist-info/WHEEL +4 -0
- fastapi_fastio-0.1.2.dist-info/entry_points.txt +2 -0
- fastapi_fastio-0.1.2.dist-info/licenses/LICENSE +21 -0
- fastio/__init__.py +2 -0
- fastio/cli/__init__.py +0 -0
- fastio/cli/app.py +151 -0
- fastio/generators/__init__.py +0 -0
- fastio/generators/base.py +33 -0
- fastio/generators/monolith.py +31 -0
- fastio/generators/monorepo.py +42 -0
- fastio/generators/service.py +92 -0
- fastio/main.py +5 -0
- fastio/models/__init__.py +0 -0
- fastio/models/options.py +65 -0
- fastio/renderers/__init__.py +0 -0
- fastio/renderers/jinja.py +20 -0
- fastio/renderers/writer.py +8 -0
- fastio/templates/common/Dockerfile.j2 +9 -0
- fastio/templates/common/compose.yml.j2 +58 -0
- fastio/templates/common/empty.py.j2 +0 -0
- fastio/templates/common/env.example.j2 +20 -0
- fastio/templates/common/gitignore.j2 +15 -0
- fastio/templates/common/publish.yml.j2 +33 -0
- fastio/templates/common/test_smoke.py.j2 +2 -0
- fastio/templates/monolith/README.md.j2 +11 -0
- fastio/templates/monolith/alembic.ini.j2 +7 -0
- fastio/templates/monolith/app/core/config.py.j2 +22 -0
- fastio/templates/monolith/app/main.py.j2 +11 -0
- fastio/templates/monolith/app/modules/users/api.py.j2 +8 -0
- fastio/templates/monolith/app/modules/users/models.py.j2 +2 -0
- fastio/templates/monolith/app/modules/users/schemas.py.j2 +6 -0
- fastio/templates/monolith/app/modules/users/service.py.j2 +3 -0
- fastio/templates/monolith/app/tasks/celery_app.py.j2 +18 -0
- fastio/templates/monolith/pyproject.toml.j2 +43 -0
- fastio/templates/monorepo/README.md.j2 +9 -0
- fastio/templates/monorepo/packages/shared-auth/README.md.j2 +3 -0
- fastio/templates/monorepo/packages/shared-clients/README.md.j2 +3 -0
- fastio/templates/monorepo/packages/shared-events/README.md.j2 +3 -0
- fastio/templates/monorepo/packages/shared-schemas/README.md.j2 +3 -0
- fastio/templates/monorepo/pyproject.toml.j2 +11 -0
- fastio/templates/service/README.md.j2 +47 -0
- fastio/templates/service/alembic.ini.j2 +7 -0
- fastio/templates/service/app/admin.py.j2 +137 -0
- fastio/templates/service/app/api/deps.py.j2 +13 -0
- fastio/templates/service/app/api/v1/airdrop.py.j2 +35 -0
- fastio/templates/service/app/api/v1/api.py.j2 +33 -0
- fastio/templates/service/app/api/v1/items.py.j2 +18 -0
- fastio/templates/service/app/api/v1/members.py.j2 +46 -0
- fastio/templates/service/app/api/v1/moderation.py.j2 +28 -0
- fastio/templates/service/app/api/v1/orders.py.j2 +28 -0
- fastio/templates/service/app/api/v1/products.py.j2 +35 -0
- fastio/templates/service/app/api/v1/profile.py.j2 +8 -0
- fastio/templates/service/app/bot/bot.py.j2 +7 -0
- fastio/templates/service/app/bot/handlers/airdrop.py.j2 +90 -0
- fastio/templates/service/app/bot/handlers/ecommerce.py.j2 +81 -0
- fastio/templates/service/app/bot/handlers/membership.py.j2 +57 -0
- fastio/templates/service/app/bot/handlers/police_group.py.j2 +111 -0
- fastio/templates/service/app/bot/handlers.py.j2 +17 -0
- fastio/templates/service/app/core/config.py.j2 +29 -0
- fastio/templates/service/app/core/security.py.j2 +2 -0
- fastio/templates/service/app/db/base.py.j2 +14 -0
- fastio/templates/service/app/db/models/item.py.j2 +12 -0
- fastio/templates/service/app/db/models/member.py.j2 +15 -0
- fastio/templates/service/app/db/models/order.py.j2 +18 -0
- fastio/templates/service/app/db/models/participant.py.j2 +18 -0
- fastio/templates/service/app/db/models/product.py.j2 +15 -0
- fastio/templates/service/app/db/models/report.py.j2 +26 -0
- fastio/templates/service/app/db/session.py.j2 +7 -0
- fastio/templates/service/app/main.py.j2 +23 -0
- fastio/templates/service/app/main_telegram.py.j2 +37 -0
- fastio/templates/service/app/schemas/item.py.j2 +13 -0
- fastio/templates/service/app/schemas/member.py.j2 +16 -0
- fastio/templates/service/app/schemas/order.py.j2 +18 -0
- fastio/templates/service/app/schemas/participant.py.j2 +20 -0
- fastio/templates/service/app/schemas/product.py.j2 +27 -0
- fastio/templates/service/app/schemas/report.py.j2 +27 -0
- fastio/templates/service/app/schemas/user.py.j2 +6 -0
- fastio/templates/service/app/services/airdrop_service.py.j2 +81 -0
- fastio/templates/service/app/services/item_service.py.j2 +21 -0
- fastio/templates/service/app/services/member_service.py.j2 +46 -0
- fastio/templates/service/app/services/moderation_service.py.j2 +70 -0
- fastio/templates/service/app/services/shop_service.py.j2 +96 -0
- fastio/templates/service/app/tasks/celery_app.py.j2 +18 -0
- fastio/templates/service/app/tasks/item_tasks.py.j2 +6 -0
- fastio/templates/service/app/tasks/user_tasks.py.j2 +21 -0
- fastio/templates/service/app/users/auth.py.j2 +1 -0
- fastio/templates/service/app/users/manager.py.j2 +1 -0
- fastio/templates/service/app/users/oauth.py.j2 +1 -0
- fastio/templates/service/pyproject.toml.j2 +46 -0
|
@@ -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,91 @@
|
|
|
1
|
+
fastio/__init__.py,sha256=ArE6rYaXsyJRb5LF9eUeRKvdvw715SpX6KFe3vWKp-c,48
|
|
2
|
+
fastio/main.py,sha256=D6dseHUsOw4XvTELxm0E8qhQv046BXieM9HyyKMntr4,62
|
|
3
|
+
fastio/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
fastio/cli/app.py,sha256=Ikdc3OIA8CX7RhvFofw6I8_hgq6MEsqmkuXFicschs8,6014
|
|
5
|
+
fastio/generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
fastio/generators/base.py,sha256=iuGjydAixukHSG5Ov1rKwTieOIuO_rTDQApfoIe98P0,1138
|
|
7
|
+
fastio/generators/monolith.py,sha256=ExU4qCQD2HrXy2dkt_UXXtsqiN_ZY4sJf4_L-9_TgLw,1723
|
|
8
|
+
fastio/generators/monorepo.py,sha256=y-k20rd673v6mzJO_qEJ8uNTrgb5gyjrIaD1HRbZuak,3340
|
|
9
|
+
fastio/generators/service.py,sha256=X2A9FsWFsYXpRgXi7HNlBtR4vbjtYot2Mk2FpWZlm0s,6142
|
|
10
|
+
fastio/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
fastio/models/options.py,sha256=NRBIEEvuMF5FzkwVa-5sWtu9dQ7tWwtSy3-_CynL4As,1955
|
|
12
|
+
fastio/renderers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
fastio/renderers/jinja.py,sha256=_eAgAJLt3ZLG_VmKlmki_M9DyLhXja-S8RoBiFL0KzA,585
|
|
14
|
+
fastio/renderers/writer.py,sha256=ukEgWXfU_gU3kQlAVw98pyr3tWEdfIf7t9zkmeqDsXU,225
|
|
15
|
+
fastio/templates/common/Dockerfile.j2,sha256=BVAfvdSO15kY3kg4Y618kgjYEgsCgH0HmuPy8G-YYFA,196
|
|
16
|
+
fastio/templates/common/compose.yml.j2,sha256=M272RRXe6eBoFBHtnLWqGKNDDTzZJGWdUD2obp1evUo,1270
|
|
17
|
+
fastio/templates/common/empty.py.j2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
fastio/templates/common/env.example.j2,sha256=g0JSmBC-127KMP8p3h6F1BBZOdrIujnQIFIb_CQTTPk,558
|
|
19
|
+
fastio/templates/common/gitignore.j2,sha256=ijUWFuFD59FtSMUziT1HmIl5vf4Mzg1Gy2VBICB77sw,141
|
|
20
|
+
fastio/templates/common/publish.yml.j2,sha256=qRgVlknGmAZF-JAugF9tgdsgTg9vu5Ld8DHRO7qcFKk,593
|
|
21
|
+
fastio/templates/common/test_smoke.py.j2,sha256=zs-Q2949bNmLCW3n7tJD-afDyiHZRuudzF8Rgc7OLMc,42
|
|
22
|
+
fastio/templates/monolith/README.md.j2,sha256=M5Jez6X0aJIL4GJwmvOaN50Lx0vpubTYIeFme-IdDV0,159
|
|
23
|
+
fastio/templates/monolith/alembic.ini.j2,sha256=Z8tBmcO-2Us1MC_R32dw87qfEnHFqtZhzUegXTuqhWg,242
|
|
24
|
+
fastio/templates/monolith/pyproject.toml.j2,sha256=w-husuowK20ljrnoT-MJVwjrOKvJ3XaSMqrTZ4UnTrg,943
|
|
25
|
+
fastio/templates/monolith/app/main.py.j2,sha256=ItlWRLHSJjALjYHLE5JewkHrgE6O7opweXfrpEPf_ZE,305
|
|
26
|
+
fastio/templates/monolith/app/core/config.py.j2,sha256=ghlcNaEJef2vzuQtGEm3bN1chimQZq9MmHve74nxmjw,711
|
|
27
|
+
fastio/templates/monolith/app/modules/users/api.py.j2,sha256=oAsnBa9dxaO0ZqpEIMvKLC8lLWvNNDSEpS-NaChg8ww,168
|
|
28
|
+
fastio/templates/monolith/app/modules/users/models.py.j2,sha256=DGisa924ifa3PqFPagrvfVSBgLiGtItSbfTqCMZ4c0Y,21
|
|
29
|
+
fastio/templates/monolith/app/modules/users/schemas.py.j2,sha256=6SuT_NVX0BPO4KX2UdVhoIV7Z5ehz3kCUci6q4wRhhk,87
|
|
30
|
+
fastio/templates/monolith/app/modules/users/service.py.j2,sha256=W005DOa4g5ElkF9JaTaoGy7kBfELY1nq5JB9MojZFrQ,128
|
|
31
|
+
fastio/templates/monolith/app/tasks/celery_app.py.j2,sha256=7wdGrlzgKX4ANCgHXgmkY-wl-11vlEtRjm9Q_EBXb5I,381
|
|
32
|
+
fastio/templates/monorepo/README.md.j2,sha256=glXyq0Kb4ZKBl0Ine4HgjGbcfO4-ZbyXrqQ76-sHNFg,182
|
|
33
|
+
fastio/templates/monorepo/pyproject.toml.j2,sha256=jWnsm27p3uW5YVsWyfKtLLe5a4G5uJf4WVOuv6qmsXs,226
|
|
34
|
+
fastio/templates/monorepo/packages/shared-auth/README.md.j2,sha256=Ja4ugpvVBd1Hht2DUymP2GwnQMPMMbzP49X4pM7qMR0,77
|
|
35
|
+
fastio/templates/monorepo/packages/shared-clients/README.md.j2,sha256=W___0Kos4rtsK9WJD5r7CYZ_zU4IrmZHcewLW-M25QI,81
|
|
36
|
+
fastio/templates/monorepo/packages/shared-events/README.md.j2,sha256=patHnc-XS0rcjaPjx9EoXfgdNHf51ljb5xpX91E3pZk,73
|
|
37
|
+
fastio/templates/monorepo/packages/shared-schemas/README.md.j2,sha256=XgfIqmgiCKLOW7BjVrZ5RB7X-Xeeqe5UKeVqVhxrdV8,79
|
|
38
|
+
fastio/templates/service/README.md.j2,sha256=SPH6D5O6oBiWi1p_4klGGsvY8mrlp8ivUH2rpX2V7A0,856
|
|
39
|
+
fastio/templates/service/alembic.ini.j2,sha256=Z8tBmcO-2Us1MC_R32dw87qfEnHFqtZhzUegXTuqhWg,242
|
|
40
|
+
fastio/templates/service/pyproject.toml.j2,sha256=3A1bxX9aV1WFubyqKa_1_PX9w-RJ6Dwn_PgHUoBPYA8,1022
|
|
41
|
+
fastio/templates/service/app/admin.py.j2,sha256=vyZpVnqxQ4AG79-qEBAsIu7MICo0-16t2T8Q0XrjbAE,5555
|
|
42
|
+
fastio/templates/service/app/main.py.j2,sha256=Zpweture5fvt5Djfwcn1eIfPAQu13vpZhUGOpCPXulI,493
|
|
43
|
+
fastio/templates/service/app/main_telegram.py.j2,sha256=IdmRT2bCKBWo3rjxoPXMKWlmdAFxuXDoCny0geY4idc,891
|
|
44
|
+
fastio/templates/service/app/api/deps.py.j2,sha256=ouhJwaW2FeVtdif3RqMcmbs7C3cATQK85dls4ydYts8,247
|
|
45
|
+
fastio/templates/service/app/api/v1/airdrop.py.j2,sha256=KpLr9NEbwreMH9yT6vmrGD3kt81gSkKSh723Xk8UHs4,1528
|
|
46
|
+
fastio/templates/service/app/api/v1/api.py.j2,sha256=JF4AU6hZhwWDV0VNdpl8VjaX94oFl5qGpxXHxRcPGrw,1956
|
|
47
|
+
fastio/templates/service/app/api/v1/items.py.j2,sha256=2BCH5lfTA-V2pFApGmWJVhpLIPIP5awoDfMqYfMlL7k,603
|
|
48
|
+
fastio/templates/service/app/api/v1/members.py.j2,sha256=gaklirbQ8KW86qVmdkuZXALAbjqHtrjT1R6gVT-1rcY,1622
|
|
49
|
+
fastio/templates/service/app/api/v1/moderation.py.j2,sha256=KLxFGJGN7Hddh7jYTAzmoeAqP_GRe-NBoILPL9RwiI8,1019
|
|
50
|
+
fastio/templates/service/app/api/v1/orders.py.j2,sha256=Rh1aY5jkvXtP7XjviJbH1G-fxEYX2jIssbsQ2AgbBho,1030
|
|
51
|
+
fastio/templates/service/app/api/v1/products.py.j2,sha256=SdTVC53W1nNu7hqIPZ-QAWgx4oe94q1l0VVazSptwn0,1495
|
|
52
|
+
fastio/templates/service/app/api/v1/profile.py.j2,sha256=wUmfTXD6li97rQM1_qOrMt4zbmU-kdglo61dEp9z2wI,172
|
|
53
|
+
fastio/templates/service/app/bot/bot.py.j2,sha256=wwaj3svxc_eUHRIvwgXzgL3p0W8Hq0r_1jrA5iz0dTo,193
|
|
54
|
+
fastio/templates/service/app/bot/handlers.py.j2,sha256=l0FEGYqYCu3Zgo0XEVzzZZOUjN_VMd4W9tIKxu2pXio,712
|
|
55
|
+
fastio/templates/service/app/bot/handlers/airdrop.py.j2,sha256=DbL1TyospE_5DXbntezmIslVcBeczpzElw2zafB3s5o,3376
|
|
56
|
+
fastio/templates/service/app/bot/handlers/ecommerce.py.j2,sha256=cYpI2FMrl5eowMoa8sbkky_Dmp49C0NY507EFNPnmz8,2948
|
|
57
|
+
fastio/templates/service/app/bot/handlers/membership.py.j2,sha256=VHpOMvbgxl0aVxyhzrGFBtvpRnd0eUvbN4JjL7Zz4Hg,2157
|
|
58
|
+
fastio/templates/service/app/bot/handlers/police_group.py.j2,sha256=toFG3TGP3HAWkvwZ9xd5R3OdH6kHinzC3lrmwX58JXI,4381
|
|
59
|
+
fastio/templates/service/app/core/config.py.j2,sha256=Uo02avFTlEecStGzf0zJ0kXZWVKFXqTe73lhlIOU32g,902
|
|
60
|
+
fastio/templates/service/app/core/security.py.j2,sha256=QlXygrwSXI3tQLxZbL9v00lIRyvMRoWzYUYgx7eGVho,59
|
|
61
|
+
fastio/templates/service/app/db/base.py.j2,sha256=hEsUrA1w1ixEUgdwhMuDiMYuDYc33gAdbRJGtYdxS1w,431
|
|
62
|
+
fastio/templates/service/app/db/session.py.j2,sha256=jGps9-xQUH6zfwSCFnIkv_etV-JLPY2SXf84aUHnMFE,272
|
|
63
|
+
fastio/templates/service/app/db/models/item.py.j2,sha256=PItVDW8MArArO0mgQ4ouIxzPjvjvQ_A3GdKpA0aJ10g,403
|
|
64
|
+
fastio/templates/service/app/db/models/member.py.j2,sha256=c6g_avU_dCd34e_EmY1sLzAi4S0_qHeS3jOqRECZ-bM,645
|
|
65
|
+
fastio/templates/service/app/db/models/order.py.j2,sha256=PbN5cCss6O1-tIYKO9pqrpt1ToMjUa8RMEfXfl3HwaI,836
|
|
66
|
+
fastio/templates/service/app/db/models/participant.py.j2,sha256=qJZhSYPR3sPpjhatsI02Hi0u217SS4cJQZV1R63CE0s,900
|
|
67
|
+
fastio/templates/service/app/db/models/product.py.j2,sha256=EjKO0RQHF42iJVzaTznYK_x-iMVNk_V7Vkzg8c4PbfI,601
|
|
68
|
+
fastio/templates/service/app/db/models/report.py.j2,sha256=oQclzRffm2pt4Ckq747YqvzbRpQ-2tgpuE0V00S8OSA,1064
|
|
69
|
+
fastio/templates/service/app/schemas/item.py.j2,sha256=xknAZJuspUOE7MPC5DjDe91Yo5SDi77pEW64YnxNFTc,210
|
|
70
|
+
fastio/templates/service/app/schemas/member.py.j2,sha256=ppFDBfmM8ZjDGpizhQ4syBlfgCOyHHYe_SSaEnSw3UQ,300
|
|
71
|
+
fastio/templates/service/app/schemas/order.py.j2,sha256=YF2B6WWzNA1kcGcvx9gKt7fMpej9kGRoTCR9Ymhg29g,337
|
|
72
|
+
fastio/templates/service/app/schemas/participant.py.j2,sha256=uXBkqt4tCn3rZFmB2Juex3V5FWFdQN5Wg4fBtluiRVg,406
|
|
73
|
+
fastio/templates/service/app/schemas/product.py.j2,sha256=yCyqtNQTdlENdzJPk8a-1kvIYqy-9s01TIGq8r7dNN4,528
|
|
74
|
+
fastio/templates/service/app/schemas/report.py.j2,sha256=JvhIMbhIwk1yy8fKIdbA1y9BpjKKBOUCMsWI6cj1TIw,522
|
|
75
|
+
fastio/templates/service/app/schemas/user.py.j2,sha256=6SuT_NVX0BPO4KX2UdVhoIV7Z5ehz3kCUci6q4wRhhk,87
|
|
76
|
+
fastio/templates/service/app/services/airdrop_service.py.j2,sha256=xgOVh9Wap2MXXoLG1upLcwfuYyOp4bt9F-hhpgahTFg,2772
|
|
77
|
+
fastio/templates/service/app/services/item_service.py.j2,sha256=0J2WgfwJWwFJ_4UiQ0K-37YExKssN-6UTVNyHmpR4NY,685
|
|
78
|
+
fastio/templates/service/app/services/member_service.py.j2,sha256=FO9zvFcrGPvdQxgR80ezehslJcI-KSyGY1a23dVZMig,1430
|
|
79
|
+
fastio/templates/service/app/services/moderation_service.py.j2,sha256=8btMw0ii7ajiuvnsRbicaTR2okbwXdIlC9jhRGbkTsg,2271
|
|
80
|
+
fastio/templates/service/app/services/shop_service.py.j2,sha256=OGjLn1zGlU9nUV7IfDWt97BuLNOnfjlEKTy1XKtvfJc,3363
|
|
81
|
+
fastio/templates/service/app/tasks/celery_app.py.j2,sha256=7wdGrlzgKX4ANCgHXgmkY-wl-11vlEtRjm9Q_EBXb5I,381
|
|
82
|
+
fastio/templates/service/app/tasks/item_tasks.py.j2,sha256=GGUB6p_RQZ4dL3FsGT-CnDL1aqbFtf54QcFBqszmGiI,152
|
|
83
|
+
fastio/templates/service/app/tasks/user_tasks.py.j2,sha256=J58YUcUJswmwcT902z_ugbQZ3ttXLb9xBqqiehimMD4,696
|
|
84
|
+
fastio/templates/service/app/users/auth.py.j2,sha256=GiivRrKBwxqup5UEavvQsnBh9nxUlQ_Qa7-AIE3GV5c,44
|
|
85
|
+
fastio/templates/service/app/users/manager.py.j2,sha256=SP797yowIavXGZDZVDr5haGokT7NWIb3wwXNZTtO37Y,41
|
|
86
|
+
fastio/templates/service/app/users/oauth.py.j2,sha256=masmHlAwd9tpswJf73nzpnld1bW6JHuomeoAW7-vYmQ,85
|
|
87
|
+
fastapi_fastio-0.1.2.dist-info/METADATA,sha256=Q-WQHuDY9Rs1QVu0b1IEF7llMxMndghkJXoN3Xo6vI0,4256
|
|
88
|
+
fastapi_fastio-0.1.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
89
|
+
fastapi_fastio-0.1.2.dist-info/entry_points.txt,sha256=jRLnQVTrDIKaiKTpDoKXvZBDMTp44MOSeyqgXPUMLOc,43
|
|
90
|
+
fastapi_fastio-0.1.2.dist-info/licenses/LICENSE,sha256=ESYyLizI0WWtxMeS7rGVcX3ivMezm-HOd5WdeOh-9oU,1056
|
|
91
|
+
fastapi_fastio-0.1.2.dist-info/RECORD,,
|
|
@@ -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.
|
fastio/__init__.py
ADDED
fastio/cli/__init__.py
ADDED
|
File without changes
|
fastio/cli/app.py
ADDED
|
@@ -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")
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fastio.generators.base import BaseGenerator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MonorepoGenerator(BaseGenerator):
|
|
7
|
+
def generate(self) -> None:
|
|
8
|
+
self.ensure_root()
|
|
9
|
+
self.write("README.md", "monorepo/README.md.j2")
|
|
10
|
+
self.write("pyproject.toml", "monorepo/pyproject.toml.j2")
|
|
11
|
+
self.write("packages/shared-schemas/README.md", "monorepo/packages/shared-schemas/README.md.j2")
|
|
12
|
+
self.write("packages/shared-auth/README.md", "monorepo/packages/shared-auth/README.md.j2")
|
|
13
|
+
self.write("packages/shared-events/README.md", "monorepo/packages/shared-events/README.md.j2")
|
|
14
|
+
self.write("packages/shared-clients/README.md", "monorepo/packages/shared-clients/README.md.j2")
|
|
15
|
+
self.write("services/example-service/README.md", "service/README.md.j2")
|
|
16
|
+
self.write("services/example-service/pyproject.toml", "service/pyproject.toml.j2")
|
|
17
|
+
self.write("services/example-service/.env.example", "common/env.example.j2")
|
|
18
|
+
self.write("services/example-service/Dockerfile", "common/Dockerfile.j2")
|
|
19
|
+
self.write("services/example-service/compose.yml", "common/compose.yml.j2")
|
|
20
|
+
self.write("services/example-service/app/__init__.py", "common/empty.py.j2")
|
|
21
|
+
self.write("services/example-service/app/main.py", "service/app/main.py.j2")
|
|
22
|
+
self.write("services/example-service/app/admin.py", "service/app/admin.py.j2")
|
|
23
|
+
self.write("services/example-service/app/core/__init__.py", "common/empty.py.j2")
|
|
24
|
+
self.write("services/example-service/app/core/config.py", "service/app/core/config.py.j2")
|
|
25
|
+
self.write("services/example-service/app/api/__init__.py", "common/empty.py.j2")
|
|
26
|
+
self.write("services/example-service/app/api/deps.py", "service/app/api/deps.py.j2")
|
|
27
|
+
self.write("services/example-service/app/api/v1/__init__.py", "common/empty.py.j2")
|
|
28
|
+
self.write("services/example-service/app/api/v1/api.py", "service/app/api/v1/api.py.j2")
|
|
29
|
+
self.write("services/example-service/app/api/v1/items.py", "service/app/api/v1/items.py.j2")
|
|
30
|
+
self.write("services/example-service/app/db/__init__.py", "common/empty.py.j2")
|
|
31
|
+
self.write("services/example-service/app/db/base.py", "service/app/db/base.py.j2")
|
|
32
|
+
self.write("services/example-service/app/db/session.py", "service/app/db/session.py.j2")
|
|
33
|
+
self.write("services/example-service/app/db/models/__init__.py", "common/empty.py.j2")
|
|
34
|
+
self.write("services/example-service/app/db/models/item.py", "service/app/db/models/item.py.j2")
|
|
35
|
+
self.write("services/example-service/app/schemas/__init__.py", "common/empty.py.j2")
|
|
36
|
+
self.write("services/example-service/app/schemas/item.py", "service/app/schemas/item.py.j2")
|
|
37
|
+
self.write("services/example-service/app/services/__init__.py", "common/empty.py.j2")
|
|
38
|
+
self.write("services/example-service/app/services/item_service.py", "service/app/services/item_service.py.j2")
|
|
39
|
+
self.write("services/example-service/app/tasks/__init__.py", "common/empty.py.j2")
|
|
40
|
+
self.write("services/example-service/app/tasks/celery_app.py", "service/app/tasks/celery_app.py.j2")
|
|
41
|
+
self.write("services/example-service/app/tasks/item_tasks.py", "service/app/tasks/item_tasks.py.j2")
|
|
42
|
+
self.write("services/example-service/alembic.ini", "service/alembic.ini.j2")
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from fastio.generators.base import BaseGenerator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ServiceGenerator(BaseGenerator):
|
|
7
|
+
def generate(self) -> None:
|
|
8
|
+
self.ensure_root()
|
|
9
|
+
self.write(".gitignore", "common/gitignore.j2")
|
|
10
|
+
self.write("README.md", "service/README.md.j2")
|
|
11
|
+
self.write("pyproject.toml", "service/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
|
+
if self.options.blueprint == "telegram-bot":
|
|
18
|
+
self.write("app/main.py", "service/app/main_telegram.py.j2")
|
|
19
|
+
else:
|
|
20
|
+
self.write("app/main.py", "service/app/main.py.j2")
|
|
21
|
+
if self.options.use_sqladmin:
|
|
22
|
+
self.write("app/admin.py", "service/app/admin.py.j2")
|
|
23
|
+
self.write("app/core/__init__.py", "common/empty.py.j2")
|
|
24
|
+
self.write("app/core/config.py", "service/app/core/config.py.j2")
|
|
25
|
+
self.write("app/api/__init__.py", "common/empty.py.j2")
|
|
26
|
+
self.write("app/api/deps.py", "service/app/api/deps.py.j2")
|
|
27
|
+
self.write("app/api/v1/__init__.py", "common/empty.py.j2")
|
|
28
|
+
self.write("app/api/v1/api.py", "service/app/api/v1/api.py.j2")
|
|
29
|
+
self.write("app/db/__init__.py", "common/empty.py.j2")
|
|
30
|
+
self.write("app/db/base.py", "service/app/db/base.py.j2")
|
|
31
|
+
self.write("app/db/session.py", "service/app/db/session.py.j2")
|
|
32
|
+
self.write("app/schemas/__init__.py", "common/empty.py.j2")
|
|
33
|
+
self.write("app/services/__init__.py", "common/empty.py.j2")
|
|
34
|
+
if self.options.use_celery:
|
|
35
|
+
self.write("app/tasks/__init__.py", "common/empty.py.j2")
|
|
36
|
+
self.write("app/tasks/celery_app.py", "service/app/tasks/celery_app.py.j2")
|
|
37
|
+
self.write("alembic.ini", "service/alembic.ini.j2")
|
|
38
|
+
if self.options.use_tests:
|
|
39
|
+
self.write("tests/test_smoke.py", "common/test_smoke.py.j2")
|
|
40
|
+
|
|
41
|
+
if self.options.blueprint == "crud-service":
|
|
42
|
+
self.write("app/api/v1/items.py", "service/app/api/v1/items.py.j2")
|
|
43
|
+
self.write("app/db/models/__init__.py", "common/empty.py.j2")
|
|
44
|
+
self.write("app/db/models/item.py", "service/app/db/models/item.py.j2")
|
|
45
|
+
self.write("app/schemas/item.py", "service/app/schemas/item.py.j2")
|
|
46
|
+
self.write("app/services/item_service.py", "service/app/services/item_service.py.j2")
|
|
47
|
+
if self.options.use_celery:
|
|
48
|
+
self.write("app/tasks/item_tasks.py", "service/app/tasks/item_tasks.py.j2")
|
|
49
|
+
elif self.options.blueprint == "telegram-bot":
|
|
50
|
+
self.write("app/bot/__init__.py", "common/empty.py.j2")
|
|
51
|
+
self.write("app/bot/bot.py", "service/app/bot/bot.py.j2")
|
|
52
|
+
self.write("app/db/models/__init__.py", "common/empty.py.j2")
|
|
53
|
+
tpl = self.options.telegram_template
|
|
54
|
+
if tpl == "membership":
|
|
55
|
+
self.write("app/bot/handlers.py", "service/app/bot/handlers/membership.py.j2")
|
|
56
|
+
self.write("app/db/models/member.py", "service/app/db/models/member.py.j2")
|
|
57
|
+
self.write("app/schemas/member.py", "service/app/schemas/member.py.j2")
|
|
58
|
+
self.write("app/services/member_service.py", "service/app/services/member_service.py.j2")
|
|
59
|
+
self.write("app/api/v1/members.py", "service/app/api/v1/members.py.j2")
|
|
60
|
+
elif tpl == "police-group":
|
|
61
|
+
self.write("app/bot/handlers.py", "service/app/bot/handlers/police_group.py.j2")
|
|
62
|
+
self.write("app/db/models/report.py", "service/app/db/models/report.py.j2")
|
|
63
|
+
self.write("app/schemas/report.py", "service/app/schemas/report.py.j2")
|
|
64
|
+
self.write("app/services/moderation_service.py", "service/app/services/moderation_service.py.j2")
|
|
65
|
+
self.write("app/api/v1/moderation.py", "service/app/api/v1/moderation.py.j2")
|
|
66
|
+
elif tpl == "airdrop":
|
|
67
|
+
self.write("app/bot/handlers.py", "service/app/bot/handlers/airdrop.py.j2")
|
|
68
|
+
self.write("app/db/models/participant.py", "service/app/db/models/participant.py.j2")
|
|
69
|
+
self.write("app/schemas/participant.py", "service/app/schemas/participant.py.j2")
|
|
70
|
+
self.write("app/services/airdrop_service.py", "service/app/services/airdrop_service.py.j2")
|
|
71
|
+
self.write("app/api/v1/airdrop.py", "service/app/api/v1/airdrop.py.j2")
|
|
72
|
+
elif tpl == "ecommerce":
|
|
73
|
+
self.write("app/bot/handlers.py", "service/app/bot/handlers/ecommerce.py.j2")
|
|
74
|
+
self.write("app/db/models/product.py", "service/app/db/models/product.py.j2")
|
|
75
|
+
self.write("app/db/models/order.py", "service/app/db/models/order.py.j2")
|
|
76
|
+
self.write("app/schemas/product.py", "service/app/schemas/product.py.j2")
|
|
77
|
+
self.write("app/schemas/order.py", "service/app/schemas/order.py.j2")
|
|
78
|
+
self.write("app/services/shop_service.py", "service/app/services/shop_service.py.j2")
|
|
79
|
+
self.write("app/api/v1/products.py", "service/app/api/v1/products.py.j2")
|
|
80
|
+
self.write("app/api/v1/orders.py", "service/app/api/v1/orders.py.j2")
|
|
81
|
+
else:
|
|
82
|
+
self.write("app/bot/handlers.py", "service/app/bot/handlers.py.j2")
|
|
83
|
+
elif self.options.blueprint == "user-service":
|
|
84
|
+
self.write("app/api/v1/profile.py", "service/app/api/v1/profile.py.j2")
|
|
85
|
+
self.write("app/core/security.py", "service/app/core/security.py.j2")
|
|
86
|
+
self.write("app/schemas/user.py", "service/app/schemas/user.py.j2")
|
|
87
|
+
self.write("app/users/__init__.py", "common/empty.py.j2")
|
|
88
|
+
self.write("app/users/auth.py", "service/app/users/auth.py.j2")
|
|
89
|
+
self.write("app/users/manager.py", "service/app/users/manager.py.j2")
|
|
90
|
+
self.write("app/users/oauth.py", "service/app/users/oauth.py.j2")
|
|
91
|
+
if self.options.use_celery:
|
|
92
|
+
self.write("app/tasks/user_tasks.py", "service/app/tasks/user_tasks.py.j2")
|