beamlit 0.0.52__py3-none-any.whl → 0.0.53__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.
- beamlit/agents/chain.py +50 -3
- beamlit/agents/chat.py +92 -7
- beamlit/agents/decorator.py +43 -9
- beamlit/agents/thread.py +14 -0
- beamlit/agents/voice/openai.py +5 -7
- beamlit/authentication/apikey.py +30 -0
- beamlit/authentication/authentication.py +64 -0
- beamlit/authentication/clientcredentials.py +51 -1
- beamlit/authentication/credentials.py +117 -0
- beamlit/authentication/device_mode.py +78 -0
- beamlit/common/error.py +18 -0
- beamlit/common/instrumentation.py +38 -12
- beamlit/common/logger.py +29 -0
- beamlit/common/secrets.py +28 -0
- beamlit/common/settings.py +39 -1
- beamlit/common/slugify.py +16 -0
- beamlit/common/utils.py +19 -0
- beamlit/deploy/__init__.py +5 -0
- beamlit/deploy/deploy.py +31 -15
- beamlit/deploy/format.py +39 -8
- beamlit/deploy/parser.py +16 -0
- beamlit/functions/__init__.py +2 -1
- beamlit/functions/common.py +57 -8
- beamlit/functions/decorator.py +21 -2
- beamlit/functions/mcp/mcp.py +15 -2
- beamlit/functions/remote/remote.py +29 -4
- beamlit/run.py +45 -0
- beamlit/serve/app.py +23 -5
- beamlit/serve/middlewares/__init__.py +6 -0
- beamlit/serve/middlewares/accesslog.py +16 -0
- beamlit/serve/middlewares/processtime.py +16 -0
- {beamlit-0.0.52.dist-info → beamlit-0.0.53.dist-info}/METADATA +1 -1
- {beamlit-0.0.52.dist-info → beamlit-0.0.53.dist-info}/RECORD +36 -35
- beamlit-0.0.53.dist-info/entry_points.txt +2 -0
- {beamlit-0.0.52.dist-info → beamlit-0.0.53.dist-info}/WHEEL +0 -0
- {beamlit-0.0.52.dist-info → beamlit-0.0.53.dist-info}/licenses/LICENSE +0 -0
beamlit/deploy/deploy.py
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
"""
|
2
|
+
This module provides functionalities to generate and manage Beamlit deployment configurations.
|
3
|
+
It includes functions to set default deployment values, create deployment configurations from resources,
|
4
|
+
format deployments, and clean up auto-generated deployments.
|
5
|
+
"""
|
6
|
+
|
1
7
|
import ast
|
2
8
|
import json
|
3
9
|
import os
|
@@ -31,6 +37,16 @@ sys.path.insert(0, os.getcwd())
|
|
31
37
|
sys.path.insert(0, os.path.join(os.getcwd(), "src"))
|
32
38
|
|
33
39
|
def set_default_values(resource: Resource, deployment: Agent | Function):
|
40
|
+
"""
|
41
|
+
Sets default values for a deployment based on the resource and deployment type.
|
42
|
+
|
43
|
+
Parameters:
|
44
|
+
resource (Resource): The resource information.
|
45
|
+
deployment (Agent | Function): The deployment instance to set defaults for.
|
46
|
+
|
47
|
+
Returns:
|
48
|
+
Agent | Function: The updated deployment with default values set.
|
49
|
+
"""
|
34
50
|
settings = get_settings()
|
35
51
|
deployment.metadata.workspace = settings.workspace
|
36
52
|
deployment.metadata.environment = settings.environment
|
@@ -46,13 +62,13 @@ def get_beamlit_deployment_from_resource(
|
|
46
62
|
resource: Resource,
|
47
63
|
) -> Agent | Function:
|
48
64
|
"""
|
49
|
-
Creates a deployment configuration from a resource.
|
65
|
+
Creates a deployment configuration from a given resource.
|
50
66
|
|
51
67
|
Args:
|
52
|
-
resource (Resource): The resource to create a deployment for
|
68
|
+
resource (Resource): The resource to create a deployment for.
|
53
69
|
|
54
70
|
Returns:
|
55
|
-
Agent | Function: The deployment configuration
|
71
|
+
Agent | Function: The deployment configuration.
|
56
72
|
"""
|
57
73
|
for arg in resource.decorator.keywords:
|
58
74
|
if arg.arg == "agent":
|
@@ -80,16 +96,15 @@ def get_beamlit_deployment_from_resource(
|
|
80
96
|
return set_default_values(resource, func)
|
81
97
|
return None
|
82
98
|
|
83
|
-
|
84
99
|
def get_flavors(flavors: list[Flavor]) -> str:
|
85
100
|
"""
|
86
|
-
Converts a list of Flavor objects to JSON string.
|
101
|
+
Converts a list of Flavor objects to a JSON string.
|
87
102
|
|
88
103
|
Args:
|
89
|
-
flavors (list[Flavor]): List of Flavor objects
|
104
|
+
flavors (list[Flavor]): List of Flavor objects.
|
90
105
|
|
91
106
|
Returns:
|
92
|
-
str: JSON string representation of flavors
|
107
|
+
str: JSON string representation of flavors.
|
93
108
|
"""
|
94
109
|
if not flavors:
|
95
110
|
return "[]"
|
@@ -176,7 +191,7 @@ def dockerfile(
|
|
176
191
|
FROM python:3.12-slim
|
177
192
|
|
178
193
|
ARG UV_VERSION="latest"
|
179
|
-
RUN apt update && apt install -y curl
|
194
|
+
RUN apt update && apt install -y curl build-essential
|
180
195
|
|
181
196
|
# Install uv.
|
182
197
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
@@ -207,9 +222,9 @@ def clean_auto_generated(
|
|
207
222
|
Cleans up auto-generated deployments of a specific type.
|
208
223
|
|
209
224
|
Args:
|
210
|
-
directory (str): Base directory containing deployments
|
211
|
-
type (
|
212
|
-
deployments (list[tuple[Resource, Agent | Function]]): List of deployment resources and configurations
|
225
|
+
directory (str): Base directory containing deployments.
|
226
|
+
type (Literal["agent", "function"]): Type of deployment to clean ("agent" or "function").
|
227
|
+
deployments (list[tuple[Resource, Agent | Function]]): List of deployment resources and configurations.
|
213
228
|
"""
|
214
229
|
|
215
230
|
deploy_dir = Path(directory) / f"{type}s"
|
@@ -233,12 +248,13 @@ def generate_beamlit_deployment(directory: str, name: str):
|
|
233
248
|
Generates all necessary deployment files for Beamlit agents and functions.
|
234
249
|
|
235
250
|
Args:
|
236
|
-
directory (str): Target directory for generated files
|
251
|
+
directory (str): Target directory for generated files.
|
252
|
+
name (str): Name identifier for the deployment.
|
237
253
|
|
238
254
|
Creates:
|
239
|
-
- Agent and function YAML configurations
|
240
|
-
- Dockerfiles for each deployment
|
241
|
-
- Directory structure for agents and functions
|
255
|
+
- Agent and function YAML configurations.
|
256
|
+
- Dockerfiles for each deployment.
|
257
|
+
- Directory structure for agents and functions.
|
242
258
|
"""
|
243
259
|
settings = init()
|
244
260
|
client = new_client()
|
beamlit/deploy/format.py
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
"""
|
2
|
+
This module provides utility functions to format deployment configurations into YAML-compatible strings.
|
3
|
+
It includes functions to convert arguments, parameters, dictionaries, and agent chains into properly formatted JSON or YAML strings.
|
4
|
+
"""
|
1
5
|
|
2
6
|
import ast
|
3
7
|
|
@@ -11,6 +15,15 @@ def arg_to_list(arg: ast.List):
|
|
11
15
|
return value
|
12
16
|
|
13
17
|
def format_value(v):
|
18
|
+
"""
|
19
|
+
Formats an AST node value into its Python equivalent.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
v (ast.AST): The AST node to format.
|
23
|
+
|
24
|
+
Returns:
|
25
|
+
Any: The formatted Python value.
|
26
|
+
"""
|
14
27
|
if isinstance(v, ast.Constant):
|
15
28
|
return v.value
|
16
29
|
elif isinstance(v, ast.Dict):
|
@@ -19,6 +32,15 @@ def format_value(v):
|
|
19
32
|
return arg_to_list(v)
|
20
33
|
|
21
34
|
def arg_to_dict(arg: ast.keyword):
|
35
|
+
"""
|
36
|
+
Converts an AST keyword argument to a dictionary.
|
37
|
+
|
38
|
+
Args:
|
39
|
+
arg (ast.keyword): The AST keyword argument.
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
dict: The resulting dictionary.
|
43
|
+
"""
|
22
44
|
value = {}
|
23
45
|
for k, v in zip(arg.keys, arg.values):
|
24
46
|
if isinstance(k, ast.Constant):
|
@@ -27,13 +49,13 @@ def arg_to_dict(arg: ast.keyword):
|
|
27
49
|
|
28
50
|
def format_parameters(parameters: list[StoreFunctionParameter]) -> str:
|
29
51
|
"""
|
30
|
-
Formats function parameters into YAML-compatible string.
|
52
|
+
Formats function parameters into a YAML-compatible string.
|
31
53
|
|
32
54
|
Args:
|
33
|
-
parameters (list[StoreFunctionParameter]): List of parameter objects
|
55
|
+
parameters (list[StoreFunctionParameter]): List of parameter objects.
|
34
56
|
|
35
57
|
Returns:
|
36
|
-
str: YAML-formatted string of parameters
|
58
|
+
str: YAML-formatted string of parameters.
|
37
59
|
"""
|
38
60
|
if not parameters:
|
39
61
|
return "[]"
|
@@ -49,6 +71,15 @@ def format_parameters(parameters: list[StoreFunctionParameter]) -> str:
|
|
49
71
|
return "\n".join(formatted)
|
50
72
|
|
51
73
|
def format_dict(obj: dict) -> str:
|
74
|
+
"""
|
75
|
+
Converts a dictionary to a YAML-compatible string.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
obj (dict): The dictionary to format.
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
str: YAML-formatted string representation of the dictionary.
|
82
|
+
"""
|
52
83
|
if not obj:
|
53
84
|
return "null"
|
54
85
|
ret = ""
|
@@ -61,13 +92,13 @@ def format_dict(obj: dict) -> str:
|
|
61
92
|
|
62
93
|
def format_agent_chain(agentChain: list[AgentChain]) -> str:
|
63
94
|
"""
|
64
|
-
Formats agent chain configuration into YAML-compatible string.
|
95
|
+
Formats agent chain configuration into a YAML-compatible string.
|
65
96
|
|
66
97
|
Args:
|
67
|
-
agentChain (list[AgentChain]): List of agent chain configurations
|
98
|
+
agentChain (list[AgentChain]): List of agent chain configurations.
|
68
99
|
|
69
100
|
Returns:
|
70
|
-
str: YAML-formatted string of agent chain
|
101
|
+
str: YAML-formatted string of agent chain.
|
71
102
|
"""
|
72
103
|
if not agentChain:
|
73
104
|
return "[]"
|
@@ -75,8 +106,8 @@ def format_agent_chain(agentChain: list[AgentChain]) -> str:
|
|
75
106
|
|
76
107
|
for agent in agentChain:
|
77
108
|
formatted.append(f"""
|
78
|
-
|
79
|
-
|
109
|
+
- agent: {agent.name}
|
110
|
+
enabled: {agent.enabled}""")
|
80
111
|
if agent.description:
|
81
112
|
formatted.append(f" description: {agent.description}")
|
82
113
|
return "\n".join(formatted)
|
beamlit/deploy/parser.py
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
"""
|
2
|
+
This module provides classes and functions for parsing deployment resources within Beamlit.
|
3
|
+
It includes the Resource dataclass for representing deployment resources and functions to extract and process resources
|
4
|
+
decorated within Python files.
|
5
|
+
"""
|
6
|
+
|
1
7
|
import ast
|
2
8
|
import importlib
|
3
9
|
import os
|
@@ -10,6 +16,16 @@ from beamlit.models import StoreFunctionParameter
|
|
10
16
|
|
11
17
|
@dataclass
|
12
18
|
class Resource:
|
19
|
+
"""
|
20
|
+
A dataclass representing a deployment resource.
|
21
|
+
|
22
|
+
Attributes:
|
23
|
+
type (Literal["agent", "function"]): The type of deployment ("agent" or "function").
|
24
|
+
module (Callable): The module containing the deployment.
|
25
|
+
name (str): The name of the deployment.
|
26
|
+
decorator (ast.Call): The decorator AST node used on the deployment function.
|
27
|
+
func (Callable): The deployment function.
|
28
|
+
"""
|
13
29
|
type: Literal["agent", "function"]
|
14
30
|
module: Callable
|
15
31
|
name: str
|
beamlit/functions/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
"""Functions package providing function decorators and utilities.
|
1
|
+
"""Functions package providing function decorators and utilities for Beamlit integration.
|
2
|
+
It includes decorators for creating function tools and utilities for managing and retrieving functions."""
|
2
3
|
|
3
4
|
from .common import get_functions
|
4
5
|
from .decorator import function, kit
|
beamlit/functions/common.py
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
-
"""Decorators for creating function tools with Beamlit and LangChain integration.
|
1
|
+
"""Decorators for creating function tools with Beamlit and LangChain integration.
|
2
|
+
|
3
|
+
This module provides functionality to discover and load function tools from Python files,
|
4
|
+
supporting both local and remote function execution.
|
5
|
+
|
6
|
+
Key Features:
|
7
|
+
- Automatic function discovery in specified directories
|
8
|
+
- Support for both synchronous and asynchronous functions
|
9
|
+
- Integration with LangChain's StructuredTool system
|
10
|
+
- Remote function toolkit handling
|
11
|
+
- Chain toolkit integration
|
12
|
+
|
13
|
+
Main Components:
|
14
|
+
- get_functions(): Core function that discovers and loads function tools
|
15
|
+
"""
|
2
16
|
import ast
|
3
17
|
import asyncio
|
4
18
|
import importlib.util
|
@@ -20,14 +34,49 @@ from beamlit.models import AgentChain
|
|
20
34
|
logger = getLogger(__name__)
|
21
35
|
|
22
36
|
def get_functions(
|
23
|
-
remote_functions:Union[list[str], None]=None,
|
24
|
-
client:Union[AuthenticatedClient, None]=None,
|
25
|
-
dir:Union[str, None]=None,
|
26
|
-
chain:Union[list[AgentChain], None]=None,
|
27
|
-
remote_functions_empty:bool=True,
|
28
|
-
from_decorator:str="function",
|
29
|
-
warning:bool=True,
|
37
|
+
remote_functions: Union[list[str], None] = None,
|
38
|
+
client: Union[AuthenticatedClient, None] = None,
|
39
|
+
dir: Union[str, None] = None,
|
40
|
+
chain: Union[list[AgentChain], None] = None,
|
41
|
+
remote_functions_empty: bool = True,
|
42
|
+
from_decorator: str = "function",
|
43
|
+
warning: bool = True,
|
30
44
|
):
|
45
|
+
"""Discovers and loads function tools from Python files and remote sources.
|
46
|
+
|
47
|
+
This function walks through Python files in a specified directory, looking for
|
48
|
+
decorated functions to convert into LangChain tools. It also handles remote
|
49
|
+
functions and chain toolkits.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
remote_functions (Union[list[str], None]): List of remote function names to load
|
53
|
+
client (Union[AuthenticatedClient, None]): Authenticated client instance for API calls
|
54
|
+
dir (Union[str, None]): Directory to search for Python files containing functions
|
55
|
+
chain (Union[list[AgentChain], None]): List of agent chains to include
|
56
|
+
remote_functions_empty (bool): Whether to allow empty remote functions
|
57
|
+
from_decorator (str): Name of the decorator to look for (default: "function")
|
58
|
+
warning (bool): Whether to show warning messages
|
59
|
+
|
60
|
+
Returns:
|
61
|
+
list: List of discovered and loaded function tools
|
62
|
+
|
63
|
+
The function performs the following steps:
|
64
|
+
1. Walks through Python files in the specified directory
|
65
|
+
2. Parses each file to find decorated functions
|
66
|
+
3. Converts found functions into LangChain StructuredTools
|
67
|
+
4. Handles both synchronous and asynchronous functions
|
68
|
+
5. Processes remote functions if specified
|
69
|
+
6. Integrates chain toolkits if provided
|
70
|
+
|
71
|
+
Example:
|
72
|
+
```python
|
73
|
+
tools = get_functions(
|
74
|
+
dir="./functions",
|
75
|
+
from_decorator="function",
|
76
|
+
warning=True
|
77
|
+
)
|
78
|
+
```
|
79
|
+
"""
|
31
80
|
from beamlit.agents.chain import ChainToolkit
|
32
81
|
|
33
82
|
settings = get_settings()
|
beamlit/functions/decorator.py
CHANGED
@@ -11,7 +11,16 @@ from beamlit.models import Function, FunctionKit
|
|
11
11
|
logger = getLogger(__name__)
|
12
12
|
|
13
13
|
def kit(bl_kit: FunctionKit = None, **kwargs: dict) -> Callable:
|
14
|
-
"""
|
14
|
+
"""
|
15
|
+
Decorator to create function tools with Beamlit and LangChain integration.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
bl_kit (FunctionKit | None): Optional FunctionKit to associate with the function.
|
19
|
+
**kwargs (dict): Additional keyword arguments for function configuration.
|
20
|
+
|
21
|
+
Returns:
|
22
|
+
Callable: The decorated function.
|
23
|
+
"""
|
15
24
|
|
16
25
|
def wrapper(func: Callable) -> Callable:
|
17
26
|
if bl_kit and not func.__doc__ and bl_kit.description:
|
@@ -22,7 +31,17 @@ def kit(bl_kit: FunctionKit = None, **kwargs: dict) -> Callable:
|
|
22
31
|
|
23
32
|
|
24
33
|
def function(*args, function: Function | dict = None, kit=False, **kwargs: dict) -> Callable:
|
25
|
-
"""
|
34
|
+
"""
|
35
|
+
Decorator to create function tools with Beamlit and LangChain integration.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
function (Function | dict): Function metadata or a dictionary representing it.
|
39
|
+
kit (bool): Whether to associate a function kit.
|
40
|
+
**kwargs (dict): Additional keyword arguments for function configuration.
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
Callable: The decorated function.
|
44
|
+
"""
|
26
45
|
if function is not None and not isinstance(function, dict):
|
27
46
|
raise Exception(
|
28
47
|
'function must be a dictionary, example: @function(function={"metadata": {"name": "my_function"}})'
|
beamlit/functions/mcp/mcp.py
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
"""
|
2
|
+
This module provides functionalities to interact with MCP (Multi-Client Platform) servers.
|
3
|
+
It includes classes for managing MCP clients, creating dynamic schemas, and integrating MCP tools into Beamlit.
|
4
|
+
"""
|
5
|
+
|
1
6
|
import asyncio
|
2
7
|
import warnings
|
3
8
|
from typing import Any, Callable
|
@@ -87,7 +92,11 @@ class MCPClient:
|
|
87
92
|
|
88
93
|
class MCPTool(BaseTool):
|
89
94
|
"""
|
90
|
-
MCP server
|
95
|
+
Tool for interacting with MCP server-hosted tools.
|
96
|
+
|
97
|
+
Attributes:
|
98
|
+
client (MCPClient): The MCP client instance.
|
99
|
+
handle_tool_error (bool | str | Callable[[ToolException], str] | None): Error handling strategy.
|
91
100
|
"""
|
92
101
|
|
93
102
|
client: MCPClient
|
@@ -119,7 +128,11 @@ class MCPTool(BaseTool):
|
|
119
128
|
|
120
129
|
class MCPToolkit(BaseToolkit):
|
121
130
|
"""
|
122
|
-
MCP server
|
131
|
+
Toolkit for managing MCP server tools.
|
132
|
+
|
133
|
+
Attributes:
|
134
|
+
client (MCPClient): The MCP client instance.
|
135
|
+
_tools (ListToolsResult | None): Cached list of tools from the MCP server.
|
123
136
|
"""
|
124
137
|
|
125
138
|
client: MCPClient
|
@@ -1,3 +1,8 @@
|
|
1
|
+
"""
|
2
|
+
This module provides functionalities to integrate remote functions into Beamlit.
|
3
|
+
It includes classes for creating dynamic schemas based on function parameters and managing remote toolkits.
|
4
|
+
"""
|
5
|
+
|
1
6
|
import asyncio
|
2
7
|
import warnings
|
3
8
|
from dataclasses import dataclass
|
@@ -17,6 +22,16 @@ from beamlit.run import RunClient
|
|
17
22
|
|
18
23
|
|
19
24
|
def create_dynamic_schema(name: str, parameters: list[StoreFunctionParameter]) -> type[pydantic.BaseModel]:
|
25
|
+
"""
|
26
|
+
Creates a dynamic Pydantic schema based on function parameters.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
name (str): The name of the schema.
|
30
|
+
parameters (list[StoreFunctionParameter]): List of parameter objects.
|
31
|
+
|
32
|
+
Returns:
|
33
|
+
type[pydantic.BaseModel]: The dynamically created Pydantic model.
|
34
|
+
"""
|
20
35
|
field_definitions = {}
|
21
36
|
for param in parameters:
|
22
37
|
field_type = str
|
@@ -39,7 +54,13 @@ def create_dynamic_schema(name: str, parameters: list[StoreFunctionParameter]) -
|
|
39
54
|
|
40
55
|
class RemoteTool(BaseTool):
|
41
56
|
"""
|
42
|
-
|
57
|
+
Tool for interacting with remote functions.
|
58
|
+
|
59
|
+
Attributes:
|
60
|
+
client (RunClient): The client used to execute remote function calls.
|
61
|
+
resource_name (str): The name of the remote resource.
|
62
|
+
kit (bool): Indicates whether the tool is part of a function kit.
|
63
|
+
handle_tool_error (bool | str | Callable[[ToolException], str] | None): Error handling strategy.
|
43
64
|
"""
|
44
65
|
|
45
66
|
client: RunClient
|
@@ -79,7 +100,12 @@ class RemoteTool(BaseTool):
|
|
79
100
|
@dataclass
|
80
101
|
class RemoteToolkit:
|
81
102
|
"""
|
82
|
-
|
103
|
+
Toolkit for managing remote function tools.
|
104
|
+
|
105
|
+
Attributes:
|
106
|
+
client (AuthenticatedClient): The authenticated client instance.
|
107
|
+
function (str): The name of the remote function to integrate.
|
108
|
+
_function (Function | None): Cached Function object after initialization.
|
83
109
|
"""
|
84
110
|
client: AuthenticatedClient
|
85
111
|
function: str
|
@@ -87,7 +113,7 @@ class RemoteToolkit:
|
|
87
113
|
model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)
|
88
114
|
|
89
115
|
def initialize(self) -> None:
|
90
|
-
"""Initialize the session and retrieve
|
116
|
+
"""Initialize the session and retrieve the remote function details."""
|
91
117
|
if self._function is None:
|
92
118
|
try:
|
93
119
|
response = get_function.sync_detailed(self.function, client=self.client)
|
@@ -106,7 +132,6 @@ class RemoteToolkit:
|
|
106
132
|
f"error: {e.status_code}. Available functions: {', '.join(names)}"
|
107
133
|
)
|
108
134
|
|
109
|
-
@t.override
|
110
135
|
def get_tools(self) -> list[BaseTool]:
|
111
136
|
settings = get_settings()
|
112
137
|
if self._function is None:
|
beamlit/run.py
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
"""
|
2
|
+
This module provides functionality for executing HTTP requests against Beamlit resources.
|
3
|
+
"""
|
1
4
|
import urllib.parse
|
2
5
|
from typing import Any
|
3
6
|
|
@@ -8,6 +11,29 @@ from beamlit.common import HTTPError, get_settings
|
|
8
11
|
|
9
12
|
|
10
13
|
class RunClient:
|
14
|
+
"""Provides functionality for executing HTTP requests against Beamlit resources.
|
15
|
+
|
16
|
+
This module contains the RunClient class which handles authenticated HTTP requests to Beamlit
|
17
|
+
resources. It allows users to interact with different resource types (like functions or services)
|
18
|
+
in specific environments, supporting various HTTP methods and request parameters.
|
19
|
+
|
20
|
+
Example:
|
21
|
+
```python
|
22
|
+
client = new_client()
|
23
|
+
run_client = RunClient(client)
|
24
|
+
response = run_client.run(
|
25
|
+
resource_type="function",
|
26
|
+
resource_name="my-function",
|
27
|
+
environment="prod",
|
28
|
+
method="POST",
|
29
|
+
json={"key": "value"}
|
30
|
+
)
|
31
|
+
```
|
32
|
+
|
33
|
+
Args:
|
34
|
+
client (AuthenticatedClient): An authenticated client instance for making HTTP requests.
|
35
|
+
"""
|
36
|
+
|
11
37
|
def __init__(self, client: AuthenticatedClient):
|
12
38
|
self.client = client
|
13
39
|
|
@@ -23,6 +49,25 @@ class RunClient:
|
|
23
49
|
data: str | None = None,
|
24
50
|
params: dict[str, str] | None = None,
|
25
51
|
) -> requests.Response:
|
52
|
+
"""Execute an HTTP request against a Beamlit resource.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
resource_type (str): The type of resource to interact with (e.g., 'function', 'service').
|
56
|
+
resource_name (str): The name of the specific resource.
|
57
|
+
environment (str): The environment to execute the request in.
|
58
|
+
method (str): The HTTP method to use (e.g., 'GET', 'POST', 'PUT', 'DELETE').
|
59
|
+
path (str, optional): Additional path segments to append to the resource URL. Defaults to "".
|
60
|
+
headers (dict[str, str] | None, optional): HTTP headers to include in the request. Defaults to None.
|
61
|
+
json (dict[str, Any] | None, optional): JSON payload to send with the request. Defaults to None.
|
62
|
+
data (str | None, optional): Raw data to send with the request. Defaults to None.
|
63
|
+
params (dict[str, str] | None, optional): Query parameters to include in the URL. Defaults to None.
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
requests.Response: The HTTP response from the server.
|
67
|
+
|
68
|
+
Raises:
|
69
|
+
HTTPError: If the server responds with a status code >= 400.
|
70
|
+
"""
|
26
71
|
settings = get_settings()
|
27
72
|
headers = headers or {}
|
28
73
|
params = params or {}
|
beamlit/serve/app.py
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
"""Module: app
|
2
|
+
|
3
|
+
This module sets up and runs the Beamlit server using FastAPI.
|
4
|
+
It configures middleware, handles server lifespan events, and defines endpoints.
|
5
|
+
"""
|
6
|
+
|
1
7
|
import asyncio
|
2
8
|
import importlib
|
9
|
+
import inspect
|
3
10
|
import os
|
4
11
|
import sys
|
5
12
|
import traceback
|
6
|
-
import inspect
|
7
13
|
from contextlib import asynccontextmanager
|
8
14
|
from logging import getLogger
|
9
15
|
from uuid import uuid4
|
@@ -13,10 +19,7 @@ from fastapi import FastAPI, Request, Response, WebSocket
|
|
13
19
|
from fastapi.responses import JSONResponse
|
14
20
|
|
15
21
|
from beamlit.common import HTTPError, get_settings, init
|
16
|
-
from beamlit.common.instrumentation import
|
17
|
-
instrument_app,
|
18
|
-
shutdown_instrumentation,
|
19
|
-
)
|
22
|
+
from beamlit.common.instrumentation import instrument_app, shutdown_instrumentation
|
20
23
|
|
21
24
|
from .middlewares import AccessLogMiddleware, AddProcessTimeHeader
|
22
25
|
|
@@ -25,6 +28,11 @@ sys.path.insert(0, os.path.join(os.getcwd(), "src"))
|
|
25
28
|
|
26
29
|
|
27
30
|
def import_module():
|
31
|
+
"""Dynamically imports the main server module based on settings.
|
32
|
+
|
33
|
+
Returns:
|
34
|
+
Callable: The main function to run the server.
|
35
|
+
"""
|
28
36
|
settings = get_settings()
|
29
37
|
main_module = importlib.import_module(".".join(settings.server.module.split(".")[0:-1]))
|
30
38
|
func = getattr(main_module, settings.server.module.split(".")[-1])
|
@@ -46,6 +54,11 @@ if "websocket" in func_params:
|
|
46
54
|
|
47
55
|
@asynccontextmanager
|
48
56
|
async def lifespan(app: FastAPI):
|
57
|
+
"""Manages the lifespan events of the FastAPI application.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
app (FastAPI): The FastAPI application instance.
|
61
|
+
"""
|
49
62
|
yield
|
50
63
|
shutdown_instrumentation()
|
51
64
|
|
@@ -62,6 +75,11 @@ instrument_app(app)
|
|
62
75
|
|
63
76
|
@app.get("/health")
|
64
77
|
async def health():
|
78
|
+
"""Health check endpoint.
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
dict: A simple status message indicating the server is running.
|
82
|
+
"""
|
65
83
|
return {"status": "ok"}
|
66
84
|
|
67
85
|
if websocket_detected:
|
@@ -1,10 +1,26 @@
|
|
1
|
+
"""Module: accesslog
|
2
|
+
|
3
|
+
Defines the AccessLogMiddleware for logging HTTP requests and responses.
|
4
|
+
"""
|
5
|
+
|
1
6
|
from logging import getLogger
|
2
7
|
|
3
8
|
from starlette.middleware.base import BaseHTTPMiddleware
|
4
9
|
|
5
10
|
|
6
11
|
class AccessLogMiddleware(BaseHTTPMiddleware):
|
12
|
+
"""Middleware for logging access information of each HTTP request."""
|
13
|
+
|
7
14
|
async def dispatch(self, request, call_next):
|
15
|
+
"""Processes each request to log access details.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
request (Request): The incoming HTTP request.
|
19
|
+
call_next (Callable): The next middleware or endpoint handler.
|
20
|
+
|
21
|
+
Returns:
|
22
|
+
Response: The HTTP response generated by the next handler.
|
23
|
+
"""
|
8
24
|
logger = getLogger(__name__)
|
9
25
|
response = await call_next(request)
|
10
26
|
process_time = response.headers.get("X-Process-Time")
|
@@ -1,10 +1,26 @@
|
|
1
|
+
"""Module: processtime
|
2
|
+
|
3
|
+
Defines the AddProcessTimeHeader middleware for adding process time information to responses.
|
4
|
+
"""
|
5
|
+
|
1
6
|
import time
|
2
7
|
|
3
8
|
from starlette.middleware.base import BaseHTTPMiddleware
|
4
9
|
|
5
10
|
|
6
11
|
class AddProcessTimeHeader(BaseHTTPMiddleware):
|
12
|
+
"""Middleware to add the X-Process-Time header to each HTTP response."""
|
13
|
+
|
7
14
|
async def dispatch(self, request, call_next):
|
15
|
+
"""Calculates and adds the processing time to the response headers.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
request (Request): The incoming HTTP request.
|
19
|
+
call_next (Callable): The next middleware or endpoint handler.
|
20
|
+
|
21
|
+
Returns:
|
22
|
+
Response: The HTTP response with the X-Process-Time header added.
|
23
|
+
"""
|
8
24
|
start_time = time.perf_counter()
|
9
25
|
response = await call_next(request)
|
10
26
|
process_time = (time.perf_counter() - start_time) * 1000
|