supervaizer 0.10.13__tar.gz → 0.10.15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {supervaizer-0.10.13 → supervaizer-0.10.15}/PKG-INFO +1 -1
  2. {supervaizer-0.10.13 → supervaizer-0.10.15}/pyproject.toml +1 -1
  3. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/__version__.py +1 -1
  4. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/account.py +7 -1
  5. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/routes.py +34 -33
  6. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/index.html +1 -0
  7. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/server.py +33 -35
  8. {supervaizer-0.10.13 → supervaizer-0.10.15}/.gitignore +0 -0
  9. {supervaizer-0.10.13 → supervaizer-0.10.15}/LICENSE.md +0 -0
  10. {supervaizer-0.10.13 → supervaizer-0.10.15}/README.md +0 -0
  11. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/__init__.py +0 -0
  12. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/account_service.py +0 -0
  13. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/static/favicon.ico +0 -0
  14. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/static/js/job-start-form.js +0 -0
  15. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/agent_detail.html +0 -0
  16. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/agents.html +0 -0
  17. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/agents_grid.html +0 -0
  18. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/base.html +0 -0
  19. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/case_detail.html +0 -0
  20. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/cases_list.html +0 -0
  21. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/cases_table.html +0 -0
  22. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/console.html +0 -0
  23. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/dashboard.html +0 -0
  24. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/job_detail.html +0 -0
  25. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/job_start_test.html +0 -0
  26. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/jobs_list.html +0 -0
  27. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/jobs_table.html +0 -0
  28. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/navigation.html +0 -0
  29. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/recent_activity.html +0 -0
  30. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/server.html +0 -0
  31. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/server_status_cards.html +0 -0
  32. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/admin/templates/supervaize_instructions.html +0 -0
  33. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/agent.py +0 -0
  34. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/case.py +0 -0
  35. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/cli.py +0 -0
  36. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/common.py +0 -0
  37. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/__init__.py +0 -0
  38. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/cli.py +0 -0
  39. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/__init__.py +0 -0
  40. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/clean.py +0 -0
  41. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/down.py +0 -0
  42. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/local.py +0 -0
  43. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/plan.py +0 -0
  44. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/status.py +0 -0
  45. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/commands/up.py +0 -0
  46. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/docker.py +0 -0
  47. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/driver_factory.py +0 -0
  48. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/drivers/__init__.py +0 -0
  49. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/drivers/aws_app_runner.py +0 -0
  50. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/drivers/base.py +0 -0
  51. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/drivers/cloud_run.py +0 -0
  52. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/drivers/do_app_platform.py +0 -0
  53. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/health.py +0 -0
  54. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/state.py +0 -0
  55. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/Dockerfile.template +0 -0
  56. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/debug_env.py +0 -0
  57. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/docker-compose.yml.template +0 -0
  58. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/dockerignore.template +0 -0
  59. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/entrypoint.sh +0 -0
  60. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/templates/index.html +0 -0
  61. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/deploy/utils.py +0 -0
  62. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/event.py +0 -0
  63. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/examples/controller_template.py +0 -0
  64. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/instructions.py +0 -0
  65. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/job.py +0 -0
  66. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/job_service.py +0 -0
  67. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/lifecycle.py +0 -0
  68. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/parameter.py +0 -0
  69. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/protocol/__init__.py +0 -0
  70. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/protocol/a2a/__init__.py +0 -0
  71. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/protocol/a2a/model.py +0 -0
  72. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/protocol/a2a/routes.py +0 -0
  73. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/py.typed +0 -0
  74. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/routes.py +0 -0
  75. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/server_utils.py +0 -0
  76. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/storage.py +0 -0
  77. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/telemetry.py +0 -0
  78. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/utils/__init__.py +0 -0
  79. {supervaizer-0.10.13 → supervaizer-0.10.15}/src/supervaizer/utils/version_check.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervaizer
3
- Version: 0.10.13
3
+ Version: 0.10.15
4
4
  Summary: Controller system for Supervaize
5
5
  Project-URL: Homepage, https://supervaize.com
6
6
  Project-URL: Repository, https://github.com/supervaize/supervaizer
@@ -121,7 +121,7 @@ mypy_path = "src"
121
121
  disallow_any_expr = false
122
122
 
123
123
  [tool.bumpversion]
124
- current_version = "0.10.13"
124
+ current_version = "0.10.15"
125
125
  commit = true
126
126
  tag = true
127
127
  tag_name = "v{new_version}"
@@ -5,6 +5,6 @@
5
5
  # https://mozilla.org/MPL/2.0/.
6
6
 
7
7
 
8
- VERSION = "0.10.13"
8
+ VERSION = "0.10.15"
9
9
  API_VERSION = "v1"
10
10
  TELEMETRY_VERSION = "v1"
@@ -199,7 +199,13 @@ class Account(AccountAbstract):
199
199
  from supervaizer.event import ServerRegisterEvent
200
200
 
201
201
  event = ServerRegisterEvent(server=server, account=self)
202
- return self.send_event(sender=server, event=event)
202
+ result = self.send_event(sender=server, event=event)
203
+ if isinstance(result, ApiSuccess):
204
+ log.success(result.message)
205
+ # TODO: Update server with the server ID from the response. store this ID in env variable.
206
+ else:
207
+ log.error(result.message)
208
+ return result
203
209
 
204
210
  def _create_api_result(
205
211
  self,
@@ -267,6 +267,7 @@ def create_admin_routes() -> APIRouter:
267
267
  "db_name": "TinyDB",
268
268
  "data_storage_path": str(storage.db_path.absolute()),
269
269
  "api_key": os.getenv("SUPERVAIZER_API_KEY"),
270
+ "server_id": os.getenv("SUPERVAIZER_SERVER_ID"),
270
271
  },
271
272
  )
272
273
  except Exception as e:
@@ -445,7 +446,11 @@ def create_admin_routes() -> APIRouter:
445
446
  if isinstance(result, ApiSuccess):
446
447
  return JSONResponse(
447
448
  status_code=200,
448
- content={"success": True, "message": result.message, "detail": result.detail},
449
+ content={
450
+ "success": True,
451
+ "message": result.message,
452
+ "detail": result.detail,
453
+ },
449
454
  )
450
455
  # ApiError
451
456
  return JSONResponse(
@@ -921,28 +926,24 @@ def create_admin_routes() -> APIRouter:
921
926
  # Combine and sort by created_at
922
927
  activities = []
923
928
  for job in recent_jobs:
924
- activities.append(
925
- {
926
- "type": "job",
927
- "id": job.get("id"),
928
- "name": job.get("name"),
929
- "status": job.get("status"),
930
- "created_at": job.get("created_at"),
931
- "agent_name": job.get("agent_name"),
932
- }
933
- )
929
+ activities.append({
930
+ "type": "job",
931
+ "id": job.get("id"),
932
+ "name": job.get("name"),
933
+ "status": job.get("status"),
934
+ "created_at": job.get("created_at"),
935
+ "agent_name": job.get("agent_name"),
936
+ })
934
937
 
935
938
  for case in recent_cases:
936
- activities.append(
937
- {
938
- "type": "case",
939
- "id": case.get("id"),
940
- "name": case.get("name"),
941
- "status": case.get("status"),
942
- "created_at": case.get("created_at"),
943
- "job_id": case.get("job_id"),
944
- }
945
- )
939
+ activities.append({
940
+ "type": "case",
941
+ "id": case.get("id"),
942
+ "name": case.get("name"),
943
+ "status": case.get("status"),
944
+ "created_at": case.get("created_at"),
945
+ "job_id": case.get("job_id"),
946
+ })
946
947
 
947
948
  # Sort by created_at descending
948
949
  activities.sort(key=lambda x: str(x.get("created_at", "")), reverse=True)
@@ -1199,23 +1200,23 @@ def get_dashboard_stats(storage: StorageManager) -> AdminStats:
1199
1200
 
1200
1201
  # Calculate job stats
1201
1202
  job_total = len(all_jobs)
1202
- job_running = len(
1203
- [j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]]
1204
- )
1203
+ job_running = len([
1204
+ j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]
1205
+ ])
1205
1206
  job_completed = len([j for j in all_jobs if j.get("status") == "completed"])
1206
- job_failed = len(
1207
- [j for j in all_jobs if j.get("status") in ["failed", "cancelled"]]
1208
- )
1207
+ job_failed = len([
1208
+ j for j in all_jobs if j.get("status") in ["failed", "cancelled"]
1209
+ ])
1209
1210
 
1210
1211
  # Calculate case stats
1211
1212
  case_total = len(all_cases)
1212
- case_running = len(
1213
- [c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]]
1214
- )
1213
+ case_running = len([
1214
+ c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]
1215
+ ])
1215
1216
  case_completed = len([c for c in all_cases if c.get("status") == "completed"])
1216
- case_failed = len(
1217
- [c for c in all_cases if c.get("status") in ["failed", "cancelled"]]
1218
- )
1217
+ case_failed = len([
1218
+ c for c in all_cases if c.get("status") in ["failed", "cancelled"]
1219
+ ])
1219
1220
 
1220
1221
  # TinyDB collections count (tables)
1221
1222
  collections_count = len(storage._db.tables())
@@ -16,6 +16,7 @@
16
16
  <p class="mt-2 text-sm text-gray-500">
17
17
  Controller version {{ version }} · API version {{ api_version }}
18
18
  </p>
19
+ <p class="mt-1 text-xs text-gray-400 font-mono">Server ID: {{ server_id }}</p>
19
20
 
20
21
  <div class="mt-8">
21
22
  <h2 class="text-lg font-medium text-gray-900 mb-4">Links</h2>
@@ -20,7 +20,7 @@ from cryptography.hazmat.primitives.asymmetric import rsa
20
20
  from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey
21
21
  from fastapi import FastAPI, HTTPException, Request, Security, status
22
22
  from fastapi.exceptions import RequestValidationError
23
- from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
23
+ from fastapi.responses import HTMLResponse, JSONResponse
24
24
  from fastapi.security import APIKeyHeader
25
25
  from fastapi.templating import Jinja2Templates
26
26
  from pydantic import BaseModel, field_validator, Field
@@ -46,11 +46,7 @@ from supervaizer.routes import (
46
46
  create_utils_routes,
47
47
  get_server,
48
48
  )
49
- from supervaizer.storage import (
50
- PERSISTENCE_ENABLED,
51
- StorageManager,
52
- load_running_entities_on_startup,
53
- )
49
+ from supervaizer.storage import StorageManager, load_running_entities_on_startup
54
50
 
55
51
  insp = inspect
56
52
 
@@ -59,6 +55,16 @@ T = TypeVar("T")
59
55
  # Additional imports for server persistence
60
56
 
61
57
 
58
+ def _get_or_create_server_id() -> str:
59
+ """Use SUPERVAIZER_SERVER_ID from env if set; else create uuid and set env."""
60
+ existing = os.getenv("SUPERVAIZER_SERVER_ID")
61
+ if existing:
62
+ return existing
63
+ new_id = str(uuid.uuid4())
64
+ os.environ["SUPERVAIZER_SERVER_ID"] = new_id
65
+ return new_id
66
+
67
+
62
68
  class ServerInfo(BaseModel):
63
69
  """Complete server information for storage."""
64
70
 
@@ -74,9 +80,7 @@ class ServerInfo(BaseModel):
74
80
 
75
81
 
76
82
  def save_server_info_to_storage(server_instance: "Server") -> None:
77
- """Save server information to storage (only when persistence is enabled)."""
78
- if not PERSISTENCE_ENABLED:
79
- return
83
+ """Save server information to storage."""
80
84
  try:
81
85
  storage = StorageManager()
82
86
 
@@ -95,6 +99,7 @@ def save_server_info_to_storage(server_instance: "Server") -> None:
95
99
 
96
100
  # Create server info
97
101
  server_info = ServerInfo(
102
+ id=getattr(server_instance, "server_id", "N/A"),
98
103
  host=getattr(server_instance, "host", "N/A"),
99
104
  port=getattr(server_instance, "port", "N/A"),
100
105
  api_version=API_VERSION,
@@ -154,6 +159,10 @@ class ServerAbstract(SvBaseModel):
154
159
  """
155
160
 
156
161
  supervaizer_VERSION: ClassVar[str] = VERSION
162
+ server_id: str = Field(
163
+ default_factory=_get_or_create_server_id,
164
+ description="Unique server id (SUPERVAIZER_SERVER_ID env or persisted uuid)",
165
+ )
157
166
  scheme: str = Field(description="URL scheme (http or https)")
158
167
  host: str = Field(
159
168
  description="Host to bind the server to (e.g., 0.0.0.0 for all interfaces)"
@@ -242,10 +251,10 @@ class Server(ServerAbstract):
242
251
  supervisor_account: Optional[Account] = None,
243
252
  a2a_endpoints: bool = True,
244
253
  admin_interface: bool = True,
245
- scheme: str = os.getenv("SUPERVAIZER_SCHEME", "https"),
254
+ scheme: str = "http",
246
255
  environment: str = os.getenv("SUPERVAIZER_ENVIRONMENT", "dev"),
247
256
  host: str = os.getenv("SUPERVAIZER_HOST", "0.0.0.0"),
248
- port: int = int(os.getenv("SUPERVAIZER_PORT", 443)),
257
+ port: int = int(os.getenv("SUPERVAIZER_PORT", 8000)),
249
258
  debug: bool = False,
250
259
  reload: bool = False,
251
260
  mac_addr: str = "",
@@ -360,6 +369,8 @@ class Server(ServerAbstract):
360
369
  **kwargs,
361
370
  )
362
371
 
372
+ log.info(f"[Server launch] Server ID: {self.server_id}")
373
+
363
374
  # Create routes
364
375
  if self.supervisor_account:
365
376
  log.info(
@@ -383,13 +394,6 @@ class Server(ServerAbstract):
383
394
  # Save server info to storage for admin interface
384
395
  save_server_info_to_storage(self)
385
396
 
386
- # Favicon (served at root so /docs, /redoc, etc. pick it up)
387
- _favicon_path = Path(__file__).parent / "admin" / "static" / "favicon.ico"
388
-
389
- @self.app.get("/favicon.ico", include_in_schema=False)
390
- async def favicon() -> FileResponse:
391
- return FileResponse(_favicon_path, media_type="image/x-icon")
392
-
393
397
  # Home page (template in admin/templates)
394
398
  _home_templates = Jinja2Templates(
395
399
  directory=str(Path(__file__).parent / "admin" / "templates")
@@ -397,20 +401,16 @@ class Server(ServerAbstract):
397
401
 
398
402
  @self.app.get("/", response_class=HTMLResponse)
399
403
  async def home_page(request: Request) -> HTMLResponse:
400
- root_index = Path.cwd() / "index.html"
401
- if root_index.is_file():
402
- return HTMLResponse(content=root_index.read_text(encoding="utf-8"))
403
404
  base = self.public_url or f"{self.scheme}://{self.host}:{self.port}"
404
405
  return _home_templates.TemplateResponse(
405
406
  "index.html",
406
407
  {
407
408
  "request": request,
408
409
  "base": base,
409
- "public_url": self.public_url,
410
- "full_url": f"{self.scheme}://{self.host}:{self.port}",
411
410
  "version": VERSION,
412
411
  "api_version": API_VERSION,
413
412
  "show_admin": bool(self.api_key and admin_interface),
413
+ "server_id": self.server_id,
414
414
  },
415
415
  )
416
416
 
@@ -481,6 +481,7 @@ class Server(ServerAbstract):
481
481
  """Get registration info for the server."""
482
482
  assert self.public_key is not None, "Public key not initialized"
483
483
  return {
484
+ "server_id": self.server_id,
484
485
  "url": self.public_url,
485
486
  "uri": self.uri,
486
487
  "api_version": API_VERSION,
@@ -500,9 +501,7 @@ class Server(ServerAbstract):
500
501
  "agents": [agent.registration_info for agent in self.agents],
501
502
  }
502
503
 
503
- def launch(
504
- self, log_level: Optional[str] = "INFO", start_uvicorn: bool = False
505
- ) -> None:
504
+ def launch(self, log_level: Optional[str] = "INFO") -> None:
506
505
  if log_level:
507
506
  log.remove()
508
507
  log.add(
@@ -561,16 +560,15 @@ class Server(ServerAbstract):
561
560
  if updated_agent:
562
561
  log.info(f"[Server launch] Updated agent {updated_agent.name}")
563
562
 
564
- if start_uvicorn:
565
- import uvicorn
563
+ import uvicorn
566
564
 
567
- uvicorn.run(
568
- self.app,
569
- host=self.host,
570
- port=self.port,
571
- reload=self.reload,
572
- log_level=log_level,
573
- )
565
+ uvicorn.run(
566
+ self.app,
567
+ host=self.host,
568
+ port=self.port,
569
+ reload=self.reload,
570
+ log_level=log_level,
571
+ )
574
572
 
575
573
  def instructions(self) -> None:
576
574
  server_url = f"http://{self.host}:{self.port}"
File without changes
File without changes
File without changes