Skip to content

Commit cbde735

Browse files
committed
lint
1 parent a65f7bc commit cbde735

File tree

1 file changed

+83
-46
lines changed
  • supporting-blog-content/serverless-ai-agent

1 file changed

+83
-46
lines changed

supporting-blog-content/serverless-ai-agent/main.py

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,28 @@
77
from llama_index.agent.openai import OpenAIAgent
88
from llama_index.llms.openai import OpenAI
99

10-
load_dotenv('.env')
10+
load_dotenv(".env")
1111
PROJECTS_FILE = "projects.json"
1212

13+
1314
def load_projects():
1415
"""Load the project mapping from the JSON file."""
1516
if os.path.exists(PROJECTS_FILE):
1617
with open(PROJECTS_FILE, "r") as f:
1718
return json.load(f)
1819
return {}
1920

21+
2022
def save_projects(project_map):
2123
"""Save the project mapping to the JSON file."""
2224
with open(PROJECTS_FILE, "w") as f:
2325
json.dump(project_map, f)
2426

27+
2528
# Store project name -> project info mapping.
2629
PROJECT_MAP = load_projects()
2730

31+
2832
def normalize_project_info(project_info):
2933
"""
3034
Ensure that the project info is a dictionary.
@@ -34,6 +38,7 @@ def normalize_project_info(project_info):
3438
return {"id": project_info}
3539
return project_info
3640

41+
3742
def create_ess_project(project_name: str) -> str:
3843
"""
3944
Creates a Serverless project by calling the ESS API.
@@ -52,15 +57,11 @@ def create_ess_project(project_name: str) -> str:
5257
return "Error: API_KEY is not set in the environment."
5358

5459
url = f"{env_url}/api/v1/serverless/projects/elasticsearch"
55-
headers = {
56-
"Authorization": f"ApiKey {api_key}",
57-
"Content-Type": "application/json"
58-
}
59-
payload = {
60-
"name": project_name,
61-
"region_id": region_id
62-
}
63-
60+
61+
headers = {"Authorization": f"ApiKey {api_key}", "Content-Type": "application/json"}
62+
payload = {"name": project_name,"region_id": region_id}
63+
64+
6465
try:
6566
response = requests.post(url, headers=headers, json=payload)
6667
response.raise_for_status()
@@ -73,25 +74,31 @@ def create_ess_project(project_name: str) -> str:
7374
return "Error: No project ID returned from the API."
7475

7576
if not re.fullmatch(r"^[a-z0-9]{32}$", project_id):
76-
return f"Error: Received project ID '{project_id}' does not match expected format."
77-
77+
return (
78+
f"Error: Received project ID '{project_id}' does not match expected format."
79+
)
80+
81+
7882
credentials = data.get("credentials")
7983
endpoints = data.get("endpoints")
8084

8185
PROJECT_MAP[project_name] = {
8286
"id": project_id,
8387
"credentials": credentials,
84-
"endpoints": endpoints
88+
"endpoints": endpoints,
8589
}
8690
save_projects(PROJECT_MAP)
87-
91+
92+
8893
summary = (
8994
f"Project '{project_name}' created successfully.\n"
9095
f"Project ID: {project_id}\n"
9196
f"Endpoints: {endpoints}"
9297
)
9398
return summary
9499

100+
101+
95102
def delete_ess_project(project_name: str) -> str:
96103
"""
97104
Deletes a Serverless project by using the project name.
@@ -102,32 +109,36 @@ def delete_ess_project(project_name: str) -> str:
102109
if not project_info:
103110
return f"Error: No project found with name '{project_name}'. Ensure the project was created previously."
104111
project_info = normalize_project_info(project_info)
105-
112+
113+
106114
project_id = project_info.get("id")
107115
env_url = os.environ.get("ES_URL")
108116
api_key = os.environ.get("API_KEY")
109-
117+
118+
110119
if not env_url:
111120
return "Error: ES_URL is not set in the environment."
112121
if not api_key:
113122
return "Error: API_KEY is not set in the environment."
114-
123+
124+
115125
url = f"{env_url}/api/v1/serverless/projects/elasticsearch/{project_id}"
116-
headers = {
117-
"Authorization": f"ApiKey {api_key}",
118-
"Content-Type": "application/json"
119-
}
126+
headers = {"Authorization": f"ApiKey {api_key}","Content-Type": "application/json"}
120127

128+
121129
try:
122130
response = requests.delete(url, headers=headers)
123131
response.raise_for_status()
124132
except requests.exceptions.RequestException as e:
125133
return f"Error during project deletion: {e}"
126-
134+
135+
127136
del PROJECT_MAP[project_name]
128137
save_projects(PROJECT_MAP)
129138
return f"Project '{project_name}' (ID: {project_id}) deleted successfully."
130139

140+
141+
131142
def get_ess_project_status(project_name: str) -> str:
132143
"""
133144
Retrieves the status of a Serverless project by using its project name.
@@ -138,19 +149,22 @@ def get_ess_project_status(project_name: str) -> str:
138149
if not project_info:
139150
return f"Error: No project found with name '{project_name}'."
140151
project_info = normalize_project_info(project_info)
141-
152+
153+
142154
project_id = project_info.get("id")
143155
env_url = os.environ.get("ES_URL")
144156
api_key = os.environ.get("API_KEY")
145-
157+
158+
146159
if not env_url:
147160
return "Error: ES_URL is not set in the environment."
148161
if not api_key:
149162
return "Error: API_KEY is not set in the environment."
150163

151164
url = f"{env_url}/api/v1/serverless/projects/elasticsearch/{project_id}/status"
152165
headers = {"Authorization": f"ApiKey {api_key}"}
153-
166+
167+
154168
try:
155169
response = requests.get(url, headers=headers)
156170
response.raise_for_status()
@@ -160,6 +174,7 @@ def get_ess_project_status(project_name: str) -> str:
160174
status_data = response.json()
161175
return json.dumps(status_data, indent=4)
162176

177+
163178
def get_ess_project_details(project_name: str) -> str:
164179
"""
165180
Retrieves the full details of a Serverless project by using its project name.
@@ -171,25 +186,29 @@ def get_ess_project_details(project_name: str) -> str:
171186
if not project_info:
172187
return f"Error: No project found with name '{project_name}'."
173188
project_info = normalize_project_info(project_info)
174-
189+
190+
175191
project_id = project_info.get("id")
176192
env_url = os.environ.get("ES_URL")
177193
api_key = os.environ.get("API_KEY")
178-
194+
195+
179196
if not env_url:
180197
return "Error: ES_URL is not set in the environment."
181198
if not api_key:
182199
return "Error: API_KEY is not set in the environment."
183200

184201
url = f"{env_url}/api/v1/serverless/projects/elasticsearch/{project_id}"
185202
headers = {"Authorization": f"ApiKey {api_key}"}
186-
203+
204+
187205
try:
188206
response = requests.get(url, headers=headers)
189207
response.raise_for_status()
190208
except requests.exceptions.RequestException as e:
191209
return f"Error retrieving project details: {e}"
192-
210+
211+
193212
details_data = response.json()
194213
if not details_data.get("credentials"):
195214
details_data["credentials"] = project_info.get("credentials")
@@ -198,6 +217,7 @@ def get_ess_project_details(project_name: str) -> str:
198217
return json.dumps(details_data, indent=4)
199218

200219

220+
201221
def get_index_status_in_project(project_name: str, index_name: str) -> str:
202222
"""
203223
Retrieves the status/details of an index in a Serverless Elasticsearch project.
@@ -213,37 +233,49 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
213233
if not project_info:
214234
return f"Error: No project found with name '{project_name}'. Ensure the project was created previously."
215235
project_info = normalize_project_info(project_info)
216-
236+
237+
217238
project_id = project_info.get("id")
218239
env_url = os.environ.get("ES_URL")
219240
api_key = os.environ.get("API_KEY")
220241
if not env_url or not api_key:
221242
return "Error: ES_URL or API_KEY is not set in the environment."
222-
243+
244+
223245
details_url = f"{env_url}/api/v1/serverless/projects/elasticsearch/{project_id}"
224246
headers = {"Authorization": f"ApiKey {api_key}"}
225247
try:
226248
resp = requests.get(details_url, headers=headers)
227249
resp.raise_for_status()
228250
except requests.exceptions.RequestException as e:
229251
return f"Error retrieving project details: {e}"
230-
252+
253+
231254
details_data = resp.json()
232255
credentials = details_data.get("credentials") or project_info.get("credentials")
233256
endpoints = details_data.get("endpoints") or project_info.get("endpoints")
234-
235-
if not credentials or not credentials.get("username") or not credentials.get("password"):
236-
return ("Error: Credentials not available. The project may still be initializing. "
237-
"Please wait a few minutes and try again.")
257+
258+
259+
if (
260+
not credentials
261+
or not credentials.get("username")
262+
or not credentials.get("password")
263+
):
264+
return (
265+
"Error: Credentials not available. The project may still be initializing. "
266+
"Please wait a few minutes and try again."
267+
)
238268

239269
if not endpoints or not endpoints.get("elasticsearch"):
240270
return "Error: Elasticsearch endpoint not found in project details."
241-
271+
272+
242273
username = credentials.get("username")
243274
password = credentials.get("password")
244275
es_endpoint = endpoints.get("elasticsearch")
245276
index_url = f"{es_endpoint}/{index_name}"
246-
277+
278+
247279
try:
248280
index_resp = requests.get(index_url, auth=(username, password))
249281
index_resp.raise_for_status()
@@ -252,6 +284,7 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
252284

253285
return json.dumps(index_resp.json(), indent=4)
254286

287+
255288
create_project_tool = FunctionTool.from_defaults(
256289
create_ess_project,
257290
name="create_ess_project",
@@ -260,7 +293,7 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
260293
"It requires a single parameter: project_name. "
261294
"The API environment URL (ES_URL), API key (API_KEY), and region (REGION) are read from the environment (.env file). "
262295
"The function stores the project details (ID, credentials, endpoints) for later use and persists them to a file."
263-
)
296+
),
264297
)
265298

266299
delete_project_tool = FunctionTool.from_defaults(
@@ -270,7 +303,7 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
270303
"Deletes a Serverless Elasticsearch project using its project name. "
271304
"It automatically looks up the project ID (stored during project creation and persisted in a file) and deletes the project. "
272305
"It returns a confirmation message or an error message."
273-
)
306+
),
274307
)
275308

276309
get_status_tool = FunctionTool.from_defaults(
@@ -280,7 +313,7 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
280313
"Retrieves the status of a Serverless Elasticsearch project by using its project name. "
281314
"It looks up the project ID (from a persisted mapping) and calls the /status endpoint. "
282315
"It returns the status information as a JSON string."
283-
)
316+
),
284317
)
285318

286319
get_details_tool = FunctionTool.from_defaults(
@@ -290,28 +323,32 @@ def get_index_status_in_project(project_name: str, index_name: str) -> str:
290323
"Retrieves the full details of a Serverless Elasticsearch project by using its project name. "
291324
"It looks up the project ID (from a persisted mapping) and calls the GET project endpoint. "
292325
"It returns the project details as a JSON string."
293-
)
326+
),
294327
)
295328

296329
openai_api_key = os.environ.get("OPENAI_API_KEY")
297330
if not openai_api_key:
298-
raise ValueError("Please set the OPENAI_API_KEY environment variable with your OpenAI API key.")
331+
raise ValueError(
332+
"Please set the OPENAI_API_KEY environment variable with your OpenAI API key."
333+
)
299334

300335
llm = OpenAI(model="gpt-4o", api_key=openai_api_key)
301336
agent = OpenAIAgent.from_tools(
302337
[create_project_tool, delete_project_tool, get_status_tool, get_details_tool],
303338
llm=llm,
304-
verbose=True
339+
verbose=True,
305340
)
306341

342+
307343
def main():
308344
print("\nWelcome to the Serverless Project AI Agent Tool!\n")
309345
print("You can ask things like:")
310346
print(" - 'Create a serverless project named my_project'")
311347
print(" - 'Delete the serverless project named my_project'")
312348
print(" - 'Get the status of the serverless project named my_project'")
313349
print(" - 'Get the details of the serverless project named my_project'")
314-
350+
351+
315352
while True:
316353
user_input = input("\nUser: ")
317354
if user_input.strip().lower() in {"exit", "quit"}:
@@ -321,4 +358,4 @@ def main():
321358
print("\nAgent:", response)
322359

323360
if __name__ == "__main__":
324-
main()
361+
main()

0 commit comments

Comments
 (0)