Skip to content

Commit 5e79e91

Browse files
authored
🧱 Split parent-report and self-report into separate Curious applets (#21)
2 parents 936a61a + ce95dbf commit 5e79e91

30 files changed

Lines changed: 2170 additions & 1253 deletions

‎.pre-commit-config.yaml‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ repos:
3535
- id: terraform_checkov
3636
files: ^infrastructure/
3737
- repo: https://github.com/DavidAnson/markdownlint-cli2
38-
rev: v0.21.0
38+
rev: v0.22.0
3939
hooks:
4040
- id: markdownlint-cli2
4141
- repo: https://github.com/ninoseki/uv-sort
@@ -44,19 +44,19 @@ repos:
4444
- id: uv-sort
4545
files: pyproject.toml
4646
- repo: https://github.com/astral-sh/uv-pre-commit
47-
rev: "0.10.8"
47+
rev: "0.11.6"
4848
hooks:
4949
- id: uv-lock
5050
files: ^python_jobs/pyproject\.toml$
5151
args: [--project, python_jobs]
5252
- repo: https://github.com/astral-sh/ruff-pre-commit
53-
rev: v0.15.5
53+
rev: v0.15.10
5454
hooks:
5555
- id: ruff-check
5656
args: [ --fix ]
5757
- id: ruff-format
5858
- repo: https://github.com/pre-commit/mirrors-mypy
59-
rev: v1.19.1
59+
rev: v1.20.1
6060
hooks:
6161
- id: mypy
6262
exclude: \**/_config_variables/.*_variables/__init__\.py$
@@ -65,6 +65,7 @@ repos:
6565
- pandas-stubs
6666
- types-pytz
6767
- types-requests
68+
language_version: python3.14
6869
- repo: local
6970
hooks:
7071
- id: sync-version

‎CHANGELOG.md‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## 1.9.4
9+
10+
### Fixed
11+
12+
- Split config for Curious invitations.
13+
14+
## 1.9.3
15+
16+
### Added
17+
18+
- Exception handling for REDCap timeout.
19+
20+
## 1.9.2
21+
22+
### Fixed
23+
24+
- Commented out missing fields.
25+
26+
## 1.9.1
27+
28+
### Fixed
29+
30+
- Curious invitations CLI.
31+
- Config keys to set Curious applet credential environment variable names.
32+
33+
## 1.9.0
34+
35+
### Changed
36+
37+
- Split parent-report and self-report into separate Curious applets.
38+
- Updated mappings for REDCap PID 247 to PID 625.
39+
- Moved `enrollment_complete` from PID 247 to PID 625.
40+
41+
### Upgraded
42+
43+
- Python@3.14
44+
45+
### Deprecated
46+
47+
- `._config_variables.curious_variables.curious_variables.activity_ids`
48+
- `._config_variables.curious_variables.curious_variables.applet_ids`
49+
- `._config_variables.curious_variables.curious_variables.Credentials`
50+
- `._config_variables.curious_variables.curious_variables.AppletCredentials.hbn_mindlogger`
51+
852
## 1.8.0
953

1054
### Added

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.8.0
1+
1.9.4

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hbnmigration",
3-
"version": "1.8.0",
3+
"version": "1.9.4",
44
"private": true,
55
"description": "HBN data migration monitoring infrastructure with Python and Node.js services",
66
"workspaces": [

‎python_jobs/VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.8.0
1+
1.9.4

‎python_jobs/pyproject.toml‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
66
name = "hbnmigration"
77
dynamic = ["version"]
88
description = "WebSocket and API monitoring with Iceberg logging"
9-
requires-python = ">=3.12,<3.14"
9+
requires-python = ">=3.14,<3.16"
1010
dependencies = [
1111
"aiohttp>=3.9.0",
1212
"boto3>=1.34.0",
@@ -35,7 +35,7 @@ dependencies = [
3535
dev = [
3636
"aiohttp",
3737
"boto3-stubs[s3,glue]",
38-
"mypy>=1.8.0",
38+
"mypy>=1.20.0",
3939
"pytest-asyncio>=0.23.0",
4040
"pytest>=7.4.0",
4141
"ruff>=0.1.0",
@@ -55,11 +55,11 @@ where = ["src"]
5555

5656
[tool.ruff]
5757
line-length = 88
58-
target-version = "py312"
58+
target-version = "py314"
5959

6060
[tool.ruff.lint]
6161
extend-select = ["A", "B904", "C4", "D", "E", "EM", "F541", "G", "I", "ICN", "LOG007", "N", "NPY", "PL", "RET", "RSE", "RUF", "Q", "T20", "TRY002", "TRY201", "TRY400", "TRY401", "UP032", "W"]
62-
ignore = ["D203", "D212"]
62+
ignore = ["D203", "D212", "RUF002"]
6363

6464
[tool.ruff.lint.isort]
6565
combine-as-imports = true
@@ -73,7 +73,7 @@ known-first-party = ["mindlogger_data_export"]
7373
"test_*.py" = ["PLC0415", "PLR0913", "PLR2004"]
7474

7575
[tool.mypy]
76-
python_version = "3.12"
76+
python_version = "3.14"
7777
strict = true
7878
exclude = [
7979
".*_config_variables/.*_variables/__init__\\.py$"

‎python_jobs/src/hbnmigration/_config_variables/curious_variables/__init__.py‎

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,44 @@
11
"""Curious variables. Put secrets in `./curious_variables.py`."""
22

3-
from ...utility_functions import CuriousId, ImportWithFallback
3+
from ...utility_functions import (
4+
Credentials as CredentialsABC,
5+
CuriousApplets,
6+
CuriousId,
7+
Endpoints as EndpointsType,
8+
ImportWithFallback,
9+
Tokens as TokensType,
10+
)
411

5-
AppletCredentials = ImportWithFallback.module(
12+
AppletCredentials: type[CredentialsABC] = ImportWithFallback.module(
613
".curious_variables",
714
"AppletCredentials",
815
"...utility_functions.datatypes",
916
"Credentials",
1017
)
1118
"""Applet credentials for decryption."""
1219

13-
Credentials = ImportWithFallback.module(
20+
applets: CuriousApplets = ImportWithFallback.literal(
21+
".curious_variables", "applets", CuriousApplets()
22+
)
23+
24+
25+
Credentials: type[CredentialsABC] = ImportWithFallback.module(
1426
".curious_variables", "Credentials", "...utility_functions.datatypes"
1527
)
16-
"""Curious credentials."""
28+
"""Curious credentials.
29+
30+
.. version-deprecated:: 1.9.0
31+
Use `AppletCredentials`.
32+
"""
1733

18-
Endpoints = ImportWithFallback.module(
34+
Endpoints: type[EndpointsType] = ImportWithFallback.module(
1935
".curious_variables", "Endpoints", "...utility_functions.datatypes"
2036
)
2137
"""Curious endpoints."""
2238

2339
try:
2440
from .curious_variables import headers
25-
except (ImportError, ModuleNotFoundError):
41+
except ImportError, ModuleNotFoundError:
2642

2743
def headers(token: str) -> dict[str, str]:
2844
"""Curious headers."""
@@ -44,7 +60,7 @@ def headers(token: str) -> dict[str, str]:
4460
)
4561
"""Curious activity IDs."""
4662

47-
Tokens = ImportWithFallback.module(
63+
Tokens: type[TokensType] = ImportWithFallback.module(
4864
".curious_variables", "Tokens", "...utility_functions", "Tokens"
4965
)
5066
"""Curious tokens."""

‎python_jobs/src/hbnmigration/_config_variables/curious_variables/__init__.pyi‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ from .curious_variables import (
44
activity_ids,
55
applet_ids,
66
AppletCredentials,
7+
applets,
78
Credentials,
89
Endpoints,
910
headers,
@@ -18,6 +19,7 @@ __all__ = [
1819
"Tokens",
1920
"activity_ids",
2021
"applet_ids",
22+
"applets",
2123
"headers",
2224
"owner_ids",
2325
]
Lines changed: 125 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,151 @@
1-
"""Typestubs for secret Curious variables."""
1+
"""Curious variables (secret)."""
22

33
from typing import Optional
4+
from warnings import deprecated
45

56
from ...utility_functions import (
67
ApiProtocol,
78
Credentials as CredentialsABC,
9+
CuriousApplets,
810
CuriousId,
911
Endpoints as EndpointsABC,
1012
Tokens as TokensABC,
1113
)
1214

13-
class AppletCredentials(CredentialsABC):
14-
hbn_mindlogger: dict[str, dict[str, str]]
15+
applets: CuriousApplets
16+
17+
class _ActivityIds(type):
18+
"""Metaclass for deprecating `applet_ids` module-level global variable."""
19+
20+
_data: dict[str, str]
21+
def __getitem__(cls, key: str) -> CuriousId: ...
22+
23+
@deprecated("Deprecated in v1.9.0. Use `applets[applet_name].activities`.")
24+
class activity_ids(metaclass=_ActivityIds): # noqa: N801
25+
"""Curious activity IDs."""
26+
27+
@classmethod
28+
def __getitem__(cls, key: str) -> CuriousId: ...
29+
30+
class _AppletIds(type):
31+
"""Metaclass for deprecating `applet_ids` module-level global variable."""
32+
33+
_data: dict[str, str]
34+
def __getitem__(cls, key: str) -> CuriousId: ...
35+
36+
applet_ids: _AppletIds # type: ignore[no-redef]
37+
38+
@deprecated("Deprecated in v1.9.0. Use `applets`.")
39+
class applet_ids(metaclass=_AppletIds): # type: ignore[no-redef] # noqa: N801
40+
"""Curious applet IDs."""
1541

42+
@classmethod
43+
def __getitem__(cls, key: str) -> CuriousId: ...
44+
45+
@deprecated("Deprecated in v1.9.0. Use `AppletCredentials`.")
1646
class Credentials(CredentialsABC):
47+
"""API login credentials for 'hbn_mindlogger'."""
48+
49+
@staticmethod
50+
@deprecated("Deprecated in v1.9.0. Use `AppletCredentials[applet_name]`.")
51+
def _hbn_mindlogger() -> dict[str, str]:
52+
"""
53+
Applet credentials for decryption.
54+
55+
.. version-deprecated:: 1.9.0
56+
Use `AppletCredentials[applet_name]`
57+
"""
58+
1759
hbn_mindlogger: dict[str, str]
60+
"""API login credentials for 'hbn_mindlogger'.
61+
62+
.. version-deprecated:: 1.9.0
63+
Use `AppletCredentials[applet_name]`
64+
"""
65+
_hbn_mindlogger()
66+
67+
class AppletCredentials(CredentialsABC):
68+
"""Applet credentials for decryption."""
69+
70+
def __init__(self) -> None:
71+
"""Initialize Applet Credentials."""
72+
73+
@staticmethod
74+
@deprecated("Deprecated in v1.9.0. Use `AppletCredentials[applet_name]`.")
75+
def _hbn_mindlogger() -> dict[str, dict[str, str]]:
76+
"""
77+
Applet credentials for decryption.
78+
79+
.. version-deprecated:: 1.9.0
80+
Use `AppletCredentials[applet_name]`
81+
"""
82+
83+
hbn_mindlogger: dict[str, dict[str, str]]
84+
"""Applet credentials for decryption.
85+
86+
.. version-deprecated:: 1.9.0
87+
Use `AppletCredentials[applet_name]`
88+
"""
89+
_hbn_mindlogger()
90+
91+
def __getitem__(self, key: str) -> dict[str, str]:
92+
"""Get applet credentials for given applet name."""
1893

1994
class Endpoints(EndpointsABC):
20-
def __init__(self, host: str = ..., protocol: ApiProtocol = ...) -> None: ...
21-
def activity(self, activity_id: CuriousId) -> str: ...
95+
"""Curious endpoints."""
96+
97+
def __init__(
98+
self, host: str = "api-v2.gettingcurious.com", protocol: ApiProtocol = "https"
99+
) -> None:
100+
"""Initialize Curious API Endpoints."""
101+
self.host: str
102+
self.protocol: ApiProtocol
103+
104+
def activity(self, activity_id: CuriousId) -> str:
105+
"""Endpoint for activities."""
106+
22107
@property
23-
def alerts(self) -> str: ...
24-
def applet(self, applet_id: CuriousId) -> str: ...
108+
def alerts(self) -> str:
109+
"""Endpoint for alerts."""
110+
111+
def applet(self, applet_id: CuriousId) -> str:
112+
"""Return applet encryption info."""
113+
25114
def applet_activity_answers_list(
26115
self, applet_id: CuriousId, activity_id: CuriousId
27-
) -> str: ...
116+
) -> str:
117+
"""Return applet activity answers list endpoint."""
118+
28119
@property
29-
def auth(self) -> str: ...
30-
def invitation_statuses(self, owner_id: CuriousId, applet_id: CuriousId) -> str: ...
120+
def auth(self) -> str:
121+
"""Return authentication endpoint."""
122+
31123
@property
32-
def login(self) -> str: ...
124+
def _base_url(self) -> str:
125+
"""Base URL for Curious API calls."""
33126

34-
activity_ids: dict[str, CuriousId]
35-
applet_ids: dict[str, CuriousId]
36-
owner_ids: dict[str, CuriousId]
127+
@_base_url.setter
128+
def _base_url(self, url: str) -> None:
129+
"""Raise exception ― _base_url is calculated for Curious endpoints."""
130+
131+
def invitation_statuses(self, owner_id: CuriousId, applet_id: CuriousId) -> str:
132+
"""Return invitation statuses endpoint."""
37133

38-
def headers(token: Optional[str] = None) -> dict[str, str]: ...
134+
@property
135+
def login(self) -> str:
136+
"""Curious authentication endpoint."""
137+
138+
def headers(token: Optional[str]) -> dict[str, str]:
139+
"""Return Curious headers."""
140+
141+
owner_ids: dict[str, CuriousId]
142+
"""Curious project owner IDs."""
39143

40144
class Tokens(TokensABC):
41-
access: str
42-
endpoints: Endpoints
43-
refresh: str
145+
"""Curious tokens."""
44146

45-
def __init__(self, endpoints: Endpoints, credentials: dict[str, str]) -> None: ...
147+
def __init__(self, endpoints: Endpoints, credentials: dict[str, str]) -> None:
148+
"""Initialize Curious tokens."""
149+
self.endpoints: Endpoints
150+
self.access: str
151+
self.refresh: str

0 commit comments

Comments
 (0)