LLMOpsThe LLMOps lifecycle · MLflow 3 · FastAPI · Docker · AWS/Azure
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
50 small wins to finish your path

The backend, and a real audit run

The project ends at a FastAPI backend. A request carries a video URL, the endpoint runs the compiled compliance graph, and the response is a session ID, the video ID and a pass-or-fail status with the violations found. One real run in the video took 146 seconds and came back failed.

Last updated: 15 Oct, 2026 · LLMOps

Observing the project wired the monitoring. This lesson is the surface everything sits behind: the API that takes a URL and returns a verdict, and what one real audit looks like end to end.

The FastAPI backend · from the End to End Multimodal LLMOps Project video · 4:54:00 to 4:57:00

The endpoint

python
from fastapi import FastAPI
from pydantic import BaseModel
import uuid
from graph.workflow import app as compliance_graph   # aliased, so it does not clash with the FastAPI app

app = FastAPI(title="Brand Guardian AI API")

class AuditRequest(BaseModel):
    video_url: str

@app.post("/audit")
def audit(req: AuditRequest):
    session_id = str(uuid.uuid4())           # one id per audit, for the trace
    final = compliance_graph.invoke({"video_url": req.video_url})
    return {
        "session_id": session_id,
        "video_id": final.get("video_id"),
        "status": final["status"],
        "violations": final["compliance_results"],
    }

The endpoint validates the body into an AuditRequest, mints a session ID so one audit can be found in the traces, invokes the compiled graph, and returns the verdict. The graph is imported aliased as compliance_graph so it does not clash with the FastAPI app, a detail the video calls out.

One real run

json
{
  "session_id": "7f3a...",
  "video_id": "a1b2c3",
  "status": "fail",
  "violations": [
    {
      "category": "FTC disclosure",
      "severity": "critical",
      "description": "The paid partnership is not disclosed in the first frames or the caption."
    }
  ]
}

The run the video shows comes back failed, with a missing-disclosure violation, after 146 seconds. That latency is the whole round trip: upload the URL, download the video, index it, retrieve the rules, judge, and return, which is why indexing is where the time goes and why the result is worth tracing.

One audit's request lifecycle, left to right: a POST /audit with a video URL, validated into an AuditRequest, a session id minted for the trace, the compiled compliance_graph running index then audit, and a JSON verdict of status plus violations. A red dashed box records the run in the video: a fail status with a missing-disclosure violation in 146 seconds, most of it the index node downloading and indexing the video.
Watch out. A 146-second request will time out a naive HTTP client and a load balancer with default settings. A long-running audit like this is usually better as a job the client polls, not a request it waits on, which is the durable-work case from the deployment part.
Try it yourself
  • Redesign the endpoint so a 146-second audit is a job the client polls, not a request it blocks on.
  • Explain what the session ID buys you when a user reports a wrong verdict an hour later.

This is what real progress feels like.