zpp_config 2.2.0__tar.gz → 2.2.2__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.
Files changed (30) hide show
  1. {zpp_config-2.2.0/zpp_config.egg-info → zpp_config-2.2.2}/PKG-INFO +56 -56
  2. zpp_config-2.2.2/zpp_config/backend/toml.py +28 -0
  3. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/config.py +25 -3
  4. {zpp_config-2.2.0 → zpp_config-2.2.2/zpp_config.egg-info}/PKG-INFO +56 -56
  5. zpp_config-2.2.0/zpp_config/backend/toml.py +0 -13
  6. {zpp_config-2.2.0 → zpp_config-2.2.2}/LICENSE +0 -0
  7. {zpp_config-2.2.0 → zpp_config-2.2.2}/README.md +0 -0
  8. {zpp_config-2.2.0 → zpp_config-2.2.2}/setup.cfg +0 -0
  9. {zpp_config-2.2.0 → zpp_config-2.2.2}/tests/test_access.py +0 -0
  10. {zpp_config-2.2.0 → zpp_config-2.2.2}/tests/test_backends.py +0 -0
  11. {zpp_config-2.2.0 → zpp_config-2.2.2}/tests/test_merge_update_delete.py +0 -0
  12. {zpp_config-2.2.0 → zpp_config-2.2.2}/tests/test_validation.py +0 -0
  13. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/__init__.py +0 -0
  14. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/__init__.py +0 -0
  15. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/cfg.py +0 -0
  16. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/global_backend.py +0 -0
  17. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/ini.py +0 -0
  18. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/json.py +0 -0
  19. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/backend/yaml.py +0 -0
  20. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/cli.py +0 -0
  21. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/core/__init__.py +0 -0
  22. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/core/autoreload.py +0 -0
  23. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/core/logs.py +0 -0
  24. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/core/vault.py +0 -0
  25. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config/core/vault_encryption.py +0 -0
  26. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config.egg-info/SOURCES.txt +0 -0
  27. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config.egg-info/dependency_links.txt +0 -0
  28. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config.egg-info/entry_points.txt +0 -0
  29. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config.egg-info/requires.txt +0 -0
  30. {zpp_config-2.2.0 → zpp_config-2.2.2}/zpp_config.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zpp_config
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Module pour le chargement et la modification de fichier de configuration
5
5
  Home-page: https://github.com/ZephyrOff/zpp_config
6
6
  Author:
@@ -37,18 +37,18 @@ Dynamic: project-url
37
37
  Dynamic: requires-dist
38
38
  Dynamic: summary
39
39
 
40
- # Présentation
40
+ # Présentation
41
41
 
42
- Ce module fournit un système complet de **gestion de fichiers de configuration** permettant :
42
+ Ce module fournit un système complet de **gestion de fichiers de configuration** permettant :
43
43
 
44
44
  - YAML / JSON / TOML
45
45
  - Templates Jinja2 (avec variables, `env()`, `vault()`, `vault_encryption()`)
46
46
  - Chargement lazy - Auto-save - Export
47
- - Validation via schéma hiérarchique et règles globales
48
- - Accès dynamique par attributs _ou_ indexés (`cfg.db.host`)
49
- - Merge / Update sans écrasement
47
+ - Validation via schéma hiérarchique et règles globales
48
+ - Accès dynamique par attributs _ou_ indexés (`cfg.db.host`)
49
+ - Merge / Update sans écrasement
50
50
  - Auto-reload du fichier via **watchdog**
51
- - Compatibilité Vault (clé protégée et décryptage)
51
+ - Compatibilité Vault (clé protégée et décryptage)
52
52
 
53
53
  # Installation
54
54
 
@@ -66,11 +66,11 @@ from zpp_config import Config
66
66
  config = Config("config.yaml")
67
67
  ```
68
68
 
69
- Le backend est automatiquement choisi selon l’extension du fichier, mais il est possible de définir le type de configuration avec l'attribut **filetype** (yaml, json ou toml).
69
+ Le backend est automatiquement choisi selon l’extension du fichier, mais il est possible de définir le type de configuration avec l'attribut **filetype** (yaml, json ou toml).
70
70
 
71
- Lors de l'initialisation, il est également possible de définir plusieurs paramètres qui seront utile pour le render Jinja.
71
+ Lors de l'initialisation, il est également possible de définir plusieurs paramètres qui seront utile pour le render Jinja.
72
72
 
73
- **context**: défini un dictionnaire contenant les variables Jinja
73
+ **context**: défini un dictionnaire contenant les variables Jinja
74
74
  **vault_file**: emplacement du fichier vault
75
75
  **vault_keyfile**: emplacement du fichier contenant le mot de passe du vault
76
76
  **vault_password**: mot de passe du vault
@@ -90,7 +90,7 @@ config = Config(
90
90
 
91
91
  #### set_context()
92
92
 
93
- Il est possible de redéfinir le context après chargement grâce à:
93
+ Il est possible de redéfinir le context après chargement grâce à:
94
94
 
95
95
  ```python
96
96
  config.set_context({"env": "staging", "debug": True})
@@ -99,38 +99,38 @@ config.reload() # re-rend le template avec le nouveau contexte
99
99
 
100
100
  ### Chargement du fichier
101
101
 
102
- Il est possible de forcer le chargement du fichier avec la méthode **load**
102
+ Il est possible de forcer le chargement du fichier avec la méthode **load**
103
103
 
104
104
  ```python
105
105
  config.load()
106
106
  ```
107
107
 
108
- Toutefois, la configuration sera chargé automatiquement lors du premier appel de la configuration.
108
+ Toutefois, la configuration sera chargé automatiquement lors du premier appel de la configuration.
109
109
 
110
110
  #### Auto-reload
111
111
 
112
- Il est possible d'activer l'auto-reload pour permet de recharger la configuration dans le cas où le fichier de configuration change
112
+ Il est possible d'activer l'auto-reload pour permet de recharger la configuration dans le cas où le fichier de configuration change
113
113
 
114
114
  ```python
115
115
  config.autoreload(True)
116
116
  ```
117
117
 
118
- Il est possible de définir un callback a déclenché lorsque la configuration est rechargé
118
+ Il est possible de définir un callback a déclenché lorsque la configuration est rechargé
119
119
 
120
120
  ```python
121
121
  def on_reload(cfg):
122
- print("Configuration rechargée !")
122
+ print("Configuration rechargée !")
123
123
 
124
124
  config._on_reload = on_reload
125
125
  config.autoreload(True)
126
126
  ```
127
127
 
128
- On est également désactiver l'auto-reload avec:
128
+ On est également désactiver l'auto-reload avec:
129
129
  ```python
130
130
  config.stop_autoreload()
131
131
  ```
132
132
 
133
- ### Accès aux valeurs
133
+ ### Accès aux valeurs
134
134
 
135
135
  #### Par attributs
136
136
  ```python
@@ -144,13 +144,13 @@ db_host = config["db.host"]
144
144
  ```python
145
145
  db_host = config.get("db.host", default="127.0.0.1")
146
146
  ```
147
- #### Itération
147
+ #### Itération
148
148
  ```python
149
149
  for key, sub in config.db.items():
150
150
  print(key, sub.to_dict())
151
151
  ```
152
152
 
153
- #### Vérifier l’existence d’un chemin
153
+ #### Vérifier l’existence d’un chemin
154
154
  ```python
155
155
  "db.host" in config # True / False
156
156
  ```
@@ -164,7 +164,7 @@ config.set("feature.enable", True)
164
164
  config.delete("db.password")
165
165
  ```
166
166
 
167
- Toutes les modifications sont gardées en mémoire tant qu’on ne sauvegarde pas.
167
+ Toutes les modifications sont gardées en mémoire tant qu’on ne sauvegarde pas.
168
168
 
169
169
  ### Suppression des valeurs
170
170
 
@@ -178,13 +178,13 @@ del config.db.password
178
178
 
179
179
  #### Sauvegarde manuelle
180
180
 
181
- Pour sauvegarder la configuration, on utilise la méthode **save**
181
+ Pour sauvegarder la configuration, on utilise la méthode **save**
182
182
 
183
183
  ```python
184
184
  config.save()
185
185
  ```
186
186
 
187
- L'argument **filepath** permettra de définir le fichier de sortie.
187
+ L'argument **filepath** permettra de définir le fichier de sortie.
188
188
 
189
189
 
190
190
  #### Sauvegarde automatique
@@ -204,39 +204,39 @@ config.merge({"db": {"port": 3307}}, overload=True)
204
204
  ```
205
205
 
206
206
 
207
- Met à jour **une partie** :
207
+ Met à jour **une partie** :
208
208
  ```python
209
209
  config.update("db", {"user": "root"})
210
210
  ```
211
211
 
212
- - `overload=False` → ne remplace pas les valeurs existantes
213
- - `overload=True` → écrase celles existantes
212
+ - `overload=False` → ne remplace pas les valeurs existantes
213
+ - `overload=True` → écrase celles existantes
214
214
 
215
- ### Vault et données chiffrées
215
+ ### Vault et données chiffrées
216
216
 
217
- Le render Jinja fournis 2 méthodes pour récupérer des données chiffrées depuis un fichier vault ou un string vault_encryption
217
+ Le render Jinja fournis 2 méthodes pour récupérer des données chiffrées depuis un fichier vault ou un string vault_encryption
218
218
 
219
- La méthode **vault** permet de récupérer des clés depuis un vault
219
+ La méthode **vault** permet de récupérer des clés depuis un vault
220
220
 
221
221
  ```python
222
222
  password: "{{ vault('db_password') }}"
223
223
  ```
224
224
 
225
- Lors de l'initialisation de la config, il faudra forcément **vault_file** et **vault_password** ou **vault_keyfile**
225
+ Lors de l'initialisation de la config, il faudra forcément **vault_file** et **vault_password** ou **vault_keyfile**
226
226
 
227
- La méthode **vault_encryption** permet de déchiffrer des clés vault_encryption
227
+ La méthode **vault_encryption** permet de déchiffrer des clés vault_encryption
228
228
 
229
229
  ```python
230
230
  api_key: "{{ vault_encryption('encrypted_api_key') }}"
231
231
  ```
232
232
 
233
- Lors de l'initialisation de la config, il faudra forcément **vault_encryption_keyfile** ou **vault_encryption_password**
233
+ Lors de l'initialisation de la config, il faudra forcément **vault_encryption_keyfile** ou **vault_encryption_password**
234
234
 
235
- ### Méthode complémentaire Jinja
235
+ ### Méthode complémentaire Jinja
236
236
 
237
- #### Méthode env
237
+ #### Méthode env
238
238
 
239
- La méthode **env** permet de récupérer des variables d'environnements
239
+ La méthode **env** permet de récupérer des variables d'environnements
240
240
 
241
241
  ```python
242
242
  debug: "{{ env('DEBUG', False) }}"
@@ -245,7 +245,7 @@ url: "https://{{ env('DOMAIN') }}/api"
245
245
 
246
246
  ## Enregistrement Jinja (filtres / tests / globals)
247
247
 
248
- Tu peux enrichir l'environnement Jinja utilisé pour rendre le fichier de config.
248
+ Tu peux enrichir l'environnement Jinja utilisé pour rendre le fichier de config.
249
249
  #### register_filter(name: str, func)
250
250
 
251
251
  Enregistre un **filtre** Jinja utilisable dans le template.
@@ -306,10 +306,10 @@ generated_at: "{{ now() }}"
306
306
 
307
307
  ### Validation de la configuration
308
308
 
309
- #### Validation via schéma hiérarchique
309
+ #### Validation via schéma hiérarchique
310
310
 
311
- Il est possible de vérifier une configuration à partir d'un schéma.
312
- Le schéma va décrire l'architecture et les prérequis des clés définis.
311
+ Il est possible de vérifier une configuration à partir d'un schéma.
312
+ Le schéma va décrire l'architecture et les prérequis des clés définis.
313
313
 
314
314
  ```python
315
315
  schema = {
@@ -322,10 +322,10 @@ schema = {
322
322
  errors = config.validate(schema=schema)
323
323
  ```
324
324
 
325
- #### Validation via des règles
325
+ #### Validation via des règles
326
326
 
327
- Il est possible de vérifier une configuration à partir d'un schéma.
328
- Le schéma va décrire l'architecture et les prérequis des clés définis.
327
+ Il est possible de vérifier une configuration à partir d'un schéma.
328
+ Le schéma va décrire l'architecture et les prérequis des clés définis.
329
329
 
330
330
  ```python
331
331
  rules = {
@@ -335,16 +335,16 @@ rules = {
335
335
  errors = config.validate(rules=rules, strict=False)
336
336
  ```
337
337
 
338
- #### Définition possible
338
+ #### Définition possible
339
339
 
340
- |Règle|Pour|Description|
340
+ |Règle|Pour|Description|
341
341
  |---|---|---|
342
- |`_required`|Tout|Clé obligatoire|
342
+ |`_required`|Tout|Clé obligatoire|
343
343
  |`_type`|Tout|Type Python attendu|
344
- |`_min`, `_max`|Numérique|Limites|
345
- |`_len`, `_min_len`, `_max_len`|Chaînes|Taille|
346
- |`_regex`|Chaînes|Validation Regex|
347
- |`_enum`|Tout|Liste de valeurs autorisées|
344
+ |`_min`, `_max`|Numérique|Limites|
345
+ |`_len`, `_min_len`, `_max_len`|Chaînes|Taille|
346
+ |`_regex`|Chaînes|Validation Regex|
347
+ |`_enum`|Tout|Liste de valeurs autorisées|
348
348
  |`_not`|Tout|Valeur interdite|
349
349
 
350
350
  ### Export
@@ -357,37 +357,37 @@ config.export("output.toml", type="toml")
357
357
 
358
358
  ### Conversion
359
359
 
360
- Ces méthodes permettent d'obtenir des formats de sortie facilement utilisables.
360
+ Ces méthodes permettent d'obtenir des formats de sortie facilement utilisables.
361
361
 
362
362
  ### to_dict()
363
363
 
364
- Retourne le contenu du nœud courant (ou racine) sous forme de `dict` Python standard.
364
+ Retourne le contenu du nœud courant (ou racine) sous forme de `dict` Python standard.
365
365
 
366
366
  Exemple :
367
367
  ```python
368
368
  data = config.to_dict()
369
- # data est un dict prêt à être sérialisé
369
+ # data est un dict prêt à être sérialisé
370
370
  ```
371
371
 
372
372
  ### to_json(indent: int = 4)
373
373
 
374
- Retourne une chaîne JSON formatée du nœud courant :
374
+ Retourne une chaîne JSON formatée du nœud courant :
375
375
  ```python
376
376
  json_str = config.to_json()
377
377
  ```
378
378
 
379
379
  ### to_yaml(sort_keys: bool = True)
380
380
 
381
- Retourne YAML sérialisé :
381
+ Retourne YAML sérialisé :
382
382
  ```python
383
383
  yaml_str = config.to_yaml()
384
384
  ```
385
385
 
386
386
  ### to_toml()
387
387
 
388
- Retourne TOML sérialisé (si toml est disponible) :
388
+ Retourne TOML sérialisé (si toml est disponible) :
389
389
  ```python
390
390
  toml_str = config.to_toml()
391
391
  ```
392
392
 
393
- Ces méthodes n’écrivent pas sur le disque — elles renvoient des chaînes. Pour écrire un fichier, utilise `export(filepath, type=...)` ou `save()`.
393
+ Ces méthodes n’écrivent pas sur le disque — elles renvoient des chaînes. Pour écrire un fichier, utilise `export(filepath, type=...)` ou `save()`.
@@ -0,0 +1,28 @@
1
+ from tomlkit import parse, dumps
2
+ from tomlkit.items import Table, Array
3
+ from tomlkit.toml_document import TOMLDocument
4
+ from .global_backend import ConfigBackend
5
+
6
+ #Convertisseur pour transformer les objets TOML en dictionnaire
7
+ def tomlkit_to_dict(obj):
8
+ if isinstance(obj, (TOMLDocument, Table)):
9
+ return {k: tomlkit_to_dict(v) for k, v in obj.items()}
10
+ elif isinstance(obj, Array):
11
+ return [tomlkit_to_dict(v) for v in obj]
12
+ else:
13
+ return obj
14
+
15
+ class TomlBackend(ConfigBackend):
16
+ """NOUVEAU: Backend pour les fichiers TOML."""
17
+ def load(self, filename):
18
+ doc = parse(filename.read_text())
19
+ return tomlkit_to_dict(doc)
20
+
21
+ def load_data(self, rendered):
22
+ if not rendered.strip():
23
+ return {}
24
+ doc = parse(rendered)
25
+ return tomlkit_to_dict(doc)
26
+
27
+ def save(self, filename, data):
28
+ filename.write_text(dumps(data))
@@ -1,10 +1,32 @@
1
1
  import impmagic
2
-
2
+ from jinja2 import FileSystemLoader
3
+ from pathlib import Path
3
4
 
4
5
  class ValidationError(Exception):
5
6
  pass
6
7
 
7
8
 
9
+ class SafeFileSystemLoader(FileSystemLoader):
10
+ def get_source(self, environment, template):
11
+ try:
12
+ return super().get_source(environment, template)
13
+
14
+ except UnicodeDecodeError:
15
+ # Reconstruction du chemin réel
16
+ for searchpath in self.searchpath:
17
+ filename = Path(searchpath) / template
18
+ if filename.exists():
19
+ break
20
+ else:
21
+ raise
22
+
23
+ # Fallback Windows
24
+ with open(filename, "r", encoding="cp1252") as f:
25
+ source = f.read()
26
+
27
+ return source, str(filename), lambda: False
28
+
29
+
8
30
  ## Méthode Jinja2
9
31
  @impmagic.loader(
10
32
  {'module':'os'},
@@ -338,7 +360,7 @@ class Config(ConfigNode):
338
360
  {'module':'zpp_config.backend.ini', 'submodule': ['IniBackend']},
339
361
  {'module':'zpp_config.backend.cfg', 'submodule': ['CfgBackend']},
340
362
  {'module':'pathlib', 'submodule': ['Path']},
341
- {'module':'jinja2', 'submodule': ['Environment', 'FileSystemLoader']},
363
+ {'module':'jinja2', 'submodule': ['Environment']},
342
364
  {'module':'zpp_config.core.vault_encryption', 'submodule': ['vault_decrypt']},
343
365
  )
344
366
  def __init__(self, filename, filetype=None, context=None, vault_file=None, vault_keyfile=None, vault_password=None, vault_encryption_keyfile=None, vault_encryption_password=None):
@@ -358,7 +380,7 @@ class Config(ConfigNode):
358
380
 
359
381
  # Environment Jinja2 personnalisable
360
382
  self._env = Environment(
361
- loader=FileSystemLoader(self._filename.parent),
383
+ loader=SafeFileSystemLoader(self._filename.parent),
362
384
  autoescape=False
363
385
  )
364
386
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zpp_config
3
- Version: 2.2.0
3
+ Version: 2.2.2
4
4
  Summary: Module pour le chargement et la modification de fichier de configuration
5
5
  Home-page: https://github.com/ZephyrOff/zpp_config
6
6
  Author:
@@ -37,18 +37,18 @@ Dynamic: project-url
37
37
  Dynamic: requires-dist
38
38
  Dynamic: summary
39
39
 
40
- # Présentation
40
+ # Présentation
41
41
 
42
- Ce module fournit un système complet de **gestion de fichiers de configuration** permettant :
42
+ Ce module fournit un système complet de **gestion de fichiers de configuration** permettant :
43
43
 
44
44
  - YAML / JSON / TOML
45
45
  - Templates Jinja2 (avec variables, `env()`, `vault()`, `vault_encryption()`)
46
46
  - Chargement lazy - Auto-save - Export
47
- - Validation via schéma hiérarchique et règles globales
48
- - Accès dynamique par attributs _ou_ indexés (`cfg.db.host`)
49
- - Merge / Update sans écrasement
47
+ - Validation via schéma hiérarchique et règles globales
48
+ - Accès dynamique par attributs _ou_ indexés (`cfg.db.host`)
49
+ - Merge / Update sans écrasement
50
50
  - Auto-reload du fichier via **watchdog**
51
- - Compatibilité Vault (clé protégée et décryptage)
51
+ - Compatibilité Vault (clé protégée et décryptage)
52
52
 
53
53
  # Installation
54
54
 
@@ -66,11 +66,11 @@ from zpp_config import Config
66
66
  config = Config("config.yaml")
67
67
  ```
68
68
 
69
- Le backend est automatiquement choisi selon l’extension du fichier, mais il est possible de définir le type de configuration avec l'attribut **filetype** (yaml, json ou toml).
69
+ Le backend est automatiquement choisi selon l’extension du fichier, mais il est possible de définir le type de configuration avec l'attribut **filetype** (yaml, json ou toml).
70
70
 
71
- Lors de l'initialisation, il est également possible de définir plusieurs paramètres qui seront utile pour le render Jinja.
71
+ Lors de l'initialisation, il est également possible de définir plusieurs paramètres qui seront utile pour le render Jinja.
72
72
 
73
- **context**: défini un dictionnaire contenant les variables Jinja
73
+ **context**: défini un dictionnaire contenant les variables Jinja
74
74
  **vault_file**: emplacement du fichier vault
75
75
  **vault_keyfile**: emplacement du fichier contenant le mot de passe du vault
76
76
  **vault_password**: mot de passe du vault
@@ -90,7 +90,7 @@ config = Config(
90
90
 
91
91
  #### set_context()
92
92
 
93
- Il est possible de redéfinir le context après chargement grâce à:
93
+ Il est possible de redéfinir le context après chargement grâce à:
94
94
 
95
95
  ```python
96
96
  config.set_context({"env": "staging", "debug": True})
@@ -99,38 +99,38 @@ config.reload() # re-rend le template avec le nouveau contexte
99
99
 
100
100
  ### Chargement du fichier
101
101
 
102
- Il est possible de forcer le chargement du fichier avec la méthode **load**
102
+ Il est possible de forcer le chargement du fichier avec la méthode **load**
103
103
 
104
104
  ```python
105
105
  config.load()
106
106
  ```
107
107
 
108
- Toutefois, la configuration sera chargé automatiquement lors du premier appel de la configuration.
108
+ Toutefois, la configuration sera chargé automatiquement lors du premier appel de la configuration.
109
109
 
110
110
  #### Auto-reload
111
111
 
112
- Il est possible d'activer l'auto-reload pour permet de recharger la configuration dans le cas où le fichier de configuration change
112
+ Il est possible d'activer l'auto-reload pour permet de recharger la configuration dans le cas où le fichier de configuration change
113
113
 
114
114
  ```python
115
115
  config.autoreload(True)
116
116
  ```
117
117
 
118
- Il est possible de définir un callback a déclenché lorsque la configuration est rechargé
118
+ Il est possible de définir un callback a déclenché lorsque la configuration est rechargé
119
119
 
120
120
  ```python
121
121
  def on_reload(cfg):
122
- print("Configuration rechargée !")
122
+ print("Configuration rechargée !")
123
123
 
124
124
  config._on_reload = on_reload
125
125
  config.autoreload(True)
126
126
  ```
127
127
 
128
- On est également désactiver l'auto-reload avec:
128
+ On est également désactiver l'auto-reload avec:
129
129
  ```python
130
130
  config.stop_autoreload()
131
131
  ```
132
132
 
133
- ### Accès aux valeurs
133
+ ### Accès aux valeurs
134
134
 
135
135
  #### Par attributs
136
136
  ```python
@@ -144,13 +144,13 @@ db_host = config["db.host"]
144
144
  ```python
145
145
  db_host = config.get("db.host", default="127.0.0.1")
146
146
  ```
147
- #### Itération
147
+ #### Itération
148
148
  ```python
149
149
  for key, sub in config.db.items():
150
150
  print(key, sub.to_dict())
151
151
  ```
152
152
 
153
- #### Vérifier l’existence d’un chemin
153
+ #### Vérifier l’existence d’un chemin
154
154
  ```python
155
155
  "db.host" in config # True / False
156
156
  ```
@@ -164,7 +164,7 @@ config.set("feature.enable", True)
164
164
  config.delete("db.password")
165
165
  ```
166
166
 
167
- Toutes les modifications sont gardées en mémoire tant qu’on ne sauvegarde pas.
167
+ Toutes les modifications sont gardées en mémoire tant qu’on ne sauvegarde pas.
168
168
 
169
169
  ### Suppression des valeurs
170
170
 
@@ -178,13 +178,13 @@ del config.db.password
178
178
 
179
179
  #### Sauvegarde manuelle
180
180
 
181
- Pour sauvegarder la configuration, on utilise la méthode **save**
181
+ Pour sauvegarder la configuration, on utilise la méthode **save**
182
182
 
183
183
  ```python
184
184
  config.save()
185
185
  ```
186
186
 
187
- L'argument **filepath** permettra de définir le fichier de sortie.
187
+ L'argument **filepath** permettra de définir le fichier de sortie.
188
188
 
189
189
 
190
190
  #### Sauvegarde automatique
@@ -204,39 +204,39 @@ config.merge({"db": {"port": 3307}}, overload=True)
204
204
  ```
205
205
 
206
206
 
207
- Met à jour **une partie** :
207
+ Met à jour **une partie** :
208
208
  ```python
209
209
  config.update("db", {"user": "root"})
210
210
  ```
211
211
 
212
- - `overload=False` → ne remplace pas les valeurs existantes
213
- - `overload=True` → écrase celles existantes
212
+ - `overload=False` → ne remplace pas les valeurs existantes
213
+ - `overload=True` → écrase celles existantes
214
214
 
215
- ### Vault et données chiffrées
215
+ ### Vault et données chiffrées
216
216
 
217
- Le render Jinja fournis 2 méthodes pour récupérer des données chiffrées depuis un fichier vault ou un string vault_encryption
217
+ Le render Jinja fournis 2 méthodes pour récupérer des données chiffrées depuis un fichier vault ou un string vault_encryption
218
218
 
219
- La méthode **vault** permet de récupérer des clés depuis un vault
219
+ La méthode **vault** permet de récupérer des clés depuis un vault
220
220
 
221
221
  ```python
222
222
  password: "{{ vault('db_password') }}"
223
223
  ```
224
224
 
225
- Lors de l'initialisation de la config, il faudra forcément **vault_file** et **vault_password** ou **vault_keyfile**
225
+ Lors de l'initialisation de la config, il faudra forcément **vault_file** et **vault_password** ou **vault_keyfile**
226
226
 
227
- La méthode **vault_encryption** permet de déchiffrer des clés vault_encryption
227
+ La méthode **vault_encryption** permet de déchiffrer des clés vault_encryption
228
228
 
229
229
  ```python
230
230
  api_key: "{{ vault_encryption('encrypted_api_key') }}"
231
231
  ```
232
232
 
233
- Lors de l'initialisation de la config, il faudra forcément **vault_encryption_keyfile** ou **vault_encryption_password**
233
+ Lors de l'initialisation de la config, il faudra forcément **vault_encryption_keyfile** ou **vault_encryption_password**
234
234
 
235
- ### Méthode complémentaire Jinja
235
+ ### Méthode complémentaire Jinja
236
236
 
237
- #### Méthode env
237
+ #### Méthode env
238
238
 
239
- La méthode **env** permet de récupérer des variables d'environnements
239
+ La méthode **env** permet de récupérer des variables d'environnements
240
240
 
241
241
  ```python
242
242
  debug: "{{ env('DEBUG', False) }}"
@@ -245,7 +245,7 @@ url: "https://{{ env('DOMAIN') }}/api"
245
245
 
246
246
  ## Enregistrement Jinja (filtres / tests / globals)
247
247
 
248
- Tu peux enrichir l'environnement Jinja utilisé pour rendre le fichier de config.
248
+ Tu peux enrichir l'environnement Jinja utilisé pour rendre le fichier de config.
249
249
  #### register_filter(name: str, func)
250
250
 
251
251
  Enregistre un **filtre** Jinja utilisable dans le template.
@@ -306,10 +306,10 @@ generated_at: "{{ now() }}"
306
306
 
307
307
  ### Validation de la configuration
308
308
 
309
- #### Validation via schéma hiérarchique
309
+ #### Validation via schéma hiérarchique
310
310
 
311
- Il est possible de vérifier une configuration à partir d'un schéma.
312
- Le schéma va décrire l'architecture et les prérequis des clés définis.
311
+ Il est possible de vérifier une configuration à partir d'un schéma.
312
+ Le schéma va décrire l'architecture et les prérequis des clés définis.
313
313
 
314
314
  ```python
315
315
  schema = {
@@ -322,10 +322,10 @@ schema = {
322
322
  errors = config.validate(schema=schema)
323
323
  ```
324
324
 
325
- #### Validation via des règles
325
+ #### Validation via des règles
326
326
 
327
- Il est possible de vérifier une configuration à partir d'un schéma.
328
- Le schéma va décrire l'architecture et les prérequis des clés définis.
327
+ Il est possible de vérifier une configuration à partir d'un schéma.
328
+ Le schéma va décrire l'architecture et les prérequis des clés définis.
329
329
 
330
330
  ```python
331
331
  rules = {
@@ -335,16 +335,16 @@ rules = {
335
335
  errors = config.validate(rules=rules, strict=False)
336
336
  ```
337
337
 
338
- #### Définition possible
338
+ #### Définition possible
339
339
 
340
- |Règle|Pour|Description|
340
+ |Règle|Pour|Description|
341
341
  |---|---|---|
342
- |`_required`|Tout|Clé obligatoire|
342
+ |`_required`|Tout|Clé obligatoire|
343
343
  |`_type`|Tout|Type Python attendu|
344
- |`_min`, `_max`|Numérique|Limites|
345
- |`_len`, `_min_len`, `_max_len`|Chaînes|Taille|
346
- |`_regex`|Chaînes|Validation Regex|
347
- |`_enum`|Tout|Liste de valeurs autorisées|
344
+ |`_min`, `_max`|Numérique|Limites|
345
+ |`_len`, `_min_len`, `_max_len`|Chaînes|Taille|
346
+ |`_regex`|Chaînes|Validation Regex|
347
+ |`_enum`|Tout|Liste de valeurs autorisées|
348
348
  |`_not`|Tout|Valeur interdite|
349
349
 
350
350
  ### Export
@@ -357,37 +357,37 @@ config.export("output.toml", type="toml")
357
357
 
358
358
  ### Conversion
359
359
 
360
- Ces méthodes permettent d'obtenir des formats de sortie facilement utilisables.
360
+ Ces méthodes permettent d'obtenir des formats de sortie facilement utilisables.
361
361
 
362
362
  ### to_dict()
363
363
 
364
- Retourne le contenu du nœud courant (ou racine) sous forme de `dict` Python standard.
364
+ Retourne le contenu du nœud courant (ou racine) sous forme de `dict` Python standard.
365
365
 
366
366
  Exemple :
367
367
  ```python
368
368
  data = config.to_dict()
369
- # data est un dict prêt à être sérialisé
369
+ # data est un dict prêt à être sérialisé
370
370
  ```
371
371
 
372
372
  ### to_json(indent: int = 4)
373
373
 
374
- Retourne une chaîne JSON formatée du nœud courant :
374
+ Retourne une chaîne JSON formatée du nœud courant :
375
375
  ```python
376
376
  json_str = config.to_json()
377
377
  ```
378
378
 
379
379
  ### to_yaml(sort_keys: bool = True)
380
380
 
381
- Retourne YAML sérialisé :
381
+ Retourne YAML sérialisé :
382
382
  ```python
383
383
  yaml_str = config.to_yaml()
384
384
  ```
385
385
 
386
386
  ### to_toml()
387
387
 
388
- Retourne TOML sérialisé (si toml est disponible) :
388
+ Retourne TOML sérialisé (si toml est disponible) :
389
389
  ```python
390
390
  toml_str = config.to_toml()
391
391
  ```
392
392
 
393
- Ces méthodes n’écrivent pas sur le disque — elles renvoient des chaînes. Pour écrire un fichier, utilise `export(filepath, type=...)` ou `save()`.
393
+ Ces méthodes n’écrivent pas sur le disque — elles renvoient des chaînes. Pour écrire un fichier, utilise `export(filepath, type=...)` ou `save()`.
@@ -1,13 +0,0 @@
1
- import toml
2
- from .global_backend import ConfigBackend
3
-
4
- class TomlBackend(ConfigBackend):
5
- """NOUVEAU: Backend pour les fichiers TOML."""
6
- def load(self, filename):
7
- return toml.loads(filename.read_text())
8
-
9
- def load_data(self, rendered):
10
- return toml.loads(rendered) if rendered.strip() else {}
11
-
12
- def save(self, filename, data):
13
- filename.write_text(toml.dumps(data))
File without changes
File without changes
File without changes
File without changes