Modernize packaging and CI; pin load behavior with an offline test suite - #102
Merged
Merged
Conversation
- pyproject.toml (hatchling, PEP 621) replaces setup.py, Pipfile, MANIFEST.in - pytest and coverage config move from pytest.ini/.coveragerc into pyproject.toml - tox rewritten: envs for python 3.10-3.14 plus serial coverage env - add test.yml workflow: python x OS matrix, monthly cron, fan-in job - delete .travis.yml and bump_version.sh - README.rst converted to README.md; Dockerfile drops pipenv for pip install -e Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
- KeyValueStore keeps its public interface; urls remain sqlite:///path form, non-sqlite urls now raise ValueError - updated timestamps stored as UTC ISO strings, returned tz-aware - delete get_datetime_if_exists/is_tz_naive helpers - tests backdate cache entries via sqlite3 instead of sqlalchemy sessions Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
…ess_api - pkg_resources (removed in setuptools >=81) replaced with importlib.resources - CLI test invokes --help explicitly (click >=8.2 exits 2 on bare group) - retry dependency replaced with an explicit request retry loop - attrs dependency replaced with stdlib dataclass - DatasetType.ISD value fixed from 'IDS' to 'ISD' Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
- hourly/daily/gsod loaders emit warnings when returned data is empty, ends more than a day before the requested end, or has an internal gap over 7 days - all-years-missing tolerant path returns a NaN series over the requested range instead of crashing on pd.concat of an empty list - loaders now always cover the full requested range, including when the data slice is empty - error_on_missing_years added to daily/gsod loaders and defaulted True everywhere, matching the ISDStation method default Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
- tests/fixtures holds real recorded NCEI responses (gzipped) for station 722874, years 1800/2005/2006/2007/2050, both datasets - mock_api_transport fixture intercepts requests.get and serves fixtures; unmatched requests fail the test rather than reaching the network - replaces the FTP-proxy mock, which no longer intercepted the api fetch path and let tests reach the live api - make_api_request monkeypatch fixtures depend on the transport mock so delegated calls also stay offline Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
…aths All data tests pin real captured observations; no synthesized weather data. - regression pins on captured 2007 data: hourly/daily counts, means, first values with explicit tolerances - truncation warnings pinned against station 724940, whose 2025 data ends Aug 27; sub-day trailing gap pinned as non-warning on the same station - internal-gap warnings pinned against station 720193, whose 2019 data has a real mid-year outage (16.1 days hourly, 25 days daily) - all-NaN-year behavior pinned against station 722874 in 2025 (temperature reported missing all year) - missing-year strict/tolerant behavior tests for hourly, daily, and gsod - degenerate sub-hour range returns empty without warning - access_api tests built from captured payload rows: retry exhaustion and recovery, missing-temp NaN, gsod unit conversion, malformed-row rejection - coverage floor set at 94 (measured 95.3; access_api at 100) Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
- releasing goes through the GitHub release publish workflow - drop gitignore whitelists for deleted config files; ignore coverage.xml Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
6 tasks
- cache operations close their connection on exit (python 3.13 warns on connections garbage-collected open, and warnings are errors in tests) - the metadata db proxy serves one cached read connection per thread, so call sites do not leak or close - datetime.UTC (python 3.11+) replaced with timezone.utc in tests to keep the 3.10 floor Signed-off-by: Travis Sikes <124101151+travis-recurve@users.noreply.github.com>
jason-recurve
approved these changes
Jul 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Your checklist for this pull request
Please review the guidelines for contributing to this repository.
fail_underfloor added).docs/api.rstentries.Description
Modernizes the repository and pins current load behavior with a test suite that runs fully offline, ahead of the GHCNh data-source migration (#100).
Packaging and CI:
pyproject.toml(hatchling) replacessetup.py,Pipfile, andMANIFEST.in; python >=3.10; dependencies now declare everything actually imported (pytzadded;retry,attrsreplaced with stdlib equivalents)pyproject.toml; warnings are errorsREADME.mdreplacesREADME.rst;CONTRIBUTING.mdrelease steps updated to the GitHub-release publish workflowFixes:
sqlite3; sqlalchemy (previously required at runtime but never declared) is no longer used. Cache urls keep thesqlite:///pathformpkg_resourcesimport (removed in setuptools >=81) replaced withimportlib.resourcesNo objects to concatenatecrash when all years in a requested range are missing anderror_on_missing_years=False; loaders always return a series covering the full requested rangeerror_on_missing_yearsadded to the daily ISD/GSOD loaders and defaulted consistentlyTests: