GitHub - dbos-inc/dbosify-py: Postgres-Backed Drop-in Temporal Replacement · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
dbos-inc
dbosify-py
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>37 Commits<br>37 Commits
.github/workflows
.github/workflows
dbosify
dbosify
docs
docs
publish
publish
tests
tests
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
pyproject.toml
pyproject.toml
uv.lock
uv.lock
View all files
Repository files navigation
DBOSify
DBOSify is a drop-in replacement for Temporal Python that uses Postgres (through DBOS Transact) instead of a Temporal server.<br>This lets you run durable workflows, activities, signals, updates, retries, and recovery without needing any infrastructure except Postgres.
To use this library, import dbosify instead of temporalio and connect your workers and clients to a Postgres database:
Usage
To install:
pip install dbosify
This is a drop-in replacement: simply import dbosify instead of temporalio and connect your clients and workers to a Postgres database instead of a Temporal server.<br>Further documentation here.
str:<br>return f"Hello, {name}!"
@workflow.defn<br>class GreetingWorkflow:<br>@workflow.run<br>async def run(self, name: str) -> str:<br>return await workflow.execute_activity(<br>compose_greeting, name, start_to_close_timeout=timedelta(seconds=10)
async def main() -> None:<br>worker = Worker(<br>DB_URL,<br>task_queue="greetings",<br>workflows=[GreetingWorkflow],<br>activities=[compose_greeting],<br>async with worker:<br>async with await Client.connect(DB_URL) as client:<br>result = await client.execute_workflow(<br>GreetingWorkflow.run, "World", id="greeting-1", task_queue="greetings"<br>print(result) # Hello, World!
if __name__ == "__main__":<br>asyncio.run(main())">import asyncio<br>import os<br>from datetime import timedelta
from dbosify import activity, workflow<br>from dbosify.client import Client<br>from dbosify.worker import Worker
# Set this to a connection string to your Postgres database<br>DB_URL = os.environ.get("DBOS_SYSTEM_DATABASE_URL")
@activity.defn<br>async def compose_greeting(name: str) -> str:<br>return f"Hello, {name}!"
@workflow.defn<br>class GreetingWorkflow:<br>@workflow.run<br>async def run(self, name: str) -> str:<br>return await workflow.execute_activity(<br>compose_greeting, name, start_to_close_timeout=timedelta(seconds=10)
async def main() -> None:<br>worker = Worker(<br>DB_URL,<br>task_queue="greetings",<br>workflows=[GreetingWorkflow],<br>activities=[compose_greeting],<br>async with worker:<br>async with await Client.connect(DB_URL) as client:<br>result = await client.execute_workflow(<br>GreetingWorkflow.run, "World", id="greeting-1", task_queue="greetings"<br>print(result) # Hello, World!
if __name__ == "__main__":<br>asyncio.run(main())
How It Works
DBOSify runs each Temporal workflow as a Postgres-backed DBOS workflow.<br>A deterministic interpreter runs the workflow (both its main coroutine and its signal, update, and query handlers) on a virtual event loop that only advances when an event arrives.<br>Using DBOS steps and workflow communication primitives, all nondeterministic actions are checkpointed in Postgres before the workflow observes them.
Activities and timers become DBOS steps and durable sleeps, each checkpointed on completion.
Signals, updates, and cancellations are durable messages delivered through Postgres using LISTEN/NOTIFY.
Recovery re-runs the workflow on a new worker: the interpreter replays the same sequence of operations against the recorded checkpoints, so execution resumes where it left off and completes exactly once.
Namespaces each map to their own Postgres schema; a Client wraps a DBOS client and a Worker wraps the DBOS runtime.
How It's Tested
As DBOSify is a drop-in replacement for Temporal, its tests cover both correctness and conformance with Temporal using the following strategies:
Ports of all relevant Temporal Python unit and integration tests
Ports of relevant Temporal Python sample applications, verifying DBOSify is a drop-in replacement
New...