Skip to content

Add Xylem Data Lake adapter#211

Merged
dmarulli merged 3 commits intomainfrom
dmarulli/xylem-datalake-adapter
Apr 15, 2026
Merged

Add Xylem Data Lake adapter#211
dmarulli merged 3 commits intomainfrom
dmarulli/xylem-datalake-adapter

Conversation

@dmarulli
Copy link
Copy Markdown
Collaborator

Summary

  • New adapter (xylem_datalake) for fetching AMI data from Xylem's Data Lake platform via the Superset SQL Lab API
  • Extracts from three tables: account (metadata), water_intervals (interval reads), water_registers (register reads)
  • Auth via Keycloak PKCE OAuth with automatic session management, CSRF refresh, and re-auth with exponential backoff on expiry
  • Parameterized by agency_code — works for any Xylem Data Lake agency (tested with Hillsborough)
  • Auth module is designed to be swappable when Xylem rolls out MFA requirements

Files changed

  • amiadapters/adapters/xylem_datalake.py — adapter implementation (extract, transform, raw loaders)
  • amiadapters/configuration/models.py — config and secrets models, enum registration
  • amiadapters/config.py — factory wiring
  • docs/adapters/xylem_datalake.md — adapter documentation
  • test/fixtures/xylem-datalake-*.yaml — local test config fixtures
  • test/manual/test_xylem_datalake.py — manual end-to-end test script

Test plan

  • Extract tested against Hillsborough Data Lake: 5,147 accounts, 87K interval reads, 87K register reads
  • Transform verified: 5,145 meters, 87K reads with correct field mapping
  • Session expiry mid-extract handled gracefully (504 → re-auth → resumed)
  • Snowflake load (uses shared load infrastructure, not separately tested)

New adapter for fetching AMI data from Xylem's Data Lake platform
(Superset SQL Lab API over Redshift). Extracts from account,
water_intervals, and water_registers tables. Auth via Keycloak PKCE
OAuth with session management and re-auth on expiry.

Tested end-to-end against Hillsborough Data Lake: extract (5,147
accounts, 87K interval reads, 87K register reads) and transform
(5,145 meters, 87K reads) confirmed working.
Copy link
Copy Markdown
Collaborator

@mdowell12 mdowell12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow! Looks great @dmarulli . I hope it wasn't too painful to add the new adapter and I'm encouraged that you made one that looks this good on your first try :)

I saw your manual test. Would you consider adding unit tests for the adapter, too? Even some basic tests, especially of the transform, can be useful down the road. There are lots of examples in the codebase and I've found that AI tools are pretty good at this. Up to you.

To fix the linter, you can run black . in the root directory.

- 12 unit tests for transform logic (basic, join, filter, edge cases)
- Black formatting applied
- Fix: meter_size from Superset comes as float, cast to str before map_meter_size
@dmarulli
Copy link
Copy Markdown
Collaborator Author

Thank you @mdowell12 ! It wasn't too painful. We did it in a few stages, with a bunch of AI support along the way. @christophertull had come up with the basic concept in a notebook and done some prototyping, I worked with that to polish some auth issues and wire up to snowflake, and then once we saw the prototype was generating clean data, I ported it into the adapter framework. I'm sure all the existing docs and transcript from our zoom walkthrough provided valuable context!

Merging.

@dmarulli dmarulli merged commit f3a1c66 into main Apr 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants