3131
3232
3333class CloudAgentEngine (BaseModel ):
34+ """Manages cloud agent deployment and operations on Volcengine FaaS platform.
35+
36+ This class handles authentication with Volcengine, deploys local projects to FaaS,
37+ updates function code, removes applications, and supports local testing.
38+
39+ Attributes:
40+ volcengine_access_key (str): Access key for Volcengine authentication.
41+ Defaults to VOLCENGINE_ACCESS_KEY environment variable.
42+ volcengine_secret_key (str): Secret key for Volcengine authentication.
43+ Defaults to VOLCENGINE_SECRET_KEY environment variable.
44+ region (str): Region for Volcengine services. Defaults to "cn-beijing".
45+ _vefaas_service (VeFaaS): Internal VeFaaS client instance, initialized post-creation.
46+
47+ Note:
48+ Credentials must be set via environment variables for default behavior.
49+ This class performs interactive confirmations for destructive operations like removal.
50+
51+ Example:
52+ >>> from veadk.cloud.cloud_agent_engine import CloudAgentEngine
53+ >>> engine = CloudAgentEngine()
54+ >>> app = engine.deploy("test-app", "/path/to/local/project")
55+ >>> print(app.vefaas_endpoint)
56+ """
57+
3458 volcengine_access_key : str = getenv ("VOLCENGINE_ACCESS_KEY" )
3559 volcengine_secret_key : str = getenv ("VOLCENGINE_SECRET_KEY" )
3660 region : str = "cn-beijing"
3761
3862 def model_post_init (self , context : Any , / ) -> None :
63+ """Initializes the internal VeFaaS service after Pydantic model validation.
64+
65+ Creates a VeFaaS instance using the configured access key, secret key, and region.
66+
67+ Args:
68+ self: The CloudAgentEngine instance.
69+ context: Pydantic post-init context parameter (not used).
70+
71+ Returns:
72+ None
73+
74+ Note:
75+ This is a Pydantic lifecycle method, ensuring service readiness after init.
76+ """
3977 self ._vefaas_service = VeFaaS (
4078 access_key = self .volcengine_access_key ,
4179 secret_key = self .volcengine_secret_key ,
4280 region = self .region ,
4381 )
4482
4583 def _prepare (self , path : str , name : str ):
84+ """Prepares the local project for deployment by validating path and name.
85+
86+ Checks if the path exists and is a directory, validates application name format.
87+
88+ Args:
89+ path (str): Full or relative path to the local agent project directory.
90+ name (str): Intended VeFaaS application name.
91+
92+ Returns:
93+ None
94+
95+ Raises:
96+ AssertionError: If path does not exist or is not a directory.
97+ ValueError: If name contains invalid characters like underscores.
98+
99+ Note:
100+ Includes commented code for handling requirements.txt; not executed currently.
101+ Called internally by deploy and update methods.
102+ """
46103 # basic check
47104 assert os .path .exists (path ), f"Local agent project path `{ path } ` not exists."
48105 assert os .path .isdir (path ), (
@@ -73,10 +130,23 @@ def _prepare(self, path: str, name: str):
73130 # )
74131
75132 def _try_launch_fastapi_server (self , path : str ):
76- """Try to launch a fastapi server for tests according to user's configuration.
133+ """Tries to start a FastAPI server locally for testing deployment readiness.
134+
135+ Runs the project's run.sh script and checks connectivity on port 8000.
77136
78137 Args:
79- path (str): Local agent project path.
138+ path (str): Path to the local project containing run.sh.
139+
140+ Returns:
141+ None
142+
143+ Raises:
144+ RuntimeError: If server startup times out after 30 seconds.
145+
146+ Note:
147+ Sets _FAAS_FUNC_TIMEOUT environment to 900 seconds.
148+ Streams output to console and terminates process after successful check.
149+ Assumes run.sh launches server on 0.0.0.0:8000.
80150 """
81151 RUN_SH = f"{ path } /run.sh"
82152
@@ -128,19 +198,32 @@ def deploy(
128198 use_adk_web : bool = False ,
129199 local_test : bool = False ,
130200 ) -> CloudApp :
131- """Deploy local agent project to Volcengine FaaS platform.
201+ """Deploys a local agent project to Volcengine FaaS, creating necessary resources.
202+
203+ Prepares project, optionally tests locally, deploys via VeFaaS, and returns app instance.
132204
133205 Args:
134- application_name (str): Expected VeFaaS application name .
135- path (str): Local agent project path .
136- gateway_name (str): Gateway name.
137- gateway_service_name (str): Gateway service name.
138- gateway_upstream_name (str): Gateway upstream name.
139- use_adk_web (bool): Whether to use ADK Web.
140- local_test (bool): Whether to run local test for FastAPI Server .
206+ application_name (str): Unique name for the VeFaaS application.
207+ path (str): Local directory path of the agent project.
208+ gateway_name (str, optional ): Custom gateway resource name. Defaults to timestamped .
209+ gateway_service_name (str, optional ): Custom service name. Defaults to timestamped .
210+ gateway_upstream_name (str, optional ): Custom upstream name. Defaults to timestamped .
211+ use_adk_web (bool): Enable ADK Web configuration. Defaults to False .
212+ local_test (bool): Perform FastAPI server test before deploy. Defaults to False .
141213
142214 Returns:
143- CloudApp: The deployed cloud application instance.
215+ CloudApp: Deployed application with endpoint, name, and ID.
216+
217+ Raises:
218+ ValueError: On deployment failure, such as invalid config or VeFaaS errors.
219+
220+ Note:
221+ Converts path to absolute; sets telemetry opt-out and ADK Web env vars.
222+ Generates default gateway names if not specified.
223+
224+ Example:
225+ >>> app = engine.deploy("my-agent", "./agent-project", local_test=True)
226+ >>> print(f"Deployed at: {app.vefaas_endpoint}")
144227 """
145228 # prevent deepeval writing operations
146229 veadk_environments ["DEEPEVAL_TELEMETRY_OPT_OUT" ] = "YES"
@@ -185,6 +268,27 @@ def deploy(
185268 )
186269
187270 def remove (self , app_name : str ):
271+ """Deletes a deployed cloud application after user confirmation.
272+
273+ Locates app by name, confirms, and issues delete via VeFaaS.
274+
275+ Args:
276+ app_name (str): Name of the application to remove.
277+
278+ Returns:
279+ None
280+
281+ Raises:
282+ ValueError: If application not found by name.
283+
284+ Note:
285+ Interactive prompt required; cancels on non-'y' input.
286+ Deletion is processed asynchronously by VeFaaS.
287+
288+ Example:
289+ >>> engine.remove("my-agent")
290+ Confirm delete cloud app my-agent? (y/N): y
291+ """
188292 confirm = input (f"Confirm delete cloud app { app_name } ? (y/N): " )
189293 if confirm .lower () != "y" :
190294 print ("Delete cancelled." )
@@ -202,14 +306,27 @@ def update_function_code(
202306 application_name : str ,
203307 path : str ,
204308 ) -> CloudApp :
205- """Update existing agent project code while keeping the same URL.
309+ """Updates the code in an existing VeFaaS application without changing endpoint.
310+
311+ Prepares new code from local path and updates function via VeFaaS.
206312
207313 Args:
208- application_name (str): Existing application name to update.
209- path (str): Local agent project path .
314+ application_name (str): Name of the existing application to update.
315+ path (str): Local path containing updated project files .
210316
211317 Returns:
212- CloudApp: Updated cloud app with same endpoint.
318+ CloudApp: Updated application instance with same endpoint.
319+
320+ Raises:
321+ ValueError: If update fails due to preparation or VeFaaS issues.
322+
323+ Note:
324+ Preserves gateway and other resources; only function code is updated.
325+ Path is resolved to absolute before processing.
326+
327+ Example:
328+ >>> updated_app = engine.update_function_code("my-agent", "./updated-project")
329+ >>> assert updated_app.vefaas_endpoint == old_endpoint
213330 """
214331 # convert `path` to absolute path
215332 path = str (Path (path ).resolve ())
0 commit comments