Get Started¶
Prerequisites¶
- Python 3.10 to 3.13
piporuv(recommended)
Installation¶
uv add osw
pip install osw
Optional extras¶
| Extra | Description |
|---|---|
osw[wikitext] |
Additional functions in wiki_tools to transform mediawiki markup / templates |
osw[DB] |
Interact with SQL databases per DatabaseController |
osw[S3] |
Interact with S3 stores per S3FileController |
osw[dataimport] |
Additional tools to import data |
osw[UI] |
To use a helper UI to work with entity slots |
osw[mcp] |
MCP server for agent clients |
osw[all] |
All of the above |
Install multiple extras with pip install osw[opt1,opt2].
First steps¶
Create a typed entity locally with the generated data model:
import osw.model.entity as model
my_entity = model.Item(
label=[model.Label(text="MyItem")],
statements=[model.DataStatement(property="IsA", value="Category:Item")],
)
print(my_entity.json())
Connect to an instance and run a semantic query with OswExpress:
from osw.express import OswExpress
osw = OswExpress(domain="wiki-dev.open-semantic-lab.org")
instances = osw.site.semantic_search("[[Category:Item]]")
print(instances)
Credentials are resolved from the environment variables OSW_USERNAME /
OSW_PASSWORD (e.g. loaded from a .env file), from an existing
credentials file, or via an interactive prompt - and are held in memory
only, never written to disk; see Authentication.
Logging¶
osw reports what it is doing through the standard logging module, on the
osw logger, at INFO by default:
import osw
osw.set_log_level("WARNING") # see less
osw.set_log_level("DEBUG") # see more
osw.disable_logging() # detach the handler osw attached
Problems that osw can work around are WARNING records on the same logger, not
Python warnings. A truncated query result and a page that does not exist are
examples. A warnings filter or the -W option therefore has no effect on
them. A message that repeats is also written out every time, where the warnings
machinery would have shown it once. Use set_log_level to control them.
The records go to stderr, which leaves stdout free for your program's own
output. That matters for anything speaking a protocol over stdout, such as an
MCP stdio server. Pass osw.enable_logging(stream=...) to send them elsewhere.
Set OSW_LOG_LEVEL to a level name, a level number, or OFF to choose the
level before the package is imported. OFF silences osw everywhere, including
in your own handlers.
Collecting osw's records in your application¶
Configure logging the way you normally would and osw's records arrive there, once:
import logging
import osw
logging.basicConfig(level=logging.INFO, filename="app.log")
The osw logger propagates at all times, so the records reach your handlers
whatever else happens. osw's own handler notices that something above it is
listening, detaches itself so nothing is written twice, and gives back the
level it had picked, so your level applies from then on. It makes no difference
whether you configure logging before or after importing osw.
A level you asked for is kept across that hand-over, so set_log_level("DEBUG")
or OSW_LOG_LEVEL=DEBUG is how you pull osw's debug records into an aggregated
setup while the rest of your application stays quieter.
One case osw cannot detect is a handler added to the osw logger itself, since
that is indistinguishable from one of its own. Call disable_logging() first if
you do that.
Output from parallel batches¶
Several osw calls process their input in parallel. What such a task prints, as
opposed to logs, is collected while the batch runs and replayed afterwards, so
that concurrent writing cannot garble the progress bar. That text arrives on the
osw.parallel.output logger, one record per line, at INFO. Give that logger its
own level or handler to keep the output of third-party code apart from osw's own
records. Most osw calls replay it only when you pass debug=True; copy_pages
always replays.
Examples and tutorials¶
- Runnable scripts in examples/, e.g. entity creation, entity manipulation, querying and file downloads
- The Basics tutorial notebook describes the OpenSemanticLab data model and how to interact with it
Troubleshooting¶
Error: datamodel-codegen not found¶
Make sure datamodel-codegen is installed and included in PATH, e.g. on
jupyterlab:
os.environ["PATH"] += os.pathsep + "/home/jovyan/.local/bin"