beamlit 0.0.23rc14__py3-none-any.whl → 0.0.23rc15__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,