API Reference
Complete Python API documentation for all GeoTUI modules, auto-generated from source docstrings.
Core Application
geotui.app — Main Application
app
Main GeoTUI application.
GeoTUIApp(config_manager=None)
Bases: App[None]
GeoTUI - Midnight Commander-style GeoServer manager.
Initialize the application.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_manager
|
ConfigManager | None
|
Optional config manager override (useful for testing). |
None
|
design
property
Return custom Kartoza color schemes.
decrypt_connection(conn)
Return a connection with its password decrypted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection with potentially encrypted password. |
required |
Returns:
| Type | Description |
|---|---|
Connection
|
Connection with plaintext password for API use. |
compose()
Compose the application layout.
on_mount()
Show splash screen, then unlock if needed.
action_switch_pane()
Switch focus between left and right panes.
action_help()
Show help dialog.
action_menu()
Show context-sensitive F2 menu.
action_copy()
F5 Copy: publish local spatial files to GeoServer.
action_move()
Move selected item.
action_mkdir()
Create directory.
action_delete()
F8 Delete: delete selected resource on GeoServer.
action_settings()
Show settings screen.
action_toggle_language()
Cycle through available languages and refresh all UI text.
geotui.config — Configuration & Encryption
config
Configuration model and manager for GeoTUI.
Manages GeoServer connection instances with atomic JSON persistence. Follows XDG Base Directory specification for config storage. Credentials are encrypted at rest using Fernet (AES-128-CBC + HMAC-SHA256) with a key derived from the user's master password via PBKDF2-HMAC-SHA256.
Connection
Bases: BaseModel
A GeoServer connection configuration.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Unique identifier for this connection. |
name |
str
|
Human-readable connection name. |
url |
str
|
GeoServer base URL (e.g. https://geoserver.example.com/geoserver). |
username |
str
|
GeoServer username. |
password |
str
|
GeoServer password. |
is_active |
bool
|
Whether this is the currently selected connection. |
AppConfig
Bases: BaseModel
Root application configuration.
Attributes:
| Name | Type | Description |
|---|---|---|
theme |
str
|
Application theme name. |
language |
str
|
Interface language code. |
connections |
list[Connection]
|
List of GeoServer connections. |
vault_salt |
str
|
Base64-encoded salt for PBKDF2 key derivation. |
vault_check |
str
|
Fernet token used to verify master password. |
has_vault
property
Return True if a master password vault has been initialised.
ConfigManager(config_path=None)
Thread-safe configuration manager with atomic persistence.
Provides CRUD operations for GeoServer connections and handles loading/saving configuration to disk.
Initialize the config manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_path
|
Path | None
|
Override path for config file. Uses XDG default if None. |
None
|
has_vault
property
Return True if a master password vault has been set up.
save()
Persist configuration to disk atomically.
Sets restrictive file permissions (0o600) on the config file and (0o700) on the config directory since it contains credentials.
add_connection(conn)
Add a new connection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection to add. |
required |
update_connection(conn_id, **kwargs)
Update an existing connection's fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn_id
|
str
|
ID of the connection to update. |
required |
**kwargs
|
str | bool
|
Fields to update. |
{}
|
Returns:
| Type | Description |
|---|---|
bool
|
True if the connection was found and updated. |
remove_connection(conn_id)
Remove a connection by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn_id
|
str
|
ID of the connection to remove. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the connection was found and removed. |
get_connection(conn_id)
Get a connection by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn_id
|
str
|
ID of the connection to find. |
required |
Returns:
| Type | Description |
|---|---|
Connection | None
|
The Connection if found, None otherwise. |
get_connection_by_name(name)
Get a connection by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the connection to find. |
required |
Returns:
| Type | Description |
|---|---|
Connection | None
|
The Connection if found, None otherwise. |
init_vault(master_password)
Initialise the encryption vault with a new master password.
Generates a random salt, derives a key, stores a verification token, and encrypts all existing connection passwords.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master_password
|
str
|
The new master password. |
required |
unlock(master_password)
Verify the master password and return a Fernet instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master_password
|
str
|
Password to verify. |
required |
Returns:
| Type | Description |
|---|---|
Fernet | None
|
Fernet instance if correct, None if wrong password. |
decrypt_connection(conn, fernet)
Return a copy of the connection with password decrypted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection with encrypted password. |
required |
fernet
|
Fernet
|
Fernet instance from a successful unlock. |
required |
Returns:
| Type | Description |
|---|---|
Connection
|
New Connection with plaintext password. |
encrypt_password(plaintext, fernet)
Encrypt a password for storage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plaintext
|
str
|
Password in cleartext. |
required |
fernet
|
Fernet
|
Fernet instance from a successful unlock. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Encrypted token string. |
change_master_password(old_password, new_password)
Change the master password, re-encrypting all connections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old_password
|
str
|
Current master password. |
required |
new_password
|
str
|
New master password. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if successful, False if old password is wrong. |
reset_vault()
Reset the vault, wiping all connections.
This is the only recovery option when the master password is forgotten.
encrypt_value(plaintext, fernet)
Encrypt a string value and return base64 token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plaintext
|
str
|
Value to encrypt. |
required |
fernet
|
Fernet
|
Initialised Fernet instance. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Fernet token as a UTF-8 string. |
decrypt_value(token, fernet)
Decrypt a Fernet token back to plaintext.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
Fernet token string. |
required |
fernet
|
Fernet
|
Initialised Fernet instance. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Decrypted plaintext string. |
Raises:
| Type | Description |
|---|---|
InvalidToken
|
If the token is invalid or the key is wrong. |
verify_master_password(master_password, salt, check_token)
Verify a master password against a stored check token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
master_password
|
str
|
Password to verify. |
required |
salt
|
bytes
|
Salt bytes from config. |
required |
check_token
|
str
|
Stored encrypted verification token. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the password is correct. |
geotui.client — GeoServer REST API Client
client
GeoServer REST API client.
Provides async methods for connection testing and fetching/creating GeoServer resources (workspaces, stores, layers) via the REST API.
ConnectionResult(success, message, version='')
dataclass
Result of a GeoServer connection test.
Attributes:
| Name | Type | Description |
|---|---|---|
success |
bool
|
Whether the connection was successful. |
message |
str
|
Human-readable result message. |
version |
str
|
GeoServer version string if connected. |
GeoServerResource(name, resource_type, children=list(), href='')
dataclass
A resource in the GeoServer hierarchy.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Resource name. |
resource_type |
str
|
Type of resource (workspace, datastore, coveragestore, wmsstore, layer, coverage). |
children |
list[GeoServerResource]
|
Child resources. |
href |
str
|
REST API href for this resource. |
StoreType(type_id, label, category, gs_type, fields)
dataclass
Definition of a GeoServer store type.
Attributes:
| Name | Type | Description |
|---|---|---|
type_id |
str
|
Internal type identifier. |
label |
str
|
Human-readable label. |
category |
str
|
'vector', 'raster', or 'remote'. |
gs_type |
str
|
GeoServer type string for REST API. |
fields |
list[tuple[str, str, str]]
|
List of (field_name, label, placeholder) for the form. |
create_path |
list[tuple[str, str, str]]
|
REST API path template (use {workspace}). |
payload_builder |
list[tuple[str, str, str]]
|
Callable to build the JSON payload. |
GeoServerClient(conn, timeout=10.0)
Async client for GeoServer REST API.
Reuses a single httpx.AsyncClient for all requests. Use as an async context manager or call close() when done.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection configuration. |
required |
timeout
|
float
|
Request timeout in seconds. |
10.0
|
Initialize the client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection configuration. |
required |
timeout
|
float
|
Request timeout in seconds. |
10.0
|
close()
async
Close the HTTP client.
__aenter__()
async
Enter async context.
__aexit__(*args)
async
Exit async context.
get_workspaces()
async
Fetch all workspaces.
get_datastores(workspace)
async
Fetch data stores for a workspace.
get_coveragestores(workspace)
async
Fetch coverage stores for a workspace.
get_wmsstores(workspace)
async
Fetch WMS stores for a workspace.
get_layers_for_datastore(workspace, store)
async
Fetch feature type layers for a data store.
get_coverages(workspace, store)
async
Fetch coverages for a coverage store.
get_full_tree()
async
Fetch the full resource hierarchy using parallel requests.
Returns:
| Type | Description |
|---|---|
list[GeoServerResource]
|
List of workspace resources with populated children. |
create_workspace(name)
async
Create a new workspace.
create_datastore(workspace, name, store_type, params)
async
Create a datastore with the given connection parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Target workspace name. |
required |
name
|
str
|
Store name. |
required |
store_type
|
str
|
GeoServer store type string. |
required |
params
|
dict[str, str]
|
Connection parameter key-value pairs. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if created successfully. |
create_coveragestore(workspace, name, store_type, url)
async
Create a coverage store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Target workspace name. |
required |
name
|
str
|
Store name. |
required |
store_type
|
str
|
GeoServer coverage store type (GeoTIFF, etc). |
required |
url
|
str
|
Path to the coverage data. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if created successfully. |
create_wmsstore(workspace, name, capabilities_url)
async
Create a WMS store.
create_store_from_type(workspace, store_type, field_values)
async
Create a store using the store type registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Target workspace. |
required |
store_type
|
StoreType
|
StoreType definition from the registry. |
required |
field_values
|
dict[str, str]
|
Form field values keyed by field name. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if created successfully. |
layer_exists(workspace, layer_name)
async
Check whether a layer already exists in GeoServer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
layer_name
|
str
|
Layer name (without workspace prefix). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the layer exists. |
get_datastore_type(workspace, store)
async
Return the GeoServer type string for a datastore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Datastore name. |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Type string (e.g. |
upload_shapefile(workspace, store, zip_data, update)
async
Upload a zipped shapefile to a GeoServer datastore.
Sends the ZIP archive to the GeoServer file-upload endpoint using
the file.shp method. When update is True the
update=overwrite query parameter is appended so that an existing
store/layer is replaced rather than causing a conflict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Target workspace name. |
required |
store
|
str
|
Target datastore name. |
required |
zip_data
|
bytes
|
Raw bytes of a ZIP archive containing the shapefile. |
required |
update
|
bool
|
If |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the upload succeeded (HTTP 201 Created or 200 OK). |
create_featuretype(workspace, store, native_name, layer_name)
async
Explicitly configure a feature type in an existing datastore.
Required when uploading additional shapefiles to a datastore that was already created — GeoServer's configure=first only runs on store creation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Target workspace name. |
required |
store
|
str
|
Target datastore name. |
required |
native_name
|
str
|
Shapefile stem (must match the file on disk). |
required |
layer_name
|
str
|
Desired GeoServer layer name. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the feature type was created (HTTP 201) or already existed. |
upload_gpkg(workspace, store, data, update=False)
async
Upload a GeoPackage file to a datastore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Datastore name. |
required |
data
|
bytes
|
GeoPackage file bytes. |
required |
update
|
bool
|
If True, overwrite existing. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if upload succeeded. |
upload_geotiff(workspace, store, data, update=False)
async
Upload a GeoTIFF file to a coverage store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Coverage store name. |
required |
data
|
bytes
|
GeoTIFF file bytes. |
required |
update
|
bool
|
If True, overwrite existing. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if upload succeeded. |
recalculate_bbox(workspace, layer_name)
async
Recalculate bounding box for a layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
layer_name
|
str
|
Layer name. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if successful. |
assign_style(workspace, layer_name, style_name)
async
Set the default style for a published layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace that owns the layer. |
required |
layer_name
|
str
|
Name of the layer (without workspace prefix). |
required |
style_name
|
str
|
Name of the style to assign. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if GeoServer accepted the update (HTTP 200 OK). |
delete_datastore(workspace, store, recurse=False)
async
Delete a datastore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Datastore name. |
required |
recurse
|
bool
|
If True, also delete contained layers. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if deleted successfully. |
delete_coveragestore(workspace, store, recurse=False)
async
Delete a coverage store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Coverage store name. |
required |
recurse
|
bool
|
If True, also delete contained coverages. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if deleted successfully. |
delete_workspace(workspace, recurse=False)
async
Delete a workspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
recurse
|
bool
|
If True, also delete all contained stores and layers. |
False
|
Returns:
| Type | Description |
|---|---|
bool
|
True if deleted successfully. |
delete_layer(workspace, store, layer_name, resource_type='layer')
async
Delete a layer/coverage and its associated global layer entry.
Uses the featuretype/coverage endpoint to delete the resource, then removes the global layer reference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workspace
|
str
|
Workspace name. |
required |
store
|
str
|
Parent store name. |
required |
layer_name
|
str
|
Layer name. |
required |
resource_type
|
str
|
'layer' for featuretypes, 'coverage' for coverages. |
'layer'
|
Returns:
| Type | Description |
|---|---|
bool
|
True if deleted successfully. |
validate_resource_name(name, kind='resource')
Validate a GeoServer resource name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The resource name to validate. |
required |
kind
|
str
|
Human-readable kind for error messages (e.g. "workspace"). |
'resource'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the name is invalid. |
resolve_base_url(url, username, password, timeout=10.0)
async
Resolve the correct GeoServer REST API base URL.
Tries the URL as-is first, then falls back to {url}/geoserver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
User-provided URL. |
required |
username
|
str
|
GeoServer username. |
required |
password
|
str
|
GeoServer password. |
required |
timeout
|
float
|
Request timeout in seconds. |
10.0
|
Returns:
| Type | Description |
|---|---|
str
|
The working base URL, or the original URL if neither works. |
test_connection(conn, timeout=10.0)
async
Test a GeoServer connection by querying the REST API.
Tries the URL as-is first, then falls back to {url}/geoserver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
Connection configuration to test. |
required |
timeout
|
float
|
Request timeout in seconds. |
10.0
|
Returns:
| Type | Description |
|---|---|
ConnectionResult
|
ConnectionResult with success status and details. |
geotui.cli — Command-Line Interface
cli
CLI interface for GeoTUI.
Provides subcommands for bulk publish, export, and import-config that can be run headlessly or from CI pipelines.
cli()
GeoTUI - GeoServer Manager.
publish(connection, workspace, datastore, source, naming, prefix, concurrency, dry_run, fail_fast, output, config_path)
Bulk publish shapefiles to GeoServer.
export(connection, workspace, output, config_path)
Export GeoServer workspace configuration.
import_config(connection, input_dir, config_path)
Import GeoServer workspace configuration.
Publishing & Reports
geotui.publisher — Bulk Publish Engine
publisher
Bulk shapefile publisher engine for GeoTUI.
Provides shapefile discovery, naming strategy resolution, and publish configuration dataclasses used by the upload execution engine.
NamingStrategy
Bases: str, Enum
Strategy for deriving a GeoServer layer name from a shapefile stem.
BASENAME = 'basename'
class-attribute
instance-attribute
Use the bare filename stem, e.g. roads.
PREFIXED_BASENAME = 'prefixed_basename'
class-attribute
instance-attribute
Prepend a user-supplied prefix to the stem, e.g. geo_roads.
PATH_SLUG = 'path_slug'
class-attribute
instance-attribute
Build a slug from the relative path components joined by _,
e.g. subdir_roads. This guarantees uniqueness across nested
directories.
ShapefileBundle(name, directory, files)
dataclass
All component files that make up a single shapefile dataset.
name
instance-attribute
The stem of the .shp file (without extension).
directory
instance-attribute
Absolute path of the directory that contains the component files.
files
instance-attribute
All component files belonging to this bundle (including optional ones).
total_size
property
Sum of byte sizes of all component files.
to_zip(dest=None)
Create a ZIP archive of all bundle component files.
When dest is provided the archive is also written to that path. Always returns the raw ZIP bytes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dest
|
Path | None
|
Optional path to write the ZIP file. The parent directory is created if it does not exist. |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
Raw ZIP archive bytes. |
SpatialFile(name, path, size)
dataclass
A single spatial file (GeoPackage, GeoTIFF, etc.).
name
instance-attribute
The file stem (without extension), e.g. parcels.
path
instance-attribute
Absolute path to the file.
size
instance-attribute
File size in bytes.
from_path(path)
classmethod
Construct a :class:SpatialFile from a filesystem path.
SpatialFileGroup(format_type, store_type, store_category, files)
dataclass
A collection of spatial files sharing the same format type.
format_type
instance-attribute
Logical format identifier, e.g. "shapefile", "geopackage",
"geotiff".
store_type
instance-attribute
GeoServer store type string for this format.
store_category
instance-attribute
Broad category used for UI grouping.
files
instance-attribute
List of :class:SpatialFile or :class:ShapefileBundle instances.
total_size
property
Sum of byte sizes of all files in the group.
BundleResult(layer_name, source_path, action, status, file_size=0, upload_time=0.0, error=None)
dataclass
Outcome of publishing a single :class:ShapefileBundle.
layer_name
instance-attribute
The GeoServer layer name that was (or would be) created/updated.
source_path
instance-attribute
Path to the .shp file for this bundle.
action
instance-attribute
One of "create", "update", or "skip".
status
instance-attribute
"ok", "dry_run", "error", or "skipped".
file_size = 0
class-attribute
instance-attribute
Total bytes uploaded (0 if dry-run or skipped).
upload_time = 0.0
class-attribute
instance-attribute
Wall-clock seconds taken for the upload.
error = None
class-attribute
instance-attribute
Human-readable error message if status is "error".
PublishConfig(workspace, datastore, source_directory, naming=NamingStrategy.BASENAME, prefix='', styles_directory=None, styles_mapping=dict(), recurse=False, concurrency=4, dry_run=False, retry_max_attempts=3, retry_backoff_seconds=2.0, fail_fast=False)
dataclass
Configuration for a bulk shapefile publish operation.
workspace
instance-attribute
Target GeoServer workspace.
datastore
instance-attribute
Target GeoServer datastore within workspace.
source_directory
instance-attribute
Root directory to scan for shapefiles.
naming = NamingStrategy.BASENAME
class-attribute
instance-attribute
Strategy for deriving layer names from shapefile stems.
prefix = ''
class-attribute
instance-attribute
Prefix applied when naming is :attr:NamingStrategy.PREFIXED_BASENAME.
styles_directory = None
class-attribute
instance-attribute
Optional directory containing SLD style files to associate with layers.
styles_mapping = field(default_factory=dict)
class-attribute
instance-attribute
Explicit {layer_name: style_name} overrides.
recurse = False
class-attribute
instance-attribute
Whether to scan source_directory recursively.
concurrency = 4
class-attribute
instance-attribute
Number of concurrent upload workers.
dry_run = False
class-attribute
instance-attribute
If True, discover and plan but do not perform any uploads.
retry_max_attempts = 3
class-attribute
instance-attribute
Maximum upload retry attempts per bundle.
retry_backoff_seconds = 2.0
class-attribute
instance-attribute
Base back-off delay (seconds) between retry attempts.
fail_fast = False
class-attribute
instance-attribute
Abort the entire batch on the first upload failure.
PublishReport(config, geoserver_url='', geoserver_version='', username='', results=list(), warnings=list(), wall_clock_seconds=0.0)
dataclass
Summary report produced after a bulk publish run.
created
property
Number of layers successfully created.
updated
property
Number of layers successfully updated.
skipped
property
Number of layers skipped (including dry-run).
failed
property
Number of layers that failed to upload.
total_uploaded_bytes
property
Total bytes uploaded across all successful bundles.
discover_bundles(directory, *, recurse=False)
Scan directory for shapefile bundles.
A bundle is considered complete when the three required sidecar files
(.shp, .shx, .dbf) are all present alongside the .shp
file. Incomplete bundles (missing any required sidecar) produce a warning
string but are not returned.
Parameters
directory:
Root directory to scan.
recurse:
When True, descend into sub-directories.
Returns
tuple[list[ShapefileBundle], list[str]]
A pair of (complete_bundles, warning_messages).
discover_spatial_files(directory)
Scan directory (non-recursively) for all supported spatial formats.
Discovers shapefiles (via :func:discover_bundles), GeoPackage (.gpkg),
and GeoTIFF (.tif / .tiff) files. Results are grouped by format.
Empty format groups are omitted.
Parameters
directory: Directory to scan (no recursion).
Returns
tuple[list[SpatialFileGroup], list[str]]
A pair of (groups, warning_messages). Warnings originate from
incomplete shapefile bundles.
discover_spatial_files_from_paths(paths)
Build spatial file groups from an explicit list of file paths.
Shapefile components are grouped into bundles by stem. GeoPackage and GeoTIFF files are grouped by format. Shapefile companion files that are present on disk but missing from paths are included automatically.
Parameters
paths: Explicit list of file paths (companions already expanded by caller).
Returns
tuple[list[SpatialFileGroup], list[str]]
A pair of (groups, warning_messages).
resolve_layer_names(bundles, base_dir, strategy, prefix='')
Derive a unique GeoServer layer name for each bundle.
Parameters
bundles:
The bundles returned by :func:discover_bundles.
base_dir:
The root directory used as the reference for relative path slugs.
strategy:
How to derive names (see :class:NamingStrategy).
prefix:
Applied only when strategy is
:attr:NamingStrategy.PREFIXED_BASENAME.
Returns
dict[ShapefileBundle, str] Mapping from each bundle to its resolved layer name.
Raises
ValueError If the chosen strategy would produce duplicate layer names (collision).
run_publish(conn, config, progress_callback=None)
async
Execute a bulk shapefile publish operation.
Discovers bundles under config.source_directory, resolves layer names, verifies the GeoServer connection, then uploads each bundle concurrently (honouring config.concurrency).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
GeoServer connection to target. |
required |
config
|
PublishConfig
|
Publish configuration (workspace, datastore, options). |
required |
progress_callback
|
object
|
Optional callable with signature
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
PublishReport
|
class: |
geotui.report — PDF & JSON Reports
report
PDF and JSON report generation for GeoTUI bulk publish operations.
Provides two public functions: - generate_json_report: write a machine-readable JSON summary. - generate_pdf_report: write a branded, human-readable PDF summary.
generate_json_report(report, output_path)
Write a machine-readable JSON report to output_path.
The report contains:
- generated: ISO-8601 timestamp.
- config: publish configuration (password redacted).
- summary: aggregate counts and totals.
- warnings: list of warning strings.
- results: per-bundle outcome records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report
|
PublishReport
|
The completed publish report. |
required |
output_path
|
Path
|
Destination file path (parent must exist or will be created). |
required |
generate_pdf_report(report, output_path)
Write a branded PDF report to output_path.
The PDF is A4 landscape and contains four sections: 1. Job summary (key-value metadata). 2. Warnings (if any). 3. Per-bundle detail table (colour-coded status pills). 4. Aggregate summary statistics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
report
|
PublishReport
|
The completed publish report. |
required |
output_path
|
Path
|
Destination file path (parent will be created if needed). |
required |
Widgets
geotui.widgets.dual_pane — Dual Pane Layout
dual_pane
Dual pane widget - the core Midnight Commander-style layout.
DualPane(config_manager, **kwargs)
Bases: Widget
A dual-pane widget in the style of Midnight Commander.
Left pane: local file browser. Right pane: GeoServer resource tree from all configured connections.
Initialize the dual pane.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_manager
|
ConfigManager
|
Application configuration manager. |
required |
compose()
Compose dual pane layout.
on_mount()
Set initial focus to left pane.
toggle_active_pane()
Toggle between left and right pane.
watch_active_pane(value)
React to active pane changes.
get_active_pane_type()
Get the type of the currently active pane.
Checks both the reactive state and actual focus to determine which pane is active. Returns 'geoserver' if the GeoServer pane is active and has connections, 'local' otherwise.
Returns:
| Type | Description |
|---|---|
str
|
'geoserver' or 'local'. |
geotui.widgets.file_pane — File Browser
file_pane
File pane widget - individual pane in the dual-pane layout.
MCDirectoryTree(path, *, name=None, id=None, classes=None, disabled=False)
Bases: DirectoryTree
DirectoryTree with '..' parent directory entry like Midnight Commander.
selected_paths
property
Return the set of selected file paths.
render_label(node, base_style, style)
Render label with selection marker for tagged files.
toggle_select_cursor()
Toggle selection on the node under the cursor.
clear_selection()
Clear all selected files.
FilePane(pane_title='Files', *, id=None)
Bases: Widget
A single file browser pane with directory tree and details.
Initialize the file pane.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pane_title
|
str
|
Title displayed in the pane header. |
'Files'
|
id
|
str | None
|
Widget ID. |
None
|
compose()
Compose the file pane layout.
watch_is_active(value)
Update styling when active state changes.
watch_current_path(value)
Update footer when path changes.
get_selected_path()
Get the path of the highlighted item in the tree.
If the cursor is on a directory, returns that directory. If on a file, returns its parent directory. Falls back to current_path if no cursor node.
Returns:
| Type | Description |
|---|---|
Path
|
Path to the selected directory. |
get_selected_files()
Get files selected via Ctrl+T, with smart shapefile companion detection.
If files are selected via Ctrl+T, returns those files plus any shapefile companions. If no files are tagged, returns an empty list (caller should fall back to directory-level discovery).
Returns:
| Type | Description |
|---|---|
list[Path]
|
List of selected file paths with companions included. |
action_toggle_select()
Toggle selection on the file under cursor, then move down.
navigate_to(path)
Navigate the tree to a new root directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Directory to navigate to. |
required |
on_directory_tree_directory_selected(event)
Handle directory selection - navigate into selected directory.
on_directory_tree_file_selected(event)
Open file with system default viewer.
open_file(path)
staticmethod
Open a file with the system default application.
Cross-platform: uses xdg-open (Linux), open (macOS), or start (Windows).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the file to open. |
required |
find_shapefile_companions(path)
Find all companion files for a shapefile component.
Given any shapefile component (e.g. roads.shp, roads.dbf), returns all sibling files with the same stem and a shapefile extension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to any shapefile component file. |
required |
Returns:
| Type | Description |
|---|---|
list[Path]
|
Sorted list of all companion paths (including the input file). |
is_shapefile_component(path)
Check if a path is a shapefile component file.
geotui.widgets.geoserver_tree — GeoServer Tree
geoserver_tree
GeoServer resource tree widget.
Displays the GeoServer resource hierarchy (workspaces > stores > layers) in a tree view, populated from all configured connections. Provides actions for creating workspaces and stores via the F2 context menu.
TreeNodeData(node_type, name, connection_id, resource=None)
dataclass
Data attached to each tree node for identification.
Attributes:
| Name | Type | Description |
|---|---|---|
node_type |
str
|
One of 'root', 'connection', 'workspace', 'datastore', 'coveragestore', 'wmsstore', 'layer', 'coverage', 'error'. |
name |
str
|
Display name of the node. |
connection_id |
str
|
ID of the Connection this node belongs to. |
resource |
GeoServerResource | None
|
Optional GeoServerResource for resource nodes. |
GeoServerTree(config_manager, **kwargs)
Bases: Widget
Tree widget showing GeoServer workspace/store/layer hierarchy.
Initialize the tree widget.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_manager
|
ConfigManager
|
The application config manager containing connections. |
required |
compose()
Compose the tree widget.
on_mount()
Set initial state and load connections.
refresh_connections()
Rebuild the tree from the config manager's connections.
on_tree_node_expanded(event)
Handle tree node expansion - lazy-load connection trees.
action_create_workspace()
Show the create workspace form.
action_create_store()
Show the store type selector.
on_option_list_option_selected(event)
Handle store type selection from the list.
action_copy_from_local()
Copy spatial files from the local pane to GeoServer (F5 handler).
action_delete_selected()
Delete the selected resource after confirmation.
action_refresh()
Refresh the selected connection, or all connections if none selected.
on_button_pressed(event)
Handle action panel buttons.
watch_is_active(value)
Update styling when active state changes.
refresh_tree()
Refresh the tree - delegates to refresh_connections.
Kept for backwards compatibility with action_menu and other callers.
geotui.widgets.status_bar — Status Bar
status_bar
Status bar widget for GeoTUI.
StatusBar
Bases: Widget
Status bar showing connection info and branding.
compose()
Compose status bar.
Screens
geotui.screens.settings — Settings Screen
settings
Settings screen for managing GeoServer connections.
Single-screen layout with connection list on the left and detail/edit form on the right. No popups - all CRUD happens inline following the cloudbench pattern.
ConnectionListItem(conn)
Bases: ListItem
A list item representing a GeoServer connection.
Initialize with a connection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conn
|
Connection
|
The connection this item represents. |
required |
compose()
Compose the list item.
SettingsScreen(config_manager)
Bases: Screen[None]
Settings screen for managing GeoServer connections.
Layout: connection list (left) | detail/edit form (right). Modes: view (read-only detail) and edit (form with inputs).
Initialize the settings screen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_manager
|
ConfigManager
|
The application config manager. |
required |
compose()
Compose the settings screen layout.
on_mount()
Initialize screen state.
on_list_view_selected(event)
Handle connection selection from the list.
on_button_pressed(event)
Handle button presses.
action_add()
Start adding a new connection.
action_edit()
Edit the selected connection.
action_delete()
Delete the selected connection.
action_test_connection()
Test the selected connection.
action_go_back()
Return to the main screen.
geotui.screens.unlock — Master Password Screen
unlock
Master password unlock screen.
Shown at startup when a vault is configured. The user must enter their master password to decrypt stored connection credentials. Also handles first-time vault setup.
UnlockScreen(*, is_setup=False)
Bases: ModalScreen[str | None]
Master password prompt shown at startup.
Returns the master password on success, or None if reset/cancelled.
Initialize the unlock screen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
is_setup
|
bool
|
True if this is first-time vault setup. |
False
|
compose()
Compose the unlock screen.
on_mount()
Focus the password input.
on_input_submitted(event)
Handle enter key in input fields.
on_button_pressed(event)
Handle button presses.
action_cancel()
Cancel - exit the app.
geotui.screens.context_menu — Context Menu
context_menu
Context-sensitive F2 menu.
Shows different actions depending on the active pane type: - GeoServer pane (with active connection): workspace/store operations - Local file pane: filesystem operations
ContextMenuScreen(pane_type)
Bases: ModalScreen[str | None]
Modal context menu triggered by F2.
Returns the selected action ID or None if cancelled.
Initialize the context menu.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pane_type
|
str
|
Type of active pane ('geoserver' or 'local'). |
required |
compose()
Compose the menu.
on_mount()
Populate menu options based on pane type.
on_option_list_option_selected(event)
Handle menu item selection.
action_cancel()
Cancel the menu.
geotui.screens.confirm — Confirmation Dialog
confirm
Confirmation dialog for destructive actions.
ConfirmScreen(title, message, *, require_name=None)
Bases: ModalScreen[bool]
Modal confirmation dialog.
Returns True if confirmed, False if cancelled. When require_name is set, the user must type the exact resource name before the Delete button becomes active.
Initialize confirmation dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Dialog title. |
required |
message
|
str
|
Confirmation message. |
required |
require_name
|
str | None
|
If set, user must type this name to confirm. |
None
|
compose()
Compose the dialog.
on_input_changed(event)
Enable Delete button only when typed name matches.
on_button_pressed(event)
Handle button presses.
action_cancel()
Cancel the dialog.
geotui.screens.splash — Splash Screen
splash
Splash screen displaying the Kartoza logo on startup.
The logo is generated from the Kartoza SVG using half-block character rendering (similar to catimg/term2alpha approach used in timlinux/nix-vim). Regenerate with:
magick resources/KartozaSymbolCMYK.svg -resize 200x200 \
-background '#1a1a2e' -flatten resources/kartoza-logo.png
python scripts/logo_to_rich.py 36 > src/geotui/screens/logo_data.py
SplashScreen
Bases: Screen[None]
Splash screen with Kartoza logo shown on startup.
compose()
Compose the splash screen.
on_mount()
Auto-dismiss after 2 seconds.
on_key()
Dismiss on any key press.
on_click()
Dismiss on mouse click.
Theme & Internationalisation
geotui.theme — Kartoza Brand Theme
theme
Kartoza brand theme for GeoTUI.
geotui.i18n — Internationalisation
i18n
Internationalization support for GeoTUI.
Supports English (default), Portuguese, and Spanish with runtime switching.
set_language(lang)
Set the active language.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lang
|
str
|
Language code (en, pt, es). |
required |
get_current_language()
Get the current language code.
Returns:
| Type | Description |
|---|---|
str
|
Current language code. |
cycle_language()
Cycle to the next available language.
Returns:
| Type | Description |
|---|---|
str
|
New language code. |
_(message)
Translate a message string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
The message to translate. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Translated message string. |