Closed
Description
What are you really trying to do?
I'm trying to run a workflow passing an object of a class that is derived from Pydantic's BaseModel
.
Describe the bug
When running the workflow, the following exception happens:
Object of type SignupCreate is not JSON serializable
More details:
" File \"C:\\Users\\alexa\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\master-control-fastapi-xNDFbqbb-py3.10\\lib\\site-packages\\temporalio\\converter.py\", line 177, in to_payloads\n payload = converter.to_payload(value)\n", " File \"C:\\Users\\alexa\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\master-control-fastapi-xNDFbqbb-py3.10\\lib\\site-packages\\temporalio\\converter.py\", line 425, in to_payload\n data=json.dumps(\n", " File \"C:\\Users\\alexa\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\__init__.py\", line 238, in dumps\n **kw).encode(obj)\n", " File \"C:\\Users\\alexa\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\encoder.py\", line 199, in encode\n chunks = self.iterencode(o, _one_shot=True)\n", " File \"C:\\Users\\alexa\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\encoder.py\", line 257, in iterencode\n return _iterencode(o, 0)\n", " File \"C:\\Users\\alexa\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\encoder.py\", line 179, in default\n raise TypeError(f'Object of type {o.__class__.__name__} '\n"
Minimal Reproduction
import asyncio
from datetime import timedelta
from pydantic import constr, BaseModel, EmailStr, Extra
from temporalio import activity, workflow
from temporalio.client import Client
from temporalio.worker import Worker
UsernameField = constr(min_length=3, max_length=20, strip_whitespace=True)
# While we could use multiple parameters in the activity, Temporal strongly
# encourages using a single dataclass instead which can have fields added to it
# in a backwards-compatible way.
class SignupCreate(BaseModel, extra=Extra.forbid):
username: UsernameField
email: EmailStr
# Basic activity that logs and does string concatenation
@activity.defn
async def create_signup(input: SignupCreate) -> str:
activity.logger.info("Running activity with parameter %s" % input)
return f"signup: {input}"
# Basic workflow that logs and invokes an activity
@workflow.defn
class SignupWorkflow:
@workflow.run
async def run(self, signup: SignupCreate) -> str:
workflow.logger.info("Running workflow with parameter %s" % signup)
return await workflow.execute_activity(
create_signup,
signup,
start_to_close_timeout=timedelta(seconds=10),
)
async def main():
# Uncomment the line below to see logging
# logging.basicConfig(level=logging.INFO)
# Start client
client = await Client.connect("localhost:7233")
# Run a worker for the workflow
async with Worker(
client,
task_queue="hello-activity-task-queue",
workflows=[SignupWorkflow],
activities=[create_signup],
):
# While the worker is running, use the client to run the workflow and
# print out its result. Note, in many production setups, the client
# would be in a completely separate process from the worker.
result = await client.execute_workflow(
SignupWorkflow.run,
SignupCreate(username="alex", email="me@gmail.com"),
id="hello-activity-workflow-id",
task_queue="hello-activity-task-queue",
)
print(f"Result: {result}")
if __name__ == "__main__":
asyncio.run(main())
Environment/Versions
- OS and processor: Windows 11, Intel I9
- Temporal Version: [e.g. 1.14.0?] and/or SDK version
- Python SDK version 0.1b1
- Are you using Docker or Kubernetes or building Temporal from source? Answer: I'm using Docker compose, images:
temporalio/ui:2.5.1
temporalio/auto-setup:1.17.5