Migrating to 0.18
From 0.17 to 0.18
Protean 0.18 right-sizes the runtime dependency surface. A plain
pip install protean no longer forces a web server, an ASGI stack, an
interactive REPL, and a project scaffolder onto every install. Those concerns
now live behind install extras, matching how the database and broker adapters
have always worked. See
ADR-0029
for the boundary and the rationale.
This is a Tier-1 breaking change, but a small one: nothing in your code changes, and the fix when you hit it is a one-word extra. If a feature you use now needs an extra, the CLI or the import tells you exactly which one.
On this page:
- What moved behind extras
- The one-line fix:
protean[all]restores the old install - What each feature needs now
- cffi and greenlet left the core install
- werkzeug left the core install
What moved behind extras
Five packages that used to be hard runtime dependencies are now install extras:
| Package(s) | Extra | Feature it gates |
|---|---|---|
fastapi, uvicorn, jinja2 |
protean[server] |
protean observatory, protean.integrations.fastapi |
ipython |
protean[shell] |
protean shell |
copier |
protean[scaffold] |
protean new |
Two convenience bundles are also available:
protean[cli]: the full interactive CLI experience (shell+scaffold).protean[all]: everything that used to ship in the core install (server+cli).
import protean and defining a domain, persisting through the memory adapter,
and running protean server (the async engine) need none of these: they
were already lazy, and they stay in the lean core.
The one-line fix
If your project relied on the old fat install and you would rather not think
about which extras you need, install all:
pip install "protean[all]"
That restores every package that shipped in the 0.17 core. From there you can trim to the specific extras you actually use whenever you like.
What each feature needs now
You only need to act if you use one of these features and you install a
trimmed set of dependencies (for example in a production image that installs
protean without [all]):
- Running the Observatory (
protean observatory) or using the FastAPI integration (from protean.integrations.fastapi import ...):
pip install "protean[server]"
- Opening the domain shell (
protean shell):
pip install "protean[shell]"
- Scaffolding a project (
protean new):
pip install "protean[scaffold]"
If you run one of these without its extra, the command fails with a clear
message naming the extra to install, not a raw ModuleNotFoundError:
Error: 'protean observatory' requires the 'fastapi' package. Install it with 'pip install "protean[server]"'.
Field sanitization is unaffected: bleach stays in the core install, because
String and Text fields sanitize by default.
cffi and greenlet left the core install
0.17 installed cffi and greenlet as hard dependencies, but nothing in
Protean imports either package. They only ever arrived as transitive
dependencies: SQLAlchemy (the postgresql, sqlite, and mssql extras)
requires greenlet on common platforms, and cryptography (pulled in by the
sendgrid extra) requires cffi.
In 0.18 both are out of the core install. Their version floors moved onto the
extras that pull them (greenlet>=3.2.3,<4 on the SQLAlchemy extras,
cffi>=2.0.0 on sendgrid), so installing one of those extras still resolves
a version with wheels for the newest supported Python.
You only need to act if your own code imports cffi or greenlet and relied
on Protean to provide it. Declare the package in your own project instead.
werkzeug left the core install
0.17 used Werkzeug's LocalProxy/LocalStack to back current_domain,
current_uow, and g. In 0.18 these context locals are backed by stdlib
contextvars, and werkzeug is no longer a core dependency.
For nearly all code this is transparent: the same push/pop nesting, the same
proxy behavior, and the same async support (in fact, contextvars follows
asyncio tasks and await boundaries natively). The public surface of
current_domain, current_uow, and g is unchanged.
You only need to act if your own code depends on Werkzeug-specific details of
the proxy or stack, such as inspecting the underlying LocalStack directly.
Internal helpers like _domain_context_stack and _uow_context_stack remain
private and have changed their implementation type.