Storages#
The contract between the server and the data of an application, and the storages that keep the resources in memory.
- class scim2_server.storage.ScimStorage[source]#
Where a SCIM server reads and writes its resources.
Subclass it to connect the server to a data source, such as a SQL database or a directory. The server handles the SCIM protocol, and calls these methods to read, search, create, update and delete resources. Every method receives the
ResourceTypeit applies to, so a single storage can serve several resource types.A storage follows these rules, which
ScimStorageContractchecks:Every resource it returns is a copy. Changing it does not change the stored resource, and the resources it receives are not changed either.
It fills
id,meta.resourceType,meta.created,meta.lastModifiedandmeta.version. It leavesmeta.locationto the server, which knows the URLs.The version changes whenever the resource changes. An update that changes nothing may keep it.
A resource that does not exist raises
NotFoundException.A value already taken by an attribute whose uniqueness is
serverorglobalraisesUniquenessException.It supports what the
ServiceProviderConfigof the server announces, such as sorting. The server refuses the rest before calling the storage.
- abstractmethod get(resource_type: ResourceType, resource_id: str) Resource[source]#
Return a resource.
- Raises:
NotFoundException – When no resource of this type has this identifier.
- abstractmethod search(resource_types: list[ResourceType], search_request: SearchRequest[Any]) tuple[int, list[Resource]][source]#
Return the number of matching resources, and one page of them.
The search request is already validated, and its
countis already bounded by themaxResultsof the server. The storage filters, sorts and pages the resources of every given resource type as a single collection. Several resource types mean a search at the server root.An attribute that a resource type does not declare matches none of its resources (RFC 7644 §3.4.2.1).
- Raises:
InvalidFilterException – When the storage cannot evaluate the filter. Filtering the page afterwards would make
totalResultsand the paging wrong.NotImplementedException – When the storage does not support searching several resource types at once.
- abstractmethod create(resource_type: ResourceType, resource: Resource) Resource[source]#
Store a new resource, and return the stored resource.
- Raises:
UniquenessException – When a unique value is taken.
- abstractmethod update(resource_type: ResourceType, resource: Resource, *, expected_version: str | None = None) Resource[source]#
Replace the stored resource that has the identifier of
resource, and return the stored resource.The server calls it for PUT and PATCH requests. It applies the request to the stored resource first, so
resourceis the whole new state of the resource.- Parameters:
expected_version – The version the stored resource must still have, when given.
- Raises:
NotFoundException – When the resource does not exist.
PreconditionFailedException – When the stored version is not
expected_version.UniquenessException – When a unique value is taken.
- abstractmethod delete(resource_type: ResourceType, resource_id: str, *, expected_version: str | None = None) None[source]#
Delete a resource.
- Parameters:
expected_version – The version the stored resource must still have, when given.
- Raises:
NotFoundException – When the resource does not exist.
PreconditionFailedException – When the stored version is not
expected_version.
- operation() AbstractContextManager[None][source]#
Enclose one SCIM operation: a single request, or one operation of a bulk request.
It does nothing by default. A SQL storage can open a savepoint here, so that a failed operation does not prevent the next ones of a bulk request (RFC 7644 §3.7). Committing the request is left to the application.
- class scim2_server.storage.AsyncScimStorage[source]#
The asynchronous variant of
ScimStorage.Its methods are coroutines, and follow the rules of
ScimStorage, whichAsyncScimStorageContractchecks.- abstractmethod async get(resource_type: ResourceType, resource_id: str) Resource[source]#
Return a resource. See
ScimStorage.get().
- abstractmethod async search(resource_types: list[ResourceType], search_request: SearchRequest[Any]) tuple[int, list[Resource]][source]#
Return the number of matching resources, and one page of them. See
ScimStorage.search().
- abstractmethod async create(resource_type: ResourceType, resource: Resource) Resource[source]#
Store a new resource. See
ScimStorage.create().
- abstractmethod async update(resource_type: ResourceType, resource: Resource, *, expected_version: str | None = None) Resource[source]#
Replace a stored resource. See
ScimStorage.update().
- abstractmethod async delete(resource_type: ResourceType, resource_id: str, *, expected_version: str | None = None) None[source]#
Delete a resource. See
ScimStorage.delete().
- operation() AbstractAsyncContextManager[None][source]#
Enclose one SCIM operation. See
ScimStorage.operation().
- class scim2_server.memory.InMemoryStorage(clock: Callable[[], ~datetime.datetime]=<function utcnow>)[source]#
A storage keeping the resources in memory, for tests, debugging and demos.
It is not optimized for performance: a search walks every resource. A lock serializes every access, so it can serve a threaded server.
- Parameters:
clock – Return the date of a write, for
meta.createdandmeta.lastModified. Pass a fixed clock to get predictable dates.
- generate_id(resource_type: ResourceType, resource: Resource) str[source]#
Return the identifier of a new resource.
Override this method to get predictable identifiers.
- class scim2_server.memory.AsyncInMemoryStorage(storage: InMemoryStorage | None = None)[source]#
The asynchronous variant of
InMemoryStorage.It serves the resources of an
InMemoryStorage. Every call runs without awaiting anything, so a call is never interrupted by another coroutine.operation()takes no lock: holding the lock of the storage across anawaitwould block the event loop. Two concurrent updates of a resource are still told apart byexpected_version.- Parameters:
storage – The storage to serve. Pass a subclass of
InMemoryStorageto change how identifiers are generated.