Archivos de configuración de Python

Configs Todos los almacenan de diferentes maneras. Alguien en .yaml , alguien en .ini y alguien en el código fuente, pensando que la "Ruta de Django" con su settings.py realmente buena.


En este artículo, quiero intentar encontrar la forma ideal (muy probable) de almacenar y usar archivos de configuración en Python. Bueno, también comparte tu biblioteca para ellos :)


Intento número 1


¿Qué pasa con el almacenamiento de la configuración en el código? Bueno, lo que es conveniente, y no tienes que aprender nuevos idiomas. Hay muchos proyectos en los que se utiliza este método, y quiero decir, con bastante éxito.


Una configuración típica en este estilo se ve así:


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

Se ve bien Solo una cosa preocupa, ¿por qué los datos de seguridad se almacenan en código? ¿Cómo vamos a cometer esto? El acertijo. Excepto para .gitignore nuestro archivo en .gitignore , pero esto, por supuesto, no es una solución en absoluto.


De todos modos, ¿por qué al menos algunos datos se almacenan en el código? Como me parece el código, también es un código que debe ejecutar algún tipo de lógica y no almacenar datos.


Este enfoque en realidad se usa mucho donde. En el mismo Django. Todos piensan que, dado que este es el marco más popular que se usa en Instagram, no aconsejarán nada malo. Es una pena que esto no sea así.


Un poco más sobre esto .


Intento número 2


Bueno, dado que decidimos que almacenar datos en el código no es bueno, busquemos una alternativa. Se ha inventado una cantidad considerable de formatos diferentes para los archivos de configuración, toml gran popularidad.


Pero comenzaremos con lo que Python mismo nos ofrece: .ini . La biblioteca estándar tiene una biblioteca configparser .


Nuestra configuración, que ya escribimos anteriormente:


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

Ahora lee en Python:


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

Todos los problemas están resueltos. Los datos no se almacenan en código; el acceso es fácil. Pero ... y si necesitamos leer otras configuraciones, bueno, hay json o yaml por ejemplo, o todo a la vez. Por supuesto, hay json en la biblioteca estándar y pyyaml , pero tienes que escribir un montón de código (bueno, o no realmente) para esto.


Documentación


Intento número 3


Y ahora, me gustaría mostrarle mi biblioteca, que está diseñada para resolver todos estos problemas (bueno, o al menos reducir su sufrimiento :)).


Se llama betterconf y está disponible en PyPi.


La instalación es tan simple como cualquier otra biblioteca:


 pip install betterconf 

Inicialmente, nuestra configuración se presenta como una clase con 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 defecto, la biblioteca intenta tomar valores de las variables de entorno, pero también podemos configurar esto:


 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() # ... 

De este ejemplo se deduce que podemos usar varios proveedores para recibir datos. Y a veces es conveniente, digo por experiencia personal.


Bueno, y si tenemos valores booleanos o números en las configuraciones, eventualmente aparecerán en cadenas de todos modos. Y para esto hay una solución:


 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) # ... 

Por lo tanto, todos los valores similares a los tipos booleanos (es decir, true y false se convertirán en un bool Python. El caso no distingue entre mayúsculas y minúsculas).


Escribir su lanzador también es fácil:


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

Repositorio de Github con documentación más detallada .


Resumen


Por lo tanto, llegamos a la conclusión de que almacenar la configuración en el código fuente no es bueno. Para esto, ya se han inventado varios formatos. Bueno, y te encontraste con otra biblioteca útil (como creo :)).


PS


Sí, también podría incluir Pydantic , pero creo que es demasiado ligero para tales tareas.

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


All Articles