

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Hermes API - FastAPI Endpoints Rules78## Endpoint Structure910### File Organization11- Endpoints in `app/api/v1/endpoints/`12- One resource per file: `downloads.py`, `auth.py`13- Router registration in `app/api/v1/router.py`14- Shared dependencies in `app/api/dependencies.py`1516### Router Definition17```python18from fastapi import APIRouter1920router = APIRouter(tags=["downloads"])2122@router.get("/list")23async def list_downloads():24 pass25```2627## Dependency Injection2829### Common Dependencies30```python31from app.api.dependencies import get_current_user_from_token32from app.db.session import get_database_session3334@router.get("/profile")35async def get_profile(36 current_user: dict = Depends(get_current_user_from_token),37 db: AsyncSession = Depends(get_database_session)38):39 return current_user40```4142- `get_database_session()` - Database session43- `get_current_user_from_token()` - Authenticated user44- `get_current_user_optional()` - Optional auth4546## Request/Response Models4748```python49from pydantic import Field50from app.models.pydantic.download import DownloadCreateRequest, DownloadResponse5152@router.post("/", response_model=DownloadResponse, status_code=201)53async def create_download(54 request: DownloadCreateRequest,55 current_user: dict = Depends(get_current_user_from_token),56 db: AsyncSession = Depends(get_database_session)57):58 # Implementation59 pass60```6162### Model Naming63- `CreateRequest` - For creation64- `UpdateRequest` - For updates65- `Response` - For responses66- `ListResponse` - For lists6768## Error Handling6970### HTTP Exceptions71```python72from fastapi import HTTPException, status7374if not download:75 raise HTTPException(76 status_code=status.HTTP_404_NOT_FOUND,77 detail=f"Download {download_id} not found"78 )79```8081Common status codes:82- `400 BAD_REQUEST` - Invalid input83- `401 UNAUTHORIZED` - Auth required84- `403 FORBIDDEN` - Permission denied85- `404 NOT_FOUND` - Not found86- `409 CONFLICT` - Duplicate87- `422 UNPROCESSABLE_ENTITY` - Validation error (automatic)88- `500 INTERNAL_SERVER_ERROR` - Server error8990### Logging91```python92from app.core.logging import get_logger9394logger = get_logger(__name__)9596try:97 # Operation98 pass99except Exception as e:100 logger.error(101 "Operation failed",102 error=str(e),103 error_type=type(e).__name__,104 user_id=current_user["id"]105 )106 raise HTTPException(107 status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,108 detail="Operation failed"109 )110```111112## Endpoint Patterns113114### List115```python116@router.get("/", response_model=List[ItemResponse])117async def list_items(118 skip: int = Query(0, ge=0),119 limit: int = Query(100, ge=1, le=100),120 db: AsyncSession = Depends(get_database_session)121):122 repos = await get_repositories()123 items = await repos["items"].get_all(skip=skip, limit=limit)124 return items125```126127### Create128```python129@router.post("/", status_code=status.HTTP_201_CREATED, response_model=ItemResponse)130async def create_item(131 request: ItemCreateRequest,132 current_user: dict = Depends(get_current_user_from_token),133 db: AsyncSession = Depends(get_database_session)134):135 repos = await get_repositories()136 item = await repos["items"].create({137 **request.dict(),138 "user_id": current_user["id"]139 })140 return item141```142143### Get144```python145@router.get("/{item_id}", response_model=ItemResponse)146async def get_item(147 item_id: str,148 current_user: dict = Depends(get_current_user_from_token),149 db: AsyncSession = Depends(get_database_session)150):151 repos = await get_repositories()152 item = await repos["items"].get_by_id(item_id)153154 if not item:155 raise HTTPException(156 status_code=status.HTTP_404_NOT_FOUND,157 detail=f"Item {item_id} not found"158 )159160 if item.user_id != current_user["id"]:161 raise HTTPException(162 status_code=status.HTTP_403_FORBIDDEN,163 detail="Not authorized"164 )165166 return item167```168169### Delete170```python171@router.delete("/{item_id}", status_code=status.HTTP_204_NO_CONTENT)172async def delete_item(173 item_id: str,174 current_user: dict = Depends(get_current_user_from_token),175 db: AsyncSession = Depends(get_database_session)176):177 repos = await get_repositories()178 item = await repos["items"].get_by_id(item_id)179180 if not item:181 raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)182183 if item.user_id != current_user["id"]:184 raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)185186 await repos["items"].delete(item_id)187```188189## Background Tasks190191```python192from app.tasks.download_tasks import process_download193194@router.post("/download")195async def trigger_download(196 request: DownloadRequest,197 current_user: dict = Depends(get_current_user_from_token)198):199 task = process_download.delay(200 url=request.url,201 user_id=current_user["id"]202 )203204 return {"task_id": task.id, "status": "queued"}205```206207## OpenAPI Documentation208209```python210@router.get("/{item_id}", response_model=ItemResponse)211async def get_item(item_id: str):212 """213 Get a single item by ID.214215 Returns item details if found and user has access.216 Raises 404 if item doesn't exist.217 """218 pass219```220221- Include docstrings for all endpoints222- Use tags to group related endpoints223- Document parameters and responses224
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TechSquidTV/Hermes.cursor/rules/30-tests.mdc · 46 | Cursor rules | buildteststylearch+4 | 85/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-app.mdc · 46 | Cursor rules | lint-formatstylearchtypes+5 | 88/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 46 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-app-components.mdc · 46 | Cursor rules | archtypesuiperformance+1 | 65/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-app-routes.mdc · 46 | Cursor rules | archapiuido-not | 65/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/30-docker.mdc · 46 | Cursor rules | setupbuildstylesecurity+4 | 84/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/00-project.mdc · 46 | Cursor rules | setuplint-formatstylearch+4 | 89/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-db.mdc · 46 | Cursor rules | teststylearchtesting-strategy+3 | 73/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-app-hooks.mdc · 46 | Cursor rules | lint-formatstylearchtypes+3 | 73/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/30-docs.mdc · 46 | Cursor rules | setuplint-formatstylearch+3 | 81/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| bybren-llc/safe-agentic-workflow.cursor/rules/10-backend-python.mdc · 399 | Cursor rules | testlint-formatstylegit+4 | 97/100 | today |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/techsquidtv-hermes-cursor-rules-20-hermes-api-api)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.