86 lines
3.1 KiB
Python
86 lines
3.1 KiB
Python
# Copyright (c) Microsoft. All rights reserved.
|
|
|
|
import logging
|
|
from contextlib import asynccontextmanager
|
|
|
|
import uvicorn
|
|
from dapr.ext.fastapi import DaprActor
|
|
from fastapi import FastAPI
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from samples.demos.process_with_dapr.process.process import get_process
|
|
from samples.demos.process_with_dapr.process.steps import CommonEvents, CStepState
|
|
from semantic_kernel import Kernel
|
|
from semantic_kernel.processes.dapr_runtime import register_fastapi_dapr_actors, start
|
|
from semantic_kernel.processes.dapr_runtime.dapr_kernel_process_context import DaprKernelProcessContext
|
|
from semantic_kernel.processes.kernel_process.kernel_process_step_state import KernelProcessStepState
|
|
|
|
logging.basicConfig(level=logging.WARNING)
|
|
|
|
|
|
# Define the kernel that is used throughout the process
|
|
kernel = Kernel()
|
|
|
|
"""
|
|
The following Process and Dapr runtime sample uses a FastAPI app
|
|
to start a process and run steps. The process is defined in the
|
|
process/process.py file and the steps are defined in the steps.py
|
|
file. The process is started by calling the /processes/{process_id}
|
|
endpoint. The actors are registered with the Dapr runtime using
|
|
the DaprActor class. The ProcessActor and the StepActor require a
|
|
kernel dependency to be injected during creation. This is done by
|
|
defining a factory function that takes the kernel as a parameter
|
|
and returns the actor instance with the kernel injected.
|
|
"""
|
|
|
|
# Get the process which means we have the `KernelProcess` object
|
|
# along with any defined step factories
|
|
process = get_process()
|
|
|
|
|
|
# Define a lifespan method that registers the actors with the Dapr runtime
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
print("## actor startup ##")
|
|
await register_fastapi_dapr_actors(actor, kernel, process.factories)
|
|
yield
|
|
|
|
|
|
# Define the FastAPI app along with the DaprActor
|
|
app = FastAPI(title="SKProcess", lifespan=lifespan)
|
|
actor = DaprActor(app)
|
|
|
|
|
|
@app.get("/healthz")
|
|
async def healthcheck():
|
|
return "Healthy!"
|
|
|
|
|
|
@app.get("/processes/{process_id}")
|
|
async def start_process(process_id: str):
|
|
try:
|
|
context: DaprKernelProcessContext = await start(
|
|
process=process,
|
|
kernel=kernel,
|
|
initial_event=CommonEvents.StartProcess,
|
|
process_id=process_id,
|
|
)
|
|
kernel_process = await context.get_state()
|
|
|
|
# If desired, uncomment the following lines to see the process state
|
|
# final_state = kernel_process.to_process_state_metadata()
|
|
# print(final_state.model_dump(exclude_none=True, by_alias=True, mode="json"))
|
|
|
|
c_step_state: KernelProcessStepState[CStepState] = next(
|
|
(s.state for s in kernel_process.steps if s.state.name == "CStep"), None
|
|
)
|
|
c_step_state_validated = CStepState.model_validate(c_step_state.state)
|
|
print(f"[FINAL STEP STATE]: CStepState current cycle: {c_step_state_validated.current_cycle}")
|
|
return JSONResponse(content={"processId": process_id}, status_code=200)
|
|
except Exception:
|
|
return JSONResponse(content={"error": "Error starting process"}, status_code=500)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
uvicorn.run(app, host="0.0.0.0", port=5001, log_level="error") # nosec
|