beamlit 0.0.23rc14__py3-none-any.whl → 0.0.23rc15__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.
@@ -65,6 +65,7 @@ class Settings(BaseSettings):
65
65
  name: str = Field(default="beamlit-agent")
66
66
  base_url: str = Field(default="https://api.beamlit.dev/v0")
67
67
  run_url: str = Field(default="https://run.beamlit.dev")
68
+ registry_url: str = Field(default="https://serverless-registry-production.beamlit.workers.dev")
68
69
  log_level: str = Field(default="INFO")
69
70
  agent: SettingsAgent = SettingsAgent()
70
71
  server: SettingsServer = SettingsServer()
beamlit/deploy/deploy.py CHANGED
@@ -7,9 +7,10 @@ from dataclasses import dataclass
7
7
  from logging import getLogger
8
8
  from typing import Callable, Literal
9
9
 
10
- from beamlit.common.settings import Settings, init
10
+ from beamlit.common.settings import Settings, get_settings, init
11
11
  from beamlit.models import (AgentChain, AgentDeployment, Flavor,
12
- FunctionDeployment, StoreFunctionParameter)
12
+ FunctionDeployment, Runtime,
13
+ StoreFunctionParameter)
13
14
 
14
15
  sys.path.insert(0, os.getcwd())
15
16
  sys.path.insert(0, os.path.join(os.getcwd(), "src"))
@@ -24,6 +25,16 @@ class Resource:
24
25
  func: Callable
25
26
 
26
27
  def get_resources(from_decorator, dir="src") -> list[Resource]:
28
+ """
29
+ Scans through Python files in a directory to find functions decorated with a specific decorator.
30
+
31
+ Args:
32
+ from_decorator (str): The name of the decorator to search for
33
+ dir (str): The directory to scan, defaults to "src"
34
+
35
+ Returns:
36
+ list[Resource]: List of Resource objects containing information about decorated functions
37
+ """
27
38
  resources = []
28
39
  logger = getLogger(__name__)
29
40
 
@@ -80,6 +91,15 @@ def get_resources(from_decorator, dir="src") -> list[Resource]:
80
91
 
81
92
 
82
93
  def get_parameters(resource: Resource) -> list[StoreFunctionParameter]:
94
+ """
95
+ Extracts parameter information from a function's signature and docstring.
96
+
97
+ Args:
98
+ resource (Resource): The resource object containing the function to analyze
99
+
100
+ Returns:
101
+ list[StoreFunctionParameter]: List of parameter objects with name, type, required status, and description
102
+ """
83
103
  parameters = []
84
104
  # Get function signature
85
105
  import inspect
@@ -134,6 +154,16 @@ def get_parameters(resource: Resource) -> list[StoreFunctionParameter]:
134
154
 
135
155
 
136
156
  def get_description(description: str | None, resource: Resource) -> str:
157
+ """
158
+ Gets the description of a function from either a provided description or the function's docstring.
159
+
160
+ Args:
161
+ description (str | None): Optional explicit description
162
+ resource (Resource): The resource object containing the function
163
+
164
+ Returns:
165
+ str: The function description
166
+ """
137
167
  if description:
138
168
  return description
139
169
  doc = resource.func.__doc__
@@ -152,6 +182,15 @@ def get_description(description: str | None, resource: Resource) -> str:
152
182
  return ""
153
183
 
154
184
  def get_kwargs(arg: ast.Call) -> dict:
185
+ """
186
+ Extracts keyword arguments from an AST Call node.
187
+
188
+ Args:
189
+ arg (ast.Call): The AST Call node to process
190
+
191
+ Returns:
192
+ dict: Dictionary of keyword arguments and their values
193
+ """
155
194
  kwargs = {}
156
195
  for keyword in arg.keywords:
157
196
  if isinstance(keyword.value, ast.Constant):
@@ -171,37 +210,100 @@ def get_kwargs(arg: ast.Call) -> dict:
171
210
  kwargs[keyword.arg][k.value] = get_kwargs(v)
172
211
  return kwargs
173
212
 
213
+ def get_runtime(type: str, name: str) -> Runtime:
214
+ settings = get_settings()
215
+ registry_url = settings.registry_url.replace("https://", "").replace("http://", "")
216
+ image = f"{registry_url}/{settings.workspace}/{type}s/{name}"
217
+ return Runtime(image=image)
218
+
174
219
  def get_beamlit_deployment_from_resource(resource: Resource) -> AgentDeployment | FunctionDeployment:
220
+ """
221
+ Creates a deployment configuration from a resource.
222
+
223
+ Args:
224
+ resource (Resource): The resource to create a deployment for
225
+
226
+ Returns:
227
+ AgentDeployment | FunctionDeployment: The deployment configuration
228
+ """
175
229
  for arg in resource.decorator.args:
176
230
  if isinstance(arg, ast.Call):
177
231
  if isinstance(arg.func, ast.Name) and arg.func.id == "AgentDeployment":
178
232
  kwargs = get_kwargs(arg)
179
233
  description = kwargs.pop("description", None)
180
- return AgentDeployment(**kwargs, description=get_description(description, resource))
234
+ return AgentDeployment(
235
+ **kwargs,
236
+ description=get_description(description, resource),
237
+ runtime=get_runtime("agent", kwargs.get("agent", resource.name))
238
+ )
181
239
  if isinstance(arg.func, ast.Name) and arg.func.id == "FunctionDeployment":
182
240
  kwargs = get_kwargs(arg)
183
241
  description = kwargs.pop("description", None)
184
- return FunctionDeployment(**kwargs, parameters=get_parameters(resource), description=get_description(description, resource))
242
+ return FunctionDeployment(
243
+ **kwargs,
244
+ parameters=get_parameters(resource),
245
+ description=get_description(description, resource),
246
+ runtime=get_runtime("function", kwargs.get("function", resource.name))
247
+ )
248
+ for arg in resource.decorator.keywords:
249
+ if isinstance(arg.value, ast.Call):
250
+ if isinstance(arg.value.func, ast.Name) and arg.value.func.id == "AgentDeployment":
251
+ kwargs = get_kwargs(arg.value)
252
+ description = kwargs.pop("description", None)
253
+ return AgentDeployment(
254
+ **kwargs,
255
+ description=get_description(description, resource),
256
+ runtime=get_runtime("agent", kwargs.get("agent", resource.name))
257
+ )
258
+ if isinstance(arg.value.func, ast.Name) and arg.value.func.id == "FunctionDeployment":
259
+ kwargs = get_kwargs(arg.value)
260
+ description = kwargs.pop("description", None)
261
+ return FunctionDeployment(
262
+ **kwargs,
263
+ parameters=get_parameters(resource),
264
+ description=get_description(description, resource),
265
+ runtime=get_runtime("function", kwargs.get("function", resource.name))
266
+ )
185
267
  if resource.type == "agent":
186
268
  return AgentDeployment(
187
269
  agent=resource.name,
188
- description=get_description(None,resource)
270
+ description=get_description(None,resource),
271
+ runtime=get_runtime("agent", resource.name)
189
272
  )
190
273
  if resource.type == "function":
191
274
  return FunctionDeployment(
192
275
  function=resource.name,
193
276
  parameters=get_parameters(resource),
194
- description=get_description(None,resource)
277
+ description=get_description(None,resource),
278
+ runtime=get_runtime("function", resource.name)
195
279
  )
196
280
  return None
197
281
 
198
282
 
199
283
  def get_flavors(flavors: list[Flavor]) -> str:
284
+ """
285
+ Converts a list of Flavor objects to JSON string.
286
+
287
+ Args:
288
+ flavors (list[Flavor]): List of Flavor objects
289
+
290
+ Returns:
291
+ str: JSON string representation of flavors
292
+ """
200
293
  if not flavors:
201
294
  return "[]"
202
295
  return json.dumps([flavor.to_dict() for flavor in flavors])
203
296
 
204
297
  def format_parameters(parameters: list[StoreFunctionParameter]) -> str:
298
+ """
299
+ Formats function parameters into YAML-compatible string.
300
+
301
+ Args:
302
+ parameters (list[StoreFunctionParameter]): List of parameter objects
303
+
304
+ Returns:
305
+ str: YAML-formatted string of parameters
306
+ """
205
307
  if not parameters:
206
308
  return "[]"
207
309
 
@@ -216,6 +318,15 @@ def format_parameters(parameters: list[StoreFunctionParameter]) -> str:
216
318
  return "\n".join(formatted)
217
319
 
218
320
  def format_agent_chain(agent_chain: list[AgentChain]) -> str:
321
+ """
322
+ Formats agent chain configuration into YAML-compatible string.
323
+
324
+ Args:
325
+ agent_chain (list[AgentChain]): List of agent chain configurations
326
+
327
+ Returns:
328
+ str: YAML-formatted string of agent chain
329
+ """
219
330
  if not agent_chain:
220
331
  return "[]"
221
332
  formatted = []
@@ -229,20 +340,33 @@ def format_agent_chain(agent_chain: list[AgentChain]) -> str:
229
340
  return "\n".join(formatted)
230
341
 
231
342
  def get_agent_yaml(agent: AgentDeployment, functions: list[tuple[Resource, FunctionDeployment]], settings: Settings) -> str:
343
+ """
344
+ Generates YAML configuration for an agent deployment.
345
+
346
+ Args:
347
+ agent (AgentDeployment): Agent deployment configuration
348
+ functions (list[tuple[Resource, FunctionDeployment]]): List of associated functions
349
+ settings (Settings): Application settings
350
+
351
+ Returns:
352
+ str: YAML configuration string
353
+ """
232
354
  template = f"""
233
355
  apiVersion: beamlit.com/v1alpha1
234
356
  kind: Agent
235
357
  metadata:
236
358
  name: {agent.agent}
237
359
  spec:
238
- display_name: Agent - {agent.agent}
360
+ display_name: {agent.agent}
239
361
  deployments:
240
- - environment: production
362
+ - environment: {settings.environment}
241
363
  enabled: true
242
364
  policies: [{", ".join(agent.policies or [])}]
243
365
  functions: [{", ".join([f"{function.function}" for (_, function) in functions])}]
244
366
  agent_chain: {format_agent_chain(agent.agent_chain)}
245
367
  model: {agent.model}
368
+ runtime:
369
+ image: {agent.runtime.image}
246
370
  """
247
371
  if agent.description:
248
372
  template += f""" description: |
@@ -250,6 +374,16 @@ spec:
250
374
  return template
251
375
 
252
376
  def get_function_yaml(function: FunctionDeployment, settings: Settings) -> str:
377
+ """
378
+ Generates YAML configuration for a function deployment.
379
+
380
+ Args:
381
+ function (FunctionDeployment): Function deployment configuration
382
+ settings (Settings): Application settings
383
+
384
+ Returns:
385
+ str: YAML configuration string
386
+ """
253
387
  return f"""
254
388
  apiVersion: beamlit.com/v1alpha1
255
389
  kind: Function
@@ -264,9 +398,22 @@ spec:
264
398
  description: |
265
399
  {function.description}
266
400
  parameters: {format_parameters(function.parameters)}
401
+ runtime:
402
+ image: {function.runtime.image}
267
403
  """
268
404
 
269
- def dockerfile(type: Literal["agent", "function"], resource: Resource, deployment: AgentDeployment | FunctionDeployment):
405
+ def dockerfile(type: Literal["agent", "function"], resource: Resource, deployment: AgentDeployment | FunctionDeployment) -> str:
406
+ """
407
+ Generates Dockerfile content for agent or function deployment.
408
+
409
+ Args:
410
+ type (Literal["agent", "function"]): Type of deployment
411
+ resource (Resource): Resource to be deployed
412
+ deployment (AgentDeployment | FunctionDeployment): Deployment configuration
413
+
414
+ Returns:
415
+ str: Dockerfile content
416
+ """
270
417
  if type == "agent":
271
418
  module = f"{resource.module.__file__.split('/')[-1].replace('.py', '')}.{resource.module.__name__}"
272
419
  else:
@@ -302,6 +449,17 @@ ENTRYPOINT [{cmd_str}]
302
449
  """
303
450
 
304
451
  def generate_beamlit_deployment(directory: str):
452
+ """
453
+ Generates all necessary deployment files for Beamlit agents and functions.
454
+
455
+ Args:
456
+ directory (str): Target directory for generated files
457
+
458
+ Creates:
459
+ - Agent and function YAML configurations
460
+ - Dockerfiles for each deployment
461
+ - Directory structure for agents and functions
462
+ """
305
463
  settings = init()
306
464
  logger = getLogger(__name__)
307
465
  logger.info(f"Importing server module: {settings.server.module}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: beamlit
3
- Version: 0.0.23rc14
3
+ Version: 0.0.23rc15
4
4
  Summary: Add your description here
5
5
  Author-email: cploujoux <ch.ploujoux@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -138,10 +138,10 @@ beamlit/common/__init__.py,sha256=yDoMJDKj-xjTGl7U1YI59KpWxiOV65HSiUulgO8xdTA,27
138
138
  beamlit/common/generate.py,sha256=VJ_MiRDulXdQdnlKdM4_Bod6CO6DOGlFiosGXOLuLGs,7227
139
139
  beamlit/common/logger.py,sha256=ayabnsoHS8ncXm8EpBS01FkvSe0XRcaNdQjKVuPI5z4,1025
140
140
  beamlit/common/secrets.py,sha256=sid81bOe3LflkMKDHwBsBs9nIju8bp5-v9qU9gkyNMc,212
141
- beamlit/common/settings.py,sha256=cL5HAg6atxnTJXL9Rxz5Xs4iApNCCYY5ijha8UM3PW4,5446
141
+ beamlit/common/settings.py,sha256=N0VzveNQ3vAE6ZJWMnWrIVi2hXidLtkRZkAXQTGo40A,5546
142
142
  beamlit/common/utils.py,sha256=jouz5igBvT37Xn_e94-foCHyQczVim-UzVcoIF6RWJ4,657
143
143
  beamlit/deploy/__init__.py,sha256=GS7l7Jtm2yKs7iNLKcfjYO-rAhUzggQ3xiYSf3oxLBY,91
144
- beamlit/deploy/deploy.py,sha256=F79JRGhZV-5wIvux66UC6ATSnqQkTfL2MvD8ayVy6-o,13487
144
+ beamlit/deploy/deploy.py,sha256=bWUXG_5b_XhFcG5t75vel2EbEfZPIdg_YLXtzkfgXUs,18799
145
145
  beamlit/functions/__init__.py,sha256=_RPG1Bfg54JGdIPnViAU6n9zD7E1cDNsdXi8oYGskzE,138
146
146
  beamlit/functions/decorator.py,sha256=uYZOVxD-7ZNHORTQfCIn0qdNKPIZupsr7_QdUmWEKu0,2996
147
147
  beamlit/functions/github/__init__.py,sha256=gYnUkeegukOfbymdabuuJkScvH-_ZJygX05BoqkPn0o,49
@@ -298,6 +298,6 @@ beamlit/serve/app.py,sha256=_0ZesKcczd1sYm8vs3ulbXO1M1boO_5DhFf3jSmjM4g,2398
298
298
  beamlit/serve/middlewares/__init__.py,sha256=1dVmnOmhAQWvWktqHkKSIX-YoF6fmMU8xkUQuhg_rJU,148
299
299
  beamlit/serve/middlewares/accesslog.py,sha256=wM52-hcwtO-_hdM1pnsEJzerzJf1MzEyN5m85BdDccE,609
300
300
  beamlit/serve/middlewares/processtime.py,sha256=lDAaIasZ4bwvN-HKHvZpaD9r-yrkVNZYx4abvbjbrCg,411
301
- beamlit-0.0.23rc14.dist-info/METADATA,sha256=l7YaLMfPwUhKPfEiD2-Ve1OtVt6U3dkdR9rEh243w5Y,2027
302
- beamlit-0.0.23rc14.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
303
- beamlit-0.0.23rc14.dist-info/RECORD,,
301
+ beamlit-0.0.23rc15.dist-info/METADATA,sha256=piLvTAjRvfpbIyBmUvCHSZHa2jxLezNRyfGLWmtIKBg,2027
302
+ beamlit-0.0.23rc15.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
303
+ beamlit-0.0.23rc15.dist-info/RECORD,,