cortexgrid 0.2.92__tar.gz → 0.2.93__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.
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cortexgrid
3
- Version: 0.2.92
3
+ Version: 0.2.93
4
4
  Summary: Connect your ML code to the RoboLab compute cluster — Ray, MLflow, and S3
5
5
  Project-URL: Homepage, https://github.com/robodatalab/cortexgrid
6
6
  Project-URL: Repository, https://github.com/robodatalab/cortexgrid
7
7
  Project-URL: Documentation, https://github.com/robodatalab/cortexgrid/blob/main/docs/cortexgrid/README.md
8
8
  License-Expression: Apache-2.0
9
9
  License-File: LICENSE
10
- Requires-Python: >=3.11
10
+ Requires-Python: <3.12,>=3.11
11
11
  Requires-Dist: boto3>=1.34
12
12
  Requires-Dist: cloudpickle>=3.0
13
13
  Requires-Dist: fabric>=3.2.3
@@ -3,7 +3,8 @@
3
3
  Ray Serve's REST `import_path` resolves to `cortexgrid._serve_entry:build`.
4
4
  On the cluster replica, `build` imports the serve-app class bundled at
5
5
  `save_model` time (its import path was stored as an MLflow tag), applies Ray's
6
- ingress with the app it was marked with by `cortexgrid.serve.ingress`, reads its
6
+ ingress with the app it was marked with by `cortexgrid.serve.ingress` (again on
7
+ each replica, see `_IngressOnReplica`), reads its
7
8
  `num_gpus`/`num_replicas` class attributes for actor placement, wraps it as a
8
9
  Ray Serve deployment, and binds it with the (family, suffix, run_name)
9
10
  identifiers.
@@ -31,6 +32,33 @@ from ray.serve.deployment import Application
31
32
  from cortexgrid.serve import ingress_app
32
33
 
33
34
 
35
+ # Requests one replica handles at once before Ray queues the rest.
36
+ _MAX_ONGOING_REQUESTS = 100
37
+
38
+ class _IngressOnReplica:
39
+ """Mixin that re-applies Ray's ingress to `_serve_app` in the replica's own
40
+ process, as Ray creates the replica instance.
41
+
42
+ Ray's ingress rewrites the signature of each route method, in place, so
43
+ FastAPI injects the replica instance as `self`. `build` applies it in the
44
+ build process only. The replica imports the serve-app's module afresh, and
45
+ its route methods carry no rewrite. FastAPI < 0.137 analysed routes once,
46
+ in the build process, and the replica received the result. FastAPI >= 0.137
47
+ analyses them in the replica on the first request, and without the rewrite
48
+ reads `self` as a required query parameter (HTTP 422).
49
+
50
+ Hooked on `__new__`, not `__init__`: Ray calls `__new__` alone, before the
51
+ serve-app's `__init__`, whether that is sync or async."""
52
+
53
+ _serve_app: type
54
+
55
+ def __new__(cls, *args: Any, **kwargs: Any) -> Any:
56
+ # Applied for its side effect on the route methods; the wrapper it
57
+ # returns is not needed.
58
+ serve.ingress(ingress_app(cls._serve_app))(cls._serve_app)
59
+ return super().__new__(cls)
60
+
61
+
34
62
  def build(args: dict[str, Any]) -> Application:
35
63
  module_name, class_name = args["class_import_path"].split(":")
36
64
  serve_app = getattr(importlib.import_module(module_name), class_name)
@@ -38,10 +66,18 @@ def build(args: dict[str, Any]) -> Application:
38
66
  # mark and are deployed as they are.
39
67
  app = ingress_app(serve_app)
40
68
  if app is not None:
41
- serve_app = serve.ingress(app)(serve_app)
69
+ on_replica = type(
70
+ serve_app.__name__,
71
+ (_IngressOnReplica, serve_app),
72
+ {"_serve_app": serve_app},
73
+ )
74
+ serve_app = serve.ingress(app)(on_replica)
42
75
  num_gpus = getattr(serve_app, "num_gpus", 0)
43
76
  num_replicas = getattr(serve_app, "num_replicas", 1)
44
77
  return serve.deployment(serve_app).options(
45
78
  num_replicas=num_replicas,
79
+ # Ray 2.32 lowered the default from 100 to 5; keep what serve-apps
80
+ # had on Ray 2.9.
81
+ max_ongoing_requests=_MAX_ONGOING_REQUESTS,
46
82
  ray_actor_options={"num_gpus": num_gpus},
47
83
  ).bind(args["family"], args["suffix"], args["run_name"])
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "cortexgrid"
3
- version = "0.2.92"
3
+ version = "0.2.93"
4
4
  description = "Connect your ML code to the RoboLab compute cluster — Ray, MLflow, and S3"
5
5
  readme = "docs/cortexgrid/README.md"
6
6
  license = "Apache-2.0"
7
7
  license-files = ["LICENSE"]
8
- requires-python = ">=3.11"
8
+ requires-python = ">=3.11,<3.12"
9
9
  dependencies = [
10
10
  "ray[default]>=2.9,<3",
11
11
  "mlflow>=3.11,<4",
File without changes
File without changes