dump-things-server/dump_things_service/manifest.py
Christian Monch 20004063b0
Some checks failed
Test execution / Test-all (push) Failing after 1m17s
[temp] add pagination after FastAPI.setup()
2026-05-08 14:08:38 +02:00

134 lines
5.1 KiB
Python

import logging
from fastapi_pagination import add_pagination
from dump_things_service.abstract_config import (
Configuration,
TokenConfig,
)
from dump_things_service.collection import create_collection
from dump_things_service.instance_state import InstanceState
logger = logging.getLogger('dump_things_service')
def manifest_configuration(
configuration: Configuration,
instance_state: InstanceState,
):
"""Interpret the configuration and instantiate respective objects
For every collection in the configuration this method will:
- create a `ModelStore`-instance with correct `Backend`-instances and
check for compatibility with existing data
- create schema-related objects
- add schema class-specific http-endpoints to:
-- validate records
-- create records in the user's inbox
-- create records in the curated area
-- create records in a specific incoming area
Objects and endpoints that belong to a non-existing configuration are
deleted.
If objects for a collection do already exist, they are kept unmodified
and are not validated. That means changes of existing configuration objects
are not possible. To modify a collection or token configuration, the
configuration has to be deleted and created in the new state.
If case of an error in the configuration, no objects will be create for
the respective collection or token.
Tokens can be updated. Collections can not be updated, to modify the
configuration of a collection, the collection must be deleted and
recreated with the modified configuration. Deleting a collection will
not delete the data of the collection. If the collection is recreated with
the same backend- and directory-configuration, the data will be accessible
in the new collection as well. It is, however, not recommended to update
the schema of a collection. This will most likely break the service on this
collection.
When collections are deleted, some tokens might still refer to them, this
is silently ignored. This supports to delete a collection and delete or
modify the token later.
Default-tokens are not validated when a new collection is created. This
allows to first create a collection and then the default token. The cost
is that a "default-token unknown" error might be created when accessing
a collection.
"""
# Determine the changes in collections.
existing_collections = set(instance_state.collections)
configured_collections = set(configuration.collections)
new_collection_names = configured_collections - existing_collections
deleted_collection_names = existing_collections - configured_collections
# Delete collection objects of collections that are no longer in the
# configuration (we do not delete the collection from token-objects here
# because token-objects are all re-created below).
for collection_name in deleted_collection_names:
delete_collection(instance_state, collection_name)
# Create the internal representation objects for collections that have been
# added to the configuration.
for collection_name in new_collection_names:
create_collection(
instance_state,
configuration,
collection_name,
)
# Delete all token objects and recreate the tokens. This ensures that
# modified token scope and permissions are set for all tokens.
for token_name in list(instance_state.tokens):
delete_token(instance_state, token_name)
for token_name, token_configuration in configuration.tokens.items():
create_token(
instance_state,
token_name,
token_configuration,
)
if new_collection_names or deleted_collection_names:
instance_state.fastapi_app.openapi_schema = None
instance_state.fastapi_app.setup()
add_pagination(instance_state.fastapi_app)
# We do not create any incoming areas for configuration-file tokens
# here. The reason is that the configuration does not fully determine
# the possible incoming areas because incoming areas come from
# authentication sources and the configuration-file authentication source
# is just one possible authentication source. Other authentication sources
# have unknown means to create incoming area labels.
# Incoming areas are therefore create when a write request for a token
# is authorized.
def create_token(
instance_state: InstanceState,
token_name: str,
token_configuration: TokenConfig,
):
instance_state.tokens[token_name] = token_configuration
def delete_token(
instance_state: InstanceState,
token_name: str,
):
instance_state.tokens.pop(token_name)
def delete_collection(
instance_state: InstanceState,
collection_name: str,
):
instance_state.collections.pop(collection_name)
# TODO: remove all collection-related information from
# instance_state. Maybe all collection-specific information
# should go into the instance_state.collection[x]-object!?
# That would allow to remove it easily.