Commit Graph
408 Commits
Author SHA1 Message Date
James Woglom d2e947ffa3 Add get_pump_logs() BFF events fetch with typed response
Implement TandemSourceApi.get_pump_logs(device_id, ...) for GET
api/reports/bff/pump-logs/{assignmentId}?pumperId&startDate&endDate&eventIds,
the JSON events endpoint that replaces the base64 reportsfacade/pumpevents.
startDate/endDate are sent as {ymd}T00:00:00Z / {ymd}T23:59:59Z per the
captured request. Adds typed PumpLogsResponse/PumpLogEvent TypedDicts,
verified to cover every key across all captured pump-logs responses.

Tests: URL/path/param construction (order-independent parse_qs), default
vs custom vs empty eventIds, empty query dict passthrough, return
passthrough, and None-dates-default-to-today.
2026-07-01 01:38:39 +00:00
James Woglom 27ddf0cb1d Rename misleading check.py local var to deviceId
The device-id flow now carries the UUID assignmentId (as deviceId) end to
end; rename the leftover tconnectDeviceId local in check.py to match. The
deviceId flow is exercised by the existing choose_device, process and
update_profiles tests.
2026-07-01 01:27:09 +00:00
James Woglom b60bfb94ee Add Phase-2 backfill tests (update_profiles, adapter, event ids)
- tests/sync/tandemsource/test_update_profiles.py: settings sourcing from
  pump_metadata() — matching deviceId with settings reaches
  PumpSettings.from_dict (proven via sentinel, using the real BFF
  settings.details shape); settings=None / no-match / empty return False
  without parsing.
- test_tandemsource.py: adapter edge cases (availableDataRange/settings
  keys absent, missing required key raises KeyError, Mobi Control-IQ+
  passthrough) and DEFAULT_EVENT_IDS regression (55 ids, no dupes,
  477/480/486 present).

Fixtures are inline and trimmed from the real captured responses.
2026-07-01 01:26:22 +00:00
James Woglom 4c548203a5 Migrate metadata consumers to BFF pump_metadata()
Switch choose_device, check, update_profiles, process.py and cli_helpers
from the old pump_event_metadata() (reportsfacade) to the normalized
pump_metadata() (BFF): tconnectDeviceId -> deviceId (UUID), and
lastUpload.settings -> settings.

Handle the BFF returning never-uploaded pumps (maxDateWithEvents=None):
skip them in the most-recent auto-select and fall back to the first
pump; raise a clear NoDevicesFound on an empty account instead of an
opaque TypeError. Clean stale comments/docstrings in tandemsource.py.

Tests: add tests/sync/tandemsource/test_choose_device.py (11 cases:
explicit/auto/never-uploaded/empty/InvalidSerialNumber/stale-warning)
and tests/api/test_tandemsource.py (pump_metadata adapter mapping),
and update the test_process fixture to the new keys.
2026-07-01 01:18:52 +00:00
James Woglom 5c5449d5bd Add normalized PumpMetadata model + BFF adapter
Introduce a typed PumpMetadata TypedDict and pump_metadata()/
_bff_pump_to_metadata() that adapt get_pumper().pumps[] into the stable
shape the sync code needs. Maps the new BFF fields to normalized names:
assignmentId -> deviceId (UUID), maxDateOfEvents -> maxDateWithEvents,
availableDataRange.start -> minDateWithEvents, settings.details ->
settings. Verified against the captured account response (7 pumps).

Additive only; consumers are migrated off pump_event_metadata() in a
follow-up commit.
2026-07-01 01:04:16 +00:00
James Woglom 8761e70b18 Add get_pumper() BFF metadata method with typed response
Add TandemSourceApi.get_pumper() for GET api/reports/bff/pumper/{pumperId},
the new device-list endpoint that replaces pumpeventmetadata. Adds
strictly-typed TypedDicts (BffPumper, BffPump, AvailableDataRange,
PumpSettingsEnvelope) derived from the captured account response; verified
they exactly cover the real JSON keys. pumps[].assignmentId is the UUID
device id for the pump-logs endpoint; settings.details (typed as dict for
now) will be modeled by PumpSettings in a later step. Nullable/absent
fields use total=False + Optional.
2026-07-01 01:02:23 +00:00
James Woglom f124b884b2 Harden id_token audience validation in extract_jwt
After the client_id change, extract_jwt still validates the id_token
audience against TDC_OIDC_CLIENT_ID (the OIDC-standard case). But since
the token exchange wasn't captured, we can't be certain Tandem sets
aud=client_id on the id_token. If it doesn't, fall back to decoding with
verify_aud disabled (signature + issuer still verified) and log a
warning, rather than failing login outright.
2026-07-01 01:00:30 +00:00
James Woglom d568a5be85 Update US Tandem Source OIDC client_id
The Tandem Source web app now authenticates with client_id
0oa4wnbvtladeyVZX4h7 (US); the old 0oa27ho9tpZE9Arjy4h7 no longer
appears in the current build. This value is used both for the OIDC
authorize/token requests and the id_token audience check, which stay
consistent. EU client_id left unchanged (no EU capture to verify).
2026-07-01 00:59:14 +00:00
James Woglom 654ee7ead3 Update DEFAULT_EVENT_IDS to the live 55-ID pump-logs list
Match the Tandem Source web app's getLogIDList() as observed in the live
GET api/reports/bff/pump-logs request (from the captured HAR). Adds the
FSL3 event ids 477 (join), 480 (data), 486 (stop); reorders to match the
frontend. No removals (was 52 ids, now 55).
2026-07-01 00:53:11 +00:00
James Woglom 9619174958 CI: run on dev branch (replaces develop)
The develop branch was replaced by dev, so point the push/pull_request
triggers at dev instead of the now-removed develop branch.
2026-07-01 00:27:19 +00:00
James Woglom a9c9a7ebd9 Add type annotations to TandemSource sync processors
Annotate the 11 event processors, the ProcessTimeRange orchestrator, and
UpdateProfiles. The shared processor interface is now typed:
__init__(tconnect, nightscout, tconnect_device_id, pretend, features),
enabled() -> bool, process(events, time_start, time_end) -> List[dict],
write(ns_entries) -> int. Converter helpers return Optional[dict] since
they fall through to None on type mismatch.

ProcessTimeRange.process() returns Tuple[int, Optional[int]] and its
tconnectDevice param reuses the PumpEventMetadata TypedDict. Client
params (TConnectApi/NightscoutApi/BaseEvent) use TYPE_CHECKING-guarded
imports with string forward refs to avoid import cycles at runtime.
2026-06-30 23:29:17 +00:00
James Woglom 8fd9bfcf72 Add type annotations to NightscoutApi
Annotate NightscoutApi methods and the module-level date helpers. Adds a
DateLike alias (str | datetime | arrow.Arrow) for the timestamp/filter
params. Writers return None; the last_uploaded_* getters return
Optional[dict]; api_status/current_profile return dict.

Response shapes are kept as loose dict/Optional[dict] rather than
TypedDicts since the Nightscout API shape varies across versions; only
inputs (which we control) are tightly typed.
2026-06-30 23:20:35 +00:00
James Woglom 000bae38b6 Add precise type annotations to TandemSourceApi
Annotate method signatures and dynamic JSON response types. Adds
TypedDicts for the responses whose shapes are confirmed from call sites
and logs:
- PumpEventMetadata (+ nested LastUpload) for pump_event_metadata()
- JwtClaims for the decoded id_token stored on jwtData; pumperId and
  accountId are UUID strings, not ints

pump_events_raw() returns a base64 str (not Any). pumper_info() stays
Any since it has no callers and its shape is never logged. TypedDict is
imported with a typing_extensions fallback for Python 3.7.
2026-06-30 23:14:06 +00:00
ClaudeandJames Woglom ea7cc8f4ec Remove dead code for legacy pre-Tandem Source APIs
Since the 2.0 migration to Tandem Source, the live sync path
(api.tandemsource + sync/tandemsource/*) no longer references the
legacy t:connect APIs. This removes that now-unreachable code.

Removed modules:
- api/controliq.py, api/ws2.py, api/android.py, api/webui.py
  (the legacy controliq / tconnectws2 / android / webui clients)
- process.py (old process_time_range; already broken since it
  imported sync submodules that no longer exist)
- parser/ciq_therapy_events.py, parser/tconnect.py (TConnectEntry)
- domain/therapy_event.py, domain/bolus.py, domain/device_settings.py,
  domain/utility.py

Trimmed dead wiring from live modules:
- api/__init__.py: dropped the controliq/ws2/android/webui properties,
  keeping only the tandemsource accessor
- check.py: removed the unused TConnectEntry import
- parser/nightscout.py: removed the unused legacy profile_store() plus
  the now-orphaned tandem_to_ns_time / tandem_to_ns_time_seconds helpers
  and InvalidTimeException (the live path uses tandemsource_profile_store)

Tests: removed suites covering the deleted modules; pared tests/api/fake.py
down to the TConnectApi fake still used by the tandemsource tests. README
"Tandem APIs" sections updated to reflect the single Tandem Source API.

Full test suite passes (48 passed, 1 skipped).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQNn3mBG1kXTAdQb9c2jfW
2026-06-30 19:12:44 -04:00
James Woglom e5195b2613 Fix WAF 403 by sending same-origin Origin/Referer to Source API
api_headers() hardcoded Origin/Referer to tconnect.tandemdiabetes.com,
but requests target SOURCE_URL (source.tandemdiabetes.com /
source.eu.tandemdiabetes.com). The WAF enforces same-origin and
returned HTTP 403 ("The request is blocked"). Derive Origin/Referer
from SOURCE_URL so both US and EU regions match.
2026-06-30 22:56:26 +00:00
Beshoy GirgisandJames Woglom f0f94baf02 revert nightscout.py 2026-03-27 11:08:23 -07:00
Beshoy GirgisandJames Woglom bf894bce02 Add script to update events.json from minified url 2026-03-27 11:08:23 -07:00
Beshoy GirgisandJames Woglom 594ee19450 Add Freestyle Libre 3 (FSL3) CGM sensor support
Implement FSL3 sensor integration alongside G6, G7, and FSL2 with expanded
CGM alert codes, improved datetime handling, and test coverage.

**FSL3 Event Integration:**
- Add FSL3 events to CGM_READING, _CGM_JOIN, and _CGM_STOP event classes
- Enable unified processing of FSL3 alongside existing sensor variants:
  - Event 480: LID_CGM_DATA_FSL3
  - Event 477: LID_CGM_JOIN_SESSION_FSL3
  - Event 486: LID_CGM_STOP_SESSION_FSL3

**CGM Alert Enumeration:**
- Expand CGM alert codes from 8 to 18 mapped codes
- Add verified alert codes: 1, 2, 3, 8, 12, 22, 25, 45, 46, 48
- Rename alert 51 to CONTROL_IQ_LOW (was DEFAULT_ALERT_51)
- Add alert descriptions based on pump history verification

**Code Quality Improvements:**
- Fix duplicate enum keys in events.json (Sensor Type codes 12, 13)
- Add logging infrastructure to generic.py for event diagnostics
- Add conftest.py test configuration

**DateTime and API Improvements:**
- Fix format_datetime() for proper UTC conversion with Z suffix
- Simplify Nightscout API methods by removing redundant retry logic
- Improve error reporting in last_uploaded_entry() and last_uploaded_bg_entry()

**Test Coverage:**
- Add 3 FSL3 test cases with real pump data
- Test single reading processing, multiple readings, and JOIN event parsing
- All 105 tests passing (102 existing + 3 new FSL3 tests)
2026-03-27 11:08:23 -07:00
James Woglom d78d70adf5 fix #136 2026-03-26 03:56:47 -04:00
James Woglom 8381e50fe6 fix duplicate enum keys 2026-03-15 13:53:03 -04:00
James Woglom 93b0901aae Update events.json blob 2026-03-15 13:35:43 -04:00
Alessio RosiandJames Woglom 82ccaa5a88 fix: upgrade Python 3.9 → 3.11 to fix missing python-dotenv 2026-03-15 02:22:10 -04:00
James Woglom b1f63f8858 v2.3.5 2026-03-05 19:22:32 -05:00
James Woglom 9878e83755 exclude venv from flake8 2026-03-05 19:17:12 -05:00
James Woglom d8b57fe788 remove duplicate pipfile definitions also in setup.cfg, fix actions 2026-03-05 19:13:21 -05:00
James Woglom 664f97be35 pin pyjwt in setup.cfg 2026-03-05 18:54:08 -05:00
James Woglom 9094976085 update for py3.8 2026-03-05 18:50:11 -05:00
James Woglom b592f6b464 ci 3.8: PyO3 modules compiled for CPython 3.8 or older may only be initialized once per interpreter process 2026-03-05 03:00:20 -05:00
James Woglom 4f2affe70f switch from pkg_resources to importlib_metadata 2026-03-05 02:54:45 -05:00
James Woglom 0733531f67 add setuptools dep 2026-03-05 02:50:33 -05:00
James Woglom 68dcb25911 v2.3.4 2025-12-14 23:59:06 -05:00
James Woglom 795361c6ad timezone tests 2025-12-14 23:58:35 -05:00
James Woglom c9190df50a timestamp override in tests 2025-12-14 23:56:30 -05:00
James Woglom 15160537f5 add process_cgm_reading tests 2025-12-14 23:52:55 -05:00
Andy LowandJames Woglom 1f1e755503 Add timezone support to timestamp calculation
Update timestamp handling to include timezone information.
2025-12-14 23:51:35 -05:00
James Woglom aea3f6bd6b v2.3.3 2025-11-23 00:03:34 -05:00
James Woglom 2bf40cac28 fix TypeError: can't compare offset-naive and offset-aware datetimes 2025-11-23 00:03:16 -05:00
James Woglom 73dabe5ead v2.3.2 2025-11-18 14:01:18 -05:00
James Woglom e848a8482d add new process test for tz change 2025-11-18 14:00:54 -05:00
James Woglom 9c06efb045 when pump TZ changes moves date into the future, do not add "current" basal to extend to that timestamp 2025-11-18 13:59:17 -05:00
James Woglom 64aeb4d752 v2.3.1 2025-06-08 17:17:13 -04:00
James Woglom 6a9a426b97 explicit time_start/time_end for autoupdate 2025-06-08 11:07:57 -04:00
samfundevandJames Woglom 5a76a4cfd1 Fix auto-update only running for 24 hours
Fixes #11
2025-06-08 11:06:24 -04:00
James Woglom 4837ac1e86 v2.3.0 2025-06-07 23:34:42 -04:00
James Woglom 8b15ec5c90 add test_profile_data 2025-06-07 23:31:10 -04:00
James Woglom 37b008f6c3 fix test path 2025-06-07 23:29:09 -04:00
James Woglom 8c40fdb533 fix test import 2025-06-07 23:27:42 -04:00
James Woglom d51080f6d0 Fix profile test 2025-06-07 23:24:41 -04:00
James Woglom b32415aaac Delete dead non-tandem source tests 2025-06-07 23:21:38 -04:00
James Woglom ffd3c5b1ea Delete dead non-tandem source code 2025-06-07 23:21:18 -04:00