orbis-sdk 0.1.0__tar.gz
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.
- orbis_sdk-0.1.0/.gitignore +49 -0
- orbis_sdk-0.1.0/PKG-INFO +184 -0
- orbis_sdk-0.1.0/README.md +152 -0
- orbis_sdk-0.1.0/pyproject.toml +42 -0
- orbis_sdk-0.1.0/src/orbis/__init__.py +18 -0
- orbis_sdk-0.1.0/src/orbis/client.py +209 -0
- orbis_sdk-0.1.0/src/orbis/integrations/__init__.py +7 -0
- orbis_sdk-0.1.0/src/orbis/integrations/autogen.py +132 -0
- orbis_sdk-0.1.0/src/orbis/integrations/crewai.py +101 -0
- orbis_sdk-0.1.0/src/orbis/integrations/langchain.py +123 -0
- orbis_sdk-0.1.0/src/orbis/models.py +42 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# compiled output
|
|
4
|
+
dist
|
|
5
|
+
tmp
|
|
6
|
+
out-tsc
|
|
7
|
+
*.tsbuildinfo
|
|
8
|
+
.expo
|
|
9
|
+
.expo-shared
|
|
10
|
+
|
|
11
|
+
# dependencies
|
|
12
|
+
node_modules
|
|
13
|
+
|
|
14
|
+
# IDEs and editors
|
|
15
|
+
/.idea
|
|
16
|
+
.project
|
|
17
|
+
.classpath
|
|
18
|
+
.c9/
|
|
19
|
+
*.launch
|
|
20
|
+
.settings/
|
|
21
|
+
*.sublime-workspace
|
|
22
|
+
|
|
23
|
+
# IDE - VSCode
|
|
24
|
+
.vscode/*
|
|
25
|
+
!.vscode/settings.json
|
|
26
|
+
!.vscode/tasks.json
|
|
27
|
+
!.vscode/launch.json
|
|
28
|
+
!.vscode/extensions.json
|
|
29
|
+
|
|
30
|
+
# misc
|
|
31
|
+
/.sass-cache
|
|
32
|
+
/connect.lock
|
|
33
|
+
/coverage
|
|
34
|
+
/libpeerconnection.log
|
|
35
|
+
npm-debug.log
|
|
36
|
+
yarn-error.log
|
|
37
|
+
testem.log
|
|
38
|
+
/typings
|
|
39
|
+
|
|
40
|
+
# System Files
|
|
41
|
+
.DS_Store
|
|
42
|
+
Thumbs.db
|
|
43
|
+
|
|
44
|
+
.cursor/rules/nx-rules.mdc
|
|
45
|
+
.github/instructions/nx.instructions.md
|
|
46
|
+
|
|
47
|
+
# Replit
|
|
48
|
+
.cache/
|
|
49
|
+
.local/
|
orbis_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orbis-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Orbis API Marketplace — call any API, pay per use with USDC, native LangChain/CrewAI/AutoGen support.
|
|
5
|
+
Project-URL: Homepage, https://orbisapi.com
|
|
6
|
+
Project-URL: Documentation, https://orbisapi.com/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/orbisapi/orbis-sdk
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/orbisapi/orbis-sdk/issues
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: agents,api,autogen,crewai,langchain,marketplace,usdc,x402
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: httpx>=0.27.0
|
|
21
|
+
Requires-Dist: requests>=2.31.0
|
|
22
|
+
Provides-Extra: all
|
|
23
|
+
Requires-Dist: crewai>=0.80.0; extra == 'all'
|
|
24
|
+
Requires-Dist: langchain-core>=0.2.0; extra == 'all'
|
|
25
|
+
Provides-Extra: autogen
|
|
26
|
+
Requires-Dist: pyautogen>=0.2.0; extra == 'autogen'
|
|
27
|
+
Provides-Extra: crewai
|
|
28
|
+
Requires-Dist: crewai>=0.80.0; extra == 'crewai'
|
|
29
|
+
Provides-Extra: langchain
|
|
30
|
+
Requires-Dist: langchain-core>=0.2.0; extra == 'langchain'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# orbis-sdk
|
|
34
|
+
|
|
35
|
+
The official Python SDK for [Orbis API Marketplace](https://orbisapi.com) — the default execution and payment layer for agent workflows.
|
|
36
|
+
|
|
37
|
+
Call any of 700+ production APIs from your AI agent with a single line. Native support for LangChain, CrewAI, and AutoGen.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install orbis-sdk
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
With framework integrations:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install orbis-sdk[langchain] # LangChain support
|
|
49
|
+
pip install orbis-sdk[crewai] # CrewAI support
|
|
50
|
+
pip install orbis-sdk[all] # Everything
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
Get your API key at [orbisapi.com](https://orbisapi.com).
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from orbis import OrbisClient
|
|
59
|
+
|
|
60
|
+
client = OrbisClient(api_key="sk_...")
|
|
61
|
+
|
|
62
|
+
# Search for APIs
|
|
63
|
+
apis = client.search("tweet generator")
|
|
64
|
+
for api in apis:
|
|
65
|
+
print(api.name, api.description)
|
|
66
|
+
|
|
67
|
+
# Call an API
|
|
68
|
+
result = client.call(
|
|
69
|
+
"tweet-thread-generator-api",
|
|
70
|
+
{"topic": "Why AI agents are replacing SaaS"}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if result.success:
|
|
74
|
+
print(result.data)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## LangChain
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from orbis import OrbisClient
|
|
81
|
+
from langchain_openai import ChatOpenAI
|
|
82
|
+
from langchain.agents import create_react_agent, AgentExecutor
|
|
83
|
+
|
|
84
|
+
client = OrbisClient(api_key="sk_...")
|
|
85
|
+
|
|
86
|
+
# Wrap Orbis APIs as LangChain tools
|
|
87
|
+
tools = client.as_langchain_tools([
|
|
88
|
+
"tweet-thread-generator-api",
|
|
89
|
+
"credit-score-estimator",
|
|
90
|
+
"weather-api",
|
|
91
|
+
])
|
|
92
|
+
|
|
93
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
94
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
95
|
+
executor = AgentExecutor(agent=agent, tools=tools)
|
|
96
|
+
|
|
97
|
+
result = executor.invoke({"input": "Write a thread about AI agents"})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or search and use dynamically:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from orbis.integrations.langchain import orbis_toolkit
|
|
104
|
+
|
|
105
|
+
tools = orbis_toolkit(client, query="social media content", limit=5)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## CrewAI
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from orbis import OrbisClient
|
|
112
|
+
from crewai import Agent, Task, Crew
|
|
113
|
+
|
|
114
|
+
client = OrbisClient(api_key="sk_...")
|
|
115
|
+
tools = client.as_crewai_tools(["tweet-thread-generator-api"])
|
|
116
|
+
|
|
117
|
+
writer = Agent(
|
|
118
|
+
role="Content Writer",
|
|
119
|
+
goal="Write viral Twitter threads about AI",
|
|
120
|
+
backstory="Expert in social media content strategy",
|
|
121
|
+
tools=tools,
|
|
122
|
+
verbose=True,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
task = Task(
|
|
126
|
+
description="Write a 10-tweet thread about why AI agents are replacing traditional SaaS",
|
|
127
|
+
expected_output="A numbered Twitter thread ready to post",
|
|
128
|
+
agent=writer,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
crew = Crew(agents=[writer], tasks=[task])
|
|
132
|
+
result = crew.kickoff()
|
|
133
|
+
print(result)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## AutoGen
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from orbis import OrbisClient
|
|
140
|
+
from orbis.integrations.autogen import register_orbis_tools
|
|
141
|
+
import autogen
|
|
142
|
+
|
|
143
|
+
client = OrbisClient(api_key="sk_...")
|
|
144
|
+
|
|
145
|
+
llm_config = {
|
|
146
|
+
"config_list": [{"model": "gpt-4o", "api_key": "YOUR_OPENAI_KEY"}],
|
|
147
|
+
"functions": client.as_autogen_functions(["tweet-thread-generator-api"]),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
assistant = autogen.AssistantAgent("assistant", llm_config=llm_config)
|
|
151
|
+
user_proxy = autogen.UserProxyAgent("user", human_input_mode="NEVER")
|
|
152
|
+
|
|
153
|
+
register_orbis_tools(client, assistant, user_proxy, ["tweet-thread-generator-api"])
|
|
154
|
+
|
|
155
|
+
user_proxy.initiate_chat(
|
|
156
|
+
assistant,
|
|
157
|
+
message="Write a thread about the agent economy"
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Available APIs
|
|
162
|
+
|
|
163
|
+
Browse all 700+ APIs at [orbisapi.com/marketplace](https://orbisapi.com/marketplace).
|
|
164
|
+
|
|
165
|
+
Categories include:
|
|
166
|
+
- AI & Machine Learning
|
|
167
|
+
- Finance & Crypto
|
|
168
|
+
- Social Media
|
|
169
|
+
- Data & Analytics
|
|
170
|
+
- Communication
|
|
171
|
+
- Developer Tools
|
|
172
|
+
|
|
173
|
+
## Pricing
|
|
174
|
+
|
|
175
|
+
Pay per call. No subscriptions required. Prices set by API providers — Orbis takes 10%, providers keep 90%.
|
|
176
|
+
|
|
177
|
+
Some APIs accept USDC payments via x402 on Base for fully autonomous agent payment flows.
|
|
178
|
+
|
|
179
|
+
## Links
|
|
180
|
+
|
|
181
|
+
- [Marketplace](https://orbisapi.com/marketplace)
|
|
182
|
+
- [Docs](https://orbisapi.com/docs)
|
|
183
|
+
- [Discord](https://discord.gg/orbisapi)
|
|
184
|
+
- [Twitter](https://twitter.com/orbisapi)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# orbis-sdk
|
|
2
|
+
|
|
3
|
+
The official Python SDK for [Orbis API Marketplace](https://orbisapi.com) — the default execution and payment layer for agent workflows.
|
|
4
|
+
|
|
5
|
+
Call any of 700+ production APIs from your AI agent with a single line. Native support for LangChain, CrewAI, and AutoGen.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install orbis-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
With framework integrations:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install orbis-sdk[langchain] # LangChain support
|
|
17
|
+
pip install orbis-sdk[crewai] # CrewAI support
|
|
18
|
+
pip install orbis-sdk[all] # Everything
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
Get your API key at [orbisapi.com](https://orbisapi.com).
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from orbis import OrbisClient
|
|
27
|
+
|
|
28
|
+
client = OrbisClient(api_key="sk_...")
|
|
29
|
+
|
|
30
|
+
# Search for APIs
|
|
31
|
+
apis = client.search("tweet generator")
|
|
32
|
+
for api in apis:
|
|
33
|
+
print(api.name, api.description)
|
|
34
|
+
|
|
35
|
+
# Call an API
|
|
36
|
+
result = client.call(
|
|
37
|
+
"tweet-thread-generator-api",
|
|
38
|
+
{"topic": "Why AI agents are replacing SaaS"}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if result.success:
|
|
42
|
+
print(result.data)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## LangChain
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from orbis import OrbisClient
|
|
49
|
+
from langchain_openai import ChatOpenAI
|
|
50
|
+
from langchain.agents import create_react_agent, AgentExecutor
|
|
51
|
+
|
|
52
|
+
client = OrbisClient(api_key="sk_...")
|
|
53
|
+
|
|
54
|
+
# Wrap Orbis APIs as LangChain tools
|
|
55
|
+
tools = client.as_langchain_tools([
|
|
56
|
+
"tweet-thread-generator-api",
|
|
57
|
+
"credit-score-estimator",
|
|
58
|
+
"weather-api",
|
|
59
|
+
])
|
|
60
|
+
|
|
61
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
62
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
63
|
+
executor = AgentExecutor(agent=agent, tools=tools)
|
|
64
|
+
|
|
65
|
+
result = executor.invoke({"input": "Write a thread about AI agents"})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or search and use dynamically:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from orbis.integrations.langchain import orbis_toolkit
|
|
72
|
+
|
|
73
|
+
tools = orbis_toolkit(client, query="social media content", limit=5)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## CrewAI
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from orbis import OrbisClient
|
|
80
|
+
from crewai import Agent, Task, Crew
|
|
81
|
+
|
|
82
|
+
client = OrbisClient(api_key="sk_...")
|
|
83
|
+
tools = client.as_crewai_tools(["tweet-thread-generator-api"])
|
|
84
|
+
|
|
85
|
+
writer = Agent(
|
|
86
|
+
role="Content Writer",
|
|
87
|
+
goal="Write viral Twitter threads about AI",
|
|
88
|
+
backstory="Expert in social media content strategy",
|
|
89
|
+
tools=tools,
|
|
90
|
+
verbose=True,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
task = Task(
|
|
94
|
+
description="Write a 10-tweet thread about why AI agents are replacing traditional SaaS",
|
|
95
|
+
expected_output="A numbered Twitter thread ready to post",
|
|
96
|
+
agent=writer,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
crew = Crew(agents=[writer], tasks=[task])
|
|
100
|
+
result = crew.kickoff()
|
|
101
|
+
print(result)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## AutoGen
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from orbis import OrbisClient
|
|
108
|
+
from orbis.integrations.autogen import register_orbis_tools
|
|
109
|
+
import autogen
|
|
110
|
+
|
|
111
|
+
client = OrbisClient(api_key="sk_...")
|
|
112
|
+
|
|
113
|
+
llm_config = {
|
|
114
|
+
"config_list": [{"model": "gpt-4o", "api_key": "YOUR_OPENAI_KEY"}],
|
|
115
|
+
"functions": client.as_autogen_functions(["tweet-thread-generator-api"]),
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
assistant = autogen.AssistantAgent("assistant", llm_config=llm_config)
|
|
119
|
+
user_proxy = autogen.UserProxyAgent("user", human_input_mode="NEVER")
|
|
120
|
+
|
|
121
|
+
register_orbis_tools(client, assistant, user_proxy, ["tweet-thread-generator-api"])
|
|
122
|
+
|
|
123
|
+
user_proxy.initiate_chat(
|
|
124
|
+
assistant,
|
|
125
|
+
message="Write a thread about the agent economy"
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Available APIs
|
|
130
|
+
|
|
131
|
+
Browse all 700+ APIs at [orbisapi.com/marketplace](https://orbisapi.com/marketplace).
|
|
132
|
+
|
|
133
|
+
Categories include:
|
|
134
|
+
- AI & Machine Learning
|
|
135
|
+
- Finance & Crypto
|
|
136
|
+
- Social Media
|
|
137
|
+
- Data & Analytics
|
|
138
|
+
- Communication
|
|
139
|
+
- Developer Tools
|
|
140
|
+
|
|
141
|
+
## Pricing
|
|
142
|
+
|
|
143
|
+
Pay per call. No subscriptions required. Prices set by API providers — Orbis takes 10%, providers keep 90%.
|
|
144
|
+
|
|
145
|
+
Some APIs accept USDC payments via x402 on Base for fully autonomous agent payment flows.
|
|
146
|
+
|
|
147
|
+
## Links
|
|
148
|
+
|
|
149
|
+
- [Marketplace](https://orbisapi.com/marketplace)
|
|
150
|
+
- [Docs](https://orbisapi.com/docs)
|
|
151
|
+
- [Discord](https://discord.gg/orbisapi)
|
|
152
|
+
- [Twitter](https://twitter.com/orbisapi)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "orbis-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for the Orbis API Marketplace — call any API, pay per use with USDC, native LangChain/CrewAI/AutoGen support."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
keywords = ["api", "marketplace", "agents", "langchain", "crewai", "autogen", "usdc", "x402"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"requests>=2.31.0",
|
|
26
|
+
"httpx>=0.27.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
langchain = ["langchain-core>=0.2.0"]
|
|
31
|
+
crewai = ["crewai>=0.80.0"]
|
|
32
|
+
autogen = ["pyautogen>=0.2.0"]
|
|
33
|
+
all = ["langchain-core>=0.2.0", "crewai>=0.80.0"]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://orbisapi.com"
|
|
37
|
+
Documentation = "https://orbisapi.com/docs"
|
|
38
|
+
Repository = "https://github.com/orbisapi/orbis-sdk"
|
|
39
|
+
"Bug Tracker" = "https://github.com/orbisapi/orbis-sdk/issues"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.wheel]
|
|
42
|
+
packages = ["src/orbis"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Orbis SDK — Python client for the Orbis API Marketplace.
|
|
3
|
+
|
|
4
|
+
The default execution and payment layer for agent workflows.
|
|
5
|
+
|
|
6
|
+
Quick start:
|
|
7
|
+
from orbis import OrbisClient
|
|
8
|
+
|
|
9
|
+
client = OrbisClient(api_key="sk_...")
|
|
10
|
+
result = client.call("tweet-thread-generator-api", {"topic": "AI agents"})
|
|
11
|
+
print(result)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from orbis.client import OrbisClient
|
|
15
|
+
from orbis.models import APIListing, CallResult
|
|
16
|
+
|
|
17
|
+
__version__ = "0.1.0"
|
|
18
|
+
__all__ = ["OrbisClient", "APIListing", "CallResult"]
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core HTTP client for the Orbis API Marketplace.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from typing import Any, Optional
|
|
9
|
+
from urllib.parse import urljoin
|
|
10
|
+
|
|
11
|
+
import requests
|
|
12
|
+
|
|
13
|
+
from orbis.models import APIListing, CallResult
|
|
14
|
+
|
|
15
|
+
BASE_URL = "https://orbisapi.com"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class OrbisClient:
|
|
19
|
+
"""
|
|
20
|
+
Client for calling APIs on the Orbis marketplace.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
api_key: Your Orbis API key (sk_...). Get one at orbisapi.com
|
|
24
|
+
base_url: Override the API base URL (useful for testing).
|
|
25
|
+
timeout: Request timeout in seconds. Default 30.
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
client = OrbisClient(api_key="sk_...")
|
|
29
|
+
result = client.call("tweet-thread-generator-api", {"topic": "AI agents"})
|
|
30
|
+
print(result.data)
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
api_key: str,
|
|
36
|
+
base_url: str = BASE_URL,
|
|
37
|
+
timeout: int = 30,
|
|
38
|
+
):
|
|
39
|
+
if not api_key or not api_key.startswith("sk_"):
|
|
40
|
+
raise ValueError("Invalid API key. Get yours at orbisapi.com")
|
|
41
|
+
self.api_key = api_key
|
|
42
|
+
self.base_url = base_url.rstrip("/")
|
|
43
|
+
self.timeout = timeout
|
|
44
|
+
self._session = requests.Session()
|
|
45
|
+
self._session.headers.update({
|
|
46
|
+
"x-api-key": self.api_key,
|
|
47
|
+
"Content-Type": "application/json",
|
|
48
|
+
"User-Agent": "orbis-sdk-python/0.1.0",
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
def search(self, query: str, limit: int = 10) -> list[APIListing]:
|
|
52
|
+
"""
|
|
53
|
+
Search for APIs on Orbis.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
query: Search query (e.g. "weather", "tweet generator")
|
|
57
|
+
limit: Max number of results to return.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
List of APIListing objects.
|
|
61
|
+
"""
|
|
62
|
+
resp = self._session.get(
|
|
63
|
+
f"{self.base_url}/api/agents/discovery",
|
|
64
|
+
params={"q": query, "limit": limit},
|
|
65
|
+
timeout=self.timeout,
|
|
66
|
+
)
|
|
67
|
+
resp.raise_for_status()
|
|
68
|
+
data = resp.json()
|
|
69
|
+
apis = data if isinstance(data, list) else data.get("apis", [])
|
|
70
|
+
return [APIListing.from_dict(a) for a in apis[:limit]]
|
|
71
|
+
|
|
72
|
+
def list_apis(self, category: Optional[str] = None, limit: int = 50) -> list[APIListing]:
|
|
73
|
+
"""
|
|
74
|
+
List available APIs on Orbis.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
category: Filter by category (optional).
|
|
78
|
+
limit: Max results.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
List of APIListing objects.
|
|
82
|
+
"""
|
|
83
|
+
params: dict[str, Any] = {"limit": limit}
|
|
84
|
+
if category:
|
|
85
|
+
params["category"] = category
|
|
86
|
+
resp = self._session.get(
|
|
87
|
+
f"{self.base_url}/api/agents/discovery",
|
|
88
|
+
params=params,
|
|
89
|
+
timeout=self.timeout,
|
|
90
|
+
)
|
|
91
|
+
resp.raise_for_status()
|
|
92
|
+
data = resp.json()
|
|
93
|
+
apis = data if isinstance(data, list) else data.get("apis", [])
|
|
94
|
+
return [APIListing.from_dict(a) for a in apis]
|
|
95
|
+
|
|
96
|
+
def call(
|
|
97
|
+
self,
|
|
98
|
+
api_slug: str,
|
|
99
|
+
payload: dict[str, Any],
|
|
100
|
+
endpoint: str = "/",
|
|
101
|
+
method: str = "POST",
|
|
102
|
+
) -> CallResult:
|
|
103
|
+
"""
|
|
104
|
+
Call an API on the Orbis marketplace.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
api_slug: The API slug (e.g. "tweet-thread-generator-api")
|
|
108
|
+
payload: Request body as a dict.
|
|
109
|
+
endpoint: API sub-path to call (default "/").
|
|
110
|
+
method: HTTP method (default "POST").
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
CallResult with success status and response data.
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
result = client.call(
|
|
117
|
+
"tweet-thread-generator-api",
|
|
118
|
+
{"topic": "AI agents replacing SaaS"},
|
|
119
|
+
)
|
|
120
|
+
if result.success:
|
|
121
|
+
print(result.data)
|
|
122
|
+
"""
|
|
123
|
+
url = f"{self.base_url}/api/proxy/{api_slug}{endpoint}"
|
|
124
|
+
try:
|
|
125
|
+
resp = self._session.request(
|
|
126
|
+
method=method.upper(),
|
|
127
|
+
url=url,
|
|
128
|
+
json=payload if method.upper() != "GET" else None,
|
|
129
|
+
params=payload if method.upper() == "GET" else None,
|
|
130
|
+
timeout=self.timeout,
|
|
131
|
+
)
|
|
132
|
+
try:
|
|
133
|
+
data = resp.json()
|
|
134
|
+
except Exception:
|
|
135
|
+
data = resp.text
|
|
136
|
+
|
|
137
|
+
return CallResult(
|
|
138
|
+
success=resp.ok,
|
|
139
|
+
data=data,
|
|
140
|
+
status_code=resp.status_code,
|
|
141
|
+
api_slug=api_slug,
|
|
142
|
+
endpoint=endpoint,
|
|
143
|
+
error=None if resp.ok else str(data),
|
|
144
|
+
)
|
|
145
|
+
except requests.RequestException as e:
|
|
146
|
+
return CallResult(
|
|
147
|
+
success=False,
|
|
148
|
+
data=None,
|
|
149
|
+
status_code=0,
|
|
150
|
+
api_slug=api_slug,
|
|
151
|
+
endpoint=endpoint,
|
|
152
|
+
error=str(e),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def get_api(self, slug: str) -> Optional[APIListing]:
|
|
156
|
+
"""Fetch a single API listing by slug."""
|
|
157
|
+
try:
|
|
158
|
+
resp = self._session.get(
|
|
159
|
+
f"{self.base_url}/api/agents/discovery",
|
|
160
|
+
params={"slug": slug},
|
|
161
|
+
timeout=self.timeout,
|
|
162
|
+
)
|
|
163
|
+
resp.raise_for_status()
|
|
164
|
+
data = resp.json()
|
|
165
|
+
apis = data if isinstance(data, list) else data.get("apis", [])
|
|
166
|
+
if apis:
|
|
167
|
+
return APIListing.from_dict(apis[0])
|
|
168
|
+
except Exception:
|
|
169
|
+
pass
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
def as_langchain_tools(self, api_slugs: list[str]) -> list:
|
|
173
|
+
"""
|
|
174
|
+
Convert a list of API slugs into LangChain BaseTool instances.
|
|
175
|
+
|
|
176
|
+
Requires: pip install orbis-sdk[langchain]
|
|
177
|
+
|
|
178
|
+
Example:
|
|
179
|
+
tools = client.as_langchain_tools(["tweet-thread-generator-api"])
|
|
180
|
+
agent = create_react_agent(llm, tools)
|
|
181
|
+
"""
|
|
182
|
+
from orbis.integrations.langchain import OrbisAPITool
|
|
183
|
+
return [OrbisAPITool(client=self, api_slug=slug) for slug in api_slugs]
|
|
184
|
+
|
|
185
|
+
def as_crewai_tools(self, api_slugs: list[str]) -> list:
|
|
186
|
+
"""
|
|
187
|
+
Convert a list of API slugs into CrewAI BaseTool instances.
|
|
188
|
+
|
|
189
|
+
Requires: pip install orbis-sdk[crewai]
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
tools = client.as_crewai_tools(["tweet-thread-generator-api"])
|
|
193
|
+
agent = Agent(role="Writer", tools=tools)
|
|
194
|
+
"""
|
|
195
|
+
from orbis.integrations.crewai import OrbisCrewAITool
|
|
196
|
+
return [OrbisCrewAITool(client=self, api_slug=slug) for slug in api_slugs]
|
|
197
|
+
|
|
198
|
+
def as_autogen_functions(self, api_slugs: list[str]) -> list[dict]:
|
|
199
|
+
"""
|
|
200
|
+
Return AutoGen-compatible function definitions for a list of API slugs.
|
|
201
|
+
|
|
202
|
+
Requires: pip install pyautogen
|
|
203
|
+
|
|
204
|
+
Example:
|
|
205
|
+
functions = client.as_autogen_functions(["tweet-thread-generator-api"])
|
|
206
|
+
assistant = AssistantAgent("assistant", llm_config={"functions": functions})
|
|
207
|
+
"""
|
|
208
|
+
from orbis.integrations.autogen import build_autogen_function
|
|
209
|
+
return [build_autogen_function(self, slug) for slug in api_slugs]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AutoGen integration for Orbis SDK.
|
|
3
|
+
|
|
4
|
+
Requires: pip install pyautogen
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from orbis import OrbisClient
|
|
8
|
+
from orbis.integrations.autogen import build_autogen_function, register_orbis_tools
|
|
9
|
+
import autogen
|
|
10
|
+
|
|
11
|
+
client = OrbisClient(api_key="sk_...")
|
|
12
|
+
|
|
13
|
+
llm_config = {
|
|
14
|
+
"config_list": [{"model": "gpt-4o", "api_key": "..."}],
|
|
15
|
+
"functions": client.as_autogen_functions(["tweet-thread-generator-api"]),
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
assistant = autogen.AssistantAgent("assistant", llm_config=llm_config)
|
|
19
|
+
user = autogen.UserProxyAgent("user", human_input_mode="NEVER")
|
|
20
|
+
|
|
21
|
+
# Register execution callbacks
|
|
22
|
+
register_orbis_tools(client, user, assistant, ["tweet-thread-generator-api"])
|
|
23
|
+
|
|
24
|
+
user.initiate_chat(assistant, message="Write a thread about AI agents")
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import json
|
|
30
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from orbis.client import OrbisClient
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def build_autogen_function(client: "OrbisClient", api_slug: str) -> dict:
|
|
37
|
+
"""
|
|
38
|
+
Build an AutoGen-compatible function definition for an Orbis API.
|
|
39
|
+
|
|
40
|
+
Returns a dict with 'name', 'description', and 'parameters' fields
|
|
41
|
+
that can be passed to an AssistantAgent's llm_config['functions'].
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
client: OrbisClient instance.
|
|
45
|
+
api_slug: The API slug to wrap.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
AutoGen function definition dict.
|
|
49
|
+
"""
|
|
50
|
+
listing = client.get_api(api_slug)
|
|
51
|
+
func_name = f"call_{api_slug.replace('-', '_')}"
|
|
52
|
+
description = (
|
|
53
|
+
f"Call the '{listing.name}' API via Orbis. {listing.description}"
|
|
54
|
+
if listing
|
|
55
|
+
else f"Call the '{api_slug}' API via Orbis marketplace."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
"name": func_name,
|
|
60
|
+
"description": description,
|
|
61
|
+
"parameters": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {
|
|
64
|
+
"payload": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "JSON string of the request parameters to send to the API.",
|
|
67
|
+
},
|
|
68
|
+
"endpoint": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "API sub-path to call (default '/').",
|
|
71
|
+
"default": "/",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
"required": ["payload"],
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _make_executor(client: "OrbisClient", api_slug: str) -> Callable:
|
|
80
|
+
"""Create the execution function for a given API slug."""
|
|
81
|
+
def execute(payload: str, endpoint: str = "/") -> str:
|
|
82
|
+
try:
|
|
83
|
+
parsed = json.loads(payload)
|
|
84
|
+
except json.JSONDecodeError:
|
|
85
|
+
parsed = {"input": payload}
|
|
86
|
+
result = client.call(api_slug, parsed, endpoint=endpoint)
|
|
87
|
+
if result.success:
|
|
88
|
+
return json.dumps(result.data, ensure_ascii=False)
|
|
89
|
+
return f"Error calling {api_slug}: {result.error}"
|
|
90
|
+
execute.__name__ = f"call_{api_slug.replace('-', '_')}"
|
|
91
|
+
return execute
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def register_orbis_tools(
|
|
95
|
+
client: "OrbisClient",
|
|
96
|
+
caller: Any,
|
|
97
|
+
executor: Any,
|
|
98
|
+
api_slugs: list[str],
|
|
99
|
+
) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Register Orbis API tools with an AutoGen agent pair.
|
|
102
|
+
|
|
103
|
+
Call this after creating your AssistantAgent and UserProxyAgent to
|
|
104
|
+
wire up the execution callbacks.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
client: OrbisClient instance.
|
|
108
|
+
caller: The AssistantAgent that will call the functions.
|
|
109
|
+
executor: The UserProxyAgent that will execute them.
|
|
110
|
+
api_slugs: List of API slugs to register.
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
register_orbis_tools(client, assistant, user_proxy, ["tweet-thread-generator-api"])
|
|
114
|
+
"""
|
|
115
|
+
try:
|
|
116
|
+
from autogen import register_function
|
|
117
|
+
except ImportError as e:
|
|
118
|
+
raise ImportError(
|
|
119
|
+
"pyautogen is required for AutoGen integration. "
|
|
120
|
+
"Install it with: pip install pyautogen"
|
|
121
|
+
) from e
|
|
122
|
+
|
|
123
|
+
for slug in api_slugs:
|
|
124
|
+
func_def = build_autogen_function(client, slug)
|
|
125
|
+
fn = _make_executor(client, slug)
|
|
126
|
+
register_function(
|
|
127
|
+
fn,
|
|
128
|
+
caller=caller,
|
|
129
|
+
executor=executor,
|
|
130
|
+
name=func_def["name"],
|
|
131
|
+
description=func_def["description"],
|
|
132
|
+
)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CrewAI integration for Orbis SDK.
|
|
3
|
+
|
|
4
|
+
Requires: pip install orbis-sdk[crewai]
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from orbis import OrbisClient
|
|
8
|
+
from crewai import Agent, Task, Crew
|
|
9
|
+
|
|
10
|
+
client = OrbisClient(api_key="sk_...")
|
|
11
|
+
tools = client.as_crewai_tools(["tweet-thread-generator-api"])
|
|
12
|
+
|
|
13
|
+
writer = Agent(
|
|
14
|
+
role="Content Writer",
|
|
15
|
+
goal="Write viral Twitter threads",
|
|
16
|
+
backstory="Expert in social media content",
|
|
17
|
+
tools=tools,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
task = Task(
|
|
21
|
+
description="Write a thread about AI agents replacing SaaS",
|
|
22
|
+
agent=writer,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
crew = Crew(agents=[writer], tasks=[task])
|
|
26
|
+
result = crew.kickoff()
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import json
|
|
32
|
+
from typing import TYPE_CHECKING, Any, Optional, Type
|
|
33
|
+
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
from orbis.client import OrbisClient
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
from crewai.tools import BaseTool
|
|
39
|
+
from pydantic import BaseModel, Field
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
raise ImportError(
|
|
42
|
+
"crewai is required for CrewAI integration. "
|
|
43
|
+
"Install it with: pip install orbis-sdk[crewai]"
|
|
44
|
+
) from e
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class OrbisToolInput(BaseModel):
|
|
48
|
+
payload: str = Field(
|
|
49
|
+
description="JSON string of parameters to send to the API."
|
|
50
|
+
)
|
|
51
|
+
endpoint: str = Field(
|
|
52
|
+
default="/",
|
|
53
|
+
description="API sub-path to call (default '/').",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class OrbisCrewAITool(BaseTool):
|
|
58
|
+
"""
|
|
59
|
+
A CrewAI tool that wraps a specific API on the Orbis marketplace.
|
|
60
|
+
|
|
61
|
+
Each tool instance wraps one API slug. Pass multiple tools to an Agent
|
|
62
|
+
to give it access to multiple APIs.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
name: str = "orbis_api"
|
|
66
|
+
description: str = "Call an API on the Orbis marketplace."
|
|
67
|
+
args_schema: Type[BaseModel] = OrbisToolInput
|
|
68
|
+
client: Any
|
|
69
|
+
api_slug: str
|
|
70
|
+
|
|
71
|
+
class Config:
|
|
72
|
+
arbitrary_types_allowed = True
|
|
73
|
+
|
|
74
|
+
def __init__(self, client: "OrbisClient", api_slug: str, **kwargs):
|
|
75
|
+
listing = client.get_api(api_slug)
|
|
76
|
+
tool_name = f"orbis_{api_slug.replace('-', '_')}"
|
|
77
|
+
tool_desc = (
|
|
78
|
+
f"Call the '{listing.name}' API via Orbis. {listing.description} "
|
|
79
|
+
f"Pass a JSON string as 'payload' with the required parameters."
|
|
80
|
+
if listing
|
|
81
|
+
else f"Call the '{api_slug}' API via Orbis. "
|
|
82
|
+
f"Pass a JSON string as 'payload' with the required parameters."
|
|
83
|
+
)
|
|
84
|
+
super().__init__(
|
|
85
|
+
name=tool_name,
|
|
86
|
+
description=tool_desc,
|
|
87
|
+
client=client,
|
|
88
|
+
api_slug=api_slug,
|
|
89
|
+
**kwargs,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def _run(self, payload: str, endpoint: str = "/") -> str:
|
|
93
|
+
try:
|
|
94
|
+
parsed = json.loads(payload)
|
|
95
|
+
except json.JSONDecodeError:
|
|
96
|
+
parsed = {"input": payload}
|
|
97
|
+
|
|
98
|
+
result = self.client.call(self.api_slug, parsed, endpoint=endpoint)
|
|
99
|
+
if result.success:
|
|
100
|
+
return json.dumps(result.data, ensure_ascii=False)
|
|
101
|
+
return f"Error calling {self.api_slug}: {result.error}"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LangChain integration for Orbis SDK.
|
|
3
|
+
|
|
4
|
+
Requires: pip install orbis-sdk[langchain]
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from orbis import OrbisClient
|
|
8
|
+
from orbis.integrations.langchain import OrbisAPITool, orbis_toolkit
|
|
9
|
+
|
|
10
|
+
client = OrbisClient(api_key="sk_...")
|
|
11
|
+
|
|
12
|
+
# Option 1: Specific APIs as tools
|
|
13
|
+
tools = client.as_langchain_tools([
|
|
14
|
+
"tweet-thread-generator-api",
|
|
15
|
+
"credit-score-estimator",
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
# Option 2: Build a full toolkit from search
|
|
19
|
+
tools = orbis_toolkit(client, query="social media", limit=5)
|
|
20
|
+
|
|
21
|
+
# Use with any LangChain agent
|
|
22
|
+
from langchain.agents import create_react_agent
|
|
23
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
from typing import TYPE_CHECKING, Any, Optional, Type
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from orbis.client import OrbisClient
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
from langchain_core.tools import BaseTool
|
|
36
|
+
from pydantic import BaseModel, Field
|
|
37
|
+
except ImportError as e:
|
|
38
|
+
raise ImportError(
|
|
39
|
+
"langchain-core is required for LangChain integration. "
|
|
40
|
+
"Install it with: pip install orbis-sdk[langchain]"
|
|
41
|
+
) from e
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class OrbisCallInput(BaseModel):
|
|
45
|
+
payload: str = Field(
|
|
46
|
+
description="JSON string of the request payload to send to the API."
|
|
47
|
+
)
|
|
48
|
+
endpoint: str = Field(
|
|
49
|
+
default="/",
|
|
50
|
+
description="API endpoint path to call (default '/').",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class OrbisAPITool(BaseTool):
|
|
55
|
+
"""
|
|
56
|
+
A LangChain tool that calls a specific API on the Orbis marketplace.
|
|
57
|
+
|
|
58
|
+
Each tool wraps a single API. Use OrbisClient.as_langchain_tools() to
|
|
59
|
+
generate a list of tools for multiple APIs at once.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
name: str = "orbis_api"
|
|
63
|
+
description: str = "Call an API on the Orbis marketplace."
|
|
64
|
+
args_schema: Type[BaseModel] = OrbisCallInput
|
|
65
|
+
client: Any
|
|
66
|
+
api_slug: str
|
|
67
|
+
|
|
68
|
+
class Config:
|
|
69
|
+
arbitrary_types_allowed = True
|
|
70
|
+
|
|
71
|
+
def __init__(self, client: "OrbisClient", api_slug: str, **kwargs):
|
|
72
|
+
listing = client.get_api(api_slug)
|
|
73
|
+
tool_name = f"orbis_{api_slug.replace('-', '_')}"
|
|
74
|
+
tool_desc = (
|
|
75
|
+
f"Call the '{listing.name}' API via Orbis. {listing.description}"
|
|
76
|
+
if listing
|
|
77
|
+
else f"Call the '{api_slug}' API via Orbis."
|
|
78
|
+
)
|
|
79
|
+
super().__init__(
|
|
80
|
+
name=tool_name,
|
|
81
|
+
description=tool_desc,
|
|
82
|
+
client=client,
|
|
83
|
+
api_slug=api_slug,
|
|
84
|
+
**kwargs,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def _run(self, payload: str, endpoint: str = "/") -> str:
|
|
88
|
+
try:
|
|
89
|
+
parsed = json.loads(payload)
|
|
90
|
+
except json.JSONDecodeError:
|
|
91
|
+
parsed = {"input": payload}
|
|
92
|
+
|
|
93
|
+
result = self.client.call(self.api_slug, parsed, endpoint=endpoint)
|
|
94
|
+
if result.success:
|
|
95
|
+
return json.dumps(result.data, ensure_ascii=False)
|
|
96
|
+
return f"Error calling {self.api_slug}: {result.error}"
|
|
97
|
+
|
|
98
|
+
async def _arun(self, payload: str, endpoint: str = "/") -> str:
|
|
99
|
+
return self._run(payload, endpoint)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def orbis_toolkit(
|
|
103
|
+
client: "OrbisClient",
|
|
104
|
+
query: str,
|
|
105
|
+
limit: int = 5,
|
|
106
|
+
) -> list[OrbisAPITool]:
|
|
107
|
+
"""
|
|
108
|
+
Search Orbis and return matching APIs as LangChain tools.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
client: OrbisClient instance.
|
|
112
|
+
query: What kind of APIs to search for.
|
|
113
|
+
limit: Max tools to return.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
List of OrbisAPITool instances ready to pass to an agent.
|
|
117
|
+
|
|
118
|
+
Example:
|
|
119
|
+
tools = orbis_toolkit(client, query="data enrichment", limit=3)
|
|
120
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
121
|
+
"""
|
|
122
|
+
listings = client.search(query, limit=limit)
|
|
123
|
+
return [OrbisAPITool(client=client, api_slug=l.slug) for l in listings]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class APIListing:
|
|
7
|
+
id: str
|
|
8
|
+
name: str
|
|
9
|
+
slug: str
|
|
10
|
+
description: str
|
|
11
|
+
category: str
|
|
12
|
+
base_url: str
|
|
13
|
+
tiers: list[dict] = field(default_factory=list)
|
|
14
|
+
tags: list[str] = field(default_factory=list)
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def from_dict(cls, data: dict) -> "APIListing":
|
|
18
|
+
return cls(
|
|
19
|
+
id=data.get("id", ""),
|
|
20
|
+
name=data.get("name", ""),
|
|
21
|
+
slug=data.get("slug", ""),
|
|
22
|
+
description=data.get("description", ""),
|
|
23
|
+
category=data.get("category", ""),
|
|
24
|
+
base_url=data.get("baseUrl", ""),
|
|
25
|
+
tiers=data.get("tiers", []),
|
|
26
|
+
tags=data.get("tags", []),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class CallResult:
|
|
32
|
+
success: bool
|
|
33
|
+
data: Any
|
|
34
|
+
status_code: int
|
|
35
|
+
api_slug: str
|
|
36
|
+
endpoint: str
|
|
37
|
+
error: Optional[str] = None
|
|
38
|
+
|
|
39
|
+
def __repr__(self) -> str:
|
|
40
|
+
if self.success:
|
|
41
|
+
return f"<CallResult {self.api_slug} OK>"
|
|
42
|
+
return f"<CallResult {self.api_slug} ERROR: {self.error}>"
|