Back to Posts
Software developer planning a whiteboard structure for a Python project, with notes including 'docs' and 'video module,' showcasing strategies from a comprehensive guide to structuring Python projects for maintainability and growth.

Efficient Python Project Setup for Long-Term Growth

By Andreas Bergman

When it comes to software development, the choices we make in the beginning can really impact how our projects turn out. One important choice is how we structure our project. Today I’m going to show you how I structure my projects to make the most of Poetry, and how to structure your projects in preparation for publishing.

The anatomy of a well-structured project

A fairly typical way to structure your project is as follows:

my_project/

├── src/                     # Main package source directory
│   ├── sub_modules/
│   │   ├── __init__.py      # Initializes the sub module
│   │   └── nested_module.py # another nested module
│   └── module.py            # Your module(s)

├── tests/                   # Test directory
│   ├── __init__.py          # Initialize the test package
│   └── test_module.py       # Test cases for your modules

├── docs/
│   ├── README.md            # Project description and instructions
|   └── WIKI.MD              # Project documentation
|
├── .gitignore               # Specifies intentionally untracked files to ignore
├── pyproject.toml           # Project specification, including dependencies
└── LICENSE.MD               # License information

The src/ directory

The src directory is often used by convention to contain all of your modules and submodules, as well as the entry point to your application.

By separating our code into into its own directory, we get the following benefits:

  • Isolation: It ensures that your source code is neatly separated from other project elements, such as tests and documentation. This separation is crucial for avoiding the accidental inclusion of non-essential files in your package’s distribution.
  • Simplicity: By clearly separating your package’s internal code in the src directory, it makes importing statements in your tests and scripts easier, which helps make the development process run more smoothly.
  • Flexibility: It allows for easier refactoring of your project’s internal structure without impacting external users, providing a foundation for scalable and maintainable code.

The tests/ directory

Testing is a vital component of software development to ensure that code functions as intended. It’s advisable to store tests in a designated folder, such as the tests folder. Testing suites can be set up to execute tests from this designated folder, which can help automate the testing process.

  • Organization: Keeping tests separate from the source code maintains your project’s cleanliness and organization.
  • Efficiency: By excluding tests from your package’s distribution, you reduce its size, thereby accelerating the installation process for end users.
  • Integration: A separate tests directory seamlessly integrates with continuous integration (CI) systems, facilitating running automated testing in isolated environments.

The docs/ directory

The README.md file is often the first point of contact between your project and potential users or contributors. It serves as an essential guide, detailing your project’s purpose, setup instructions, and usage examples. A well-crafted README enhances accessibility, clarity, and engagement with your project’s audience.

A good readme generally includes:

  • Short description: It’s good to give a clear, concise idea of the purpose and goals of your application.
  • Installation instructions: Does your application have external dependencies that are not provided on PyPI? Do you have optional dependencies? Let the user know.
  • Overview of features: What are your application capabilities? Does it have compatibility or interoperability with other libraries?
    • Example usage: Show the user how your application works in practice. Depending on the size and complexity of your application, you may wish to provide only basic examples, and link to a wiki.

Include a .gitignore file

The .gitignore file plays a crucial role in maintaining the integrity of your Git repository. It specifies which files and directories should be ignored, preventing the accidental inclusion of sensitive information or unnecessary files in your repository. It’s highly unlikely that you will need to include IDE configurations, venvs, and other files specific to your particular environment, and as such, you should also add these to your .gitignore file.

Understanding pyproject.toml

The pyproject.toml file is a standard for defining Python project metadata and dependencies. It allows us to define many aspects of our application configuration, from build systems, such as Poetry, to our dependencies and other metadata.

  • Standardization: The pyproject.toml file is recommended by PEP and is widely used as an industry standard.
  • Ease of use: Simplifies the setup process for developers, fostering a more accessible and user-friendly development environment.
  • Compatibility: Ensures compatibility with the broader Python packaging ecosystem, streamlining package creation and dependency management.
  • Configurability: Enables the definition of dependencies, including those for development and optional use.

Why include a LICENSE file?

For open-source projects, the LICENSE file is non-negotiable. It outlines how others can use, modify, and distribute your project, providing legal protection and defining the scope of permitted use. A clear license supports the open-source community by encouraging participation and contribution under defined terms. When one isn’t included, it’s generally presumed that the project has an all rights reserved license, but I would recommend including one to avoid any ambiguity.

Note, it’s best practice to use an existing licence like MIT or GPL instead of writing your own, as they have been thoroughly reviewed by the open source community.

Improve your code with my 3-part code diagnosis framework

Watch my free 30 minutes code diagnosis workshop on how to quickly detect problems in your code and review your code more effectively.

When you sign up, you'll get an email from me regularly with additional free content. You can unsubscribe at any time.

Recent posts