@zimezone/z-command 1.1.0 → 1.1.1

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 (182) hide show
  1. package/package.json +4 -1
  2. package/templates/agents/api-documenter.agent.md +161 -0
  3. package/templates/agents/architect-review.agent.md +146 -0
  4. package/templates/agents/arm-cortex-expert.agent.md +288 -0
  5. package/templates/agents/backend-architect.agent.md +309 -0
  6. package/templates/agents/backend-security-coder.agent.md +152 -0
  7. package/templates/agents/bash-pro.agent.md +285 -0
  8. package/templates/agents/c-pro.agent.md +35 -0
  9. package/templates/agents/c4-code.agent.md +320 -0
  10. package/templates/agents/c4-component.agent.md +227 -0
  11. package/templates/agents/c4-container.agent.md +248 -0
  12. package/templates/agents/c4-context.agent.md +235 -0
  13. package/templates/agents/conductor-validator.agent.md +245 -0
  14. package/templates/agents/csharp-pro.agent.md +38 -0
  15. package/templates/agents/customer-support.agent.md +148 -0
  16. package/templates/agents/database-admin.agent.md +142 -0
  17. package/templates/agents/database-architect.agent.md +238 -0
  18. package/templates/agents/database-optimizer.agent.md +144 -0
  19. package/templates/agents/debugger.agent.md +30 -0
  20. package/templates/agents/deployment-engineer.agent.md +0 -0
  21. package/templates/agents/devops-troubleshooter.agent.md +138 -0
  22. package/templates/agents/django-pro.agent.md +159 -0
  23. package/templates/agents/docs-architect.agent.md +77 -0
  24. package/templates/agents/dotnet-architect.agent.md +175 -0
  25. package/templates/agents/dx-optimizer.agent.md +63 -0
  26. package/templates/agents/elixir-pro.agent.md +38 -0
  27. package/templates/agents/error-detective.agent.md +32 -0
  28. package/templates/agents/event-sourcing-architect.agent.md +42 -0
  29. package/templates/agents/fastapi-pro.agent.md +171 -0
  30. package/templates/agents/firmware-analyst.agent.md +330 -0
  31. package/templates/agents/frontend-security-coder.agent.md +149 -0
  32. package/templates/agents/haskell-pro.agent.md +37 -0
  33. package/templates/agents/hr-pro.agent.md +105 -0
  34. package/templates/agents/incident-responder.agent.md +190 -0
  35. package/templates/agents/ios-developer.agent.md +198 -0
  36. package/templates/agents/java-pro.agent.md +156 -0
  37. package/templates/agents/javascript-pro.agent.md +35 -0
  38. package/templates/agents/julia-pro.agent.md +187 -0
  39. package/templates/agents/legal-advisor.agent.md +49 -0
  40. package/templates/agents/malware-analyst.agent.md +272 -0
  41. package/templates/agents/mermaid-expert.agent.md +39 -0
  42. package/templates/agents/minecraft-bukkit-pro.agent.md +104 -0
  43. package/templates/agents/mobile-security-coder.agent.md +163 -0
  44. package/templates/agents/monorepo-architect.agent.md +44 -0
  45. package/templates/agents/observability-engineer.agent.md +228 -0
  46. package/templates/agents/performance-engineer.agent.md +167 -0
  47. package/templates/agents/php-pro.agent.md +43 -0
  48. package/templates/agents/posix-shell-pro.agent.md +284 -0
  49. package/templates/agents/quant-analyst.agent.md +32 -0
  50. package/templates/agents/reference-builder.agent.md +167 -0
  51. package/templates/agents/reverse-engineer.agent.md +202 -0
  52. package/templates/agents/risk-manager.agent.md +41 -0
  53. package/templates/agents/ruby-pro.agent.md +35 -0
  54. package/templates/agents/rust-pro.agent.md +156 -0
  55. package/templates/agents/sales-automator.agent.md +35 -0
  56. package/templates/agents/scala-pro.agent.md +60 -0
  57. package/templates/agents/search-specialist.agent.md +59 -0
  58. package/templates/agents/security-auditor.agent.md +138 -0
  59. package/templates/agents/seo-authority-builder.agent.md +116 -0
  60. package/templates/agents/seo-cannibalization-detector.agent.md +103 -0
  61. package/templates/agents/seo-content-auditor.agent.md +63 -0
  62. package/templates/agents/seo-content-planner.agent.md +88 -0
  63. package/templates/agents/seo-content-refresher.agent.md +98 -0
  64. package/templates/agents/seo-content-writer.agent.md +76 -0
  65. package/templates/agents/seo-keyword-strategist.agent.md +75 -0
  66. package/templates/agents/seo-meta-optimizer.agent.md +72 -0
  67. package/templates/agents/seo-snippet-hunter.agent.md +94 -0
  68. package/templates/agents/seo-structure-architect.agent.md +88 -0
  69. package/templates/agents/service-mesh-expert.agent.md +41 -0
  70. package/templates/agents/sql-pro.agent.md +146 -0
  71. package/templates/agents/tdd-orchestrator.agent.md +183 -0
  72. package/templates/agents/temporal-python-pro.agent.md +349 -0
  73. package/templates/agents/terraform-specialist.agent.md +137 -0
  74. package/templates/agents/test-automator.agent.md +203 -0
  75. package/templates/agents/threat-modeling-expert.agent.md +44 -0
  76. package/templates/agents/tutorial-engineer.agent.md +118 -0
  77. package/templates/agents/ui-ux-designer.agent.md +188 -0
  78. package/templates/agents/ui-visual-validator.agent.md +192 -0
  79. package/templates/agents/vector-database-engineer.agent.md +43 -0
  80. package/templates/skills/angular-migration/SKILL.md +410 -0
  81. package/templates/skills/api-design-principles/SKILL.md +528 -0
  82. package/templates/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  83. package/templates/skills/api-design-principles/assets/rest-api-template.py +182 -0
  84. package/templates/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  85. package/templates/skills/api-design-principles/references/rest-best-practices.md +408 -0
  86. package/templates/skills/architecture-decision-records/SKILL.md +428 -0
  87. package/templates/skills/architecture-patterns/SKILL.md +494 -0
  88. package/templates/skills/async-python-patterns/SKILL.md +694 -0
  89. package/templates/skills/auth-implementation-patterns/SKILL.md +634 -0
  90. package/templates/skills/changelog-automation/SKILL.md +552 -0
  91. package/templates/skills/code-review-excellence/SKILL.md +520 -0
  92. package/templates/skills/competitive-landscape/SKILL.md +479 -0
  93. package/templates/skills/context-driven-development/SKILL.md +385 -0
  94. package/templates/skills/cost-optimization/SKILL.md +274 -0
  95. package/templates/skills/cqrs-implementation/SKILL.md +554 -0
  96. package/templates/skills/data-quality-frameworks/SKILL.md +587 -0
  97. package/templates/skills/data-storytelling/SKILL.md +453 -0
  98. package/templates/skills/database-migration/SKILL.md +424 -0
  99. package/templates/skills/dbt-transformation-patterns/SKILL.md +561 -0
  100. package/templates/skills/debugging-strategies/SKILL.md +527 -0
  101. package/templates/skills/defi-protocol-templates/SKILL.md +454 -0
  102. package/templates/skills/dependency-upgrade/SKILL.md +409 -0
  103. package/templates/skills/deployment-pipeline-design/SKILL.md +359 -0
  104. package/templates/skills/distributed-tracing/SKILL.md +438 -0
  105. package/templates/skills/dotnet-backend-patterns/SKILL.md +815 -0
  106. package/templates/skills/dotnet-backend-patterns/assets/repository-template.cs +523 -0
  107. package/templates/skills/dotnet-backend-patterns/assets/service-template.cs +336 -0
  108. package/templates/skills/dotnet-backend-patterns/references/dapper-patterns.md +544 -0
  109. package/templates/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +355 -0
  110. package/templates/skills/e2e-testing-patterns/SKILL.md +547 -0
  111. package/templates/skills/employment-contract-templates/SKILL.md +507 -0
  112. package/templates/skills/error-handling-patterns/SKILL.md +636 -0
  113. package/templates/skills/event-store-design/SKILL.md +437 -0
  114. package/templates/skills/fastapi-templates/SKILL.md +567 -0
  115. package/templates/skills/git-advanced-workflows/SKILL.md +400 -0
  116. package/templates/skills/github-actions-templates/SKILL.md +333 -0
  117. package/templates/skills/go-concurrency-patterns/SKILL.md +655 -0
  118. package/templates/skills/grafana-dashboards/SKILL.md +369 -0
  119. package/templates/skills/helm-chart-scaffolding/SKILL.md +544 -0
  120. package/templates/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
  121. package/templates/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
  122. package/templates/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
  123. package/templates/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
  124. package/templates/skills/javascript-testing-patterns/SKILL.md +1025 -0
  125. package/templates/skills/langchain-architecture/SKILL.md +338 -0
  126. package/templates/skills/llm-evaluation/SKILL.md +471 -0
  127. package/templates/skills/microservices-patterns/SKILL.md +595 -0
  128. package/templates/skills/modern-javascript-patterns/SKILL.md +911 -0
  129. package/templates/skills/monorepo-management/SKILL.md +622 -0
  130. package/templates/skills/nextjs-app-router-patterns/SKILL.md +544 -0
  131. package/templates/skills/nodejs-backend-patterns/SKILL.md +1020 -0
  132. package/templates/skills/nx-workspace-patterns/SKILL.md +452 -0
  133. package/templates/skills/openapi-spec-generation/SKILL.md +1028 -0
  134. package/templates/skills/paypal-integration/SKILL.md +467 -0
  135. package/templates/skills/pci-compliance/SKILL.md +466 -0
  136. package/templates/skills/postgresql/SKILL.md +204 -0
  137. package/templates/skills/projection-patterns/SKILL.md +490 -0
  138. package/templates/skills/prometheus-configuration/SKILL.md +392 -0
  139. package/templates/skills/prompt-engineering-patterns/SKILL.md +201 -0
  140. package/templates/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
  141. package/templates/skills/prompt-engineering-patterns/assets/prompt-template-library.md +246 -0
  142. package/templates/skills/prompt-engineering-patterns/references/chain-of-thought.md +399 -0
  143. package/templates/skills/prompt-engineering-patterns/references/few-shot-learning.md +369 -0
  144. package/templates/skills/prompt-engineering-patterns/references/prompt-optimization.md +414 -0
  145. package/templates/skills/prompt-engineering-patterns/references/prompt-templates.md +470 -0
  146. package/templates/skills/prompt-engineering-patterns/references/system-prompts.md +189 -0
  147. package/templates/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
  148. package/templates/skills/python-packaging/SKILL.md +870 -0
  149. package/templates/skills/python-performance-optimization/SKILL.md +869 -0
  150. package/templates/skills/python-testing-patterns/SKILL.md +907 -0
  151. package/templates/skills/rag-implementation/SKILL.md +403 -0
  152. package/templates/skills/react-modernization/SKILL.md +513 -0
  153. package/templates/skills/react-native-architecture/SKILL.md +671 -0
  154. package/templates/skills/react-state-management/SKILL.md +429 -0
  155. package/templates/skills/risk-metrics-calculation/SKILL.md +555 -0
  156. package/templates/skills/rust-async-patterns/SKILL.md +517 -0
  157. package/templates/skills/secrets-management/SKILL.md +346 -0
  158. package/templates/skills/security-requirement-extraction/SKILL.md +677 -0
  159. package/templates/skills/shellcheck-configuration/SKILL.md +454 -0
  160. package/templates/skills/similarity-search-patterns/SKILL.md +558 -0
  161. package/templates/skills/slo-implementation/SKILL.md +329 -0
  162. package/templates/skills/sql-optimization-patterns/SKILL.md +493 -0
  163. package/templates/skills/stripe-integration/SKILL.md +442 -0
  164. package/templates/skills/tailwind-design-system/SKILL.md +666 -0
  165. package/templates/skills/temporal-python-testing/SKILL.md +158 -0
  166. package/templates/skills/temporal-python-testing/resources/integration-testing.md +455 -0
  167. package/templates/skills/temporal-python-testing/resources/local-setup.md +553 -0
  168. package/templates/skills/temporal-python-testing/resources/replay-testing.md +462 -0
  169. package/templates/skills/temporal-python-testing/resources/unit-testing.md +328 -0
  170. package/templates/skills/terraform-module-library/SKILL.md +249 -0
  171. package/templates/skills/terraform-module-library/references/aws-modules.md +63 -0
  172. package/templates/skills/threat-mitigation-mapping/SKILL.md +745 -0
  173. package/templates/skills/track-management/SKILL.md +593 -0
  174. package/templates/skills/typescript-advanced-types/SKILL.md +717 -0
  175. package/templates/skills/uv-package-manager/SKILL.md +831 -0
  176. package/templates/skills/vector-index-tuning/SKILL.md +521 -0
  177. package/templates/skills/wcag-audit-patterns/SKILL.md +555 -0
  178. package/templates/skills/workflow-orchestration-patterns/SKILL.md +316 -0
  179. package/templates/skills/workflow-patterns/SKILL.md +623 -0
  180. package/templates/agents/game-developer.agent.md +0 -57
  181. package/templates/agents/kubernetes-specialist.agent.md +0 -56
  182. package/templates/agents/market-researcher.agent.md +0 -47
@@ -0,0 +1,567 @@
1
+ ---
2
+ name: fastapi-templates
3
+ description: Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
4
+ ---
5
+
6
+ # FastAPI Project Templates
7
+
8
+ Production-ready FastAPI project structures with async patterns, dependency injection, middleware, and best practices for building high-performance APIs.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Starting new FastAPI projects from scratch
13
+ - Implementing async REST APIs with Python
14
+ - Building high-performance web services and microservices
15
+ - Creating async applications with PostgreSQL, MongoDB
16
+ - Setting up API projects with proper structure and testing
17
+
18
+ ## Core Concepts
19
+
20
+ ### 1. Project Structure
21
+
22
+ **Recommended Layout:**
23
+
24
+ ```
25
+ app/
26
+ ├── api/ # API routes
27
+ │ ├── v1/
28
+ │ │ ├── endpoints/
29
+ │ │ │ ├── users.py
30
+ │ │ │ ├── auth.py
31
+ │ │ │ └── items.py
32
+ │ │ └── router.py
33
+ │ └── dependencies.py # Shared dependencies
34
+ ├── core/ # Core configuration
35
+ │ ├── config.py
36
+ │ ├── security.py
37
+ │ └── database.py
38
+ ├── models/ # Database models
39
+ │ ├── user.py
40
+ │ └── item.py
41
+ ├── schemas/ # Pydantic schemas
42
+ │ ├── user.py
43
+ │ └── item.py
44
+ ├── services/ # Business logic
45
+ │ ├── user_service.py
46
+ │ └── auth_service.py
47
+ ├── repositories/ # Data access
48
+ │ ├── user_repository.py
49
+ │ └── item_repository.py
50
+ └── main.py # Application entry
51
+ ```
52
+
53
+ ### 2. Dependency Injection
54
+
55
+ FastAPI's built-in DI system using `Depends`:
56
+
57
+ - Database session management
58
+ - Authentication/authorization
59
+ - Shared business logic
60
+ - Configuration injection
61
+
62
+ ### 3. Async Patterns
63
+
64
+ Proper async/await usage:
65
+
66
+ - Async route handlers
67
+ - Async database operations
68
+ - Async background tasks
69
+ - Async middleware
70
+
71
+ ## Implementation Patterns
72
+
73
+ ### Pattern 1: Complete FastAPI Application
74
+
75
+ ```python
76
+ # main.py
77
+ from fastapi import FastAPI, Depends
78
+ from fastapi.middleware.cors import CORSMiddleware
79
+ from contextlib import asynccontextmanager
80
+
81
+ @asynccontextmanager
82
+ async def lifespan(app: FastAPI):
83
+ """Application lifespan events."""
84
+ # Startup
85
+ await database.connect()
86
+ yield
87
+ # Shutdown
88
+ await database.disconnect()
89
+
90
+ app = FastAPI(
91
+ title="API Template",
92
+ version="1.0.0",
93
+ lifespan=lifespan
94
+ )
95
+
96
+ # CORS middleware
97
+ app.add_middleware(
98
+ CORSMiddleware,
99
+ allow_origins=["*"],
100
+ allow_credentials=True,
101
+ allow_methods=["*"],
102
+ allow_headers=["*"],
103
+ )
104
+
105
+ # Include routers
106
+ from app.api.v1.router import api_router
107
+ app.include_router(api_router, prefix="/api/v1")
108
+
109
+ # core/config.py
110
+ from pydantic_settings import BaseSettings
111
+ from functools import lru_cache
112
+
113
+ class Settings(BaseSettings):
114
+ """Application settings."""
115
+ DATABASE_URL: str
116
+ SECRET_KEY: str
117
+ ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
118
+ API_V1_STR: str = "/api/v1"
119
+
120
+ class Config:
121
+ env_file = ".env"
122
+
123
+ @lru_cache()
124
+ def get_settings() -> Settings:
125
+ return Settings()
126
+
127
+ # core/database.py
128
+ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
129
+ from sqlalchemy.ext.declarative import declarative_base
130
+ from sqlalchemy.orm import sessionmaker
131
+ from app.core.config import get_settings
132
+
133
+ settings = get_settings()
134
+
135
+ engine = create_async_engine(
136
+ settings.DATABASE_URL,
137
+ echo=True,
138
+ future=True
139
+ )
140
+
141
+ AsyncSessionLocal = sessionmaker(
142
+ engine,
143
+ class_=AsyncSession,
144
+ expire_on_commit=False
145
+ )
146
+
147
+ Base = declarative_base()
148
+
149
+ async def get_db() -> AsyncSession:
150
+ """Dependency for database session."""
151
+ async with AsyncSessionLocal() as session:
152
+ try:
153
+ yield session
154
+ await session.commit()
155
+ except Exception:
156
+ await session.rollback()
157
+ raise
158
+ finally:
159
+ await session.close()
160
+ ```
161
+
162
+ ### Pattern 2: CRUD Repository Pattern
163
+
164
+ ```python
165
+ # repositories/base_repository.py
166
+ from typing import Generic, TypeVar, Type, Optional, List
167
+ from sqlalchemy.ext.asyncio import AsyncSession
168
+ from sqlalchemy import select
169
+ from pydantic import BaseModel
170
+
171
+ ModelType = TypeVar("ModelType")
172
+ CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
173
+ UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
174
+
175
+ class BaseRepository(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
176
+ """Base repository for CRUD operations."""
177
+
178
+ def __init__(self, model: Type[ModelType]):
179
+ self.model = model
180
+
181
+ async def get(self, db: AsyncSession, id: int) -> Optional[ModelType]:
182
+ """Get by ID."""
183
+ result = await db.execute(
184
+ select(self.model).where(self.model.id == id)
185
+ )
186
+ return result.scalars().first()
187
+
188
+ async def get_multi(
189
+ self,
190
+ db: AsyncSession,
191
+ skip: int = 0,
192
+ limit: int = 100
193
+ ) -> List[ModelType]:
194
+ """Get multiple records."""
195
+ result = await db.execute(
196
+ select(self.model).offset(skip).limit(limit)
197
+ )
198
+ return result.scalars().all()
199
+
200
+ async def create(
201
+ self,
202
+ db: AsyncSession,
203
+ obj_in: CreateSchemaType
204
+ ) -> ModelType:
205
+ """Create new record."""
206
+ db_obj = self.model(**obj_in.dict())
207
+ db.add(db_obj)
208
+ await db.flush()
209
+ await db.refresh(db_obj)
210
+ return db_obj
211
+
212
+ async def update(
213
+ self,
214
+ db: AsyncSession,
215
+ db_obj: ModelType,
216
+ obj_in: UpdateSchemaType
217
+ ) -> ModelType:
218
+ """Update record."""
219
+ update_data = obj_in.dict(exclude_unset=True)
220
+ for field, value in update_data.items():
221
+ setattr(db_obj, field, value)
222
+ await db.flush()
223
+ await db.refresh(db_obj)
224
+ return db_obj
225
+
226
+ async def delete(self, db: AsyncSession, id: int) -> bool:
227
+ """Delete record."""
228
+ obj = await self.get(db, id)
229
+ if obj:
230
+ await db.delete(obj)
231
+ return True
232
+ return False
233
+
234
+ # repositories/user_repository.py
235
+ from app.repositories.base_repository import BaseRepository
236
+ from app.models.user import User
237
+ from app.schemas.user import UserCreate, UserUpdate
238
+
239
+ class UserRepository(BaseRepository[User, UserCreate, UserUpdate]):
240
+ """User-specific repository."""
241
+
242
+ async def get_by_email(self, db: AsyncSession, email: str) -> Optional[User]:
243
+ """Get user by email."""
244
+ result = await db.execute(
245
+ select(User).where(User.email == email)
246
+ )
247
+ return result.scalars().first()
248
+
249
+ async def is_active(self, db: AsyncSession, user_id: int) -> bool:
250
+ """Check if user is active."""
251
+ user = await self.get(db, user_id)
252
+ return user.is_active if user else False
253
+
254
+ user_repository = UserRepository(User)
255
+ ```
256
+
257
+ ### Pattern 3: Service Layer
258
+
259
+ ```python
260
+ # services/user_service.py
261
+ from typing import Optional
262
+ from sqlalchemy.ext.asyncio import AsyncSession
263
+ from app.repositories.user_repository import user_repository
264
+ from app.schemas.user import UserCreate, UserUpdate, User
265
+ from app.core.security import get_password_hash, verify_password
266
+
267
+ class UserService:
268
+ """Business logic for users."""
269
+
270
+ def __init__(self):
271
+ self.repository = user_repository
272
+
273
+ async def create_user(
274
+ self,
275
+ db: AsyncSession,
276
+ user_in: UserCreate
277
+ ) -> User:
278
+ """Create new user with hashed password."""
279
+ # Check if email exists
280
+ existing = await self.repository.get_by_email(db, user_in.email)
281
+ if existing:
282
+ raise ValueError("Email already registered")
283
+
284
+ # Hash password
285
+ user_in_dict = user_in.dict()
286
+ user_in_dict["hashed_password"] = get_password_hash(user_in_dict.pop("password"))
287
+
288
+ # Create user
289
+ user = await self.repository.create(db, UserCreate(**user_in_dict))
290
+ return user
291
+
292
+ async def authenticate(
293
+ self,
294
+ db: AsyncSession,
295
+ email: str,
296
+ password: str
297
+ ) -> Optional[User]:
298
+ """Authenticate user."""
299
+ user = await self.repository.get_by_email(db, email)
300
+ if not user:
301
+ return None
302
+ if not verify_password(password, user.hashed_password):
303
+ return None
304
+ return user
305
+
306
+ async def update_user(
307
+ self,
308
+ db: AsyncSession,
309
+ user_id: int,
310
+ user_in: UserUpdate
311
+ ) -> Optional[User]:
312
+ """Update user."""
313
+ user = await self.repository.get(db, user_id)
314
+ if not user:
315
+ return None
316
+
317
+ if user_in.password:
318
+ user_in_dict = user_in.dict(exclude_unset=True)
319
+ user_in_dict["hashed_password"] = get_password_hash(
320
+ user_in_dict.pop("password")
321
+ )
322
+ user_in = UserUpdate(**user_in_dict)
323
+
324
+ return await self.repository.update(db, user, user_in)
325
+
326
+ user_service = UserService()
327
+ ```
328
+
329
+ ### Pattern 4: API Endpoints with Dependencies
330
+
331
+ ```python
332
+ # api/v1/endpoints/users.py
333
+ from fastapi import APIRouter, Depends, HTTPException, status
334
+ from sqlalchemy.ext.asyncio import AsyncSession
335
+ from typing import List
336
+
337
+ from app.core.database import get_db
338
+ from app.schemas.user import User, UserCreate, UserUpdate
339
+ from app.services.user_service import user_service
340
+ from app.api.dependencies import get_current_user
341
+
342
+ router = APIRouter()
343
+
344
+ @router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
345
+ async def create_user(
346
+ user_in: UserCreate,
347
+ db: AsyncSession = Depends(get_db)
348
+ ):
349
+ """Create new user."""
350
+ try:
351
+ user = await user_service.create_user(db, user_in)
352
+ return user
353
+ except ValueError as e:
354
+ raise HTTPException(status_code=400, detail=str(e))
355
+
356
+ @router.get("/me", response_model=User)
357
+ async def read_current_user(
358
+ current_user: User = Depends(get_current_user)
359
+ ):
360
+ """Get current user."""
361
+ return current_user
362
+
363
+ @router.get("/{user_id}", response_model=User)
364
+ async def read_user(
365
+ user_id: int,
366
+ db: AsyncSession = Depends(get_db),
367
+ current_user: User = Depends(get_current_user)
368
+ ):
369
+ """Get user by ID."""
370
+ user = await user_service.repository.get(db, user_id)
371
+ if not user:
372
+ raise HTTPException(status_code=404, detail="User not found")
373
+ return user
374
+
375
+ @router.patch("/{user_id}", response_model=User)
376
+ async def update_user(
377
+ user_id: int,
378
+ user_in: UserUpdate,
379
+ db: AsyncSession = Depends(get_db),
380
+ current_user: User = Depends(get_current_user)
381
+ ):
382
+ """Update user."""
383
+ if current_user.id != user_id:
384
+ raise HTTPException(status_code=403, detail="Not authorized")
385
+
386
+ user = await user_service.update_user(db, user_id, user_in)
387
+ if not user:
388
+ raise HTTPException(status_code=404, detail="User not found")
389
+ return user
390
+
391
+ @router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
392
+ async def delete_user(
393
+ user_id: int,
394
+ db: AsyncSession = Depends(get_db),
395
+ current_user: User = Depends(get_current_user)
396
+ ):
397
+ """Delete user."""
398
+ if current_user.id != user_id:
399
+ raise HTTPException(status_code=403, detail="Not authorized")
400
+
401
+ deleted = await user_service.repository.delete(db, user_id)
402
+ if not deleted:
403
+ raise HTTPException(status_code=404, detail="User not found")
404
+ ```
405
+
406
+ ### Pattern 5: Authentication & Authorization
407
+
408
+ ```python
409
+ # core/security.py
410
+ from datetime import datetime, timedelta
411
+ from typing import Optional
412
+ from jose import JWTError, jwt
413
+ from passlib.context import CryptContext
414
+ from app.core.config import get_settings
415
+
416
+ settings = get_settings()
417
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
418
+
419
+ ALGORITHM = "HS256"
420
+
421
+ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
422
+ """Create JWT access token."""
423
+ to_encode = data.copy()
424
+ if expires_delta:
425
+ expire = datetime.utcnow() + expires_delta
426
+ else:
427
+ expire = datetime.utcnow() + timedelta(minutes=15)
428
+ to_encode.update({"exp": expire})
429
+ encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
430
+ return encoded_jwt
431
+
432
+ def verify_password(plain_password: str, hashed_password: str) -> bool:
433
+ """Verify password against hash."""
434
+ return pwd_context.verify(plain_password, hashed_password)
435
+
436
+ def get_password_hash(password: str) -> str:
437
+ """Hash password."""
438
+ return pwd_context.hash(password)
439
+
440
+ # api/dependencies.py
441
+ from fastapi import Depends, HTTPException, status
442
+ from fastapi.security import OAuth2PasswordBearer
443
+ from jose import JWTError, jwt
444
+ from sqlalchemy.ext.asyncio import AsyncSession
445
+
446
+ from app.core.database import get_db
447
+ from app.core.security import ALGORITHM
448
+ from app.core.config import get_settings
449
+ from app.repositories.user_repository import user_repository
450
+
451
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/auth/login")
452
+
453
+ async def get_current_user(
454
+ db: AsyncSession = Depends(get_db),
455
+ token: str = Depends(oauth2_scheme)
456
+ ):
457
+ """Get current authenticated user."""
458
+ credentials_exception = HTTPException(
459
+ status_code=status.HTTP_401_UNAUTHORIZED,
460
+ detail="Could not validate credentials",
461
+ headers={"WWW-Authenticate": "Bearer"},
462
+ )
463
+
464
+ try:
465
+ payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[ALGORITHM])
466
+ user_id: int = payload.get("sub")
467
+ if user_id is None:
468
+ raise credentials_exception
469
+ except JWTError:
470
+ raise credentials_exception
471
+
472
+ user = await user_repository.get(db, user_id)
473
+ if user is None:
474
+ raise credentials_exception
475
+
476
+ return user
477
+ ```
478
+
479
+ ## Testing
480
+
481
+ ```python
482
+ # tests/conftest.py
483
+ import pytest
484
+ import asyncio
485
+ from httpx import AsyncClient
486
+ from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
487
+ from sqlalchemy.orm import sessionmaker
488
+
489
+ from app.main import app
490
+ from app.core.database import get_db, Base
491
+
492
+ TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
493
+
494
+ @pytest.fixture(scope="session")
495
+ def event_loop():
496
+ loop = asyncio.get_event_loop_policy().new_event_loop()
497
+ yield loop
498
+ loop.close()
499
+
500
+ @pytest.fixture
501
+ async def db_session():
502
+ engine = create_async_engine(TEST_DATABASE_URL, echo=True)
503
+ async with engine.begin() as conn:
504
+ await conn.run_sync(Base.metadata.create_all)
505
+
506
+ AsyncSessionLocal = sessionmaker(
507
+ engine, class_=AsyncSession, expire_on_commit=False
508
+ )
509
+
510
+ async with AsyncSessionLocal() as session:
511
+ yield session
512
+
513
+ @pytest.fixture
514
+ async def client(db_session):
515
+ async def override_get_db():
516
+ yield db_session
517
+
518
+ app.dependency_overrides[get_db] = override_get_db
519
+
520
+ async with AsyncClient(app=app, base_url="http://test") as client:
521
+ yield client
522
+
523
+ # tests/test_users.py
524
+ import pytest
525
+
526
+ @pytest.mark.asyncio
527
+ async def test_create_user(client):
528
+ response = await client.post(
529
+ "/api/v1/users/",
530
+ json={
531
+ "email": "test@example.com",
532
+ "password": "testpass123",
533
+ "name": "Test User"
534
+ }
535
+ )
536
+ assert response.status_code == 201
537
+ data = response.json()
538
+ assert data["email"] == "test@example.com"
539
+ assert "id" in data
540
+ ```
541
+
542
+ ## Resources
543
+
544
+ - **references/fastapi-architecture.md**: Detailed architecture guide
545
+ - **references/async-best-practices.md**: Async/await patterns
546
+ - **references/testing-strategies.md**: Comprehensive testing guide
547
+ - **assets/project-template/**: Complete FastAPI project
548
+ - **assets/docker-compose.yml**: Development environment setup
549
+
550
+ ## Best Practices
551
+
552
+ 1. **Async All The Way**: Use async for database, external APIs
553
+ 2. **Dependency Injection**: Leverage FastAPI's DI system
554
+ 3. **Repository Pattern**: Separate data access from business logic
555
+ 4. **Service Layer**: Keep business logic out of routes
556
+ 5. **Pydantic Schemas**: Strong typing for request/response
557
+ 6. **Error Handling**: Consistent error responses
558
+ 7. **Testing**: Test all layers independently
559
+
560
+ ## Common Pitfalls
561
+
562
+ - **Blocking Code in Async**: Using synchronous database drivers
563
+ - **No Service Layer**: Business logic in route handlers
564
+ - **Missing Type Hints**: Loses FastAPI's benefits
565
+ - **Ignoring Sessions**: Not properly managing database sessions
566
+ - **No Testing**: Skipping integration tests
567
+ - **Tight Coupling**: Direct database access in routes