一键导入
python-patterns
Buenas prácticas y patrones de desarrollo Python para el proyecto MCP. Incluye estándares de código, patrones arquitectónicos, y convenciones.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Buenas prácticas y patrones de desarrollo Python para el proyecto MCP. Incluye estándares de código, patrones arquitectónicos, y convenciones.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Entrevista a un experto de dominio (SME) para extraer su conocimiento técnico tácito y sintetizarlo en una Skill reutilizable. Se activa PROACTIVAMENTE ante 3 situaciones: (1) Frustración — el usuario se queja de código, arquitectura o falta de estándares; (2) Ambigüedad sin Reglas — se pide un refactor profundo pero no hay estándares definidos; (3) Fricción — el usuario ha corregido 2+ veces decisiones de diseño en la misma sesión. USE FOR: extraer estándares, crear reglas de arquitectura, definir anti-patrones, capturar conocimiento tácito, generar prompts reutilizables, entrevistar experto, sintetizar conocimiento técnico, crear skills desde cero.
Entrevista a un experto de dominio (SME) para extraer su conocimiento técnico y sintetizarlo en una Skill Maestra Abstracta (prompt reutilizable). Se activa PROACTIVAMENTE ante 3 situaciones: (1) Frustración — el usuario se queja de código, arquitectura o falta de estándares (ej. "vaya desastre", "arregla este espagueti", "los logs están mal"); (2) Ambigüedad sin Reglas — se pide un refactor profundo o pieza core pero no hay estándares definidos en el contexto; (3) Fricción — el usuario ha corregido 2 o más veces decisiones de diseño/arquitectura/formato en la misma sesión. USE FOR: extraer estándares, crear reglas de arquitectura, definir anti-patrones, refactor sin criterios claros, capturar conocimiento tácito, generar prompts reutilizables, entrevistar experto, sintetizar conocimiento técnico.
Skill para mantener la calidad del código: linting, formatting, type checking. Garantiza que el código cumple con los estándares del proyecto.
Skill para mantener la documentación sincronizada con el código. Incluye patrones de documentación, ubicaciones estándar, y checklists.
Skill para manejar el flujo de trabajo de Git: changelog, commits, push, y releases. Automatiza el proceso de versionado y publicación.
Skill para desarrollar, mantener y extender el servidor MCP de Obsidian. Incluye patrones de código, arquitectura, testing y gestión de paquetes.
| name | Python Patterns |
| description | Buenas prácticas y patrones de desarrollo Python para el proyecto MCP. Incluye estándares de código, patrones arquitectónicos, y convenciones. |
| tools | ["read","edit","grep_search"] |
"""
Descripción breve del módulo.
Descripción más detallada si es necesario.
"""
# 1. Imports de stdlib primero
from datetime import datetime
from pathlib import Path
from typing import Optional, Tuple, Dict, List
# 2. Imports de terceros
from fastmcp import FastMCP
from pydantic import BaseModel
# 3. Imports locales (relativos)
from ..config import get_vault_path
from ..utils import get_logger
# 4. Logger al inicio
logger = get_logger(__name__)
# 5. Funciones helper (privadas) primero
def _helper_function(data: str) -> str:
"""Helper interno del módulo."""
return data.strip()
# 6. Funciones/clases públicas después
def public_function(param: str) -> str:
"""
Función pública del módulo.
Args:
param: Descripción del parámetro.
Returns:
Descripción del retorno.
"""
return _helper_function(param)
# ✅ CORRECTO: Todo tipado
def process_note(
path: Path,
options: Optional[Dict[str, Any]] = None,
) -> Tuple[bool, str]:
...
# ❌ INCORRECTO: Sin tipos
def process_note(path, options=None):
...
Tipos comunes en el proyecto:
from pathlib import Path
from typing import Optional, Tuple, Dict, List, Any, Literal
# Para retornos con error
def operation() -> Tuple[bool, str]:
"""Retorna (success, message)."""
if error:
return False, "Error message"
return True, "Success"
# Para configuración opcional
TransportType = Literal["stdio", "http", "sse"]
# Patrón estándar del proyecto para operaciones
def operation(param: str) -> str:
"""
Realiza operación.
Returns:
Mensaje con emoji indicando resultado.
"""
try:
# Validación temprana
if not param:
return "❌ Error: Parámetro requerido"
vault_path = get_vault_path()
if not vault_path:
return "❌ Error: La ruta del vault no está configurada."
# Lógica principal
result = do_something(param)
# Éxito
return f"✅ Operación completada: {result}"
except SpecificError as e:
return f"❌ Error específico: {e}"
except Exception as e:
return f"❌ Error inesperado: {e}"
def validate_something(value: str) -> Tuple[bool, str]:
"""
Valida un valor.
Returns:
Tupla (es_valido, mensaje_error).
"""
if not value:
return False, "El valor es requerido"
if len(value) < 3:
return False, "El valor debe tener al menos 3 caracteres"
return True, ""
# Uso
is_valid, error = validate_something(input_value)
if not is_valid:
return f"❌ {error}"
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
class MySettings(BaseSettings):
"""Configuración con validación automática."""
model_config = SettingsConfigDict(
env_prefix="MY_APP_",
env_file=".env",
extra="ignore",
)
required_field: str = Field(
description="Campo requerido"
)
optional_field: int = Field(
default=10,
ge=1,
le=100,
description="Campo opcional con límites"
)
@field_validator("required_field", mode="before")
@classmethod
def validate_field(cls, v: str) -> str:
"""Validación personalizada."""
if not v:
raise ValueError("Campo no puede estar vacío")
return v.strip()
_settings: Optional[MySettings] = None
def get_settings() -> MySettings:
"""Get or create singleton."""
global _settings
if _settings is None:
_settings = MySettings()
return _settings
def reset_settings() -> None:
"""Reset singleton (for testing)."""
global _settings
_settings = None
| Tipo | Convención | Ejemplo |
|---|---|---|
| Funciones | snake_case | buscar_notas() |
| Variables | snake_case | vault_path |
| Constantes | UPPER_SNAKE | MAX_RESULTS |
| Clases | PascalCase | VaultSettings |
| Módulos | snake_case | navigation.py |
| Privados | _prefijo | _helper() |
def function_name(param1: str, param2: int = 10) -> Dict[str, Any]:
"""
Descripción breve en una línea.
Descripción más detallada si es necesario. Puede
ocupar múltiples líneas.
Args:
param1: Descripción del primer parámetro.
param2: Descripción del segundo parámetro.
Continuación indentada si es largo.
Returns:
Descripción del valor de retorno.
Raises:
ValueError: Si param1 está vacío.
Example:
>>> result = function_name("test")
>>> print(result)
"""
# Específico antes de genérico
try:
result = risky_operation()
except FileNotFoundError:
logger.warning(f"Archivo no encontrado: {path}")
return "❌ Archivo no existe"
except PermissionError:
logger.error(f"Sin permisos: {path}")
return "⛔ Acceso denegado"
except Exception as e:
logger.exception(f"Error inesperado: {e}")
return f"❌ Error: {e}"
from ..utils import get_logger
logger = get_logger(__name__)
# Niveles apropiados
logger.debug("Detalles de debugging") # Solo en dev
logger.info("Operación completada") # Flujo normal
logger.warning("Situación anómala") # Problema no fatal
logger.error("Error en operación") # Error que afecta función
logger.exception("Con traceback completo") # En bloques except
# ❌ Imports dentro de funciones (excepto lazy imports justificados)
def my_function():
import os # Moverlo arriba
...
# ❌ Mutable default arguments
def bad(items: List = []): # ¡Peligro!
items.append(1)
# ✅ Correcto
def good(items: Optional[List] = None):
if items is None:
items = []
# ❌ Bare except
try:
...
except: # Captura TODO incluido KeyboardInterrupt
pass
# ✅ Correcto
try:
...
except Exception as e:
logger.error(f"Error: {e}")
# ❌ String concatenation en loops
result = ""
for item in items:
result += str(item) # Ineficiente
# ✅ Correcto
result = "".join(str(item) for item in items)
Al revisar código nuevo, verificar: