Skip to content

US_CDC_PRAMS : Import Automation - #2205

Open
kartik-s21 wants to merge 69 commits into
datacommonsorg:masterfrom
kartik-s21:prams-automation
Open

kartik-s21 wants to merge 69 commits into
datacommonsorg:masterfrom
kartik-s21:prams-automation

Conversation

@kartik-s21

@kartik-s21 kartik-s21 commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Modernizes and automates the US_CDC_PRAMS import pipeline to ingest official consolidated multi-year Excel workbooks, expanding observation coverage from 2016 through 2022 (45,524 observations) across all 50 states, NYC, Puerto Rico, and aggregated sites.

This replaces the legacy Java/Tabula PDF scraper with a pure Python openpyxl pipeline, eliminates external JVM runtime dependencies, resolves historical Confidence Interval scaling factor discrepancies (ScalingFactor: 100.0), establishes automated dynamic workbook discovery for future years, and implements robust header validation and comma-safe numeric parsing.


Key Changes

1. Pipeline Modernization (scripts/cdc_prams/process.py)

  • Excel Ingestion: Migrated from fragile PDF scraping to official multi-year Excel workbooks (openpyxl), expanding date coverage from 2016–2020 to 2016–2022.
  • Header Validation: Added _validate_sheet_headers() to verify row 5 sub-headers (Denominator/Sample Size, Weighted %, Lower 95% CI, Upper 95% CI) before ingestion, preventing silent data corruption if CDC layout shifts.
  • Comma-Safe Numeric Parsing: Added _parse_float() to strip string commas (e.g., "1,200"), whitespace, and handle missing markers (na, -, *) cleanly with debug logging.
  • Unmapped StatVar Detection: Detects unmapped variables prior to in-place .map(), ensuring error logs and exceptions display actual variable names instead of [nan].
  • Duplicate & Geography Logging: Added warning logs when unknown site names are skipped and when duplicate keys are deduplicated.
  • Schema Harmonization: Aligned ScalingFactor: 100.0 across percentages and Confidence Interval lower/upper limits.
  • Atomic Publication: Writes all output files (PRAMS.csv, PRAMS.mcf, PRAMS.tmcf) to .tmp files and moves them atomically with os.replace().

2. Download Stage (scripts/cdc_prams/download_input_files.py & download.py)

  • Resilient Dynamic Discovery: In discover_excel_url(), dynamically discovers the latest multi-year workbook from the CDC landing page and logs explicit errors upon mismatch or network failures rather than silently falling back.
  • HTTP Retry Session: Configured _get_session() with urllib3.util.retry.Retry (5 retries with exponential backoff on 429, 500, 502, 503, 504) and shared across download scripts.

3. Configuration & Validation (validation_config.json & manifest.json)

  • Dynamic Date Freshness Check: Updated check_all_statvars_freshness to dynamically evaluate against CURRENT_DATE (CAST(SUBSTRING(CAST(MaxDate AS VARCHAR), 1, 4) AS INT) >= (EXTRACT(YEAR FROM CURRENT_DATE) - 4) AND MaxDate >= '2022').
  • Archive Retention: Added "manifest.json" to "source_files" in manifest.json.
  • Provenance Description: Aligned description with Google3 manifest: "US CDC Pregnancy Risk Assessment Monitoring System (PRAMS) MCH indicators across states, territories, and cities.".
  • Dependency Cleanup: Removed dead dependency tabula-py from import-automation/executor/requirements.txt and dead constant _YEAR / unused imports from constants.py.

Test Environment & Latest Cloud Batch Job Run

Artifact Links

Validation Suite Results

Rule ID Status Details
check_all_statvars_freshness PASSED Dynamic SQL check: MaxDate >= '2022' and within allowable survey lag
check_max_date_consistent PASSED Uniform MaxDate (2022) across 168/168 series
check_empty_import PASSED 45,524 observation rows / nodes generated
check_lint_error_count PASSED 0 lint errors (threshold: 0)
check_missing_refs_count PASSED 0 missing references (threshold: 0)
check_deleted_records_percent NOTE 49.37% due to CI node hash updates from scalingFactor: 100.0 harmonization (0 real data loss)

Execution Performance

  • Script Execution Time: 3.99s
  • GenMCF Execution Time: 9.04s
  • Validation Time: 21.69s
  • Total Rows Processed: 45,524
  • Local Unit Tests: 7/7 passed in 0.163s

Linked Artifacts

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request establishes import automation for the US CDC Pregnancy Risk Assessment Monitoring System (PRAMS) dataset. The changes introduce a manifest, validation configurations, and golden datasets, while refactoring the download and processing scripts to use robust HTTP sessions and modern pandas methods. Unit tests have also been updated to use class-level setup and teardown. The review feedback suggests making the confidence interval string-splitting logic more robust against variable spacing and improving exception handling and caching during ZIP file downloads.

Comment thread scripts/cdc_prams/process.py Outdated
Comment thread scripts/cdc_prams/download.py Outdated
…tures

- Address CRA review findings for US CDC PRAMS import:
  * Drop suppressed data ('.' or '(.-.)') instead of converting to '0.0'
  * Fix CI regex to handle percentages >= 10.0% and prevent parenthesis truncation
  * Use named regex capturing groups for confidence interval column extraction
  * Add ScalingFactor=100 to lower and upper confidence interval limits
  * Update provenance and download URLs to canonical active endpoint
  * Implement atomic file downloads and artifact publishing (.tmp + os.replace)
  * Standardize logging with absl.logging.fatal
  * Add State and National test coverage in test fixtures and streamline datasets
  * Document Java 8+ prerequisite and automation cadence in README.md
…nicode dashes in CI regex, safe boolean masking for Postpartum, validate unmapped SVs, add deduplication, clean up download logic, and document refresh procedure
…, fix deletion check description, add validation_config.json and resource_limits to manifest, resolve exception contracts in helper functions, reformat long lines <= 100 chars, and enforce POSIX EOF newlines
…2016-2022)

- Transition from legacy 2016-2020 PDF parser (tabula-py) to pure Python openpyxl Excel ingestion.
- Dynamically discover and download official consolidated multi-year PRAMS Excel workbooks from the CDC landing page.
- Extend dataset coverage through observation year 2022 (45,524 total observations), preserving 2021 production data without regression.
- Update manifest.json, validation_config.json, and Google3 metadata to reflect the 2016-2022 observation date range.
- Replace PDF fixtures with lightweight Excel test fixture (< 50 KB) and verify hermetic unit tests pass in 0.16s.
…rsing, unmapped SV logging fix, dynamic date freshness, and dead dependency cleanup
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