Skip to content

SFMS: Provide Daily FWI endpoint#5573

Open
conbrad wants to merge 28 commits into
mainfrom
5502-sfms-provide-daily-fwi-end-point
Open

SFMS: Provide Daily FWI endpoint#5573
conbrad wants to merge 28 commits into
mainfrom
5502-sfms-provide-daily-fwi-end-point

Conversation

@conbrad

@conbrad conbrad commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Adds /api/sfms/daily-fwi endpoints to download SFMS daily FWI actuals rasters (FFMC, DMC, DC, ISI, FWI, BUI) and hourly FFMC rasters, and to query raster values by lat/lon.

Endpoints

Method Path Description
GET /api/sfms/daily-fwi/{date}/{parameter} Download daily FWI actuals raster (dc, dmc, bui, ffmc, isi, fwi)
GET /api/sfms/daily-fwi/{date}/hffmc?hour= Download hourly FFMC actuals raster
GET /api/sfms/daily-fwi/{date}/{parameter}/value?lat=&lon= Query raster value at a WGS84 lat/lon point
GET /api/sfms/daily-fwi/{date}/hffmc/value?hour=&lat=&lon= Query hourly FFMC value at a lat/lon point

Endpoints are open at the Python level and protected via the BC Government APS gateway (Kong key-auth plugin, 60 req/min rate limit per consumer) consumers register for an API key through the APS portal rather than using a Keycloak IDIR token. Public URL: psu.api.gov.bc.ca/api/sfms/daily-fwi/....

Standalone service (not publicly exposed)

The daily FWI routes are served by a dedicated wps-sfms-fwi-api deployment rather than the main API:

  • app/sfms_fwi_main.py — separate FastAPI entrypoint including only the sfms_fwi router; the shared API image selects it via the APP_MODULE env var. The main API no longer serves these routes (guarded by a test).
  • openshift/templates/sfms_fwi_api.yaml — Deployment + ClusterIP Service with no Route; the only ingress is a NetworkPolicy allowing the APS gateway namespace (allow_gateway_to_wps_sfms_fwi_api.yaml). Uses the same Crunchy DB credentials as the other API pods so startup migrations work.
  • Reuses the existing object_store_proxy._proxy method for raster streaming.

CI / gateway publishing

  • ASA Go and SFMS FWI deploy as separate, parallel dev jobs; a shared publish-aps-gateway-dev job (depending on both) publishes gateway config, so Kong never routes to a not-yet-deployed upstream.
  • New gw-config-publish composite action consolidates the two previous publish actions; render scripts standardized on GW_HOST. Gateway configs publish under independent qualifiers (pr-N/prod for ASA Go, fwi-pr-N/fwi-prod for SFMS FWI) and are pruned on PR cleanup.
  • SFMS FWI dataset + product are published to the API Directory via gwa apply.

Closes #5502

Test Links:

Landing Page
MoreCast
Percentile Calculator
C-Haines
FireCalc
FireCalc bookmark
Auto Spatial Advisory (ASA)
HFI Calculator
SFMS Insights
Fire Watch
Weather Toolkit

@conbrad conbrad linked an issue Jun 29, 2026 that may be closed by this pull request
3 tasks
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.61789% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.38%. Comparing base (a355861) to head (621182c).

Files with missing lines Patch % Lines
backend/packages/wps-api/src/app/sfms_fwi_main.py 66.66% 10 Missing and 2 partials ⚠️
...ckend/packages/wps-api/src/app/routers/sfms_fwi.py 96.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5573      +/-   ##
==========================================
+ Coverage   67.26%   67.38%   +0.11%     
==========================================
  Files         382      384       +2     
  Lines       22688    22811     +123     
  Branches     3107     3112       +5     
==========================================
+ Hits        15262    15371     +109     
- Misses       6256     6267      +11     
- Partials     1170     1173       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread backend/packages/wps-api/src/app/sfms_fwi_main.py Fixed
@sonarqubecloud

sonarqubecloud Bot commented Jul 2, 2026

Copy link
Copy Markdown

@conbrad conbrad requested a review from brettedw July 2, 2026 21:53

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why the rename of aps-publish to gw-config-publish? I find the new naming a bit confusing, being so similar to gwa-publish. In my mind gwa-publish installs/runs gwa, while aps-publish tied it together for the higher level APS flow. Could we keep the aps-publish name and just generalize the inputs instead?

"${OUTPUT_DIR}"

- name: Apply SFMS FWI dataset and product
uses: ./.github/actions/gwa-apply

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The gwa-apply custom action is only used once here, do you think it's worth having a custom action for?
Side note: I think in our workflows we're now installing the gwa cli 3 times. Maybe we should just install it once as an explicit step?

],
):
"""Download the daily FWI actuals raster for the given date and parameter."""
key = _addresser.get_calculated_index_key(datetime(for_date.year, for_date.month, for_date.day, tzinfo=timezone.utc), parameter, RunType.ACTUAL)

@brettedw brettedw Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These endpoints are getting the incorrect data, they need to be getting data from the current SFMS

Comment on lines +452 to +453
col = int((x - geotransform[0]) / geotransform[1])
row = int((y - geotransform[3]) / geotransform[5])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
col = int((x - geotransform[0]) / geotransform[1])
row = int((y - geotransform[3]) / geotransform[5])
inverse_geotransform = gdal.InvGeoTransform(geotransform)
pixel_x, pixel_y = gdal.ApplyGeoTransform(inverse_geotransform, x, y)
col = math.floor(pixel_x)
row = math.floor(pixel_y)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We might want to do something like to avoid returning values from pixels that are just fractionally outside the raster

suffix: ${{ env.SUFFIX }}
qualifier-prefix: fwi-

- name: Publish SFMS FWI dataset and product to test API Directory

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Useful for testing to see the dataset/product this time for sure, but do you think we want this regularly? I think this will list every PR we have as a dataset and product in the API Directory

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It might be worth adding something to launch.json so we can easily run the SFMS api locally

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.

SFMS: Provide Daily FWI End Point

3 participants