Skip to content

Lesson 2 — install Xyberos

What you will build

Nothing: this lesson is about what you get when you install the package, and what you deliberately do not. That distinction decides how you read every later lesson, because an optional capability is an install, not an import that fails mysteriously.

The Python range

Xyberos supports Python 3.10 through 3.13, tested in continuous integration on each of them.

python -m venv .venv
.venv\Scripts\python -m pip install xyberos
python -m venv .venv
.venv/bin/python -m pip install xyberos

The extras

The core package has one dependency, and it is not a web framework, a database driver, or an AI SDK. Everything else is an extra you ask for by name:

Extra What it adds Install
— composition, dependency injection, scopes, lifecycle, configuration, workflows, plugins, and the AI facade with a fake provider pip install xyberos
http the Starlette-backed HTTP adapter pip install "xyberos[http]"
database the SQLite provider, Alembic migrations, and the provider conformance suite pip install "xyberos[database]"
ollama the Ollama adapter pip install "xyberos[ollama]"
durable the experimental durable executor pip install "xyberos[durable]"

The AI facade being in core is the part that surprises people, so it is what the example proves.

The code

examples/learn_fundamentals/fundamentals02_install.py
"""Lesson 2 — what installing Xyberos gives you, and what it deliberately does not.

The core package imports no optional capability, so a missing extra is a stated requirement rather
than an import error somewhere else. This module proves the property by running: it records what is
loaded before the AI import, and asks the facade for an answer with no SDK involved.
"""

from __future__ import annotations

import asyncio
import sys

import xyberos


async def main() -> None:
    """Show that the core package, and the AI facade, need no extra installed."""
    print(f"xyberos {xyberos.__version__}")

    before = "httpx" in sys.modules
    from xyberos.ai import AIFacade, ChatRequest, FakeModelProvider, Message, ModelReply

    print("importing the AI facade pulled in an SDK:", "httpx" in sys.modules and not before)

    facade = AIFacade(FakeModelProvider([ModelReply.ok("hello from the fake")]))
    answer = await facade.chat(ChatRequest(messages=(Message.user("hi"),), model="fake"))
    print("an answer with no SDK installed:", answer.message.content)


if __name__ == "__main__":
    asyncio.run(main())

How to run it

$env:PYTHONPATH = "src;examples"
python -m learn_fundamentals.fundamentals02_install
PYTHONPATH=src:examples python -m learn_fundamentals.fundamentals02_install

In your own project, python -m pip install xyberos is the only prerequisite; this file needs no extra.

What it prints

xyberos 2.0.0
importing the AI facade pulled in an SDK: False
an answer with no SDK installed: hello from the fake

Read the middle line carefully: the module records whether httpx was loaded before importing xyberos.ai, then checks again. Importing the facade pulls in no vendor SDK, in any environment — which is why the last line can ask a model for an answer with nothing installed but the core package.

Common mistakes

  • Installing an extra you do not need. The core package is the smallest thing that can run an application; adding http to a script that never answers a request is a dependency you now maintain.
  • Expecting a helpful error from a bare import. A missing extra reports the extra to install, and the message is part of the contract — the command line repeats it verbatim. That is why tests/test_optional_dependencies.py exists.
  • Assuming the AI facade needs a model service. It needs one when you point it at a real provider. The fake provider is not a mock of the facade; it is a provider, with declared capabilities, that answers instantly.

Exercise

Run the same file with an extra installed and count the difference.

Show the answer === "PowerShell"
python -m pip install "xyberos[http]"
$env:PYTHONPATH = "src;examples"
python -m learn_fundamentals.fundamentals02_install
The output does not change. Installing an extra makes a capability *available*; it does not make the core package import it, which is exactly the property the middle line of output tests. Check it from the other direction: `python -c "import sys, xyberos; print([m for m in ('starlette', 'sqlalchemy') if m in sys.modules])"` prints `[]` with the extras installed.

Next

Lesson 3 creates a project you can run, so that the rest of the path works on a real layout rather than on a single file. Until it is published, the roadmap shows where each lesson stands.