Skip to main content

onlyworlds (Python)

OnlyWorlds is an open standard for worldbuilding data: 22 element types (characters, locations, events, laws and the rest) that any tool can read and write. This is a Python client for its API, and a reader and writer for OnlyWorlds world folders (a world as a folder of JSON files). Python 3.12+, no runtime dependencies (the optional OKF export needs PyYAML).

Install

pip install onlyworlds

The newest unreleased code: pip install git+https://github.com/OnlyWorlds/python-sdk.

First run

Moppetopia is a public demo world. Its read-only key, 0000000001, needs no account:

from onlyworlds import Client

client = Client("0000000001")
print(client.get_world()["name"])
for c in client.list_page("character", filter={"name__icontains": "fluffington"})["data"]:
    print(" ", c["name"])
Moppetopia
  Admiral Fluffington

Your own world

Create a world at onlyworlds.com; its keys are on the world's page. A new key is shown once, so copy it then.

  • An ow_r_ key reads, with no PIN: Client("ow_r_…").
  • An ow_w_ key reads and writes. Writes also send a PIN: Client("ow_w_…", "…").
  • For code that writes, give it its own agent seat, a key for one tool or script. The seat's key and its ow_s_ secret (passed as the PIN) work in one world, and you can remove them without touching your account PIN.

Elements are plain dicts:

writer = Client("ow_w_…", "ow_s_…")
peak = writer.create("location", {"name": "Dragon Peak"})
writer.patch("location", peak["id"], {"supertype": "Mountain"})

for character in client.iter_elements("character", expand=["species"]):
    print(character["name"])

World folders

A world folder is one JSON file per element, in the world folder format. Atlas, the OnlyWorlds editor, reads and writes the same format.

from onlyworlds import export_world, read_folder

export_world("moppetopia", api_key="0000000001")
folder = read_folder("moppetopia")
print(folder.world["name"], len(folder.elements), "elements")

write_folder(root, world, elements) writes a folder from a world dict and a dict of element lists by type. Reading never changes a file, and a file without an id is skipped and left alone.

To send a folder's edits back, keep a copy exported before you edited, then push the difference:

from onlyworlds import push

result = push("moppetopia-before", "moppetopia", api_key="ow_w_…", pin="ow_s_…", log_path="push.jsonl")

push sends only the fields that changed, retries what the server asks it to retry, checks that what came back is what it sent, and logs every write, so running it again skips what already landed. dry_run=True shows the plan without sending it.

Export to OKF

A world folder can be exported as a valid Open Knowledge Format (OKF) 0.2 bundle, as the spec stands at one pinned commit (onlyworlds.okf.OKF_COMMIT): one markdown file per element, with its fields in the frontmatter, its text under headings and its links (in-prose ow:// references included) as markdown links, plus an index per type. This needs PyYAML, which the rest of the package does not:

pip install "onlyworlds[okf]"
python -m onlyworlds.okf moppetopia moppetopia-okf
from onlyworlds.okf import export_okf

report = export_okf("moppetopia", "moppetopia-okf")
print(report.elements, "elements,", len(report.notes), "notes")

The output directory must not exist yet. Anything the export leaves out (a file that isn't an element, a key that isn't a field, a link to the wrong type) is listed in report.notes; the command prints these on stderr. The same folder always gives the same bytes. What a bundle never carries: the server's bookkeeping (change_seq, created_at, who wrote what) and the world's key, so a bundle is a copy to read elsewhere, not a folder to sync.

Errors

A failed call raises ApiError with the API's code, param (the field that failed) and doc_url, and flags for the cases you handle differently: is_validation_error, is_auth_error, is_not_author, is_owner_only, is_id_conflict, is_resync_required, is_busy, is_precondition_failed.

To write only if nobody changed an element since you read it, pass its change_seq: client.patch("character", el["id"], {"name": "Mine"}, if_match=el["change_seq"]) (on edit_links too). If it moved, nothing is written and PreconditionFailed is raised, whose current is the element as it is now. The server never merges: compare the copy you edited from with current, and send again with if_match=current["change_seq"] or ask which version to keep.

The change feed

walk = client.walk_changes(saved_cursor)  # None for everything
for op in walk:
    ...  # op["op"] is "upsert" or "delete"
saved_cursor = walk.cursor  # opaque: keep it, don't parse it

Schema

The 22 element types and each field's kind are generated from the published schema distribution; onlyworlds.SCHEMA_VERSION and onlyworlds.SCHEMA_DIST_TAG say which one. The package's own version doesn't track the schema's.

Not yet: typed element models, the account routes, a snapshot writer.

Develop

uv sync
uv run pytest -q
uv run ruff check . && uv run mypy --strict src
uv run python codegen/generate_schema.py --check

Three groups of tests run only when asked:

  • OW_CONFORMANCE_FIXTURE=<path>: the folder-format conformance fixture from the Atlas repo.
  • OW_OPENAPI=https://www.onlyworlds.com/api/v2/openapi.json (or a saved copy): checks the client's routes, parameters and fields against the API's own OpenAPI document.
  • OW_LIVE=1: read-only calls against the demo world.

OKF_REFERENCE_SRC=<path> (the src/ of an open-knowledge-format checkout) also runs OKF's own parser and viewer over an exported bundle.

License

MIT. See LICENSE.

Metadata

Release files for onlyworlds 0.6.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 onlyworlds 0.6.0
File Size Uploaded
onlyworlds-0.6.0.tar.gz 160.9 kB Details

Built distribution (wheel)

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

Total release size: 209.2 kB

Release files / onlyworlds-0.6.0.tar.gz

Download URL onlyworlds-0.6.0.tar.gz
Size 160.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6057a23e95ef44d87e7020acbab1b62f209b5ced793ae91a2a3f1e32978ee071
BLAKE2b-256 checksum
How to use checksums
0bad61fa4f431f5be58f73459931524c7818a9b933134fbeed8a3b4a8043f4ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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

Transparency log

Release files / onlyworlds-0.6.0-py3-none-any.whl

Download URL onlyworlds-0.6.0-py3-none-any.whl
Size 48.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e2bcb036e230700d2cc176c1622d5fcd2b0422eb542525015bdd59c87b683f6
BLAKE2b-256 checksum
How to use checksums
01cdae9cca8bb64d8d10a53567fbe3f32cb2ff094ff01991a9beca6d93b32e1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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

Transparency log

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

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