Spaces:
Paused
Paused
Update admin_routes.py
Browse files- admin_routes.py +31 -26
admin_routes.py
CHANGED
|
@@ -16,6 +16,11 @@ from pydantic import BaseModel, Field
|
|
| 16 |
import httpx
|
| 17 |
|
| 18 |
from config_provider import ConfigProvider
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
# ===================== Constants & Config =====================
|
| 21 |
security = HTTPBearer()
|
|
@@ -148,7 +153,7 @@ async def login(request: LoginRequest):
|
|
| 148 |
# Create token
|
| 149 |
token = create_token(request.username)
|
| 150 |
|
| 151 |
-
|
| 152 |
return LoginResponse(token=token, username=request.username)
|
| 153 |
|
| 154 |
@router.post("/change-password")
|
|
@@ -179,7 +184,7 @@ async def change_password(
|
|
| 179 |
# Save configuration
|
| 180 |
cfg.save()
|
| 181 |
|
| 182 |
-
|
| 183 |
return {"success": True}
|
| 184 |
|
| 185 |
# ===================== Locales Endpoints =====================
|
|
@@ -340,7 +345,7 @@ async def update_environment(
|
|
| 340 |
username: str = Depends(verify_token)
|
| 341 |
):
|
| 342 |
"""Update environment configuration with provider validation"""
|
| 343 |
-
|
| 344 |
|
| 345 |
cfg = ConfigProvider.get()
|
| 346 |
|
|
@@ -374,7 +379,7 @@ async def update_environment(
|
|
| 374 |
# Update via ConfigProvider
|
| 375 |
ConfigProvider.update_environment(update.model_dump(), username)
|
| 376 |
|
| 377 |
-
|
| 378 |
return {"success": True}
|
| 379 |
|
| 380 |
# ===================== Project Endpoints =====================
|
|
@@ -439,7 +444,7 @@ async def create_project(
|
|
| 439 |
# Create project via ConfigProvider
|
| 440 |
new_project = ConfigProvider.create_project(project.model_dump(), username)
|
| 441 |
|
| 442 |
-
|
| 443 |
return new_project.model_dump()
|
| 444 |
|
| 445 |
@router.put("/projects/{project_id}")
|
|
@@ -464,7 +469,7 @@ async def update_project(
|
|
| 464 |
# Update via ConfigProvider
|
| 465 |
updated_project = ConfigProvider.update_project(project_id, update.model_dump(), username)
|
| 466 |
|
| 467 |
-
|
| 468 |
return updated_project.model_dump()
|
| 469 |
|
| 470 |
@router.delete("/projects/{project_id}")
|
|
@@ -472,7 +477,7 @@ async def delete_project(project_id: int, username: str = Depends(verify_token))
|
|
| 472 |
"""Delete project (soft delete)"""
|
| 473 |
ConfigProvider.delete_project(project_id, username)
|
| 474 |
|
| 475 |
-
|
| 476 |
return {"success": True}
|
| 477 |
|
| 478 |
@router.patch("/projects/{project_id}/toggle")
|
|
@@ -480,7 +485,7 @@ async def toggle_project(project_id: int, username: str = Depends(verify_token))
|
|
| 480 |
"""Toggle project enabled status"""
|
| 481 |
enabled = ConfigProvider.toggle_project(project_id, username)
|
| 482 |
|
| 483 |
-
|
| 484 |
return {"enabled": enabled}
|
| 485 |
|
| 486 |
# ===================== Version Endpoints =====================
|
|
@@ -512,7 +517,7 @@ async def create_version(
|
|
| 512 |
"""Create new version"""
|
| 513 |
new_version = ConfigProvider.create_version(project_id, version_data.model_dump(), username)
|
| 514 |
|
| 515 |
-
|
| 516 |
return new_version.model_dump()
|
| 517 |
|
| 518 |
@router.put("/projects/{project_id}/versions/{version_id}")
|
|
@@ -525,7 +530,7 @@ async def update_version(
|
|
| 525 |
"""Update version"""
|
| 526 |
updated_version = ConfigProvider.update_version(project_id, version_id, update.model_dump(), username)
|
| 527 |
|
| 528 |
-
|
| 529 |
return updated_version.model_dump()
|
| 530 |
|
| 531 |
@router.post("/projects/{project_id}/versions/{version_id}/publish")
|
|
@@ -537,7 +542,7 @@ async def publish_version(
|
|
| 537 |
"""Publish version"""
|
| 538 |
project, version = ConfigProvider.publish_version(project_id, version_id, username)
|
| 539 |
|
| 540 |
-
|
| 541 |
|
| 542 |
# Notify LLM provider if project is enabled and provider requires repo info
|
| 543 |
cfg = ConfigProvider.get()
|
|
@@ -547,7 +552,7 @@ async def publish_version(
|
|
| 547 |
try:
|
| 548 |
await notify_llm_startup(project, version)
|
| 549 |
except Exception as e:
|
| 550 |
-
|
| 551 |
# Don't fail the publish
|
| 552 |
|
| 553 |
return {"success": True}
|
|
@@ -561,7 +566,7 @@ async def delete_version(
|
|
| 561 |
"""Delete version (soft delete)"""
|
| 562 |
ConfigProvider.delete_version(project_id, version_id, username)
|
| 563 |
|
| 564 |
-
|
| 565 |
return {"success": True}
|
| 566 |
|
| 567 |
@router.get("/projects/{project_name}/versions")
|
|
@@ -618,7 +623,7 @@ async def create_api(api: APICreate, username: str = Depends(verify_token)):
|
|
| 618 |
"""Create new API"""
|
| 619 |
new_api = ConfigProvider.create_api(api.model_dump(), username)
|
| 620 |
|
| 621 |
-
|
| 622 |
return new_api.model_dump()
|
| 623 |
|
| 624 |
@router.put("/apis/{api_name}")
|
|
@@ -630,7 +635,7 @@ async def update_api(
|
|
| 630 |
"""Update API"""
|
| 631 |
updated_api = ConfigProvider.update_api(api_name, update.model_dump(), username)
|
| 632 |
|
| 633 |
-
|
| 634 |
return updated_api.model_dump()
|
| 635 |
|
| 636 |
@router.delete("/apis/{api_name}")
|
|
@@ -638,7 +643,7 @@ async def delete_api(api_name: str, username: str = Depends(verify_token)):
|
|
| 638 |
"""Delete API (soft delete)"""
|
| 639 |
ConfigProvider.delete_api(api_name, username)
|
| 640 |
|
| 641 |
-
|
| 642 |
return {"success": True}
|
| 643 |
|
| 644 |
@router.post("/validate/regex")
|
|
@@ -677,7 +682,7 @@ async def run_all_tests(
|
|
| 677 |
username: str = Depends(verify_token)
|
| 678 |
):
|
| 679 |
"""Run all tests"""
|
| 680 |
-
|
| 681 |
|
| 682 |
# TODO: Implement test runner
|
| 683 |
# For now, return mock results
|
|
@@ -755,7 +760,7 @@ async def generate_tts(
|
|
| 755 |
headers={"X-TTS-Status": "disabled"}
|
| 756 |
)
|
| 757 |
|
| 758 |
-
|
| 759 |
|
| 760 |
# Preprocess text if needed
|
| 761 |
preprocessor = TTSPreprocessor(language=request.language)
|
|
@@ -781,7 +786,7 @@ async def generate_tts(
|
|
| 781 |
)
|
| 782 |
|
| 783 |
except Exception as e:
|
| 784 |
-
|
| 785 |
raise HTTPException(status_code=500, detail=str(e))
|
| 786 |
|
| 787 |
@router.get("/tts/voices")
|
|
@@ -806,7 +811,7 @@ async def get_tts_voices(username: str = Depends(verify_token)):
|
|
| 806 |
return {"voices": voice_list}
|
| 807 |
|
| 808 |
except Exception as e:
|
| 809 |
-
|
| 810 |
return {"voices": []}
|
| 811 |
|
| 812 |
# ===================== Helper Functions =====================
|
|
@@ -829,12 +834,12 @@ async def notify_llm_startup(project, version):
|
|
| 829 |
|
| 830 |
success = await llm_provider.startup(project_config)
|
| 831 |
if success:
|
| 832 |
-
|
| 833 |
else:
|
| 834 |
-
|
| 835 |
|
| 836 |
except Exception as e:
|
| 837 |
-
|
| 838 |
raise
|
| 839 |
|
| 840 |
# ===================== Cleanup Task =====================
|
|
@@ -856,11 +861,11 @@ def cleanup_activity_log():
|
|
| 856 |
|
| 857 |
if len(cfg.activity_log) < original_count:
|
| 858 |
removed = original_count - len(cfg.activity_log)
|
| 859 |
-
|
| 860 |
cfg.save()
|
| 861 |
|
| 862 |
except Exception as e:
|
| 863 |
-
|
| 864 |
|
| 865 |
# Run every hour
|
| 866 |
time.sleep(3600)
|
|
@@ -869,4 +874,4 @@ def start_cleanup_task():
|
|
| 869 |
"""Start the cleanup task in background"""
|
| 870 |
thread = threading.Thread(target=cleanup_activity_log, daemon=True)
|
| 871 |
thread.start()
|
| 872 |
-
|
|
|
|
| 16 |
import httpx
|
| 17 |
|
| 18 |
from config_provider import ConfigProvider
|
| 19 |
+
from logger import log_info, log_error, log_warning, log_debug
|
| 20 |
+
from exceptions import (
|
| 21 |
+
RaceConditionError, ValidationError, ResourceNotFoundError,
|
| 22 |
+
AuthenticationError, AuthorizationError
|
| 23 |
+
)
|
| 24 |
|
| 25 |
# ===================== Constants & Config =====================
|
| 26 |
security = HTTPBearer()
|
|
|
|
| 153 |
# Create token
|
| 154 |
token = create_token(request.username)
|
| 155 |
|
| 156 |
+
log_info(f"β
User '{request.username}' logged in successfully")
|
| 157 |
return LoginResponse(token=token, username=request.username)
|
| 158 |
|
| 159 |
@router.post("/change-password")
|
|
|
|
| 184 |
# Save configuration
|
| 185 |
cfg.save()
|
| 186 |
|
| 187 |
+
log_info(f"β
Password changed for user '{username}'")
|
| 188 |
return {"success": True}
|
| 189 |
|
| 190 |
# ===================== Locales Endpoints =====================
|
|
|
|
| 345 |
username: str = Depends(verify_token)
|
| 346 |
):
|
| 347 |
"""Update environment configuration with provider validation"""
|
| 348 |
+
log_info(f"π Updating environment config by {username}")
|
| 349 |
|
| 350 |
cfg = ConfigProvider.get()
|
| 351 |
|
|
|
|
| 379 |
# Update via ConfigProvider
|
| 380 |
ConfigProvider.update_environment(update.model_dump(), username)
|
| 381 |
|
| 382 |
+
log_info(f"β
Environment updated to LLM: {update.llm_provider.name}, TTS: {update.tts_provider.name}, STT: {update.stt_provider.name} by {username}")
|
| 383 |
return {"success": True}
|
| 384 |
|
| 385 |
# ===================== Project Endpoints =====================
|
|
|
|
| 444 |
# Create project via ConfigProvider
|
| 445 |
new_project = ConfigProvider.create_project(project.model_dump(), username)
|
| 446 |
|
| 447 |
+
log_info(f"β
Project '{project.name}' created by {username}")
|
| 448 |
return new_project.model_dump()
|
| 449 |
|
| 450 |
@router.put("/projects/{project_id}")
|
|
|
|
| 469 |
# Update via ConfigProvider
|
| 470 |
updated_project = ConfigProvider.update_project(project_id, update.model_dump(), username)
|
| 471 |
|
| 472 |
+
log_info(f"β
Project '{updated_project.name}' updated by {username}")
|
| 473 |
return updated_project.model_dump()
|
| 474 |
|
| 475 |
@router.delete("/projects/{project_id}")
|
|
|
|
| 477 |
"""Delete project (soft delete)"""
|
| 478 |
ConfigProvider.delete_project(project_id, username)
|
| 479 |
|
| 480 |
+
log_info(f"β
Project deleted by {username}")
|
| 481 |
return {"success": True}
|
| 482 |
|
| 483 |
@router.patch("/projects/{project_id}/toggle")
|
|
|
|
| 485 |
"""Toggle project enabled status"""
|
| 486 |
enabled = ConfigProvider.toggle_project(project_id, username)
|
| 487 |
|
| 488 |
+
log_info(f"β
Project {'enabled' if enabled else 'disabled'} by {username}")
|
| 489 |
return {"enabled": enabled}
|
| 490 |
|
| 491 |
# ===================== Version Endpoints =====================
|
|
|
|
| 517 |
"""Create new version"""
|
| 518 |
new_version = ConfigProvider.create_version(project_id, version_data.model_dump(), username)
|
| 519 |
|
| 520 |
+
log_info(f"β
Version created for project {project_id} by {username}")
|
| 521 |
return new_version.model_dump()
|
| 522 |
|
| 523 |
@router.put("/projects/{project_id}/versions/{version_id}")
|
|
|
|
| 530 |
"""Update version"""
|
| 531 |
updated_version = ConfigProvider.update_version(project_id, version_id, update.model_dump(), username)
|
| 532 |
|
| 533 |
+
log_info(f"β
Version {version_id} updated for project {project_id} by {username}")
|
| 534 |
return updated_version.model_dump()
|
| 535 |
|
| 536 |
@router.post("/projects/{project_id}/versions/{version_id}/publish")
|
|
|
|
| 542 |
"""Publish version"""
|
| 543 |
project, version = ConfigProvider.publish_version(project_id, version_id, username)
|
| 544 |
|
| 545 |
+
log_info(f"β
Version {version_id} published for project '{project.name}' by {username}")
|
| 546 |
|
| 547 |
# Notify LLM provider if project is enabled and provider requires repo info
|
| 548 |
cfg = ConfigProvider.get()
|
|
|
|
| 552 |
try:
|
| 553 |
await notify_llm_startup(project, version)
|
| 554 |
except Exception as e:
|
| 555 |
+
log_error(f"β οΈ Failed to notify LLM provider", e)
|
| 556 |
# Don't fail the publish
|
| 557 |
|
| 558 |
return {"success": True}
|
|
|
|
| 566 |
"""Delete version (soft delete)"""
|
| 567 |
ConfigProvider.delete_version(project_id, version_id, username)
|
| 568 |
|
| 569 |
+
log_info(f"β
Version {version_id} deleted for project {project_id} by {username}")
|
| 570 |
return {"success": True}
|
| 571 |
|
| 572 |
@router.get("/projects/{project_name}/versions")
|
|
|
|
| 623 |
"""Create new API"""
|
| 624 |
new_api = ConfigProvider.create_api(api.model_dump(), username)
|
| 625 |
|
| 626 |
+
log_info(f"β
API '{api.name}' created by {username}")
|
| 627 |
return new_api.model_dump()
|
| 628 |
|
| 629 |
@router.put("/apis/{api_name}")
|
|
|
|
| 635 |
"""Update API"""
|
| 636 |
updated_api = ConfigProvider.update_api(api_name, update.model_dump(), username)
|
| 637 |
|
| 638 |
+
log_info(f"β
API '{api_name}' updated by {username}")
|
| 639 |
return updated_api.model_dump()
|
| 640 |
|
| 641 |
@router.delete("/apis/{api_name}")
|
|
|
|
| 643 |
"""Delete API (soft delete)"""
|
| 644 |
ConfigProvider.delete_api(api_name, username)
|
| 645 |
|
| 646 |
+
log_info(f"β
API '{api_name}' deleted by {username}")
|
| 647 |
return {"success": True}
|
| 648 |
|
| 649 |
@router.post("/validate/regex")
|
|
|
|
| 682 |
username: str = Depends(verify_token)
|
| 683 |
):
|
| 684 |
"""Run all tests"""
|
| 685 |
+
log_info(f"π§ͺ Running {request.test_type} tests requested by {username}")
|
| 686 |
|
| 687 |
# TODO: Implement test runner
|
| 688 |
# For now, return mock results
|
|
|
|
| 760 |
headers={"X-TTS-Status": "disabled"}
|
| 761 |
)
|
| 762 |
|
| 763 |
+
log_info(f"π€ TTS request: '{request.text[:50]}...' with provider: {tts_provider.get_provider_name()}")
|
| 764 |
|
| 765 |
# Preprocess text if needed
|
| 766 |
preprocessor = TTSPreprocessor(language=request.language)
|
|
|
|
| 786 |
)
|
| 787 |
|
| 788 |
except Exception as e:
|
| 789 |
+
log_error("β TTS generation error", e)
|
| 790 |
raise HTTPException(status_code=500, detail=str(e))
|
| 791 |
|
| 792 |
@router.get("/tts/voices")
|
|
|
|
| 811 |
return {"voices": voice_list}
|
| 812 |
|
| 813 |
except Exception as e:
|
| 814 |
+
log_error("β Error getting TTS voices", e)
|
| 815 |
return {"voices": []}
|
| 816 |
|
| 817 |
# ===================== Helper Functions =====================
|
|
|
|
| 834 |
|
| 835 |
success = await llm_provider.startup(project_config)
|
| 836 |
if success:
|
| 837 |
+
log_info(f"β
LLM provider notified for project '{project.name}'")
|
| 838 |
else:
|
| 839 |
+
log_info(f"β οΈ LLM provider notification failed for project '{project.name}'")
|
| 840 |
|
| 841 |
except Exception as e:
|
| 842 |
+
log_error("β Error notifying LLM provider", e)
|
| 843 |
raise
|
| 844 |
|
| 845 |
# ===================== Cleanup Task =====================
|
|
|
|
| 861 |
|
| 862 |
if len(cfg.activity_log) < original_count:
|
| 863 |
removed = original_count - len(cfg.activity_log)
|
| 864 |
+
log_info(f"π§Ή Cleaned up {removed} old activity log entries")
|
| 865 |
cfg.save()
|
| 866 |
|
| 867 |
except Exception as e:
|
| 868 |
+
log_error("β Activity log cleanup error", e)
|
| 869 |
|
| 870 |
# Run every hour
|
| 871 |
time.sleep(3600)
|
|
|
|
| 874 |
"""Start the cleanup task in background"""
|
| 875 |
thread = threading.Thread(target=cleanup_activity_log, daemon=True)
|
| 876 |
thread.start()
|
| 877 |
+
log_info("π§Ή Activity log cleanup task started")
|