print_log.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. from datetime import datetime
  2. from pydantic import BaseModel, ConfigDict
  3. from backend.app.schemas.not_null import IgnoresNullForRequiredColumns
  4. class PrintLogEntrySchema(BaseModel):
  5. # from_attributes lets the routes build this straight off the ORM row.
  6. # The GET serialiser used to name every field by hand, and each field it
  7. # forgot came back as its default — a silent null rather than an error.
  8. # That cost the log its failure_reason (#1687 part 4) and then its cost /
  9. # energy_kwh / energy_cost (#2636). Validating from the row removes the
  10. # chance to forget one.
  11. model_config = ConfigDict(from_attributes=True)
  12. id: int
  13. archive_id: int | None = None
  14. print_name: str | None = None
  15. plate_id: int | None = None
  16. printer_name: str | None = None
  17. printer_id: int | None = None
  18. status: str
  19. started_at: datetime | None = None
  20. completed_at: datetime | None = None
  21. duration_seconds: int | None = None
  22. filament_type: str | None = None
  23. filament_color: str | None = None
  24. filament_used_grams: float | None = None
  25. cost: float | None = None
  26. energy_kwh: float | None = None
  27. energy_cost: float | None = None
  28. wear_cost: float | None = None # #694
  29. failure_reason: str | None = None
  30. user_verdict: str | None = None # Post-print quality verdict (#1898)
  31. user_verdict_source: str | None = None
  32. confirm_requested: bool | None = None
  33. duration_unmeasured: bool | None = None
  34. quantity: int | None = None
  35. # This print's own (archive redesign): its note, its finish photos (served
  36. # by the archive's photo route) and its video (the run's timelapse route).
  37. notes: str | None = None
  38. photos: list[str] | None = None
  39. timelapse_path: str | None = None
  40. # The slicer's estimate for the plate it printed (#3375); only in an
  41. # archive's runs list (GET /archives/{id}/runs).
  42. estimate_seconds: int | None = None
  43. estimate_grams: float | None = None
  44. thumbnail_path: str | None = None
  45. created_by_id: int | None = None
  46. created_by_username: str | None = None
  47. created_at: datetime
  48. class PrintLogResponse(BaseModel):
  49. items: list[PrintLogEntrySchema]
  50. total: int
  51. # The print log only: archives of these prints that were deleted, whose
  52. # prints stay logged (#1343) but have no archive page to open.
  53. deleted_archive_ids: list[int] = []
  54. class PrintLogEntryUpdate(IgnoresNullForRequiredColumns):
  55. """Per-row classification edits (#1687 part 4 — IndividualGhost1905).
  56. Lets the user set ``failure_reason`` (and re-classify ``status``) directly
  57. on a Print Log row, including on orphan entries that have no archive to
  58. edit through. The Failure Analysis widget already groups by
  59. ``PrintLogEntry.failure_reason``, so this just plugs the editor gap.
  60. """
  61. __orm_table__ = "print_log_entries"
  62. failure_reason: str | None = None
  63. status: str | None = None
  64. # The print's own note, beside the archive's (the file's) note.
  65. notes: str | None = None