fred-oss 0.32.0__tar.gz → 0.34.0__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 (92) hide show
  1. {fred_oss-0.32.0/src/main/fred_oss.egg-info → fred_oss-0.34.0}/PKG-INFO +1 -1
  2. fred_oss-0.34.0/src/main/fred/version +1 -0
  3. fred_oss-0.34.0/src/main/fred/worker/runner/rest/auth.py +22 -0
  4. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/routers/_runner.py +56 -2
  5. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/routers/interface.py +21 -1
  6. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/server.py +6 -1
  7. fred_oss-0.34.0/src/main/fred/worker/runner/rest/settings.py +12 -0
  8. {fred_oss-0.32.0 → fred_oss-0.34.0/src/main/fred_oss.egg-info}/PKG-INFO +1 -1
  9. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred_oss.egg-info/SOURCES.txt +2 -0
  10. fred_oss-0.32.0/src/main/fred/version +0 -1
  11. {fred_oss-0.32.0 → fred_oss-0.34.0}/MANIFEST.in +0 -0
  12. {fred_oss-0.32.0 → fred_oss-0.34.0}/NOTICE.txt +0 -0
  13. {fred_oss-0.32.0 → fred_oss-0.34.0}/README.md +0 -0
  14. {fred_oss-0.32.0 → fred_oss-0.34.0}/requirements.txt +0 -0
  15. {fred_oss-0.32.0 → fred_oss-0.34.0}/setup.cfg +0 -0
  16. {fred_oss-0.32.0 → fred_oss-0.34.0}/setup.py +0 -0
  17. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/cli/__init__.py +0 -0
  18. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/cli/__main__.py +0 -0
  19. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/cli/interface.py +0 -0
  20. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/cli/main.py +0 -0
  21. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/__init__.py +0 -0
  22. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/comp/__init__.py +0 -0
  23. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/comp/_keyval.py +0 -0
  24. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/comp/_queue.py +0 -0
  25. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/comp/catalog.py +0 -0
  26. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/comp/interface.py +0 -0
  27. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/__init__.py +0 -0
  28. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/_redis.py +0 -0
  29. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/_stdlib.py +0 -0
  30. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/catalog.py +0 -0
  31. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/interface.py +0 -0
  32. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/dao/service/utils.py +0 -0
  33. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/__init__.py +0 -0
  34. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/callback/__init__.py +0 -0
  35. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/callback/_function.py +0 -0
  36. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/callback/catalog.py +0 -0
  37. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/callback/interface.py +0 -0
  38. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/impl.py +0 -0
  39. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/result.py +0 -0
  40. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/settings.py +0 -0
  41. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/future/utils.py +0 -0
  42. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/__init__.py +0 -0
  43. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/cli_ext.py +0 -0
  44. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/runtime.py +0 -0
  45. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/runtimes/__init__.py +0 -0
  46. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/runtimes/scanner.py +0 -0
  47. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/runtimes/sync.py +0 -0
  48. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/wrappers/__init__.py +0 -0
  49. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/databricks/wrappers/dbutils.py +0 -0
  50. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/runpod/__init__.py +0 -0
  51. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/runpod/cli_ext.py +0 -0
  52. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/integrations/runpod/helper.py +0 -0
  53. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/maturity.py +0 -0
  54. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/monad/__init__.py +0 -0
  55. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/monad/_either.py +0 -0
  56. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/monad/catalog.py +0 -0
  57. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/monad/interface.py +0 -0
  58. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/settings.py +0 -0
  59. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/utils/__init__.py +0 -0
  60. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/utils/dateops.py +0 -0
  61. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/utils/runtime.py +0 -0
  62. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/version.py +0 -0
  63. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/__init__.py +0 -0
  64. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/interface.py +0 -0
  65. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/__init__.py +0 -0
  66. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/backend.py +0 -0
  67. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/client.py +0 -0
  68. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/handler.py +0 -0
  69. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/info.py +0 -0
  70. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/__init__.py +0 -0
  71. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/_handler.py +0 -0
  72. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/_item.py +0 -0
  73. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/_request.py +0 -0
  74. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/_runner_spec.py +0 -0
  75. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/catalog.py +0 -0
  76. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/model/interface.py +0 -0
  77. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/plugins/__init__.py +0 -0
  78. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/plugins/_local.py +0 -0
  79. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/plugins/catalog.py +0 -0
  80. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/plugins/interface.py +0 -0
  81. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/__init__.py +0 -0
  82. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/cli_ext.py +0 -0
  83. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/routers/__init__.py +0 -0
  84. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/rest/routers/catalog.py +0 -0
  85. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/settings.py +0 -0
  86. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/signal.py +0 -0
  87. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/status.py +0 -0
  88. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred/worker/runner/utils.py +0 -0
  89. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred_oss.egg-info/dependency_links.txt +0 -0
  90. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred_oss.egg-info/entry_points.txt +0 -0
  91. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred_oss.egg-info/requires.txt +0 -0
  92. {fred_oss-0.32.0 → fred_oss-0.34.0}/src/main/fred_oss.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fred-oss
3
- Version: 0.32.0
3
+ Version: 0.34.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -0,0 +1 @@
1
+ 0.34.0
@@ -0,0 +1,22 @@
1
+ from fastapi import Security, HTTPException, status
2
+ from fastapi.security import APIKeyHeader
3
+
4
+ from fred.worker.runner.rest.settings import FRD_RESTAPI_TOKEN
5
+
6
+ async def verify_key(
7
+ api_key_header: str = Security(
8
+ APIKeyHeader(
9
+ name="X-API-Key",
10
+ auto_error=False
11
+ )
12
+ ),
13
+ ):
14
+ """
15
+ Verify the provided API key against the expected token.
16
+ Raises an HTTPException if the key is invalid or missing.
17
+ """
18
+ if api_key_header != FRD_RESTAPI_TOKEN:
19
+ raise HTTPException(
20
+ status_code=status.HTTP_401_UNAUTHORIZED,
21
+ detail="Invalid or missing API Key",
22
+ )
@@ -1,7 +1,11 @@
1
1
  from dataclasses import dataclass
2
2
 
3
+ from fred.settings import logger_manager
4
+ from fred.utils.dateops import datetime_utcnow
3
5
  from fred.worker.runner.rest.routers.interface import RouterInterface
4
6
 
7
+ logger = logger_manager.get_logger(name=__name__)
8
+
5
9
 
6
10
  class RunnerRouterMethods:
7
11
 
@@ -28,7 +32,20 @@ class RunnerRouterMethods:
28
32
  except Exception as e:
29
33
  result_payload["metadata"]["error"] = str(e)
30
34
  return result_payload
31
-
35
+
36
+ def qlen(self, queue_slug: str) -> dict:
37
+
38
+ snapshot_at = datetime_utcnow().isoformat()
39
+ req_queue = self.runner_backend.queue(f"req:{queue_slug}")
40
+ res_queue = self.runner_backend.queue(f"res:{queue_slug}")
41
+
42
+ return {
43
+ "snapshot_at": snapshot_at,
44
+ "queue_slug": queue_slug,
45
+ "req": req_queue.size(),
46
+ "res": res_queue.size(),
47
+ }
48
+
32
49
  def runner_start(self, payload: dict) -> dict:
33
50
  from fred.worker.runner.model.catalog import RunnerModelCatalog
34
51
  from fred.worker.runner.plugins.catalog import PluginCatalog
@@ -44,10 +61,31 @@ class RunnerRouterMethods:
44
61
  "runner_id": plugin.execute(runner_spec, wait_for_exec=wait_for_exec).runner_id,
45
62
  "queue_slug": runner_spec.queue_slug,
46
63
  }
64
+
65
+ def runner_execute(self, payload: dict) -> dict:
66
+ from fred.worker.runner.model.catalog import RunnerModelCatalog
67
+
68
+ request_id = payload.pop("request_id", None)
69
+ queue_slug = payload.pop("queue_slug", None) or (
70
+ logger.error("No 'queue_slug' value provided; defaulting to 'demo'.")
71
+ or "demo"
72
+ )
73
+
74
+ item = RunnerModelCatalog.ITEM.value.uuid(payload=payload, uuid_hash=False)
75
+ request = item.as_request(use_hash=False, request_id=request_id)
76
+ request.dispatch(
77
+ request_queue=self.runner_backend.queue(f"req:{queue_slug}")
78
+ )
79
+ return {
80
+ "item_id": item.item_id,
81
+ "request_id": request.request_id,
82
+ "queue_slug": queue_slug,
83
+ "dispatched_at": datetime_utcnow().isoformat(),
84
+ }
47
85
 
48
86
 
49
87
  @dataclass(frozen=True, slots=False)
50
- class RunnerRouter(RouterInterface, RunnerRouterMethods):
88
+ class RunnerRouter(RouterInterface.with_backend(), RunnerRouterMethods):
51
89
 
52
90
  def __post_init__(self):
53
91
  self.router.add_api_route(
@@ -58,6 +96,14 @@ class RunnerRouter(RouterInterface, RunnerRouterMethods):
58
96
  summary="Check if a handler class exists and is a RunnerHandler.",
59
97
  response_description="Details about the handler class.",
60
98
  )
99
+ self.router.add_api_route(
100
+ "/qlen/{queue_slug}",
101
+ self.qlen,
102
+ methods=["GET"],
103
+ tags=["Runner"],
104
+ summary="Get the length of the request and response queues for a given queue slug.",
105
+ response_description="The lengths of the request and response queues.",
106
+ )
61
107
  self.router.add_api_route(
62
108
  "/start",
63
109
  self.runner_start,
@@ -66,3 +112,11 @@ class RunnerRouter(RouterInterface, RunnerRouterMethods):
66
112
  summary="Start a runner using the specified plugin.",
67
113
  response_description="The ID of the started runner.",
68
114
  )
115
+ self.router.add_api_route(
116
+ "/execute",
117
+ self.runner_execute,
118
+ methods=["POST"],
119
+ tags=["Runner"],
120
+ summary="Execute a task by dispatching a request to the specified queue.",
121
+ response_description="Details about the dispatched request.",
122
+ )
@@ -1,11 +1,31 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Optional
3
3
 
4
+ from fred.worker.runner.backend import RunnerBackend
5
+ from fred.worker.runner.settings import FRD_RUNNER_BACKEND
6
+
4
7
  from fastapi import APIRouter
5
8
 
6
9
 
10
+ class RouterInterfaceBackendMixin:
11
+ """Base class for router interfaces that require a backend service."""
12
+ runner_backend: RunnerBackend
13
+
14
+ @classmethod
15
+ def with_backend(cls, service_name: Optional[str] = None, **kwargs) -> type["RouterInterfaceBackendMixin"]:
16
+ # Avoid re-initializing if already set
17
+ if getattr(cls, "runner_backend", None):
18
+ return cls
19
+ # Initialize the backend once and assign to the class attribute
20
+ cls.runner_backend = RunnerBackend.auto(
21
+ service_name=service_name or FRD_RUNNER_BACKEND,
22
+ **kwargs,
23
+ )
24
+ return cls
25
+
26
+
7
27
  @dataclass(frozen=True, slots=False)
8
- class RouterInterface:
28
+ class RouterInterface(RouterInterfaceBackendMixin):
9
29
  router: APIRouter
10
30
  router_configs: dict
11
31
 
@@ -1,9 +1,11 @@
1
1
  from dataclasses import dataclass
2
2
 
3
- from fastapi import FastAPI
3
+ from fastapi import FastAPI, Depends
4
4
 
5
5
  from fred.settings import logger_manager, get_environ_variable
6
+ from fred.worker.runner.rest.settings import FRD_RESTAPI_TOKEN
6
7
  from fred.worker.runner.rest.routers.catalog import RouterCatalog
8
+ from fred.worker.runner.rest.auth import verify_key
7
9
 
8
10
  logger = logger_manager.get_logger(name=__name__)
9
11
 
@@ -39,6 +41,9 @@ class RunnerServer:
39
41
  if (name := router.strip())
40
42
  ]
41
43
  # Create FastAPI instance
44
+ kwargs["dependencies"] = kwargs.get("dependencies", []) + [
45
+ Depends(verify_key),
46
+ ]
42
47
  app_instance = FastAPI(**kwargs)
43
48
  return cls(
44
49
  app=app_instance,
@@ -0,0 +1,12 @@
1
+ from fred.settings import get_environ_variable, logger_manager
2
+
3
+ logger = logger_manager.get_logger(name=__name__)
4
+
5
+
6
+ FRD_RESTAPI_TOKEN = get_environ_variable(
7
+ "FRD_RESTAPI_TOKEN",
8
+ default=None
9
+ )
10
+ if not FRD_RESTAPI_TOKEN:
11
+ logger.warning("FRD_RESTAPI_TOKEN not found in environment; using default token 'changeme'.")
12
+ FRD_RESTAPI_TOKEN = "changeme"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fred-oss
3
- Version: 0.32.0
3
+ Version: 0.34.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -73,8 +73,10 @@ src/main/fred/worker/runner/plugins/_local.py
73
73
  src/main/fred/worker/runner/plugins/catalog.py
74
74
  src/main/fred/worker/runner/plugins/interface.py
75
75
  src/main/fred/worker/runner/rest/__init__.py
76
+ src/main/fred/worker/runner/rest/auth.py
76
77
  src/main/fred/worker/runner/rest/cli_ext.py
77
78
  src/main/fred/worker/runner/rest/server.py
79
+ src/main/fred/worker/runner/rest/settings.py
78
80
  src/main/fred/worker/runner/rest/routers/__init__.py
79
81
  src/main/fred/worker/runner/rest/routers/_runner.py
80
82
  src/main/fred/worker/runner/rest/routers/catalog.py
@@ -1 +0,0 @@
1
- 0.32.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes