HOWTO · Python

Estructura del proyecto para una aplicación Python

Aprenda a estructurar una aplicación Python

En esta página

Un proyecto de Python fácil de mantener mantiene su raíz enfocada, agrupa el código relacionado en paquetes y añade carpetas auxiliares solo cuando la aplicación las necesita. Elige la estructura según cómo se ejecute el programa; una aplicación modular también puede desplegarse como un monolito pequeño.

Elige una estructura adecuada para tu aplicación

Una estructura clara facilita encontrar, mantener y compartir el código con otras personas. No obliga a dividir el programa en microservicios. Una aplicación pequeña puede seguir siendo un único programa desplegable y, al mismo tiempo, agrupar el código relacionado en módulos y paquetes. Añade directorios cuando delimiten una parte útil del proyecto; evita crear carpetas vacías solo para imitar la estructura de un proyecto más grande.

La estructura adecuada depende de cómo se ejecute la aplicación y de lo que incluya. Una herramienta de línea de comandos quizá solo necesite el código de la aplicación, información sobre las dependencias y pruebas. Una aplicación web también puede necesitar plantillas y recursos estáticos. Un proyecto que use SQLite puede crear un archivo de base de datos local, mientras que uno conectado a un servicio de base de datos suele mantener esos datos fuera del árbol de código fuente.

Empieza por la raíz del proyecto

La raíz del proyecto es el directorio que contiene los archivos usados para desarrollar, probar, documentar y empaquetar la aplicación. Algunas opciones habituales son un README.md con instrucciones de configuración y uso, una LICENSE que indique cómo pueden utilizar y distribuir el código otras personas, y una declaración de dependencias como pyproject.toml o requirements.txt. Estos archivos cumplen funciones distintas; un proyecto no necesita todos los formatos de empaquetado o gestión de dependencias.

Las aplicaciones de Python no comparten un único nombre obligatorio para el punto de entrada. Una aplicación de línea de comandos podría iniciarse con python -m package_name, mientras que un framework o la configuración de empaquetado puede definir otro comando. Usa el método de inicio adecuado para la aplicación, en lugar de suponer que todo proyecto necesita run.py o setup.py.

Crea un entorno virtual local para aislar los paquetes instalados para el proyecto. No lo incluyas en el control de versiones; quienes colaboren contigo pueden crear el suyo a partir de la información sobre las dependencias. Un archivo .gitignore suele excluir ese entorno, además de las cachés y otros archivos generados. La raíz puede mantenerse compacta: añade documentación o configuración de empaquetado según las necesidades del proyecto.

Organiza el código de la aplicación en paquetes

Agrupa los módulos de Python según su responsabilidad. Por ejemplo, un blog podría guardar el código relacionado con las cuentas en users y el relacionado con las publicaciones en posts. Esta es una organización normal dentro del proceso: ambos paquetes pueden ejecutarse como partes de una misma aplicación y no necesitan comunicarse como servicios independientes.

Un paquete regular suele incluir un archivo __init__.py. Puede estar vacío o exponer nombres seleccionados como parte de la interfaz del paquete. Python también admite paquetes de espacio de nombres que pueden omitir este archivo, así que sigue el estilo de paquetes y las herramientas elegidos para el proyecto, en vez de tratar __init__.py como un requisito universal. Si varias partes usan código compartido, colócalo en un módulo o paquete y evita duplicar el mismo comportamiento en distintas carpetas.

Añade pruebas, documentación y recursos web cuando hagan falta

Un directorio tests mantiene las comprobaciones automatizadas separadas del código de la aplicación. Las pruebas son útiles incluso en proyectos pequeños: facilitan verificar el comportamiento esperado a medida que cambia el código. Un directorio docs puede contener instrucciones más extensas para usuarios o colaboradores cuando el README ya no sea suficiente.

Los proyectos web suelen tener un directorio templates para el HTML que renderiza la aplicación y un directorio static para recursos como archivos CSS, JavaScript e imágenes. Su ubicación exacta depende del framework y de su configuración. Una aplicación de línea de comandos que no sea web normalmente no necesita incluirlos.

Los modelos de base de datos van donde mejor encajen en la arquitectura elegida; el proyecto puede usar un módulo específico como models.py o un paquete para varios grupos de modelos. Un archivo como database.db solo corresponde cuando la aplicación usa realmente una base de datos local basada en archivos, por ejemplo, SQLite. No añadas un archivo de base de datos a la estructura del código fuente solo porque la aplicación almacene datos en otro lugar.

Ejemplo: una aplicación de blog pequeña

Este blog mantiene el código de cuentas y publicaciones en paquetes separados y coloca en la raíz los recursos exclusivos de la web y los archivos auxiliares del proyecto. El árbol es un punto de partida: las convenciones del framework pueden situar las plantillas, los modelos o los archivos estáticos en otros lugares. El archivo de base de datos corresponde a una configuración local con SQLite, y el entorno virtual local se deja fuera deliberadamente de la estructura del proyecto bajo control de versiones.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

layout = [
    "blog/",
    "├── README.md",
    "├── LICENSE",
    "├── pyproject.toml",
    "├── blog/",
    "│   ├── __init__.py",
    "│   ├── users/",
    "│   └── posts/",
    "├── templates/",
    "├── static/",
    "├── tests/",
    "└── database.db  (local SQLite only)",
]
print("\n".join(layout))
blog/
├── README.md
├── LICENSE
├── pyproject.toml
├── blog/
│   ├── __init__.py
│   ├── users/
│   └── posts/
├── templates/
├── static/
├── tests/
└── database.db  (local SQLite only)

El árbol no incluye la configuración de despliegue ni los detalles del framework, así que adáptalo a las herramientas que uses. Añade archivos como models.py dentro del paquete responsable de los datos, o amplía un paquete cuando crezca. En un proyecto de línea de comandos, omite las carpetas web; si usas un servicio de base de datos, omite el archivo de base de datos local. Mantén el mismo principio a medida que evolucione el proyecto: cada directorio debe ayudar a encontrar código o recursos relacionados. El bloque de salida conserva sus etiquetas originales en inglés; el texto de este apartado explica la estructura en español.