dbos 0.20.0a3__tar.gz → 0.20.0a6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dbos might be problematic. Click here for more details.
- {dbos-0.20.0a3 → dbos-0.20.0a6}/PKG-INFO +1 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_core.py +21 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_dbos.py +1 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_fastapi.py +10 -9
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_sys_db.py +1 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/pyproject.toml +1 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/conftest.py +7 -15
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_async.py +1 -1
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_dbos.py +16 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_fastapi.py +76 -2
- {dbos-0.20.0a3 → dbos-0.20.0a6}/LICENSE +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/README.md +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/__init__.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_admin_server.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_app_db.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_classproperty.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_cloudutils/authentication.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_cloudutils/cloudutils.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_cloudutils/databases.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_context.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_croniter.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_db_wizard.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_dbos_config.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_error.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_flask.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_kafka.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_kafka_message.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_logger.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/env.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/script.py.mako +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_outcome.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_queue.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_recovery.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_registrations.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_request.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_roles.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_scheduler.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_schemas/__init__.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_schemas/application_database.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_schemas/system_database.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_serialization.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/README.md +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_tracer.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_workflow_commands.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/cli/_github_init.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/cli/_template_init.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/cli/cli.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/dbos-config.schema.json +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/py.typed +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/__init__.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/atexit_no_ctor.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/atexit_no_launch.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/classdefs.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/more_classdefs.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/queuedworkflow.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_admin_server.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_classdecorators.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_concurrency.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_config.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_croniter.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_failures.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_fastapi_roles.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_flask.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_kafka.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_outcome.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_package.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_queue.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_scheduler.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_schema_migration.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_singleton.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_spans.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/tests/test_workflow_cmds.py +0 -0
- {dbos-0.20.0a3 → dbos-0.20.0a6}/version/__init__.py +0 -0
|
@@ -488,6 +488,22 @@ def start_workflow(
|
|
|
488
488
|
return WorkflowHandleFuture(new_wf_id, future, dbos)
|
|
489
489
|
|
|
490
490
|
|
|
491
|
+
if sys.version_info < (3, 12):
|
|
492
|
+
|
|
493
|
+
def _mark_coroutine(func: Callable[P, R]) -> Callable[P, R]:
|
|
494
|
+
@wraps(func)
|
|
495
|
+
async def async_wrapper(*args: Any, **kwargs: Any) -> R:
|
|
496
|
+
return await func(*args, **kwargs) # type: ignore
|
|
497
|
+
|
|
498
|
+
return async_wrapper # type: ignore
|
|
499
|
+
|
|
500
|
+
else:
|
|
501
|
+
|
|
502
|
+
def _mark_coroutine(func: Callable[P, R]) -> Callable[P, R]:
|
|
503
|
+
inspect.markcoroutinefunction(func)
|
|
504
|
+
return func
|
|
505
|
+
|
|
506
|
+
|
|
491
507
|
def workflow_wrapper(
|
|
492
508
|
dbosreg: "DBOSRegistry",
|
|
493
509
|
func: Callable[P, R],
|
|
@@ -548,7 +564,7 @@ def workflow_wrapper(
|
|
|
548
564
|
)
|
|
549
565
|
return outcome() # type: ignore
|
|
550
566
|
|
|
551
|
-
return wrapper
|
|
567
|
+
return _mark_coroutine(wrapper) if inspect.iscoroutinefunction(func) else wrapper
|
|
552
568
|
|
|
553
569
|
|
|
554
570
|
def decorate_workflow(
|
|
@@ -838,6 +854,10 @@ def decorate_step(
|
|
|
838
854
|
assert tempwf
|
|
839
855
|
return tempwf(*args, **kwargs)
|
|
840
856
|
|
|
857
|
+
wrapper = (
|
|
858
|
+
_mark_coroutine(wrapper) if inspect.iscoroutinefunction(func) else wrapper # type: ignore
|
|
859
|
+
)
|
|
860
|
+
|
|
841
861
|
def temp_wf_sync(*args: Any, **kwargs: Any) -> Any:
|
|
842
862
|
return wrapper(*args, **kwargs)
|
|
843
863
|
|
|
@@ -245,7 +245,7 @@ class DBOS:
|
|
|
245
245
|
return _dbos_global_instance
|
|
246
246
|
|
|
247
247
|
@classmethod
|
|
248
|
-
def destroy(cls, *, destroy_registry: bool =
|
|
248
|
+
def destroy(cls, *, destroy_registry: bool = False) -> None:
|
|
249
249
|
global _dbos_global_instance
|
|
250
250
|
if _dbos_global_instance is not None:
|
|
251
251
|
_dbos_global_instance._destroy()
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import uuid
|
|
2
|
-
from typing import Any, Callable, cast
|
|
2
|
+
from typing import Any, Callable, MutableMapping, cast
|
|
3
3
|
|
|
4
4
|
from fastapi import FastAPI
|
|
5
5
|
from fastapi import Request as FastAPIRequest
|
|
6
6
|
from fastapi.responses import JSONResponse
|
|
7
|
-
from starlette.types import ASGIApp,
|
|
7
|
+
from starlette.types import ASGIApp, Receive, Scope, Send
|
|
8
8
|
|
|
9
9
|
from . import DBOS
|
|
10
10
|
from ._context import (
|
|
@@ -61,15 +61,16 @@ class LifespanMiddleware:
|
|
|
61
61
|
|
|
62
62
|
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
|
63
63
|
if scope["type"] == "lifespan":
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if message["type"] == "lifespan.startup":
|
|
64
|
+
|
|
65
|
+
async def wrapped_send(message: MutableMapping[str, Any]) -> None:
|
|
66
|
+
if message["type"] == "lifespan.startup.complete":
|
|
67
67
|
self.dbos._launch()
|
|
68
|
-
|
|
69
|
-
elif message["type"] == "lifespan.shutdown":
|
|
68
|
+
elif message["type"] == "lifespan.shutdown.complete":
|
|
70
69
|
self.dbos._destroy()
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
await send(message)
|
|
71
|
+
|
|
72
|
+
# Call the original app with our wrapped functions
|
|
73
|
+
await self.app(scope, receive, wrapped_send)
|
|
73
74
|
else:
|
|
74
75
|
await self.app(scope, receive, send)
|
|
75
76
|
|
|
@@ -367,7 +367,7 @@ class SystemDatabase:
|
|
|
367
367
|
with self.engine.begin() as c:
|
|
368
368
|
stmt = (
|
|
369
369
|
sa.update(SystemSchema.workflow_status)
|
|
370
|
-
.where(SystemSchema.
|
|
370
|
+
.where(SystemSchema.workflow_status.c.workflow_uuid == workflow_uuid)
|
|
371
371
|
.values(
|
|
372
372
|
status=status,
|
|
373
373
|
)
|
|
@@ -98,7 +98,7 @@ def cleanup_test_databases(config: ConfigFile, postgres_db_engine: sa.Engine) ->
|
|
|
98
98
|
def dbos(
|
|
99
99
|
config: ConfigFile, cleanup_test_databases: None
|
|
100
100
|
) -> Generator[DBOS, Any, None]:
|
|
101
|
-
DBOS.destroy()
|
|
101
|
+
DBOS.destroy(destroy_registry=True)
|
|
102
102
|
|
|
103
103
|
# This launches for test convenience.
|
|
104
104
|
# Tests add to running DBOS and then call stuff without adding
|
|
@@ -109,38 +109,30 @@ def dbos(
|
|
|
109
109
|
DBOS.launch()
|
|
110
110
|
|
|
111
111
|
yield dbos
|
|
112
|
-
DBOS.destroy()
|
|
112
|
+
DBOS.destroy(destroy_registry=True)
|
|
113
113
|
|
|
114
114
|
|
|
115
115
|
@pytest.fixture()
|
|
116
116
|
def dbos_fastapi(
|
|
117
117
|
config: ConfigFile, cleanup_test_databases: None
|
|
118
118
|
) -> Generator[Tuple[DBOS, FastAPI], Any, None]:
|
|
119
|
-
DBOS.destroy()
|
|
119
|
+
DBOS.destroy(destroy_registry=True)
|
|
120
120
|
app = FastAPI()
|
|
121
|
-
|
|
122
|
-
# ignore the on_event deprecation warnings
|
|
123
|
-
with warnings.catch_warnings():
|
|
124
|
-
warnings.filterwarnings(
|
|
125
|
-
"ignore",
|
|
126
|
-
category=DeprecationWarning,
|
|
127
|
-
message=r"\s*on_event is deprecated, use lifespan event handlers instead\.",
|
|
128
|
-
)
|
|
129
|
-
dbos = DBOS(fastapi=app, config=config)
|
|
121
|
+
dbos = DBOS(fastapi=app, config=config)
|
|
130
122
|
|
|
131
123
|
# This is for test convenience.
|
|
132
124
|
# Usually fastapi itself does launch, but we are not completing the fastapi lifecycle
|
|
133
125
|
DBOS.launch()
|
|
134
126
|
|
|
135
127
|
yield dbos, app
|
|
136
|
-
DBOS.destroy()
|
|
128
|
+
DBOS.destroy(destroy_registry=True)
|
|
137
129
|
|
|
138
130
|
|
|
139
131
|
@pytest.fixture()
|
|
140
132
|
def dbos_flask(
|
|
141
133
|
config: ConfigFile, cleanup_test_databases: None
|
|
142
134
|
) -> Generator[Tuple[DBOS, Flask], Any, None]:
|
|
143
|
-
DBOS.destroy()
|
|
135
|
+
DBOS.destroy(destroy_registry=True)
|
|
144
136
|
app = Flask(__name__)
|
|
145
137
|
|
|
146
138
|
dbos = DBOS(flask=app, config=config)
|
|
@@ -150,7 +142,7 @@ def dbos_flask(
|
|
|
150
142
|
DBOS.launch()
|
|
151
143
|
|
|
152
144
|
yield dbos, app
|
|
153
|
-
DBOS.destroy()
|
|
145
|
+
DBOS.destroy(destroy_registry=True)
|
|
154
146
|
|
|
155
147
|
|
|
156
148
|
# Pretty-print test names
|
|
@@ -303,7 +303,7 @@ def test_async_tx_raises(config: ConfigFile) -> None:
|
|
|
303
303
|
pass
|
|
304
304
|
|
|
305
305
|
# destroy call needed to avoid "functions were registered but DBOS() was not called" warning
|
|
306
|
-
DBOS.destroy()
|
|
306
|
+
DBOS.destroy(destroy_registry=True)
|
|
307
307
|
|
|
308
308
|
|
|
309
309
|
@pytest.mark.asyncio
|
|
@@ -1212,3 +1212,19 @@ def test_debug_logging(dbos: DBOS, caplog: pytest.LogCaptureFixture) -> None:
|
|
|
1212
1212
|
|
|
1213
1213
|
# Reset logging
|
|
1214
1214
|
logging.getLogger("dbos").propagate = original_propagate
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
def test_destroy_semantics(dbos: DBOS, config: ConfigFile) -> None:
|
|
1218
|
+
|
|
1219
|
+
@DBOS.workflow()
|
|
1220
|
+
def test_workflow(var: str) -> str:
|
|
1221
|
+
return var
|
|
1222
|
+
|
|
1223
|
+
var = "test"
|
|
1224
|
+
assert test_workflow(var) == var
|
|
1225
|
+
|
|
1226
|
+
DBOS.destroy()
|
|
1227
|
+
DBOS(config=config)
|
|
1228
|
+
DBOS.launch()
|
|
1229
|
+
|
|
1230
|
+
assert test_workflow(var) == var
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import logging
|
|
2
3
|
import uuid
|
|
3
|
-
from
|
|
4
|
+
from contextlib import asynccontextmanager
|
|
5
|
+
from typing import Any, Tuple
|
|
4
6
|
|
|
7
|
+
import httpx
|
|
5
8
|
import pytest
|
|
6
9
|
import sqlalchemy as sa
|
|
10
|
+
import uvicorn
|
|
7
11
|
from fastapi import FastAPI
|
|
8
12
|
from fastapi.testclient import TestClient
|
|
9
13
|
|
|
10
14
|
# Public API
|
|
11
|
-
from dbos import DBOS
|
|
15
|
+
from dbos import DBOS, ConfigFile
|
|
12
16
|
|
|
13
17
|
# Private API because this is a unit test
|
|
14
18
|
from dbos._context import assert_current_dbos_context
|
|
@@ -157,3 +161,73 @@ def test_endpoint_recovery(dbos_fastapi: Tuple[DBOS, FastAPI]) -> None:
|
|
|
157
161
|
workflow_handles = DBOS.recover_pending_workflows()
|
|
158
162
|
assert len(workflow_handles) == 1
|
|
159
163
|
assert workflow_handles[0].get_result() == ("a", wfuuid)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@pytest.mark.asyncio
|
|
167
|
+
async def test_custom_lifespan(
|
|
168
|
+
config: ConfigFile, cleanup_test_databases: None
|
|
169
|
+
) -> None:
|
|
170
|
+
resource = None
|
|
171
|
+
port = 8000
|
|
172
|
+
|
|
173
|
+
@asynccontextmanager
|
|
174
|
+
async def lifespan(app: FastAPI) -> Any:
|
|
175
|
+
nonlocal resource
|
|
176
|
+
resource = 1
|
|
177
|
+
yield
|
|
178
|
+
resource = None
|
|
179
|
+
|
|
180
|
+
app = FastAPI(lifespan=lifespan)
|
|
181
|
+
|
|
182
|
+
DBOS.destroy()
|
|
183
|
+
DBOS(fastapi=app, config=config)
|
|
184
|
+
|
|
185
|
+
@app.get("/")
|
|
186
|
+
@DBOS.workflow()
|
|
187
|
+
async def resource_workflow() -> Any:
|
|
188
|
+
return {"resource": resource}
|
|
189
|
+
|
|
190
|
+
uvicorn_config = uvicorn.Config(
|
|
191
|
+
app=app, host="127.0.0.1", port=port, log_level="error"
|
|
192
|
+
)
|
|
193
|
+
server = uvicorn.Server(config=uvicorn_config)
|
|
194
|
+
|
|
195
|
+
# Run server in background task
|
|
196
|
+
server_task = asyncio.create_task(server.serve())
|
|
197
|
+
await asyncio.sleep(0.2) # Give server time to start
|
|
198
|
+
|
|
199
|
+
async with httpx.AsyncClient() as client:
|
|
200
|
+
r = await client.get(f"http://127.0.0.1:{port}")
|
|
201
|
+
assert r.json()["resource"] == 1
|
|
202
|
+
|
|
203
|
+
server.should_exit = True
|
|
204
|
+
await server_task
|
|
205
|
+
assert resource is None
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_stacked_decorators_wf(dbos_fastapi: Tuple[DBOS, FastAPI]) -> None:
|
|
209
|
+
dbos, app = dbos_fastapi
|
|
210
|
+
client = TestClient(app)
|
|
211
|
+
|
|
212
|
+
@app.get("/endpoint/{var1}/{var2}")
|
|
213
|
+
@DBOS.workflow()
|
|
214
|
+
async def test_endpoint(var1: str, var2: str) -> str:
|
|
215
|
+
return f"{var1}, {var2}!"
|
|
216
|
+
|
|
217
|
+
response = client.get("/endpoint/plums/deify")
|
|
218
|
+
assert response.status_code == 200
|
|
219
|
+
assert response.text == '"plums, deify!"'
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_stacked_decorators_step(dbos_fastapi: Tuple[DBOS, FastAPI]) -> None:
|
|
223
|
+
dbos, app = dbos_fastapi
|
|
224
|
+
client = TestClient(app)
|
|
225
|
+
|
|
226
|
+
@app.get("/endpoint/{var1}/{var2}")
|
|
227
|
+
@DBOS.step()
|
|
228
|
+
async def test_endpoint(var1: str, var2: str) -> str:
|
|
229
|
+
return f"{var1}, {var2}!"
|
|
230
|
+
|
|
231
|
+
response = client.get("/endpoint/plums/deify")
|
|
232
|
+
assert response.status_code == 200
|
|
233
|
+
assert response.text == '"plums, deify!"'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbos-0.20.0a3 → dbos-0.20.0a6}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|