Skip to content

feat: prepare climate-api for PyPI release#75

Open
turban wants to merge 8 commits intomainfrom
feat/pypi-release
Open

feat: prepare climate-api for PyPI release#75
turban wants to merge 8 commits intomainfrom
feat/pypi-release

Conversation

@turban
Copy link
Copy Markdown
Contributor

@turban turban commented May 7, 2026

Closes #62.

What

Prepares climate-api for PyPI publication.

Changes

Flat package layout

src/climate_api/ moved to climate_api/ at the project root. Updated pyproject.toml ([tool.uv.build-backend] module-root = ""), Makefile, and Dockerfile accordingly. No import paths change.

Blocker removed: dhis2eo git-sourced dependency

dhis2eo is removed from dependencies (it was already on PyPI as of PR #74). It is called lazily via importlib.import_module inside _get_dynamic_function, so the core API is unaffected. A ModuleNotFoundError handler now surfaces a clear install instruction if a download is attempted without the package:

Download provider package 'dhis2eo' is not installed.
Install it manually before triggering dataset downloads:

  pip install "dhis2eo @ git+https://github.com/dhis2/dhis2eo.git@v1.2.0"

Version bump: 0.1.00.1.0a1

PEP 440 alpha pre-release — invisible to pip install climate-api by default, opt-in via pip install --pre climate-api or an explicit pin.

Package metadata

Added to pyproject.toml:

  • license: BSD-3-Clause (matching dhis2-core)
  • authors: University of Oslo / climate@dhis2.org
  • readme, keywords, classifiers, [project.urls]

A LICENSE file is included at the project root with the same text as dhis2-core.

Publish workflow

.github/workflows/publish.yml — triggers on v* tags, builds with uv build, publishes via Trusted Publishing (no API token stored in secrets).

README

Documents the dhis2eo manual install step for users who need dataset download support.

What still needs doing before first publish

  1. Register climate-api on PyPI and configure Trusted Publishing for this repo
  2. Create a pypi environment in repo settings
  3. Push a v0.1.0a1 tag

@turban turban force-pushed the feat/pypi-release branch from da5fa6f to e17bc8d Compare May 7, 2026 12:28
turban added 5 commits May 7, 2026 14:36
- Remove dhis2eo git-sourced dependency; add ModuleNotFoundError guard
  with install instructions in _get_dynamic_function
- Bump version to 0.1.0a1 (PEP 440 alpha, invisible to pip install by default)
- Add package metadata: license, authors, readme, keywords, classifiers, URLs
- Add GitHub Actions publish workflow (Trusted Publishing on v* tags)
- Document dhis2eo manual install in README
@turban turban force-pushed the feat/pypi-release branch from 099a67c to 5fab788 Compare May 7, 2026 12:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR prepares climate-api for PyPI publication by switching to a flat package layout, enriching pyproject.toml metadata, and adding an automated Trusted Publishing workflow for tagged releases. It also adjusts dependency handling so optional download-provider functionality can be installed separately without blocking core API installation.

Changes:

  • Move from src/ to a flat climate_api/ layout and update tooling paths (uv build backend, mypy, Docker, Makefile).
  • Remove dhis2eo from runtime dependencies and add clearer lazy-import error handling for download-time provider imports.
  • Add PyPI metadata + LICENSE + a GitHub Actions publish workflow for tag-based releases.

Reviewed changes

Copilot reviewed 6 out of 55 changed files in this pull request and generated no comments.

Show a summary per file
File Description
uv.lock Removes dhis2eo (and transitive deps) from the resolved runtime environment.
README.md Documents optional download-provider installation and updates bundled path references.
pyproject.toml Adds PyPI metadata, switches build config to flat layout, updates lint/type-check paths.
Makefile Updates mypy target and removes PYTHONPATH usage for OpenAPI generation.
LICENSE Adds BSD-3-Clause license text at repository root for distribution.
Dockerfile Copies climate_api/ instead of src/ and builds a runtime environment from lockfile.
climate_api/templates/landing_page.html Adds bundled HTML landing page template for the root endpoint.
climate_api/system/templates.py Implements root HTML/JSON rendering and Accept-header negotiation.
climate_api/system/schemas.py Adds Pydantic models for system endpoints (root, health, info).
climate_api/system/routes.py Adds /, /health, and /info system routes.
climate_api/system/init.py Exposes system submodules.
climate_api/startup.py Ensures early .env loading and default pygeoapi env var setup.
climate_api/stac/services.py Implements STAC catalog/collection builders backed by published artifacts.
climate_api/stac/schemas.py Adds response models for STAC endpoints with extension-friendly payloads.
climate_api/stac/routes.py Adds STAC routes under /stac.
climate_api/stac/init.py Declares STAC package.
climate_api/shared/time.py Adds shared period parsing/normalization helpers for ingestion/sync logic.
climate_api/shared/init.py Shared package marker (and potential exports).
climate_api/pygeoapi_app.py Adds reloadable in-process pygeoapi mount wrapper.
climate_api/publications/services.py Generates pygeoapi config/OpenAPI from published artifacts; refreshes mount.
climate_api/publications/init.py Declares publications package.
climate_api/providers/availability.py Adds provider availability policies used by sync planning.
climate_api/providers/init.py Declares providers package.
climate_api/main.py Constructs FastAPI app, mounts routers, configures zarr-specific CORS behavior.
climate_api/ingestions/sync_engine.py Adds sync planning/execution engine for managed datasets.
climate_api/ingestions/services.py Implements artifact storage, dataset views, publication, zarr serving, and sync services.
climate_api/ingestions/schemas.py Adds ingestion/dataset/sync API schemas.
climate_api/ingestions/routes.py Adds ingestion, datasets, zarr, and sync routers.
climate_api/ingestions/init.py Declares ingestions package.
climate_api/extents/services.py Loads and validates instance extent from CLIMATE_API_CONFIG.
climate_api/extents/schemas.py Adds Pydantic model for extent API response.
climate_api/extents/routes.py Exposes the configured extent via FastAPI routes.
climate_api/extents/init.py Declares extents package.
climate_api/data/pygeoapi/base.yml Bundles base pygeoapi config as package data.
climate_api/data/datasets/worldpop.yaml Adds/updates built-in dataset template(s) including sync metadata.
climate_api/data/datasets/era5_land.yaml Adds/updates built-in dataset template(s) including sync metadata.
climate_api/data/datasets/chirps3.yaml Adds/updates built-in dataset template(s) including sync metadata.
climate_api/data_registry/services/datasets.py Loads/validates dataset templates (builtin + config override) via importlib.resources.
climate_api/data_registry/services/init.py Exposes dataset registry services.
climate_api/data_registry/routes.py Adds dataset-template discovery routes.
climate_api/data_registry/init.py Declares data_registry package.
climate_api/data_manager/services/utils.py Adds axis discovery helpers for time and lon/lat dimensions.
climate_api/data_manager/services/downloader.py Implements dataset downloading and zarr building; adds provider-missing install guidance.
climate_api/data_manager/services/init.py Exposes data manager services.
climate_api/data_manager/routes.py Keeps internal download/build routes for compatibility.
climate_api/data_manager/init.py Declares data manager package.
climate_api/data_accessor/services/accessor.py Opens cached data and derives coverage metadata; handles pyramid zarr opening.
climate_api/data_accessor/services/init.py Exposes data accessor services.
climate_api/data_accessor/routes.py Adds file download route for filtered dataset export.
climate_api/data_accessor/init.py Declares data accessor package.
climate_api/config.py Loads instance config from CLIMATE_API_CONFIG with env-var substitution + caching.
climate_api/client.py Adds lightweight client for STAC discovery and opening zarr datasets via xarray.
climate_api/cli.py Adds climate-api console script entrypoint for running uvicorn.
climate_api/init.py Exposes package __version__ from installed distribution metadata.
.github/workflows/publish.yml Adds tag-triggered build + Trusted Publishing workflow for PyPI releases.
Comments suppressed due to low confidence (1)

README.md:27

  • The README states that dhis2eo is "not yet on PyPI" and instructs installing from a Git URL pinned to v1.2.0, but the repo metadata/lockfile indicate dhis2eo has a PyPI release (and the PR removes it from dependencies). Please update this section to reflect the intended install path/version (e.g., PyPI install vs. Git install) so users don’t follow stale instructions.

Copy `.env.example` to `.env` and adjust values as needed. Environment variables are loaded automatically from `.env` at runtime. See `.env.example` for the full list of available options.

Start the app:

uv run uvicorn climate_api.main:app --reload

</details>

@turban turban requested a review from abyot May 7, 2026 13:27
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.

PyPI release: make climate-api installable via pip install climate-api

2 participants