filaments.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. from fastapi import APIRouter, Depends, HTTPException
  2. from sqlalchemy.ext.asyncio import AsyncSession
  3. from sqlalchemy import select
  4. from backend.app.core.database import get_db
  5. from backend.app.models.filament import Filament
  6. from backend.app.schemas.filament import (
  7. FilamentCreate,
  8. FilamentUpdate,
  9. FilamentResponse,
  10. FilamentCostCalculation,
  11. )
  12. router = APIRouter(prefix="/filaments", tags=["filaments"])
  13. @router.get("/", response_model=list[FilamentResponse])
  14. async def list_filaments(db: AsyncSession = Depends(get_db)):
  15. """List all filaments."""
  16. result = await db.execute(
  17. select(Filament).order_by(Filament.type, Filament.name)
  18. )
  19. return list(result.scalars().all())
  20. @router.post("/", response_model=FilamentResponse)
  21. async def create_filament(
  22. filament_data: FilamentCreate,
  23. db: AsyncSession = Depends(get_db),
  24. ):
  25. """Create a new filament entry."""
  26. filament = Filament(**filament_data.model_dump())
  27. db.add(filament)
  28. await db.commit()
  29. await db.refresh(filament)
  30. return filament
  31. @router.get("/{filament_id}", response_model=FilamentResponse)
  32. async def get_filament(filament_id: int, db: AsyncSession = Depends(get_db)):
  33. """Get a specific filament."""
  34. result = await db.execute(
  35. select(Filament).where(Filament.id == filament_id)
  36. )
  37. filament = result.scalar_one_or_none()
  38. if not filament:
  39. raise HTTPException(404, "Filament not found")
  40. return filament
  41. @router.patch("/{filament_id}", response_model=FilamentResponse)
  42. async def update_filament(
  43. filament_id: int,
  44. filament_data: FilamentUpdate,
  45. db: AsyncSession = Depends(get_db),
  46. ):
  47. """Update a filament."""
  48. result = await db.execute(
  49. select(Filament).where(Filament.id == filament_id)
  50. )
  51. filament = result.scalar_one_or_none()
  52. if not filament:
  53. raise HTTPException(404, "Filament not found")
  54. for field, value in filament_data.model_dump(exclude_unset=True).items():
  55. setattr(filament, field, value)
  56. await db.commit()
  57. await db.refresh(filament)
  58. return filament
  59. @router.delete("/{filament_id}")
  60. async def delete_filament(filament_id: int, db: AsyncSession = Depends(get_db)):
  61. """Delete a filament."""
  62. result = await db.execute(
  63. select(Filament).where(Filament.id == filament_id)
  64. )
  65. filament = result.scalar_one_or_none()
  66. if not filament:
  67. raise HTTPException(404, "Filament not found")
  68. await db.delete(filament)
  69. await db.commit()
  70. return {"status": "deleted"}
  71. @router.post("/calculate-cost", response_model=FilamentCostCalculation)
  72. async def calculate_cost(
  73. filament_id: int,
  74. weight_grams: float,
  75. db: AsyncSession = Depends(get_db),
  76. ):
  77. """Calculate the cost for a given weight of filament."""
  78. result = await db.execute(
  79. select(Filament).where(Filament.id == filament_id)
  80. )
  81. filament = result.scalar_one_or_none()
  82. if not filament:
  83. raise HTTPException(404, "Filament not found")
  84. cost = (weight_grams / 1000) * filament.cost_per_kg
  85. return FilamentCostCalculation(
  86. filament_id=filament.id,
  87. filament_name=filament.name,
  88. weight_grams=weight_grams,
  89. cost=round(cost, 2),
  90. currency=filament.currency,
  91. )
  92. @router.get("/by-type/{filament_type}", response_model=list[FilamentResponse])
  93. async def get_filaments_by_type(
  94. filament_type: str,
  95. db: AsyncSession = Depends(get_db),
  96. ):
  97. """Get all filaments of a specific type."""
  98. result = await db.execute(
  99. select(Filament)
  100. .where(Filament.type.ilike(f"%{filament_type}%"))
  101. .order_by(Filament.name)
  102. )
  103. return list(result.scalars().all())
  104. @router.post("/seed-defaults")
  105. async def seed_default_filaments(db: AsyncSession = Depends(get_db)):
  106. """Seed the database with common filament types."""
  107. defaults = [
  108. {"name": "Generic PLA", "type": "PLA", "cost_per_kg": 20.0, "print_temp_min": 190, "print_temp_max": 220, "bed_temp_min": 50, "bed_temp_max": 60, "density": 1.24},
  109. {"name": "Generic PETG", "type": "PETG", "cost_per_kg": 25.0, "print_temp_min": 230, "print_temp_max": 250, "bed_temp_min": 70, "bed_temp_max": 80, "density": 1.27},
  110. {"name": "Generic ABS", "type": "ABS", "cost_per_kg": 22.0, "print_temp_min": 230, "print_temp_max": 260, "bed_temp_min": 90, "bed_temp_max": 110, "density": 1.04},
  111. {"name": "Generic TPU", "type": "TPU", "cost_per_kg": 35.0, "print_temp_min": 220, "print_temp_max": 250, "bed_temp_min": 40, "bed_temp_max": 60, "density": 1.21},
  112. {"name": "Generic ASA", "type": "ASA", "cost_per_kg": 28.0, "print_temp_min": 240, "print_temp_max": 260, "bed_temp_min": 90, "bed_temp_max": 110, "density": 1.07},
  113. {"name": "Bambu PLA Basic", "type": "PLA", "brand": "Bambu Lab", "cost_per_kg": 20.0, "print_temp_min": 190, "print_temp_max": 220, "bed_temp_min": 35, "bed_temp_max": 55, "density": 1.24},
  114. {"name": "Bambu PLA Matte", "type": "PLA", "brand": "Bambu Lab", "cost_per_kg": 25.0, "print_temp_min": 190, "print_temp_max": 220, "bed_temp_min": 35, "bed_temp_max": 55, "density": 1.24},
  115. {"name": "Bambu PETG Basic", "type": "PETG", "brand": "Bambu Lab", "cost_per_kg": 25.0, "print_temp_min": 250, "print_temp_max": 270, "bed_temp_min": 70, "bed_temp_max": 80, "density": 1.27},
  116. {"name": "Bambu ABS", "type": "ABS", "brand": "Bambu Lab", "cost_per_kg": 30.0, "print_temp_min": 260, "print_temp_max": 280, "bed_temp_min": 90, "bed_temp_max": 100, "density": 1.04},
  117. ]
  118. created = 0
  119. for filament_data in defaults:
  120. # Check if already exists
  121. result = await db.execute(
  122. select(Filament).where(
  123. Filament.name == filament_data["name"],
  124. Filament.type == filament_data["type"],
  125. )
  126. )
  127. if result.scalar_one_or_none():
  128. continue
  129. filament = Filament(**filament_data)
  130. db.add(filament)
  131. created += 1
  132. await db.commit()
  133. return {"created": created, "message": f"Created {created} default filaments"}