Skip to content

Commit 7b33406

Browse files
authored
[MISC] Enforce type checking (#146)
* chore: Add type checker configuration * chore: Type check tests * chore: Add S3 env vars to pass_env in tox.ini
1 parent fa20533 commit 7b33406

File tree

16 files changed

+739
-464
lines changed

16 files changed

+739
-464
lines changed

poetry.lock

Lines changed: 652 additions & 429 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ optional = true
4343
[tool.poetry.group.lint.dependencies]
4444
ruff = ">=0.14.7"
4545
codespell = ">=2.4.1"
46-
boto3-stubs = { extras = ["s3"], version = "^1.41.5" }
46+
mypy = "^1.17.1"
47+
boto3-stubs = { extras = ["s3"], version = "^1.42.0" }
48+
types-pyyaml = "^6.0.12.20250915"
49+
types-requests = "^2.32.4.20260107"
4750

4851
[tool.poetry.group.unit]
4952
optional = true
@@ -91,9 +94,28 @@ extend-ignore = [
9194
"D413",
9295
]
9396
ignore = ["E501", "D107"]
94-
per-file-ignores = { "tests/*" = ["D100", "D101", "D102", "D103", "D104", "E999"], "src/literals.py" = ["D101"] }
97+
per-file-ignores = { "tests/*" = ["D100", "D101", "D102", "D103", "D104", "E999"], "src/literals.py" = ["D101"], "src/*/__init__.py" = ["D104"] }
9598
mccabe.max-complexity = 10
9699

100+
[tool.mypy]
101+
exclude = [
102+
"lib",
103+
]
104+
follow_imports = "silent"
105+
106+
[[tool.mypy.overrides]]
107+
module = [
108+
"charms.data_platform_libs.*",
109+
"charms.grafana_k8s.*",
110+
"charms.loki_k8s.*",
111+
"charms.prometheus_k8s.*",
112+
"charms.tls_certificates_interface.*",
113+
"charms.oauth2_proxy_k8s.*",
114+
"charms.oathkeeper.*",
115+
"charms.traefik_k8s.*",
116+
]
117+
ignore_missing_imports = true
118+
97119
# Testing tools configuration
98120
[tool.coverage.run]
99121
branch = true

src/common/__init__.py

Whitespace-only changes.

src/core/__init__.py

Whitespace-only changes.

src/core/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def __init__(self, charm: CharmBase):
5353
def authorized_users(self) -> str | None:
5454
"""The comma-separated list of authorized users."""
5555
return (
56-
self.charm.config[AUTHORIZED_USERS]
56+
str(self.charm.config[AUTHORIZED_USERS])
5757
if (self._oathkeeper_relation or self._oauth2_proxy_relation)
5858
else None
5959
)

src/events/__init__.py

Whitespace-only changes.

src/events/base.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ def get_app_status(
7070
return Status.ACTIVE.value
7171

7272

73-
def compute_status(
74-
hook: Callable[[BaseEventHandler, EventBase], None],
75-
) -> Callable[[BaseEventHandler, EventBase], None]:
73+
def compute_status(hook: Callable) -> Callable[[BaseEventHandler, EventBase], None]:
7674
"""Decorator to automatically compute statuses at the end of the hook."""
7775

7876
@wraps(hook)
@@ -100,7 +98,7 @@ def wrapper_hook(event_handler: BaseEventHandler, event: EventBase):
10098

10199

102100
def defer_when_not_ready(
103-
hook: Callable[[BaseEventHandler, EventBase], None],
101+
hook: Callable,
104102
) -> Callable[[BaseEventHandler, EventBase], None]:
105103
"""Decorator to automatically compute statuses at the end of the hook."""
106104

src/events/ingress.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,9 @@ def _on_ingress_ready(self, event: IngressPerAppReadyEvent):
8484
@defer_when_not_ready
8585
def _on_ingress_revoked(self, _: IngressPerAppRevokedEvent):
8686
"""Handle the `IngressPerAppRevokedEvent`."""
87-
self.log_result("This app no longer has ingress")(
88-
self.history_server.update(
89-
self.context.s3, self.context.azure_storage, None, self.context.authorized_users
90-
)
87+
self.logger.info("This app no longer has ingress")
88+
self.history_server.update(
89+
self.context.s3, self.context.azure_storage, None, self.context.authorized_users
9190
)
9291

9392
self.charm.unit.status = self.get_app_status(

src/managers/__init__.py

Whitespace-only changes.

src/managers/history_server.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
"""History Server manager."""
66

77
import os
8-
import re
9-
from urllib.parse import ParseResult, urlparse
8+
from urllib.parse import ParseResult, urlparse, urlunparse
109

1110
from common.utils import WithLogging, is_proxy_skipped
1211
from core.context import (
@@ -26,8 +25,6 @@
2625
class HistoryServerConfig(WithLogging):
2726
"""Class representing the Spark Properties configuration file."""
2827

29-
_ingress_pattern = re.compile("http://.*?/|https://.*?/")
30-
3128
_base_conf: dict[str, str] = {
3229
"spark.hadoop.fs.s3a.path.style.access": "true",
3330
"spark.eventLog.enabled": "true",
@@ -60,13 +57,14 @@ def _ingress_proxy_conf(self) -> dict[str, str]:
6057
if not self.ingress:
6158
return {}
6259

63-
# Get DNS and skip the trailing /
64-
proxy_dns = self._ingress_pattern.match(f"{self.ingress.url}/").group()[:-1]
65-
proxy_base = str(self.ingress.url).removeprefix(proxy_dns)
60+
parsed_ingress = urlparse(self.ingress.url)
61+
redirect_uri = urlunparse((parsed_ingress.scheme, parsed_ingress.netloc, "", "", "", ""))
62+
ingress_properties = {"spark.ui.proxyRedirectUri": redirect_uri}
6663

67-
return {"spark.ui.proxyRedirectUri": proxy_dns} | (
68-
{"spark.ui.proxyBase": proxy_base} if proxy_base != "/" else {}
69-
)
64+
if base := parsed_ingress.path.strip("/"):
65+
ingress_properties["spark.ui.proxyBase"] = base
66+
67+
return ingress_properties
7068

7169
@property
7270
def _s3_conf(self) -> dict[str, str]:

0 commit comments

Comments
 (0)