Skip to main content

fakecspace

A small simulated CollectionSpace services API, for developing and testing UC Berkeley's CollectionSpace apps: the Bulk Media Uploader (cspace-bulk-media-uploader) and Serena, the media server (cspace-media-server). Both apps use this one copy of the simulator.

It is not CollectionSpace, and it must never hold real data. Its accounts are synthetic and each password is the user name (published here, in src/fakecspace/accounts.py). Its records are in memory and gone when it stops. Behaviour against the real server must be confirmed on a CollectionSpace test tenant. Each app's deployment keeps its own switch, so the simulator is never deployed with production.

What it simulates

  • One CollectionSpace per museum (bampfa, botgarden, cinefiles, pahma, ucjeps), each with its own records. The museum comes from the host name a request uses (pahma.fakecspace) or a path prefix (/pahma/cspace-services/...); PAHMA when neither names one. Tenant IDs are synthetic (PAHMA is 14).
  • Accounts: accounts/0/accountperms and accounts/0/accountroles, with the BMU's users (admin, limited, intern, newstaff, reader, bmureader) and Serena's (serena, pahma-admin, viewer; admin is a Serena admin of every museum).
  • Records: Media (GET, POST, search by identificationNumber, title or blobCsid), files attached with PUT media/<csid>/blob, Objects, Relations, groups, Person and Organization terms, the languages vocabulary, and the date parser.
  • Files: media/<csid>/blob/content, media/<csid>/blob/derivatives/<name>/content, blobs/<csid> and blobs/<csid>/derivatives/<name>/content. A file uploaded the BMU's way is served as the original and as every derivative (Thumbnail, Small, Medium, FullHD, OriginalJpeg). A file over 5 MB isn't kept: the record then has no file.
  • Development hooks under /_fake (src/fakecspace/hooks.py lists them): reset, sample sets, records with sample files, soft delete, replace, an outage, failures on demand, slowness, and terms changed meanwhile.

The simulator starts empty. A client asks for the samples it needs after each reset:

curl -X POST http://localhost:8180/_fake/reset
curl -X POST http://localhost:8180/_fake/seed -H 'Content-Type: application/json' -d '{"set": "bmu"}'

Failures on demand

POST /_fake/fail takes one JSON shape for both apps:

Field Meaning
step One step of the BMU's work: media, upload, objectSearch, objectCreate, relation, mediaSearch, group, termRead. Without a step, the rule applies to every request whose path contains path.
path Part of a request's path, e.g. /blob/content.
match With a step: part of a name the step carries (identification number, file name, object number, group title, term).
status The HTTP status answered (default 500).
effect none or many, for objectSearch and mediaSearch: what the search finds, instead of a status.
times How many requests fail (default 1; 0 until DELETE /_fake/fail).
agent Only requests whose User-Agent starts with this, e.g. bmu-worker for the BMU's job runs.
curl -X POST http://localhost:8180/_fake/fail -H 'Content-Type: application/json' \
  -d '{"path": "/blob/content", "status": 503, "times": 2}'

Using it from an app

Pin a version from PyPI, with its hash, in the app's development requirements (pip install fakecspace for a quick try). The extras: server (uvicorn, to run it) and bands (pyvips, for records with a size band).

In tests, call it in-process, with no server:

from fastapi.testclient import TestClient
from fakecspace.app import app, stores

stores.reset()                       # every museum's store empty
client = TestClient(app, base_url="http://pahma.fakecspace")
stores["pahma"].add("m-1")           # a Media record with sample files

fakecspace.app.store is PAHMA's store. A Media record (store.media[csid]) can be read by attribute (media.blob) or by CollectionSpace's field name (media["blobCsid"]).

To run it: uvicorn fakecspace.app:app --port 8180, or docker build -t fakecspace . && docker run --rm -p 8180:8180 fakecspace.

Development

Python 3.11 (.python-version).

python3.11 -m venv .venv && . .venv/bin/activate
pip install --require-hashes -r requirements-dev.txt
pip install --no-deps --no-build-isolation -e .
pytest -q && ruff check . && mypy

Dependencies are listed in pyproject.toml and pinned with hashes in requirements.txt (the server, what the Dockerfile installs), requirements-dev.txt and requirements-tools.txt, all made by ./pin-requirements.sh. Never edit those files by hand. CLAUDE.md has the rules for changes.

Releasing

  1. In a pull request, set the new version in src/fakecspace/__init__.py and add it to CHANGELOG.md.
  2. Optional dry run: Actions › Publish › Run workflow on the branch publishes it to TestPyPI.
  3. After the merge, tag the merge commit vX.Y.Z and push the tag. The Publish workflow builds it and, once a reviewer approves the pypi environment, publishes it to PyPI through trusted publishing (no stored token).
  4. Dependabot then proposes the new version in each app.

License

Copyright The Regents of the University of California: educational, research and not-for-profit use. See LICENSE.

Metadata

Release files for fakecspace 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fakecspace 0.2.0
File Size Uploaded Provenance Actions
fakecspace-0.2.0.tar.gz 37.1 kB With provenance Details for fakecspace-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fakecspace 0.2.0
File Interpreter ABI Platform Actions
fakecspace-0.2.0-py3-none-any.whl Python 3 none any Details for fakecspace-0.2.0-py3-none-any.whl

Total release size: 68.7 kB

Release files / fakecspace-0.2.0.tar.gz

Download URL fakecspace-0.2.0.tar.gz
Size 37.1 kB
Tags Source
SHA-256 checksum
How to use checksums
28af0140e5bb6fa9b284e322a919fa0bfd690650b2d9e6d703aea89c51ea9fbe
BLAKE2b-256 checksum
How to use checksums
65182b7a5ff8d6458c097c4286e8308e00d78fc59d6abc1a857e35bdf75888fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Release files / fakecspace-0.2.0-py3-none-any.whl

Download URL fakecspace-0.2.0-py3-none-any.whl
Size 31.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3853b1ab9dc80d8ae0531a0ccd7ca973c8bf06d83872de38453493d7e27e623c
BLAKE2b-256 checksum
How to use checksums
c89d2aa0beb272ab086a9d496376e3f3af411a1b37b30e469b5e7c05b1f54d3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Security for fakecspace 0.2.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for fakecspace-0.2.0.tar.gz

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 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page