Где найти файл config json
По умолчанию в проекте уже есть файл конфигурации json - appsettings.json , а также appsettings.Development.json , которые загружаются по умолчанию в приложении и которые мы можем использовать для хранения конфигурационных настроек.
Например, код файла appsettings.json:
Здесь определяются настройки логгирования (элемент "Logging") и разрешенные хосты (элемент "AllowedHosts"). Одни элементы могут иметь вложенные элементы. Аналогичным образом можно задать другие необходимые настройки или удалить ранее определенные.
Однако в данном случае для примера возьмем новый файл json. Итак, добавим в проект новый файл config.json :
И определим в нем следующее содержимое:
Здесь задается два элемента с ключами "person" и "company". Используем эти настройки в приложении:
Для установки конфигурации из json-файла название файла передается в метод AddJsonFile() .
При определении настроек в файле json нам надо учитывать, что они должны иметь уникальные ключи. Но при этом мы можем использовать для конфигурации более чем одного файла:
И если во втором файле есть настройки, которые имеют тот же ключ, что и настройки первого файла, то происходит переопределение настроек: настройки из второго файла заменяют настройки первого.
Но json может хранить также более сложные по составу объекты, например:
И чтобы обратиться к этой настройке, нам надо использовать знак двоеточия для обращения к иерархии настроек:
Python-dotenv — считываем конфигурацию приложения из переменных среды
Теперь перейдем к сторонним библиотекам, использующимся для управления конфигурацией приложений Python. До сих пор я намеренно пропустил еще один тип файлов конфигурации, а именно .env . Так значения настроек, находящихся в файле .env при запуске терминала (скрипта приложения) будут загружены как переменные среды, и поэтому с помощью библиотеки python-dotenv , а точнее ее метода os.getenv() можно получить доступ к ним из кода приложения.
Файл .env обычно выглядит следующим образом. По умолчанию его местонахождение – корневая папка вашего проекта.
Интеграция с Pytest
Еще одна интересная особенность dynaconf – это возможность его интеграции с pytest. Так настройки для модульного тестирования unit testing обычно существенно отличаются в различных средах. Для этого вы можете использовать параметр FORCE_ENV_FOR_DYNACONF , чтобы ваше приложение могло прочитать значения настроек из внешнего файла, или использовать фикстуру monkeypatch для замены определенных пар ключ и значение в файле настроек.
Группа конфигураций
Hydra вводит концепцию под названием config group . Идея которой состоит в том, чтобы сгруппировать файлы конфигурации одного типа (или для выполнения одних задач) и затем выбирать один из них во время выполнения приложения. Например, у вас имеется группа настроек «Базы данных» с одной конфигурацией для Postgres, а другой для MySQL.
Когда конфигурация приложения станет более сложной, то в вашей программе она может иметь следующую структуру (пример из документации Hydra).
Например, вы хотите протестировать свое приложение с различными комбинациями опций db , schema и ui , это можно сделать следующим образом:
Hydra — упрощаем разработку, динамически создавая иерархическую структуру конфигурации приложения
Рассмотрим последним, в этой статье, способ создания и поддержки конфигурации для вашего приложения, который по сути является гораздо большим, чем просто загрузчик и парсер файлов с настройками.
Hydra – это платформа, разработанная Facebook для гибкой и элегантной настройки самых сложных приложений. Которая помимо чтения, записи и валидации корректности файлов конфигурации, реализовывает свою достаточно рациональную стратегию упрощения управления несколькими конфигурационными файлами, переопределения (перезаписи) их с использованием интерфейса командной строки, создания snapshot снимка состояния приложения перед каждым его запуском (между перезапусками) и т.д.
Попытка №3
А сейчас, я хотел бы показать Вам свою библиотеку, которая призвана решить все эти проблемы (ну, или хотя бы уменьшить ваши страдания :)).
Называется она betterconf и доступна на PyPi.
Установка так же проста, как и любой другой библиотеки:
Изначально, наш конфиг представлен в виде класса с полями:
По умолчанию, библиотека пытается взять значения из переменных окружения, но мы также можем настроить и это:
Из этого примера следует, что мы можем применять различные провайдеры для получения данных. И это действительно иногда бывает удобно, говорю из личного опыта.
Хорошо, а что если у нас в конфигах есть булевые значения, или числа, они же в итоге будут все равно приходить в строках. И для этого есть решение:
Таким образом, все похожие на булевые типы значения (а именно true и false будут преобразованы в питоновский bool . Регистр не учитывается.
Свой кастер написать также легко:
Чтение
Этот тип файла конфигурации очень легко использовать. Так если вы решите переопределить существующую (или создать новую) переменную среды, то можете использовать вызов метод load_dotenv() , например, зададим значение параметра override .
Валидация
Валидация данных с Configureparser не так проста, как для пакетов, работающих с форматами YAML и JSON. Во-первых, он не возбуждает исключения FileNotFoundError если файла настроек не существует, а вместо этого вызывает исключение типа KeyError, как при попытке доступа к отсутствующему ключу.
Кроме того, этот пакет «игнорирует» некоторые ошибки форматирования, например, неправильное использование отступа. Так в приведенном ниже примере, в случае если в файле присутствует дополнительная табуляция или пробел перед настройкой DEBUG , то вы получите неправильные значения для обеих настроек ENVIRONMENT и DEBUG .
Тем не менее, Configureparser может возбуждать исключение ParserError при наличии нескольких ошибок (см. пример кода с тестами ниже). И в большинстве случаев этого достаточно для определения проблемных мест в самом файле настроек.
Конфигурация в XML
За использование конфигурации в XML-файле отвечает провайдер XmlConfigurationProvider . Для загрузки xml-файла применяется метод расширения AddXmlFile() .
Итак, добавим в проект новый xml-файл, который назовем config.xml . Затем изменим его код на следующий:
Здесь определены два элемента person и company, которые представляют конфигурационные настройки.
Обратите внимание, что у файла xml в свойствах должно быть выставлено копирование при компиляции в выходную папку приложения:
Теперь используем этот файл:
Если у нас файл конфигурации имеет разные уровни вложенности, например:
то мы можем обращаться к этим уровням также, как и в файле json:
Валидация
При использовании обоих пакетов при попытке чтения несуществующего файла будет генерироваться исключение типа FileNotFoundError . Использование пакета для чтения файлов YAML позволяет получать разные исключения для следующих случаев: пользователь указал файл не являющимся YAML файлом, а также прочитанный файл YAML является не корректным, то есть содержит синтаксические ошибки. В свою очередь пакет для чтения JSON файлов генерирует единственное исключение типа JSONDecoderError для обоих рассмотренных случаев.
Настройка сети
С базовыми операциями по управлению контейнерами мы разобрались. Попробуем настроить в контейнере сеть. Это не самая простая задача. Все операции нужно осуществлять вручную.
Для начала выполним следующую последовательность команд (взято из этой статьи):
Приведённые команды говорят сами за себя. Сначала мы создаём мост для связи между контейнером и интерфейсом на основном хосте. Затем «поднимаем» виртуальный интерфейс и добавляем его в мост. После этого мы создаём сетевое пространство имён (неймспейс) с именем runc и назначаем в нём IP-адрес интерфейсу eth1.
Чтобы настроить в контейнере сеть, мы должны ассоциировать с ним неймспейс runc. Для этого внесём небольшие изменения в файл config.json:
В разделе namespaces укажем путь к пространству имён runc:
Вот и всё: все необходимые настройки прописаны. Сохраняем внесённые изменения и перезапускаем контейнер. Выполним на основном хосте команду:
Её вывод свидетельствует о том, что контейнер принимает ping с основного хоста.
Использование файла tsconfig.json
Файл tsconfig.json используется при компиляции в том случае, если компилятору не передаются названия файлов, которые надо скомпилировать. В этом случае компилятор TypeScript просматривает текущий каталог, ищет в нем файл tsconfig.json и затем при компиляции использует те параметры, которые определены в этом файле.
Если же компилятору передаются названия файлов, например, tsc app.ts , то файл tsconfig.json игнорируется.
Полный список применяемых опций в tsconfig.json можно просмотреть в документации
Установка
Мы будем описывать установку runc для Ubuntu 16.04. В этой операционной системе последняя на текущий момент стабильная версия Go (1.6) уже включена в официальные репозитории и устанавливается стандартным способом:
Runc тоже включён в репозитории Ubuntu 16.04, но далеко не в самой свежей версии. Последнюю на сегодняшний день версию (1.0.0) нужно собирать из исходного кода. Для этого сначала потребуется установить необходимые зависимости:
Вот и всё, можно приступать к сборке runC:
В результате выполнения этих команд runc будет установлен в директорию /usr/local/bin/runc.
Чтение
Рассмотрим основы использования hydra. Так в следующем примере команда +APP.NAME , добавленная в командную строку при запуске скрипта, позволяет добавить новое поле (настройку) в конфигурацию приложения, а также осуществить перезапись значения существующего поля (значения настройки) APP.NAME=hydra1.1 .
Чтение
Как видно из примера Configureparser не может «угадать» типы данных, содержащихся в файле конфигурации, так как значение каждой настройки сохраняется в виде строки. Тем не менее, он предоставляет несколько полезных методов для преобразования строк (значений настроек) в нужный тип данных. Наиболее интересным из них является метод преобразующий значения в логический тип, то есть он может распознавать некоторые логические значения, например, yes / no , on / off , true / false и 1 / 0 .
Как уже нами упоминалось ранее, Configureparser может читать данные настроек в следующих видах на выходе: словаря с помощью метода read_dict() , простой строки с использованием read_string() и итерируемого файлоподобного объекта, возвращаемого методом read_file() .
Валидация
Тем не менее пакет python-dotenv не проверяет корректность .env файла. Допустим у вас есть некоторый .env файл (его содержимое представлено ниже), и вы хотите получить доступ к значению переменной (параметра настройки) DEBUG , то будет возвращено значение None без возбуждения исключения соответствующего типа.
Пакет Cofigureparser из состава стандартной библиотеки Python
В этом разделе рассмотрим пакеты, предназначенные непосредственно для управления конфигурацией приложения. И начнем со встроенного в стандартную библиотеку Python пакета: Configureparser.
Configureparser в большинстве случаев используется для чтения и записи INI файлов, и поддерживает чтение входных данных из файла сразу в виде словаря или итерируемого iterable файлоподобного объекта. Как известно, каждый файл INI состоит из нескольких секций, содержащих настройки в виде пар ключ-значение. Ниже приведен простой пример кода для доступа к полям настроек.
Создаём первый контейнер
Итак, к созданию первого контейнера всё готово.
Первое, что нам нужно сделать — это создать отдельную директорию под новый контейнер, а внутри её — директорию rootfs:
Начнём с cамого простого примера. Загрузим docker-образ memcached, преобразуем его в архив *.tar и распакуем в директорию rootfs:
В результате выполнения этой команды в директорию rootfs будут помещены системные файлы для будущего контейнера:
После этого мы можем запускать контейнеры и управлять ими, не прибегая к помощи Docker. Создадим конфигурационный файл, в котором будут прописаны настройки нового контейнера:
После этого в директории rootfs появится новый файл — config.json. К запуску нового контейнера всё готово. Выполним:
Внутри контейнера будет запущена командная оболочка.
Мы рассмотрели самый элементарный пример, в котором контейнер был запущен с автоматически сгенерированными настройками. Для более тонкой настройки контейнеров упомянутый выше файл config.json придётся редактировать вручную. Разберём его структуру более подробно.
Структура файла
tsconfig.json представляет собой стандартный файл в формате json, который содержит ряд секций. Так, секция "compilerOptions" настраивает параметры компиляции. Здесь можно указать необходимые параметры и их значения. Параметры называются также, как и в командной строке. И соответственно значения мы им можем передать те же, что передаются в командной строке (или терминале). Например:
Здесь используется все те же параметры, которые применяются при компиляции в командной строке. Например, параметр "target" указывает, какой стандарт JavaScript будет применяться при компиляции.
Параметр "removeComments" удаляет комментарии. Параметр "outDir" задает каталог для скомпилированных файлов. "sourceMap" указывает, что надо сгенерировать карту для сопоставления исходных и скомпилированных файлов. И параметр "outFile" задает название выходного файла.
При необходимости можно включать другие опции компиляции.
С помощью секции files можно установить набор включаемых в проект файлов:
Если секция "files" не указана в файле tsconfig.json, то компилятор по умолчанию включает все файлы TypeScript (файлы с расширением *.ts и *.tsx ), которые находятся в каталоге и подкаталогах проекта. Если же указана секция "files", то используются только файлы из этой секции.
Параметр exclude , наоборот, позволяет исключить при компиляции определенные файлы:
При компиляции компилятор не будет учитывать файлы TypeScript, которые находятся в каталогах из секции exclude.
При этом следует учитывать, что если в файле одновременно будут заданы обе секции files и exclude, то секция exclude будет игнорироваться.
Все файлы, на которые есть ссылки в файлах из секции "files", также компилируются.
Параметр compileOnSave при значении true указывает используемой IDE сгенерировать все файлы js при каждом сохранении файлов TypeScript:
Чтение
Из-за проблем с безопасностью рекомендуется использовать метод yaml.safe_load() вместо yaml.load() , чтобы избежать внедрения вредоносного кода при чтении файла конфигурации.
Заключение
Эта статья представляет собой лишь краткое введение в runC. Для желающих узнать больше приводим небольшую подборку полезных ссылок:
С помощью файла tsconfig.json можно настроить проект TypeScript. В частности, этот файл выполняет следующие задачи:
устанавливает корневой каталог проекта TypeScript
выполняет настройку параметров компиляции
устанавливает файлы проекта
Для его использования достаточно вручную добавить новый файл с именем tsconfig.json в корень проекта.
Итоги
Таким образом, мы пришли к выводу, что хранить настройки в исходных кодах — не есть хорошо. Для этого уже придуманы различные форматы. Ну, а вы познакомились с ещё одной полезной (как я считаю :)) библиотекой.
Да, также можно было включить и Pydantic , но я считаю, что он слишком НЕлегковесный для таких задач.
Относитесь к файлу конфигурации, использующемуся в приложении, как к разрабатываемому вами коду.
Когда мы разрабатываем программное обеспечение, то всегда прикладываем много усилий для написания качественного и производительного кода. Однако зачастую этого недостаточно.
Разработка качественного программного обеспечения, включает заботу о разработке своей экосистемы, например, для организации процессов тестирования, развертывания, сетевого обмена данными и т.д. Одним из наиболее важных аспектов, который необходимо при этом учитывать, является реализация гибкого механизма управления конфигурацией (настройками) программного обеспечения.
Правильная реализация управления конфигурацией по сути должна позволять запускать программное обеспечение в любой среде без внесения изменений в его исходный код. Этот подход обеспечивает эффективное управление проблемными настройками вашего приложения со стороны администраторов Ops, обеспечивает представление информации о том, что может произойти во время его функционирования, а также позволяет изменять его поведение во время выполнения.
Наиболее распространенные конфигурации включают в себя учетные данные для базы данных или внешней службы, имя хоста сервера, а также любые динамические параметры и т.д.
В этой статье я хочу поделиться с вами несколькими зарекомендовавшими себя практиками управления конфигурациями, а также как мы можем реализовать их в приложениях, написанных на Python.
Конфигурация в XML
За использование конфигурации в XML-файле отвечает провайдер XmlConfigurationProvider . Для загрузки xml-файла применяется метод расширения AddXmlFile() .
Итак, добавим в проект новый xml-файл, который назовем config.xml . Затем изменим его код на следующий:
Здесь определены два элемента person и company, которые представляют конфигурационные настройки.
Обратите внимание, что у файла xml в свойствах должно быть выставлено копирование при компиляции в выходную папку приложения:
Теперь используем этот файл:
Если у нас файл конфигурации имеет разные уровни вложенности, например:
то мы можем обращаться к этим уровням также, как и в файле json:
Попытка №1
А что насчёт того чтобы хранить конфигурацию в коде? Ну, а что, вроде удобно, да и новых языков не придётся изучать. Существует множество проектов, в которых данный способ используется, и хочу сказать, вполне успешно.
Типичный конфиг в этом стиле выглядит так:
Выглядит неплохо. Только одно настораживает, почему секьюрные данные хранятся в коде? Как мы это коммитить будем? Загадка. Разве что вносить наш файл в .gitignore , но это, конечно, вообще не решение.
Да и вообще, почему хоть какие-то данные хранятся в коде? Как мне кажется код, он на то и код, что должен выполнять какую-то логику, а не хранить данные.
Данный подход, на самом деле используется много где. В том же Django. Все думают, что раз это самый популярный фреймворк, который используется в самом Инстаграме, то они то уж плохое советовать не будут. Жаль, что это не так.
Какой формат файла конфигурации использовать?
С практической точки зрения, на формат файла конфигурации нет никаких технических ограничений, если код приложения может его прочитать и анализировать. Но есть и более рациональные практики для выбора формата файла с настройками. Так наиболее распространенными, стандартизованными форматами являются YAML, JSON, TOML и INI. Самый подходящий формата для файл конфигурации должен соответствовать как минимум трем критериям:
- Быть легко читаемым и редактируемым: файл должен иметь текстовый формат и такую структуру, чтобы его содержимое было легко понятно даже не разработчику.
- Разрешать использование комментариев: файл конфигурации – это то, что могут читать не только разработчики. Поэтому в процессе эксплуатации приложения чрезвычайно важно когда пользователи могут успешно пытаться понять его работу и изменить его поведение. Написание комментариев – это эффективный способ быстро пояснить ключевые особенности настройки приложения и делает конфигурационный файл более выразительным.
- Простота развертывания: файл конфигурации должен понятен для обработки всеми операционными системами и средами. Он также должен легко доставляться на сервер с помощью конвейера pipeline CDaaS.
Возможно вам пока не ясно какой из форматов файла лучше использовать. Но если вы подумаете об этом в контексте программирования на языке Python, то наиболее очевидным ответом будет YAML или INI. Форматы YAML и INI хорошо понятны большинству программ и пакетов Python.
INI файл, вероятно, является наиболее простым решением для сохранения настроек приложения, имеющих только один уровень иерархии (вложенности) параметров. Однако формат INI не поддерживает других типов данных, кроме строк: в нем все данные имеют строковое представление.
Та же конфигурация настроек в YAML выглядит следующим образом.
Как видите, YAML изначально поддерживает использование вложенные структуры (также как и JSON) с помощью отступов. Кроме того, YAML, в отличие от формата INI файлов, поддерживает некоторые другие типы данных такие как целые и с плавающей запятой числа, логические значения, списки, словари и т.д.
Формат файлов JSON по сути очень похож на YAML и тоже чрезвычайно популярен, однако в JSON файлы нельзя добавлять комментарии. JSON, как текстовый формат содержащий структурированные данные, часто используется для хранения внутренней конфигурации внутри программы, но совершенно не предназначен для того, чтобы делиться конфигурацией приложения с другими людьми (в особенности с далекими от вопросов разработки ПО).
Формат TOML, с другой стороны, похож на INI, но поддерживает гораздо больше типов данных, а также специальный синтаксис для хранения вложенных структур. Его часто используют менеджеры пакетов Python такие, например, pip или poetry. Но если в файле конфигурации присутствует слишком много вложенных структур, то YAML в этом отношении, с моей точки зрения, наилучший выбор. Следующий ниже фрагмент файла выглядит как INI, но в отличие от него каждое строковое значение имеет кавычки.
Пока что мы выяснили ЧТО из себя представляют форматы файлов YAML, JSON, TOML и INI, далее мы рассмотрим КАК они могут быть использованы.
Попытка №2
Ладно, раз уж мы решили, что хранить данные в коде — не круто, то давайте искать альтернативу. Для конфигурационных файлов изобретено немалое количество различных форматов, в последнее время набирают большую популярность toml .
Но мы начнём с того, что нам предлагает сам Python — .ini . В стандартной библиотеке имеется библиотека configparser .
Наш конфиг, который мы уже писали ранее:
А теперь прочитаем в Python:
Все проблемы решены. Данные хранятся не в коде, доступ прост. Но… а если нам нужно читать другие конфиги, ну там json или yaml например, или все сразу. Конечно, есть json в стандартной библиотеке и pyyaml , но придётся написать кучу (ну, или не совсем) кода для этого.
Dynaconf — мощный конфигуратор настроек для приложений Python
Dynaconf — это очень мощная система для конфигурации настроек в Python, которая поддерживает следующие форматы файлов: yaml, json, ini, toml и python. Она также позволяет автоматически загружать .env файл и поддерживает настраиваемые правила для валидации данных настроек. Проще говоря, он охватывает практически весь функционал трех предыдущих рассмотренных вариантов и даже выходит за рамки этого. Например, вы можете сохранить зашифрованный пароль и используя специальный загрузчик для его расшифровки. Он прекрасно интегрирован с Flask, Django и Pytest. Я не буду упоминать все его возможности в этой статье, и поэтому для более подробной информации обратитесь к его документации.
Далее…
Hydra поддерживает использование нескольких наборов параметров конфигурации с опцией --multirun , при этом запускаются параллельно несколько задач с различными файлами конфигурации. Например, для предыдущего примера мы можем запустить скрипт следующим образом:
В этом случае в основном потоке запускаются 6 задач одновременно:
Конфигурационный файл config.json
В первой части конфигурационного файла описываются общие характеристики контейнера: версия OCI, операционная система и её архитектура, параметры терминала:
В следующем разделе приводятся настройки для директории, в которой работает контейнер:
Аббревиатура CWD означает current working directory. В нашем случае это директория «/». Далее указывается набор capabilities (на русский язык этот термин не совсем удачно переводят как «возможности») — разрешений для исполняемых файлов на использование определённых подсистем без прав root. CAP_AUDIT_WRITE разрешает делать записи в журнал аудита, CAP_KILL — отправлять процессам сигналы, а CAP_NET_BIND_SERVICE — разрешает привязку сокетов к привилегированным портам (т.е. портам с номерами меньше 1024).
Следующий раздел — rlimits:
Здесь мы устанавливаем для контейнера лимит ресурсов, а именно — максимальное количество одновременно открытых файлов (RLIMIT_NOFILE), которое составляет 1024.
Далее идёт описание настроек корневой файловой системы:
В разделе mounts описываются cмонтированные в контейнер директории:
Мы рассмотрели лишь самые основные разделы файла config.json. О некоторых других его разделах мы поговорим ниже. С подробным описанием этого файла можно ознакомиться здесь.
Ещё одна интересная возможность runc — настройка хуков: мы можем прописать в конфигурационном файле конкретные действия, которые будут выполнены перед запуском пользовательского процесса в контейнере (prestart), после запуска пользовательского процесса (poststart) и после его остановки (poststop).
Приведём несколько примеров, чтобы лучше понять, зачем нужны хуки и как прописываются соответствующие настройки в конфигурационном файле. Представим себе вполне такую ситуацию: прежде чем запускать некоторую программу в контейнере, нам нужно настроить сеть. Для этого добавим в конфигурационный файл такой хук (пример взят из официальной документации):
В разделе path прописывается путь к программе, которая и выполнит настройку сети. Готовые программные инструменты подобного рода можно найти на Github — см., например, здесь.
Рассмотрим теперь пример poststart-хука:
Когда этот хук сработает, будет запущен скрипт (в нашем примере она называется notify-start), который запишет в логи информацию о событиях, связанных с запуском контейнера.
Poststop-хуки инициируют действия, которые будут выполнены после завершения пользовательского процесса в контейнере. Они могут понадобиться, например, в случае, когда нам нужно удалить логи и сессионные файлы, оставленные контейнером в системе, а заодно и сам контейнер. Вот простой пример:
При срабатывании этого хука будет запущен скрипт cleanup.sh, который и выполнить все упомянутые выше действия.
Чтение
Dynaconf использует .env файл для поиска других конфигурационных файлов и последующего заполнения полей settings объекта с настройками. Так если в двух файлах настроек есть одна и та же переменная, то ее значение будет перезаписано значением из последнего файла настроек.
Валидация
Hydra прекрасно интегрируется с декоратором @dataclass для выполнения основных проверок корректности, таких как проверка типов или значения полей. Однако у нее нет поддержки __post_init__ метода расширенной проверки значений, как это описано в моей предыдущей статье.
YAML/JSON — простое чтение внешнего файла
Как обычно, мы начнем с самого простого, то есть создадим внешний файл с настройками, а затем прочитаем его. Python имеет в своем составе встроенные пакеты для чтения и анализа файлов YAML и JSON. И как видно из приведенного ниже кода, они фактически возвращают один и тот же объект типа dict, поэтому доступ к его атрибутам будет одинаковым для обоих файлов.
Валидация
Одна из наиболее интересных, в частности для меня, возможностей dynaconf – это его настраиваемый валидатор. Как упоминалось ранее, Configureparser недостаточно строго проверяет корректность INI файлов настроек, но это можно легко реализовать в dynaconf. В следующем примере мы проверяем, существуют ли определенные ключи в файле с настройками и имеется ли в нем конкретный ключ с корректным значением. Если вы читаете настройки из файла YAML или TOML, которые как мы говорили ранее, поддерживают несколько типов данных, то вы даже можете проверить, находится ли значение настройки, например, число в заданном диапазоне.
Когда необходим файл конфигурации приложения?
Перед разработкой конфигурационного файла сначала необходимо спросить себя, нужен ли вообще какой-либо внешний файл с данными? Разве мы не можем просто поместить их в виде константных значений прямо в исходном коде? Собственно, достаточно известная концепция The Twelve-Factor App давно отвечает на этот вопрос:
Лакмусовой бумажкой для проверки правильности решения о выделении config всей конфигурационной информации приложения из кода, является рассмотрение возможности о публикации в любой момент кодовой базы вашего приложения, то есть можно ли сделать его исходный код открытым, без нарушения конфиденциальности чьих-либо учетных данных.
Обратите внимание, что это определение config не включает внутреннюю конфигурацию приложения, такую как, например, как config/routes.rb в Rails, или способ подключения модулей в Spring. Перечисленные выше примеры способов конфигурации не меняются в зависимости от среды развертывания, и поэтому это лучше всего реализовать их в коде.
Подходы рекомендованные этой концепцией предписывают, чтобы любые параметры, зависящие от среды, такие как учетные данные базы данных, находились во внешнем файле. В противном случае их реализуют просто обычными константами в коде. Другой вариант использования, который я часто вижу, – это хранение динамических переменных (данных) во внешнем файле (базе данных), например, черный blacklist или белый whitelist список пользователей. Ими могут быть числа в заданном диапазоне (например, длительность тайм-аута) или любые текстовые файлы с произвольным содержимым. Отметим, что эти динамические переменные (данные) остаются неизменными вне зависимости от особенностей исполняемой среды.
В свою очередь файл конфигурации делает программное обеспечение более гибким и легким для редактирования его функциональных возможностей. Однако, если он слишком сильно разрастается, рациональнее все таки перенести его в базу данных.
Конфигурация в ini-файлах
Для работы с конфигурацией INI применяется провайдер IniConfigurationProvider . А для загрузки конфигурации из INI-файла нам надо использовать метод расширения AddIniFile() .
Например, добавим в проект текстовый файл и переименуем его в config.ini .
Конфиги. Все хранят их по разному. Кто-то в .yaml , кто-то в .ini , а кто-то вообще в исходном коде, подумав, что "Путь Django" с его settings.py действительно хорош.
В этой статье, я хочу попробовать найти идеальный (вероятнее всего) способ хранения и использования конфигурационных файлов в Python. Ну, а также поделиться своей библиотекой для них :)
Обновляем конфигурацию приложения во время его выполнения
Dynaconf в своем составе содержит метод reload() , который очищает значения настроек и перезапускает все загрузчики вашего приложения. Это полезно, если вы хотите, чтобы приложение перезагружало файл настроек во время выполнения и соответственно в последствие изменяло свое поведение. Например, приложение должно автоматически перезагрузить настройки, если файл конфигурации был открыт и изменен (откорректирован).
Управление контейнерами: основные команды
Для управление контейнерами в runc используются простые и привычные команды. Вот их краткий список:
Вывод
В этой статье мы рассмотрели несколько способов управления конфигурацией приложений в Python. Независимо от того какой из них вы выберете, всегда необходимо думать о удобочитаемости файлов конфигурации, дальнейшей их поддержки, а также способах обнаружения ошибок для случаев их некорректного использования. Таким образом, конфигурационный файл – это по сути еще один тип кода.
Надеюсь, вам понравится эта статья, не стесняйтесь оставлять свои комментарии ниже.
Продолжаем цикл статей о контейнеризации. Сегодня мы поговорим о runC — инструменте для запуска контейнеров, разрабатываемом в рамках проекта Open Containers. Цель этого проекта заключается в разработке единого стандарта в области контейнерных технологий. Проект поддерживают такие компании, как Facebook, Google, Microsoft, Oracle, EMC, Docker. Летом 2015 года был опубликован черновой вариант спецификации под названием Open Container Initiative (OCI).
RunC уже активно используется в современных инструментах контейнеризации. Так, последние версии Docker (начиная с 1.11, вышедшей весной этого года) созданы в соответствии со спецификациями OCI и работают на базе runC. А библиотека libcontainer, которая по сути является частью runc, используется в Docker вместо LXC начиная ещё с версии 1.8.
В этой статье мы покажем, как можно создавать контейнеры и управлять ими с помощью runC.
Читайте также: