<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>FastAPI-mapserver Blog</title>
        <link>https://ogc-service.wps.met.no/guide/blog</link>
        <description>FastAPI-mapserver Blog</description>
        <lastBuildDate>Fri, 10 Apr 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Why The Docs Live With The API Image]]></title>
            <link>https://ogc-service.wps.met.no/guide/blog/2026-04-10-docs-live-with-the-api</link>
            <guid>https://ogc-service.wps.met.no/guide/blog/2026-04-10-docs-live-with-the-api</guid>
            <pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[One of the useful architectural choices in this repository is that the docs are published with the application image instead of being treated as a separate service.]]></description>
            <content:encoded><![CDATA[<p>One of the useful architectural choices in this repository is that the docs are published with the application image instead of being treated as a separate service.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>That keeps the public guide version aligned with the code and deployment that operators are actually running.</p></div></div>
<!-- -->
<p>The deployment model is simple:</p>
<ul>
<li class="">Docusaurus builds static assets during the Docker build</li>
<li class="">the built site is copied into the runtime image</li>
<li class="">FastAPI serves those files under <code>/guide</code></li>
</ul>
<p>That has a few practical consequences for this project:</p>
<ul>
<li class="">the docs update when the image updates</li>
<li class="">there is no extra router or TLS surface to maintain</li>
<li class="">local and swarm deployments keep the same documentation path</li>
<li class="">operational notes can describe the exact runtime files and URLs that the service exposes</li>
</ul>
<p>For FastAPI-mapserver, that is the right tradeoff. This stack already has enough moving parts with MapServer, MapCache, Celery, Redis, terrain outputs, and HySpex jobs. Splitting documentation into a separately deployed site would add another versioning problem without solving an urgent one.</p>]]></content:encoded>
            <category>Documentation</category>
            <category>CI</category>
            <category>FastAPI</category>
            <category>MapCache</category>
        </item>
        <item>
            <title><![CDATA[Day 2: Expanding Route Coverage And Isolating Smoke CI]]></title>
            <link>https://ogc-service.wps.met.no/guide/blog/2026-04-09-route-coverage-and-smoke-ci</link>
            <guid>https://ogc-service.wps.met.no/guide/blog/2026-04-09-route-coverage-and-smoke-ci</guid>
            <pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The second day focused on confidence: more route-level tests, better job coverage, and a cleaner split between unit validation and runtime smoke checks.]]></description>
            <content:encoded><![CDATA[<p>The second day focused on confidence: more route-level tests, better job coverage, and a cleaner split between unit validation and runtime smoke checks.</p>
<p>Use a <code>{/*</code> <code>truncate</code> <code>*/}</code> comment to limit blog post size in the list view.</p>
<!-- -->
<p>The most important work was around the API surface that operators and workflows actually hit.</p>
<p>On the job side, the test suite now covers more of the behavior that tends to regress quietly:</p>
<ul>
<li class="">listing jobs with refresh behavior for non-terminal states</li>
<li class="">status shaping for success, in-progress, failure, and unknown job IDs</li>
<li class="">delete and cleanup routes, including tombstone recording and status-based cleanup</li>
</ul>
<p>Outside the jobs router, coverage was extended to routes that define the operator experience:</p>
<ul>
<li class="">auth endpoints for <code>/token</code> and <code>/login</code></li>
<li class="">config and service-health endpoints</li>
<li class="">lightweight dataset listing, duplicate reporting, and missing HySpex variant reporting</li>
</ul>
<p>This mattered because the runtime story here is bigger than one task queue. The platform depends on consistent behavior across auth, config persistence, dataset state, job manifests, and cache-related routes.</p>
<p>The other major change was CI structure. Instead of keeping everything in one path, the workflow now separates concerns more cleanly:</p>
<ul>
<li class=""><code>unit</code> remains the fast, containerized baseline</li>
<li class=""><code>integration</code> stays as its own stage for broader behavior</li>
<li class=""><code>smoke</code> now starts the runtime container and validates the health, login, and protected dataset flow independently</li>
</ul>
<p>The smoke script itself also became less optimistic. It now waits for the health endpoint before trying auth and protected requests, which is the difference between a flaky runner and a useful runtime signal.</p>
<p>Locally, validating that path exposed an environment truth that CI runners usually hide: host ports were already occupied by long-running containers. Once that was understood, the runtime flow was still verified from the live container context, which confirmed that the smoke sequence itself was correct even though the local host bindings were not clean.</p>
<p>The outcome is straightforward: the documentation now explains the system more accurately, and the tests do a better job of protecting the routes and workflows that define how the service is actually used.</p>]]></content:encoded>
            <category>CI</category>
            <category>FastAPI</category>
            <category>Celery</category>
            <category>HySpex</category>
            <category>MapCache</category>
            <category>Documentation</category>
        </item>
        <item>
            <title><![CDATA[Day 1: Replacing The Docusaurus Scaffold With Project Documentation]]></title>
            <link>https://ogc-service.wps.met.no/guide/blog/2026-04-08-docs-site-project-reset</link>
            <guid>https://ogc-service.wps.met.no/guide/blog/2026-04-08-docs-site-project-reset</guid>
            <pubDate>Wed, 08 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The first pass over the Docusaurus site was about removing generic scaffold content and making the docs reflect the actual FastAPI-mapserver deployment and runtime model.]]></description>
            <content:encoded><![CDATA[<p>The first pass over the Docusaurus site was about removing generic scaffold content and making the docs reflect the actual FastAPI-mapserver deployment and runtime model.</p>
<!-- -->
<p>The project already had enough moving parts to justify real operational documentation:</p>
<ul>
<li class="">a FastAPI application with a large router surface</li>
<li class="">MapServer and MapCache sitting behind the service layer</li>
<li class="">Celery and Redis for asynchronous processing</li>
<li class="">terrain generation and Mago output handling</li>
<li class="">HySpex ingestion paths that can fan out into batch jobs</li>
</ul>
<p>What changed on day 1 was not just the text. The docs site started to describe the real deployment shape:</p>
<ul>
<li class="">the public host layout under <code>/docs</code>, <code>/ui</code>, <code>/guide</code>, and the OGC endpoints</li>
<li class="">storage and manifest behavior under <code>/data</code></li>
<li class="">deployment files and local swarm profiles</li>
<li class="">caching, terrain, and HySpex workflows from an operator point of view</li>
</ul>
<p>That matters because this repository is not a library. It is an operating service, and the documentation has to answer practical questions like:</p>
<ul>
<li class="">where job state is persisted</li>
<li class="">how MapCache is regenerated and cleaned</li>
<li class="">which manifests define dataset and terrain state</li>
<li class="">how public URLs map to runtime services</li>
</ul>
<p>By the end of the first day, the docs site had stopped looking like a default Docusaurus starter and started reading like the control-plane manual for the stack we actually run.</p>]]></content:encoded>
            <category>Documentation</category>
            <category>FastAPI</category>
            <category>OGC</category>
            <category>MapServer</category>
            <category>MapCache</category>
            <category>Terrain</category>
        </item>
        <item>
            <title><![CDATA[What FastAPI-mapserver Is Built To Do]]></title>
            <link>https://ogc-service.wps.met.no/guide/blog/what-fastapi-mapserver-is-built-to-do</link>
            <guid>https://ogc-service.wps.met.no/guide/blog/what-fastapi-mapserver-is-built-to-do</guid>
            <pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[FastAPI-mapserver is the service layer that ties together raster ingestion, OGC publishing, background processing, caching, terrain generation, and HySpex catalog workflows in one operational stack.]]></description>
            <content:encoded><![CDATA[<p>FastAPI-mapserver is the service layer that ties together raster ingestion, OGC publishing, background processing, caching, terrain generation, and HySpex catalog workflows in one operational stack.</p>
<p>This project is not just a FastAPI wrapper around a few endpoints. It is the control plane around GeoTIFF datasets, MapServer and MapCache, Celery workers, Redis-backed job state, a built-in frontend, and terrain products that need to stay aligned across API, storage, and deployment.</p>
<!-- -->
<p>At a high level, the stack is responsible for four kinds of work:</p>
<ul>
<li class="">ingesting or registering datasets and exposing them through OGC routes</li>
<li class="">converting source products into GeoTIFF-backed outputs that the platform can serve consistently</li>
<li class="">generating and publishing terrain artifacts for Cesium and related clients</li>
<li class="">tracking long-running jobs, especially HySpex CSW parent campaigns that expand into many child jobs</li>
</ul>
<p>The reason this repository matters operationally is that these features share the same manifests, cache directories, deployment files, and runtime assumptions. A small change in routing, config persistence, or cache generation can affect user-facing map behavior immediately.</p>
<p>That is also why the documentation effort now lives close to the code: operators need one place to understand how <code>/datasets</code>, <code>/jobs</code>, <code>/mapcache</code>, terrain generation, and HySpex-specific flows fit together.</p>
<p>In practice, the platform currently centers on these capabilities:</p>
<ul>
<li class="">GeoTIFF dataset upload, registration, metadata repair, and duplicate detection</li>
<li class="">MapServer-backed WMS and related OGC service exposure</li>
<li class="">MapCache config generation, cache cleanup, and optional seeding during ingestion</li>
<li class="">Celery and Redis orchestration for asynchronous tasks and job introspection</li>
<li class="">HySpex CSW ingestion, including resumable parent-batch execution and campaign status tracking</li>
<li class="">terrain preparation for Mago and Cesium-oriented clients</li>
</ul>
<p><img decoding="async" loading="lazy" alt="FastAPI-mapserver docs banner" src="https://ogc-service.wps.met.no/guide/assets/images/docusaurus-plushie-banner-a60f7593abca1e3eef26a9afa244e4fb.jpeg" width="1500" height="500" class="img_ev3q"></p>
<p>Over the last two days, the focus has been tightening this operational surface: turning the docs site into project documentation, replacing scaffold content with real platform notes, expanding route-level test coverage, and separating smoke validation from the main unit path.</p>
<p>This blog is where that work is recorded in smaller, chronological slices.</p>]]></content:encoded>
            <category>FastAPI</category>
            <category>OGC</category>
            <category>MapServer</category>
            <category>MapCache</category>
            <category>GeoTIFF</category>
            <category>HySpex</category>
            <category>Terrain</category>
            <category>Documentation</category>
        </item>
    </channel>
</rss>