corio 2.2.1__tar.gz → 2.2.2a0__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 (159) hide show
  1. {corio-2.2.1 → corio-2.2.2a0}/PKG-INFO +7 -1
  2. {corio-2.2.1 → corio-2.2.2a0}/corio/entrypoint.py +2 -2
  3. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/releaser.py +138 -0
  4. {corio-2.2.1 → corio-2.2.2a0}/corio/path/path.py +9 -0
  5. {corio-2.2.1 → corio-2.2.2a0}/corio/pyproject.package.toml +9 -9
  6. corio-2.2.2a0/corio/tests/test_caching.py +39 -0
  7. corio-2.2.2a0/corio/tests/test_datatype.py +24 -0
  8. corio-2.2.2a0/corio/tests/test_encrypt.py +43 -0
  9. {corio-2.2.1 → corio-2.2.2a0}/corio/tests/test_path.py +13 -8
  10. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/PKG-INFO +7 -1
  11. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/SOURCES.txt +5 -3
  12. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/requires.txt +6 -0
  13. {corio-2.2.1 → corio-2.2.2a0}/pyproject.toml +9 -9
  14. corio-2.2.1/corio/tests/test_datatype.py +0 -33
  15. {corio-2.2.1 → corio-2.2.2a0}/LICENSE +0 -0
  16. {corio-2.2.1 → corio-2.2.2a0}/README.md +0 -0
  17. {corio-2.2.1 → corio-2.2.2a0}/corio/__init__.py +0 -0
  18. {corio-2.2.1 → corio-2.2.2a0}/corio/ai/__init__.py +0 -0
  19. {corio-2.2.1 → corio-2.2.2a0}/corio/ai/agentic.py +0 -0
  20. {corio-2.2.1 → corio-2.2.2a0}/corio/ai/infer.py +0 -0
  21. {corio-2.2.1 → corio-2.2.2a0}/corio/aio.py +0 -0
  22. {corio-2.2.1 → corio-2.2.2a0}/corio/api.py +0 -0
  23. {corio-2.2.1 → corio-2.2.2a0}/corio/augmentation.py +0 -0
  24. {corio-2.2.1 → corio-2.2.2a0}/corio/av.py +0 -0
  25. {corio-2.2.1 → corio-2.2.2a0}/corio/caching.py +0 -0
  26. {corio-2.2.1 → corio-2.2.2a0}/corio/constants.py +0 -0
  27. {corio-2.2.1 → corio-2.2.2a0}/corio/context.py +0 -0
  28. {corio-2.2.1 → corio-2.2.2a0}/corio/dataclass.py +0 -0
  29. {corio-2.2.1 → corio-2.2.2a0}/corio/datatype.py +0 -0
  30. {corio-2.2.1 → corio-2.2.2a0}/corio/db/__init__.py +0 -0
  31. {corio-2.2.1 → corio-2.2.2a0}/corio/db/document.py +0 -0
  32. {corio-2.2.1 → corio-2.2.2a0}/corio/debug.py +0 -0
  33. {corio-2.2.1 → corio-2.2.2a0}/corio/dm.py +0 -0
  34. {corio-2.2.1 → corio-2.2.2a0}/corio/dns/__init__.py +0 -0
  35. {corio-2.2.1 → corio-2.2.2a0}/corio/dns/client.py +0 -0
  36. {corio-2.2.1 → corio-2.2.2a0}/corio/dns/dm.py +0 -0
  37. {corio-2.2.1 → corio-2.2.2a0}/corio/dns/proxy.py +0 -0
  38. {corio-2.2.1 → corio-2.2.2a0}/corio/dns/server.py +0 -0
  39. {corio-2.2.1 → corio-2.2.2a0}/corio/docker/__init__.py +0 -0
  40. {corio-2.2.1 → corio-2.2.2a0}/corio/dt.py +0 -0
  41. {corio-2.2.1 → corio-2.2.2a0}/corio/encrypt.py +0 -0
  42. {corio-2.2.1 → corio-2.2.2a0}/corio/env.py +0 -0
  43. {corio-2.2.1 → corio-2.2.2a0}/corio/function.py +0 -0
  44. {corio-2.2.1 → corio-2.2.2a0}/corio/google_api.py +0 -0
  45. {corio-2.2.1 → corio-2.2.2a0}/corio/ha/__init__.py +0 -0
  46. {corio-2.2.1 → corio-2.2.2a0}/corio/ha/constants.py +0 -0
  47. {corio-2.2.1 → corio-2.2.2a0}/corio/ha/core.py +0 -0
  48. {corio-2.2.1 → corio-2.2.2a0}/corio/ha/supervisor.py +0 -0
  49. {corio-2.2.1 → corio-2.2.2a0}/corio/ha/utils.py +0 -0
  50. {corio-2.2.1 → corio-2.2.2a0}/corio/hash.py +0 -0
  51. {corio-2.2.1 → corio-2.2.2a0}/corio/hfh.py +0 -0
  52. {corio-2.2.1 → corio-2.2.2a0}/corio/hook.py +0 -0
  53. {corio-2.2.1 → corio-2.2.2a0}/corio/https.py +0 -0
  54. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/__init__.py +0 -0
  55. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/api.py +0 -0
  56. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/incrementor_pyproject.py +0 -0
  57. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/project.py +0 -0
  58. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/repository.py +0 -0
  59. {corio-2.2.1 → corio-2.2.2a0}/corio/infra/stack.py +0 -0
  60. {corio-2.2.1 → corio-2.2.2a0}/corio/inherit.py +0 -0
  61. {corio-2.2.1 → corio-2.2.2a0}/corio/inspection.py +0 -0
  62. {corio-2.2.1 → corio-2.2.2a0}/corio/interface/__init__.py +0 -0
  63. {corio-2.2.1 → corio-2.2.2a0}/corio/interface/context.py +0 -0
  64. {corio-2.2.1 → corio-2.2.2a0}/corio/interface/controls.py +0 -0
  65. {corio-2.2.1 → corio-2.2.2a0}/corio/interface/interface.py +0 -0
  66. {corio-2.2.1 → corio-2.2.2a0}/corio/iterator.py +0 -0
  67. {corio-2.2.1 → corio-2.2.2a0}/corio/jsn.py +0 -0
  68. {corio-2.2.1 → corio-2.2.2a0}/corio/json_fix.py +0 -0
  69. {corio-2.2.1 → corio-2.2.2a0}/corio/logs.py +0 -0
  70. {corio-2.2.1 → corio-2.2.2a0}/corio/markup.py +0 -0
  71. {corio-2.2.1 → corio-2.2.2a0}/corio/merging.py +0 -0
  72. {corio-2.2.1 → corio-2.2.2a0}/corio/metric.py +0 -0
  73. {corio-2.2.1 → corio-2.2.2a0}/corio/mqtt.py +0 -0
  74. {corio-2.2.1 → corio-2.2.2a0}/corio/name.py +0 -0
  75. {corio-2.2.1 → corio-2.2.2a0}/corio/net.py +0 -0
  76. {corio-2.2.1 → corio-2.2.2a0}/corio/netrc.py +0 -0
  77. {corio-2.2.1 → corio-2.2.2a0}/corio/openai.py +0 -0
  78. {corio-2.2.1 → corio-2.2.2a0}/corio/parallel.py +0 -0
  79. {corio-2.2.1 → corio-2.2.2a0}/corio/path/__init__.py +0 -0
  80. {corio-2.2.1 → corio-2.2.2a0}/corio/path/app.py +0 -0
  81. {corio-2.2.1 → corio-2.2.2a0}/corio/path/type.py +0 -0
  82. {corio-2.2.1 → corio-2.2.2a0}/corio/paths.py +0 -0
  83. {corio-2.2.1 → corio-2.2.2a0}/corio/patterns.py +0 -0
  84. {corio-2.2.1 → corio-2.2.2a0}/corio/pdf.py +0 -0
  85. {corio-2.2.1 → corio-2.2.2a0}/corio/plat.py +0 -0
  86. {corio-2.2.1 → corio-2.2.2a0}/corio/process.py +0 -0
  87. {corio-2.2.1 → corio-2.2.2a0}/corio/profiling.py +0 -0
  88. {corio-2.2.1 → corio-2.2.2a0}/corio/rand.py +0 -0
  89. /corio-2.2.1/corio/secrets.py → /corio-2.2.2a0/corio/sec.py +0 -0
  90. {corio-2.2.1 → corio-2.2.2a0}/corio/semantic.py +0 -0
  91. {corio-2.2.1 → corio-2.2.2a0}/corio/sets.py +0 -0
  92. {corio-2.2.1 → corio-2.2.2a0}/corio/setup/__init__.py +0 -0
  93. {corio-2.2.1 → corio-2.2.2a0}/corio/spaces.py +0 -0
  94. {corio-2.2.1 → corio-2.2.2a0}/corio/strings.py +0 -0
  95. {corio-2.2.1 → corio-2.2.2a0}/corio/tabular.py +0 -0
  96. {corio-2.2.1 → corio-2.2.2a0}/corio/tests/__init__.py +0 -0
  97. {corio-2.2.1 → corio-2.2.2a0}/corio/tests/conftest.py +0 -0
  98. {corio-2.2.1 → corio-2.2.2a0}/corio/tests/helpers.py +0 -0
  99. /corio-2.2.1/corio/tests/test_environment.py → /corio-2.2.2a0/corio/tests/test_env.py +0 -0
  100. /corio-2.2.1/corio/tests/test_json.py → /corio-2.2.2a0/corio/tests/test_jsn.py +0 -0
  101. {corio-2.2.1 → corio-2.2.2a0}/corio/tests/test_yaml.py +0 -0
  102. {corio-2.2.1 → corio-2.2.2a0}/corio/tokenization.py +0 -0
  103. {corio-2.2.1 → corio-2.2.2a0}/corio/toml.py +0 -0
  104. {corio-2.2.1 → corio-2.2.2a0}/corio/tools.py +0 -0
  105. {corio-2.2.1 → corio-2.2.2a0}/corio/unicode.py +0 -0
  106. {corio-2.2.1 → corio-2.2.2a0}/corio/version/__init__.py +0 -0
  107. {corio-2.2.1 → corio-2.2.2a0}/corio/version/version.py +0 -0
  108. {corio-2.2.1 → corio-2.2.2a0}/corio/webhook.py +0 -0
  109. {corio-2.2.1 → corio-2.2.2a0}/corio/yml.py +0 -0
  110. {corio-2.2.1 → corio-2.2.2a0}/corio/youtube.py +0 -0
  111. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/dependency_links.txt +0 -0
  112. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/entry_points.txt +0 -0
  113. {corio-2.2.1 → corio-2.2.2a0}/corio.egg-info/top_level.txt +0 -0
  114. {corio-2.2.1 → corio-2.2.2a0}/scripts/add-service +0 -0
  115. {corio-2.2.1 → corio-2.2.2a0}/scripts/add-user-path +0 -0
  116. {corio-2.2.1 → corio-2.2.2a0}/scripts/add-ve-shell +0 -0
  117. {corio-2.2.1 → corio-2.2.2a0}/scripts/apt-essentials +0 -0
  118. {corio-2.2.1 → corio-2.2.2a0}/scripts/apt-headless +0 -0
  119. {corio-2.2.1 → corio-2.2.2a0}/scripts/auth-token +0 -0
  120. {corio-2.2.1 → corio-2.2.2a0}/scripts/compose-update +0 -0
  121. {corio-2.2.1 → corio-2.2.2a0}/scripts/compress-dir +0 -0
  122. {corio-2.2.1 → corio-2.2.2a0}/scripts/cru +0 -0
  123. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-build-bases +0 -0
  124. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-build-bases-dev +0 -0
  125. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-install-deps +0 -0
  126. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-install-prod +0 -0
  127. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-prune +0 -0
  128. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-sandbox +0 -0
  129. {corio-2.2.1 → corio-2.2.2a0}/scripts/docker-sandbox-init +0 -0
  130. {corio-2.2.1 → corio-2.2.2a0}/scripts/docs-deploy +0 -0
  131. {corio-2.2.1 → corio-2.2.2a0}/scripts/download +0 -0
  132. {corio-2.2.1 → corio-2.2.2a0}/scripts/encrypt-secrets +0 -0
  133. {corio-2.2.1 → corio-2.2.2a0}/scripts/fmtr-test-script +0 -0
  134. {corio-2.2.1 → corio-2.2.2a0}/scripts/git-clone +0 -0
  135. {corio-2.2.1 → corio-2.2.2a0}/scripts/ha-addon-launch +0 -0
  136. {corio-2.2.1 → corio-2.2.2a0}/scripts/infra +0 -0
  137. {corio-2.2.1 → corio-2.2.2a0}/scripts/infra-sync +0 -0
  138. {corio-2.2.1 → corio-2.2.2a0}/scripts/install-browser +0 -0
  139. {corio-2.2.1 → corio-2.2.2a0}/scripts/install-docker +0 -0
  140. {corio-2.2.1 → corio-2.2.2a0}/scripts/install-ts +0 -0
  141. {corio-2.2.1 → corio-2.2.2a0}/scripts/install-ys +0 -0
  142. {corio-2.2.1 → corio-2.2.2a0}/scripts/mirror-dir +0 -0
  143. {corio-2.2.1 → corio-2.2.2a0}/scripts/opt-dev-init +0 -0
  144. {corio-2.2.1 → corio-2.2.2a0}/scripts/parse-args +0 -0
  145. {corio-2.2.1 → corio-2.2.2a0}/scripts/pypi-check +0 -0
  146. {corio-2.2.1 → corio-2.2.2a0}/scripts/pypi-reserve +0 -0
  147. {corio-2.2.1 → corio-2.2.2a0}/scripts/run-script +0 -0
  148. {corio-2.2.1 → corio-2.2.2a0}/scripts/set-password +0 -0
  149. {corio-2.2.1 → corio-2.2.2a0}/scripts/set-secure-path +0 -0
  150. {corio-2.2.1 → corio-2.2.2a0}/scripts/set-user-sudo +0 -0
  151. {corio-2.2.1 → corio-2.2.2a0}/scripts/snips-install +0 -0
  152. {corio-2.2.1 → corio-2.2.2a0}/scripts/ssh-auth +0 -0
  153. {corio-2.2.1 → corio-2.2.2a0}/scripts/ssh-serve +0 -0
  154. {corio-2.2.1 → corio-2.2.2a0}/scripts/tasmota-config +0 -0
  155. {corio-2.2.1 → corio-2.2.2a0}/scripts/tasmota-flash +0 -0
  156. {corio-2.2.1 → corio-2.2.2a0}/scripts/tasmota-terminal +0 -0
  157. {corio-2.2.1 → corio-2.2.2a0}/scripts/vlc-tn +0 -0
  158. {corio-2.2.1 → corio-2.2.2a0}/scripts/vm-launch +0 -0
  159. {corio-2.2.1 → corio-2.2.2a0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.2.1
3
+ Version: 2.2.2a0
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Author-email: Frontmatter AI <innovative.fowler@mask.pro.fmtr.dev>
6
6
  License-Expression: Apache-2.0
@@ -39,7 +39,10 @@ Requires-Dist: logfire[fastapi]; extra == "dev"
39
39
  Requires-Dist: tomlkit; extra == "dev"
40
40
  Requires-Dist: pyrage; extra == "dev"
41
41
  Requires-Dist: dotenv; extra == "dev"
42
+ Requires-Dist: pytest; extra == "dev"
43
+ Requires-Dist: pytest-cov; extra == "dev"
42
44
  Provides-Extra: test
45
+ Requires-Dist: pytest; extra == "test"
43
46
  Requires-Dist: pytest-cov; extra == "test"
44
47
  Provides-Extra: yaml
45
48
  Requires-Dist: yamlscript; extra == "yaml"
@@ -255,6 +258,8 @@ Requires-Dist: logfire[fastapi]; extra == "infra"
255
258
  Requires-Dist: tomlkit; extra == "infra"
256
259
  Requires-Dist: pyrage; extra == "infra"
257
260
  Requires-Dist: dotenv; extra == "infra"
261
+ Requires-Dist: pytest; extra == "infra"
262
+ Requires-Dist: pytest-cov; extra == "infra"
258
263
  Provides-Extra: vcs
259
264
  Requires-Dist: pygit2; extra == "vcs"
260
265
  Provides-Extra: tasmota
@@ -313,6 +318,7 @@ Requires-Dist: logfire[fastapi]; extra == "all"
313
318
  Requires-Dist: tomlkit; extra == "all"
314
319
  Requires-Dist: pyrage; extra == "all"
315
320
  Requires-Dist: dotenv; extra == "all"
321
+ Requires-Dist: pytest; extra == "all"
316
322
  Requires-Dist: pytest-cov; extra == "all"
317
323
  Requires-Dist: dask[bag]; extra == "all"
318
324
  Requires-Dist: distributed; extra == "all"
@@ -1,7 +1,7 @@
1
1
  from pydantic_settings import CliSubCommand
2
2
 
3
3
  from corio import dm
4
- from corio import secrets
4
+ from corio import sec
5
5
  from corio import sets
6
6
 
7
7
 
@@ -78,7 +78,7 @@ class RemoteDebugTest(dm.Base):
78
78
 
79
79
 
80
80
  class Cli(sets.Base, cli_parse_args=True):
81
- secrets: CliSubCommand[secrets.Cli]
81
+ secrets: CliSubCommand[sec.Cli]
82
82
  docs: CliSubCommand[Docs]
83
83
  pyproject: CliSubCommand[Pyproject]
84
84
  ep_test: CliSubCommand[EpTest]
@@ -1,4 +1,5 @@
1
1
  import shutil
2
+ import subprocess
2
3
  from functools import cached_property
3
4
 
4
5
  import build
@@ -44,6 +45,13 @@ class Releaser(Inherit[Project]):
44
45
 
45
46
  from corio.infra.stack import ProductionPrivate, ProductionPublic
46
47
 
48
+ is_passed = self.tester.run()
49
+ if not is_passed:
50
+ if self.versions.is_pre:
51
+ logger.warning(f"Tests failed, but release is pre-release ({self.version.prerelease}). Continuing.")
52
+ else:
53
+ raise RuntimeError("Tests failed. Aborting release.")
54
+
47
55
  if increment:
48
56
  self.repo.fetch()
49
57
  self.increment()
@@ -174,6 +182,10 @@ class Releaser(Inherit[Project]):
174
182
 
175
183
  return releases
176
184
 
185
+ @cached_property
186
+ def tester(self):
187
+ return Tester(self)
188
+
177
189
  def release(self):
178
190
  for release in self.releases:
179
191
  release.release()
@@ -200,6 +212,9 @@ class Incrementor(Inherit[Releaser]):
200
212
  raise NotImplementedError
201
213
 
202
214
 
215
+
216
+
217
+
203
218
  class IncrementorHomeAssistantAddon(Incrementor):
204
219
  DESC = 'Home Assistant Add-On config file'
205
220
 
@@ -529,3 +544,126 @@ class ReleaseDocumentation(Release):
529
544
 
530
545
  with self.paths.repo.chdir:
531
546
  self.deploy()
547
+
548
+
549
+ class Tester(Inherit[Releaser]):
550
+ TEST_FILENAME_PREFIX = "test_"
551
+ TEST_FILENAME_SUFFIX = ".py"
552
+ TOX_REQUIRES = ["tox>=4.22", "tox-uv>=1"]
553
+
554
+ @cached_property
555
+ def path_config_dir(self) -> Path:
556
+ return Path.temp() / f"{self.name}-tox"
557
+
558
+ @cached_property
559
+ def path_config(self) -> Path:
560
+ return self.path_config_dir / "tox.toml"
561
+
562
+ @cached_property
563
+ def dependencies(self) -> dict[str, list[str]]:
564
+ data = self.paths.pyproject_repo.read_toml()
565
+ table = data.get("tool", {}).get("corio", {}).get("dependencies", {})
566
+ dependencies = {
567
+ str(key): [str(value) for value in values]
568
+ for key, values in table.items()
569
+ if isinstance(values, list)
570
+ }
571
+ return dependencies
572
+
573
+ @cached_property
574
+ def modules(self) -> list[str]:
575
+ if not self.paths.tests.exists():
576
+ return []
577
+
578
+ modules = []
579
+ for path in sorted(self.paths.tests.glob(f"{self.TEST_FILENAME_PREFIX}*{self.TEST_FILENAME_SUFFIX}")):
580
+ module = path.stem.removeprefix(self.TEST_FILENAME_PREFIX)
581
+ if module:
582
+ modules.append(module)
583
+ return modules
584
+
585
+ @cached_property
586
+ def envs(self) -> dict[str, dict]:
587
+ envs = {}
588
+ extras_available = set(self.dependencies.keys())
589
+
590
+ for module in self.modules:
591
+ extras = ["test"]
592
+ if module in extras_available:
593
+ extras.insert(0, module)
594
+
595
+ path_test = self.paths.tests / f"{self.TEST_FILENAME_PREFIX}{module}{self.TEST_FILENAME_SUFFIX}"
596
+ path_test = path_test.relative_to(self.paths.repo)
597
+ envs[module] = {
598
+ "description": f"Run tests for module {module}.",
599
+ "extras": extras,
600
+ "commands": [["python", "-m", "pytest", "-q", str(path_test)]],
601
+ }
602
+
603
+ return envs
604
+
605
+ @cached_property
606
+ def data(self) -> dict:
607
+ data = {
608
+ "requires": self.TOX_REQUIRES,
609
+ "env_list": list(self.envs.keys()),
610
+ "env": self.envs,
611
+ }
612
+ return data
613
+
614
+ def write_config(self):
615
+ self.path_config_dir.mkdir(parents=True, exist_ok=True)
616
+ self.path_config.write_toml(self.data)
617
+
618
+ def run_subprocess(self) -> int:
619
+ command = [
620
+ "uvx",
621
+ "--with",
622
+ "tox-uv",
623
+ "tox",
624
+ "-c",
625
+ str(self.path_config),
626
+ "--root",
627
+ str(self.paths.repo),
628
+ "--workdir",
629
+ str(self.paths.repo / ".tox"),
630
+ "run",
631
+ ]
632
+
633
+ process = subprocess.Popen(
634
+ command,
635
+ cwd=self.paths.repo,
636
+ stdout=subprocess.PIPE,
637
+ stderr=subprocess.STDOUT,
638
+ text=True,
639
+ bufsize=1,
640
+ )
641
+
642
+ assert process.stdout is not None
643
+ for line in process.stdout:
644
+ line = line.rstrip().replace("{", "{{").replace("}", "}}")
645
+ logger.info(line)
646
+
647
+ code = process.wait()
648
+ return code
649
+
650
+ @logger.instrument('Running test suite for "{self.paths.name_ns}"...')
651
+ def run(self) -> bool:
652
+ if not self.envs:
653
+ logger.warning(f'No tests found under "{self.paths.tests}". Skipping.')
654
+ return True
655
+
656
+ logger.info(f'Generating temporary tox config: "{self.path_config}"')
657
+ self.write_config()
658
+ try:
659
+ code = self.run_subprocess()
660
+ finally:
661
+ self.path_config.unlink(missing_ok=True)
662
+ shutil.rmtree(self.path_config_dir, ignore_errors=True)
663
+
664
+ if code == 0:
665
+ logger.info("All test environments passed.")
666
+ return True
667
+
668
+ logger.error(f"Test suite failed with exit code {code}.")
669
+ return False
@@ -762,6 +762,15 @@ class PackagePaths(FromCallerMixin):
762
762
 
763
763
  return self.repo / Constants.SCRIPTS_DIR
764
764
 
765
+ @property
766
+ def tests(self) -> Path:
767
+ """
768
+
769
+ Path of package tests.
770
+
771
+ """
772
+ return self.path / "tests"
773
+
765
774
  def __repr__(self) -> str:
766
775
  """
767
776
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [tool.corio.dependencies]
6
6
  dev = ["logging", "version.dev", "debug", "sets", "yaml", "db.document", "infra"]
7
7
  install = []
8
- test = ["pytest-cov"]
8
+ test = ["pytest", "pytest-cov"]
9
9
  yaml = ["yamlscript", "pyyaml"]
10
10
  logging = ["logfire", "version"]
11
11
  parallel = ["dask[bag]", "distributed", "bokeh"]
@@ -56,7 +56,7 @@ ha = ["env.io"]
56
56
  "ha.api" = ["ha", "homeassistant_api", "aiohasupervisor"]
57
57
  doc = ["mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav"]
58
58
  youtube = ["pytubefix"]
59
- infra = ["version.dev", "logging", "setup", "doc", "sets", "build", "twine", "packaging", "vcs", "docker.client", "merging", "http", "api", "tomlkit", "secrets", "cli"]
59
+ infra = ["version.dev", "logging", "setup", "doc", "sets", "build", "twine", "packaging", "vcs", "docker.client", "merging", "http", "api", "tomlkit", "secrets", "cli", "test"]
60
60
  vcs = ["pygit2"]
61
61
  tasmota = ["decode-config", "esptool"]
62
62
  encrypt = ["pyrage"]
@@ -64,7 +64,7 @@ secrets = ["encrypt", "env.io", "yaml", "logging", "sets", "vcs"]
64
64
  cli = ["sets", "logging"]
65
65
 
66
66
  [tool.corio.metadata]
67
- version = "2.2.1"
67
+ version = "2.2.2-alpha000"
68
68
  port = 0
69
69
  base = "python"
70
70
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -93,7 +93,7 @@ corio = ["pyproject.package.toml"]
93
93
 
94
94
  [project]
95
95
  name = "corio"
96
- version = "2.2.1"
96
+ version = "2.2.2-alpha000"
97
97
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
98
98
  readme = "README.md"
99
99
  dependencies = []
@@ -102,8 +102,8 @@ license-files = ["LICENSE"]
102
102
  keywords = []
103
103
 
104
104
  [project.optional-dependencies]
105
- dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
106
- test = ["pytest-cov"]
105
+ dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]
106
+ test = ["pytest", "pytest-cov"]
107
107
  yaml = ["yamlscript", "pyyaml"]
108
108
  logging = ["logfire"]
109
109
  parallel = ["dask[bag]", "distributed", "bokeh"]
@@ -154,13 +154,13 @@ ha = ["dotenv"]
154
154
  "ha.api" = ["dotenv", "homeassistant_api", "aiohasupervisor"]
155
155
  doc = ["mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav"]
156
156
  youtube = ["pytubefix"]
157
- infra = ["semver", "logfire", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
157
+ infra = ["semver", "logfire", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]
158
158
  vcs = ["pygit2"]
159
159
  tasmota = ["decode-config", "esptool"]
160
160
  encrypt = ["pyrage"]
161
161
  secrets = ["pyrage", "dotenv", "yamlscript", "pyyaml", "logfire", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "pygit2"]
162
162
  cli = ["pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "logfire"]
163
- all = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest-cov", "dask[bag]", "distributed", "bokeh", "tokenizers", "faker", "sre_yield", "contexttimer", "Unidecode", "tinynetrc", "huggingface_hub", "peft", "transformers[sentencepiece]", "torchvision", "torchaudio", "cuda-bindings==13.2.0", "cuda-pathfinder==1.5.4", "cuda-toolkit==13.0.2", "nvidia-cublas==13.1.0.3", "nvidia-cuda-cupti==13.0.85", "nvidia-cuda-nvrtc==13.0.88", "nvidia-cuda-runtime==13.0.96", "nvidia-cudnn-cu13==9.19.0.56", "nvidia-cufft==12.0.0.61", "nvidia-cufile==1.15.1.6", "nvidia-curand==10.4.0.35", "nvidia-cusolver==12.0.4.66", "nvidia-cusparse==12.6.3.3", "nvidia-cusparselt-cu13==0.8.0", "nvidia-nccl-cu13==2.28.9", "nvidia-nvjitlink==13.0.88", "nvidia-nvshmem-cu13==3.4.5", "nvidia-nvtx==13.0.85", "torch==2.11.0", "triton==3.6.0", "openai", "pydantic-ai-slim[logfire,openai]", "ollama", "json_repair", "sentence_transformers", "pandas", "tabulate", "openpyxl", "odfpy", "deepdiff", "html2text", "flet[all] <0.80.0", "flet-video", "flet-webview", "google-auth", "google-auth-oauthlib", "google-auth-httplib2", "google-api-python-client", "diskcache", "cachetools", "pymupdf", "pymupdf4llm", "appdirs", "filetype", "dnspython[doh]", "regex", "playwright", "aiomqtt", "av", "homeassistant_api", "aiohasupervisor", "pytubefix", "decode-config", "esptool"]
163
+ all = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov", "dask[bag]", "distributed", "bokeh", "tokenizers", "faker", "sre_yield", "contexttimer", "Unidecode", "tinynetrc", "huggingface_hub", "peft", "transformers[sentencepiece]", "torchvision", "torchaudio", "cuda-bindings==13.2.0", "cuda-pathfinder==1.5.4", "cuda-toolkit==13.0.2", "nvidia-cublas==13.1.0.3", "nvidia-cuda-cupti==13.0.85", "nvidia-cuda-nvrtc==13.0.88", "nvidia-cuda-runtime==13.0.96", "nvidia-cudnn-cu13==9.19.0.56", "nvidia-cufft==12.0.0.61", "nvidia-cufile==1.15.1.6", "nvidia-curand==10.4.0.35", "nvidia-cusolver==12.0.4.66", "nvidia-cusparse==12.6.3.3", "nvidia-cusparselt-cu13==0.8.0", "nvidia-nccl-cu13==2.28.9", "nvidia-nvjitlink==13.0.88", "nvidia-nvshmem-cu13==3.4.5", "nvidia-nvtx==13.0.85", "torch==2.11.0", "triton==3.6.0", "openai", "pydantic-ai-slim[logfire,openai]", "ollama", "json_repair", "sentence_transformers", "pandas", "tabulate", "openpyxl", "odfpy", "deepdiff", "html2text", "flet[all] <0.80.0", "flet-video", "flet-webview", "google-auth", "google-auth-oauthlib", "google-auth-httplib2", "google-api-python-client", "diskcache", "cachetools", "pymupdf", "pymupdf4llm", "appdirs", "filetype", "dnspython[doh]", "regex", "playwright", "aiomqtt", "av", "homeassistant_api", "aiohasupervisor", "pytubefix", "decode-config", "esptool"]
164
164
 
165
165
  [[project.authors]]
166
166
  name = "Frontmatter AI"
@@ -173,4 +173,4 @@ Homepage = "https://github.com/fmtr/corio"
173
173
  corio = "corio.entrypoint:main"
174
174
 
175
175
  [dependency-groups]
176
- dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
176
+ dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]
@@ -0,0 +1,39 @@
1
+ from contextlib import nullcontext
2
+
3
+ import corio.caching as caching_module
4
+ from corio.caching import Disk, TLRU
5
+
6
+
7
+ def test_disk_nested_dump(tmp_path):
8
+ cache = Disk(tmp_path / "cache")
9
+
10
+ cache.setdefault("svc", Disk)["enabled"] = True
11
+ cache["count"] = 2
12
+
13
+ dumped = cache.dump()
14
+ assert dumped["count"] == 2
15
+ assert dumped["svc"]["enabled"] is True
16
+
17
+
18
+ def test_tlru_expire_with_custom_timer(monkeypatch):
19
+ class DummyLogger:
20
+ @staticmethod
21
+ def span(_):
22
+ return nullcontext()
23
+
24
+ @staticmethod
25
+ def debug(_):
26
+ return None
27
+
28
+ monkeypatch.setattr(caching_module, "logger", DummyLogger())
29
+
30
+ now = [0]
31
+ cache = TLRU(maxsize=4, timer=lambda: now[0], ttu_static=5, desc="test")
32
+ cache["k1"] = "v1"
33
+
34
+ assert "k1" in cache
35
+ now[0] = 6
36
+ expired = cache.expire()
37
+
38
+ assert expired == [("k1", "v1")]
39
+ assert "k1" not in cache
@@ -0,0 +1,24 @@
1
+ from corio import datatype
2
+ from corio.tests import helpers
3
+
4
+
5
+ @helpers.parametrize(
6
+ 'raw, expected',
7
+ [
8
+ ('true', True),
9
+ ('1', True),
10
+ ('y', True),
11
+ ('yes', True),
12
+ ('on', True),
13
+ ('false', False),
14
+ (0, False),
15
+ ('f', False),
16
+ ('n', False),
17
+ ('no', False),
18
+ ('nooo', False),
19
+ ('zzz', False),
20
+ ]
21
+ )
22
+ def test_to_bool(raw, expected):
23
+ actual = datatype.to_bool(raw)
24
+ assert actual == expected
@@ -0,0 +1,43 @@
1
+ from pyrage import x25519
2
+
3
+ from corio.encrypt import Encryptor, EncryptorValues
4
+
5
+
6
+ def test_encryptor_round_trip():
7
+ identity = x25519.Identity.generate()
8
+ encryptor = Encryptor(key=str(identity))
9
+ expected = {
10
+ "service": "corio",
11
+ "enabled": True,
12
+ "retries": 3,
13
+ "tags": ["alpha", "beta"],
14
+ "metadata": {"region": "eu-west-2"},
15
+ }
16
+
17
+ encrypted = encryptor.encrypt(expected)
18
+ assert isinstance(encrypted, str)
19
+ assert encryptor.is_encrypted(encrypted)
20
+
21
+ actual = encryptor.decrypt(encrypted)
22
+ assert actual == expected
23
+
24
+
25
+ def test_encryptor_values_round_trip():
26
+ identity = x25519.Identity.generate()
27
+ encryptor = EncryptorValues(key=str(identity))
28
+ expected = {
29
+ "api": {
30
+ "token": "test-token",
31
+ "enabled": True,
32
+ "ports": [80, 443],
33
+ },
34
+ "count": 2,
35
+ }
36
+
37
+ encrypted = encryptor.encrypt(expected)
38
+ assert encrypted != expected
39
+ assert encryptor.is_encrypted(encrypted["api"]["token"])
40
+ assert encryptor.is_encrypted(encrypted["api"]["ports"][0])
41
+
42
+ actual = encryptor.decrypt(encrypted)
43
+ assert actual == expected
@@ -1,6 +1,7 @@
1
1
  import pathlib
2
2
  import pytest
3
3
 
4
+ from corio.hook import MissingExtraError
4
5
  from corio import path
5
6
  from corio.tests.helpers import SERIALIZATION_DATA
6
7
 
@@ -68,10 +69,10 @@ def test_serialization_json():
68
69
 
69
70
  """
70
71
  expected = SERIALIZATION_DATA
71
- path = path.Path.temp() / 'serialization_test.json'
72
- path.write_json(expected)
73
- actual = path.read_json()
74
- path.unlink()
72
+ path_tmp = path.Path.temp() / 'serialization_test.json'
73
+ path_tmp.write_json(expected)
74
+ actual = path_tmp.read_json()
75
+ path_tmp.unlink()
75
76
  assert actual == expected
76
77
 
77
78
 
@@ -87,8 +88,12 @@ def test_serialization_yaml():
87
88
  'set': {'foo', 'bar', 'baz'},
88
89
  'text': 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium \n' * 100
89
90
  }
90
- path = path.Path.temp() / 'serialization_test.yaml'
91
- path.write_yaml(expected)
92
- actual = path.read_yaml()
93
- path.unlink()
91
+ path_tmp = path.Path.temp() / 'serialization_test.yaml'
92
+ try:
93
+ path_tmp.write_yaml(expected)
94
+ actual = path_tmp.read_yaml()
95
+ except MissingExtraError:
96
+ pytest.skip("requires yaml extra")
97
+ else:
98
+ path_tmp.unlink()
94
99
  assert actual == expected
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corio
3
- Version: 2.2.1
3
+ Version: 2.2.2a0
4
4
  Summary: Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML
5
5
  Author-email: Frontmatter AI <innovative.fowler@mask.pro.fmtr.dev>
6
6
  License-Expression: Apache-2.0
@@ -39,7 +39,10 @@ Requires-Dist: logfire[fastapi]; extra == "dev"
39
39
  Requires-Dist: tomlkit; extra == "dev"
40
40
  Requires-Dist: pyrage; extra == "dev"
41
41
  Requires-Dist: dotenv; extra == "dev"
42
+ Requires-Dist: pytest; extra == "dev"
43
+ Requires-Dist: pytest-cov; extra == "dev"
42
44
  Provides-Extra: test
45
+ Requires-Dist: pytest; extra == "test"
43
46
  Requires-Dist: pytest-cov; extra == "test"
44
47
  Provides-Extra: yaml
45
48
  Requires-Dist: yamlscript; extra == "yaml"
@@ -255,6 +258,8 @@ Requires-Dist: logfire[fastapi]; extra == "infra"
255
258
  Requires-Dist: tomlkit; extra == "infra"
256
259
  Requires-Dist: pyrage; extra == "infra"
257
260
  Requires-Dist: dotenv; extra == "infra"
261
+ Requires-Dist: pytest; extra == "infra"
262
+ Requires-Dist: pytest-cov; extra == "infra"
258
263
  Provides-Extra: vcs
259
264
  Requires-Dist: pygit2; extra == "vcs"
260
265
  Provides-Extra: tasmota
@@ -313,6 +318,7 @@ Requires-Dist: logfire[fastapi]; extra == "all"
313
318
  Requires-Dist: tomlkit; extra == "all"
314
319
  Requires-Dist: pyrage; extra == "all"
315
320
  Requires-Dist: dotenv; extra == "all"
321
+ Requires-Dist: pytest; extra == "all"
316
322
  Requires-Dist: pytest-cov; extra == "all"
317
323
  Requires-Dist: dask[bag]; extra == "all"
318
324
  Requires-Dist: distributed; extra == "all"
@@ -46,7 +46,7 @@ corio/process.py
46
46
  corio/profiling.py
47
47
  corio/pyproject.package.toml
48
48
  corio/rand.py
49
- corio/secrets.py
49
+ corio/sec.py
50
50
  corio/semantic.py
51
51
  corio/sets.py
52
52
  corio/spaces.py
@@ -100,9 +100,11 @@ corio/setup/__init__.py
100
100
  corio/tests/__init__.py
101
101
  corio/tests/conftest.py
102
102
  corio/tests/helpers.py
103
+ corio/tests/test_caching.py
103
104
  corio/tests/test_datatype.py
104
- corio/tests/test_environment.py
105
- corio/tests/test_json.py
105
+ corio/tests/test_encrypt.py
106
+ corio/tests/test_env.py
107
+ corio/tests/test_jsn.py
106
108
  corio/tests/test_path.py
107
109
  corio/tests/test_yaml.py
108
110
  corio/version/__init__.py
@@ -71,6 +71,7 @@ logfire[fastapi]
71
71
  tomlkit
72
72
  pyrage
73
73
  dotenv
74
+ pytest
74
75
  pytest-cov
75
76
  dask[bag]
76
77
  distributed
@@ -213,6 +214,8 @@ logfire[fastapi]
213
214
  tomlkit
214
215
  pyrage
215
216
  dotenv
217
+ pytest
218
+ pytest-cov
216
219
 
217
220
  [dm]
218
221
  pydantic
@@ -300,6 +303,8 @@ logfire[fastapi]
300
303
  tomlkit
301
304
  pyrage
302
305
  dotenv
306
+ pytest
307
+ pytest-cov
303
308
 
304
309
  [interface]
305
310
  flet[all]<0.80.0
@@ -404,6 +409,7 @@ decode-config
404
409
  esptool
405
410
 
406
411
  [test]
412
+ pytest
407
413
  pytest-cov
408
414
 
409
415
  [tokenization]
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [tool.corio.dependencies]
6
6
  dev = ["logging", "version.dev", "debug", "sets", "yaml", "db.document", "infra"]
7
7
  install = []
8
- test = ["pytest-cov"]
8
+ test = ["pytest", "pytest-cov"]
9
9
  yaml = ["yamlscript", "pyyaml"]
10
10
  logging = ["logfire", "version"]
11
11
  parallel = ["dask[bag]", "distributed", "bokeh"]
@@ -56,7 +56,7 @@ ha = ["env.io"]
56
56
  "ha.api" = ["ha", "homeassistant_api", "aiohasupervisor"]
57
57
  doc = ["mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav"]
58
58
  youtube = ["pytubefix"]
59
- infra = ["version.dev", "logging", "setup", "doc", "sets", "build", "twine", "packaging", "vcs", "docker.client", "merging", "http", "api", "tomlkit", "secrets", "cli"]
59
+ infra = ["version.dev", "logging", "setup", "doc", "sets", "build", "twine", "packaging", "vcs", "docker.client", "merging", "http", "api", "tomlkit", "secrets", "cli", "test"]
60
60
  vcs = ["pygit2"]
61
61
  tasmota = ["decode-config", "esptool"]
62
62
  encrypt = ["pyrage"]
@@ -64,7 +64,7 @@ secrets = ["encrypt", "env.io", "yaml", "logging", "sets", "vcs"]
64
64
  cli = ["sets", "logging"]
65
65
 
66
66
  [tool.corio.metadata]
67
- version = "2.2.1"
67
+ version = "2.2.2-alpha000"
68
68
  port = 0
69
69
  base = "python"
70
70
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
@@ -93,7 +93,7 @@ corio = ["pyproject.package.toml"]
93
93
 
94
94
  [project]
95
95
  name = "corio"
96
- version = "2.2.1"
96
+ version = "2.2.2-alpha000"
97
97
  description = "Collection of high-level tools to simplify everyday development tasks, with a focus on AI/ML"
98
98
  readme = "README.md"
99
99
  dependencies = []
@@ -102,8 +102,8 @@ license-files = ["LICENSE"]
102
102
  keywords = []
103
103
 
104
104
  [project.optional-dependencies]
105
- dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
106
- test = ["pytest-cov"]
105
+ dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]
106
+ test = ["pytest", "pytest-cov"]
107
107
  yaml = ["yamlscript", "pyyaml"]
108
108
  logging = ["logfire"]
109
109
  parallel = ["dask[bag]", "distributed", "bokeh"]
@@ -154,13 +154,13 @@ ha = ["dotenv"]
154
154
  "ha.api" = ["dotenv", "homeassistant_api", "aiohasupervisor"]
155
155
  doc = ["mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav"]
156
156
  youtube = ["pytubefix"]
157
- infra = ["semver", "logfire", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
157
+ infra = ["semver", "logfire", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]
158
158
  vcs = ["pygit2"]
159
159
  tasmota = ["decode-config", "esptool"]
160
160
  encrypt = ["pyrage"]
161
161
  secrets = ["pyrage", "dotenv", "yamlscript", "pyyaml", "logfire", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "pygit2"]
162
162
  cli = ["pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "logfire"]
163
- all = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest-cov", "dask[bag]", "distributed", "bokeh", "tokenizers", "faker", "sre_yield", "contexttimer", "Unidecode", "tinynetrc", "huggingface_hub", "peft", "transformers[sentencepiece]", "torchvision", "torchaudio", "cuda-bindings==13.2.0", "cuda-pathfinder==1.5.4", "cuda-toolkit==13.0.2", "nvidia-cublas==13.1.0.3", "nvidia-cuda-cupti==13.0.85", "nvidia-cuda-nvrtc==13.0.88", "nvidia-cuda-runtime==13.0.96", "nvidia-cudnn-cu13==9.19.0.56", "nvidia-cufft==12.0.0.61", "nvidia-cufile==1.15.1.6", "nvidia-curand==10.4.0.35", "nvidia-cusolver==12.0.4.66", "nvidia-cusparse==12.6.3.3", "nvidia-cusparselt-cu13==0.8.0", "nvidia-nccl-cu13==2.28.9", "nvidia-nvjitlink==13.0.88", "nvidia-nvshmem-cu13==3.4.5", "nvidia-nvtx==13.0.85", "torch==2.11.0", "triton==3.6.0", "openai", "pydantic-ai-slim[logfire,openai]", "ollama", "json_repair", "sentence_transformers", "pandas", "tabulate", "openpyxl", "odfpy", "deepdiff", "html2text", "flet[all] <0.80.0", "flet-video", "flet-webview", "google-auth", "google-auth-oauthlib", "google-auth-httplib2", "google-api-python-client", "diskcache", "cachetools", "pymupdf", "pymupdf4llm", "appdirs", "filetype", "dnspython[doh]", "regex", "playwright", "aiomqtt", "av", "homeassistant_api", "aiohasupervisor", "pytubefix", "decode-config", "esptool"]
163
+ all = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov", "dask[bag]", "distributed", "bokeh", "tokenizers", "faker", "sre_yield", "contexttimer", "Unidecode", "tinynetrc", "huggingface_hub", "peft", "transformers[sentencepiece]", "torchvision", "torchaudio", "cuda-bindings==13.2.0", "cuda-pathfinder==1.5.4", "cuda-toolkit==13.0.2", "nvidia-cublas==13.1.0.3", "nvidia-cuda-cupti==13.0.85", "nvidia-cuda-nvrtc==13.0.88", "nvidia-cuda-runtime==13.0.96", "nvidia-cudnn-cu13==9.19.0.56", "nvidia-cufft==12.0.0.61", "nvidia-cufile==1.15.1.6", "nvidia-curand==10.4.0.35", "nvidia-cusolver==12.0.4.66", "nvidia-cusparse==12.6.3.3", "nvidia-cusparselt-cu13==0.8.0", "nvidia-nccl-cu13==2.28.9", "nvidia-nvjitlink==13.0.88", "nvidia-nvshmem-cu13==3.4.5", "nvidia-nvtx==13.0.85", "torch==2.11.0", "triton==3.6.0", "openai", "pydantic-ai-slim[logfire,openai]", "ollama", "json_repair", "sentence_transformers", "pandas", "tabulate", "openpyxl", "odfpy", "deepdiff", "html2text", "flet[all] <0.80.0", "flet-video", "flet-webview", "google-auth", "google-auth-oauthlib", "google-auth-httplib2", "google-api-python-client", "diskcache", "cachetools", "pymupdf", "pymupdf4llm", "appdirs", "filetype", "dnspython[doh]", "regex", "playwright", "aiomqtt", "av", "homeassistant_api", "aiohasupervisor", "pytubefix", "decode-config", "esptool"]
164
164
 
165
165
  [[project.authors]]
166
166
  name = "Frontmatter AI"
@@ -173,4 +173,4 @@ Homepage = "https://github.com/fmtr/corio"
173
173
  corio = "corio.entrypoint:main"
174
174
 
175
175
  [dependency-groups]
176
- dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv"]
176
+ dev = ["logfire", "semver", "pydevd-pycharm~=251.25410.159", "pydantic-settings", "pydantic", "pydantic-extra-types", "pycountry", "yamlscript", "pyyaml", "beanie", "setuptools", "mkdocs", "mkdocs-material", "mkdocstrings[python]", "mike", "mkdocs-include-dir-to-nav", "build", "twine", "packaging", "pygit2", "python-on-whales", "deepmerge", "httpx", "httpx_retries", "logfire[httpx]", "fastapi", "uvicorn[standard]", "logfire[fastapi]", "tomlkit", "pyrage", "dotenv", "pytest", "pytest-cov"]