Skip to content

Commit 1729112

Browse files
committed
[CLEANUP][Code examples] [Example Guide][X402 Example]
1 parent efe293d commit 1729112

9 files changed

Lines changed: 336 additions & 60 deletions
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# X402 Payment Integration with Swarms Agents
2+
3+
X402 is a protocol that enables seamless cryptocurrency payments for API endpoints. This guide demonstrates how to monetize your Swarms agents by integrating X402 payment requirements into your FastAPI applications.
4+
5+
With X402, you can:
6+
7+
| Feature | Description |
8+
|-----------------------------------------------------|----------------------------------------------|
9+
| Charge per API request | Monetize your agents on a per-call basis |
10+
| Accept cryptocurrency payments | e.g., Base, Base Sepolia, and more |
11+
| Payment gate protection for agent endpoints | Secure endpoints with pay-to-access gates |
12+
| Create pay-per-use AI services | Offer AI agents as on-demand paid services |
13+
14+
## Prerequisites
15+
16+
Before you begin, ensure you have:
17+
18+
- Python 3.10 or higher
19+
- A cryptocurrency wallet address (for receiving payments)
20+
- API keys for your AI model provider (e.g., OpenAI)
21+
- An Exa API key (if using web search functionality)
22+
23+
## Installation
24+
25+
Install the required dependencies:
26+
27+
```bash
28+
pip install swarms x402 fastapi uvicorn python-dotenv swarms-tools
29+
```
30+
31+
## Environment Setup
32+
33+
Create a `.env` file in your project root:
34+
35+
```bash
36+
# OpenAI API Key
37+
OPENAI_API_KEY=your_openai_api_key_here
38+
39+
# Exa API Key (for web search)
40+
EXA_API_KEY=your_exa_api_key_here
41+
42+
# Your wallet address (where you'll receive payments)
43+
WALLET_ADDRESS=0xYourWalletAddressHere
44+
```
45+
46+
## Basic X402 Integration Example
47+
48+
Here's a complete example of a research agent with X402 payment integration:
49+
50+
```python
51+
from dotenv import load_dotenv
52+
from fastapi import FastAPI
53+
from swarms_tools import exa_search
54+
55+
from swarms import Agent
56+
from x402.fastapi.middleware import require_payment
57+
58+
# Load environment variables
59+
load_dotenv()
60+
61+
app = FastAPI(title="Research Agent API")
62+
63+
# Initialize the research agent
64+
research_agent = Agent(
65+
agent_name="Research-Agent",
66+
system_prompt="You are an expert research analyst. Conduct thorough research on the given topic and provide comprehensive, well-structured insights with citations.",
67+
model_name="gpt-4o-mini",
68+
max_loops=1,
69+
tools=[exa_search],
70+
)
71+
72+
73+
# Apply x402 payment middleware to the research endpoint
74+
app.middleware("http")(
75+
require_payment(
76+
path="/research",
77+
price="$0.01",
78+
pay_to_address="0xYourWalletAddressHere",
79+
network_id="base-sepolia",
80+
description="AI-powered research agent that conducts comprehensive research on any topic",
81+
input_schema={
82+
"type": "object",
83+
"properties": {
84+
"query": {
85+
"type": "string",
86+
"description": "Research topic or question",
87+
}
88+
},
89+
"required": ["query"],
90+
},
91+
output_schema={
92+
"type": "object",
93+
"properties": {
94+
"research": {
95+
"type": "string",
96+
"description": "Comprehensive research results",
97+
}
98+
},
99+
},
100+
)
101+
)
102+
103+
104+
@app.get("/research")
105+
async def conduct_research(query: str):
106+
"""
107+
Conduct research on a given topic using the research agent.
108+
109+
Args:
110+
query: The research topic or question
111+
112+
Returns:
113+
Research results from the agent
114+
"""
115+
result = research_agent.run(query)
116+
return {"research": result}
117+
118+
119+
@app.get("/")
120+
async def root():
121+
"""Health check endpoint (free, no payment required)"""
122+
return {
123+
"message": "Research Agent API with x402 payments",
124+
"endpoints": {
125+
"/research": "Paid endpoint - $0.01 per request",
126+
},
127+
}
128+
129+
130+
if __name__ == "__main__":
131+
import uvicorn
132+
133+
uvicorn.run(app, host="0.0.0.0", port=8000)
134+
```
135+
136+
137+
## Running Your Service
138+
139+
Start the server:
140+
141+
```bash
142+
python research_agent_x402_example.py
143+
```
144+
145+
Or with uvicorn directly:
146+
147+
```bash
148+
uvicorn research_agent_x402_example:app --host 0.0.0.0 --port 8000 --reload
149+
```
150+
151+
Your API will be available at:
152+
153+
- Main endpoint: `http://localhost:8000/`
154+
155+
- Research endpoint: `http://localhost:8000/research`
156+
157+
- API docs: `http://localhost:8000/docs`
158+
159+
160+
## Next Steps
161+
162+
1. Experiment with different pricing models
163+
2. Add multiple agents with specialized capabilities
164+
3. Implement analytics to track usage and revenue
165+
4. Deploy to production (see [Deployment Solutions](../deployment_solutions/overview.md))
166+
5. Integrate with your existing payment processing

docs/mkdocs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ nav:
433433
- AOP:
434434
- Medical AOP Example: "examples/aop_medical.md"
435435

436+
- X402:
437+
- x402 Quickstart Example: "examples/x402_payment_integration.md"
438+
436439

437440
- Swarms Cloud API:
438441
- Overview: "swarms_cloud/migration.md"

tests/structs/test_concurrent_workflow.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from swarms.structs.concurrent_workflow import ConcurrentWorkflow
33
import pytest
44

5+
56
def test_concurrent_workflow_basic_execution():
67
"""Test basic ConcurrentWorkflow execution with multiple agents"""
78
# Create specialized agents for different perspectives
@@ -54,7 +55,9 @@ def test_concurrent_workflow_basic_execution():
5455
for r in result:
5556
assert isinstance(r, dict)
5657
assert "role" in r # Agent name is stored in 'role' field
57-
assert "content" in r # Agent output is stored in 'content' field
58+
assert (
59+
"content" in r
60+
) # Agent output is stored in 'content' field
5861

5962

6063
def test_concurrent_workflow_with_dashboard():
@@ -106,7 +109,9 @@ def test_concurrent_workflow_with_dashboard():
106109
for r in result:
107110
assert isinstance(r, dict)
108111
assert "role" in r # Agent name is stored in 'role' field
109-
assert "content" in r # Agent output is stored in 'content' field
112+
assert (
113+
"content" in r
114+
) # Agent output is stored in 'content' field
110115

111116

112117
def test_concurrent_workflow_batched_execution():
@@ -117,8 +122,8 @@ def test_concurrent_workflow_batched_execution():
117122
agent_name=f"Analysis-Agent-{i+1}",
118123
agent_description=f"Agent {i+1} for comprehensive business analysis",
119124
model_name="gpt-4o-mini",
120-
verbose=False,
121-
print_on=False,
125+
verbose=False,
126+
print_on=False,
122127
max_loops=1,
123128
)
124129
for i in range(4)
@@ -206,7 +211,9 @@ def test_concurrent_workflow_max_loops_configuration():
206211
for r in result:
207212
assert isinstance(r, dict)
208213
assert "role" in r # Agent name is stored in 'role' field
209-
assert "content" in r # Agent output is stored in 'content' field
214+
assert (
215+
"content" in r
216+
) # Agent output is stored in 'content' field
210217

211218

212219
def test_concurrent_workflow_different_output_types():
@@ -318,7 +325,9 @@ def test_concurrent_workflow_real_world_scenario():
318325
for r in result:
319326
assert isinstance(r, dict)
320327
assert "role" in r # Agent name is stored in 'role' field
321-
assert "content" in r # Agent output is stored in 'content' field
328+
assert (
329+
"content" in r
330+
) # Agent output is stored in 'content' field
322331

323332

324333
def test_concurrent_workflow_team_collaboration():
@@ -385,7 +394,10 @@ def test_concurrent_workflow_team_collaboration():
385394
for r in result:
386395
assert isinstance(r, dict)
387396
assert "role" in r # Agent name is stored in 'role' field
388-
assert "content" in r # Agent output is stored in 'content' field
397+
assert (
398+
"content" in r
399+
) # Agent output is stored in 'content' field
400+
389401

390402
if __name__ == "__main__":
391-
pytest.main([__file__, "-v"])
403+
pytest.main([__file__, "-v"])

tests/structs/test_graph_workflow_comprehensive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,4 @@ def test_graph_workflow_node_metadata():
222222

223223

224224
if __name__ == "__main__":
225-
pytest.main([__file__, "-v"])
225+
pytest.main([__file__, "-v"])

tests/structs/test_hierarchical_swarm.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,5 @@ def test_hierarchical_swarm_real_world_scenario():
404404

405405
if __name__ == "__main__":
406406
import pytest
407-
pytest.main([__file__, "-v"])
407+
408+
pytest.main([__file__, "-v"])

tests/structs/test_spreadsheet.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,27 @@ def sample_csv_file(tmp_path):
2121
"""Create a sample CSV file with agent configurations."""
2222
csv_path = tmp_path / "test_agents.csv"
2323
csv_content = [
24-
["agent_name", "description", "system_prompt", "task", "model_name"],
25-
["agent_1", "First test agent", "You are a helpful assistant. Respond with exactly 'Task completed.'", "Say hello", "gpt-4o-mini"],
26-
["agent_2", "Second test agent", "You are a code reviewer. Respond with exactly 'Review done.'", "Review this: print('hello')", "gpt-4o-mini"],
24+
[
25+
"agent_name",
26+
"description",
27+
"system_prompt",
28+
"task",
29+
"model_name",
30+
],
31+
[
32+
"agent_1",
33+
"First test agent",
34+
"You are a helpful assistant. Respond with exactly 'Task completed.'",
35+
"Say hello",
36+
"gpt-4o-mini",
37+
],
38+
[
39+
"agent_2",
40+
"Second test agent",
41+
"You are a code reviewer. Respond with exactly 'Review done.'",
42+
"Review this: print('hello')",
43+
"gpt-4o-mini",
44+
],
2745
]
2846

2947
with open(csv_path, "w", newline="") as f:
@@ -261,10 +279,14 @@ def test_load_from_csv_basic(sample_csv_file, temp_workspace):
261279
assert "agent_1" in swarm.agent_tasks
262280
assert "agent_2" in swarm.agent_tasks
263281
assert swarm.agent_tasks["agent_1"] == "Say hello"
264-
assert swarm.agent_tasks["agent_2"] == "Review this: print('hello')"
282+
assert (
283+
swarm.agent_tasks["agent_2"] == "Review this: print('hello')"
284+
)
265285

266286

267-
def test_load_from_csv_creates_agents(sample_csv_file, temp_workspace):
287+
def test_load_from_csv_creates_agents(
288+
sample_csv_file, temp_workspace
289+
):
268290
"""Test that CSV loading creates proper Agent objects."""
269291
agent = Agent(
270292
agent_name="placeholder",
@@ -349,7 +371,13 @@ def test_save_to_csv_headers(temp_workspace):
349371
with open(swarm.save_file_path, "r") as f:
350372
reader = csv.reader(f)
351373
headers = next(reader)
352-
assert headers == ["Run ID", "Agent Name", "Task", "Result", "Timestamp"]
374+
assert headers == [
375+
"Run ID",
376+
"Agent Name",
377+
"Task",
378+
"Result",
379+
"Timestamp",
380+
]
353381

354382

355383
def test_save_to_csv_data(temp_workspace):

0 commit comments

Comments
 (0)