The directory structure for the project (in particular on Flask)

The article will answer the question that caused the loss of time of many programmers: which directory structure should be used for a future or existing project? What structure will be the most optimal not only for the current project germ, but in the future it will not be so painful in terms of project expansion or its division into parts?

Root


And so we took up the project. Let it be the easiest project myapp. Create a directory for it in the main development folder (I have this Devel).

mkdir myapp
cd myapp

In the future, all actions will be inside the main project directory.

Git


We initialize an empty repository

git init

.gitignore


# Игнорировать байткод
*.pyc
*.pyo
**/__pycache__/
# Игнорировать каталог с файлами настройки
**/config/
# Игнорировать каталог с данными и логами
**/data/
**/logs/
# Игнорировать каталог с исполнимыми файлами и модулями (если таковой имеется)
**/bin/

Read me


The next step is creating the required README file. This file contains the main and key description of our future project. Some make a text / plain file called README.txt. On large repositories portals adopted for the standard Markdown called README.md. I prefer html, because I prefer to make color selections, insert links, pictures and other multimedia, open in the browser, insert pieces of code in the tags <pre> and <code>, use ready-made frameworks like Bootstrap for decoration and other magic outside of Hogvards. Accordingly, the name README.html

touch README.html

If the project is conducted by several teams, I recommend that each team have its own README file within each independently developed module, component, library, etc.

application


The main application directory is called the same as the project directory. In the case of this article myapp

mkdir myapp
touch myapp/__init__.py

Modules and components


Inside the application directory, __init__.py is created by default, containing the code for initializing the application and connecting all the necessary parts to the application. In particular, these are Blueprints for single-threaded URLs or a namespace for the logic of a separate service, but with different URLs (a simple example would be to create a namespace for a service of blog articles, where there are clearly different paths like / pages and / page / ID)

mkdir myapp/bp_component
touch myapp/bp_component/__init__.py

or

mkdir myapp/ns_component
touch myapp/ns_component/__init__.py

DB Model


The database model contains the database initialization code, as well as the connection. And, of course, the structure of tables and relationships. It is also desirable to separate the tables into separate files based on the business logic of the application. Description of several classes of tables and links in one separate file is convenient because you can easily reuse the code by copying the desired file to another project or using symbolic links to the file from the common library for different projects.

mkdir myapp/models
touch myapp/models/__init__.py
touch myapp/models/page.py

Templates for template engine


For some applications (mostly web applications), it is typical to use patterns to generate leaf pages. Since the main goal is to separate the executable code from data presentation, this step will help the team to save a lot of time, effort and money, providing the possibility of parallel work of programmers and designers.

mkdir myapp/templates
mkdir myapp/templates/html
mkdir myapp/templates/js
mkdir myapp/templates/css

I note that in this case the js and css subdirectories are not used to store static JavaScript libraries or CSS styles, but for modifiable code, code with parameters, or code to be inserted. For example, if there is a calendar drawing component with the addition of additional functionality to the buttons, it will be much more convenient to put the calendar component in js, and in the html files to make the component turn on, but with the necessary parameters. Maybe it will seem to someone to govnokodom, but it is much better than creating a ready-made static calendar library, and in six months or a year to understand that you need to add a couple more three properties and methods to the component (for example, to make the datepicker not only in the form of one month, but and add the ability to turn into a calendar for the year), and no one will remember what magic was inside. Inserts will give more transparency.

Statics


Here are all the main never changing (or extremely rarely changing) styles, images, sounds, JS libraries and frameworks.

mkdir myapp/static
mkdir myapp/static/css
mkdir myapp/static/js
mkdir myapp/static/images

Function library


The convenience of connecting libraries depends mainly on the language and framework of the application. There are NOT libraries connected from repositories and supported by independent developers. Here are your own auxiliary functions. For example, I have some decorator functions when processing the route, but before calling the main function.

mkdir myapp/lib
touch myapp/lib/__init__.py

Settings and configuration


How to store the settings that determine the global parameters of the application? How many battles were on this score and not to count. No details like I do: I keep in the form of a Python module as a separate directory. Inside files for different startup modes.

mkdir config
echo"CONFIG = 'config.devel'" > config/__init__.py
touch config/devel.py
touch config/prod.py

Why py? Yes, because nobody gave up parsing XML, YAML, INI and other nonsense, when it is easy enough to create variables of the form:

import os
DEBUG = True
TITLE = 'SpecialistOff.NET'
DIR_BASE = '/'.join(os.path.dirname(os.path.abspath(__file__)).split('/')[:-1])
DIR_DATA = DIR_BASE + '/data'
DIR_FILES = DIR_DATA + '/files'
MIMETYPES = {
    'gif': 'image/gif',
    'jpg': 'image/jpeg',
    'jpeg': 'image/jpeg',
    'png': 'image/png',
    'txt': 'text/plain'
}
SERVERS = [
    {'name': 'server1', 'IP': '8.8.8.8', 'port': '80'}
]

Data


Files, logs and other data loaded during work are stored in a separate data directory

mkdir data
mkdir data/files

Testing


Test modules and fixtures

mkdir tests
mkdir tests/fixture
touch tests/__init__.py
touch test.py
chmod +x test.py

Documentation


All project documentation should be kept separate. I use the doc directory for this and store it as static web pages with the entry point index.html. This is convenient because I can share a separate documentation directory through any web server. Or browse directly from the directory with any web browser (including console-type lynx, elinks).

mkdir doc
touch doc/index.html

Deployment


It all depends on the tasks. And in the comments (in my humble opinion) is not particularly in need.

mkdir deploy
touch deploy/requirements.txt
touch deploy/build.sh
mkdir deploy/config
touch deploy/config/__init__.py
touch deploy/config/demo.py
mkdir deploy/cron
touch deploy/cron/myapp
mkdir deploy/docker
touch deploy/docker/Dockerfile
touch deploy/docker/docker-compose.yml
mkdir deploy/nginx
touch deploy/nginx/myapp.conf
mkdir deploy/uwsgi
touch deploy/uwsgi/conf.ini
mkdir deploy/uwsgi/conf.d
touch deploy/uwsgi/conf.d/myapp.conf

Logging


Here you can add logs during test runs or the conclusions of the application itself.

mkdir logs

Auxiliary scripts and utilities


mkdir utils
touch utils/useradd.py
chmod +x utils/useradd.py

Instead of conclusion


Basically, that's all. Why am I so laconic? Because the code will say for me better than myself. The rest of my comments can either confuse or spark controversy about which approach will be better / worse.

Also popular now: