fastapi-fullstack 0.1.7__py3-none-any.whl → 0.1.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. {fastapi_fullstack-0.1.7.dist-info → fastapi_fullstack-0.1.15.dist-info}/METADATA +9 -2
  2. {fastapi_fullstack-0.1.7.dist-info → fastapi_fullstack-0.1.15.dist-info}/RECORD +71 -55
  3. fastapi_gen/__init__.py +6 -1
  4. fastapi_gen/cli.py +9 -0
  5. fastapi_gen/config.py +154 -2
  6. fastapi_gen/generator.py +34 -14
  7. fastapi_gen/prompts.py +172 -31
  8. fastapi_gen/template/VARIABLES.md +33 -4
  9. fastapi_gen/template/cookiecutter.json +10 -0
  10. fastapi_gen/template/hooks/post_gen_project.py +87 -2
  11. fastapi_gen/template/{{cookiecutter.project_slug}}/.env.prod.example +9 -0
  12. fastapi_gen/template/{{cookiecutter.project_slug}}/.gitlab-ci.yml +178 -0
  13. fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md +3 -0
  14. fastapi_gen/template/{{cookiecutter.project_slug}}/README.md +334 -0
  15. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example +32 -0
  16. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/env.py +10 -1
  17. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/admin.py +1 -1
  18. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/__init__.py +31 -0
  19. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py +563 -0
  20. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py +526 -0
  21. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py +4 -3
  22. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py +371 -0
  23. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/agent.py +1472 -0
  24. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/oauth.py +3 -7
  25. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/cleanup.py +2 -2
  26. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/seed.py +7 -2
  27. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/config.py +44 -7
  28. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/__init__.py +7 -0
  29. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/base.py +42 -0
  30. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py +262 -1
  31. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/item.py +76 -1
  32. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/session.py +118 -1
  33. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/user.py +158 -1
  34. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/webhook.py +185 -3
  35. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/main.py +29 -2
  36. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/base.py +6 -0
  37. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/session.py +4 -4
  38. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py +9 -9
  39. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/session.py +6 -6
  40. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/webhook.py +7 -7
  41. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/__init__.py +1 -1
  42. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/arq_app.py +165 -0
  43. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/__init__.py +10 -1
  44. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +40 -0
  45. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_metrics.py +53 -0
  46. fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py +2 -0
  47. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml +6 -0
  48. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +100 -0
  49. fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml +39 -0
  50. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.env.example +5 -0
  51. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +28 -1
  52. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts +1 -0
  53. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +22 -4
  54. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx +23 -3
  55. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-approval-dialog.tsx +138 -0
  56. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts +242 -18
  57. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-local-chat.ts +242 -17
  58. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/constants.ts +1 -1
  59. fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +57 -1
  60. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/configmap.yaml +63 -0
  61. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/deployment.yaml +242 -0
  62. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/ingress.yaml +44 -0
  63. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/kustomization.yaml +28 -0
  64. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/namespace.yaml +12 -0
  65. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/secret.yaml +59 -0
  66. fastapi_gen/template/{{cookiecutter.project_slug}}/kubernetes/service.yaml +23 -0
  67. fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/nginx.conf +225 -0
  68. fastapi_gen/template/{{cookiecutter.project_slug}}/nginx/ssl/.gitkeep +18 -0
  69. {fastapi_fullstack-0.1.7.dist-info → fastapi_fullstack-0.1.15.dist-info}/WHEEL +0 -0
  70. {fastapi_fullstack-0.1.7.dist-info → fastapi_fullstack-0.1.15.dist-info}/entry_points.txt +0 -0
  71. {fastapi_fullstack-0.1.7.dist-info → fastapi_fullstack-0.1.15.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,178 @@
1
+ {%- if cookiecutter.use_gitlab_ci %}
2
+ # GitLab CI/CD Pipeline for {{ cookiecutter.project_name }}
3
+
4
+ stages:
5
+ - lint
6
+ - test
7
+ - security
8
+ {%- if cookiecutter.enable_docker %}
9
+ - build
10
+ {%- endif %}
11
+
12
+ variables:
13
+ PYTHON_VERSION: "{{ cookiecutter.python_version }}"
14
+ PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
15
+ UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
16
+
17
+ # Cache configuration
18
+ .cache_config: &cache_config
19
+ cache:
20
+ key: "$CI_COMMIT_REF_SLUG"
21
+ paths:
22
+ - .cache/pip
23
+ - .cache/uv
24
+ - backend/.venv
25
+
26
+ # Base Python job template
27
+ .python_base:
28
+ image: python:${PYTHON_VERSION}-slim
29
+ before_script:
30
+ - pip install uv
31
+ - cd backend
32
+ - uv sync --dev
33
+ <<: *cache_config
34
+
35
+ # =============================================================================
36
+ # Lint Stage
37
+ # =============================================================================
38
+
39
+ ruff-check:
40
+ stage: lint
41
+ extends: .python_base
42
+ script:
43
+ - uv run ruff check app tests cli
44
+ rules:
45
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
46
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
47
+
48
+ ruff-format:
49
+ stage: lint
50
+ extends: .python_base
51
+ script:
52
+ - uv run ruff format app tests cli --check
53
+ rules:
54
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
55
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
56
+
57
+ mypy:
58
+ stage: lint
59
+ extends: .python_base
60
+ script:
61
+ - uv run mypy app
62
+ rules:
63
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
64
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
65
+
66
+ # =============================================================================
67
+ # Test Stage
68
+ # =============================================================================
69
+
70
+ test:
71
+ stage: test
72
+ image: python:${PYTHON_VERSION}-slim
73
+ {%- if cookiecutter.use_postgresql or cookiecutter.enable_redis %}
74
+ services:
75
+ {%- if cookiecutter.use_postgresql %}
76
+ - name: postgres:16-alpine
77
+ alias: postgres
78
+ variables:
79
+ POSTGRES_USER: postgres
80
+ POSTGRES_PASSWORD: postgres
81
+ POSTGRES_DB: test_db
82
+ {%- endif %}
83
+ {%- if cookiecutter.enable_redis %}
84
+ - name: redis:7-alpine
85
+ alias: redis
86
+ {%- endif %}
87
+ {%- endif %}
88
+ variables:
89
+ {%- if cookiecutter.use_postgresql %}
90
+ POSTGRES_HOST: postgres
91
+ POSTGRES_PORT: "5432"
92
+ POSTGRES_USER: postgres
93
+ POSTGRES_PASSWORD: postgres
94
+ POSTGRES_DB: test_db
95
+ {%- endif %}
96
+ {%- if cookiecutter.enable_redis %}
97
+ REDIS_HOST: redis
98
+ REDIS_PORT: "6379"
99
+ {%- endif %}
100
+ before_script:
101
+ - pip install uv
102
+ - cd backend
103
+ - uv sync --dev
104
+ script:
105
+ - uv run pytest tests/ -v --cov=app --cov-report=xml --cov-report=term-missing
106
+ coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
107
+ artifacts:
108
+ reports:
109
+ coverage_report:
110
+ coverage_format: cobertura
111
+ path: backend/coverage.xml
112
+ expire_in: 1 week
113
+ <<: *cache_config
114
+ rules:
115
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
116
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
117
+
118
+ # =============================================================================
119
+ # Security Stage
120
+ # =============================================================================
121
+
122
+ security-scan:
123
+ stage: security
124
+ extends: .python_base
125
+ script:
126
+ - uv pip install pip-audit
127
+ - uv run pip-audit --require-hashes=false --progress-spinner=off
128
+ allow_failure: true
129
+ rules:
130
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
131
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
132
+
133
+ {%- if cookiecutter.enable_docker %}
134
+
135
+ # =============================================================================
136
+ # Build Stage
137
+ # =============================================================================
138
+
139
+ docker-build:
140
+ stage: build
141
+ image: docker:24
142
+ services:
143
+ - docker:24-dind
144
+ variables:
145
+ DOCKER_TLS_CERTDIR: "/certs"
146
+ before_script:
147
+ - docker info
148
+ script:
149
+ - docker build -t {{ cookiecutter.project_slug }}:$CI_COMMIT_SHORT_SHA ./backend
150
+ - docker tag {{ cookiecutter.project_slug }}:$CI_COMMIT_SHORT_SHA {{ cookiecutter.project_slug }}:latest
151
+ rules:
152
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
153
+
154
+ # Optional: Push to GitLab Container Registry
155
+ # Uncomment and configure as needed
156
+ #
157
+ # docker-push:
158
+ # stage: build
159
+ # image: docker:24
160
+ # services:
161
+ # - docker:24-dind
162
+ # variables:
163
+ # DOCKER_TLS_CERTDIR: "/certs"
164
+ # before_script:
165
+ # - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
166
+ # script:
167
+ # - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA ./backend
168
+ # - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
169
+ # - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest
170
+ # - docker push $CI_REGISTRY_IMAGE:latest
171
+ # rules:
172
+ # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
173
+ # needs:
174
+ # - docker-build
175
+ {%- endif %}
176
+ {%- else %}
177
+ # GitLab CI is disabled for this project
178
+ {%- endif %}
@@ -12,6 +12,9 @@
12
12
  {%- if cookiecutter.enable_redis %}, Redis{%- endif %}
13
13
  {%- if cookiecutter.enable_ai_agent and cookiecutter.use_pydantic_ai %}, PydanticAI{%- endif %}
14
14
  {%- if cookiecutter.enable_ai_agent and cookiecutter.use_langchain %}, LangChain{%- endif %}
15
+ {%- if cookiecutter.enable_ai_agent and cookiecutter.use_langgraph %}, LangGraph{%- endif %}
16
+ {%- if cookiecutter.enable_ai_agent and cookiecutter.use_crewai %}, CrewAI{%- endif %}
17
+ {%- if cookiecutter.enable_ai_agent and cookiecutter.use_deepagents %}, DeepAgents{%- endif %}
15
18
  {%- if cookiecutter.use_celery %}, Celery{%- endif %}
16
19
  {%- if cookiecutter.use_taskiq %}, Taskiq{%- endif %}
17
20
  {%- if cookiecutter.use_frontend %}, Next.js 15{%- endif %}
@@ -144,6 +144,11 @@ cd my_ai_app
144
144
  make install
145
145
  ```
146
146
 
147
+ > **Windows Users:** The `make` command requires GNU Make which is not available by default on Windows.
148
+ > You can either install Make via [Chocolatey](https://chocolatey.org/) (`choco install make`),
149
+ > use WSL (Windows Subsystem for Linux), or use the raw commands from the
150
+ > [Manual Commands Reference](#-manual-commands-reference-windows--no-make) section below.
151
+
147
152
  #### Step 2: Start the Database
148
153
  {%- if cookiecutter.use_postgresql %}
149
154
 
@@ -575,6 +580,224 @@ with logfire.span("process_order", order_id=order.id):
575
580
 
576
581
  For more details, see [Logfire Documentation](https://logfire.pydantic.dev/docs/integrations/).
577
582
 
583
+ {%- if cookiecutter.enable_prometheus %}
584
+
585
+ ---
586
+
587
+ ## 📈 Prometheus Metrics
588
+
589
+ This project includes Prometheus metrics for monitoring and alerting.
590
+
591
+ ### Accessing Metrics
592
+
593
+ Metrics are exposed at the `/metrics` endpoint:
594
+
595
+ ```bash
596
+ curl http://localhost:{{ cookiecutter.backend_port }}/metrics
597
+ ```
598
+
599
+ ### Available Metrics
600
+
601
+ | Metric | Type | Description |
602
+ |--------|------|-------------|
603
+ | `http_requests_total` | Counter | Total HTTP requests by method, path, status |
604
+ | `http_request_duration_seconds` | Histogram | Request latency distribution |
605
+ | `http_requests_inprogress` | Gauge | Currently in-flight requests |
606
+ | `http_request_size_bytes` | Histogram | Request body size |
607
+ | `http_response_size_bytes` | Histogram | Response body size |
608
+
609
+ ### Prometheus Configuration
610
+
611
+ Add to your `prometheus.yml`:
612
+
613
+ ```yaml
614
+ scrape_configs:
615
+ - job_name: '{{ cookiecutter.project_slug }}'
616
+ static_configs:
617
+ - targets: ['localhost:{{ cookiecutter.backend_port }}']
618
+ metrics_path: /metrics
619
+ scrape_interval: 15s
620
+ ```
621
+
622
+ ### Docker Labels
623
+
624
+ When running with Docker, the service includes labels for Prometheus service discovery:
625
+
626
+ ```yaml
627
+ labels:
628
+ - "prometheus.scrape=true"
629
+ - "prometheus.port={{ cookiecutter.backend_port }}"
630
+ - "prometheus.path=/metrics"
631
+ ```
632
+
633
+ ### Environment Variables
634
+
635
+ | Variable | Default | Description |
636
+ |----------|---------|-------------|
637
+ | `PROMETHEUS_METRICS_PATH` | `/metrics` | Endpoint path for metrics |
638
+ | `PROMETHEUS_INCLUDE_IN_SCHEMA` | `false` | Include in OpenAPI schema |
639
+ {%- endif %}
640
+
641
+ {%- if cookiecutter.use_arq %}
642
+
643
+ ---
644
+
645
+ ## ⚡ Background Tasks (ARQ)
646
+
647
+ This project uses [ARQ](https://arq-docs.helpmanual.io/) (Async Redis Queue) for background task processing.
648
+
649
+ ### Starting the Worker
650
+
651
+ ```bash
652
+ # Using the CLI
653
+ cd backend
654
+ arq app.worker.arq_app.WorkerSettings
655
+
656
+ # Using Docker
657
+ docker-compose up -d arq_worker
658
+ ```
659
+
660
+ ### Enqueueing Tasks
661
+
662
+ ```python
663
+ from arq.connections import ArqRedis, create_pool
664
+ from app.core.config import settings
665
+
666
+ # Create a connection pool
667
+ redis = await create_pool(RedisSettings(
668
+ host=settings.ARQ_REDIS_HOST,
669
+ port=settings.ARQ_REDIS_PORT,
670
+ database=settings.ARQ_REDIS_DB,
671
+ ))
672
+
673
+ # Enqueue a task
674
+ await redis.enqueue_job('example_task', 'Hello, World!')
675
+
676
+ # Enqueue with delay
677
+ from datetime import timedelta
678
+ await redis.enqueue_job('example_task', 'Delayed message', _defer_by=timedelta(minutes=5))
679
+ ```
680
+
681
+ ### Creating New Tasks
682
+
683
+ Add tasks to `app/worker/arq_app.py`:
684
+
685
+ ```python
686
+ async def my_task(ctx: dict, arg1: str, arg2: int) -> dict:
687
+ """My custom background task."""
688
+ # ctx contains: redis connection, job_id, job_try, etc.
689
+ result = await do_something(arg1, arg2)
690
+ return {"status": "completed", "result": result}
691
+
692
+ # Register in WorkerSettings.functions list
693
+ class WorkerSettings:
694
+ functions = [
695
+ example_task,
696
+ my_task, # Add your task here
697
+ ]
698
+ ```
699
+
700
+ ### Scheduled Tasks (Cron)
701
+
702
+ ```python
703
+ from arq import cron
704
+
705
+ class WorkerSettings:
706
+ cron_jobs = [
707
+ cron(my_scheduled_task, minute=0, hour=0), # Daily at midnight
708
+ cron(my_scheduled_task, minute={0, 30}), # Every 30 minutes
709
+ ]
710
+ ```
711
+
712
+ ### Environment Variables
713
+
714
+ | Variable | Default | Description |
715
+ |----------|---------|-------------|
716
+ | `ARQ_REDIS_HOST` | `localhost` | Redis host |
717
+ | `ARQ_REDIS_PORT` | `6379` | Redis port |
718
+ | `ARQ_REDIS_PASSWORD` | `None` | Redis password |
719
+ | `ARQ_REDIS_DB` | `2` | Redis database number |
720
+ {%- endif %}
721
+
722
+ {%- if cookiecutter.enable_kubernetes %}
723
+
724
+ ---
725
+
726
+ ## ☸️ Kubernetes Deployment
727
+
728
+ This project includes Kubernetes manifests for production deployment.
729
+
730
+ ### Quick Deploy
731
+
732
+ ```bash
733
+ # Using kustomize (recommended)
734
+ kubectl apply -k kubernetes/
735
+
736
+ # Or apply individually
737
+ kubectl apply -f kubernetes/namespace.yaml
738
+ kubectl apply -f kubernetes/configmap.yaml
739
+ kubectl apply -f kubernetes/secret.yaml
740
+ kubectl apply -f kubernetes/deployment.yaml
741
+ kubectl apply -f kubernetes/service.yaml
742
+ kubectl apply -f kubernetes/ingress.yaml
743
+ ```
744
+
745
+ ### Manifest Files
746
+
747
+ | File | Description |
748
+ |------|-------------|
749
+ | `namespace.yaml` | Creates dedicated namespace |
750
+ | `configmap.yaml` | Non-sensitive configuration |
751
+ | `secret.yaml` | Sensitive data (passwords, API keys) |
752
+ | `deployment.yaml` | Backend + worker deployments |
753
+ | `service.yaml` | ClusterIP service for backend |
754
+ | `ingress.yaml` | External access with nginx ingress |
755
+ | `kustomization.yaml` | Kustomize configuration |
756
+
757
+ ### Before Deploying
758
+
759
+ 1. **Update secrets** in `kubernetes/secret.yaml`:
760
+ ```bash
761
+ # Generate a secure SECRET_KEY
762
+ openssl rand -hex 32
763
+ ```
764
+
765
+ 2. **Configure ingress** in `kubernetes/ingress.yaml`:
766
+ - Replace `api.example.com` with your domain
767
+ - Uncomment TLS section for HTTPS
768
+
769
+ 3. **Build and push Docker image**:
770
+ ```bash
771
+ docker build -t your-registry/{{ cookiecutter.project_slug }}:latest ./backend
772
+ docker push your-registry/{{ cookiecutter.project_slug }}:latest
773
+ ```
774
+
775
+ 4. **Update image** in `kubernetes/kustomization.yaml`:
776
+ ```yaml
777
+ images:
778
+ - name: {{ cookiecutter.project_slug }}
779
+ newName: your-registry/{{ cookiecutter.project_slug }}
780
+ newTag: latest
781
+ ```
782
+
783
+ ### Scaling
784
+
785
+ ```bash
786
+ # Scale backend replicas
787
+ kubectl scale deployment {{ cookiecutter.project_slug }}-backend -n {{ cookiecutter.project_slug }} --replicas=3
788
+
789
+ # View pods
790
+ kubectl get pods -n {{ cookiecutter.project_slug }}
791
+
792
+ # View logs
793
+ kubectl logs -f deployment/{{ cookiecutter.project_slug }}-backend -n {{ cookiecutter.project_slug }}
794
+ ```
795
+
796
+ ### Using with Helm (optional)
797
+
798
+ For more advanced deployments, consider creating a Helm chart based on these manifests.
799
+ {%- endif %}
800
+
578
801
  ---
579
802
 
580
803
  ## 🛠️ Django-style CLI
@@ -635,6 +858,117 @@ uv run {{ cookiecutter.project_slug }} cmd seed --dry-run
635
858
 
636
859
  ---
637
860
 
861
+ ## 🖥️ Manual Commands Reference (Windows / No Make)
862
+
863
+ If you don't have `make` installed (common on Windows), use these commands directly.
864
+ All commands should be run from the project root directory.
865
+
866
+ ### Setup & Development
867
+
868
+ | Task | Command |
869
+ |------|---------|
870
+ | Install dependencies | `uv sync --directory backend --dev` |
871
+ | Start dev server | `uv run --directory backend {{ cookiecutter.project_slug }} server run --reload` |
872
+ | Start prod server | `uv run --directory backend {{ cookiecutter.project_slug }} server run --host 0.0.0.0 --port {{ cookiecutter.backend_port }}` |
873
+ | Show routes | `uv run --directory backend {{ cookiecutter.project_slug }} server routes` |
874
+
875
+ ### Code Quality
876
+
877
+ | Task | Command |
878
+ |------|---------|
879
+ | Format code | `uv run --directory backend ruff format app tests cli` |
880
+ | Fix lint issues | `uv run --directory backend ruff check app tests cli --fix` |
881
+ | Check linting | `uv run --directory backend ruff check app tests cli` |
882
+ | Type check | `uv run --directory backend mypy app` |
883
+
884
+ ### Testing
885
+
886
+ | Task | Command |
887
+ |------|---------|
888
+ | Run tests | `uv run --directory backend pytest tests/ -v` |
889
+ | Run with coverage | `uv run --directory backend pytest tests/ -v --cov=app --cov-report=term-missing` |
890
+
891
+ {%- if cookiecutter.use_postgresql or cookiecutter.use_sqlite %}
892
+
893
+ ### Database
894
+
895
+ | Task | Command |
896
+ |------|---------|
897
+ | Create migration | `uv run --directory backend {{ cookiecutter.project_slug }} db migrate -m "message"` |
898
+ | Apply migrations | `uv run --directory backend {{ cookiecutter.project_slug }} db upgrade` |
899
+ | Rollback migration | `uv run --directory backend {{ cookiecutter.project_slug }} db downgrade` |
900
+ | Show current | `uv run --directory backend {{ cookiecutter.project_slug }} db current` |
901
+ | Show history | `uv run --directory backend {{ cookiecutter.project_slug }} db history` |
902
+ {%- endif %}
903
+
904
+ {%- if cookiecutter.use_jwt %}
905
+
906
+ ### Users
907
+
908
+ | Task | Command |
909
+ |------|---------|
910
+ | Create admin | `uv run --directory backend {{ cookiecutter.project_slug }} user create-admin` |
911
+ | Create user | `uv run --directory backend {{ cookiecutter.project_slug }} user create` |
912
+ | List users | `uv run --directory backend {{ cookiecutter.project_slug }} user list` |
913
+ {%- endif %}
914
+
915
+ {%- if cookiecutter.use_celery %}
916
+
917
+ ### Celery
918
+
919
+ | Task | Command |
920
+ |------|---------|
921
+ | Start worker | `uv run --directory backend {{ cookiecutter.project_slug }} celery worker` |
922
+ | Start beat | `uv run --directory backend {{ cookiecutter.project_slug }} celery beat` |
923
+ | Start flower | `uv run --directory backend {{ cookiecutter.project_slug }} celery flower` |
924
+ {%- endif %}
925
+
926
+ {%- if cookiecutter.use_taskiq %}
927
+
928
+ ### Taskiq
929
+
930
+ | Task | Command |
931
+ |------|---------|
932
+ | Start worker | `uv run --directory backend {{ cookiecutter.project_slug }} taskiq worker` |
933
+ | Start scheduler | `uv run --directory backend {{ cookiecutter.project_slug }} taskiq scheduler` |
934
+ {%- endif %}
935
+
936
+ {%- if cookiecutter.use_arq %}
937
+
938
+ ### ARQ
939
+
940
+ | Task | Command |
941
+ |------|---------|
942
+ | Start worker | `arq app.worker.arq_app.WorkerSettings` (from backend/) |
943
+ {%- endif %}
944
+
945
+ {%- if cookiecutter.enable_docker %}
946
+
947
+ ### Docker
948
+
949
+ | Task | Command |
950
+ |------|---------|
951
+ | Start all services | `docker-compose up -d` |
952
+ | Stop all services | `docker-compose down` |
953
+ | View logs | `docker-compose logs -f` |
954
+ | Build images | `docker-compose build` |
955
+ {%- if cookiecutter.use_postgresql %}
956
+ | Start PostgreSQL only | `docker-compose up -d db` |
957
+ {%- endif %}
958
+ {%- if cookiecutter.enable_redis %}
959
+ | Start Redis only | `docker-compose up -d redis` |
960
+ {%- endif %}
961
+ | Start production | `docker-compose -f docker-compose.prod.yml up -d` |
962
+ {%- endif %}
963
+
964
+ ### Cleanup
965
+
966
+ | Task | Command (Unix) | Command (Windows PowerShell) |
967
+ |------|----------------|------------------------------|
968
+ | Clean cache | `find . -type d -name __pycache__ -exec rm -rf {} +` | `Get-ChildItem -Recurse -Directory -Filter __pycache__ \| Remove-Item -Recurse -Force` |
969
+
970
+ ---
971
+
638
972
  ## 📁 Generated Project Structure
639
973
 
640
974
  ```
@@ -79,12 +79,28 @@ TASKIQ_BROKER_URL=redis://localhost:6379/1
79
79
  TASKIQ_RESULT_BACKEND=redis://localhost:6379/1
80
80
  {%- endif %}
81
81
 
82
+ {%- if cookiecutter.use_arq %}
83
+
84
+ # === ARQ (Async Redis Queue) ===
85
+ ARQ_REDIS_HOST=localhost
86
+ ARQ_REDIS_PORT=6379
87
+ # ARQ_REDIS_PASSWORD=
88
+ ARQ_REDIS_DB=2
89
+ {%- endif %}
90
+
82
91
  {%- if cookiecutter.enable_sentry %}
83
92
 
84
93
  # === Sentry ===
85
94
  SENTRY_DSN=
86
95
  {%- endif %}
87
96
 
97
+ {%- if cookiecutter.enable_prometheus %}
98
+
99
+ # === Prometheus ===
100
+ PROMETHEUS_METRICS_PATH=/metrics
101
+ PROMETHEUS_INCLUDE_IN_SCHEMA=false
102
+ {%- endif %}
103
+
88
104
  {%- if cookiecutter.enable_file_storage %}
89
105
 
90
106
  # === S3/MinIO Storage ===
@@ -120,6 +136,22 @@ LANGCHAIN_API_KEY=
120
136
  LANGCHAIN_PROJECT={{ cookiecutter.project_slug }}
121
137
  LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
122
138
  {%- endif %}
139
+ {%- if cookiecutter.use_deepagents %}
140
+
141
+ # === DeepAgents Configuration ===
142
+ # Skills paths (comma-separated, relative paths e.g. "/skills/user/,/skills/project/")
143
+ DEEPAGENTS_SKILLS_PATHS=
144
+ # Enable/disable built-in tools
145
+ DEEPAGENTS_ENABLE_FILESYSTEM=true
146
+ DEEPAGENTS_ENABLE_EXECUTE=false
147
+ DEEPAGENTS_ENABLE_TODOS=true
148
+ DEEPAGENTS_ENABLE_SUBAGENTS=true
149
+ # Human-in-the-loop: tools requiring approval (comma-separated, or "all")
150
+ # e.g. "write_file,edit_file,execute" or leave empty to disable HITL
151
+ DEEPAGENTS_INTERRUPT_TOOLS=
152
+ # Allowed decisions for interrupted tools (approve, edit, reject)
153
+ DEEPAGENTS_ALLOWED_DECISIONS=approve,edit,reject
154
+ {%- endif %}
123
155
  {%- endif %}
124
156
 
125
157
  {%- if cookiecutter.enable_cors %}
@@ -6,11 +6,16 @@ from logging.config import fileConfig
6
6
 
7
7
  from alembic import context
8
8
  from sqlalchemy import engine_from_config, pool
9
+ {%- if cookiecutter.use_sqlmodel %}
10
+ from sqlmodel import SQLModel
11
+ {%- endif %}
9
12
 
10
13
  from app.core.config import settings
14
+ {%- if not cookiecutter.use_sqlmodel %}
11
15
  from app.db.base import Base
16
+ {%- endif %}
12
17
 
13
- # Import all models here to ensure they are registered with Base.metadata
18
+ # Import all models here to ensure they are registered with metadata
14
19
  {%- if cookiecutter.use_jwt %}
15
20
  from app.db.models.user import User # noqa: F401
16
21
  {%- endif %}
@@ -20,7 +25,11 @@ config = context.config
20
25
  if config.config_file_name is not None:
21
26
  fileConfig(config.config_file_name)
22
27
 
28
+ {%- if cookiecutter.use_sqlmodel %}
29
+ target_metadata = SQLModel.metadata
30
+ {%- else %}
23
31
  target_metadata = Base.metadata
32
+ {%- endif %}
24
33
 
25
34
 
26
35
  def get_url() -> str:
@@ -1,4 +1,4 @@
1
- {%- if cookiecutter.enable_admin_panel and cookiecutter.use_postgresql %}
1
+ {%- if cookiecutter.enable_admin_panel and (cookiecutter.use_postgresql or cookiecutter.use_sqlite) and cookiecutter.use_sqlalchemy %}
2
2
  """SQLAdmin configuration with automatic model discovery."""
3
3
 
4
4
  from typing import Any, ClassVar
@@ -18,6 +18,37 @@ Tools are defined in the tools/ subdirectory.
18
18
  from app.agents.langchain_assistant import AgentContext, AgentState, LangChainAssistant
19
19
 
20
20
  __all__ = ["LangChainAssistant", "AgentContext", "AgentState"]
21
+ {%- elif cookiecutter.enable_ai_agent and cookiecutter.use_langgraph %}
22
+ """AI Agents module using LangGraph.
23
+
24
+ This module contains a ReAct agent built with LangGraph.
25
+ Tools are defined in the tools/ subdirectory.
26
+ """
27
+
28
+ from app.agents.langgraph_assistant import AgentContext, AgentState, LangGraphAssistant
29
+
30
+ __all__ = ["LangGraphAssistant", "AgentContext", "AgentState"]
31
+ {%- elif cookiecutter.enable_ai_agent and cookiecutter.use_crewai %}
32
+ """AI Agents module using CrewAI.
33
+
34
+ This module contains a multi-agent crew built with CrewAI.
35
+ Agents work together in a team to accomplish complex tasks.
36
+ """
37
+
38
+ from app.agents.crewai_assistant import CrewAIAssistant, CrewConfig, CrewContext
39
+
40
+ __all__ = ["CrewAIAssistant", "CrewConfig", "CrewContext"]
41
+ {%- elif cookiecutter.enable_ai_agent and cookiecutter.use_deepagents %}
42
+ """AI Agents module using DeepAgents.
43
+
44
+ This module contains an agentic coding assistant built with DeepAgents.
45
+ DeepAgents provides built-in tools for filesystem operations, task management,
46
+ and code execution.
47
+ """
48
+
49
+ from app.agents.deepagents_assistant import AgentContext, AgentState, DeepAgentsAssistant
50
+
51
+ __all__ = ["DeepAgentsAssistant", "AgentContext", "AgentState"]
21
52
  {%- else %}
22
53
  """AI Agents - not configured."""
23
54
  {%- endif %}