| 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"] |
Python Patterns Skill
Cuándo usar esta skill
- Al escribir nuevo código Python.
- Al revisar código existente.
- Cuando necesites decidir patrones de diseño.
- Al estructurar módulos y clases.
Patrones Core del Proyecto
1. Estructura de Módulos
"""
Descripción breve del módulo.
Descripción más detallada si es necesario.
"""
from datetime import datetime
from pathlib import Path
from typing import Optional, Tuple, Dict, List
from fastmcp import FastMCP
from pydantic import BaseModel
from ..config import get_vault_path
from ..utils import get_logger
logger = get_logger(__name__)
def _helper_function(data: str) -> str:
"""Helper interno del módulo."""
return data.strip()
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)
2. Type Hints (Obligatorio)
def process_note(
path: Path,
options: Optional[Dict[str, Any]] = None,
) -> Tuple[bool, str]:
...
def process_note(path, options=None):
...
Tipos comunes en el proyecto:
from pathlib import Path
from typing import Optional, Tuple, Dict, List, Any, Literal
def operation() -> Tuple[bool, str]:
"""Retorna (success, message)."""
if error:
return False, "Error message"
return True, "Success"
TransportType = Literal["stdio", "http", "sse"]
3. Patrón de Resultado (Success/Error)
def operation(param: str) -> str:
"""
Realiza operación.
Returns:
Mensaje con emoji indicando resultado.
"""
try:
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."
result = do_something(param)
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}"
4. Patrón de Validación (Tuple)
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, ""
is_valid, error = validate_something(input_value)
if not is_valid:
return f"❌ {error}"
5. Configuración con Pydantic
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()
6. Singleton Pattern (Settings)
_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
Convenciones de Nombres
| 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() |
Docstrings (Google Style)
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)
"""
Error Handling
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}"
Logging
from ..utils import get_logger
logger = get_logger(__name__)
logger.debug("Detalles de debugging")
logger.info("Operación completada")
logger.warning("Situación anómala")
logger.error("Error en operación")
logger.exception("Con traceback completo")
Anti-Patterns a Evitar
def my_function():
import os
...
def bad(items: List = []):
items.append(1)
def good(items: Optional[List] = None):
if items is None:
items = []
try:
...
except:
pass
try:
...
except Exception as e:
logger.error(f"Error: {e}")
result = ""
for item in items:
result += str(item)
result = "".join(str(item) for item in items)
Checklist de Revisión
Al revisar código nuevo, verificar: