vet app
This commit is contained in:
365
openapi_first/templates/vet_app/routes.py
Normal file
365
openapi_first/templates/vet_app/routes.py
Normal file
@@ -0,0 +1,365 @@
|
||||
"""
|
||||
Veterinary Clinic route handlers bound via OpenAPI operationId.
|
||||
|
||||
Handlers explicitly control HTTP response status codes to ensure runtime
|
||||
behavior matches the OpenAPI contract. Domain models defined using
|
||||
Pydantic are used for request and response payloads.
|
||||
|
||||
No routing decorators, path definitions, or implicit framework behavior
|
||||
appear in this module. All routing, HTTP methods, and schemas are defined
|
||||
in the OpenAPI specification.
|
||||
"""
|
||||
|
||||
from fastapi import Response, HTTPException, UploadFile
|
||||
|
||||
from models import (
|
||||
ParentCreate,
|
||||
VetCreate,
|
||||
TreatmentCreate,
|
||||
PetCreate,
|
||||
AppointmentCreate,
|
||||
)
|
||||
from data import (
|
||||
list_parents as _list_parents,
|
||||
get_parent as _get_parent,
|
||||
create_parent as _create_parent,
|
||||
update_parent as _update_parent,
|
||||
delete_parent as _delete_parent,
|
||||
list_vets as _list_vets,
|
||||
get_vet as _get_vet,
|
||||
create_vet as _create_vet,
|
||||
update_vet as _update_vet,
|
||||
delete_vet as _delete_vet,
|
||||
list_treatments as _list_treatments,
|
||||
get_treatment as _get_treatment,
|
||||
create_treatment as _create_treatment,
|
||||
update_treatment as _update_treatment,
|
||||
delete_treatment as _delete_treatment,
|
||||
list_pets as _list_pets,
|
||||
get_pet as _get_pet,
|
||||
create_pet as _create_pet,
|
||||
update_pet as _update_pet,
|
||||
delete_pet as _delete_pet,
|
||||
list_appointments as _list_appointments,
|
||||
get_appointment as _get_appointment,
|
||||
create_appointment as _create_appointment,
|
||||
update_appointment as _update_appointment,
|
||||
delete_appointment as _delete_appointment,
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Parents
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_parents(limit: int = 20, offset: int = 0):
|
||||
"""List parents (paginated).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
limit : int
|
||||
Maximum number of records to return.
|
||||
offset : int
|
||||
Number of records to skip.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
Paginated response with ``total`` and ``items``.
|
||||
"""
|
||||
items = _list_parents()
|
||||
return {"total": len(items), "items": items[offset:offset + limit]}
|
||||
|
||||
|
||||
def create_parent(payload: ParentCreate, response: Response):
|
||||
"""Create a parent.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
payload : ParentCreate
|
||||
Parent data excluding the ``id`` field.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Parent
|
||||
The newly created parent.
|
||||
"""
|
||||
parent = _create_parent(payload)
|
||||
response.status_code = 201
|
||||
return parent
|
||||
|
||||
|
||||
def get_parent(id: int):
|
||||
"""Retrieve a single parent by ID.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
id : int
|
||||
Identifier of the parent.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Parent
|
||||
The requested parent.
|
||||
|
||||
Raises
|
||||
------
|
||||
HTTPException
|
||||
404 if the parent does not exist.
|
||||
"""
|
||||
try:
|
||||
return _get_parent(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Parent not found")
|
||||
|
||||
|
||||
def update_parent(id: int, payload: ParentCreate):
|
||||
"""Update an existing parent.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
id : int
|
||||
Identifier of the parent.
|
||||
payload : ParentCreate
|
||||
Updated parent data.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Parent
|
||||
The updated parent.
|
||||
|
||||
Raises
|
||||
------
|
||||
HTTPException
|
||||
404 if the parent does not exist.
|
||||
"""
|
||||
try:
|
||||
return _update_parent(id, payload)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Parent not found")
|
||||
|
||||
|
||||
def delete_parent(id: int, response: Response):
|
||||
"""Delete an existing parent.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
id : int
|
||||
Identifier of the parent.
|
||||
|
||||
Raises
|
||||
------
|
||||
HTTPException
|
||||
404 if the parent does not exist.
|
||||
"""
|
||||
try:
|
||||
_delete_parent(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Parent not found")
|
||||
response.status_code = 204
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Vets
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_vets(limit: int = 20, offset: int = 0):
|
||||
"""List vets (paginated)."""
|
||||
items = _list_vets()
|
||||
return {"total": len(items), "items": items[offset:offset + limit]}
|
||||
|
||||
|
||||
def create_vet(payload: VetCreate, response: Response):
|
||||
"""Create a vet."""
|
||||
vet = _create_vet(payload)
|
||||
response.status_code = 201
|
||||
return vet
|
||||
|
||||
|
||||
def get_vet(id: int):
|
||||
"""Retrieve a single vet by ID."""
|
||||
try:
|
||||
return _get_vet(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Vet not found")
|
||||
|
||||
|
||||
def update_vet(id: int, payload: VetCreate):
|
||||
"""Update an existing vet."""
|
||||
try:
|
||||
return _update_vet(id, payload)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Vet not found")
|
||||
|
||||
|
||||
def delete_vet(id: int, response: Response):
|
||||
"""Delete an existing vet."""
|
||||
try:
|
||||
_delete_vet(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Vet not found")
|
||||
response.status_code = 204
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Treatments
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_treatments():
|
||||
"""List treatments (catalogue).
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[Treatment]
|
||||
A list of treatment domain objects.
|
||||
"""
|
||||
return _list_treatments()
|
||||
|
||||
|
||||
def create_treatment(payload: TreatmentCreate, response: Response):
|
||||
"""Add a treatment (admin only)."""
|
||||
treatment = _create_treatment(payload)
|
||||
response.status_code = 201
|
||||
return treatment
|
||||
|
||||
|
||||
def get_treatment(id: int):
|
||||
"""Retrieve a single treatment by ID."""
|
||||
try:
|
||||
return _get_treatment(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Treatment not found")
|
||||
|
||||
|
||||
def update_treatment(id: int, payload: TreatmentCreate):
|
||||
"""Update an existing treatment."""
|
||||
try:
|
||||
return _update_treatment(id, payload)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Treatment not found")
|
||||
|
||||
|
||||
def delete_treatment(id: int, response: Response):
|
||||
"""Delete an existing treatment."""
|
||||
try:
|
||||
_delete_treatment(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Treatment not found")
|
||||
response.status_code = 204
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pets
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_pets(limit: int = 20, offset: int = 0):
|
||||
"""List pets (paginated)."""
|
||||
items = _list_pets()
|
||||
return {"total": len(items), "items": items[offset:offset + limit]}
|
||||
|
||||
|
||||
def create_pet(payload: PetCreate, response: Response):
|
||||
"""Create a pet."""
|
||||
pet = _create_pet(payload)
|
||||
response.status_code = 201
|
||||
return pet
|
||||
|
||||
|
||||
def get_pet(id: int):
|
||||
"""Retrieve a single pet by ID."""
|
||||
try:
|
||||
return _get_pet(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Pet not found")
|
||||
|
||||
|
||||
def update_pet(id: int, payload: PetCreate):
|
||||
"""Update an existing pet."""
|
||||
try:
|
||||
return _update_pet(id, payload)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Pet not found")
|
||||
|
||||
|
||||
def delete_pet(id: int, response: Response):
|
||||
"""Delete an existing pet."""
|
||||
try:
|
||||
_delete_pet(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Pet not found")
|
||||
response.status_code = 204
|
||||
|
||||
|
||||
def upload_pet_photo(id: int, file: UploadFile):
|
||||
"""Upload a pet photo.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
id : int
|
||||
Identifier of the pet.
|
||||
file : UploadFile
|
||||
Image file to upload.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
A confirmation with the pet ID.
|
||||
"""
|
||||
_ = file # In a real app, save to disk / object store
|
||||
return {"id": id, "status": "photo_uploaded"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Appointments
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def list_appointments(limit: int = 20, offset: int = 0, date: str = None, vet: int = None, pet: int = None):
|
||||
"""List appointments (paginated, filterable)."""
|
||||
items = _list_appointments()
|
||||
|
||||
# Basic in-memory filtering
|
||||
if date:
|
||||
items = [a for a in items if a.date.startswith(date)]
|
||||
if vet is not None:
|
||||
items = [a for a in items if a.vet_id == vet]
|
||||
if pet is not None:
|
||||
items = [a for a in items if a.pet_id == pet]
|
||||
|
||||
return {"total": len(items), "items": items[offset:offset + limit]}
|
||||
|
||||
|
||||
def create_appointment(payload: AppointmentCreate, response: Response):
|
||||
"""Create an appointment."""
|
||||
appointment = _create_appointment(payload)
|
||||
response.status_code = 201
|
||||
return appointment
|
||||
|
||||
|
||||
def get_appointment(id: int):
|
||||
"""Retrieve a single appointment by ID."""
|
||||
try:
|
||||
return _get_appointment(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Appointment not found")
|
||||
|
||||
|
||||
def update_appointment(id: int, payload: AppointmentCreate):
|
||||
"""Update an existing appointment."""
|
||||
try:
|
||||
return _update_appointment(id, payload)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Appointment not found")
|
||||
|
||||
|
||||
def delete_appointment(id: int, response: Response):
|
||||
"""Delete an existing appointment."""
|
||||
try:
|
||||
_delete_appointment(id)
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=404, detail="Appointment not found")
|
||||
response.status_code = 204
|
||||
Reference in New Issue
Block a user