oe-python-template 0.10.1__tar.gz → 0.10.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.
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/PKG-INFO +1 -1
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/pyproject.toml +2 -2
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_service.py +1 -1
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/__init__.py +2 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_api.py +41 -3
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_service.py +21 -2
- oe_python_template-0.10.2/src/oe_python_template/system/_settings.py +31 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/__init__.py +3 -1
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_constants.py +1 -1
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_logfire.py +5 -4
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_sentry.py +5 -4
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_settings.py +13 -1
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/.gitignore +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/LICENSE +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/README.md +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/__init__.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/api.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/cli.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/constants.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/__init__.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_api.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_cli.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_constants.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_models.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_settings.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_cli.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_api.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_cli.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_console.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_di.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_health.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_log.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_process.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_service.py +0 -0
- {oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/boot.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oe-python-template
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.2
|
|
4
4
|
Summary: 🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling.
|
|
5
5
|
Project-URL: Homepage, https://oe-python-template.readthedocs.io/en/latest/
|
|
6
6
|
Project-URL: Documentation, https://oe-python-template.readthedocs.io/en/latest/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "oe-python-template"
|
|
3
|
-
version = "0.10.
|
|
3
|
+
version = "0.10.2"
|
|
4
4
|
description = "🧠 Copier template to scaffold Python projects compliant with best practices and modern tooling."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Helmut Hoffer von Ankershoffen", email = "helmuthva@gmail.com" }]
|
|
@@ -275,7 +275,7 @@ source = ["src/"]
|
|
|
275
275
|
|
|
276
276
|
|
|
277
277
|
[tool.bumpversion]
|
|
278
|
-
current_version = "0.10.
|
|
278
|
+
current_version = "0.10.2"
|
|
279
279
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
280
280
|
serialize = ["{major}.{minor}.{patch}"]
|
|
281
281
|
search = "{current_version}"
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_service.py
RENAMED
|
@@ -23,7 +23,7 @@ class Service(BaseService):
|
|
|
23
23
|
|
|
24
24
|
def __init__(self) -> None:
|
|
25
25
|
"""Initialize service."""
|
|
26
|
-
super().__init__(Settings)
|
|
26
|
+
super().__init__(Settings) # automatically loads and validates the settings
|
|
27
27
|
|
|
28
28
|
def info(self) -> dict[str, Any]: # noqa: PLR6301
|
|
29
29
|
"""Determine info of this service.
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_api.py
RENAMED
|
@@ -7,7 +7,7 @@ The endpoints use Pydantic models for request and response validation.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from collections.abc import Callable, Generator
|
|
10
|
-
from typing import Annotated
|
|
10
|
+
from typing import Annotated, Any
|
|
11
11
|
|
|
12
12
|
from fastapi import APIRouter, Depends, Response, status
|
|
13
13
|
|
|
@@ -41,11 +41,11 @@ def register_health_endpoint(router: APIRouter) -> Callable[..., Health]:
|
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
@router.get("/healthz")
|
|
44
|
-
@router.get("/health")
|
|
44
|
+
@router.get("/system/health")
|
|
45
45
|
def health_endpoint(service: Annotated[Service, Depends(get_service)], response: Response) -> Health:
|
|
46
46
|
"""Determine aggregate health of the system.
|
|
47
47
|
|
|
48
|
-
The health is aggregated from all modules
|
|
48
|
+
The health is aggregated from all modules making
|
|
49
49
|
up this system including external dependencies.
|
|
50
50
|
|
|
51
51
|
The response is to be interpreted as follows:
|
|
@@ -71,8 +71,46 @@ def register_health_endpoint(router: APIRouter) -> Callable[..., Health]:
|
|
|
71
71
|
return health_endpoint
|
|
72
72
|
|
|
73
73
|
|
|
74
|
+
def register_info_endpoint(router: APIRouter) -> Callable[..., dict[str, Any]]:
|
|
75
|
+
"""Register info endpoint to the given router.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
router: The router to register the info endpoint to.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Callable[..., Health]: The health endpoint function.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
@router.get("/system/info")
|
|
85
|
+
def info_endpoint(
|
|
86
|
+
service: Annotated[Service, Depends(get_service)], response: Response, token: str
|
|
87
|
+
) -> dict[str, Any]:
|
|
88
|
+
"""Determine aggregate info of the system.
|
|
89
|
+
|
|
90
|
+
The info is aggregated from all modules making up this system.
|
|
91
|
+
|
|
92
|
+
If the token does not match the setting, a 403 Forbidden status code is returned.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
service (Service): The service instance.
|
|
96
|
+
response (Response): The FastAPI response object.
|
|
97
|
+
token (str): Token to present.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
dict[str, Any]: The aggregate info of the system.
|
|
101
|
+
"""
|
|
102
|
+
if service.is_token_valid(token):
|
|
103
|
+
return service.info(include_environ=True, filter_secrets=False)
|
|
104
|
+
|
|
105
|
+
response.status_code = status.HTTP_403_FORBIDDEN
|
|
106
|
+
return {"error": "Forbidden"}
|
|
107
|
+
|
|
108
|
+
return info_endpoint
|
|
109
|
+
|
|
110
|
+
|
|
74
111
|
api_routers = {}
|
|
75
112
|
for version in API_VERSIONS:
|
|
76
113
|
router = VersionedAPIRouter(version, tags=["system"])
|
|
77
114
|
api_routers[version] = router
|
|
78
115
|
health = register_health_endpoint(api_routers[version])
|
|
116
|
+
info = register_info_endpoint(api_routers[version])
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_service.py
RENAMED
|
@@ -11,6 +11,7 @@ from typing import Any
|
|
|
11
11
|
from pydantic_settings import BaseSettings
|
|
12
12
|
|
|
13
13
|
from ..utils import ( # noqa: TID252
|
|
14
|
+
UNHIDE_SENSITIVE_INFO,
|
|
14
15
|
BaseService,
|
|
15
16
|
Health,
|
|
16
17
|
__env__,
|
|
@@ -18,18 +19,24 @@ from ..utils import ( # noqa: TID252
|
|
|
18
19
|
__project_path__,
|
|
19
20
|
__repository_url__,
|
|
20
21
|
__version__,
|
|
22
|
+
get_logger,
|
|
21
23
|
get_process_info,
|
|
22
24
|
load_settings,
|
|
23
25
|
locate_subclasses,
|
|
24
26
|
)
|
|
27
|
+
from ._settings import Settings
|
|
28
|
+
|
|
29
|
+
logger = get_logger(__name__)
|
|
25
30
|
|
|
26
31
|
|
|
27
32
|
class Service(BaseService):
|
|
28
33
|
"""System service."""
|
|
29
34
|
|
|
35
|
+
_settings: Settings
|
|
36
|
+
|
|
30
37
|
def __init__(self) -> None:
|
|
31
38
|
"""Initialize service."""
|
|
32
|
-
super().__init__()
|
|
39
|
+
super().__init__(Settings)
|
|
33
40
|
|
|
34
41
|
@staticmethod
|
|
35
42
|
def _is_healthy() -> bool:
|
|
@@ -60,6 +67,18 @@ class Service(BaseService):
|
|
|
60
67
|
reason = None if self._is_healthy() else "System marked as unhealthy"
|
|
61
68
|
return Health(status=status, components=components, reason=reason)
|
|
62
69
|
|
|
70
|
+
def is_token_valid(self, token: str) -> bool:
|
|
71
|
+
"""Check if the presented token is valid.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
bool: True if the token is valid, False otherwise.
|
|
75
|
+
"""
|
|
76
|
+
logger.info(token)
|
|
77
|
+
if not self._settings.token:
|
|
78
|
+
logger.warning("Token is not set in settings.")
|
|
79
|
+
return False
|
|
80
|
+
return token == self._settings.token.get_secret_value()
|
|
81
|
+
|
|
63
82
|
@staticmethod
|
|
64
83
|
def info(include_environ: bool = False, filter_secrets: bool = True) -> dict[str, Any]:
|
|
65
84
|
"""
|
|
@@ -126,7 +145,7 @@ class Service(BaseService):
|
|
|
126
145
|
for settings_class in locate_subclasses(BaseSettings):
|
|
127
146
|
settings_instance = load_settings(settings_class)
|
|
128
147
|
env_prefix = settings_instance.model_config.get("env_prefix", "")
|
|
129
|
-
settings_dict =
|
|
148
|
+
settings_dict = settings_instance.model_dump(context={UNHIDE_SENSITIVE_INFO: not filter_secrets})
|
|
130
149
|
for key, value in settings_dict.items():
|
|
131
150
|
flat_key = f"{env_prefix}{key}".upper()
|
|
132
151
|
settings[flat_key] = value
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Settings of the system module."""
|
|
2
|
+
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, PlainSerializer, SecretStr
|
|
6
|
+
from pydantic_settings import SettingsConfigDict
|
|
7
|
+
|
|
8
|
+
from ..utils import OpaqueSettings, __env_file__, __project_name__ # noqa: TID252
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Settings(OpaqueSettings):
|
|
12
|
+
"""Settings."""
|
|
13
|
+
|
|
14
|
+
model_config = SettingsConfigDict(
|
|
15
|
+
env_prefix=f"{__project_name__.upper()}_SYSTEM_",
|
|
16
|
+
extra="ignore",
|
|
17
|
+
env_file=__env_file__,
|
|
18
|
+
env_file_encoding="utf-8",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
token: Annotated[
|
|
22
|
+
SecretStr | None,
|
|
23
|
+
PlainSerializer(func=OpaqueSettings.serialize_sensitive_info, return_type=str, when_used="always"),
|
|
24
|
+
Field(
|
|
25
|
+
description=(
|
|
26
|
+
"Secret token to present when performing sensitive operations such as "
|
|
27
|
+
"retrieving info via webservice API"
|
|
28
|
+
),
|
|
29
|
+
default=None,
|
|
30
|
+
),
|
|
31
|
+
]
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/__init__.py
RENAMED
|
@@ -23,15 +23,17 @@ from ._logfire import LogfireSettings
|
|
|
23
23
|
from ._process import ProcessInfo, get_process_info
|
|
24
24
|
from ._sentry import SentrySettings
|
|
25
25
|
from ._service import BaseService
|
|
26
|
-
from ._settings import load_settings
|
|
26
|
+
from ._settings import UNHIDE_SENSITIVE_INFO, OpaqueSettings, load_settings
|
|
27
27
|
from .boot import boot
|
|
28
28
|
|
|
29
29
|
__all__ = [
|
|
30
|
+
"UNHIDE_SENSITIVE_INFO",
|
|
30
31
|
"BaseService",
|
|
31
32
|
"Health",
|
|
32
33
|
"LogSettings",
|
|
33
34
|
"LogSettings",
|
|
34
35
|
"LogfireSettings",
|
|
36
|
+
"OpaqueSettings",
|
|
35
37
|
"ProcessInfo",
|
|
36
38
|
"SentrySettings",
|
|
37
39
|
"VersionedAPIRouter",
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_constants.py
RENAMED
|
@@ -10,7 +10,7 @@ __project_path__ = str(Path(__file__).parent.parent.parent)
|
|
|
10
10
|
__version__ = metadata.version(__project_name__)
|
|
11
11
|
__is_development_mode__ = "uvx" not in sys.argv[0].lower()
|
|
12
12
|
__is_running_in_container__ = os.getenv(f"{__project_name__.upper()}_RUNNING_IN_CONTAINER")
|
|
13
|
-
__env__ = os.getenv("ENV", "local")
|
|
13
|
+
__env__ = os.getenv("ENV", os.getenv("VERCEL_ENV", "local"))
|
|
14
14
|
__env_file__ = [
|
|
15
15
|
Path.home() / f".{__project_name__}" / ".env",
|
|
16
16
|
Path.home() / f".{__project_name__}" / f".env.{__env__}",
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_logfire.py
RENAMED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
from typing import Annotated
|
|
4
4
|
|
|
5
5
|
import logfire
|
|
6
|
-
from pydantic import Field, SecretStr
|
|
7
|
-
from pydantic_settings import
|
|
6
|
+
from pydantic import Field, PlainSerializer, SecretStr
|
|
7
|
+
from pydantic_settings import SettingsConfigDict
|
|
8
8
|
|
|
9
9
|
from ._constants import __env__, __env_file__, __project_name__, __repository_url__, __version__
|
|
10
|
-
from ._settings import load_settings
|
|
10
|
+
from ._settings import OpaqueSettings, load_settings
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class LogfireSettings(
|
|
13
|
+
class LogfireSettings(OpaqueSettings):
|
|
14
14
|
"""Configuration settings for Logfire integration."""
|
|
15
15
|
|
|
16
16
|
model_config = SettingsConfigDict(
|
|
@@ -22,6 +22,7 @@ class LogfireSettings(BaseSettings):
|
|
|
22
22
|
|
|
23
23
|
token: Annotated[
|
|
24
24
|
SecretStr | None,
|
|
25
|
+
PlainSerializer(func=OpaqueSettings.serialize_sensitive_info, return_type=str, when_used="always"),
|
|
25
26
|
Field(description="Logfire token. Leave empty to disable logfire.", examples=["YOUR_TOKEN"], default=None),
|
|
26
27
|
]
|
|
27
28
|
instrument_system_metrics: Annotated[
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_sentry.py
RENAMED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
from typing import Annotated
|
|
4
4
|
|
|
5
5
|
import sentry_sdk
|
|
6
|
-
from pydantic import Field, SecretStr
|
|
7
|
-
from pydantic_settings import
|
|
6
|
+
from pydantic import Field, PlainSerializer, SecretStr
|
|
7
|
+
from pydantic_settings import SettingsConfigDict
|
|
8
8
|
from sentry_sdk.integrations.typer import TyperIntegration
|
|
9
9
|
|
|
10
10
|
from ._constants import __env__, __env_file__, __project_name__, __version__
|
|
11
|
-
from ._settings import load_settings
|
|
11
|
+
from ._settings import OpaqueSettings, load_settings
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class SentrySettings(
|
|
14
|
+
class SentrySettings(OpaqueSettings):
|
|
15
15
|
"""Configuration settings for Sentry integration."""
|
|
16
16
|
|
|
17
17
|
model_config = SettingsConfigDict(
|
|
@@ -23,6 +23,7 @@ class SentrySettings(BaseSettings):
|
|
|
23
23
|
|
|
24
24
|
dsn: Annotated[
|
|
25
25
|
SecretStr | None,
|
|
26
|
+
PlainSerializer(func=OpaqueSettings.serialize_sensitive_info, return_type=str, when_used="always"),
|
|
26
27
|
Field(description="Sentry DSN", examples=["https://SECRET@SECRET.ingest.de.sentry.io/SECRET"], default=None),
|
|
27
28
|
]
|
|
28
29
|
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_settings.py
RENAMED
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import TypeVar
|
|
8
8
|
|
|
9
|
-
from pydantic import ValidationError
|
|
9
|
+
from pydantic import FieldSerializationInfo, SecretStr, ValidationError
|
|
10
10
|
from pydantic_settings import BaseSettings
|
|
11
11
|
from rich.panel import Panel
|
|
12
12
|
from rich.text import Text
|
|
@@ -17,6 +17,18 @@ T = TypeVar("T", bound=BaseSettings)
|
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
20
|
+
UNHIDE_SENSITIVE_INFO = "unhide_sensitive_info"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class OpaqueSettings(BaseSettings):
|
|
24
|
+
@staticmethod
|
|
25
|
+
def serialize_sensitive_info(input_value: SecretStr, info: FieldSerializationInfo) -> str | None:
|
|
26
|
+
if not input_value:
|
|
27
|
+
return None
|
|
28
|
+
if info.context.get(UNHIDE_SENSITIVE_INFO, False): # type: ignore
|
|
29
|
+
return input_value.get_secret_value()
|
|
30
|
+
return str(input_value)
|
|
31
|
+
|
|
20
32
|
|
|
21
33
|
def load_settings(settings_class: type[T]) -> T:
|
|
22
34
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/__init__.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_api.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_cli.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_constants.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_models.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/hello/_settings.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/system/_cli.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_api.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_cli.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_console.py
RENAMED
|
File without changes
|
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_health.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_log.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_process.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/_service.py
RENAMED
|
File without changes
|
{oe_python_template-0.10.1 → oe_python_template-0.10.2}/src/oe_python_template/utils/boot.py
RENAMED
|
File without changes
|