supervaizer 0.10.9__tar.gz → 0.10.11__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.9 → supervaizer-0.10.11}/PKG-INFO +1 -1
  2. {supervaizer-0.10.9 → supervaizer-0.10.11}/pyproject.toml +1 -1
  3. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/__version__.py +1 -1
  4. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/account.py +10 -2
  5. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/account_service.py +13 -3
  6. supervaizer-0.10.11/src/supervaizer/admin/static/favicon.ico +0 -0
  7. supervaizer-0.10.11/src/supervaizer/deploy/templates/index.html +57 -0
  8. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/server.py +28 -12
  9. {supervaizer-0.10.9 → supervaizer-0.10.11}/.gitignore +0 -0
  10. {supervaizer-0.10.9 → supervaizer-0.10.11}/LICENSE.md +0 -0
  11. {supervaizer-0.10.9 → supervaizer-0.10.11}/README.md +0 -0
  12. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/__init__.py +0 -0
  13. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/routes.py +0 -0
  14. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/static/js/job-start-form.js +0 -0
  15. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/agent_detail.html +0 -0
  16. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/agents.html +0 -0
  17. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/agents_grid.html +0 -0
  18. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/base.html +0 -0
  19. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/case_detail.html +0 -0
  20. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/cases_list.html +0 -0
  21. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/cases_table.html +0 -0
  22. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/console.html +0 -0
  23. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/dashboard.html +0 -0
  24. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/index.html +0 -0
  25. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/job_detail.html +0 -0
  26. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/job_start_test.html +0 -0
  27. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/jobs_list.html +0 -0
  28. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/jobs_table.html +0 -0
  29. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/navigation.html +0 -0
  30. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/recent_activity.html +0 -0
  31. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/server.html +0 -0
  32. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/server_status_cards.html +0 -0
  33. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/admin/templates/supervaize_instructions.html +0 -0
  34. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/agent.py +0 -0
  35. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/case.py +0 -0
  36. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/cli.py +0 -0
  37. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/common.py +0 -0
  38. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/__init__.py +0 -0
  39. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/cli.py +0 -0
  40. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/__init__.py +0 -0
  41. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/clean.py +0 -0
  42. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/down.py +0 -0
  43. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/local.py +0 -0
  44. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/plan.py +0 -0
  45. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/status.py +0 -0
  46. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/commands/up.py +0 -0
  47. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/docker.py +0 -0
  48. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/driver_factory.py +0 -0
  49. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/drivers/__init__.py +0 -0
  50. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/drivers/aws_app_runner.py +0 -0
  51. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/drivers/base.py +0 -0
  52. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/drivers/cloud_run.py +0 -0
  53. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/drivers/do_app_platform.py +0 -0
  54. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/health.py +0 -0
  55. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/state.py +0 -0
  56. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/templates/Dockerfile.template +0 -0
  57. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/templates/debug_env.py +0 -0
  58. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/templates/docker-compose.yml.template +0 -0
  59. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/templates/dockerignore.template +0 -0
  60. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/templates/entrypoint.sh +0 -0
  61. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/deploy/utils.py +0 -0
  62. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/event.py +0 -0
  63. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/examples/controller_template.py +0 -0
  64. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/instructions.py +0 -0
  65. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/job.py +0 -0
  66. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/job_service.py +0 -0
  67. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/lifecycle.py +0 -0
  68. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/parameter.py +0 -0
  69. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/protocol/__init__.py +0 -0
  70. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/protocol/a2a/__init__.py +0 -0
  71. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/protocol/a2a/model.py +0 -0
  72. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/protocol/a2a/routes.py +0 -0
  73. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/py.typed +0 -0
  74. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/routes.py +0 -0
  75. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/server_utils.py +0 -0
  76. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/storage.py +0 -0
  77. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/telemetry.py +0 -0
  78. {supervaizer-0.10.9 → supervaizer-0.10.11}/src/supervaizer/utils/__init__.py +0 -0
  79. {supervaizer-0.10.9 → supervaizer-0.10.11}/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.9
3
+ Version: 0.10.11
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.9"
124
+ current_version = "0.10.11"
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.9"
8
+ VERSION = "0.10.11"
9
9
  API_VERSION = "v1"
10
10
  TELEMETRY_VERSION = "v1"
@@ -8,7 +8,7 @@
8
8
  from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union
9
9
 
10
10
  import httpx
11
- from pydantic import Field
11
+ from pydantic import Field, field_validator
12
12
 
13
13
  from supervaizer.__version__ import VERSION
14
14
  from supervaizer.common import ApiError, ApiResult, ApiSuccess, SvBaseModel
@@ -55,6 +55,14 @@ class AccountAbstract(SvBaseModel):
55
55
  description="The URL of the Supervaize SaaS API provided by Supervaize.com"
56
56
  )
57
57
 
58
+ @field_validator("workspace_id", "api_key", "api_url", mode="before")
59
+ @classmethod
60
+ def strip_whitespace(cls, v: Any) -> Any:
61
+ """Strip leading/trailing whitespace (e.g. newlines from env vars)."""
62
+ if isinstance(v, str):
63
+ return v.strip()
64
+ return v
65
+
58
66
  model_config = {
59
67
  "reference_group": "Core",
60
68
  "json_schema_extra": {
@@ -121,7 +129,7 @@ class Account(AccountAbstract):
121
129
  """URL for the Supervaize Control API.
122
130
  Tested in tests/test_account.py
123
131
  """
124
- return f"{self.api_url_w_v1}/ctrl-events/"
132
+ return f"{self.api_url_w_v1}/ctrl-events/".strip()
125
133
 
126
134
  def get_url(self, pattern_name: str, **kwargs: Any) -> str:
127
135
  """Generate a URL using the predefined patterns.
@@ -59,14 +59,17 @@ def send_event(
59
59
 
60
60
  headers = account.api_headers
61
61
  payload = event.payload
62
+ url_event = (
63
+ account.url_event.strip()
64
+ ) # defensive: env vars often have trailing newline
62
65
 
63
66
  # Generate curl equivalent for debugging
64
67
 
65
68
  curl_headers = " ".join([f'-H "{k}: {v}"' for k, v in headers.items()])
66
- curl_cmd = f"curl -X 'GET' '{account.url_event}' {curl_headers}"
69
+ curl_cmd = f"curl -X 'GET' '{url_event}' {curl_headers}"
67
70
 
68
71
  try:
69
- response = _httpx_client.post(account.url_event, headers=headers, json=payload)
72
+ response = _httpx_client.post(url_event, headers=headers, json=payload)
70
73
 
71
74
  # Log response details before raising for status
72
75
 
@@ -76,6 +79,13 @@ def send_event(
76
79
  )
77
80
 
78
81
  log.success(result.log_message)
82
+ except (httpx.ConnectError, httpx.ConnectTimeout) as e:
83
+ log.error(
84
+ f"Supervaize controller is not available at {url_event}. "
85
+ "Connection refused or timed out. Is the controller server running?"
86
+ )
87
+ log.error(f"❌ Error sending event {event.type.name}: {e!s}")
88
+ raise e
79
89
  except httpx.HTTPError as e:
80
90
  # Enhanced error logging
81
91
  log.error("[Send event] HTTP Error occurred")
@@ -83,7 +93,7 @@ def send_event(
83
93
 
84
94
  error_result = ApiError(
85
95
  message=f"Error sending event {event.type.name}",
86
- url=account.url_event,
96
+ url=url_event,
87
97
  payload=event.payload,
88
98
  exception=e,
89
99
  )
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Supervaizer API</title>
7
+ <!-- Tailwind CSS -->
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ </head>
10
+ <body class="bg-gray-50 min-h-screen">
11
+ <main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
12
+ <div class="px-4 py-6 sm:px-0">
13
+ <h1 class="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
14
+ Supervaizer API
15
+ </h1>
16
+ <p class="mt-2 text-sm text-gray-500">
17
+ Controller version {{ version }} · API version {{ api_version }}
18
+ </p>
19
+
20
+ <div class="mt-8">
21
+ <h2 class="text-lg font-medium text-gray-900 mb-4">Links</h2>
22
+ <ul class="space-y-2">
23
+ <li>
24
+ <a href="/docs" class="text-blue-600 hover:text-blue-800 font-medium">
25
+ Swagger UI
26
+ </a>
27
+ </li>
28
+ <li>
29
+ <a href="/redoc" class="text-blue-600 hover:text-blue-800 font-medium">
30
+ ReDoc
31
+ </a>
32
+ </li>
33
+ <li>
34
+ <a href="/openapi.json" class="text-blue-600 hover:text-blue-800 font-medium">
35
+ OpenAPI
36
+ </a>
37
+ </li>
38
+ {% if show_admin %}
39
+ <li>
40
+ <a href="/admin" class="text-blue-600 hover:text-blue-800 font-medium">
41
+ Admin
42
+ </a>
43
+ </li>
44
+ {% endif %}
45
+ <li>
46
+ <a href="/console" class="text-blue-600 hover:text-blue-800 font-medium">
47
+ Console
48
+ </a>
49
+ </li>
50
+ <li> BASE: {{ base }}
51
+ </li>
52
+ </ul>
53
+ </div>
54
+ </div>
55
+ </main>
56
+ </body>
57
+ </html>
@@ -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 HTMLResponse, JSONResponse
23
+ from fastapi.responses import FileResponse, 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,7 +46,11 @@ from supervaizer.routes import (
46
46
  create_utils_routes,
47
47
  get_server,
48
48
  )
49
- from supervaizer.storage import StorageManager, load_running_entities_on_startup
49
+ from supervaizer.storage import (
50
+ PERSISTENCE_ENABLED,
51
+ StorageManager,
52
+ load_running_entities_on_startup,
53
+ )
50
54
 
51
55
  insp = inspect
52
56
 
@@ -70,7 +74,9 @@ class ServerInfo(BaseModel):
70
74
 
71
75
 
72
76
  def save_server_info_to_storage(server_instance: "Server") -> None:
73
- """Save server information to storage."""
77
+ """Save server information to storage (only when persistence is enabled)."""
78
+ if not PERSISTENCE_ENABLED:
79
+ return
74
80
  try:
75
81
  storage = StorageManager()
76
82
 
@@ -377,6 +383,13 @@ class Server(ServerAbstract):
377
383
  # Save server info to storage for admin interface
378
384
  save_server_info_to_storage(self)
379
385
 
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
+
380
393
  # Home page (template in admin/templates)
381
394
  _home_templates = Jinja2Templates(
382
395
  directory=str(Path(__file__).parent / "admin" / "templates")
@@ -487,7 +500,9 @@ class Server(ServerAbstract):
487
500
  "agents": [agent.registration_info for agent in self.agents],
488
501
  }
489
502
 
490
- def launch(self, log_level: Optional[str] = "INFO") -> None:
503
+ def launch(
504
+ self, log_level: Optional[str] = "INFO", start_uvicorn: bool = False
505
+ ) -> None:
491
506
  if log_level:
492
507
  log.remove()
493
508
  log.add(
@@ -546,15 +561,16 @@ class Server(ServerAbstract):
546
561
  if updated_agent:
547
562
  log.info(f"[Server launch] Updated agent {updated_agent.name}")
548
563
 
549
- import uvicorn
564
+ if start_uvicorn:
565
+ import uvicorn
550
566
 
551
- uvicorn.run(
552
- self.app,
553
- host=self.host,
554
- port=self.port,
555
- reload=self.reload,
556
- log_level=log_level,
557
- )
567
+ uvicorn.run(
568
+ self.app,
569
+ host=self.host,
570
+ port=self.port,
571
+ reload=self.reload,
572
+ log_level=log_level,
573
+ )
558
574
 
559
575
  def instructions(self) -> None:
560
576
  server_url = f"http://{self.host}:{self.port}"
File without changes
File without changes
File without changes