Программа для создания файлов конфигурации. Часто встречается нужда держать конфигурационные файлы в порядке, и консистенции, распределять общие данные по разным типам файлам, у некоторых типов файлов нет возможности читать переменные окружения, или приходиться подстраиваться под каждый формат по отдельности. Для того чтобы не подстраиваться под каждый формат файла, можно использовать всю мощь python и держать все конфигурации в одном файле.

Ссылка на проект

Дисклеймер

Дисклеймер
  1. Этот проект является прототипом, я не заставляю вас использовать эту программу для решения своих задач, в большой степени мне хочется узнать мнение общественности о необходимости решения таких задач, и если будет поддержка идеи то уже тогда можно задуматься о создании надежной и конкурентной программы.

  2. Если вас не заинтересовала данная статья, и вам не хотите использовать данные решения, то поставьте дизлайк по причине "В статье нет новой для меня информации" а не по какой-нибудь другой причине.

  3. Если вы решили поставить дизлайк по причине "Низкий технический уровень материала", то просьба аргументировать в комментариях в чем он низкий. Если вы не разбирались в исходном коде программы, и вам просто неопрятен моя манера письма, то поставьте дизлайк по причине "Личная неприязнь к автору или компании", не нужно вводить в заблуждение и панику других пользователей ссылать на неаргументированный низкий технический уровень.

  4. Осуждение того что документация и комментарии в исходном коде написаны на родном для меня Русском языке, а не на Английском. Является проявлением русофобии, и в как-то мери национализмом. Каждый в равно степени может писать и документировать на любом удобном для себя языке. Если вы действительно хотите помочь в мультиязычности проекта, то я(мы) готов(ы) к сотрудничеству.

  5. У меня нет гарантий что этот проект будет поддерживаться. Если он мне не понравиться, и не будет поддержки со стороны общественности, то проекту суждено "кануть в лету". Вы, наверное, удивитесь, но так поступают со многими стартапами по всему миру которые не оправдывают ожидания. Так что вспомните об этом, когда захотите упомянуть, что "этот проект не надежен", что "нет гарантий поддержки этого проекта в длительной перспективе", что "лучше писать костыли к проверенным технологиям чем довериться этой авантюрной идеи". Забвение может произойти с любым сатрапам, но по крайне меры ни кто не вкладывал денег в этот проект.

  6. Если вы знаете аналоги для решения этих задач, то буду рад увидеть их в комментариях.

Использование

- Скомпилировать конфигурационные файлы

configer parseconf $ПутьКонфигурациям$.py

- Сделать копию и скрыть данные

configer hideconf $ПутьКонфигурациям$.py

Создание файла конфигураций

Для того чтобы указать какие переменные нужно рассматривать в качестве конфигураций, их нужно поместить в переменную export_var, переменная с конфигурациями должна соответствовать правилам, это должен быть картеж со следующим порядком значений:

  1. Название файла (`str`)

  2. Путь куда поместить файл (`str`)

  3. Шаблон (`str`)

    1. Значения которые нужно взять из словаря заключите в $$(Ключ)$$

  4. Словарь для замены слов dict[str,str]

Эти значения подставится в классConfFile(*args)

port = 8080

env = ("__env.env", "./test", """
## Django
# Ключ для расшифровки сессии
DJANGO_SECRET_KEY="$$(secret_key)$$"
# Имя проекта
NAME_PROJ="$$(project_name)$$"
# Режим работы (true/false)
DEBUG=true

### Docker
# Путь к рабочей директории
WORK_DIR="/usr/src/$$(project_name)$$"
# Путь к переемным окружениям
PATH_ENV="./__env.env"
NGINX_PORT=$$(port)$$

"""[1:], {
    "secret_key": "dq232dc3f34f32q4fwe3",
    "project_name": "МойПроект",
    "port": port,
})
export_var = [
    env
]

Выполним команду

configer parseconf conf.py

В итоге мы получим файл, расположенный в ./test/__env.env. Содержание

## Django
# Ключ для расшифровки сессии
DJANGO_SECRET_KEY="dq232dc3f34f32q4fwe3"
# Имя проекта
NAME_PROJ="МойПроект"
# Режим работы (true/false)
DEBUG=true

### Docker
# Путь к рабочей директории
WORK_DIR="/usr/src/МойПроект"
# Путь к переемным окружениям
PATH_ENV="./__env.env"
NGINX_PORT=8080

Логи

[INFO][TEMPLATE]:'__env.env'
[INFO][FIND]:['secret_key', 'project_name', 'project_name', 'port']
[INFO][FILE_WRITE]:'/home/ПолныйПуть/test/__env.env'
[INFO][VAR_CREATE]:'__env.env'

Сделать копию и скрыть данные

Почти всегда нам нужно иметь в проекте секретные(приватные) данные, которые не должны стать публичными. У нас есть возможность создавать копию конфигурации со скрытыми данными. Для того чтобы указать переменную у которой нужно скрыть значения, напишите в начел её имени _hide_

Пример, нам нужно скрыть данные url для подключения к БД, ключ для шифрования сессии, данные для входа в админ панель, ну или любые другие данные. Для того чтобы сделать копию этой конфигурации, например, для того чтобы сохранить всю логики, но при этом скрыть выше указанные данные, мы указываем в начале имени _hide_, в итоге мы получим файл conf_pub.py который можно спокойно хранить в открытом доступе, например в GitHab.

_hide_SQL_URL: str = "postgresql+asyncpg://postgres:root@localhost/fast"
_hide_SESSION_SECRET_KEY = "qQWEdqwdwqefASDQF4qw4h3ofv3vw3oervwg532gg5"
_hide_ADMIN_PANEL: tuple[str, str, str] = ("user", "password", "emal")

host = "0.0.0.0"
port = 8080

env = ("__env.env", "./test", """
SQL_URL = $$(sql_url)$$
SESSION_SECRET_KEY = $$(session_secret_kry)$$
ADMIN_PANEL = $$(admin_panel)$$
"""[1:], {
    "sql_url": _hide_SQL_URL,
    "session_secret_kry": _hide_SESSION_SECRET_KEY,
    "port": port,
})
export_var = [
    env
]

Выполним команду

configer hideconf conf.py

В итоге мы получим копию, расположенную в ./conf_pub.py. Содержание

_hide_ADMIN_PANEL: tuple[str, str, str] = ___
_hide_SESSION_SECRET_KEY = ___
_hide_SQL_URL: str = ___

host = "0.0.0.0"
port = 8080

env = ("__env.env", "./test", """
SQL_URL = $$(sql_url)$$
SESSION_SECRET_KEY = $$(session_secret_kry)$$
ADMIN_PANEL = $$(admin_panel)$$
"""[1:], {
    "sql_url": _hide_SQL_URL,
    "session_secret_kry": _hide_SESSION_SECRET_KEY,
    "port": port,
})
export_var = [
    env
]

Логи

[INFO][VAR_HIDE]:'_hide_ADMIN_PANEL: tuple[str, str, str]'
[INFO][VAR_HIDE]:'_hide_SESSION_SECRET_KEY'
[INFO][VAR_HIDE]:'_hide_SQL_URL: str '

Не перезаписывать файл если он уже существует

Допустим у нас есть ситуация когда нужно создать шаблонный файл, по указанному пути. Но нам не нужно его постоянно перезаписывать при вызове parseconf. Например, нам нужно чтобы был создан файл README.md для проекта, и pyproject.tom для зависимостей проекта. README.md файл может часто вами изменятся и расширятся, pyproject.toml файл тоже может часто изменятся например вы обновили версии зависимостей. Писать весь текст файлами в conf.py неудобно поэтому мы хотим чтобы он был создан единожды и больше не перезаписывался для этого мы передаем последним аргументом "norewrite"

name_proj = "ИмяПроекта"
version = "0.0.1"
auth = "Иван Иванов <ivan-ivan@mail.com>"
description = "Любое описание"

pyproject_toml = ("pyproject.toml", "./", """
[tool.poetry]
name = "$$(name_proj)$$"
version = "$$(version)$$"
description = "$$(description)$$"
repository = "https://github.com/denisxab/$$(name_proj)$$.git"
documentation = "https://$$(name_proj)$$.readthedocs.io/ru/latest/index.html"
authors = ["$$(auth)$$"]
readme = "README.md"
exclude = [
    "$$(name_proj)$$/.idea",
    "$$(name_proj)$$/venv",
    "$$(name_proj)$$/.git",
    "$$(name_proj)$$/.gitignore",
    "$$(name_proj)$$/test",
    "$$(name_proj)$$/Makefile"
]

[tool.poetry.dependencies]
python = "^3.10"


[tool.poetry.dev-dependencies]
pytest = "^7.0.0"
Nuitka = "^0.6.19"
Sphinx = "^4.4.0"
sphinx-autobuild = "^2021.3.14"
sphinx-rtd-theme = "^1.0.0"
m2r2 = "^0.3.2"


[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

"""[1:], {
    "name_proj": name_proj,
    "version": version,
    "auth": auth,
    "description": description,
}, "norewrite")

readme_md = ("README.md", "./", """
## О чем

## Как установить


## Использование


## Примеры

"""[1:], {}, "norewrite")

export_var = [
    pyproject_toml,
    readme_md,
]

Комментарии (15)


  1. DoGraf
    02.03.2022 16:47
    +2

    Кто-то опять изобрел Ansible))


    1. denisxab Автор
      02.03.2022 16:57
      -1

      Я не видел такой возможности в Ansible скинь ссылку на пример как это возможно там сделать ?


  1. fralik
    02.03.2022 16:57
    +1

    Еще можно на вот это глянуть: https://pydantic-docs.helpmanual.io/usage/settings/


    1. denisxab Автор
      02.03.2022 17:23
      -4

      У него вроде только json поддерживаться, а у меня задача под любой формат подстроиться, у меня это достигается путем простой шаблонизации текста. (если не так то поправь)


      1. fralik
        03.03.2022 03:00
        +1

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

        pydantic про настройки. Он дает возможность добавлять конфигурацию к программам на питоне. Конфигурация задается как класс, каждое свойство - отдельный параметр конфигурации. Pydantic использует аннотации типов, чтобы контролировать значения; поддерживает чтение из .env файлов и переменных окружения. Не надо ничего дополнительно "компилировать". Общие настройки можно реализовать либо через наследование, либо композицию.


  1. ovalsky
    02.03.2022 16:59

    а какие плюсы/минусы относительно dynaconf?


    1. denisxab Автор
      02.03.2022 17:18
      -2

      dynaconf я не использовал, вот только сейчас 5 минут прочитал документацию и нашел следующий отличия

      1. Поддерживать только toml|yaml|json|ini|py

      У него как-то сложная документация, задача то простая, я хочу просто создавать файл и брать значения для них из python а в dynaconf у него 20 заголовков по 6 под глав(в среднем) в каждой, в которых я за 5 минут не разобрался. Личное мнения, но я бы не захотел им пользоваться, излишняя сложность.


  1. baldr
    02.03.2022 17:37
    +6

    Денис, я честно читал все ваши предыдущие статьи и у меня только такие выводы - вы пишете велосипеды, не любите читать (и писать) документацию, писать тесты и вообще следовать стандартам. А еще не любите прислушиваться к чужому мнению. Впрочем, это никто не любит.

    У него как-то сложная документация

    Я не хочу разбираться в очередной переоценённой технологии, которая не даёт гибкости в действиях.

    Ну, понятно, снова "фатальный недостаток".

    Снова - cookiecutter решает проблемы по шаблонизации проекта.

    Поверьте - хуже нет чем новому разработчику, придя в проект, разбираться в велосипедах, которые понаписали до него, игнорируя уже готовые и известные подходы (логирование, конфиги, деплой).


    1. denisxab Автор
      02.03.2022 20:08
      -4

      Я не нашёл примера у программcookiecutter / dynaconf

      где они показывают аналогичный функционал. Может быть если я потрачу на изучения несколько дней то я найду вариант который может просто использовать python файлы как инструмент создания конфигураций, а может не найду, тогда мне придётся подстраиваться под их правила, шерстить всю документация вверх и вниз, искать ответы на форумах. Но зачем это все делать если задача банальная, эту программу можно написать за вечер и она будет решать свою задачу. Это не Docker или веб фреймворк или СУБД, чтобы подстраиваться под их правила, даже если они тебе не нравятся.

      Писать велосипед к простым и важным технологиям это хорошо, потому то они решают конкретные задачи, без излишеств. Вы можете потратить недели разработки, а потом узнать что нужно фичи нет сторонней технологии, и что вы будете, разбираться в тысячах строчек чужого кода для создания форка и добавления фичи, и постоянно быть на чеку чтобы этот форк был актуален. Может это выход для сложных технологий, но не для простых технологий.


      1. ovalsky
        02.03.2022 21:56
        +2

        так можно и свой язык написать, что бы избежать чтения документации)


        1. denisxab Автор
          03.03.2022 13:04
          -1

          Так и создали C# / Golang. Наверное, все разработчики языков программирования не хотели читать документацию Асембера вот и навыдумывали велосипеды из других языков. Да ?


  1. fralik
    03.03.2022 03:06

    Ещё насчёт вашей просьбы о том, какие именно ставить минусы. Насколько я знаю, типы минусов видны только автору. Поэтому невозможно ввести в заблуждение аудиторию, ставя минус по поводу низкого технического содержания.


  1. unsignedchar
    03.03.2022 09:49
    +2

    Ошипке в заголовке надо бы избежать.


  1. denisxab Автор
    03.03.2022 15:25
    -1

    В общем меня ограничили доступ к публикациям на Habr. Поэтому я ухожу с этой платформы. Спасибо, что в меня не верили и дизайкали без причинны, теперь у меня есть аргумент почему в нашей стране нет Open Sourse и почему все прогибаются под запад. Потому что российское комьюнити само себя сжирает, и не дает шансов новым идеям. (Это не все, но как видно большинство)


  1. amarao
    03.03.2022 22:34
    +1

    Это лучшее решение из доступных в России, особенно после того, как hashicorp решил, что война - это плохо.

    Весь остальной мир пользуется системами управления конфигурациями и системами управления секретами.