This page describes the architecture owned by this repository and the high-level relationship between fmu-settings and the surrounding FMU Settings repositories.
fmu-settings is the behavioral core. It reads, writes, and manages resources in project and user .fmu/ directories, including locking, diffing, caching, restoring, and validation.
flowchart LR
CLI["fmu-settings-cli\nTyper launcher"]
API["fmu-settings-api\nFastAPI backend and static-file host"]
GUI["fmu-settings-gui\nReact SPA and packaged static assets"]
LIB["fmu-settings\nCore .fmu library"]
MODELS["fmu-datamodels\nShared Pydantic domain models"]
CLI -->|starts one application process\ncreates bootstrap token| API
CLI -->|gets packaged static directory| GUI
CLI -->|uses init/find/sync/copy helpers| LIB
CLI -->|loads global configuration models| MODELS
GUI -->|generated OpenAPI client\nwith cookie session| API
API -->|reads/writes .fmu resources\nlock/cache/changelog/session flows| LIB
API -->|reuses typed domain models\nfor masterdata, mappings, RMS payloads| MODELS
LIB -->|embeds masterdata, access, model,\nstratigraphy and mapping schemas| MODELS
The dependency chain is intentionally layered:
fmu-settingsreads, writes, and manages the resources stored in.fmu/directories.fmu-datamodelsprovides the shared vocabulary for masterdata, access, global configuration, and mappings.fmu-settings-apiwrapsfmu-settingsin a session-oriented application layer, coordinates interaction with external systems, and serves the packaged GUI assets.fmu-settings-guibuilds and packages the React application, which talks to the API.fmu-settings-cliis the user-facing command line interface for bootstrapping user state, launching the combined application, and running utility commands.
classDiagram
class FMUDirectoryBase {
+base_path: Path
+path: Path
+config
+cache: CacheManager
+get_config_value(key, default)
+set_config_value(key, value)
+update_config(updates)
+read_text_file(relative_path)
+write_text_file(relative_path, content)
+list_restorable_files()
+restore()
}
class ProjectFMUDirectory {
+changelog: ChangelogManager
+mappings: MappingsManager
+find_rms_projects()
+get_dir_diff(new_fmu_dir)
+sync_dir(new_fmu_dir)
+restore_from_cache(relative_path, revision_id)
+get_cache_content(relative_path, revision_id)
}
class UserFMUDirectory
class CacheManager {
+get_revision_content(..., migration_manager)
+restore_revision(..., migration_manager)
}
class LockManager {
+acquire()
+ensure_can_write()
+refresh()
+release()
+is_acquired()
}
class PydanticResourceManager~PydanticResource~ {
+migration_manager
+load(force, store_cache)
+save(model)
+get_resource_diff(incoming_resource)
+get_structured_model_diff(current_model, incoming_model)
}
class MigrationManager~MigratableResource~ {
+model_class
+current_version: int
+migrate_resource(data)
+requires_migration(data)
}
class MutablePydanticResourceManager~MutablePydanticResource~ {
+get(key, default)
+set(key, value)
+update(updates)
+reset()
+merge_changes(changes)
}
class ProjectConfigManager {
+relative_path = config.json
+save(model)
+set(key, value)
+update(updates)
}
class UserConfigManager {
+relative_path = config.json
+save(model)
}
class MappingsManager {
+relative_path = mappings.json
+update_stratigraphy_mappings(...)
+update_wellbore_mappings(...)
+read_rms_eclipse_csv(...)
+write_rms_eclipse_csv(...)
}
class ChangelogManager
class LogManager~Log~ {
+add_log_entry(log_entry)
+filter_log(filter)
}
class UserSessionLogManager
FMUDirectoryBase <|-- ProjectFMUDirectory
FMUDirectoryBase <|-- UserFMUDirectory
PydanticResourceManager <|-- MutablePydanticResourceManager
MutablePydanticResourceManager <|-- ProjectConfigManager
MutablePydanticResourceManager <|-- UserConfigManager
PydanticResourceManager <|-- LockManager
PydanticResourceManager <|-- MappingsManager
PydanticResourceManager <|-- LogManager
LogManager <|-- UserSessionLogManager
FMUDirectoryBase *-- LockManager
FMUDirectoryBase *-- CacheManager
PydanticResourceManager o-- MigrationManager
CacheManager ..> MigrationManager
ProjectFMUDirectory *-- ProjectConfigManager
ProjectFMUDirectory *-- ChangelogManager
ProjectFMUDirectory *-- MappingsManager
UserFMUDirectory *-- UserConfigManager
The main library split is:
FMUDirectoryBaseis the filesystem-centered abstraction. It owns the.fmupath, lock manager, cache manager, and generic read/write helpers.ProjectFMUDirectoryandUserFMUDirectoryspecialize the base class for project-local.fmu/directories and$HOME/.fmu/.PydanticResourceManageris the generic resource engine for loading, saving, diffing, and caching JSON-backed Pydantic models.MigrationManagerapplies registered, forward-only schema migrations and validates the result as the current Pydantic model.MutablePydanticResourceManageradds dot-notationget,set,update,reset, and merge behavior for editable resources.ProjectConfigManager,UserConfigManager,MappingsManager, andLogManagerbind specific Pydantic models to managed files inside.fmu/.- Directory objects compose the correct managers and delegate resource operations to them.
ProjectConfig, UserConfig, and InternalMappings are versioned resources. Each
model declares its current schema version, and each resource manager has a
MigrationManager with the migration registry for that model.
Migration is forward-only. Data without schema_version is treated as version 1.
Each registered migration function increments the schema version by one. The manager
rejects a newer schema, a missing migration step, an invalid version, or data that
does not validate as the current model.
The migration boundary depends on the resource operation:
- Load:
PydanticResourceManagerdecodes the stored JSON and asksMigrationManagerfor a validated current model. Migration happens in memory. Loading does not write the resource, create a cache revision, or add a changelog entry. - Save: The resource manager checks the write lock first. If the stored data is
older, it attempts to store the exact original JSON under
.fmu/migration-backups/before writing the current model. This backup is best-effort: a file-system failure is logged and does not stop the save. The original JSON is also stored as a cache revision. The newly written current data is added as another cache revision. - Cache read:
CacheManageruses the migration manager to return old revisions as current validated models. - Restore:
CacheManagermigrates the selected revision before writing it, so the restored resource uses the current schema. If you roll back to an older release while the pre-migration revision is still retained, restore that revision with the older release to return the resource file to the older schema. Project restore operations use the existing restore changelog entry.
There is no backward migration. After a current-schema resource is saved, an older
fmu-settings release can reject it as newer than supported. If the pre-migration
cache revision is still retained, restore it with the older release. Migration
backups are not loaded or restored by the library. If the cache revision is no longer
available, we should help users copy the appropriate migration backup back to the
resource file before running the older release.
See the schema migration guide for the implementation, test, and coordinated release process.
The full runtime spans multiple repositories, but fmu-settings owns the .fmu/ directory operations used by the API and CLI.
When a user runs the command fmu settings, fmu-settings-cli starts a local application around fmu-settings:
- The CLI ensures the user-level
.fmu/directory exists, creating$HOME/.fmu/throughinit_user_fmu_directory()when needed. - It creates a short-lived bootstrap token used only to authenticate the browser session startup.
- It gets the packaged React static directory from
fmu-settings-guiand starts one FastAPI/Uvicorn process with the static directory, bootstrap token, and runtime settings. - It opens the browser on the local application URL with the bootstrap token in the URL fragment.
- The React app reads the token from the fragment, stores it in browser session storage, and exchanges it for an API session.
- The API verifies the bootstrap token, ensures user settings are available, creates or renews a server-side session, and sets an HttpOnly session cookie.
- If the command was launched from inside an initialized FMU project, the API locates the nearest project
.fmu/directory and tries to acquire its lock. - After session setup, the GUI talks to the API with the session cookie, and the API uses
ProjectFMUDirectoryandUserFMUDirectoryfromfmu-settingsto read and write managed resources.
sequenceDiagram
participant User
participant CLI as fmu-settings-cli
participant Browser
participant SPA as React SPA
participant API as fmu-settings-api
participant Session as SessionManager<br/>fmu-settings-api
participant UserFMU as UserFMUDirectory<br/>fmu-settings
participant ProjectFMU as ProjectFMUDirectory<br/>fmu-settings
User->>CLI: run `fmu settings`
CLI->>UserFMU: init_user_fmu_directory() if needed
CLI->>CLI: generate bootstrap auth token
CLI->>CLI: get packaged GUI static directory
CLI->>API: start local application with assets and token
CLI->>Browser: open application URL with token fragment
Browser->>API: request GUI assets
API-->>Browser: serve React SPA
Browser->>SPA: load application
SPA->>SPA: read token from URL fragment
SPA->>SPA: store token in sessionStorage
SPA->>API: POST /api/v1/session with x-fmu-settings-api
API->>API: verify bootstrap token
API->>UserFMU: ensure ~/.fmu exists and load user config
API->>Session: create or renew session
API->>ProjectFMU: find_nearest_fmu_directory() if present
API->>ProjectFMU: try acquire project lock
API-->>SPA: set HttpOnly session cookie
SPA->>API: subsequent requests with cookie
API->>Session: resolve Session or ProjectSession
API->>ProjectFMU: read/write project config, mappings, cache, changelog
API->>UserFMU: read/write user config and API keys