US_CDC_PRAMS : Import Automation - #2205
Conversation
Code fix unenergy
…s, and fix pipeline scripts
There was a problem hiding this comment.
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.
| df[i] = df[i].fillna('').astype(str).replace({ | ||
| '<NA>': '', | ||
| 'nan': '', | ||
| 'None': '' | ||
| }) | ||
| # Splitting the column based on space and "-" | ||
| df_split = df[i].str.split(r"\s+|-", expand=True) |
There was a problem hiding this comment.
Splitting the CI column using r"\s+|-" is fragile when there are spaces around the hyphen (e.g., 39.3 (36.4 - 42.2)). This results in empty columns in the split DataFrame, shifting the upper limit out of the first 3 columns and causing it to be lost. Normalizing the string by removing parentheses and replacing hyphens with spaces first, then splitting by whitespace, is much more robust and handles variable spacing gracefully.
| df[i] = df[i].fillna('').astype(str).replace({ | |
| '<NA>': '', | |
| 'nan': '', | |
| 'None': '' | |
| }) | |
| # Splitting the column based on space and "-" | |
| df_split = df[i].str.split(r"\s+|-", expand=True) | |
| df[i] = df[i].fillna('').astype(str).replace({ | |
| '\u003cNA\u003e': '', | |
| 'nan': '', | |
| 'None': '' | |
| }) | |
| # Normalize separators by removing parentheses and replacing hyphens with spaces | |
| normalized = df[i].str.replace(r'[\\(\\)]', '', regex=True).str.replace('-', ' ', regex=False).str.strip() | |
| df_split = normalized.str.split(r'\\s+', expand=True) |
| if download_file_url.endswith(".zip"): | ||
| with zipfile.ZipFile(io.BytesIO(req.content)) as zipfileout: | ||
| zipfileout.extractall(path) | ||
| else: | ||
| with open(out_file, 'wb') as file: | ||
| file.write(req.content) |
There was a problem hiding this comment.
When downloading and processing ZIP files, ensure that exception handling covers both network-related errors (e.g., requests.exceptions.RequestException) and ZIP-specific errors (e.g., zipfile.BadZipFile) to prevent the script from crashing on corrupted or invalid downloads. Additionally, writing the downloaded content to out_file first before extracting it ensures the caching mechanism works correctly and avoids redundant downloads.
| if download_file_url.endswith(".zip"): | |
| with zipfile.ZipFile(io.BytesIO(req.content)) as zipfileout: | |
| zipfileout.extractall(path) | |
| else: | |
| with open(out_file, 'wb') as file: | |
| file.write(req.content) | |
| try: | |
| with open(out_file, 'wb') as file: | |
| file.write(req.content) | |
| if download_file_url.endswith(".zip"): | |
| with zipfile.ZipFile(out_file) as zipfileout: | |
| zipfileout.extractall(path) | |
| except (requests.exceptions.RequestException, zipfile.BadZipFile) as e: | |
| raise RuntimeError(f"Failed to download or extract zip file: {e}") |
References
- When downloading and processing ZIP files, ensure that exception handling covers both network-related errors (e.g., requests.exceptions.RequestException) and ZIP-specific errors (e.g., zipfile.BadZipFile) to prevent the script from crashing on corrupted or invalid downloads.
Summary
Automates the manual script-based import
US_CDC_PRAMS(scripts/cdc_prams) to enable automated scheduling, regression testing, and pipeline execution in the Data Commons importer.Context
Key Changes
manifest.jsonregisteringscripts/cdc_prams:US_CDC_PRAMSwith yearly refresh (0 0 1 6 *).list_imports.py.download.py&download_input_files.py: Added User-Agent handling to bypass CDC Akamai WAF blocks.process.py: Upgraded for NumPy 2.x (np.nan) and Pandas 2.x compatibility; eliminated dynamic dtype warnings.process_test.py: Fixed tuple syntax bug and streamlined test suite (runs cleanly in ~16s).validation_config.jsonwith standard rules (DELETED_RECORDS_PERCENT,EMPTY_IMPORT_CHECK,LINT_ERROR_COUNT,MISSING_REFS_COUNT,GOLDENS_CHECK).golden_observations.csv(validated againstgs://unresolved_mcf/import_validation/top_100k_places.csv, 49/49 places matching).golden_summary_report.csv(canonical GenMCF schema summary covering all 168 StatVars).tabula-pytoimport-automation/executor/requirements.txtto support PDF extraction across executor container environments.README.mdwith complete indicator topics, layout, and execution instructions.Verification
python3 -m unittest scripts/cdc_prams/process_test.py-> 2/2 tests passed (OK).yapf --style=google(0 diffs).validator_goldens.pyon summary report: 168/168 goldens matched (100%).validator_goldens.pyon observations: 49/49 golden places matched (100%).