v1_machine.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. __package__ = 'archivebox.api'
  2. from uuid import UUID
  3. from typing import List, Optional
  4. from datetime import datetime
  5. from ninja import Router, Schema, FilterSchema, Field, Query
  6. from ninja.pagination import paginate
  7. from archivebox.api.v1_core import CustomPagination
  8. router = Router(tags=['Machine and Dependencies'])
  9. # ============================================================================
  10. # Machine Schemas
  11. # ============================================================================
  12. class MachineSchema(Schema):
  13. """Schema for Machine model."""
  14. TYPE: str = 'machine.Machine'
  15. id: UUID
  16. created_at: datetime
  17. modified_at: datetime
  18. guid: str
  19. hostname: str
  20. hw_in_docker: bool
  21. hw_in_vm: bool
  22. hw_manufacturer: str
  23. hw_product: str
  24. hw_uuid: str
  25. os_arch: str
  26. os_family: str
  27. os_platform: str
  28. os_release: str
  29. os_kernel: str
  30. stats: dict
  31. num_uses_succeeded: int
  32. num_uses_failed: int
  33. class MachineFilterSchema(FilterSchema):
  34. id: Optional[str] = Field(None, q='id__startswith')
  35. hostname: Optional[str] = Field(None, q='hostname__icontains')
  36. os_platform: Optional[str] = Field(None, q='os_platform__icontains')
  37. os_arch: Optional[str] = Field(None, q='os_arch')
  38. hw_in_docker: Optional[bool] = Field(None, q='hw_in_docker')
  39. hw_in_vm: Optional[bool] = Field(None, q='hw_in_vm')
  40. # ============================================================================
  41. bin_providers: Optional[str] = Field(None, q='bin_providers__icontains')
  42. # ============================================================================
  43. # Binary Schemas
  44. # ============================================================================
  45. class BinarySchema(Schema):
  46. """Schema for Binary model."""
  47. TYPE: str = 'machine.Binary'
  48. id: UUID
  49. created_at: datetime
  50. modified_at: datetime
  51. machine_id: UUID
  52. machine_hostname: str
  53. name: str
  54. binproviders: str
  55. binprovider: str
  56. abspath: str
  57. version: str
  58. sha256: str
  59. status: str
  60. is_valid: bool
  61. num_uses_succeeded: int
  62. num_uses_failed: int
  63. @staticmethod
  64. def resolve_machine_hostname(obj) -> str:
  65. return obj.machine.hostname
  66. @staticmethod
  67. def resolve_is_valid(obj) -> bool:
  68. return obj.is_valid
  69. class BinaryFilterSchema(FilterSchema):
  70. id: Optional[str] = Field(None, q='id__startswith')
  71. name: Optional[str] = Field(None, q='name__icontains')
  72. binprovider: Optional[str] = Field(None, q='binprovider')
  73. status: Optional[str] = Field(None, q='status')
  74. machine_id: Optional[str] = Field(None, q='machine_id__startswith')
  75. version: Optional[str] = Field(None, q='version__icontains')
  76. # ============================================================================
  77. # Machine Endpoints
  78. # ============================================================================
  79. @router.get("/machines", response=List[MachineSchema], url_name="get_machines")
  80. @paginate(CustomPagination)
  81. def get_machines(request, filters: MachineFilterSchema = Query(...)):
  82. """List all machines."""
  83. from archivebox.machine.models import Machine
  84. return filters.filter(Machine.objects.all()).distinct()
  85. @router.get("/machine/{machine_id}", response=MachineSchema, url_name="get_machine")
  86. def get_machine(request, machine_id: str):
  87. """Get a specific machine by ID."""
  88. from archivebox.machine.models import Machine
  89. from django.db.models import Q
  90. return Machine.objects.get(Q(id__startswith=machine_id) | Q(hostname__iexact=machine_id))
  91. @router.get("/machine/current", response=MachineSchema, url_name="get_current_machine")
  92. def get_current_machine(request):
  93. """Get the current machine."""
  94. from archivebox.machine.models import Machine
  95. return Machine.current()
  96. # ============================================================================
  97. # ============================================================================
  98. # Binary Endpoints
  99. # ============================================================================
  100. @router.get("/binaries", response=List[BinarySchema], url_name="get_binaries")
  101. @paginate(CustomPagination)
  102. def get_binaries(request, filters: BinaryFilterSchema = Query(...)):
  103. """List all binaries."""
  104. from archivebox.machine.models import Binary
  105. return filters.filter(Binary.objects.all().select_related('machine', 'dependency')).distinct()
  106. @router.get("/binary/{binary_id}", response=BinarySchema, url_name="get_binary")
  107. def get_binary(request, binary_id: str):
  108. """Get a specific binary by ID."""
  109. from archivebox.machine.models import Binary
  110. return Binary.objects.select_related('machine', 'dependency').get(id__startswith=binary_id)
  111. @router.get("/binary/by-name/{name}", response=List[BinarySchema], url_name="get_binaries_by_name")
  112. def get_binaries_by_name(request, name: str):
  113. """Get all binaries with the given name."""
  114. from archivebox.machine.models import Binary
  115. return list(Binary.objects.filter(name__iexact=name).select_related('machine', 'dependency'))