Spaces:
Building
Building
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")
|