| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #!/usr/bin/env python3
- """Seed Bambuddy with a quick visual set of filament effect spools.
- Usage:
- python scripts/fill_spool_effects.py --bambuddy-url http://localhost:8000
- python scripts/fill_spool_effects.py --bambuddy-url http://localhost:8000 --api-key YOUR_KEY
- This script creates stock spools for every effect type defined in the `SPOOLS` list below,
- using the bulk endpoint for creation:
- POST /api/v1/inventory/spools/bulk
- """
- from __future__ import annotations
- import argparse
- import sys
- from dataclasses import dataclass
- import requests
- API_PATH_BULK_CREATE = "/api/v1/inventory/spools/bulk"
- @dataclass(frozen=True)
- class TestSpool:
- "Class representing a spool definition and count for the test spool set"
- effect_type: str
- colors: dict[str, str]
- quantity: int = 1
- SPOOLS: list[TestSpool] = [
- TestSpool(
- effect_type="sparkle",
- colors={"dodger blue": "1E90FFFF"},
- quantity=2,
- ),
- TestSpool(
- effect_type="sparkle",
- colors={"dark red": "8B0000FF"},
- ),
- TestSpool(
- effect_type="wood",
- colors={"brown": "A47251FF"},
- ),
- TestSpool(
- effect_type="marble",
- colors={"slate": "4F5D75FF"},
- ),
- TestSpool(
- effect_type="glow",
- colors={"mint-pop": "6CD4BCFF"},
- ),
- TestSpool(
- effect_type="matte",
- colors={"charcoal": "2B2D42FF"},
- ),
- TestSpool(
- effect_type="silk",
- colors={"rose": "FF8FA3FF"},
- ),
- TestSpool(
- effect_type="galaxy",
- colors={"indigo": "4361EEFF"},
- ),
- TestSpool(
- effect_type="rainbow",
- colors={"amber": "FFBF69FF"},
- ),
- TestSpool(
- effect_type="metal",
- colors={"petrol-blue": "2D9CDBFF"},
- ),
- TestSpool(
- effect_type="translucent",
- colors={"cream": "FFF3E2AA"},
- ),
- TestSpool(
- effect_type="gradient",
- colors={
- "dark olive green": "556B2FFF",
- "goldenrod": "DAA520FF",
- },
- ),
- TestSpool(
- effect_type="dual-color",
- colors={
- "plum": "7B2CBFFF",
- "saffron": "F2C94CFF",
- },
- ),
- TestSpool(
- effect_type="tri-color",
- colors={
- "coral": "FF6B6BFF",
- "seafoam": "80ED99FF",
- "indigo": "4361EEFF",
- },
- ),
- TestSpool(
- effect_type="multicolor",
- colors={
- "sunset-orange": "EC984CFF",
- "mint-pop": "6CD4BCFF",
- "violet-bloom": "A66EB9FF",
- "raspberry-dawn": "D87694FF",
- },
- ),
- TestSpool(
- effect_type="multicolor",
- colors={
- "deep-navy": "1B1F3BFF",
- "cream": "FFF3E2FF",
- "rose": "FF8FA3FF",
- "teal": "2EC4B6FF",
- "amber": "FFBF69FF",
- },
- ),
- ]
- def build_spool_payload(variant: TestSpool) -> dict:
- "Function to build the payload for a single spool variant"
- color_values = list(variant.colors.values())
- color_names = list(variant.colors.keys())
- return {
- "material": "PLA",
- "subtype": variant.effect_type,
- "brand": "Generic",
- "color_name": ", ".join(color_names),
- "rgba": color_values[0],
- "extra_colors": ",".join(color_values),
- "effect_type": variant.effect_type,
- "label_weight": 1000,
- "core_weight": 250,
- "weight_used": 0,
- "core_weight_catalog_id": None,
- "slicer_filament": None,
- "slicer_filament_name": None,
- "nozzle_temp_min": None,
- "nozzle_temp_max": None,
- "note": "Dev effect overview seed",
- "cost_per_kg": None,
- "category": None,
- "low_stock_threshold_pct": None,
- }
- def create_bulk_spools(
- bambuddy_url: str,
- spool_data: dict,
- quantity: int,
- api_key: str | None,
- timeout: int,
- ) -> list[dict]:
- "Function that creates multiple spools using the bulk API endpoint and returns the list of created spools"
- url = f"{bambuddy_url.rstrip('/')}{API_PATH_BULK_CREATE}"
- headers: dict[str, str] = {}
- if api_key:
- headers["X-API-Key"] = api_key
- payload = {"spool": spool_data, "quantity": quantity}
- resp = requests.post(url, json=payload, headers=headers, timeout=timeout)
- resp.raise_for_status()
- data = resp.json()
- if not isinstance(data, list):
- raise ValueError("Bulk endpoint returned unexpected response format: expected a list of created spools")
- return data
- def main() -> None:
- parser = argparse.ArgumentParser(description="Create development stock spools for every effect type")
- parser.add_argument("--bambuddy-url", required=True, help="Bambuddy URL (e.g. http://localhost:8000)")
- parser.add_argument("--api-key", help="Bambuddy API key (required if auth is enabled)")
- parser.add_argument("--timeout", type=int, default=30, help="HTTP timeout in seconds (default: 30)")
- args = parser.parse_args()
- created = 0
- failed = 0
- for variant in SPOOLS:
- payload = build_spool_payload(variant)
- try:
- created_spools = create_bulk_spools(
- args.bambuddy_url,
- payload,
- quantity=variant.quantity,
- api_key=args.api_key,
- timeout=args.timeout,
- )
- ids = [str(item.get("id", "?")) for item in created_spools]
- print(f" Created effect={variant.effect_type:<11} qty={len(created_spools)} ids={','.join(ids)}")
- created += len(created_spools)
- except (requests.RequestException, ValueError) as exc:
- print(f" FAILED effect={variant.effect_type}: {exc}", file=sys.stderr)
- failed += variant.quantity
- print(f"\nDone: {created} created, {failed} failed")
- if __name__ == "__main__":
- main()
|