DVPPython Studio
Module 10: Expose a useful service / Build 1 of 4

Expose a strict evaluation endpoint

Turn supplied metadata into a documented local API response without pretending to analyze video.

Runs on your computer · 60–90 minutes · no paid services

Download practice filesFiles, commands & notes

Without JavaScript, use the step links and keep your files on your computer.

One useful idea

An HTTP endpoint gives a function a public contract inside a running application: method, path, input schema, actor and response. POST /evaluations creates a new classroom evaluation; GET /evaluations/{id} reads its stored creation snapshot. JSON is the transport representation, not a Python object or a promise that the supplied measurements are true.

FastAPI registers a function with a decorator. The supplied app.py uses @app.post("/evaluations", response_model=Evaluation, status_code=201). The annotated body is parsed as EvaluationCreate; the dependency supplies a configured Actor. The endpoint generates uuid4().hex, calls your build_evaluation, validates the result, writes it and returns it with Location. You own the transformation, not the provided routing/database scaffolding in this build. Open the actual route source and follow those steps.

Pydantic BaseModel provides runtime parsing/validation; annotations alone do not. The reviewed Model has strict=True, frozen=True, extra="forbid" and revalidate_instances="always". Width/height are integers 1..16384; frames 1..1,000,000; fps is the classroom integer set 24/25/30. Booleans, numeric strings and forged author fields fail, rather than being silently coerced. Field bounds and the fps validator declare that policy. model_validate checks incoming values, model_dump produces Python fields and model_dump_json serializes the model. Frozen assignment prevents ordinary mutation, not all malicious construction; revalidate boundary inputs and outputs.

Return the supplied asset ID, dimensions, frames and rate unchanged. Attach exactly the resolution-at-least-1080p and duration-at-most-60s checks, in that order: width >= 1920 AND height >= 1080; frames <= 60 * fps. These are disclosed comparisons of supplied metadata, not measurements, creative-quality judgments or a winner. Only a configured author may create the evaluation. Its review_status_at_creation is unreviewed; later findings have their own current state. A creation snapshot must not imply that later review never happened.

The worked example uses the real app/SQLite reference through TestClient in-process; it does not start a TCP server. Predict the status and two checks, then run it in the kit environment. Generated IDs are observed by shape/parity rather than copied into a fixed expected answer. For actual server requests, use the setup guide and a second terminal. Keep fixture credentials separate from your DVP tutor login.

Refresh first: Validated value objects and classes, HTTP requests and status boundaries, What an API test actually observes.

Trace a finished example

from pathlib import Path
from tempfile import TemporaryDirectory
import re

from fastapi.testclient import TestClient
from evaluation_service.app import create_app, FIXTURE_CREDENTIALS
from evaluation_service.storage import Repository

payload = {"asset_id": "Fresh_detail", "width": 1919, "height": 1080,
           "frames": 1801, "fps": 30}
headers = {"Authorization": "Bearer fixture-author-a"}
with TemporaryDirectory(prefix="dvp-owned-endpoint-") as folder:
    store = Repository(Path(folder) / "example.db")
    store.initialize(new=True)
    with TestClient(create_app(store, credentials=FIXTURE_CREDENTIALS)) as client:
        response = client.post("/evaluations", json=payload, headers=headers)
        body = response.json()
        print(response.status_code, body["created_by"], body["review_status_at_creation"])
        print([check["met"] for check in body["machine_checks"]])
        location = response.headers["location"]
        read_back = client.get(location, headers=headers).json()
        print(bool(re.fullmatch("[a-f0-9]{32}", body["id"])), read_back == body)

Expected output

201 author_A unreviewed
[False, False]
True True

The request uses changed fixture metadata: width 1919 fails the resolution rule and 1801 frames at 30 fps exceeds 60 seconds. The route creates a fresh ID, writes the typed reference result and returns actual 201/Location. A subsequent GET reads equal persisted values. Only this example’s owned temporary database is cleaned.

The finished implementation is in evaluation_service/core.py. Reading it is guided practice, not independent evidence.

Predict a boundary

At width 1920, height 1080, frames 1500 and fps 25, which machine checks are met?

Compare your answer · self-reviewed

Both are True: each dimension reaches its threshold and 1500 equals 60 × 25. At frame 1501 the duration condition is False; do not round it back into a pass.

Find the forged identity

Can a body author_id change which actor created the evaluation?

Compare your answer · self-reviewed

No. Unknown request fields are refused and the actor comes from the configured credential dependency. These public classroom credentials still do not authenticate a real person.

Recall the response

Does 201 with review_status_at_creation=unreviewed mean the video was analyzed or no finding can ever be approved?

Compare your answer · self-reviewed

Neither. It reports a created metadata record and its creation state. Read a finding/audit for later state; no video analysis or real-review certification was performed.

Change it, then build your own

One controlled change

Change only frames to 1800, then width to 1920. Predict each two-check list before running. Next send width=True and a forged author_id; expect schema refusal, not a coerced success.

Your independent task

Implement build_evaluation in practice.py. Revalidate EvaluationCreate and Actor with the reviewed models, require author role, preserve supplied values and create a fresh Evaluation with the provided evaluation_id/server actor ID and two MachineCheck values. Do not import/call the completed transformation. Run Build 1 practice tests and its actual selected demo; routing/repository remain disclosed reference assistance for this build.

What success looks like

Changed metadata and exact threshold cases produce the correct typed values without mutating input. Reviewer creation and malformed schema are refused. Actual API tests observe 201/Location/generated ID/read-back and documented strict schemas. A reference response is setup evidence, not your own completed service.

Hint 1 · a question

List the five supplied metadata fields and the two derived comparisons. Which values must remain unchanged?

Hint 2 · a concept cue

Validate before building. Require author role, and supply id/created_by from the declared function inputs. The endpoint, not this function, generates the ID.

Hint 3 · a localized example

Construct MachineCheck objects for width >= 1920 and height >= 1080, then frames <= 60 * fps. Use model_dump only after validating the request.

Need the complete worked solution?

Open evaluation_service/core.py from the kit. Trace it, close it, then try fresh inputs in your own files. Treat the attempt as guided; seeing the solution does not award a practical pass.

Course help is guidance, not independent evidence. With JavaScript, opening help records guidance locally; otherwise note it in your README. Reset does not erase that history.

Repair a failed check

If changed values remain Museum_detail, remove canned fields. If True or numeric strings pass, inspect strict model validation instead of relying on equality/type hints. If a forged actor is trusted, use the configured actor, never body identity. If the page cannot import FastAPI, use the separate Module 10 interpreter and installation rather than changing earlier kits.

NotImplementedError means a practice stub is still unfinished. Read the failing test name and the last error line. Change one behavior, rerun that build, then rerun all implemented builds.

Show it works on new inputs

Use a fresh invented asset ID, both sides of each dimension threshold and frame counts 1499/1500/1501 at 25 fps. Retain actual practice test output, one 201/Location/read-back and one strict refusal. Explain why supplied metadata checks are not video analysis, creative quality or authenticated review.

Self-review: name the input, result, refused case and reason. Your local test output and explanation are separate from a quiz score; this page does not certify a pass.

Keep the idea

An endpoint is a contract around a transformation. Preserve supplied facts, derive only declared checks, and keep creation status separate from later authored findings.