Arquivos de configuração Python

Configs. Todos os armazenam de maneiras diferentes. Alguém em .yaml , alguém em .ini e alguém no código fonte, pensando que o "Caminho do Django" com seu settings.py realmente bom.


Neste artigo, quero tentar encontrar a maneira ideal (mais provável) de armazenar e usar arquivos de configuração no Python. Bem, também compartilhe sua biblioteca para eles :)


Tentativa número 1


Que tal armazenar a configuração no código? Bem, o que é conveniente, e você não precisa aprender novos idiomas. Existem muitos projetos nos quais esse método é usado, e quero dizer, com bastante sucesso.


Uma configuração típica nesse estilo se parece com isso:


 # settings.py TWITTER_USERNAME="johndoe" TWITTER_PASSWORD="johndoespassword" TWITTER_TOKEN="......." 

Parece bom. Só uma coisa preocupa: por que os dados de segurança são armazenados no código? Como vamos cometer isso? O enigma. Exceto para .gitignore nosso arquivo no .gitignore , mas isso, é claro, não é uma solução.


Enfim, por que pelo menos alguns dados são armazenados no código? Como o código me parece, também é um código que deve executar algum tipo de lógica e não armazenar dados.


Essa abordagem é realmente usada muito onde. No mesmo Django. Todo mundo pensa que, como esse é o framework mais popular usado no Instagram, eles não aconselham nada de ruim. É uma pena que não seja assim.


Um pouco mais sobre isso .


Tentativa número 2


Bem, como decidimos que armazenar dados no código não é legal, vamos procurar uma alternativa. Um número considerável de formatos diferentes foi inventado para arquivos de configuração; o toml grande popularidade.


Mas começaremos com o que o próprio Python nos oferece - .ini . A biblioteca padrão possui uma biblioteca configparser .


Nossa configuração, que já escrevemos anteriormente:


 # settings.ini [Twitter] username="johndoe" password="johndoespassword" token="....." 

Agora leia em Python:


 import configparser #   config = configparser.ConfigParser() #    config.read("settings.ini") #   print(config["Twitter"]["username"]) #     ! # 'johndoe' 

Todos os problemas foram resolvidos. Os dados não são armazenados no código; o acesso é fácil. Mas ... e se precisarmos ler outras configurações, json ou yaml por exemplo, ou todos de uma vez. Obviamente, existe json na biblioteca padrão e pyyaml , mas você precisa escrever um monte de códigos (bem, ou não realmente) para isso.


Documentação


Tentativa número 3


E agora, eu gostaria de mostrar a você minha biblioteca, projetada para resolver todos esses problemas (bem, ou pelo menos reduzir o seu sofrimento :)).


É chamado betterconf e está disponível no PyPi.


A instalação é tão simples quanto qualquer outra biblioteca:


 pip install betterconf 

Inicialmente, nossa configuração é apresentada como uma classe com campos:


 # settings.py from betterconf import Config, field class TwitterConfig(Config): #  ,    `Config` username = field("TWITTER_USERNAME", default="johndoe") #   `username`,    ,   password = field("TWITTER_PASSWORD", default="johndoespassword") #  token = field("TWITTER_TOKEN", default=lambda: raise RuntimeError("Account's token must be defined!") #   ,      cfg = TwitterConfig() print(cfg.username) # 'johndoe' 

Por padrão, a biblioteca tenta obter valores das variáveis ​​de ambiente, mas também podemos configurar isso:


 from betterconf import Config, field from betterconf.config import AbstractProvider import json class JSONProvider(AbstractProvider): #     SETTINGS_JSON_FILE = "settings.json" #      def __init__(self): with open(self.SETTINGS_JSON_FILE, "r") as f: self._settings = json.load(f) #    def get(self, name): return self._settings.get(name) #    -  ,  - None.     ,   None. provider = JSONProvider() class TwitterConfig(Config): username = field("twitter_username", provider=provider) #      # ... cfg = TwitterConfig() # ... 

A partir deste exemplo, podemos usar vários provedores para receber dados. E às vezes é realmente conveniente, digo por experiência pessoal.


Bem, e se tivermos valores ou números booleanos nas configurações, eles eventualmente aparecerão em cadeias de qualquer maneira. E para isso existe uma solução:


 from betterconf import Config, field #     2  from betterconf.caster import to_bool, to_int class TwitterConfig(Config): # ... post_tweets = field("TWITTER_POST_TWEETS", caster=to_bool) # ... 

Portanto, todos os valores semelhantes aos tipos booleanos ( true e false serão convertidos em um bool Python. O caso não faz distinção entre maiúsculas e minúsculas.


Escrever o rodízio também é fácil:


 from betterconf.caster import AbstractCaster class DashToDotCaster(AbstractCaster): def cast(self, val): return val.replace("-", ".") #     to_dot = DashToDotCaster() # ... 

Repositório do Github com documentação mais detalhada .


Sumário


Assim, chegamos à conclusão de que armazenar as configurações no código fonte não é bom. Para isso, vários formatos já foram inventados. Bem, e você se encontrou com outra biblioteca útil (como eu acho :)).


PS


Sim, você também pode incluir o Pydantic , mas acredito que seja muito leve para essas tarefas.

Source: https://habr.com/ru/post/pt485236/


All Articles