oe-python-template 0.13.14__py3-none-any.whl → 0.13.16__py3-none-any.whl
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/utils/_log.py +42 -1
- oe_python_template/utils/_sentry.py +2 -2
- {oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/METADATA +1 -1
- {oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/RECORD +7 -7
- {oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/WHEEL +0 -0
- {oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/entry_points.txt +0 -0
- {oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/licenses/LICENSE +0 -0
oe_python_template/utils/_log.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"""Logging configuration and utilities."""
|
|
2
2
|
|
|
3
3
|
import logging as python_logging
|
|
4
|
+
import os
|
|
4
5
|
import typing as t
|
|
5
6
|
from logging import FileHandler
|
|
7
|
+
from pathlib import Path
|
|
6
8
|
from typing import Annotated, Literal
|
|
7
9
|
|
|
8
10
|
import click
|
|
9
11
|
import logfire
|
|
10
|
-
from pydantic import Field
|
|
12
|
+
from pydantic import AfterValidator, Field
|
|
11
13
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
12
14
|
from rich.console import Console
|
|
13
15
|
from rich.logging import RichHandler
|
|
@@ -31,6 +33,44 @@ def get_logger(name: str | None) -> python_logging.Logger:
|
|
|
31
33
|
return python_logging.getLogger(f"{__project_name__}.{name}")
|
|
32
34
|
|
|
33
35
|
|
|
36
|
+
def _validate_file_name(file_name: str | None) -> str | None:
|
|
37
|
+
"""Validate the file_name is valid and the file writeable.
|
|
38
|
+
|
|
39
|
+
- Checks file_name does not yet exist or is a file
|
|
40
|
+
- If not yet existing, checks it can be created
|
|
41
|
+
- If existing file, checks file is writeable
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
file_name: The file name of the log file
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
str | None: The validated file name
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
ValueError: If file name is not valid or the file not writeable
|
|
51
|
+
"""
|
|
52
|
+
if file_name is None:
|
|
53
|
+
return file_name
|
|
54
|
+
|
|
55
|
+
file_path = Path(file_name)
|
|
56
|
+
if file_path.exists():
|
|
57
|
+
if not file_path.is_file():
|
|
58
|
+
message = f"File name {file_path.absolute()} is not a file"
|
|
59
|
+
raise ValueError(message)
|
|
60
|
+
if not os.access(file_path, os.W_OK):
|
|
61
|
+
message = f"File {file_path.absolute()} is not writable"
|
|
62
|
+
raise ValueError(message)
|
|
63
|
+
else:
|
|
64
|
+
try:
|
|
65
|
+
file_path.touch(exist_ok=False)
|
|
66
|
+
file_path.unlink()
|
|
67
|
+
except OSError as e:
|
|
68
|
+
message = f"File {file_path.absolute()} cannot be created: {e}"
|
|
69
|
+
raise ValueError(message) from e
|
|
70
|
+
|
|
71
|
+
return file_name
|
|
72
|
+
|
|
73
|
+
|
|
34
74
|
class LogSettings(BaseSettings):
|
|
35
75
|
"""Settings for configuring logging behavior."""
|
|
36
76
|
|
|
@@ -51,6 +91,7 @@ class LogSettings(BaseSettings):
|
|
|
51
91
|
]
|
|
52
92
|
file_name: Annotated[
|
|
53
93
|
str,
|
|
94
|
+
AfterValidator(_validate_file_name),
|
|
54
95
|
Field(description="Name of the log file", default=f"{__project_name__}.log"),
|
|
55
96
|
]
|
|
56
97
|
console_enabled: Annotated[
|
|
@@ -77,7 +77,7 @@ def _validate_sentry_domain(netloc_with_auth: str) -> None:
|
|
|
77
77
|
raise ValueError(_ERR_MSG_INVALID_DOMAIN)
|
|
78
78
|
|
|
79
79
|
|
|
80
|
-
def
|
|
80
|
+
def _validate_https_dsn(value: SecretStr | None) -> SecretStr | None:
|
|
81
81
|
"""Validate that the Sentry DSN is a valid HTTPS URL.
|
|
82
82
|
|
|
83
83
|
Args:
|
|
@@ -124,7 +124,7 @@ class SentrySettings(OpaqueSettings):
|
|
|
124
124
|
dsn: Annotated[
|
|
125
125
|
SecretStr | None,
|
|
126
126
|
BeforeValidator(strip_to_none_before_validator),
|
|
127
|
-
AfterValidator(
|
|
127
|
+
AfterValidator(_validate_https_dsn),
|
|
128
128
|
PlainSerializer(func=OpaqueSettings.serialize_sensitive_info, return_type=str, when_used="always"),
|
|
129
129
|
Field(description="Sentry DSN", examples=["https://SECRET@SECRET.ingest.de.sentry.io/SECRET"], default=None),
|
|
130
130
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oe-python-template
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.16
|
|
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/
|
|
@@ -24,17 +24,17 @@ oe_python_template/utils/_constants.py,sha256=FRe5ZNaBwpBPwOHZVWYOlI-ijamfzdBVr8
|
|
|
24
24
|
oe_python_template/utils/_di.py,sha256=KdjiD4xZ_QSfbddkKWwsPJmG5YrIg6dzuBrlsd-FhxA,2189
|
|
25
25
|
oe_python_template/utils/_gui.py,sha256=PmMTSmUOxbf6pmYCIgKrK5wNheh35aGd90I12y3L7Uc,5720
|
|
26
26
|
oe_python_template/utils/_health.py,sha256=35QOWe2r5InrEpGtuVMym9dI5aRHS0HWf4BHBRAUIj0,4102
|
|
27
|
-
oe_python_template/utils/_log.py,sha256=
|
|
27
|
+
oe_python_template/utils/_log.py,sha256=5tMW1xY_FlpPEfZNeaTCdngBF3FKp8VWmQatt4_7RFU,4863
|
|
28
28
|
oe_python_template/utils/_logfire.py,sha256=wZYNVowQx7kh3XJoJ59FjUKdrta7tp6cXOJRUT6lDU8,2128
|
|
29
29
|
oe_python_template/utils/_notebook.py,sha256=oBQw9IBcXjuhzd1ECfOEPN4WJHGOm9xiPtrs11GtWG4,1777
|
|
30
30
|
oe_python_template/utils/_process.py,sha256=40R0NZMqJUn0iUPERzohSUpJgU1HcJApIg1HipIxFCw,941
|
|
31
|
-
oe_python_template/utils/_sentry.py,sha256=
|
|
31
|
+
oe_python_template/utils/_sentry.py,sha256=6SZknbGBpdZHYUpF-11qk6UYBM-c79U8D9sF4517kdU,6369
|
|
32
32
|
oe_python_template/utils/_service.py,sha256=atHAejvBucKXjzhsMSdOBBFa7rRD74zcV70Pp0pl0Tg,1038
|
|
33
33
|
oe_python_template/utils/_settings.py,sha256=owFoaHEzJnVD3EVyOWF4rfIY7g6eLnU6rN0m4VHhCbA,2464
|
|
34
34
|
oe_python_template/utils/boot.py,sha256=Qgq1sjT8d3fcfibnMyx5CVUJ_KKXgFI3ozZUIJbhh4I,2921
|
|
35
35
|
oe_python_template/utils/.vendored/bottle.py,sha256=kZAZmh3nRzCUf-9IKGpv0yqlMciZMA_DNaaMDdcQmt0,175437
|
|
36
|
-
oe_python_template-0.13.
|
|
37
|
-
oe_python_template-0.13.
|
|
38
|
-
oe_python_template-0.13.
|
|
39
|
-
oe_python_template-0.13.
|
|
40
|
-
oe_python_template-0.13.
|
|
36
|
+
oe_python_template-0.13.16.dist-info/METADATA,sha256=zqRR7YIXUY-XV10xXh4MvmdN2SFKaPGJNmcuvsyDAuo,34476
|
|
37
|
+
oe_python_template-0.13.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
oe_python_template-0.13.16.dist-info/entry_points.txt,sha256=IroSSWhLGxus9rxcashkYQda39TTvf7LbUMYtOKXUBE,66
|
|
39
|
+
oe_python_template-0.13.16.dist-info/licenses/LICENSE,sha256=5H409K6xzz9U5eUaoAHQExNkoWJRlU0LEj6wL2QJ34s,1113
|
|
40
|
+
oe_python_template-0.13.16.dist-info/RECORD,,
|
|
File without changes
|
{oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{oe_python_template-0.13.14.dist-info → oe_python_template-0.13.16.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|