luminarycloud 0.20.0__py3-none-any.whl → 0.22.0__py3-none-any.whl

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 (95) hide show
  1. luminarycloud/__init__.py +5 -1
  2. luminarycloud/_client/client.py +5 -0
  3. luminarycloud/_client/http_client.py +10 -8
  4. luminarycloud/_feature_flag.py +22 -0
  5. luminarycloud/_helpers/_create_simulation.py +7 -2
  6. luminarycloud/_helpers/_upload_mesh.py +1 -0
  7. luminarycloud/_helpers/download.py +3 -1
  8. luminarycloud/_helpers/pagination.py +62 -0
  9. luminarycloud/_helpers/proto_decorator.py +13 -5
  10. luminarycloud/_helpers/upload.py +18 -12
  11. luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2.py +55 -0
  12. luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2.pyi +52 -0
  13. luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2_grpc.py +72 -0
  14. luminarycloud/_proto/api/v0/luminarycloud/feature_flag/feature_flag_pb2_grpc.pyi +35 -0
  15. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +168 -124
  16. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +133 -4
  17. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +66 -0
  18. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +20 -0
  19. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +8 -8
  20. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +5 -5
  21. luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.py +74 -73
  22. luminarycloud/_proto/api/v0/luminarycloud/mesh/mesh_pb2.pyi +17 -3
  23. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +33 -20
  24. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +21 -1
  25. luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.py +16 -16
  26. luminarycloud/_proto/api/v0/luminarycloud/project/project_pb2.pyi +7 -3
  27. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +97 -61
  28. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +72 -3
  29. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +34 -0
  30. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +12 -0
  31. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.py +33 -31
  32. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.pyi +23 -2
  33. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +68 -19
  34. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +98 -0
  35. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.py +33 -0
  36. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.pyi +10 -0
  37. luminarycloud/_proto/assistant/assistant_pb2.py +74 -41
  38. luminarycloud/_proto/assistant/assistant_pb2.pyi +64 -2
  39. luminarycloud/_proto/assistant/assistant_pb2_grpc.py +33 -0
  40. luminarycloud/_proto/assistant/assistant_pb2_grpc.pyi +10 -0
  41. luminarycloud/_proto/base/base_pb2.py +20 -7
  42. luminarycloud/_proto/base/base_pb2.pyi +38 -0
  43. luminarycloud/_proto/cad/shape_pb2.py +39 -19
  44. luminarycloud/_proto/cad/shape_pb2.pyi +86 -34
  45. luminarycloud/_proto/cad/transformation_pb2.py +60 -16
  46. luminarycloud/_proto/cad/transformation_pb2.pyi +138 -32
  47. luminarycloud/_proto/client/simulation_pb2.py +490 -348
  48. luminarycloud/_proto/client/simulation_pb2.pyi +570 -8
  49. luminarycloud/_proto/geometry/geometry_pb2.py +77 -63
  50. luminarycloud/_proto/geometry/geometry_pb2.pyi +42 -3
  51. luminarycloud/_proto/hexmesh/hexmesh_pb2.py +24 -18
  52. luminarycloud/_proto/hexmesh/hexmesh_pb2.pyi +23 -2
  53. luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +10 -10
  54. luminarycloud/_proto/inferenceservice/inferenceservice_pb2.pyi +5 -5
  55. luminarycloud/_proto/quantity/quantity_options_pb2.py +6 -6
  56. luminarycloud/_proto/quantity/quantity_options_pb2.pyi +10 -1
  57. luminarycloud/_proto/quantity/quantity_pb2.py +176 -167
  58. luminarycloud/_proto/quantity/quantity_pb2.pyi +11 -5
  59. luminarycloud/enum/__init__.py +1 -0
  60. luminarycloud/enum/gpu_type.py +2 -0
  61. luminarycloud/enum/quantity_type.py +9 -0
  62. luminarycloud/enum/vis_enums.py +23 -3
  63. luminarycloud/feature_modification.py +45 -35
  64. luminarycloud/geometry.py +104 -8
  65. luminarycloud/geometry_version.py +57 -3
  66. luminarycloud/meshing/mesh_generation_params.py +8 -8
  67. luminarycloud/params/enum/_enum_wrappers.py +537 -30
  68. luminarycloud/params/simulation/adaptive_mesh_refinement_.py +4 -0
  69. luminarycloud/params/simulation/physics/__init__.py +0 -1
  70. luminarycloud/params/simulation/physics/periodic_pair_.py +12 -31
  71. luminarycloud/physics_ai/architectures.py +5 -5
  72. luminarycloud/physics_ai/inference.py +13 -13
  73. luminarycloud/physics_ai/solution.py +3 -1
  74. luminarycloud/pipelines/__init__.py +11 -3
  75. luminarycloud/pipelines/api.py +240 -4
  76. luminarycloud/pipelines/arguments.py +15 -0
  77. luminarycloud/pipelines/core.py +113 -96
  78. luminarycloud/pipelines/{operators.py → stages.py} +96 -39
  79. luminarycloud/project.py +15 -47
  80. luminarycloud/simulation.py +66 -3
  81. luminarycloud/simulation_param.py +0 -9
  82. luminarycloud/types/matrix3.py +12 -0
  83. luminarycloud/vis/__init__.py +2 -0
  84. luminarycloud/vis/interactive_report.py +79 -93
  85. luminarycloud/vis/report.py +219 -65
  86. luminarycloud/vis/visualization.py +60 -0
  87. luminarycloud/volume_selection.py +132 -69
  88. {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/METADATA +1 -1
  89. {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/RECORD +90 -89
  90. luminarycloud/params/simulation/physics/periodic_pair/__init__.py +0 -2
  91. luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/__init__.py +0 -2
  92. luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/rotational_periodicity_.py +0 -31
  93. luminarycloud/params/simulation/physics/periodic_pair/periodicity_type/translational_periodicity_.py +0 -29
  94. luminarycloud/params/simulation/physics/periodic_pair/periodicity_type_.py +0 -25
  95. {luminarycloud-0.20.0.dist-info → luminarycloud-0.22.0.dist-info}/WHEEL +0 -0
luminarycloud/__init__.py CHANGED
@@ -13,18 +13,22 @@ from . import (
13
13
  types as types,
14
14
  vis as vis,
15
15
  )
16
-
17
16
  from ._client import (
18
17
  Client as Client,
19
18
  get_default_client as get_default_client,
20
19
  set_default_client as set_default_client,
21
20
  )
21
+ from ._feature_flag import (
22
+ _get_feature_flags as _get_feature_flags,
23
+ )
22
24
  from .geometry import (
23
25
  get_geometry as get_geometry,
24
26
  Geometry as Geometry,
25
27
  )
26
28
  from .geometry_version import (
27
29
  GeometryVersion as GeometryVersion,
30
+ get_geometry_version as get_geometry_version,
31
+ update_geometry_version as update_geometry_version,
28
32
  )
29
33
  from .mesh import (
30
34
  get_mesh as get_mesh,
@@ -44,6 +44,9 @@ from .._proto.api.v0.luminarycloud.project_ui_state.project_ui_state_pb2_grpc im
44
44
  from .._proto.api.v0.luminarycloud.solution.solution_pb2_grpc import SolutionServiceStub
45
45
  from .._proto.api.v0.luminarycloud.upload.upload_pb2_grpc import UploadServiceStub
46
46
  from .._proto.api.v0.luminarycloud.vis.vis_pb2_grpc import VisAPIServiceStub
47
+ from .._proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2_grpc import (
48
+ FeatureFlagServiceStub,
49
+ )
47
50
  from .authentication_plugin import AuthenticationPlugin
48
51
  from .config import LC_DOMAIN, LC_API_KEY
49
52
  from .logging_interceptor import LoggingInterceptor
@@ -71,6 +74,7 @@ class Client(
71
74
  InferenceServiceStub,
72
75
  OnshapeServiceStub,
73
76
  ProjectUIStateServiceStub,
77
+ FeatureFlagServiceStub,
74
78
  ):
75
79
  """
76
80
  Creates a Luminary API client.
@@ -248,6 +252,7 @@ class Client(
248
252
  NamedVariableSetServiceStub.__init__(self, self._channel)
249
253
  OnshapeServiceStub.__init__(self, self._channel)
250
254
  ProjectUIStateServiceStub.__init__(self, self._channel)
255
+ FeatureFlagServiceStub.__init__(self, self._channel)
251
256
  for name, value in self.__dict__.items():
252
257
  if isinstance(value, grpc.UnaryUnaryMultiCallable):
253
258
  setattr(self, name, rpc_error(value))
@@ -113,9 +113,11 @@ class HttpClient:
113
113
  f"Bearer {self.auth0_client.fetch_access_token()}"
114
114
  )
115
115
 
116
- def _request(self, method: str, path: str, **kwargs) -> requests.Response:
116
+ # This method, which takes a full URL instead of just a path, is made public so the upload
117
+ # helper can use it to make authenticated requests to a gcsproxy endpoint which is hosted by
118
+ # jobmaster, not apiserver
119
+ def raw_request(self, method: str, url: str, **kwargs) -> requests.Response:
117
120
  self._authenticate_session()
118
- url = self._url(path)
119
121
  self._log_request(method, url, kwargs)
120
122
  resp = self.session.request(method, url, timeout=self.timeout, **kwargs)
121
123
  self._log_response(resp)
@@ -128,22 +130,22 @@ class HttpClient:
128
130
 
129
131
  # ---- Raw methods ----
130
132
  def raw_get(self, path: str, **kwargs) -> requests.Response:
131
- return self._request("GET", path, **kwargs)
133
+ return self.raw_request("GET", self._url(path), **kwargs)
132
134
 
133
135
  def raw_post(self, path: str, body: dict | None = None, **kwargs) -> requests.Response:
134
- return self._request("POST", path, json=body, **kwargs)
136
+ return self.raw_request("POST", self._url(path), json=body, **kwargs)
135
137
 
136
138
  def raw_put(self, path: str, body: dict | None = None, **kwargs) -> requests.Response:
137
- return self._request("PUT", path, json=body, **kwargs)
139
+ return self.raw_request("PUT", self._url(path), json=body, **kwargs)
138
140
 
139
141
  def raw_patch(self, path: str, body: dict | None = None, **kwargs) -> requests.Response:
140
- return self._request("PATCH", path, json=body, **kwargs)
142
+ return self.raw_request("PATCH", self._url(path), json=body, **kwargs)
141
143
 
142
144
  def raw_delete(self, path: str, **kwargs) -> requests.Response:
143
- return self._request("DELETE", path, **kwargs)
145
+ return self.raw_request("DELETE", self._url(path), **kwargs)
144
146
 
145
147
  def raw_head(self, path: str, **kwargs) -> requests.Response:
146
- return self._request("HEAD", path, **kwargs)
148
+ return self.raw_request("HEAD", self._url(path), **kwargs)
147
149
 
148
150
  # ---- JSON convenience methods ----
149
151
  def get(self, path: str, **kwargs) -> dict:
@@ -0,0 +1,22 @@
1
+ # Copyright 2023-2025 Luminary Cloud, Inc. All Rights Reserved.
2
+ from google.protobuf import empty_pb2
3
+
4
+ from ._proto.api.v0.luminarycloud.feature_flag import feature_flag_pb2
5
+ from ._client import get_default_client
6
+
7
+
8
+ def _get_feature_flags() -> dict[int, str]:
9
+ """Get enabled feature flags for the authenticated user.
10
+
11
+ Feature flags are used to control access to experimental and internal features.
12
+ Each flag is identified by an experiment ID and a feature flag name.
13
+
14
+ Returns
15
+ -------
16
+ dict[int, str]
17
+ A dictionary mapping experiment IDs (uint64) to feature flag names.
18
+ Returns an empty dictionary if no feature flags are enabled for the user.
19
+ """
20
+ req = empty_pb2.Empty()
21
+ res = get_default_client().GetFeatureFlags(req)
22
+ return dict(res.enabled_feature_flags)
@@ -7,6 +7,9 @@ from .._proto.api.v0.luminarycloud.simulation.simulation_pb2 import (
7
7
  SimulationOptions,
8
8
  CreateSimulationRequest,
9
9
  )
10
+ from .._proto.api.v0.luminarycloud.simulation_template.simulation_template_pb2 import (
11
+ SimulationTemplate,
12
+ )
10
13
  from .._client import Client
11
14
  from ..enum import GPUType
12
15
 
@@ -18,8 +21,9 @@ def create_simulation(
18
21
  project_id: str,
19
22
  mesh_id: str,
20
23
  name: str,
21
- simulation_template_id: str,
24
+ simulation_template_id: Optional[str] = None,
22
25
  *,
26
+ simulation_template: Optional[SimulationTemplate] = None,
23
27
  named_variable_set_version_id: Optional[str] = None,
24
28
  description: str = "",
25
29
  batch_processing: bool = True,
@@ -32,7 +36,8 @@ def create_simulation(
32
36
  CreateSimulationRequest(
33
37
  project_id=project_id,
34
38
  mesh_id=mesh_id,
35
- simulation_template_id=simulation_template_id,
39
+ simulation_template_id=simulation_template_id or "",
40
+ simulation_template=simulation_template,
36
41
  named_variable_set_version_id=named_variable_set_version_id or "",
37
42
  name=name,
38
43
  description=description,
@@ -137,6 +137,7 @@ def _upload_mesh_from_path(
137
137
  logger.debug(f"started upload")
138
138
 
139
139
  gcs_resumable_upload(
140
+ client=client,
140
141
  filepath=pathlib.Path(filepath),
141
142
  signed_url=start_res.upload.gcs_resumable.signed_url,
142
143
  http_headers=start_res.upload.gcs_resumable.http_headers,
@@ -4,7 +4,7 @@ import logging
4
4
  import os
5
5
  from pathlib import Path
6
6
  import requests
7
- from typing import Any, Iterator, Optional, Union, cast, List
7
+ from typing import Any, Iterator, Optional, Union, cast, List, Dict
8
8
 
9
9
  from .file_chunk_stream import FileChunkStream
10
10
  from .._proto.api.v0.luminarycloud.common import common_pb2 as commonpb
@@ -139,6 +139,7 @@ def download_solution_physics_ai(
139
139
  volume_fields_to_keep: Optional[List[QuantityType]] = None,
140
140
  process_volume: bool = False,
141
141
  single_precision: bool = False,
142
+ internal_options: Optional[Dict[str, str]] = None,
142
143
  ) -> Optional[FileChunkStream]:
143
144
  """
144
145
  Returns the download as a file-like object, or None if destination_url is provided.
@@ -184,6 +185,7 @@ def download_solution_physics_ai(
184
185
  ),
185
186
  process_volume=process_volume,
186
187
  single_precision=single_precision,
188
+ internal_options=internal_options or {},
187
189
  )
188
190
  response = client.GetSolutionDataPhysicsAI(request)
189
191
 
@@ -0,0 +1,62 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Generic, Optional, TypeVar
3
+
4
+ from .._client import get_default_client
5
+
6
+ T = TypeVar("T")
7
+
8
+
9
+ class PaginationIterator(ABC, Generic[T]):
10
+ """Generic iterator class that provides length hint for paginated results."""
11
+
12
+ @abstractmethod
13
+ def _fetch_page(self, page_size: int, page_token: str) -> tuple[list[T], str, int]:
14
+ """
15
+ Fetch a page of results from the server. Must return a tuple of the list of results, the
16
+ next page token, and the total count of results.
17
+ """
18
+ pass
19
+
20
+ def __init__(self, page_size: int):
21
+ self._page_size: int = page_size
22
+ self._page_token: str = ""
23
+ self._total_count: Optional[int] = None
24
+ self._current_page: Optional[list[T]] = None
25
+ self._client = get_default_client()
26
+ self._iterated_count: int = 0
27
+
28
+ def __iter__(self) -> "PaginationIterator[T]":
29
+ return self
30
+
31
+ def __next__(self) -> T:
32
+ if self._current_page is None:
33
+ self._fetch_next_page()
34
+
35
+ # _current_page really can't be None here, but this assertion is needed to appease mypy
36
+ assert self._current_page is not None
37
+
38
+ if len(self._current_page) == 0:
39
+ if not self._page_token:
40
+ raise StopIteration
41
+ self._fetch_next_page()
42
+
43
+ self._iterated_count += 1
44
+
45
+ return self._current_page.pop(0)
46
+
47
+ def _fetch_next_page(self) -> None:
48
+ items, next_page_token, total_count = self._fetch_page(self._page_size, self._page_token)
49
+
50
+ self._current_page = items
51
+ self._page_token = next_page_token
52
+
53
+ # Set length hint on first fetch if available
54
+ if self._total_count is None:
55
+ self._total_count = total_count
56
+
57
+ def __length_hint__(self) -> int:
58
+ if self._total_count is None:
59
+ # Fetch first page to get total size if not already fetched
60
+ if self._current_page is None:
61
+ self._fetch_next_page()
62
+ return max(0, (self._total_count or 0) - self._iterated_count)
@@ -9,6 +9,9 @@ from typing import (
9
9
  from google.protobuf.message import Message
10
10
 
11
11
  from luminarycloud.types import Vector3
12
+ from luminarycloud.types.adfloat import _to_ad_proto
13
+ from luminarycloud.types.vector3 import _to_vector3_ad_proto
14
+ from .._proto.base.base_pb2 import AdFloatType, AdVector3
12
15
 
13
16
  P = TypeVar("P", bound=Message)
14
17
  C = TypeVar("C")
@@ -36,11 +39,16 @@ class proto_decorator(Generic[P]):
36
39
  _type = type_hints.get(field.name, None)
37
40
  if _type:
38
41
  value = getattr(self, field.name)
39
- if issubclass(_type, Vector3):
40
- vector_proto = getattr(proto, field.name)
41
- vector_proto.x = value.x
42
- vector_proto.y = value.y
43
- vector_proto.z = value.z
42
+ proto_value = getattr(proto, field.name)
43
+ if issubclass(_type, float) and isinstance(proto_value, AdFloatType):
44
+ proto_value.CopyFrom(_to_ad_proto(value))
45
+ elif issubclass(_type, Vector3):
46
+ if isinstance(proto_value, AdVector3):
47
+ proto_value.CopyFrom(_to_vector3_ad_proto((value.x, value.y, value.z)))
48
+ else:
49
+ proto_value.x = value.x
50
+ proto_value.y = value.y
51
+ proto_value.z = value.z
44
52
  else:
45
53
  setattr(proto, field.name, value)
46
54
  return proto
@@ -3,6 +3,7 @@ from os import PathLike
3
3
  import os
4
4
  import pathlib
5
5
  from typing import Mapping
6
+ from urllib.parse import urlparse
6
7
  import requests
7
8
  import logging
8
9
  import grpc
@@ -15,7 +16,7 @@ logger = logging.getLogger(__name__)
15
16
 
16
17
 
17
18
  def gcs_resumable_upload(
18
- filepath: PathLike | str, signed_url: str, http_headers: Mapping[str, str]
19
+ client: Client, filepath: PathLike | str, signed_url: str, http_headers: Mapping[str, str]
19
20
  ) -> None:
20
21
  """
21
22
  Performs a resumable upload to a GCS signed url.
@@ -24,12 +25,17 @@ def gcs_resumable_upload(
24
25
  """
25
26
 
26
27
  # initiate the upload
28
+ parsed_url = urlparse(signed_url)
27
29
  try:
28
- post_res = requests.post(
29
- url=signed_url,
30
- headers=http_headers,
31
- json={}, # intentionally empty, we're not uploading the file data yet
32
- )
30
+ if parsed_url.hostname and parsed_url.hostname.endswith(".luminarycloud.com"):
31
+ # we must be using the gcsproxy, so we'll use the `client.http` client to authenticate
32
+ # with our backend
33
+ logger.debug("signed url points to LC backend, will use authenticated client")
34
+ post_res = client.http.raw_request("POST", signed_url, headers=http_headers)
35
+ else:
36
+ # we're using the GCS signed url directly, no additional authentication is needed
37
+ logger.debug("signed url points to GCS, will use unauthenticated client")
38
+ post_res = requests.post(url=signed_url, headers=http_headers)
33
39
  logger.debug(
34
40
  f"sucessfully initialized signed URL upload for {filepath}, POST status code: {post_res.status_code}"
35
41
  )
@@ -49,6 +55,8 @@ def gcs_resumable_upload(
49
55
  session_uri = post_res.headers["Location"]
50
56
  size = os.path.getsize(filepath)
51
57
  with open(filepath, "rb") as fp:
58
+ # even if a signed url upload is initiated via the gcsproxy, the subsequent PUT request
59
+ # goes straight to GCS, so we don't want to use the authenticated client here
52
60
  put_res = requests.put(
53
61
  url=session_uri,
54
62
  headers={
@@ -57,14 +65,11 @@ def gcs_resumable_upload(
57
65
  data=fp.read(size),
58
66
  )
59
67
  logger.debug(f"sucessfully uploaded {filepath}, PUT status code: {put_res.status_code}")
60
- except:
68
+ except Exception as e:
61
69
  # don't log the session_uri, just to be safe
62
- msg = (
63
- f"failed to upload {filepath}, PUT status code: {put_res.status_code}, content: "
64
- + str(put_res.content)
65
- )
70
+ msg = f"failed to upload {filepath}, {e})"
66
71
  logger.error(msg)
67
- raise Exception(msg)
72
+ raise Exception(e)
68
73
 
69
74
 
70
75
  def upload_file(
@@ -92,6 +97,7 @@ def upload_file(
92
97
  logger.debug("started gcs upload")
93
98
 
94
99
  gcs_resumable_upload(
100
+ client=client,
95
101
  filepath=pathlib.Path(file_path),
96
102
  signed_url=start_res.upload.gcs_resumable.signed_url,
97
103
  http_headers=start_res.upload.gcs_resumable.http_headers,
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: proto/api/v0/luminarycloud/feature_flag/feature_flag.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf import descriptor as _descriptor
6
+ from google.protobuf import descriptor_pool as _descriptor_pool
7
+ from google.protobuf import message as _message
8
+ from google.protobuf import reflection as _reflection
9
+ from google.protobuf import symbol_database as _symbol_database
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+ from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
16
+ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
17
+
18
+
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n:proto/api/v0/luminarycloud/feature_flag/feature_flag.proto\x12\x30luminary.proto.api.v0.luminarycloud.feature_flag\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\"\xd9\x01\n\x17GetFeatureFlagsResponse\x12\x81\x01\n\x15\x65nabled_feature_flags\x18\x01 \x03(\x0b\x32\x62.luminary.proto.api.v0.luminarycloud.feature_flag.GetFeatureFlagsResponse.EnabledFeatureFlagsEntry\x1a:\n\x18\x45nabledFeatureFlagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x32\xa6\x01\n\x12\x46\x65\x61tureFlagService\x12\x8f\x01\n\x0fGetFeatureFlags\x12\x16.google.protobuf.Empty\x1aI.luminary.proto.api.v0.luminarycloud.feature_flag.GetFeatureFlagsResponse\"\x19\x82\xd3\xe4\x93\x02\x13\x12\x11/v0/feature_flagsB@Z>luminarycloud.com/core/proto/api/v0/luminarycloud/feature_flagb\x06proto3')
20
+
21
+
22
+
23
+ _GETFEATUREFLAGSRESPONSE = DESCRIPTOR.message_types_by_name['GetFeatureFlagsResponse']
24
+ _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY = _GETFEATUREFLAGSRESPONSE.nested_types_by_name['EnabledFeatureFlagsEntry']
25
+ GetFeatureFlagsResponse = _reflection.GeneratedProtocolMessageType('GetFeatureFlagsResponse', (_message.Message,), {
26
+
27
+ 'EnabledFeatureFlagsEntry' : _reflection.GeneratedProtocolMessageType('EnabledFeatureFlagsEntry', (_message.Message,), {
28
+ 'DESCRIPTOR' : _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY,
29
+ '__module__' : 'proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2'
30
+ # @@protoc_insertion_point(class_scope:luminary.proto.api.v0.luminarycloud.feature_flag.GetFeatureFlagsResponse.EnabledFeatureFlagsEntry)
31
+ })
32
+ ,
33
+ 'DESCRIPTOR' : _GETFEATUREFLAGSRESPONSE,
34
+ '__module__' : 'proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2'
35
+ # @@protoc_insertion_point(class_scope:luminary.proto.api.v0.luminarycloud.feature_flag.GetFeatureFlagsResponse)
36
+ })
37
+ _sym_db.RegisterMessage(GetFeatureFlagsResponse)
38
+ _sym_db.RegisterMessage(GetFeatureFlagsResponse.EnabledFeatureFlagsEntry)
39
+
40
+ _FEATUREFLAGSERVICE = DESCRIPTOR.services_by_name['FeatureFlagService']
41
+ if _descriptor._USE_C_DESCRIPTORS == False:
42
+
43
+ DESCRIPTOR._options = None
44
+ DESCRIPTOR._serialized_options = b'Z>luminarycloud.com/core/proto/api/v0/luminarycloud/feature_flag'
45
+ _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY._options = None
46
+ _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY._serialized_options = b'8\001'
47
+ _FEATUREFLAGSERVICE.methods_by_name['GetFeatureFlags']._options = None
48
+ _FEATUREFLAGSERVICE.methods_by_name['GetFeatureFlags']._serialized_options = b'\202\323\344\223\002\023\022\021/v0/feature_flags'
49
+ _GETFEATUREFLAGSRESPONSE._serialized_start=172
50
+ _GETFEATUREFLAGSRESPONSE._serialized_end=389
51
+ _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY._serialized_start=331
52
+ _GETFEATUREFLAGSRESPONSE_ENABLEDFEATUREFLAGSENTRY._serialized_end=389
53
+ _FEATUREFLAGSERVICE._serialized_start=392
54
+ _FEATUREFLAGSERVICE._serialized_end=558
55
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,52 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+ import builtins
6
+ import collections.abc
7
+ import google.protobuf.descriptor
8
+ import google.protobuf.internal.containers
9
+ import google.protobuf.message
10
+ import sys
11
+
12
+ if sys.version_info >= (3, 8):
13
+ import typing as typing_extensions
14
+ else:
15
+ import typing_extensions
16
+
17
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
18
+
19
+ class GetFeatureFlagsResponse(google.protobuf.message.Message):
20
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
21
+
22
+ class EnabledFeatureFlagsEntry(google.protobuf.message.Message):
23
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
24
+
25
+ KEY_FIELD_NUMBER: builtins.int
26
+ VALUE_FIELD_NUMBER: builtins.int
27
+ key: builtins.int
28
+ value: builtins.str
29
+ def __init__(
30
+ self,
31
+ *,
32
+ key: builtins.int = ...,
33
+ value: builtins.str = ...,
34
+ ) -> None: ...
35
+ def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ...
36
+
37
+ ENABLED_FEATURE_FLAGS_FIELD_NUMBER: builtins.int
38
+ @property
39
+ def enabled_feature_flags(self) -> google.protobuf.internal.containers.ScalarMap[builtins.int, builtins.str]:
40
+ """Map of enabled feature flags where:
41
+ - Key: experiment ID (uint64)
42
+ - Value: feature flag name (string)
43
+ Returns an empty map if no feature flags are enabled for the user.
44
+ """
45
+ def __init__(
46
+ self,
47
+ *,
48
+ enabled_feature_flags: collections.abc.Mapping[builtins.int, builtins.str] | None = ...,
49
+ ) -> None: ...
50
+ def ClearField(self, field_name: typing_extensions.Literal["enabled_feature_flags", b"enabled_feature_flags"]) -> None: ...
51
+
52
+ global___GetFeatureFlagsResponse = GetFeatureFlagsResponse
@@ -0,0 +1,72 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+
5
+ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
6
+ from luminarycloud._proto.api.v0.luminarycloud.feature_flag import feature_flag_pb2 as proto_dot_api_dot_v0_dot_luminarycloud_dot_feature__flag_dot_feature__flag__pb2
7
+
8
+
9
+ class FeatureFlagServiceStub(object):
10
+ """Manages feature flags for internal users.
11
+ """
12
+
13
+ def __init__(self, channel):
14
+ """Constructor.
15
+
16
+ Args:
17
+ channel: A grpc.Channel.
18
+ """
19
+ self.GetFeatureFlags = channel.unary_unary(
20
+ '/luminary.proto.api.v0.luminarycloud.feature_flag.FeatureFlagService/GetFeatureFlags',
21
+ request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
22
+ response_deserializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_feature__flag_dot_feature__flag__pb2.GetFeatureFlagsResponse.FromString,
23
+ )
24
+
25
+
26
+ class FeatureFlagServiceServicer(object):
27
+ """Manages feature flags for internal users.
28
+ """
29
+
30
+ def GetFeatureFlags(self, request, context):
31
+ """Gets all enabled feature flags for the authenticated user.
32
+ Feature flags are used to control access to experimental and internal features.
33
+ """
34
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
35
+ context.set_details('Method not implemented!')
36
+ raise NotImplementedError('Method not implemented!')
37
+
38
+
39
+ def add_FeatureFlagServiceServicer_to_server(servicer, server):
40
+ rpc_method_handlers = {
41
+ 'GetFeatureFlags': grpc.unary_unary_rpc_method_handler(
42
+ servicer.GetFeatureFlags,
43
+ request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
44
+ response_serializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_feature__flag_dot_feature__flag__pb2.GetFeatureFlagsResponse.SerializeToString,
45
+ ),
46
+ }
47
+ generic_handler = grpc.method_handlers_generic_handler(
48
+ 'luminary.proto.api.v0.luminarycloud.feature_flag.FeatureFlagService', rpc_method_handlers)
49
+ server.add_generic_rpc_handlers((generic_handler,))
50
+
51
+
52
+ # This class is part of an EXPERIMENTAL API.
53
+ class FeatureFlagService(object):
54
+ """Manages feature flags for internal users.
55
+ """
56
+
57
+ @staticmethod
58
+ def GetFeatureFlags(request,
59
+ target,
60
+ options=(),
61
+ channel_credentials=None,
62
+ call_credentials=None,
63
+ insecure=False,
64
+ compression=None,
65
+ wait_for_ready=None,
66
+ timeout=None,
67
+ metadata=None):
68
+ return grpc.experimental.unary_unary(request, target, '/luminary.proto.api.v0.luminarycloud.feature_flag.FeatureFlagService/GetFeatureFlags',
69
+ google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
70
+ proto_dot_api_dot_v0_dot_luminarycloud_dot_feature__flag_dot_feature__flag__pb2.GetFeatureFlagsResponse.FromString,
71
+ options, channel_credentials,
72
+ insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -0,0 +1,35 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+ import abc
6
+ import google.protobuf.empty_pb2
7
+ import grpc
8
+ import luminarycloud._proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2
9
+
10
+ class FeatureFlagServiceStub:
11
+ """Manages feature flags for internal users."""
12
+
13
+ def __init__(self, channel: grpc.Channel) -> None: ...
14
+ GetFeatureFlags: grpc.UnaryUnaryMultiCallable[
15
+ google.protobuf.empty_pb2.Empty,
16
+ luminarycloud._proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2.GetFeatureFlagsResponse,
17
+ ]
18
+ """Gets all enabled feature flags for the authenticated user.
19
+ Feature flags are used to control access to experimental and internal features.
20
+ """
21
+
22
+ class FeatureFlagServiceServicer(metaclass=abc.ABCMeta):
23
+ """Manages feature flags for internal users."""
24
+
25
+ @abc.abstractmethod
26
+ def GetFeatureFlags(
27
+ self,
28
+ request: google.protobuf.empty_pb2.Empty,
29
+ context: grpc.ServicerContext,
30
+ ) -> luminarycloud._proto.api.v0.luminarycloud.feature_flag.feature_flag_pb2.GetFeatureFlagsResponse:
31
+ """Gets all enabled feature flags for the authenticated user.
32
+ Feature flags are used to control access to experimental and internal features.
33
+ """
34
+
35
+ def add_FeatureFlagServiceServicer_to_server(servicer: FeatureFlagServiceServicer, server: grpc.Server) -> None: ...