mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-27 23:16:49 +00:00
5.1 KiB
5.1 KiB
06 — Code Standards and Style
General Principles
- Preserve the style of the surrounding file. When in doubt, read neighboring code first.
- Prefer the smallest correct change. Do not introduce a new abstraction layer without a clear payoff.
- Do not add features, refactors, or abstractions beyond what the task requires.
- Do not add error handling or validation for scenarios that cannot happen. Trust internal code and framework guarantees; only validate at system boundaries (user input, external API responses).
Python Version and Typing
- Target: Python 3.11+. CI runs Python 3.12.
- Type annotations are required on all public methods and function signatures.
- Use
Optional[X]for nullable types (do not useX | None— keep consistency with the existing codebase style). - Use
Union[X, Y]for multi-type parameters. - Prefer
list[X],dict[K, V],tuple[X, Y]built-in generics in new code (Python 3.9+); match the style of the surrounding file. - Use
pathlib.Pathfor all file path operations. Never use raw string concatenation for paths.
Pydantic Models
- All request body and response models must be defined as Pydantic
BaseModelsubclasses inapp/schemas/. - Use
Field(...)for required fields; useField(default=...)orField(None)for optional fields. - Do not define ad-hoc
dictreturn types for API responses — define a schema class. - Settings and deployment configuration live in
ConfigModel/Settingsinapp/core/config.pyusingpydantic-settings. - Use
model_validatorfor cross-field validation logic.
Async and Concurrency
- Prefer
async deffor I/O-bound operations (network requests, database queries, file operations). - Use
awaitconsistently; do not mix sync and async code paths in the same function without usingrun_in_threadpoolfrom FastAPI orasyncio.to_thread. - For CPU-bound work that must not block the event loop, submit to
ThreadHelper(seeapp/helper/thread.py). - Do not use bare
threading.Threadin new code; useThreadHelper.submit().
Imports
Order imports as follows, separated by blank lines:
- Standard library (
import os,import json, etc.) - Third-party packages (
from fastapi import ...,from pydantic import ...) - Local application packages (
from app.chain import ...,from app.schemas import ...)
Within each group, sort alphabetically. Do not use wildcard imports (from module import *) in application code.
String Formatting
- Use f-strings for all string interpolation. Do not use
%formatting or.format(). - For log messages, use
logger.info(f"...")— do not use lazy%sformat in logger calls (the project does not rely on lazy evaluation here).
Error Handling
- In chain and module layers: do not raise HTTP exceptions. Catch exceptions, log them, and return
Noneor a domain-level error object so the caller can decide how to proceed. - In endpoint layer: use FastAPI's
HTTPExceptionor the project's standard response schemas for errors. - Never swallow exceptions silently. At minimum log the error with
logger.error(f"...: {str(err)}"). - Do not use bare
except:— always catch a specific exception type or at minimumException.
# Correct
try:
result = self.do_work()
except Exception as err:
logger.error(f"Failed to do work: {str(err)}")
return None
# Wrong — swallowing silently
try:
result = self.do_work()
except:
pass
Logging
- Use
loggerfromapp/log.py. Do not import the standard libraryloggingdirectly in application code. - Log levels:
logger.debug(...)— detailed diagnostic information, disabled by default.logger.info(...)— normal operational events.logger.warning(...)— unexpected but recoverable situations.logger.error(...)— failures that affect functionality.
- Keep log messages in Chinese unless the surrounding file consistently uses English.
Constants and Magic Values
- Do not scatter raw string keys for
SystemConfig. Add aSystemConfigKeyenum entry and reference it. - Do not use magic numbers or magic strings inline. Define a named constant or enum value.
File Organization
- One primary class per file is the norm for chains, modules, and helpers.
- Private helper functions in the same file are preferable to extracting a new helper for single-use logic.
- Keep files focused on one domain concern.
What Not To Do
- Do not introduce new third-party libraries without updating
requirements.inand runningpip-compile. - Do not use
requestsorhttpxdirectly for external HTTP calls — useRequestUtilsfromapp/utils/http.py. - Do not issue raw SQLAlchemy queries from chains, modules, or endpoints — use the
*_oper.pyclasses. - Do not add TODO or FIXME without context. Only keep one if it is genuinely deferred and cannot be addressed in the current task.
- Do not add noisy markers like
# change starts here,# important, or# this is a fix. - Do not write comments that restate what the code already clearly says.
Last Updated: 2026-05-25