swarms 7.7.8__py3-none-any.whl → 7.7.9__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.
swarms/client/main.py DELETED
@@ -1,407 +0,0 @@
1
- import json
2
- import os
3
- from typing import List, Literal, Optional
4
-
5
- import httpx
6
- from swarms.utils.loguru_logger import initialize_logger
7
- from pydantic import BaseModel, Field
8
- from tenacity import retry, stop_after_attempt, wait_exponential
9
- from swarms.structs.swarm_router import SwarmType
10
- from typing import Any
11
-
12
- logger = initialize_logger(log_folder="swarms_api")
13
-
14
-
15
- class AgentInput(BaseModel):
16
- agent_name: Optional[str] = Field(
17
- None,
18
- description="The name of the agent, limited to 100 characters.",
19
- max_length=100,
20
- )
21
- description: Optional[str] = Field(
22
- None,
23
- description="A detailed description of the agent's purpose and capabilities, up to 500 characters.",
24
- max_length=500,
25
- )
26
- system_prompt: Optional[str] = Field(
27
- None,
28
- description="The initial prompt or instructions given to the agent.",
29
- )
30
- model_name: Optional[str] = Field(
31
- "gpt-4o",
32
- description="The name of the model used by the agent. Model names can be configured like provider/model_name",
33
- )
34
- auto_generate_prompt: Optional[bool] = Field(
35
- False,
36
- description="Indicates whether the agent should automatically generate prompts.",
37
- )
38
- max_tokens: Optional[int] = Field(
39
- 8192,
40
- description="The maximum number of tokens the agent can use in its responses.",
41
- )
42
- temperature: Optional[float] = Field(
43
- 0.5,
44
- description="Controls the randomness of the agent's responses; higher values result in more random outputs.",
45
- )
46
- role: Optional[str] = Field(
47
- "worker",
48
- description="The role assigned to the agent, such as 'worker' or 'manager'.",
49
- )
50
- max_loops: Optional[int] = Field(
51
- 1,
52
- description="The maximum number of iterations the agent is allowed to perform.",
53
- )
54
- dynamic_temperature_enabled: Optional[bool] = Field(
55
- True,
56
- description="Indicates whether the agent should use dynamic temperature.",
57
- )
58
-
59
-
60
- class SwarmRequest(BaseModel):
61
- name: Optional[str] = Field(
62
- "swarms-01",
63
- description="The name of the swarm, limited to 100 characters.",
64
- max_length=100,
65
- )
66
- description: Optional[str] = Field(
67
- None,
68
- description="A comprehensive description of the swarm's objectives and scope, up to 500 characters.",
69
- max_length=500,
70
- )
71
- agents: Optional[List[AgentInput]] = Field(
72
- None,
73
- description="A list of agents that are part of the swarm.",
74
- )
75
- max_loops: Optional[int] = Field(
76
- 1,
77
- description="The maximum number of iterations the swarm can execute.",
78
- )
79
- swarm_type: Optional[SwarmType] = Field(
80
- None,
81
- description="The type of swarm, defining its operational structure and behavior.",
82
- )
83
- rearrange_flow: Optional[str] = Field(
84
- None,
85
- description="The flow or sequence in which agents are rearranged during the swarm's operation.",
86
- )
87
- task: Optional[str] = Field(
88
- None,
89
- description="The specific task or objective the swarm is designed to accomplish.",
90
- )
91
- img: Optional[str] = Field(
92
- None,
93
- description="A URL to an image associated with the swarm, if applicable.",
94
- )
95
- return_history: Optional[bool] = Field(
96
- True,
97
- description="Determines whether the full history of the swarm's operations should be returned.",
98
- )
99
- rules: Optional[str] = Field(
100
- None,
101
- description="Any specific rules or guidelines that the swarm should follow.",
102
- )
103
- output_type: Optional[str] = Field(
104
- "str",
105
- description="The format in which the swarm's output should be returned, such as 'str', 'json', or 'dict'.",
106
- )
107
-
108
-
109
- # class SwarmResponse(BaseModel):
110
- # swarm_id: str
111
- # status: str
112
- # result: Optional[str]
113
- # error: Optional[str]
114
-
115
-
116
- class HealthResponse(BaseModel):
117
- status: str
118
- version: str
119
-
120
-
121
- class SwarmAPIError(Exception):
122
- """Base exception for Swarms API errors."""
123
-
124
- pass
125
-
126
-
127
- class SwarmAuthenticationError(SwarmAPIError):
128
- """Raised when authentication fails."""
129
-
130
- pass
131
-
132
-
133
- class SwarmValidationError(SwarmAPIError):
134
- """Raised when request validation fails."""
135
-
136
- pass
137
-
138
-
139
- class SwarmsAPIClient:
140
- """Production-grade client for the Swarms API."""
141
-
142
- def __init__(
143
- self,
144
- api_key: Optional[str] = None,
145
- base_url: str = "https://api.swarms.world",
146
- timeout: int = 30,
147
- max_retries: int = 3,
148
- format_type: Literal["pydantic", "json", "dict"] = "pydantic",
149
- ):
150
- """Initialize the Swarms API client.
151
-
152
- Args:
153
- api_key: API key for authentication. If not provided, looks for SWARMS_API_KEY env var
154
- base_url: Base URL for the API
155
- timeout: Request timeout in seconds
156
- max_retries: Maximum number of retries for failed requests
157
- format_type: Desired output format ('pydantic', 'json', 'dict')
158
- """
159
- self.api_key = api_key or os.getenv("SWARMS_API_KEY")
160
-
161
- if not self.api_key:
162
- logger.error(
163
- "API key not provided and SWARMS_API_KEY env var not found"
164
- )
165
- raise SwarmAuthenticationError(
166
- "API key not provided and SWARMS_API_KEY env var not found"
167
- )
168
-
169
- self.base_url = base_url.rstrip("/")
170
- self.timeout = timeout
171
- self.max_retries = max_retries
172
- self.format_type = format_type
173
- # Setup HTTP client
174
- self.client = httpx.Client(
175
- timeout=timeout,
176
- headers={
177
- "x-api-key": self.api_key,
178
- "Content-Type": "application/json",
179
- },
180
- )
181
- logger.info(
182
- "SwarmsAPIClient initialized with base_url: {}",
183
- self.base_url,
184
- )
185
-
186
- @retry(
187
- stop=stop_after_attempt(3),
188
- wait=wait_exponential(multiplier=1, min=4, max=10),
189
- reraise=True,
190
- )
191
- async def health_check(self) -> HealthResponse:
192
- """Check the API health status.
193
-
194
- Args:
195
- output_format: Desired output format ('pydantic', 'json', 'dict')
196
-
197
- Returns:
198
- HealthResponse object or formatted output
199
- """
200
- logger.info("Performing health check")
201
- try:
202
- response = self.client.get(f"{self.base_url}/health")
203
- response.raise_for_status()
204
- health_response = HealthResponse(**response.json())
205
- logger.info("Health check successful")
206
- return self.format_output(
207
- health_response, self.format_type
208
- )
209
- except httpx.HTTPError as e:
210
- logger.error("Health check failed: {}", str(e))
211
- raise SwarmAPIError(f"Health check failed: {str(e)}")
212
-
213
- @retry(
214
- stop=stop_after_attempt(3),
215
- wait=wait_exponential(multiplier=1, min=4, max=10),
216
- reraise=True,
217
- )
218
- async def arun(self, swarm_request: SwarmRequest) -> Any:
219
- """Create and run a new swarm.
220
-
221
- Args:
222
- swarm_request: SwarmRequest object containing the swarm configuration
223
- output_format: Desired output format ('pydantic', 'json', 'dict')
224
-
225
- Returns:
226
- SwarmResponse object or formatted output
227
- """
228
- logger.info(
229
- "Creating and running a new swarm with request: {}",
230
- swarm_request,
231
- )
232
- try:
233
- response = self.client.post(
234
- f"{self.base_url}/v1/swarm/completions",
235
- json=swarm_request.model_dump(),
236
- )
237
- response.raise_for_status()
238
- logger.info("Swarm creation and run successful")
239
- return self.format_output(
240
- response.json(), self.format_type
241
- )
242
- except httpx.HTTPStatusError as e:
243
- if e.response.status_code == 401:
244
- logger.error("Invalid API key")
245
- raise SwarmAuthenticationError("Invalid API key")
246
- elif e.response.status_code == 422:
247
- logger.error("Invalid request parameters")
248
- raise SwarmValidationError(
249
- "Invalid request parameters"
250
- )
251
- logger.error("Swarm creation failed: {}", str(e))
252
- raise SwarmAPIError(f"Swarm creation failed: {str(e)}")
253
- except Exception as e:
254
- logger.error(
255
- "Unexpected error during swarm creation: {}", str(e)
256
- )
257
- raise
258
-
259
- @retry(
260
- stop=stop_after_attempt(3),
261
- wait=wait_exponential(multiplier=1, min=4, max=10),
262
- reraise=True,
263
- )
264
- def run(self, swarm_request: SwarmRequest) -> Any:
265
- """Create and run a new swarm.
266
-
267
- Args:
268
- swarm_request: SwarmRequest object containing the swarm configuration
269
- output_format: Desired output format ('pydantic', 'json', 'dict')
270
-
271
- Returns:
272
- SwarmResponse object or formatted output
273
- """
274
- logger.info(
275
- "Creating and running a new swarm with request: {}",
276
- swarm_request,
277
- )
278
- try:
279
- response = self.client.post(
280
- f"{self.base_url}/v1/swarm/completions",
281
- json=swarm_request.model_dump(),
282
- )
283
- print(response.json())
284
- logger.info("Swarm creation and run successful")
285
- return response.json()
286
- except httpx.HTTPStatusError as e:
287
- if e.response.status_code == 401:
288
- logger.error("Invalid API key")
289
- raise SwarmAuthenticationError("Invalid API key")
290
- elif e.response.status_code == 422:
291
- logger.error("Invalid request parameters")
292
- raise SwarmValidationError(
293
- "Invalid request parameters"
294
- )
295
- logger.error("Swarm creation failed: {}", str(e))
296
- raise SwarmAPIError(f"Swarm creation failed: {str(e)}")
297
- except Exception as e:
298
- logger.error(
299
- "Unexpected error during swarm creation: {}", str(e)
300
- )
301
- raise
302
-
303
- @retry(
304
- stop=stop_after_attempt(3),
305
- wait=wait_exponential(multiplier=1, min=4, max=10),
306
- reraise=True,
307
- )
308
- async def run_batch(
309
- self, swarm_requests: List[SwarmRequest]
310
- ) -> List[Any]:
311
- """Create and run multiple swarms in batch.
312
-
313
- Args:
314
- swarm_requests: List of SwarmRequest objects
315
- output_format: Desired output format ('pydantic', 'json', 'dict')
316
-
317
- Returns:
318
- List of SwarmResponse objects or formatted outputs
319
- """
320
- logger.info(
321
- "Creating and running batch swarms with requests: {}",
322
- swarm_requests,
323
- )
324
- try:
325
- response = self.client.post(
326
- f"{self.base_url}/v1/swarm/batch/completions",
327
- json=[req.model_dump() for req in swarm_requests],
328
- )
329
- response.raise_for_status()
330
- logger.info("Batch swarm creation and run successful")
331
- return [
332
- self.format_output(resp, self.format_type)
333
- for resp in response.json()
334
- ]
335
- except httpx.HTTPStatusError as e:
336
- if e.response.status_code == 401:
337
- logger.error("Invalid API key")
338
- raise SwarmAuthenticationError("Invalid API key")
339
- elif e.response.status_code == 422:
340
- logger.error("Invalid request parameters")
341
- raise SwarmValidationError(
342
- "Invalid request parameters"
343
- )
344
- logger.error("Batch swarm creation failed: {}", str(e))
345
- raise SwarmAPIError(
346
- f"Batch swarm creation failed: {str(e)}"
347
- )
348
- except Exception as e:
349
- logger.error(
350
- "Unexpected error during batch swarm creation: {}",
351
- str(e),
352
- )
353
- raise
354
-
355
- def get_logs(self):
356
- logger.info("Retrieving logs")
357
- try:
358
- response = self.client.get(
359
- f"{self.base_url}/v1/swarm/logs"
360
- )
361
- response.raise_for_status()
362
- logs = response.json()
363
- logger.info("Logs retrieved successfully")
364
- return self.format_output(logs, self.format_type)
365
- except httpx.HTTPError as e:
366
- logger.error("Failed to retrieve logs: {}", str(e))
367
- raise SwarmAPIError(f"Failed to retrieve logs: {str(e)}")
368
-
369
- def format_output(self, data, output_format: str):
370
- """Format the output based on the specified format.
371
-
372
- Args:
373
- data: The data to format
374
- output_format: The desired output format ('pydantic', 'json', 'dict')
375
-
376
- Returns:
377
- Formatted data
378
- """
379
- logger.info(
380
- "Formatting output with format: {}", output_format
381
- )
382
- if output_format == "json":
383
- return (
384
- data.model_dump_json(indent=4)
385
- if isinstance(data, BaseModel)
386
- else json.dumps(data)
387
- )
388
- elif output_format == "dict":
389
- return (
390
- data.model_dump()
391
- if isinstance(data, BaseModel)
392
- else data
393
- )
394
- return data # Default to returning the pydantic model
395
-
396
- def close(self):
397
- """Close the HTTP client."""
398
- logger.info("Closing HTTP client")
399
- self.client.close()
400
-
401
- async def __aenter__(self):
402
- logger.info("Entering async context")
403
- return self
404
-
405
- async def __aexit__(self, exc_type, exc_val, exc_tb):
406
- logger.info("Exiting async context")
407
- self.close()