fujin-cli 0.7.0__tar.gz → 0.7.1__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.

Potentially problematic release.


This version of fujin-cli might be problematic. Click here for more details.

Files changed (82) hide show
  1. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/.pre-commit-config.yaml +7 -0
  2. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/CHANGELOG.md +6 -0
  3. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/PKG-INFO +1 -1
  4. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/printenv.rst +1 -1
  5. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/conf.py +1 -1
  6. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/configuration.rst +8 -4
  7. fujin_cli-0.7.1/docs/requirements.txt +100 -0
  8. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/pyproject.toml +4 -4
  9. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/__init__.py +0 -1
  10. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/_base.py +2 -1
  11. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/deploy.py +2 -1
  12. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/init.py +2 -1
  13. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/printenv.py +4 -2
  14. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/rollback.py +2 -1
  15. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/connection.py +3 -5
  16. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/hooks.py +2 -1
  17. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/secrets/__init__.py +4 -2
  18. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/secrets/bitwarden.py +16 -5
  19. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/secrets/onepassword.py +6 -5
  20. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/uv.lock +328 -970
  21. fujin_cli-0.7.0/docs/requirements.txt +0 -138
  22. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/.github/workflows/publish.yml +0 -0
  23. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/.gitignore +0 -0
  24. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/.readthedocs.yaml +0 -0
  25. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/LICENSE.txt +0 -0
  26. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/README.md +0 -0
  27. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/Vagrantfile +0 -0
  28. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/changelog.rst +0 -0
  29. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/app.rst +0 -0
  30. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/config.rst +0 -0
  31. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/deploy.rst +0 -0
  32. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/docs.rst +0 -0
  33. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/down.rst +0 -0
  34. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/index.rst +0 -0
  35. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/init.rst +0 -0
  36. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/proxy.rst +0 -0
  37. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/prune.rst +0 -0
  38. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/redeploy.rst +0 -0
  39. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/rollback.rst +0 -0
  40. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/server.rst +0 -0
  41. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/commands/up.rst +0 -0
  42. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/hooks.rst +0 -0
  43. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/index.rst +0 -0
  44. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/installation.rst +0 -0
  45. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/secrets.rst +0 -0
  46. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/docs/tutorial.rst +0 -0
  47. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/README.md +0 -0
  48. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/__init__.py +0 -0
  49. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/__main__.py +0 -0
  50. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/asgi.py +0 -0
  51. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/settings.py +0 -0
  52. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/urls.py +0 -0
  53. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/bookstore/wsgi.py +0 -0
  54. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/fujin.toml +0 -0
  55. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/manage.py +0 -0
  56. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/pyproject.toml +0 -0
  57. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/django/bookstore/requirements.txt +0 -0
  58. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/golang/pocketbase/.env.prod +0 -0
  59. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/examples/golang/pocketbase/fujin.toml +0 -0
  60. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/justfile +0 -0
  61. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/__init__.py +0 -0
  62. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/__main__.py +0 -0
  63. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/app.py +0 -0
  64. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/config.py +0 -0
  65. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/docs.py +0 -0
  66. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/down.py +0 -0
  67. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/proxy.py +0 -0
  68. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/prune.py +0 -0
  69. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/redeploy.py +1 -1
  70. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/server.py +0 -0
  71. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/commands/up.py +1 -1
  72. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/config.py +0 -0
  73. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/errors.py +0 -0
  74. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/process_managers/__init__.py +0 -0
  75. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/process_managers/systemd.py +0 -0
  76. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/proxies/__init__.py +0 -0
  77. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/proxies/caddy.py +0 -0
  78. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/proxies/dummy.py +0 -0
  79. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/proxies/nginx.py +0 -0
  80. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/templates/simple.service +0 -0
  81. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/templates/web.service +0 -0
  82. {fujin_cli-0.7.0 → fujin_cli-0.7.1}/src/fujin/templates/web.socket +0 -0
@@ -34,3 +34,10 @@ repos:
34
34
  - id: pyproject-fmt
35
35
  args: [ "pyproject.toml" ]
36
36
  exclude: ^(examples/)
37
+
38
+ # - repo: https://github.com/asottile/reorder_python_imports
39
+ # rev: v3.13.0
40
+ # hooks:
41
+ # - id: reorder-python-imports
42
+ # args:
43
+ # - "--application-directories=src"
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.7.1] - 2024-11-23
8
+
9
+ ### 🐛 Bug Fixes
10
+
11
+ - Broken .venv folder can fail deploy
12
+
7
13
  ## [0.7.0] - 2024-11-22
8
14
 
9
15
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fujin-cli
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Get your project up and running in a few minutes on your own vps.
5
5
  Project-URL: Documentation, https://github.com/falcopackages/fujin#readme
6
6
  Project-URL: Issues, https://github.com/falcopackages/fujin/issues
@@ -1,4 +1,4 @@
1
- secrets
1
+ printenv
2
2
  =======
3
3
 
4
4
  .. cappa:: fujin.commands.printenv.Printenv
@@ -20,7 +20,7 @@ extensions = [
20
20
  "sphinx.ext.autodoc",
21
21
  "sphinx_design",
22
22
  "sphinx_copybutton",
23
- "jupyter_sphinx",
23
+ "sphinx_exec_code",
24
24
  "sphinx_togglebutton",
25
25
  ]
26
26
 
@@ -13,20 +13,24 @@ This is a minimal working example.
13
13
 
14
14
  .. tab-item:: python package
15
15
 
16
- .. jupyter-execute::
17
- :hide-code:
16
+ .. exec_code::
17
+ :language_output: toml
18
18
 
19
+ # --- hide: start ---
19
20
  from fujin.commands.init import simple_config
20
21
  from tomli_w import dumps
21
22
 
22
23
  print(dumps(simple_config("bookstore")))
24
+ #hide:toggle
23
25
 
24
26
  .. tab-item:: binary mode
25
27
 
26
- .. jupyter-execute::
27
- :hide-code:
28
+ .. exec_code::
29
+ :language_output: toml
28
30
 
31
+ # --- hide: start ---
29
32
  from fujin.commands.init import binary_config
30
33
  from tomli_w import dumps
31
34
 
32
35
  print(dumps(binary_config("bookstore")))
36
+ #hide:toggle
@@ -0,0 +1,100 @@
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv export --no-hashes --group docs --format requirements-txt
3
+ -e .
4
+ alabaster==1.0.0
5
+ annotated-types==0.7.0
6
+ anyio==4.6.2.post1
7
+ asgiref==3.8.1
8
+ astroid==3.3.5
9
+ babel==2.16.0
10
+ bcrypt==4.2.1
11
+ bracex==2.5.post1
12
+ bump-my-version==0.28.1
13
+ cappa==0.25.1
14
+ certifi==2024.8.30
15
+ cffi==1.17.1
16
+ charset-normalizer==3.4.0
17
+ click==8.1.7
18
+ colorama==0.4.6
19
+ cryptography==43.0.3
20
+ decorator==5.1.1
21
+ deprecated==1.2.15
22
+ django==5.1.3
23
+ docutils==0.21.2
24
+ exceptiongroup==1.2.2 ; python_full_version < '3.11'
25
+ fabric==3.2.2
26
+ faker==33.0.0
27
+ fastapi==0.115.5
28
+ gevent==24.11.1
29
+ git-cliff==2.7.0
30
+ greenlet==3.1.1 ; platform_python_implementation == 'CPython'
31
+ h11==0.14.0
32
+ httpcore==1.0.7
33
+ httpx==0.27.2
34
+ idna==3.10
35
+ imagesize==1.4.1
36
+ invoke==2.2.0
37
+ jinja2==3.1.4
38
+ litestar==2.13.0
39
+ litestar-htmx==0.3.0
40
+ markdown-it-py==3.0.0
41
+ markupsafe==3.0.2
42
+ mdit-py-plugins==0.4.2
43
+ mdurl==0.1.2
44
+ msgspec==0.18.6
45
+ multidict==6.1.0
46
+ myst-parser==4.0.0
47
+ packaging==24.2
48
+ paramiko==3.5.0
49
+ polyfactory==2.18.0
50
+ prompt-toolkit==3.0.48
51
+ psutil==6.1.0 ; sys_platform != 'win32' or platform_python_implementation == 'CPython'
52
+ pycparser==2.22
53
+ pydantic==2.10.1
54
+ pydantic-core==2.27.1
55
+ pydantic-settings==2.6.1
56
+ pygments==2.18.0
57
+ pynacl==1.5.0
58
+ python-dateutil==2.9.0.post0
59
+ python-dotenv==1.0.1
60
+ pyyaml==6.0.2
61
+ questionary==1.10.0
62
+ requests==2.32.3
63
+ rich==13.9.4
64
+ rich-click==1.8.4
65
+ setuptools==75.6.0
66
+ shibuya==2024.10.15
67
+ six==1.16.0
68
+ sniffio==1.3.1
69
+ snowballstemmer==2.2.0
70
+ sphinx==8.1.3
71
+ sphinx-autobuild==2024.10.3
72
+ sphinx-autodoc2==0.5.0
73
+ sphinx-copybutton==0.5.2
74
+ sphinx-design==0.6.1
75
+ sphinx-exec-code==0.14
76
+ sphinx-togglebutton==0.3.2
77
+ sphinxcontrib-applehelp==2.0.0
78
+ sphinxcontrib-devhelp==2.0.0
79
+ sphinxcontrib-htmlhelp==2.1.0
80
+ sphinxcontrib-jsmath==1.0.1
81
+ sphinxcontrib-qthelp==2.0.0
82
+ sphinxcontrib-serializinghtml==2.0.0
83
+ sqlparse==0.5.2
84
+ starlette==0.41.3
85
+ tomli==2.1.0 ; python_full_version < '3.11'
86
+ tomli-w==1.1.0
87
+ tomlkit==0.13.2
88
+ type-lens==0.2.3
89
+ typing-extensions==4.12.2
90
+ tzdata==2024.2 ; sys_platform == 'win32'
91
+ urllib3==2.2.3
92
+ uvicorn==0.32.1
93
+ watchfiles==0.24.0
94
+ wcmatch==10.0
95
+ wcwidth==0.2.13
96
+ websockets==14.1
97
+ wheel==0.45.1
98
+ wrapt==1.17.0
99
+ zope-event==5.0
100
+ zope-interface==7.1.1
@@ -7,7 +7,7 @@ requires = [
7
7
 
8
8
  [project]
9
9
  name = "fujin-cli"
10
- version = "0.7.0"
10
+ version = "0.7.1"
11
11
  description = "Get your project up and running in a few minutes on your own vps."
12
12
  readme = "README.md"
13
13
  keywords = [
@@ -61,13 +61,13 @@ dev = [
61
61
  "litestar>=2.12.1",
62
62
  ]
63
63
  docs = [
64
- "jupyter-sphinx>=0.5.3",
65
64
  "myst-parser",
66
65
  "shibuya",
67
66
  "sphinx-autobuild",
68
67
  "sphinx-autodoc2>=0.5",
69
68
  "sphinx-copybutton",
70
69
  "sphinx-design",
70
+ "sphinx-exec-code>=0.14",
71
71
  "sphinx-togglebutton>=0.3.2",
72
72
  ]
73
73
 
@@ -116,12 +116,12 @@ lint.select = [
116
116
  "B", # flake8-bugbear
117
117
  "E", # Pycodestyle
118
118
  "F", # Pyflakes
119
- "I", # isort
120
119
  "UP", # pyupgrade
121
120
  ]
122
121
  lint.ignore = [
123
122
  "E501",
124
123
  "E741",
124
+ "I", # isort
125
125
  ] # temporary
126
126
  # Tests can use magic values, assertions, and relative imports
127
127
  lint.per-file-ignores."tests/**/*" = [
@@ -154,7 +154,7 @@ lint.isort.required-imports = [
154
154
  lint.pyupgrade.keep-runtime-typing = true
155
155
 
156
156
  [tool.bumpversion]
157
- current_version = "0.7.0"
157
+ current_version = "0.7.1"
158
158
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
159
159
  serialize = [
160
160
  "{major}.{minor}.{patch}",
@@ -1,2 +1 @@
1
1
  from ._base import BaseCommand # noqa
2
- from ._base import BaseCommand # noqa
@@ -6,7 +6,8 @@ from functools import cached_property
6
6
  import cappa
7
7
 
8
8
  from fujin.config import Config
9
- from fujin.connection import host_connection, Connection
9
+ from fujin.connection import Connection
10
+ from fujin.connection import host_connection
10
11
  from fujin.errors import ImproperlyConfiguredError
11
12
  from fujin.hooks import HookManager
12
13
  from fujin.process_managers import ProcessManager
@@ -7,8 +7,8 @@ import cappa
7
7
 
8
8
  from fujin.commands import BaseCommand
9
9
  from fujin.config import InstallationMode
10
- from fujin.secrets import resolve_secrets
11
10
  from fujin.connection import Connection
11
+ from fujin.secrets import resolve_secrets
12
12
 
13
13
 
14
14
  @cappa.command(
@@ -100,6 +100,7 @@ export PATH=".venv/bin:$PATH"
100
100
  conn.run(f"echo '{appenv.strip()}' > {self.app_dir}/.appenv")
101
101
  versioned_assets_dir = f"{self.app_dir}/v{version}"
102
102
  if not skip_setup:
103
+ conn.run("rm -rf .venv")
103
104
  conn.run("uv venv")
104
105
  if self.config.requirements:
105
106
  conn.run(f"uv pip install -r {versioned_assets_dir}/requirements.txt")
@@ -8,7 +8,8 @@ import cappa
8
8
  import tomli_w
9
9
 
10
10
  from fujin.commands import BaseCommand
11
- from fujin.config import tomllib, InstallationMode
11
+ from fujin.config import InstallationMode
12
+ from fujin.config import tomllib
12
13
 
13
14
 
14
15
  @cappa.command(help="Generate a sample configuration file")
@@ -5,12 +5,14 @@ from fujin.secrets import resolve_secrets
5
5
 
6
6
 
7
7
  @cappa.command(
8
- help="Print the content of the envfile with extracted secrets (for debugging)"
8
+ help="Display the contents of the envfile with resolved secrets (for debugging purposes)"
9
9
  )
10
10
  class Printenv(BaseCommand):
11
11
  def __call__(self):
12
12
  if self.config.secret_config:
13
- result = resolve_secrets(self.config.host.envfile, self.config.secret_config)
13
+ result = resolve_secrets(
14
+ self.config.host.envfile, self.config.secret_config
15
+ )
14
16
  else:
15
17
  result = self.config.host.envfile.read_text()
16
18
  self.stdout.output(result)
@@ -1,7 +1,8 @@
1
1
  from dataclasses import dataclass
2
2
 
3
3
  import cappa
4
- from rich.prompt import Prompt, Confirm
4
+ from rich.prompt import Confirm
5
+ from rich.prompt import Prompt
5
6
 
6
7
  from fujin.commands import BaseCommand
7
8
  from fujin.commands.deploy import Deploy
@@ -8,11 +8,9 @@ import cappa
8
8
  from fabric import Connection
9
9
  from invoke import Responder
10
10
  from invoke.exceptions import UnexpectedExit
11
- from paramiko.ssh_exception import (
12
- AuthenticationException,
13
- NoValidConnectionsError,
14
- SSHException,
15
- )
11
+ from paramiko.ssh_exception import AuthenticationException
12
+ from paramiko.ssh_exception import NoValidConnectionsError
13
+ from paramiko.ssh_exception import SSHException
16
14
 
17
15
  if TYPE_CHECKING:
18
16
  from fujin.config import HostConfig
@@ -1,8 +1,9 @@
1
1
  from dataclasses import dataclass
2
2
 
3
- from fujin.connection import Connection
4
3
  from rich import print as rich_print
5
4
 
5
+ from fujin.connection import Connection
6
+
6
7
  try:
7
8
  from enum import StrEnum
8
9
  except ImportError:
@@ -1,13 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
+ from typing import Callable
5
+
4
6
  import gevent
5
7
  from dotenv import dotenv_values
6
- from typing import Callable
7
8
 
8
- from fujin.config import SecretConfig, SecretAdapter
9
9
  from .bitwarden import bitwarden
10
10
  from .onepassword import one_password
11
+ from fujin.config import SecretAdapter
12
+ from fujin.config import SecretConfig
11
13
 
12
14
 
13
15
  secret_reader = Callable[[str], str]
@@ -1,12 +1,14 @@
1
1
  from __future__ import annotations
2
- import cappa
2
+
3
3
  import os
4
+ import subprocess
5
+ from contextlib import contextmanager
6
+ from typing import Generator
7
+ from typing import TYPE_CHECKING
4
8
 
9
+ import cappa
5
10
 
6
11
  from fujin.config import SecretConfig
7
- import subprocess
8
- from contextlib import contextmanager
9
- from typing import Generator, TYPE_CHECKING
10
12
 
11
13
  if TYPE_CHECKING:
12
14
  from . import secret_reader
@@ -25,7 +27,16 @@ def bitwarden(secret_config: SecretConfig) -> Generator[secret_reader, None, Non
25
27
 
26
28
  def read_secret(name: str) -> str:
27
29
  result = subprocess.run(
28
- ["bw", "get", "password", name, "--raw", "--session", session, "--nointeraction"],
30
+ [
31
+ "bw",
32
+ "get",
33
+ "password",
34
+ name,
35
+ "--raw",
36
+ "--session",
37
+ session,
38
+ "--nointeraction",
39
+ ],
29
40
  capture_output=True,
30
41
  text=True,
31
42
  )
@@ -1,12 +1,13 @@
1
1
  from __future__ import annotations
2
- import cappa
3
-
4
2
 
5
- from fujin.config import SecretConfig
6
3
  import subprocess
7
-
8
4
  from contextlib import contextmanager
9
- from typing import Generator, TYPE_CHECKING
5
+ from typing import Generator
6
+ from typing import TYPE_CHECKING
7
+
8
+ import cappa
9
+
10
+ from fujin.config import SecretConfig
10
11
 
11
12
  if TYPE_CHECKING:
12
13
  from . import secret_reader