compose-generator 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- compose_generator-0.1.0/PKG-INFO +58 -0
- compose_generator-0.1.0/README.md +42 -0
- compose_generator-0.1.0/compose_generator/__init__.py +81 -0
- compose_generator-0.1.0/compose_generator/example.env +16 -0
- compose_generator-0.1.0/compose_generator/example.py +101 -0
- compose_generator-0.1.0/pyproject.toml +16 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: compose-generator
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Проект представляет собой генератор docker-compose.yml файла на основе настроек приложения
|
|
5
|
+
Author: pasha_danilevich
|
|
6
|
+
Author-email: danilevitch.pasha@yandex.ru
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Dist: pydantic-settings (>=2.11.0,<3.0.0)
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
Этот проект представляет собой **генератор docker-compose.yml файла** на основе настроек приложения. Вот подробное описание:
|
|
18
|
+
|
|
19
|
+
## Основное назначение
|
|
20
|
+
Автоматическое создание `docker-compose.yml` файла с подстановкой всех переменных окружения из конфигурации приложения.
|
|
21
|
+
|
|
22
|
+
## Ключевые компоненты
|
|
23
|
+
|
|
24
|
+
### 1. `ConfigurationComponent`
|
|
25
|
+
- **Назначение**: Преобразует объекты конфигурации в строки переменных окружения
|
|
26
|
+
- **Функциональность**:
|
|
27
|
+
- Извлекает префикс переменных окружения из конфигурации Pydantic
|
|
28
|
+
- Генерирует строки в формате `VARIABLE_NAME: ${VARIABLE_NAME}`
|
|
29
|
+
- Добавляет комментарии с названиями классов конфигурации
|
|
30
|
+
|
|
31
|
+
### 2. `Generator`
|
|
32
|
+
- **Назначение**: Основной класс для генерации docker-compose файла
|
|
33
|
+
- **Функциональность**:
|
|
34
|
+
- Заменяет плейсхолдеры `[ENV]` и `[VERSION]` в шаблоне
|
|
35
|
+
- Сохраняет форматирование и отступы
|
|
36
|
+
- Записывает результат в файл `docker-compose.yml`
|
|
37
|
+
|
|
38
|
+
## Особенности реализации
|
|
39
|
+
|
|
40
|
+
### Шаблон Docker Compose
|
|
41
|
+
Создает сервисы:
|
|
42
|
+
- **api** - веб-сервер с пробросом портов
|
|
43
|
+
- **bg** - фоновый сервис
|
|
44
|
+
- Оба используют общую сеть `common-net`
|
|
45
|
+
|
|
46
|
+
### Автоматизация конфигурации
|
|
47
|
+
- Извлекает все переменные из объектов `BaseSettings`
|
|
48
|
+
- Сохраняет структуру и префиксы конфигурации
|
|
49
|
+
- Генерирует полный список переменных окружения
|
|
50
|
+
|
|
51
|
+
### Преимущества подхода
|
|
52
|
+
1. **Синхронизация** - версии и настройки всегда актуальны
|
|
53
|
+
2. **Безопасность** - не хранит чувствительные данные в репозитории
|
|
54
|
+
3. **Автоматизация** - исключает ручное редактирование
|
|
55
|
+
4. **Масштабируемость** - легко добавлять новые сервисы и настройки
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Проект полезен для CI/CD процессов, где требуется автоматическое создание docker-compose файлов с актуальными настройками окружения.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Этот проект представляет собой **генератор docker-compose.yml файла** на основе настроек приложения. Вот подробное описание:
|
|
2
|
+
|
|
3
|
+
## Основное назначение
|
|
4
|
+
Автоматическое создание `docker-compose.yml` файла с подстановкой всех переменных окружения из конфигурации приложения.
|
|
5
|
+
|
|
6
|
+
## Ключевые компоненты
|
|
7
|
+
|
|
8
|
+
### 1. `ConfigurationComponent`
|
|
9
|
+
- **Назначение**: Преобразует объекты конфигурации в строки переменных окружения
|
|
10
|
+
- **Функциональность**:
|
|
11
|
+
- Извлекает префикс переменных окружения из конфигурации Pydantic
|
|
12
|
+
- Генерирует строки в формате `VARIABLE_NAME: ${VARIABLE_NAME}`
|
|
13
|
+
- Добавляет комментарии с названиями классов конфигурации
|
|
14
|
+
|
|
15
|
+
### 2. `Generator`
|
|
16
|
+
- **Назначение**: Основной класс для генерации docker-compose файла
|
|
17
|
+
- **Функциональность**:
|
|
18
|
+
- Заменяет плейсхолдеры `[ENV]` и `[VERSION]` в шаблоне
|
|
19
|
+
- Сохраняет форматирование и отступы
|
|
20
|
+
- Записывает результат в файл `docker-compose.yml`
|
|
21
|
+
|
|
22
|
+
## Особенности реализации
|
|
23
|
+
|
|
24
|
+
### Шаблон Docker Compose
|
|
25
|
+
Создает сервисы:
|
|
26
|
+
- **api** - веб-сервер с пробросом портов
|
|
27
|
+
- **bg** - фоновый сервис
|
|
28
|
+
- Оба используют общую сеть `common-net`
|
|
29
|
+
|
|
30
|
+
### Автоматизация конфигурации
|
|
31
|
+
- Извлекает все переменные из объектов `BaseSettings`
|
|
32
|
+
- Сохраняет структуру и префиксы конфигурации
|
|
33
|
+
- Генерирует полный список переменных окружения
|
|
34
|
+
|
|
35
|
+
### Преимущества подхода
|
|
36
|
+
1. **Синхронизация** - версии и настройки всегда актуальны
|
|
37
|
+
2. **Безопасность** - не хранит чувствительные данные в репозитории
|
|
38
|
+
3. **Автоматизация** - исключает ручное редактирование
|
|
39
|
+
4. **Масштабируемость** - легко добавлять новые сервисы и настройки
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
Проект полезен для CI/CD процессов, где требуется автоматическое создание docker-compose файлов с актуальными настройками окружения.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from pydantic_settings import BaseSettings
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ConfigurationComponent:
|
|
5
|
+
"""Конфигурационные объекты, составляющие настройки всего приложения"""
|
|
6
|
+
|
|
7
|
+
def __init__(self, item: BaseSettings) -> None:
|
|
8
|
+
self.item = item
|
|
9
|
+
|
|
10
|
+
self.env_prefix = item.model_config.get("env_prefix", "")
|
|
11
|
+
self.title = self.item.__class__.__name__
|
|
12
|
+
self.attrs = list(item.model_dump().keys())
|
|
13
|
+
|
|
14
|
+
def parsed(self) -> str:
|
|
15
|
+
"""
|
|
16
|
+
Парсит объект в строку для записи в docker-compose.yml
|
|
17
|
+
|
|
18
|
+
Пример:
|
|
19
|
+
# RabbitMQ
|
|
20
|
+
RABBITMQ_HOST: ${RABBITMQ_HOST}
|
|
21
|
+
RABBITMQ_USER: ${RABBITMQ_USER}
|
|
22
|
+
RABBITMQ_PASS: ${RABBITMQ_PASS}
|
|
23
|
+
"""
|
|
24
|
+
title = f'# {self.title}' if self.title else " "
|
|
25
|
+
result = [title]
|
|
26
|
+
|
|
27
|
+
for attr in self.attrs:
|
|
28
|
+
full_attr = self.env_prefix + attr
|
|
29
|
+
line = f"{full_attr}: " + f"${{{full_attr}}}"
|
|
30
|
+
result.append(line)
|
|
31
|
+
|
|
32
|
+
return "\n".join(result)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Generator:
|
|
36
|
+
"""Генератор docker-compose.yml"""
|
|
37
|
+
|
|
38
|
+
ENV_KEY = '[ENV]'
|
|
39
|
+
VERSION_KEY = '[VERSION]'
|
|
40
|
+
FILE_NAME = 'docker-compose.yml'
|
|
41
|
+
|
|
42
|
+
def __init__(self, settings: BaseSettings, template: str, version: str) -> None:
|
|
43
|
+
self.settings = settings
|
|
44
|
+
self.template = template
|
|
45
|
+
self.version = version
|
|
46
|
+
|
|
47
|
+
def insert_to_template(self, content: str, key: str) -> None:
|
|
48
|
+
# Разбиваем вставляемую строку на отдельные строки
|
|
49
|
+
|
|
50
|
+
def define_indentation() -> str:
|
|
51
|
+
lines = self.template.split('\n')
|
|
52
|
+
for line in lines:
|
|
53
|
+
if key in line:
|
|
54
|
+
return line.split(key)[0]
|
|
55
|
+
return ''
|
|
56
|
+
|
|
57
|
+
# Форматируем каждую строку с правильным отступом
|
|
58
|
+
formatted = '\n'.join(
|
|
59
|
+
[define_indentation() + line for line in content.split('\n')]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Заменяем {ENV} в шаблоне
|
|
63
|
+
self.template = self.template.replace(key, formatted.strip())
|
|
64
|
+
|
|
65
|
+
def replace_version(self, version: str) -> None:
|
|
66
|
+
self.template = self.template.replace(self.VERSION_KEY, version)
|
|
67
|
+
|
|
68
|
+
def generate(self) -> None:
|
|
69
|
+
components = list(self.settings.__dict__.values())
|
|
70
|
+
parsed_components: list[str] = [
|
|
71
|
+
ConfigurationComponent(c).parsed() for c in components
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
self.insert_to_template(
|
|
75
|
+
content='\n\n'.join(parsed_components), key=self.ENV_KEY
|
|
76
|
+
)
|
|
77
|
+
self.replace_version(self.version)
|
|
78
|
+
|
|
79
|
+
with open(self.FILE_NAME, 'w') as f:
|
|
80
|
+
f.write(self.template)
|
|
81
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
APP_SERVER_PORT=5000
|
|
2
|
+
|
|
3
|
+
DEFAULT_DB_USER=test
|
|
4
|
+
DEFAULT_DB_PASS=test
|
|
5
|
+
DEFAULT_DB_HOST=test
|
|
6
|
+
DEFAULT_DB_PORT=123
|
|
7
|
+
DEFAULT_DB_NAME=test
|
|
8
|
+
|
|
9
|
+
JWT_EXPIRES_SECONDS=259200
|
|
10
|
+
JWT_SECRET_KEY=ls6ied8kQ2jd
|
|
11
|
+
|
|
12
|
+
API_KEY=ls6ied8sdaf4wkQ2jd
|
|
13
|
+
|
|
14
|
+
SWAGGER_LOGIN=admin
|
|
15
|
+
SWAGGER_PASSWORD=admin
|
|
16
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Example
|
|
2
|
+
from compose_generator import Generator
|
|
3
|
+
|
|
4
|
+
TEMPLATE = """version: "3.9"
|
|
5
|
+
|
|
6
|
+
networks:
|
|
7
|
+
common-net:
|
|
8
|
+
external: true
|
|
9
|
+
|
|
10
|
+
x-serv-common-env: &serv-common-env
|
|
11
|
+
[ENV]
|
|
12
|
+
|
|
13
|
+
services:
|
|
14
|
+
api:
|
|
15
|
+
image: /project/user/super-project/api:[VERSION]
|
|
16
|
+
networks:
|
|
17
|
+
- common-net
|
|
18
|
+
ports:
|
|
19
|
+
- ${APP_SERVER_PORT}:${APP_SERVER_PORT}
|
|
20
|
+
environment:
|
|
21
|
+
<<: *serv-common-env
|
|
22
|
+
restart:
|
|
23
|
+
unless-stopped
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
from pydantic import Field
|
|
29
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FromEnvFile(BaseSettings):
|
|
33
|
+
model_config = SettingsConfigDict(
|
|
34
|
+
env_file=Path(Path(__file__).resolve().parent, "example.env"),
|
|
35
|
+
extra="ignore",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BaseConnection(FromEnvFile):
|
|
40
|
+
USER: str
|
|
41
|
+
PASS: str
|
|
42
|
+
HOST: str
|
|
43
|
+
PORT: int
|
|
44
|
+
NAME: str
|
|
45
|
+
|
|
46
|
+
def get_connection_config(self) -> dict:
|
|
47
|
+
return {
|
|
48
|
+
"engine": "tortoise.backends.asyncpg",
|
|
49
|
+
"credentials": {
|
|
50
|
+
"host": self.HOST,
|
|
51
|
+
"port": self.PORT,
|
|
52
|
+
"user": self.USER,
|
|
53
|
+
"password": self.PASS,
|
|
54
|
+
"database": self.NAME,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DefaultDB(BaseConnection):
|
|
60
|
+
model_config = SettingsConfigDict(env_prefix="DEFAULT_DB_")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class App(FromEnvFile):
|
|
64
|
+
model_config = SettingsConfigDict(env_prefix="APP_")
|
|
65
|
+
SERVER_PORT: int
|
|
66
|
+
VERSION: str = '1.0.0'
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class API(FromEnvFile):
|
|
70
|
+
model_config = SettingsConfigDict(env_prefix="API_")
|
|
71
|
+
KEY: str
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class Swagger(FromEnvFile):
|
|
75
|
+
model_config = SettingsConfigDict(env_prefix="SWAGGER_")
|
|
76
|
+
LOGIN: str
|
|
77
|
+
PASSWORD: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class JWT(FromEnvFile):
|
|
81
|
+
model_config = SettingsConfigDict(env_prefix="JWT_")
|
|
82
|
+
SECRET_KEY: str
|
|
83
|
+
EXPIRES_SECONDS: int
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class Settings(BaseSettings):
|
|
87
|
+
app: App = Field(default_factory=App)
|
|
88
|
+
db: DefaultDB = Field(default_factory=DefaultDB)
|
|
89
|
+
jwt: JWT = Field(default_factory=JWT)
|
|
90
|
+
api: API = Field(default_factory=API)
|
|
91
|
+
swagger: Swagger = Field(default_factory=Swagger)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
stt = Settings()
|
|
96
|
+
generator = Generator(
|
|
97
|
+
settings=stt,
|
|
98
|
+
template=TEMPLATE,
|
|
99
|
+
version=stt.app.VERSION,
|
|
100
|
+
)
|
|
101
|
+
generator.generate()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "compose-generator"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Проект представляет собой генератор docker-compose.yml файла на основе настроек приложения"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "pasha_danilevich",email = "danilevitch.pasha@yandex.ru"}
|
|
7
|
+
]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
|
|
11
|
+
[tool.poetry.dependencies]
|
|
12
|
+
pydantic-settings = "^2.11.0"
|
|
13
|
+
|
|
14
|
+
[build-system]
|
|
15
|
+
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
16
|
+
build-backend = "poetry.core.masonry.api"
|