fred-oss 0.13.0__tar.gz → 0.15.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 (61) hide show
  1. {fred_oss-0.13.0/src/main/fred_oss.egg-info → fred_oss-0.15.0}/PKG-INFO +3 -1
  2. {fred_oss-0.13.0 → fred_oss-0.15.0}/requirements.txt +3 -1
  3. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/cli/main.py +5 -0
  4. fred_oss-0.15.0/src/main/fred/dao/__init__.py +11 -0
  5. fred_oss-0.15.0/src/main/fred/dao/service/_redis.py +25 -0
  6. fred_oss-0.15.0/src/main/fred/dao/service/catalog.py +22 -0
  7. fred_oss-0.15.0/src/main/fred/dao/service/interface.py +54 -0
  8. fred_oss-0.15.0/src/main/fred/dao/service/utils.py +37 -0
  9. fred_oss-0.15.0/src/main/fred/version +1 -0
  10. fred_oss-0.15.0/src/main/fred/worker/runner/plugins/__init__.py +0 -0
  11. fred_oss-0.15.0/src/main/fred/worker/runner/rest/__init__.py +0 -0
  12. fred_oss-0.15.0/src/main/fred/worker/runner/rest/cli_ext.py +32 -0
  13. fred_oss-0.15.0/src/main/fred/worker/runner/rest/routers/__init__.py +0 -0
  14. fred_oss-0.15.0/src/main/fred/worker/runner/rest/routers/_runner.py +40 -0
  15. fred_oss-0.15.0/src/main/fred/worker/runner/rest/routers/catalog.py +18 -0
  16. fred_oss-0.15.0/src/main/fred/worker/runner/rest/routers/interface.py +39 -0
  17. fred_oss-0.15.0/src/main/fred/worker/runner/rest/server.py +77 -0
  18. {fred_oss-0.13.0 → fred_oss-0.15.0/src/main/fred_oss.egg-info}/PKG-INFO +3 -1
  19. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred_oss.egg-info/SOURCES.txt +13 -0
  20. fred_oss-0.15.0/src/main/fred_oss.egg-info/requires.txt +5 -0
  21. fred_oss-0.13.0/src/main/fred/version +0 -1
  22. fred_oss-0.13.0/src/main/fred_oss.egg-info/requires.txt +0 -3
  23. {fred_oss-0.13.0 → fred_oss-0.15.0}/MANIFEST.in +0 -0
  24. {fred_oss-0.13.0 → fred_oss-0.15.0}/NOTICE.txt +0 -0
  25. {fred_oss-0.13.0 → fred_oss-0.15.0}/README.md +0 -0
  26. {fred_oss-0.13.0 → fred_oss-0.15.0}/setup.cfg +0 -0
  27. {fred_oss-0.13.0 → fred_oss-0.15.0}/setup.py +0 -0
  28. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/cli/__init__.py +0 -0
  29. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/cli/__main__.py +0 -0
  30. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/cli/interface.py +0 -0
  31. {fred_oss-0.13.0/src/main/fred/integrations/databricks/runtimes → fred_oss-0.15.0/src/main/fred/dao/service}/__init__.py +0 -0
  32. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/__init__.py +0 -0
  33. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/cli_ext.py +0 -0
  34. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/runtime.py +0 -0
  35. {fred_oss-0.13.0/src/main/fred/integrations/databricks/wrappers → fred_oss-0.15.0/src/main/fred/integrations/databricks/runtimes}/__init__.py +0 -0
  36. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/runtimes/scanner.py +0 -0
  37. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/runtimes/sync.py +0 -0
  38. {fred_oss-0.13.0/src/main/fred/utils → fred_oss-0.15.0/src/main/fred/integrations/databricks/wrappers}/__init__.py +0 -0
  39. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/databricks/wrappers/dbutils.py +0 -0
  40. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/runpod/__init__.py +0 -0
  41. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/runpod/cli_ext.py +0 -0
  42. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/integrations/runpod/helper.py +0 -0
  43. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/maturity.py +0 -0
  44. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/settings.py +0 -0
  45. {fred_oss-0.13.0/src/main/fred/worker/runner/plugins → fred_oss-0.15.0/src/main/fred/utils}/__init__.py +0 -0
  46. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/utils/dateops.py +0 -0
  47. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/utils/runtime.py +0 -0
  48. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/version.py +0 -0
  49. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/__init__.py +0 -0
  50. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/interface.py +0 -0
  51. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/__init__.py +0 -0
  52. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/client.py +0 -0
  53. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/handler.py +0 -0
  54. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/info.py +0 -0
  55. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/plugins/_local.py +0 -0
  56. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/plugins/catalog.py +0 -0
  57. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/plugins/interface.py +0 -0
  58. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred/worker/runner/utils.py +0 -0
  59. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred_oss.egg-info/dependency_links.txt +0 -0
  60. {fred_oss-0.13.0 → fred_oss-0.15.0}/src/main/fred_oss.egg-info/entry_points.txt +0 -0
  61. {fred_oss-0.13.0 → fred_oss-0.15.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.13.0
3
+ Version: 0.15.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -11,6 +11,8 @@ License-File: NOTICE.txt
11
11
  Requires-Dist: fire==0.7.1
12
12
  Requires-Dist: psutil==7.0.0
13
13
  Requires-Dist: redis==6.4.0
14
+ Requires-Dist: fastapi==0.116.2
15
+ Requires-Dist: uvicorn[standard]==0.35.0
14
16
  Dynamic: author
15
17
  Dynamic: author-email
16
18
  Dynamic: description
@@ -2,6 +2,8 @@
2
2
  fire==0.7.1
3
3
  # Minimal requirements
4
4
  psutil==7.0.0
5
- # Fred Workers Infra
5
+ # Fred Worker/Runner Infra
6
6
  redis==6.4.0
7
+ fastapi==0.116.2
8
+ uvicorn[standard]==0.35.0
7
9
  # Databricks Runtime: 16.4 LTS (Python 3.12.3)
@@ -18,6 +18,11 @@ class CLIExtensionGroups:
18
18
  def runpod(self):
19
19
  from fred.integrations.runpod.cli_ext import RunPodExt
20
20
  return RunPodExt()
21
+
22
+ @property
23
+ def runner_server(self):
24
+ from fred.worker.runner.rest.cli_ext import RunnerServerExt
25
+ return RunnerServerExt()
21
26
 
22
27
 
23
28
  class CLI(AbstractCLI, CLIExtensionGroups):
@@ -0,0 +1,11 @@
1
+ from fred.maturity import Maturity, MaturityLevel
2
+
3
+
4
+ module_maturity = Maturity(
5
+ level=MaturityLevel.ALPHA,
6
+ reference=__name__,
7
+ message=(
8
+ "Fred-DAO implementation is in early development "
9
+ "and therefore currently with incomplete and unstable features."
10
+ )
11
+ )
@@ -0,0 +1,25 @@
1
+ from redis import Redis, ConnectionPool
2
+
3
+ from fred.dao.service.utils import get_redis_configs_from_payload
4
+ from fred.dao.service.interface import ServiceConnectionPoolInterface, ServiceInterface
5
+
6
+
7
+ class RedisConnectionPool(ServiceConnectionPoolInterface[ConnectionPool]):
8
+
9
+ @classmethod
10
+ def _create_pool(cls, **kwargs) -> ConnectionPool:
11
+ configs = get_redis_configs_from_payload(payload=kwargs, keep=False)
12
+ return ConnectionPool(**configs)
13
+
14
+
15
+ class RedisService(ServiceInterface[Redis]):
16
+ instance: Redis
17
+
18
+ @classmethod
19
+ def _create_instance(cls, **kwargs) -> Redis:
20
+ return Redis(connection_pool=RedisConnectionPool.get_or_create_pool(**kwargs))
21
+
22
+ @classmethod
23
+ def auto(cls, **kwargs) -> "RedisService":
24
+ cls.instance = Redis(connection_pool=RedisConnectionPool.get_or_create_pool(**kwargs))
25
+ return cls(**kwargs)
@@ -0,0 +1,22 @@
1
+ import enum
2
+ from functools import lru_cache
3
+
4
+ from fred.dao.service.interface import ServiceInterface
5
+ from fred.dao.service._redis import RedisService
6
+
7
+
8
+ class ServiceCatalog(enum.Enum):
9
+ REDIS = RedisService
10
+
11
+ @classmethod
12
+ def from_classname(cls, classname: str) -> "ServiceCatalog":
13
+ for item in cls:
14
+ if item.value.__name__ == classname:
15
+ return item
16
+ raise ValueError(f"No service found for classname: {classname}")
17
+
18
+ def service_cls(self) -> type[ServiceInterface]:
19
+ return self.value
20
+
21
+ def auto(self, **kwargs) -> ServiceInterface:
22
+ return self.value.auto(**kwargs)
@@ -0,0 +1,54 @@
1
+ import uuid
2
+ import json
3
+ from functools import lru_cache
4
+ from typing import Generic, TypeVar
5
+
6
+ T = TypeVar("T")
7
+
8
+
9
+ class ServiceConnectionPoolInterface(Generic[T]):
10
+ pool_registry: dict[str, T] = {}
11
+
12
+ @classmethod
13
+ def get_pool_id(cls, **kwargs) -> str:
14
+ return str(uuid.uuid5(uuid.NAMESPACE_OID, json.dumps(kwargs, sort_keys=True)))
15
+
16
+ @classmethod
17
+ def _create_pool(cls, **kwargs) -> T:
18
+ raise NotImplementedError("This method should be implemented by subclasses.")
19
+
20
+ @classmethod
21
+ @lru_cache
22
+ def get_or_create_pool(cls, **kwargs) -> T:
23
+ pool_id = cls.get_pool_id(**kwargs)
24
+ pool = cls.pool_registry.get(pool_id)
25
+ if not pool:
26
+ pool = cls.pool_registry[pool_id] = cls._create_pool(**kwargs)
27
+ return pool
28
+
29
+
30
+ class ServiceInterface(Generic[T]):
31
+ instance: T
32
+
33
+ def __init__(self, **kwargs):
34
+ self.config = kwargs
35
+
36
+ @classmethod
37
+ def _create_instance(cls, **kwargs) -> T:
38
+ raise NotImplementedError("This method should be implemented by subclasses.")
39
+
40
+ @classmethod
41
+ def auto(cls, **kwargs) -> "ServiceInterface":
42
+ raise NotImplementedError("This method should be implemented by subclasses.")
43
+
44
+ @property
45
+ def client(self) -> T:
46
+ if not getattr(self, "instance", None):
47
+ self.instance = self._create_instance(**getattr(self, "config", {}))
48
+ return self.instance
49
+
50
+ def close(self):
51
+ # Close the instance if it has a close method.
52
+ # This method can be overridden by subclasses if needed.
53
+ if self.instance and hasattr(self.instance, "close") and callable(self.instance.close):
54
+ self.instance.close()
@@ -0,0 +1,37 @@
1
+ from fred.settings import get_environ_variable
2
+
3
+
4
+ def get_redis_configs_from_payload(
5
+ payload: dict,
6
+ keep: bool = False,
7
+ ) -> dict:
8
+ """Extract Redis configuration from the given payload dictionary.
9
+ This function looks for common Redis configuration keys in the payload
10
+ dictionary. If a key is not found, it falls back to environment variables.
11
+ Args:
12
+ payload (dict): The dictionary from which to extract Redis configuration.
13
+ keep (bool): If True, the original keys are retained in the payload. If False, they are removed.
14
+ Returns:
15
+ dict: A dictionary containing Redis configuration parameters.
16
+ """
17
+ host = port = password = db = None
18
+ for host_key in ["host", "redis_host"]:
19
+ if (host := payload.get(host_key) if keep else payload.pop(host_key, None)):
20
+ break
21
+ for port_key in ["port", "redis_port"]:
22
+ if (port := payload.get(port_key) if keep else payload.pop(port_key, None)):
23
+ break
24
+ for password_key in ["password", "redis_password"]:
25
+ if (password := payload.get(password_key) if keep else payload.pop(password_key, None)):
26
+ break
27
+ for db_key in ["db", "redis_db"]:
28
+ if (db := payload.get(db_key) if keep else payload.pop(db_key, None)):
29
+ break
30
+ return {
31
+ "host": host or get_environ_variable(name="REDIS_HOST", default="localhost"),
32
+ "port": int(port or get_environ_variable(name="REDIS_PORT", default=6379)),
33
+ "password": password or get_environ_variable(name="REDIS_PASSWORD", default=None),
34
+ "db": int(db or get_environ_variable(name="REDIS_DB", default=0)),
35
+ "decode_responses": True,
36
+ **(payload.get("redis_configs", {}) if keep else payload.pop("redis_configs", {})),
37
+ }
@@ -0,0 +1 @@
1
+ 0.15.0
@@ -0,0 +1,32 @@
1
+ from typing import Optional
2
+
3
+ from fred.cli.interface import IntegrationExtCLI
4
+ from fred.settings import logger_manager
5
+
6
+
7
+ logger = logger_manager.get_logger(name=__name__)
8
+
9
+
10
+ class RunnerServerExt(IntegrationExtCLI):
11
+
12
+ def start(
13
+ self,
14
+ include_routers: Optional[list[str]] = None,
15
+ exclude_routers: Optional[list[str]] = None,
16
+ fast_api_configs: Optional[dict] = None,
17
+ server_configs: Optional[dict] = None,
18
+ ):
19
+ from fred.worker.runner.rest.server import RunnerServer
20
+
21
+ include_routers = include_routers or []
22
+ exclude_routers = exclude_routers or []
23
+ fast_api_configs = fast_api_configs or {}
24
+ server_configs = server_configs or {}
25
+
26
+ logger.info("Starting REST server...")
27
+ server = RunnerServer.auto(
28
+ include_routers=include_routers,
29
+ exclude_routers=exclude_routers,
30
+ **fast_api_configs,
31
+ )
32
+ server.start(**server_configs)
@@ -0,0 +1,40 @@
1
+ from dataclasses import dataclass
2
+ from fred.worker.runner.rest.routers.interface import RouterInterface
3
+
4
+
5
+ @dataclass(frozen=True, slots=False)
6
+ class RunnerRouter(RouterInterface):
7
+
8
+ def __post_init__(self):
9
+ self.router.add_api_route(
10
+ "/handler_exists",
11
+ self.handler_exists,
12
+ methods=["GET"],
13
+ tags=["Runner"],
14
+ summary="Check if a handler class exists and is a RunnerHandler.",
15
+ response_description="Details about the handler class.",
16
+ )
17
+
18
+ def handler_exists(self, classname: str, classpath: str) -> dict:
19
+ from fred.worker.runner.handler import RunnerHandler
20
+ from fred.worker.interface import HandlerInterface
21
+
22
+ result_payload = {
23
+ "handler_classname": classname,
24
+ "handler_classpath": classpath,
25
+ "exists": False,
26
+ "is_runner_handler": False,
27
+ "metadata": {}
28
+ }
29
+
30
+ try:
31
+ handler = HandlerInterface.find_handler(
32
+ import_pattern=classpath,
33
+ handler_classname=classname,
34
+ )
35
+ result_payload["is_runner_handler"] = isinstance(handler, RunnerHandler)
36
+ result_payload["exists"] = True
37
+ return result_payload
38
+ except Exception as e:
39
+ result_payload["metadata"]["error"] = str(e)
40
+ return result_payload
@@ -0,0 +1,18 @@
1
+ import enum
2
+
3
+ from fred.worker.runner.rest.routers.interface import RouterInterface
4
+ from fred.worker.runner.rest.routers._runner import RunnerRouter
5
+
6
+
7
+ class RouterCatalog(enum.Enum):
8
+ EXAMPLE = RouterInterface.auto() # Default example router directly from the base interface
9
+ RUNNER = RunnerRouter.auto(
10
+ prefix="/runner",
11
+ tags=["Runner"],
12
+ )
13
+
14
+ def get_router_instance(self) -> RouterInterface:
15
+ return self.value.router
16
+
17
+ def get_router_configs(self) -> dict:
18
+ return self.value.router_configs
@@ -0,0 +1,39 @@
1
+ from dataclasses import dataclass
2
+ from typing import Optional
3
+
4
+ from fastapi import APIRouter
5
+
6
+
7
+ @dataclass(frozen=True, slots=False)
8
+ class RouterInterface:
9
+ router: APIRouter
10
+ router_configs: dict
11
+
12
+ @classmethod
13
+ def auto(
14
+ cls,
15
+ router: Optional[APIRouter] = None,
16
+ **kwargs,
17
+ ) -> "RouterInterface":
18
+ return cls(
19
+ router=router or APIRouter(),
20
+ router_configs=kwargs,
21
+ )
22
+
23
+ def __post_init__(self):
24
+ self.router.add_api_route(
25
+ "/ping",
26
+ self.ping,
27
+ methods=["GET"],
28
+ tags=["Health"],
29
+ summary="Ping the server to check if it's alive.",
30
+ response_description="A simple pong response.",
31
+ )
32
+
33
+ def ping(self, pong: Optional[str] = None) -> dict:
34
+ from fred.utils.dateops import datetime_utcnow
35
+
36
+ return {
37
+ "ping_time": datetime_utcnow().isoformat(),
38
+ "ping_response": pong or "pong",
39
+ }
@@ -0,0 +1,77 @@
1
+ from dataclasses import dataclass
2
+
3
+ from fastapi import FastAPI
4
+
5
+ from fred.settings import logger_manager, get_environ_variable
6
+ from fred.worker.runner.rest.routers.catalog import RouterCatalog
7
+
8
+ logger = logger_manager.get_logger(name=__name__)
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class RunnerServer:
13
+ app: FastAPI
14
+ include_routers: list[str]
15
+ exclude_routers: list[str]
16
+
17
+ @classmethod
18
+ def auto(cls, **kwargs) -> "RunnerServer":
19
+ # Include routers by checking on keyword argument or environment variable
20
+ include_routers = kwargs.pop("include_routers", None) or get_environ_variable(
21
+ "FRD_RUNNER_API_INCLUDE_ROUTERS",
22
+ default=""
23
+ )
24
+ if isinstance(include_routers, str):
25
+ include_routers = [
26
+ name.upper()
27
+ for router in include_routers.split(";")
28
+ if (name := router.strip())
29
+ ]
30
+ # Exclude routers by checking on keyword argument or environment variable
31
+ exclude_routers = kwargs.pop("exclude_routers", None) or get_environ_variable(
32
+ "FRD_RUNNER_API_EXCLUDE_ROUTERS",
33
+ default=""
34
+ )
35
+ if isinstance(exclude_routers, str):
36
+ exclude_routers = [
37
+ name.upper()
38
+ for router in exclude_routers.split(";")
39
+ if (name := router.strip())
40
+ ]
41
+ # Create FastAPI instance
42
+ app_instance = FastAPI(**kwargs)
43
+ return cls(
44
+ app=app_instance,
45
+ include_routers=include_routers,
46
+ exclude_routers=exclude_routers,
47
+ )
48
+
49
+ def __post_init__(self):
50
+ logger.info("Attempting to register routers...")
51
+ logger.info("Included routers candidates: %s", self.include_routers or "ALL")
52
+ logger.info("Excluded routers candidates: %s", self.exclude_routers or "NONE")
53
+ for router in RouterCatalog:
54
+ name = router.name.upper()
55
+ if self.include_routers and name not in self.include_routers:
56
+ logger.info(f"Skipping router '{name}' as it's not in the include list.")
57
+ continue
58
+ if self.exclude_routers and name in self.exclude_routers:
59
+ logger.info(f"Skipping router '{name}' as it's in the exclude list.")
60
+ continue
61
+ logger.info(f"Registering router '{name}'.")
62
+ self.app.include_router(
63
+ router.get_router_instance(),
64
+ **router.get_router_configs(),
65
+ )
66
+
67
+ def start(self, **kwargs):
68
+ import uvicorn
69
+
70
+ server_kwargs = {
71
+ "host": "localhost",
72
+ "port": 8000,
73
+ "log_level": "info",
74
+ **kwargs,
75
+ }
76
+
77
+ uvicorn.run(self.app, **server_kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fred-oss
3
- Version: 0.13.0
3
+ Version: 0.15.0
4
4
  Summary: FREDOSS
5
5
  Home-page: https://fred.fahera.mx
6
6
  Author: Fahera Research, Education, and Development
@@ -11,6 +11,8 @@ License-File: NOTICE.txt
11
11
  Requires-Dist: fire==0.7.1
12
12
  Requires-Dist: psutil==7.0.0
13
13
  Requires-Dist: redis==6.4.0
14
+ Requires-Dist: fastapi==0.116.2
15
+ Requires-Dist: uvicorn[standard]==0.35.0
14
16
  Dynamic: author
15
17
  Dynamic: author-email
16
18
  Dynamic: description
@@ -11,6 +11,12 @@ src/main/fred/cli/__init__.py
11
11
  src/main/fred/cli/__main__.py
12
12
  src/main/fred/cli/interface.py
13
13
  src/main/fred/cli/main.py
14
+ src/main/fred/dao/__init__.py
15
+ src/main/fred/dao/service/__init__.py
16
+ src/main/fred/dao/service/_redis.py
17
+ src/main/fred/dao/service/catalog.py
18
+ src/main/fred/dao/service/interface.py
19
+ src/main/fred/dao/service/utils.py
14
20
  src/main/fred/integrations/databricks/__init__.py
15
21
  src/main/fred/integrations/databricks/cli_ext.py
16
22
  src/main/fred/integrations/databricks/runtime.py
@@ -36,6 +42,13 @@ src/main/fred/worker/runner/plugins/__init__.py
36
42
  src/main/fred/worker/runner/plugins/_local.py
37
43
  src/main/fred/worker/runner/plugins/catalog.py
38
44
  src/main/fred/worker/runner/plugins/interface.py
45
+ src/main/fred/worker/runner/rest/__init__.py
46
+ src/main/fred/worker/runner/rest/cli_ext.py
47
+ src/main/fred/worker/runner/rest/server.py
48
+ src/main/fred/worker/runner/rest/routers/__init__.py
49
+ src/main/fred/worker/runner/rest/routers/_runner.py
50
+ src/main/fred/worker/runner/rest/routers/catalog.py
51
+ src/main/fred/worker/runner/rest/routers/interface.py
39
52
  src/main/fred_oss.egg-info/PKG-INFO
40
53
  src/main/fred_oss.egg-info/SOURCES.txt
41
54
  src/main/fred_oss.egg-info/dependency_links.txt
@@ -0,0 +1,5 @@
1
+ fire==0.7.1
2
+ psutil==7.0.0
3
+ redis==6.4.0
4
+ fastapi==0.116.2
5
+ uvicorn[standard]==0.35.0
@@ -1 +0,0 @@
1
- 0.13.0
@@ -1,3 +0,0 @@
1
- fire==0.7.1
2
- psutil==7.0.0
3
- redis==6.4.0
File without changes
File without changes
File without changes
File without changes
File without changes