Despite being picky about syntax and style, Python offers unexpected structural flexibility in your programs.
Its adaptability has its benefits; for example, it enables specialized structures to be used for specific applications. Nonetheless, it might be highly overwhelming for a beginner programmer.
As for online resources, there are about as many viewpoints as there are Python blogs. In this post, I want to provide you with a reliable reference guide for the structure of your Python applications that will cover the great majority of your needs.
You will see several web application layouts using popular frameworks like Flask and Django, as well as command-line applications (CLI apps), standalone scripts, and installable packages. Please be aware that reading this reference book requires an existing familiarity with Python packages and modules. If you need a refresher on Python modules and packages, have a look at our introduction if you want to learn more.
Command-Line Application Layouts
Many of us rely heavily on CLI-based Python programs in our daily work. Having to deal with the blank slate that is Python application layouts is a common practice here.
Having to start with a blank project folder might be nerve-wracking and cause a serious case of writer’s block. In this part, I will discuss several tried-and-true structures that I use as templates for all of my Python CLI programs.
We’ll begin with the simplest possible layout for the simplest possible use case: a self-contained script. The layout’s development with the use cases will be shown.
You simply throw up a.py script and you’re good to go, right? You may just execute the script from its directory; no installation is required.
This is good if you’re simply developing a script for yourself or one with no other dependencies, but what if you need to share it with others? More so to the layperson than the techie?
The following structure is adaptable to any of these scenarios and may be altered to suit your own installation and additional tools. This structure will serve you well whether you’re writing a “pure” Python script (one with no dependencies) or a script that will use a tool like pip or Pipenv.
When you read this guidance, bear in mind that the rationale behind the file locations is more important than their precise coordinates. Anything related to your project should live in a folder with the same name. The sample project’s name and starting point will be called helloworld.
Have a look at how I normally organize a Python project for a command-line interface.
helloworld/ │ ├── .gitignore ├── helloworld.py ├── LICENSE ├── README.md ├── requirements.txt ├── setup.py └── tests.py
Everything you need is in the same folder, so this is an easy task. While the files shown here are not comprehensive, I do advise reducing the amount of files to a minimal if you want to use a simple layout such as this. You may not be familiar with all of these file types, so let’s quickly go through what they all do.
: This is a file that tells Git which kinds of files to ignore, like IDE clutter or local configuration files.
Our Git tutorial has all the details
, and you can find sample
files for Python projects
: This is the script that you’re distributing. As far as naming the main script file goes, I recommend that you go with the name of your project (which is the same as the name of the top-level directory).
: This plaintext file describes the license you’re using for a project. It’s always a good idea to have one if you’re distributing code. The filename is in all caps by convention.
Need help selecting a license for your project? Check out
: This is a
) file documenting the purpose and usage of your application. Crafting a good
is an art, but you can find a shortcut to mastery
: This file defines outside Python dependencies and their versions for your application.
: This file can also be used to define dependencies, but it really shines for other work that needs to be done during installation. You can read more about both
guide to Pipenv
: This script houses your tests, if you have any.
You should have some
Should you retain all the parts of your expanding program in the root directory now that you’ve split it up into several parts inside the same package? Your application’s complexity has increased, therefore you should start being more organized.
Installable Single Package
Let’s pretend helloworld.py is still the primary script to run, but you’ve separated out all of the auxiliary functions into a separate file named helpers.py.
All the ancillary files, including your README and.gitignore, will remain in the root directory while we package the helloworld Python scripts together.
Check out the new and improved
helloworld/ │ ├── helloworld/ │ ├── __init__.py │ ├── helloworld.py │ └── helpers.py │ ├── tests/ │ ├── helloworld_tests.py │ └── helpers_tests.py │ ├── .gitignore ├── LICENSE ├── README.md ├── requirements.txt └── setup.py
All of your application’s code still resides in the package-specific helloworld directory, with the addition of a new file entitled __init .py. Please meet these brand-new
: This file has many functions, but for our purposes it tells the Python interpreter that this directory is a package directory. You can set up this
file in a way that enables you to import classes and methods from the package as a whole, instead of knowing the internal module structure and importing from
For a deeper discussion on internal packages and
our Python modules and packages overview
has you covered.
: As mentioned above, we’ve moved much of
’s business logic to this file. Thanks to
, outside modules will be able to access these helpers simply by importing from the
: We’ve moved our tests into their own directory, a pattern you’ll continue to see as our program structures gain complexity. We have also split our tests into separate modules, mirroring our package’s structure.
This structure is an abbreviated version of Kenneth Reitz’s samplemod app format. For more involved CLI apps, it’s a terrific place to begin.
Application with Internal Packages
When packaging a bigger application, you may need to create one or more internal packages that either interact with or are used by the main runner script. The aforementioned norms will be modified to include
helloworld/ │ ├── bin/ │ ├── docs/ │ ├── hello.md │ └── world.md │ ├── helloworld/ │ ├── __init__.py │ ├── runner.py │ ├── hello/ │ │ ├── __init__.py │ │ ├── hello.py │ │ └── helpers.py │ │ │ └── world/ │ ├── __init__.py │ ├── helpers.py │ └── world.py │ ├── data/ │ ├── input.csv │ └── output.xlsx │ ├── tests/ │ ├── hello │ │ ├── helpers_tests.py │ │ └── hello_tests.py │ │ │ └── world/ │ ├── helpers_tests.py │ └── world_tests.py │ ├── .gitignore ├── LICENSE └── README.md
There’s more to take in, but if you keep in mind that what comes next naturally flows from what came before, it shouldn’t be too difficult to understand. I’ll go over each upgrade and alteration, when you may want to utilize it, and why.
: This directory holds any executable files. I’ve adapted this from
Jean-Paul Calderone’s classic structure post
, and his prescriptions for the use of a
directory are still important. The most important point to remember is that your executable shouldn’t have a lot of code, just an import and a call to a
in your runner script. If you are using pure Python or don’t have any executable files, you can leave out this directory.
: With a more advanced application, you’ll want to maintain good documentation of all its parts. I like to put any documentation for internal modules here, which is why you see separate documents for the
packages. If you use
in your internal modules (and you should!), your whole-module documentation should at the very least give a holistic view of the purpose and function of the module.
: This is similar to
in the previous structure, but now there are subdirectories. As you add more complexity, you’ll want to use a “divide and conquer” tactic and split out parts of your application logic into more manageable chunks. Remember that the directory name refers to the overall package name, and so the subdirectory names (
) should reflect their package names.
: Having this directory is helpful for testing. It’s a central location for any files that your application will ingest or produce. Depending on how you deploy your application, you can keep “production-level” inputs and outputs pointed to this directory, or only use it for internal testing.
: Here, you can put all your tests—unit tests, execution tests, integration tests, and so on. Feel free to structure this directory in the most convenient way for your testing strategies, import strategies, and more. For a refresher on testing command-line applications with Python, check out my article
4 Techniques for Testing Python Command-Line (CLI) Apps
The root folder structure is almost unchanged as before. Depending on the GUI framework you’re using, you may need to make minor adjustments, but these three layouts should cover most use cases for command-line apps. Remember that these are simply sketches and not the final product. If you aren’t sharing tests along with your code, for example, there’s no need to include the tests/ directory. But, make sure docs/ isn’t forgotten. Maintaining a record of your
Web Application Layouts
Web applications are another important area where Python is used. Django and Flask are two of the most popular Python web frameworks, and they are both notably more opinionated than other frameworks when it comes to the design of online applications.
To ensure this piece serves as a comprehensive layout reference, I felt it necessary to draw attention to the structure shared by these
Django will be our first stop as we go through the alphabet. When you run django-admin startproject project, where project is the name of your project, Django will automatically provide a basic framework for your project. After you do this, a new folder named project will be created in your current working directory with the following internal
project/ │ ├── project/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py
Do you feel that something is missing from this? What happened to all the common sense? The sights? There are no examinations whatsoever.
A project is the glue that holds Django’s other core idea, applications, together. A blog is an application since it has logic, models, views, and so on that are used to do some purpose.
Django applications are organized like specialized Python packages, allowing them to be imported into projects and reused in other contexts.
Django, much like projects, simplifies the process of creating Django app layouts. Just type python manage.py startapp app where app is the name of your app once you have finished setting up your project.
The output will be a folder named app containing the following
app/ │ ├── migrations/ │ └── __init__.py │ ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── tests.py └── views.py
You may then include this immediately into your work. For more details on the purpose of these files, how to leverage them for your project, and so on, check out our Django tutorial or the official Django documentation.
You just need this minimal file and folder structure to get started with Django. The layouts of the command-line applications may and should be adapted for any open-source Django project. This is usually what I get for the outside of a job.
project/ │ ├── app/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ │ │ ├── migrations/ │ │ └── __init__.py │ │ │ ├── models.py │ ├── tests.py │ └── views.py │ ├── docs/ │ ├── project/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ ├── static/ │ └── style.css │ ├── templates/ │ └── base.html │ ├── .gitignore ├── manage.py ├── LICENSE └── README.md
Check out this Stack Overflow thread for a more in-depth examination of more complex Django application layouts. Several of the folders mentioned in the Stack Overflow post have descriptions in the django-project-skeleton project documentation. Two Scoops of Django is a deep dive into Django that will teach you the most up-to-date best practices for developing with Django.
You may find more Django tutorials in our Real Python Django area.
One of the key selling points of Flask, a Python web “microframework,” is how quickly you can get it up and running with how little overhead it has. A web application sample consisting of less than ten lines of code and a single script is provided in the Flask documentation. But, you probably won’t be coding a web app this minimal in reality.
Fortunately, the Flask documentation comes to the rescue with a recommended structure for their instructional project (a blogging web application named Flaskr), which we shall analyze here as a subproject.
flaskr/ │ ├── flaskr/ │ ├── ___init__.py │ ├── db.py │ ├── schema.sql │ ├── auth.py │ ├── blog.py │ ├── templates/ │ │ ├── base.html │ │ ├── auth/ │ │ │ ├── login.html │ │ │ └── register.html │ │ │ │ │ └── blog/ │ │ ├── create.html │ │ ├── index.html │ │ └── update.html │ │ │ └── static/ │ └── style.css │ ├── tests/ │ ├── conftest.py │ ├── data.sql │ ├── test_factory.py │ ├── test_db.py │ ├── test_auth.py │ └── test_blog.py │ ├── venv/ │ ├── .gitignore ├── setup.py └── MANIFEST.in
Flask applications, like other Python programs, rely on preexisting Python libraries, as shown here. Take note: Don’t get it. Finding packages is easy if you know to search for a file named __init .py. This file should be placed in the package’s root directory. As you can see in the diagram above, flaskr is a bundle that includes the database, auth, and blog components.
The flaskr package contains everything except the tests, the virtual environments directory, and the typical top-level files. Your tests will generally correspond to the flaskr package’s separate modules, as is the case with other layouts. If you compare this to the Django layouts, you’ll see that your templates are included in the main project package as well.
Visit our Flask Boilerplate Github page to see the boilerplate in action and to see an example of a more fully developed Flask application.
If you want to learn more about Flask, have a look at our comprehensive Flask guides.