(
files: list[UploadFile] = File(...), tmp: Optional[bool] = False
)
| 292 | |
| 293 | @app.post("/builder/save", response_model_exclude_none=True) |
| 294 | async def builder_build( |
| 295 | files: list[UploadFile] = File(...), tmp: Optional[bool] = False |
| 296 | ) -> bool: |
| 297 | try: |
| 298 | app_names: set[str] = set() |
| 299 | uploads: list[tuple[str, bytes]] = [] |
| 300 | for file in files: |
| 301 | app_name, rel_path = _parse_upload_filename(file.filename) |
| 302 | app_names.add(app_name) |
| 303 | content = await file.read() |
| 304 | uploads.append((rel_path, content)) |
| 305 | |
| 306 | if len(app_names) != 1: |
| 307 | logger.error( |
| 308 | "Exactly one app name is required, found: %s", |
| 309 | sorted(app_names), |
| 310 | ) |
| 311 | return False |
| 312 | |
| 313 | app_name = next(iter(app_names)) |
| 314 | |
| 315 | for rel_path, content in uploads: |
| 316 | _check_yaml_for_blocked_keys(content, f"{app_name}/{rel_path}") |
| 317 | |
| 318 | if tmp: |
| 319 | app_root = _get_app_root(app_name) |
| 320 | tmp_agent_root = _get_tmp_agent_root(app_root, app_name) |
| 321 | tmp_agent_root.mkdir(parents=True, exist_ok=True) |
| 322 | |
| 323 | for rel_path, content in uploads: |
| 324 | destination_path = _resolve_under_dir(tmp_agent_root, rel_path) |
| 325 | destination_path.parent.mkdir(parents=True, exist_ok=True) |
| 326 | destination_path.write_bytes(content) |
| 327 | |
| 328 | return True |
| 329 | |
| 330 | app_root = _get_app_root(app_name) |
| 331 | app_root.mkdir(parents=True, exist_ok=True) |
| 332 | |
| 333 | tmp_agent_root = _get_tmp_agent_root(app_root, app_name) |
| 334 | if tmp_agent_root.is_dir(): |
| 335 | copy_dir_contents(tmp_agent_root, app_root) |
| 336 | |
| 337 | for rel_path, content in uploads: |
| 338 | destination_path = _resolve_under_dir(app_root, rel_path) |
| 339 | destination_path.parent.mkdir(parents=True, exist_ok=True) |
| 340 | destination_path.write_bytes(content) |
| 341 | |
| 342 | return cleanup_tmp(app_name) |
| 343 | except ValueError as exc: |
| 344 | logger.exception("Error in builder_build: %s", exc) |
| 345 | raise HTTPException(status_code=400, detail=str(exc)) |
| 346 | except OSError as exc: |
| 347 | logger.exception("Error in builder_build: %s", exc) |
| 348 | return False |
| 349 | |
| 350 | @app.post("/builder/app/{app_name}/cancel", response_model_exclude_none=True) |
| 351 | async def builder_cancel(app_name: str) -> bool: |
nothing calls this directly
no test coverage detected