Mastering Python Project Structures: A Comprehensive Reference

From Usahobs, the free encyclopedia of technology

Introduction

Every Python developer eventually faces the same question: Where should I put my code? A well-structured project layout not only saves time but also prevents the dreaded coder's block that arises when you are unsure about file organization. By understanding the standard patterns for different types of Python applications—from one-off scripts to full-scale web projects—you can focus on writing quality code instead of wrestling with directory decisions. This article provides a reliable reference for structuring your Python projects effectively.

Mastering Python Project Structures: A Comprehensive Reference
Source: realpython.com

Why Layout Matters

A consistent project layout offers several benefits:

  • Clarity: New team members (or your future self) can quickly locate modules, tests, and configuration files.
  • Maintainability: Separating concerns prevents messy, unmanageable codebases.
  • Reusability: Proper packaging enables easy sharing and installation via PyPI.
  • Scalability: A well-defined structure accommodates growth from a single script to a multi-module application.

Below, we explore the most common Python application layouts, each suited to different project sizes and goals.

One-Off Scripts

The simplest case is a single script intended for a specific task. Even here, a minimal structure helps:

my_script.py
README.md
requirements.txt (optional)

For scripts that are shared or run regularly, add a tests/ folder and a config.py for constants. Avoid dumping all logic into one giant file—break it into functions or classes within the same file for readability.

Installable Packages

When a project grows beyond a single script, consider packaging it for distribution. The standard layout follows the src layout:

my_project/
├── src/
│   └── my_package/
│       ├── __init__.py
│       ├── module_a.py
│       └── module_b.py
├── tests/
├── pyproject.toml
├── README.md
└── LICENSE

Key points:

  • Use pyproject.toml (or setup.cfg/setup.py) to define metadata and dependencies.
  • Place package code inside a src/ directory to avoid accidental imports before installation.
  • Include __init__.py files to mark directories as Python packages.

This layout is ideal for libraries that you intend to publish to PyPI or reuse across multiple projects.

Large Applications with Internal Packages

For complex applications (e.g., desktop apps, automation suites), you can nest packages within a main project folder. A common pattern:

my_app/
├── my_app/
│   ├── __init__.py
│   ├── main.py
│   ├── core/
│   │   ├── ...
│   └── utils/
│       └── ...
├── tests/
├── docs/
├── scripts/
├── requirements.txt
├── README.md
└── setup.py (or pyproject.toml)

This structure keeps everything self-contained while allowing sub-modules for different functionalities. Use internal packages (e.g., core/, utils/) to organize modules without exposing them as public APIs. Add a main.py entry point and include a scripts/ directory for helper utilities.

Mastering Python Project Structures: A Comprehensive Reference
Source: realpython.com

Web Projects with Django or Flask

Web frameworks often dictate their own layouts. However, you can still apply general principles.

Django Projects

Django generates a default project structure, but a refined version looks like:

my_site/
├── manage.py
├── my_site/
│   ├── settings/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── local.py
│   │   └── production.py
│   ├── urls.py
│   └── wsgi.py
├── apps/
│   ├── blog/
│   └── users/
├── templates/
├── static/
├── media/
├── requirements/
├── tests/
└── README.md

Keep settings split by environment, and place each Django app inside an apps/ directory for clarity. Use templates/ and static/ at the project root for shared assets.

Flask Projects

Flask offers more flexibility. A recommended layout is:

my_flask_app/
├── app.py (or run.py)
├── my_app/
│   ├── __init__.py
│   ├── routes.py
│   ├── models.py
│   └── templates/
│       └── base.html
├── config.py
├── requirements.txt
└── README.md

Put the application code inside a package (my_app/) and use a factory function in __init__.py. Keep configuration separate in config.py. For larger apps, add sub-packages like api/, admin/, or views/.

Conclusion

Choosing the right project layout depends on your application's complexity and goals. Start simple with one-off scripts, then graduate to installable packages as you need reusability. For sizable applications, internal packages keep your code organized. Finally, follow framework conventions for Django or Flask while adapting them to your project's scale. Remember, a dependable starting layout frees you to focus on what truly matters: writing great Python code.