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
fastio/main.py
ADDED
|
File without changes
|
fastio/models/options.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Literal, Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field, field_validator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Mode = Literal["service", "monolith", "monorepo"]
|
|
10
|
+
Blueprint = Literal["base", "crud-service", "user-service", "telegram-bot"]
|
|
11
|
+
Database = Literal["sqlite", "postgres"]
|
|
12
|
+
AlchemyMode = Literal["sync", "async"]
|
|
13
|
+
TelegramTemplate = Literal["membership", "police-group", "airdrop", "ecommerce"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ProjectOptions(BaseModel):
|
|
17
|
+
name: str = Field(min_length=2)
|
|
18
|
+
output_dir: Path
|
|
19
|
+
mode: Mode = "service"
|
|
20
|
+
blueprint: Blueprint = "base"
|
|
21
|
+
database: Database = "sqlite"
|
|
22
|
+
sqlalchemy_mode: AlchemyMode = "sync"
|
|
23
|
+
use_sqladmin: bool = True
|
|
24
|
+
use_celery: bool = True
|
|
25
|
+
use_docker: bool = True
|
|
26
|
+
use_tests: bool = True
|
|
27
|
+
use_ci: bool = True
|
|
28
|
+
use_fastapi_users: bool = False
|
|
29
|
+
use_google_oauth: bool = False
|
|
30
|
+
use_telegram_bot: bool = False
|
|
31
|
+
telegram_template: Optional[TelegramTemplate] = None
|
|
32
|
+
|
|
33
|
+
@field_validator("name")
|
|
34
|
+
@classmethod
|
|
35
|
+
def validate_name(cls, value: str) -> str:
|
|
36
|
+
clean = value.strip()
|
|
37
|
+
if not clean:
|
|
38
|
+
raise ValueError("Project name cannot be empty.")
|
|
39
|
+
return clean
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def project_dir(self) -> Path:
|
|
43
|
+
return self.output_dir / self.name
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def package_name(self) -> str:
|
|
47
|
+
return self.name.replace("-", "_")
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def app_import_path(self) -> str:
|
|
51
|
+
return "app.main:app"
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def uses_async(self) -> bool:
|
|
55
|
+
return self.sqlalchemy_mode == "async"
|
|
56
|
+
|
|
57
|
+
def normalized(self) -> "ProjectOptions":
|
|
58
|
+
data = self.model_dump()
|
|
59
|
+
if self.blueprint == "user-service":
|
|
60
|
+
data["use_fastapi_users"] = True
|
|
61
|
+
data["use_google_oauth"] = True
|
|
62
|
+
data["sqlalchemy_mode"] = "async"
|
|
63
|
+
elif self.blueprint == "telegram-bot":
|
|
64
|
+
data["use_telegram_bot"] = True
|
|
65
|
+
return ProjectOptions(**data)
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from jinja2 import Environment, FileSystemLoader, StrictUndefined, select_autoescape
|
|
7
|
+
|
|
8
|
+
_TEMPLATES_DIR = Path(__file__).parent.parent / "templates"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@lru_cache(maxsize=1)
|
|
12
|
+
def get_environment() -> Environment:
|
|
13
|
+
return Environment(
|
|
14
|
+
loader=FileSystemLoader(str(_TEMPLATES_DIR)),
|
|
15
|
+
autoescape=select_autoescape(enabled_extensions=("html", "xml")),
|
|
16
|
+
keep_trailing_newline=True,
|
|
17
|
+
lstrip_blocks=True,
|
|
18
|
+
trim_blocks=True,
|
|
19
|
+
undefined=StrictUndefined,
|
|
20
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
app:
|
|
5
|
+
build: .
|
|
6
|
+
ports:
|
|
7
|
+
- "8000:8000"
|
|
8
|
+
environment:
|
|
9
|
+
- DATABASE_URL=postgresql://{{ project_name }}:password@db:5432/{{ project_name }}
|
|
10
|
+
- REDIS_URL=redis://redis:6379/0
|
|
11
|
+
depends_on:
|
|
12
|
+
- db
|
|
13
|
+
- redis
|
|
14
|
+
volumes:
|
|
15
|
+
- .:/app
|
|
16
|
+
command: uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
|
17
|
+
|
|
18
|
+
{% if project.database == "postgres" %}
|
|
19
|
+
db:
|
|
20
|
+
image: postgres:16-alpine
|
|
21
|
+
environment:
|
|
22
|
+
- POSTGRES_USER={{ project_name }}
|
|
23
|
+
- POSTGRES_PASSWORD=password
|
|
24
|
+
- POSTGRES_DB={{ project_name }}
|
|
25
|
+
ports:
|
|
26
|
+
- "5432:5432"
|
|
27
|
+
volumes:
|
|
28
|
+
- postgres_data:/var/lib/postgresql/data
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
31
|
+
{% if project.use_celery %}
|
|
32
|
+
redis:
|
|
33
|
+
image: redis:7-alpine
|
|
34
|
+
ports:
|
|
35
|
+
- "6379:6379"
|
|
36
|
+
volumes:
|
|
37
|
+
- redis_data:/data
|
|
38
|
+
|
|
39
|
+
celery:
|
|
40
|
+
build: .
|
|
41
|
+
command: uv run celery -A app.tasks.celery_app worker --loglevel=info
|
|
42
|
+
environment:
|
|
43
|
+
- DATABASE_URL=postgresql://{{ project_name }}:password@db:5432/{{ project_name }}
|
|
44
|
+
- REDIS_URL=redis://redis:6379/0
|
|
45
|
+
depends_on:
|
|
46
|
+
- db
|
|
47
|
+
- redis
|
|
48
|
+
volumes:
|
|
49
|
+
- .:/app
|
|
50
|
+
{% endif %}
|
|
51
|
+
|
|
52
|
+
volumes:
|
|
53
|
+
{% if project.database == "postgres" %}
|
|
54
|
+
postgres_data:
|
|
55
|
+
{% endif %}
|
|
56
|
+
{% if project.use_celery %}
|
|
57
|
+
redis_data:
|
|
58
|
+
{% endif %}
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
APP_NAME={{ project_name }}
|
|
2
|
+
ENVIRONMENT=local
|
|
3
|
+
DEBUG=true
|
|
4
|
+
{% if project.database == "postgres" %}
|
|
5
|
+
DATABASE_URL=postgresql://{{ project_name }}:password@localhost:5432/{{ project_name }}
|
|
6
|
+
{% else %}
|
|
7
|
+
DATABASE_URL=sqlite:///./{{ package_name }}.db
|
|
8
|
+
{% endif %}
|
|
9
|
+
SECRET_KEY=change-me
|
|
10
|
+
{% if project.use_celery %}
|
|
11
|
+
CELERY_BROKER_URL=redis://localhost:6379/0
|
|
12
|
+
CELERY_RESULT_BACKEND=redis://localhost:6379/1
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% if project.use_google_oauth %}
|
|
15
|
+
GOOGLE_CLIENT_ID=
|
|
16
|
+
GOOGLE_CLIENT_SECRET=
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% if project.use_telegram_bot %}
|
|
19
|
+
TELEGRAM_BOT_TOKEN=
|
|
20
|
+
{% endif %}
|
|
@@ -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,22 @@
|
|
|
1
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Settings(BaseSettings):
|
|
5
|
+
app_name: str = "{{ project_name }}"
|
|
6
|
+
environment: str = "local"
|
|
7
|
+
debug: bool = True
|
|
8
|
+
{% if project.database == "postgres" %}
|
|
9
|
+
database_url: str = "postgresql://{{ project_name }}:password@localhost:5432/{{ project_name }}"
|
|
10
|
+
{% else %}
|
|
11
|
+
database_url: str = "sqlite:///./{{ package_name }}.db"
|
|
12
|
+
{% endif %}
|
|
13
|
+
secret_key: str = "change-me"
|
|
14
|
+
{% if project.use_celery %}
|
|
15
|
+
celery_broker_url: str = "redis://localhost:6379/0"
|
|
16
|
+
celery_result_backend: str = "redis://localhost:6379/1"
|
|
17
|
+
{% endif %}
|
|
18
|
+
|
|
19
|
+
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
settings = Settings()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from fastapi import FastAPI
|
|
2
|
+
|
|
3
|
+
from app.modules.users.api import router as users_router
|
|
4
|
+
|
|
5
|
+
app = FastAPI(title="{{ project_name }}", docs_url="/docs")
|
|
6
|
+
app.include_router(users_router, prefix="/api/v1/users", tags=["users"])
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@app.get("/health/live")
|
|
10
|
+
def live() -> dict[str, str]:
|
|
11
|
+
return {"status": "ok"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from celery import Celery
|
|
2
|
+
|
|
3
|
+
from app.core.config import settings
|
|
4
|
+
|
|
5
|
+
celery_app = Celery(
|
|
6
|
+
"{{ project_name }}",
|
|
7
|
+
broker=settings.celery_broker_url,
|
|
8
|
+
backend=settings.celery_result_backend,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
celery_app.conf.update(
|
|
12
|
+
task_serializer="json",
|
|
13
|
+
accept_content=["json"],
|
|
14
|
+
result_serializer="json",
|
|
15
|
+
timezone="UTC",
|
|
16
|
+
enable_utc=True,
|
|
17
|
+
task_track_started=True,
|
|
18
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_name }}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "{{ project_name }} generated by fastio"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"fastapi[standard]>=0.115.0",
|
|
9
|
+
"sqlalchemy>=2.0.35",
|
|
10
|
+
"alembic>=1.13.2",
|
|
11
|
+
"pydantic>=2.8.2",
|
|
12
|
+
"pydantic-settings>=2.4.0",
|
|
13
|
+
{% if project.use_sqladmin %}
|
|
14
|
+
"sqladmin>=0.18.0",
|
|
15
|
+
{% endif %}
|
|
16
|
+
{% if project.use_celery %}
|
|
17
|
+
"celery[redis]>=5.4.0",
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% if project.uses_async and project.database == "postgres" %}
|
|
20
|
+
"asyncpg>=0.29.0",
|
|
21
|
+
{% elif project.uses_async %}
|
|
22
|
+
"aiosqlite>=0.20.0",
|
|
23
|
+
{% elif project.database == "postgres" %}
|
|
24
|
+
"psycopg2-binary>=2.9.9",
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if project.use_fastapi_users %}
|
|
27
|
+
"fastapi-users[sqlalchemy,oauth]>=13.0.0",
|
|
28
|
+
{% endif %}
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["hatchling>=1.25.0"]
|
|
33
|
+
build-backend = "hatchling.build"
|
|
34
|
+
|
|
35
|
+
[tool.uv]
|
|
36
|
+
package = false
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"pytest>=8.3.2",
|
|
41
|
+
"httpx>=0.27.2",
|
|
42
|
+
"ruff>=0.6.5",
|
|
43
|
+
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
Generated by `fastio`.
|
|
4
|
+
|
|
5
|
+
## Run locally
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
uv run alembic upgrade head
|
|
10
|
+
uv run fastapi dev app.main:app
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Structure
|
|
14
|
+
|
|
15
|
+
- `app/api/v1` for versioned routes
|
|
16
|
+
- `app/services` for business logic
|
|
17
|
+
{% if project.use_celery %}
|
|
18
|
+
- `app/tasks` for Celery jobs
|
|
19
|
+
{% endif %}
|
|
20
|
+
- `app/db` for SQLAlchemy setup
|
|
21
|
+
{% if project.use_sqladmin %}
|
|
22
|
+
- `app/admin.py` for SQLAdmin at `/admin`
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% if project.use_celery %}
|
|
25
|
+
|
|
26
|
+
## Celery
|
|
27
|
+
|
|
28
|
+
Start a worker:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv run celery -A app.tasks.celery_app worker --loglevel=info
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> **Windows:** Celery's default prefork pool is not supported on Windows.
|
|
35
|
+
> Use `--pool=solo` for local development:
|
|
36
|
+
> ```bash
|
|
37
|
+
> uv run celery -A app.tasks.celery_app worker --loglevel=info --pool=solo
|
|
38
|
+
> ```
|
|
39
|
+
{% endif %}
|
|
40
|
+
{% if project.use_docker %}
|
|
41
|
+
|
|
42
|
+
## Docker
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
docker compose up --build
|
|
46
|
+
```
|
|
47
|
+
{% endif %}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from fastapi import FastAPI
|
|
2
|
+
from sqladmin import Admin, ModelView
|
|
3
|
+
|
|
4
|
+
from app.db.session import engine
|
|
5
|
+
|
|
6
|
+
{% if project.blueprint == "crud-service" %}
|
|
7
|
+
from app.db.models.item import Item
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ItemAdmin(ModelView, model=Item):
|
|
11
|
+
name = "Item"
|
|
12
|
+
name_plural = "Items"
|
|
13
|
+
icon = "fa-solid fa-box"
|
|
14
|
+
column_list = [Item.id, Item.name, Item.slug]
|
|
15
|
+
column_searchable_list = [Item.name, Item.slug]
|
|
16
|
+
column_sortable_list = [Item.id, Item.name]
|
|
17
|
+
|
|
18
|
+
{% elif project.blueprint == "user-service" %}
|
|
19
|
+
class UserAdmin:
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "membership" %}
|
|
23
|
+
from app.db.models.member import Member
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MemberAdmin(ModelView, model=Member):
|
|
27
|
+
name = "Member"
|
|
28
|
+
name_plural = "Members"
|
|
29
|
+
icon = "fa-solid fa-users"
|
|
30
|
+
column_list = [Member.id, Member.telegram_id, Member.first_name, Member.username, Member.phone, Member.is_active, Member.created_at]
|
|
31
|
+
column_searchable_list = [Member.first_name, Member.username, Member.phone]
|
|
32
|
+
column_sortable_list = [Member.id, Member.first_name, Member.created_at]
|
|
33
|
+
column_filters = [Member.is_active]
|
|
34
|
+
can_create = True
|
|
35
|
+
can_edit = True
|
|
36
|
+
can_delete = True
|
|
37
|
+
can_view_details = True
|
|
38
|
+
form_columns = [Member.first_name, Member.username, Member.phone, Member.is_active]
|
|
39
|
+
|
|
40
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "police-group" %}
|
|
41
|
+
from app.db.models.report import Report, Warning
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ReportAdmin(ModelView, model=Report):
|
|
45
|
+
name = "Report"
|
|
46
|
+
name_plural = "Reports"
|
|
47
|
+
icon = "fa-solid fa-flag"
|
|
48
|
+
column_list = [Report.id, Report.group_id, Report.reporter_id, Report.reported_id, Report.reported_username, Report.reason, Report.created_at]
|
|
49
|
+
column_searchable_list = [Report.reported_username, Report.reason]
|
|
50
|
+
column_sortable_list = [Report.id, Report.created_at]
|
|
51
|
+
can_create = False
|
|
52
|
+
can_edit = False
|
|
53
|
+
can_delete = True
|
|
54
|
+
can_view_details = True
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class WarningAdmin(ModelView, model=Warning):
|
|
58
|
+
name = "Warning"
|
|
59
|
+
name_plural = "Warnings"
|
|
60
|
+
icon = "fa-solid fa-triangle-exclamation"
|
|
61
|
+
column_list = [Warning.id, Warning.group_id, Warning.user_id, Warning.username, Warning.reason, Warning.issued_by, Warning.created_at]
|
|
62
|
+
column_searchable_list = [Warning.username, Warning.reason]
|
|
63
|
+
column_sortable_list = [Warning.id, Warning.user_id, Warning.created_at]
|
|
64
|
+
can_create = False
|
|
65
|
+
can_edit = False
|
|
66
|
+
can_delete = True
|
|
67
|
+
can_view_details = True
|
|
68
|
+
|
|
69
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "airdrop" %}
|
|
70
|
+
from app.db.models.participant import Participant
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ParticipantAdmin(ModelView, model=Participant):
|
|
74
|
+
name = "Participant"
|
|
75
|
+
name_plural = "Participants"
|
|
76
|
+
icon = "fa-solid fa-parachute-box"
|
|
77
|
+
column_list = [Participant.id, Participant.telegram_id, Participant.first_name, Participant.username, Participant.wallet_address, Participant.referral_code, Participant.points, Participant.is_verified, Participant.created_at]
|
|
78
|
+
column_searchable_list = [Participant.first_name, Participant.username, Participant.wallet_address, Participant.referral_code]
|
|
79
|
+
column_sortable_list = [Participant.id, Participant.points, Participant.created_at]
|
|
80
|
+
column_filters = [Participant.is_verified]
|
|
81
|
+
can_create = False
|
|
82
|
+
can_edit = True
|
|
83
|
+
can_delete = True
|
|
84
|
+
can_view_details = True
|
|
85
|
+
form_columns = [Participant.wallet_address, Participant.points, Participant.is_verified]
|
|
86
|
+
|
|
87
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "ecommerce" %}
|
|
88
|
+
from app.db.models.order import Order
|
|
89
|
+
from app.db.models.product import Product
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ProductAdmin(ModelView, model=Product):
|
|
93
|
+
name = "Product"
|
|
94
|
+
name_plural = "Products"
|
|
95
|
+
icon = "fa-solid fa-tag"
|
|
96
|
+
column_list = [Product.id, Product.name, Product.price, Product.stock, Product.is_active, Product.created_at]
|
|
97
|
+
column_searchable_list = [Product.name]
|
|
98
|
+
column_sortable_list = [Product.id, Product.name, Product.price, Product.stock]
|
|
99
|
+
column_filters = [Product.is_active]
|
|
100
|
+
can_create = True
|
|
101
|
+
can_edit = True
|
|
102
|
+
can_delete = True
|
|
103
|
+
can_view_details = True
|
|
104
|
+
form_columns = [Product.name, Product.description, Product.price, Product.stock, Product.is_active]
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class OrderAdmin(ModelView, model=Order):
|
|
108
|
+
name = "Order"
|
|
109
|
+
name_plural = "Orders"
|
|
110
|
+
icon = "fa-solid fa-cart-shopping"
|
|
111
|
+
column_list = [Order.id, Order.telegram_id, Order.username, Order.product_id, Order.quantity, Order.total_price, Order.status, Order.created_at]
|
|
112
|
+
column_searchable_list = [Order.username, Order.status]
|
|
113
|
+
column_sortable_list = [Order.id, Order.total_price, Order.status, Order.created_at]
|
|
114
|
+
column_filters = [Order.status]
|
|
115
|
+
can_create = False
|
|
116
|
+
can_edit = True
|
|
117
|
+
can_delete = True
|
|
118
|
+
can_view_details = True
|
|
119
|
+
form_columns = [Order.status]
|
|
120
|
+
|
|
121
|
+
{% endif %}
|
|
122
|
+
|
|
123
|
+
def setup_admin(app: FastAPI) -> None:
|
|
124
|
+
admin = Admin(app, engine, base_url="/admin")
|
|
125
|
+
{% if project.blueprint == "crud-service" %}
|
|
126
|
+
admin.add_view(ItemAdmin)
|
|
127
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "membership" %}
|
|
128
|
+
admin.add_view(MemberAdmin)
|
|
129
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "police-group" %}
|
|
130
|
+
admin.add_view(ReportAdmin)
|
|
131
|
+
admin.add_view(WarningAdmin)
|
|
132
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "airdrop" %}
|
|
133
|
+
admin.add_view(ParticipantAdmin)
|
|
134
|
+
{% elif project.blueprint == "telegram-bot" and project.telegram_template == "ecommerce" %}
|
|
135
|
+
admin.add_view(ProductAdmin)
|
|
136
|
+
admin.add_view(OrderAdmin)
|
|
137
|
+
{% endif %}
|