Portolan GeoServer
A Python integration between Portolan catalogs and GeoServer.
portolan-geoserver discovers resources from Portolan catalogs and maps them to appropriate GeoServer stores, resources, and layers.
It combines:
portolan-pythonfor understanding Portolan;python-geoservercloudfor interacting with GeoServer.
The project can operate as a standalone CLI and can also expose itself as a plugin for a pluggable portolan-cli.
Purpose
Given a Portolan catalog such as:
catalog
├── buildings
│ └── buildings.parquet
├── roads
│ └── roads.parquet
└── orthophoto
└── imagery.tif
the integration should be able to derive:
Portolan GeoParquet asset
↓
GeoServer GeoParquet DataStore
↓
FeatureType
↓
Layer
and:
Portolan COG asset
↓
GeoServer COG CoverageStore
↓
Coverage
↓
Layer
The actual GeoParquet and COG data access remains the responsibility of GeoServer's corresponding native stores/readers.
Architecture
Portolan Catalog
│
▼
portolan-python
│
domain objects
│
▼
portolan-geoserver
mapping / planning
│
▼
python-geoservercloud
│
▼
GeoServer
┌────────┴────────┐
▼ ▼
GeoParquet Store COG Store
│ │
▼ ▼
FeatureTypes Coverages
│ │
└────────┬────────┘
▼
Layers
Responsibilities
portolan-geoserver is responsible for:
- opening Portolan catalogs through
portolan-python; - discovering collections and assets;
- determining whether an asset can be mapped to a supported GeoServer store;
- generating a publication plan;
- creating appropriate GeoServer stores;
- creating resources;
- publishing layers;
- recording Portolan provenance;
- reconciling existing GeoServer resources with Portolan catalogs;
- supporting dry-run/plan operations;
- supporting synchronization.
Commands include:
portolan-geoserver plan <catalog>
portolan-geoserver publish <catalog>
portolan-geoserver sync <catalog>
portolan-geoserver serve --catalog-id <id>
portolan-geoserver serve --all
plan, publish, and sync operate on a local Portolan catalog. serve
operates from a Portolan registry. It fetches one or more catalog snapshots from
the registry and publishes them to GeoServer.
Portolan CLI plugin
The same project should optionally register commands with portolan-cli.
Once installed:
pip install portolan-cli
pip install portolan-geoserver
the user may obtain:
portolan geoserver plan ...
portolan geoserver publish ...
portolan geoserver sync ...
portolan geoserver serve ...
without moving GeoServer-specific code into portolan-cli.
This package exposes the entry point portolan.cli.plugins. A portolan-cli
installation can mount that entry point after it implements command-plugin
discovery. Until then, portolan-geoserver works as a standalone CLI.
Conceptually:
portolan-cli
│
│ discovers plugins
▼
portolan-geoserver
The standalone and plugin interfaces should call the same application layer and must not duplicate publication logic.
Dependency boundaries
The project deliberately separates responsibilities.
portolan-python
Answers questions such as:
- What collections exist?
- What assets belong to a collection?
- What is the asset HREF?
- What media type does it declare?
- What Portolan metadata applies?
- Is the catalog conformant?
portolan-geoserver
Answers:
- Which GeoServer store corresponds to this asset?
- What should the store be called?
- Which workspace should contain it?
- What resources need to be created?
- What needs to change during synchronization?
python-geoservercloud
Handles GeoServer operations.
GeoServer
Reads and serves the actual data.
This means portolan-geoserver should not implement GeoParquet or COG readers.
Planning before mutation
Publication should preferably be represented internally as a plan:
Portolan Catalog
↓
Publication Planner
↓
Publication Plan
↓
GeoServer Executor
Example conceptual plan:
workspace: overture
stores:
- name: buildings
type: geoparquet
asset: s3://bucket/buildings.parquet
resources:
- name: buildings
store: buildings
layers:
- name: buildings
resource: buildings
This makes dry-run, testing, auditing, and reconciliation substantially easier.
Provenance
Resources managed from Portolan should preserve enough provenance to identify their source.
Possible metadata:
portolan.managed
portolan.catalog
portolan.collection
portolan.asset
portolan.checksum
For GeoServer, authoritative provenance should preferably be associated with the published resource (FeatureTypeInfo / CoverageInfo) rather than only with LayerInfo.
This enables future synchronization to answer:
Which Portolan object created this resource?
Has the source changed?
Should this resource be updated?
Should an obsolete managed resource be removed?
Relationship with geoserver-portolan
The two projects solve related problems using different integration strategies.
portolan-geoserver is an external Python-driven integration:
Portolan
↓
Python
↓
GeoServer API
geoserver-portolan is a native GeoServer integration:
GeoServer
↓
Java
↓
Portolan
They should share mapping concepts and expected behavior where appropriate, but neither should depend on the other.
portolan-geoserver is particularly useful for:
- automation;
- CI/CD;
- external orchestration;
- existing GeoServer installations;
- experimentation;
- provisioning and synchronization.
Local documentation
- Architecture explains the catalog, planning, and execution layers.
- Examples shows standalone and plugin command usage.
- Plugin documents the
portolan-cliintegration point. - Development lists setup, test, and build commands.
- Distribution explains release artifacts and PyPI publishing.
Metadata
Release files for portolan-geoserver 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| portolan_geoserver-0.1.7.tar.gz | 121.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| portolan_geoserver-0.1.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 136.3 kB
Release files / portolan_geoserver-0.1.7.tar.gz
| Download URL | portolan_geoserver-0.1.7.tar.gz |
|---|---|
| Size | 121.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7d04de75e0088c601a260d7327d5f9e05a600142b58e20394a98234f23cf340e
|
|
BLAKE2b-256 checksum How to use checksums |
3ed2ea98c1f9fd83cf3f957e2056bf1f9486a8dab12ba0430fbdd0256434a23f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency logRelease files / portolan_geoserver-0.1.7-py3-none-any.whl
| Download URL | portolan_geoserver-0.1.7-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a1445b4ef1456bf29a87d34aefa0e77d1145029064b444c6bf454ecd2f8da889
|
|
BLAKE2b-256 checksum How to use checksums |
e0f538aeaa5a6ff7fba66444f5ec366c850446a9f4502bd6df16d2cae7335e1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.
Transparency log