Как стать автором
Поиск
Написать публикацию
Обновить

Структура каталогов для проекта (в частности на Flask)

Время на прочтение5 мин
Количество просмотров22K
Статья ответит на вопрос, который стал причиной потери времени многих программистов: какую структуру каталогов необходимо использовать для будущего или существующего проекта? Какая структура будет наиболее оптимальной не только для текущего зачатка проекта, но и в будущем будет не такой болезненной в плане расширения проекта или его разделения на части?

Корень


И так мы взялись за проект. Пусть это будет самый простой проект myapp. Создаём для него каталог в основной папке для разработки (у меня это Devel).

mkdir myapp
cd myapp

В дальнейшем все действия будут внутри каталога основного проекта

Git


Инициализируем пустой репозиторий

git init

.gitignore


# Игнорировать байткод
*.pyc
*.pyo

**/__pycache__/

# Игнорировать каталог с файлами настройки
**/config/

# Игнорировать каталог с данными и логами
**/data/
**/logs/

# Игнорировать каталог с исполнимыми файлами и модулями (если таковой имеется)
**/bin/

Прочти меня


Следующим шагом идёт создание обязательного файла README. В этом файле хранится основное и ключевое описание нашего будущего проекта. Некоторые делают файл в виде text/plain с названием README.txt. На крупных порталах репозитариях принят за стандарт Markdown с названием README.md. Я же предпочитаю html, т.к. мне удобнее делать цветовые выделения, вставлять ссылки, картинки и другие мультимедиа, открывать в браузере, вставлять куски кода в тегах <pre> и <code>, использовать готовые фреймворки типа Bootstrap для оформления и другой магии вне Хогвардса. Соответственно и название README.html

touch README.html

Если проект ведётся несколькими командами, то рекомендую каждой команде иметь свой README файл внутри каждого разрабатываемого независимо модуля, компонента, библиотеки и т.д.

Приложение


Основной каталог приложения называю так же, как и каталог проекта. В случае этой статьи myapp

mkdir myapp
touch myapp/__init__.py

Модули и компоненты


Внутри каталога приложения стандартно создаются __init__.py, содержащий код инициализации приложения и подключения всех необходимых частей к приложению. В частности это Blueprints для одноветочных URL или namespace для логики отдельного сервиса, но с разными URL (простым примером может служить создание namespace для сервиса статей блога, где явно имеются разные пути вида /pages и /page/ID)

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

или

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

Модель БД


Модель базы данных содержит код инициализации базы данных, а также подключения. И, обязательно, структуру таблиц и связей. Так же желательно выделять таблицы в отдельные файлы на основе бизнес-логики приложения. Описание нескольких классов таблиц и связей в один отдельный файл удобно тем, что можно достаточно легко повторно использовать код, скопировав нужный файл в другой проект или использовать символьные ссылки на файл из общей библиотеки для разных проектов.

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

Шаблоны для шаблонизатора


Для некоторых приложений (в основном веб-приложений) характерно использование шаблонов для генерации конечных страниц. Так как основной целью является отделение исполняемого кода от представления данных, то данный шаг поможет в работе команды сэкономить много времени, сил и денег, обеспечив возможность параллельной работы программистов и дизайнеров.

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

Замечу, что в данном случае подкаталог js и css служат не для хранения статических библиотек JavaScript или стилей CSS, а именно для изменяемого кода, кода с параметрами или кода для вставки. Например если имеется компонент прорисовки календаря с подключением допфункционала к кнопкам, то будет гораздо удобнее в js положить компонент календаря, а в html файлах делать включения компонента, но с нужными параметрами. Возможно это покажется кому-то говнокодом, но это гораздо лучше, чем создать готовую статическую библиотеку календаря, а через полгода-год понять, что требуется добавить ещё пару тройку свойств и методов к компоненту (например сделать datepicker не только в виде одного месяца, но и добавить возможность превратить в календарь на год), а какая магия была внутри никто и не вспомнит. Вставки дадут больше прозрачности.

Статика


Здесь все основные никогда не меняющиеся (или меняющиеся крайне редко) стили, картинки, звуки, JS библиотеки и фреймворки.

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

Библиотека функций


Удобство подключения библиотек зависит в основном от языка и фреймворка в основе приложения. Здесь НЕ лежат библиотеки, подключаемые из репозитариев и поддерживаемые независимыми разработчиками. Здесь лежат ваши собственные вспомогательные функции. Например у меня лежат некоторые функции-декораторы, при обработке маршрута, но до вызова основной функции.

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

Настройки и конфигурирование


Как хранить настройки, определяющие глобальные параметры приложения? Сколько на этот счет было баталий и не счесть. Без деталей как делаю я: храню в виде Python модуля отдельным каталогом. Внутри файлы для разных режимов запуска.

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

Почему py? Да потому, что никому не сдался парсинг XML, YAML, INI и другой чепухи, когда под рукой достаточно легко создавать переменные вида:

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

mkdir data
mkdir data/files

Тестирование


Тестовые модули и фикстуры

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

Документация


Вся документация по проекту должна храниться отдельно. Я использую для этого каталог doc и храню как статические веб-страницы с входной точкой index.html. Это удобно тем, что я могу расшарить отдельный каталог документации через любой веб-сервер. Или просмотреть прямо из каталога любым веб-браузером (в том числе и консольными типа lynx, elinks).

mkdir doc
touch doc/index.html

Развертывание


Здесь всё зависит от задач. И в комментариях (по моему скромному мнению) не особенно нуждается.

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

Логирование


Сюда можно складывать логи при тестовых запусках или выводы самого приложения.

mkdir logs

Вспомогательные скрипты и утилиты


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

Вместо заключения


В принципе, это все. Почему я так немногословен? Потому что код скажет за меня лучше, чем я сам. Остальные мои комментарии могут либо запутать, либо разжечь споры о том, какой подход будет лучше/хуже.
Теги:
Хабы:
Всего голосов 9: ↑6 и ↓3+3
Комментарии5

Публикации

Ближайшие события