agentsclimarketplace

Python

Skill aps08/fullstack-clean-architecture/.agents/skills/python

Read to code, just run Docker compose.

Install
npx -y skills add aps08/fullstack-clean-architecture --skill python

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Enforces FastAPI, Dependency Injection, and general Python coding standards based on the repository structure.

SKILL.md

5.0 KB, as published. Nobody here has run it

Python & FastAPI Coding & Architecture Guidelines

Use this skill when extending the Python backend, writing routes, services, or repositories, or working with core server logic.


1. FastAPI & Dependency Injection

We use dependency-injector for wiring application components together.

  • Wiring: The container is defined in server/app/core/container.py and wired in server/app/main.py.

  • Dependency injection in Routes:

    • Decorate endpoints with @inject (from dependency_injector.wiring).

    • Create clean dependency type aliases using Annotated and Depends(Provide[Container.service_name]).

    • Example:

      TodoServiceDep = Annotated[TodoService, Depends(Provide[Container.todo_service])]
      
      @router.get("/todos/")
      @inject
      async def list_todos(service: TodoServiceDep):
          ...
      
  • No Direct Instantiation: Do not manually instantiate services or repositories; resolve them via the container.


2. FastAPI Route & Handler Best Practices

Use Annotated

Always prefer the Annotated style for parameter and dependency declarations.

from typing import Annotated
from fastapi import Path, Query

@router.get("/items/{item_id}")
async def read_item(
    item_id: Annotated[UUID, Path(description="The item ID")],
    q: Annotated[str | None, Query(max_length=50)] = None,
):
    ...

Return Types & response_model

  • Specify explicit return type annotations (-> Model) for FastAPI validation, filtering, and serialization (running Pydantic's Rust-based serialization).
  • If the returned object differs from the API response contract (e.g. returning a database model that needs filtering/serialization to a public schema), use response_model on the router decorator instead:
@router.get("/todos/{todo_id}", response_model=Todo)
async def get_todo(todo_id: UUID) -> Any:
    ...

No Ellipsis (...) for Required Fields

Do not use ... as a default value for required fields or query parameters.

# CORRECT
async def create_item(item: Item, project_id: Annotated[int, Query()]): ...

# INCORRECT
async def create_item(item: Item, project_id: Annotated[int, Query(...)]): ...

Declaring APIRouters

Prefer defining path prefixes and tags on the router itself, rather than in include_router():

router = APIRouter(prefix="/todos", tags=["todos"])

Async vs Sync Handlers

  • Use async def only when calling await-compatible non-blocking code.
  • If a route calls blocking code (like synchronous DB queries or filesystem operations), use standard def instead of async def so FastAPI runs it in an external threadpool.

Do not use Pydantic RootModel

Instead, use regular type annotations with Annotated and validation utilities:

@router.post("/items/")
async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]):
    return items

One HTTP Method Per Function

Keep handler functions dedicated to a single HTTP operation. Do not use @router.api_route for multiple methods in a single function.


3. Layered Architecture

Always structure backend logic using the established 3-layer architecture:

  1. Routes/Endpoints (app/routes): Parse requests, validate inputs via Pydantic, call services, and handle HTTP routing. Keep business logic out of this layer.
  2. Services (app/services): Implement business logic, orchestration, and validation checks. Inherit from BaseService for CRUD operations.
  3. Repositories (app/repositories): Handle raw database persistence and queries using SQLAlchemy. Inherit from BaseRepository.

4. Database Scopes & Transactions

  • Scoped Sessions: Uses async_scoped_session keyed by a unique request-based UUID context variable.
  • Transactions:
    • Service-level or middleware-level functions run within async with db.session_scope(): to ensure automatic rollback on failure and commit on success.
    • Always perform queries asynchronously (e.g. await session.execute(...)).
  • Timezones: Use timezone-aware datetime objects (TIMESTAMP(timezone=True)) or Pydantic UTC validation.

5. Code Quality & Type Safety

  • Type Annotations: Annotate all function signatures and variables. Use Annotated, TypeVar, and Generic for generic classes like repositories.
  • Pydantic Models: Define explicit request/response schemas under app/schemas/.
    • Ensure they map accurately to database models.
    • Configure model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True, from_attributes=True) for camelCase serialization support.
  • Error Handling: Centralize errors using specific exceptions defined in app/core/exceptions.py (e.g. NotFoundError, DuplicatedError).

6. Background Tasks

  • Always use BackgroundTasks when sending emails or other long-running tasks to prevent user delays in response to user requests.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.