sentryrelay-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.
- sentryrelay_sdk-0.1.0/.gitignore +9 -0
- sentryrelay_sdk-0.1.0/PKG-INFO +464 -0
- sentryrelay_sdk-0.1.0/README.md +415 -0
- sentryrelay_sdk-0.1.0/pyproject.toml +103 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/__init__.py +87 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/client.py +479 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/constants.py +28 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/errors.py +175 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/__init__.py +65 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/agno.py +140 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/browser_use.py +122 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/claude_agent.py +215 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/crewai.py +75 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/google_adk.py +198 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/langgraph.py +115 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/microsoft_agent.py +161 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/openai_agents.py +158 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/playwright.py +43 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/pydantic_ai.py +188 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/smolagents.py +182 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/integrations/strands.py +175 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/models.py +202 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/py.typed +0 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/resources/__init__.py +19 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/resources/audit_logs.py +81 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/resources/identities.py +366 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/resources/totp.py +205 -0
- sentryrelay_sdk-0.1.0/src/sentryrelay/resources/webhooks.py +81 -0
- sentryrelay_sdk-0.1.0/tests/conftest.py +18 -0
- sentryrelay_sdk-0.1.0/tests/test_agent_framework_integrations.py +337 -0
- sentryrelay_sdk-0.1.0/tests/test_async.py +132 -0
- sentryrelay_sdk-0.1.0/tests/test_client.py +47 -0
- sentryrelay_sdk-0.1.0/tests/test_errors_and_retries.py +110 -0
- sentryrelay_sdk-0.1.0/tests/test_identities.py +271 -0
- sentryrelay_sdk-0.1.0/tests/test_integrations.py +111 -0
- sentryrelay_sdk-0.1.0/tests/test_totp.py +175 -0
- sentryrelay_sdk-0.1.0/tests/test_webhooks.py +109 -0
- sentryrelay_sdk-0.1.0/uv.lock +10116 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sentryrelay-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for Sentry Relay — The 2FA, OTP & Magic-Link Inbox API for Autonomous Software
|
|
5
|
+
Project-URL: Homepage, https://sentryrelay.com
|
|
6
|
+
Project-URL: Documentation, https://sentryrelay.com/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/sentryrelay/sentryrelay
|
|
8
|
+
Author-email: Sentry Relay Team <engineering@sentryrelay.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: 2fa,agno,ai-agents,automation,browser-use,claude-agent-sdk,crewai,google-adk,langgraph,magic-link,microsoft-agents,openai-agents,otp,playwright,pydantic-ai,sentryrelay,smolagents,strands,totp
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
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: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Security
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: httpx>=0.25.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Provides-Extra: agno
|
|
25
|
+
Requires-Dist: agno>=1.0.0; extra == 'agno'
|
|
26
|
+
Provides-Extra: claude-agent
|
|
27
|
+
Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude-agent'
|
|
28
|
+
Provides-Extra: crewai
|
|
29
|
+
Requires-Dist: crewai>=0.1.0; extra == 'crewai'
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: respx>=0.21.0; extra == 'dev'
|
|
34
|
+
Provides-Extra: google-adk
|
|
35
|
+
Requires-Dist: google-adk>=0.1.0; extra == 'google-adk'
|
|
36
|
+
Provides-Extra: langchain
|
|
37
|
+
Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
|
|
38
|
+
Provides-Extra: microsoft-agents
|
|
39
|
+
Requires-Dist: agent-framework>=0.1.0; extra == 'microsoft-agents'
|
|
40
|
+
Provides-Extra: openai-agents
|
|
41
|
+
Requires-Dist: openai-agents>=0.1.0; extra == 'openai-agents'
|
|
42
|
+
Provides-Extra: pydantic-ai
|
|
43
|
+
Requires-Dist: pydantic-ai>=0.0.1; extra == 'pydantic-ai'
|
|
44
|
+
Provides-Extra: smolagents
|
|
45
|
+
Requires-Dist: smolagents>=1.0.0; extra == 'smolagents'
|
|
46
|
+
Provides-Extra: strands
|
|
47
|
+
Requires-Dist: strands-agents>=0.1.0; extra == 'strands'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# Sentry Relay Python SDK
|
|
51
|
+
|
|
52
|
+
[](https://pypi.org/project/sentryrelay-sdk/)
|
|
53
|
+
[](https://www.python.org/downloads/)
|
|
54
|
+
[](https://opensource.org/licenses/MIT)
|
|
55
|
+
|
|
56
|
+
Official Python SDK for **[Sentry Relay](https://sentryrelay.com)** (`sentryrelay.com`) — The zero-retention 2FA, OTP, Magic-Link & Authenticator (TOTP) Vault API engineered specifically for autonomous software, AI browser agents, and multi-agent frameworks.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Key Features
|
|
61
|
+
|
|
62
|
+
- **⚡ Sub-200ms Long-Polling (`/wait`):** Deterministic OTP & magic-link extraction from incoming email and carrier-grade SMS shortcodes via Redis pub/sub push.
|
|
63
|
+
- **🛡️ Expiring-Window TOTP Rollover (`auto_wait_fresh_window`):** When `<=4s` remain in an RFC 6238 TOTP window, the SDK automatically pauses and fetches a freshly rolled code so browser agents never fail mid-keystroke.
|
|
64
|
+
- **🔄 Sync & Async Support:** Native support for both synchronous (`SentryRelay`) and asynchronous (`AsyncSentryRelay`) workflows.
|
|
65
|
+
- **🤖 Native Multi-Framework Agent Integrations:** Turnkey tools for **Google ADK**, **Microsoft Agent Framework**, **PydanticAI**, **OpenAI Agents SDK**, **Claude Agent SDK**, **Strands Agents**, **Agno**, **Smolagents**, **LangGraph**, **CrewAI**, **Browser Use**, and **Playwright**.
|
|
66
|
+
- **🔒 Zero-PII & Zero Raw Message Retention:** Ephemeral in-memory OTP queueing with automatic 60-second purge or atomic burn-after-read.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Core SDK (httpx + pydantic)
|
|
74
|
+
pip install sentryrelay-sdk
|
|
75
|
+
|
|
76
|
+
# Or using uv:
|
|
77
|
+
uv add sentryrelay-sdk
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Framework Optional Extras
|
|
81
|
+
|
|
82
|
+
Install with specialized dependencies for your favorite agent framework:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install "sentryrelay-sdk[google-adk]" # Google ADK (Gemini & Vertex AI)
|
|
86
|
+
pip install "sentryrelay-sdk[microsoft-agents]" # Microsoft Agent Framework
|
|
87
|
+
pip install "sentryrelay-sdk[pydantic-ai]" # PydanticAI
|
|
88
|
+
pip install "sentryrelay-sdk[openai-agents]" # OpenAI Agents SDK
|
|
89
|
+
pip install "sentryrelay-sdk[claude-agent]" # Claude Agent SDK / Anthropic
|
|
90
|
+
pip install "sentryrelay-sdk[strands]" # Strands Agents
|
|
91
|
+
pip install "sentryrelay-sdk[agno]" # Agno (formerly Phidata)
|
|
92
|
+
pip install "sentryrelay-sdk[smolagents]" # Smolagents (Hugging Face)
|
|
93
|
+
pip install "sentryrelay-sdk[langchain]" # LangGraph / LangChain
|
|
94
|
+
pip install "sentryrelay-sdk[crewai]" # CrewAI
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Authentication
|
|
100
|
+
|
|
101
|
+
Set your API key as an environment variable:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
export SENTRY_RELAY_API_KEY="sr_live_..."
|
|
105
|
+
# Or test sandbox environment:
|
|
106
|
+
export SENTRY_RELAY_API_KEY="sr_test_..."
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or pass it directly when instantiating the client:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from sentryrelay import SentryRelay
|
|
113
|
+
|
|
114
|
+
relay = SentryRelay(api_key="sr_live_...")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Quickstart
|
|
120
|
+
|
|
121
|
+
### 1. Synchronous Client
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from sentryrelay import SentryRelay
|
|
125
|
+
|
|
126
|
+
relay = SentryRelay()
|
|
127
|
+
|
|
128
|
+
# Wait up to 30s for an inbound OTP (Email or SMS)
|
|
129
|
+
auth = relay.wait("checkout-bot", sender="stripe.com", timeout=30)
|
|
130
|
+
|
|
131
|
+
if auth.matched:
|
|
132
|
+
print(f"Received OTP: {auth.otp_code} in {auth.wait_duration_ms}ms")
|
|
133
|
+
if auth.magic_link:
|
|
134
|
+
print(f"Magic Link: {auth.magic_link}")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 2. Asynchronous Client
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
import asyncio
|
|
141
|
+
from sentryrelay import AsyncSentryRelay
|
|
142
|
+
|
|
143
|
+
async def main():
|
|
144
|
+
async with AsyncSentryRelay() as relay:
|
|
145
|
+
auth = await relay.wait("checkout-bot", channel="email", timeout=30)
|
|
146
|
+
if auth.matched:
|
|
147
|
+
print(f"OTP Code: {auth.otp_code}")
|
|
148
|
+
|
|
149
|
+
asyncio.run(main())
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Agent Framework Integrations
|
|
155
|
+
|
|
156
|
+
Sentry Relay includes dedicated integration modules in `sentryrelay.integrations` for all major AI agent frameworks.
|
|
157
|
+
|
|
158
|
+
### 1. Google ADK (Agent Development Kit)
|
|
159
|
+
|
|
160
|
+
For Gemini and Vertex AI agents built with `google-adk`:
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from google.adk.agents.llm_agent import Agent
|
|
164
|
+
from sentryrelay import SentryRelay
|
|
165
|
+
from sentryrelay.integrations.google_adk import create_google_adk_tools
|
|
166
|
+
|
|
167
|
+
relay = SentryRelay()
|
|
168
|
+
tools = create_google_adk_tools(relay)
|
|
169
|
+
|
|
170
|
+
agent = Agent(
|
|
171
|
+
model="gemini-2.5-flash",
|
|
172
|
+
name="auth_verifier",
|
|
173
|
+
instruction="Resolve 2FA verification challenges by waiting for codes or retrieving TOTPs.",
|
|
174
|
+
tools=tools,
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 2. Microsoft Agent Framework
|
|
179
|
+
|
|
180
|
+
For Microsoft Agent Framework (`agent-framework`) and Azure AI Projects:
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from agent_framework import ChatAgent
|
|
184
|
+
from sentryrelay import SentryRelay
|
|
185
|
+
from sentryrelay.integrations.microsoft_agent import create_microsoft_agent_tools
|
|
186
|
+
|
|
187
|
+
relay = SentryRelay()
|
|
188
|
+
tools = create_microsoft_agent_tools(relay)
|
|
189
|
+
|
|
190
|
+
agent = ChatAgent(
|
|
191
|
+
name="SecurityAgent",
|
|
192
|
+
tools=tools,
|
|
193
|
+
instructions="Handle 2FA and OTP authentication challenges autonomously.",
|
|
194
|
+
)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 3. PydanticAI
|
|
198
|
+
|
|
199
|
+
Type-safe agent tools with structured schemas for `pydantic-ai`:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from pydantic_ai import Agent
|
|
203
|
+
from sentryrelay import SentryRelay
|
|
204
|
+
from sentryrelay.integrations.pydantic_ai import register_sentryrelay_tools
|
|
205
|
+
|
|
206
|
+
relay = SentryRelay()
|
|
207
|
+
agent = Agent('openai:gpt-4o', system_prompt="Handle automated authentication.")
|
|
208
|
+
|
|
209
|
+
# Registers wait_for_verification_code, get_totp_code, and list_identities
|
|
210
|
+
register_sentryrelay_tools(agent, relay)
|
|
211
|
+
|
|
212
|
+
result = agent.run_sync("Log into Okta using identity dev-agent and provide the OTP.")
|
|
213
|
+
print(result.data)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 4. OpenAI Agents SDK
|
|
217
|
+
|
|
218
|
+
For the official OpenAI Agents SDK (`openai-agents` / `agents`):
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from agents import Agent, Runner
|
|
222
|
+
from sentryrelay import SentryRelay
|
|
223
|
+
from sentryrelay.integrations.openai_agents import create_openai_agents_tools
|
|
224
|
+
|
|
225
|
+
relay = SentryRelay()
|
|
226
|
+
tools = create_openai_agents_tools(relay)
|
|
227
|
+
|
|
228
|
+
agent = Agent(
|
|
229
|
+
name="LoginAssistant",
|
|
230
|
+
instructions="You automate account sign-ins. Use Sentry Relay tools to solve 2FA challenges.",
|
|
231
|
+
tools=tools,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
result = Runner.run_sync(agent, "Sign in using checkout-bot and retrieve the incoming SMS code.")
|
|
235
|
+
print(result.final_output)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 5. Claude Agent SDK & Anthropic Tool Use
|
|
239
|
+
|
|
240
|
+
For Claude models (`claude-3-7-sonnet`, `claude-3-5-haiku`) and `claude-agent-sdk`:
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
import anthropic
|
|
244
|
+
from sentryrelay import SentryRelay
|
|
245
|
+
from sentryrelay.integrations.claude_agent import create_claude_agent_tools
|
|
246
|
+
|
|
247
|
+
relay = SentryRelay()
|
|
248
|
+
tools = create_claude_agent_tools(relay)
|
|
249
|
+
client = anthropic.Anthropic()
|
|
250
|
+
|
|
251
|
+
# Pass tools.definitions directly to messages.create
|
|
252
|
+
response = client.messages.create(
|
|
253
|
+
model="claude-3-7-sonnet-20250219",
|
|
254
|
+
max_tokens=1024,
|
|
255
|
+
tools=tools.definitions,
|
|
256
|
+
messages=[{"role": "user", "content": "Wait for OTP code on identity 'checkout-bot'"}],
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Dispatch execution
|
|
260
|
+
for block in response.content:
|
|
261
|
+
if block.type == "tool_use":
|
|
262
|
+
result = tools.execute(block.name, block.input)
|
|
263
|
+
print("Tool Output:", result)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 6. Strands Agents
|
|
267
|
+
|
|
268
|
+
For agents built with `strands-agents`:
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from strands import Agent
|
|
272
|
+
from sentryrelay import SentryRelay
|
|
273
|
+
from sentryrelay.integrations.strands import create_strands_tools
|
|
274
|
+
|
|
275
|
+
relay = SentryRelay()
|
|
276
|
+
tools = create_strands_tools(relay)
|
|
277
|
+
|
|
278
|
+
agent = Agent(
|
|
279
|
+
model="claude-3-7-sonnet-20250219",
|
|
280
|
+
name="browser_auth_agent",
|
|
281
|
+
system_prompt="Resolve OTP and TOTP verification challenges using Sentry Relay.",
|
|
282
|
+
tools=tools,
|
|
283
|
+
)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 7. Agno (formerly Phidata)
|
|
287
|
+
|
|
288
|
+
Integrated `Toolkit` subclass for Agno agents:
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
from agno.agent import Agent
|
|
292
|
+
from agno.models.openai import OpenAIChat
|
|
293
|
+
from sentryrelay import SentryRelay
|
|
294
|
+
from sentryrelay.integrations.agno import SentryRelayTools
|
|
295
|
+
|
|
296
|
+
relay = SentryRelay()
|
|
297
|
+
|
|
298
|
+
agent = Agent(
|
|
299
|
+
model=OpenAIChat(id="gpt-4o"),
|
|
300
|
+
tools=[SentryRelayTools(relay)],
|
|
301
|
+
instructions="Solve 2FA challenges by waiting on inbound codes or generating live TOTPs.",
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
agent.print_response("Wait for the 2FA code sent to identity 'checkout-bot'")
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### 8. Smolagents (Hugging Face)
|
|
308
|
+
|
|
309
|
+
Native `Tool` classes for Hugging Face `smolagents`:
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
from smolagents import CodeAgent, HfApiModel
|
|
313
|
+
from sentryrelay import SentryRelay
|
|
314
|
+
from sentryrelay.integrations.smolagents import create_smolagents_tools
|
|
315
|
+
|
|
316
|
+
relay = SentryRelay()
|
|
317
|
+
tools = create_smolagents_tools(relay)
|
|
318
|
+
|
|
319
|
+
agent = CodeAgent(
|
|
320
|
+
tools=tools,
|
|
321
|
+
model=HfApiModel(),
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
agent.run("Fetch the latest TOTP authenticator code for identity 'checkout-bot' with secret 'github_ops'")
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### 9. LangGraph & LangChain
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from langgraph.prebuilt import create_react_agent
|
|
331
|
+
from langchain_openai import ChatOpenAI
|
|
332
|
+
from sentryrelay import SentryRelay
|
|
333
|
+
from sentryrelay.integrations.langgraph import create_sentryrelay_tools
|
|
334
|
+
|
|
335
|
+
relay = SentryRelay()
|
|
336
|
+
tools = create_sentryrelay_tools(relay)
|
|
337
|
+
llm = ChatOpenAI(model="gpt-4o")
|
|
338
|
+
|
|
339
|
+
app = create_react_agent(llm, tools=tools)
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 10. CrewAI
|
|
343
|
+
|
|
344
|
+
```python
|
|
345
|
+
from crewai import Agent, Task, Crew
|
|
346
|
+
from sentryrelay import SentryRelay
|
|
347
|
+
from sentryrelay.integrations.crewai import create_crewai_tools
|
|
348
|
+
|
|
349
|
+
relay = SentryRelay()
|
|
350
|
+
tools = create_crewai_tools(relay)
|
|
351
|
+
|
|
352
|
+
auth_specialist = Agent(
|
|
353
|
+
role="Authentication Specialist",
|
|
354
|
+
goal="Handle 2FA and MFA verification challenges",
|
|
355
|
+
backstory="Expert at retrieving inbound OTP codes and managing TOTP credentials",
|
|
356
|
+
tools=tools,
|
|
357
|
+
)
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### 11. Browser Use
|
|
361
|
+
|
|
362
|
+
Integrate Sentry Relay actions into your [Browser Use](https://browser-use.com) controller:
|
|
363
|
+
|
|
364
|
+
```python
|
|
365
|
+
from browser_use import Agent, Controller
|
|
366
|
+
from sentryrelay import AsyncSentryRelay
|
|
367
|
+
from sentryrelay.integrations.browser_use import register_sentryrelay_actions
|
|
368
|
+
|
|
369
|
+
controller = Controller()
|
|
370
|
+
relay = AsyncSentryRelay()
|
|
371
|
+
|
|
372
|
+
# Registers 'wait_for_2fa_code' and 'get_totp_token'
|
|
373
|
+
register_sentryrelay_actions(controller, relay)
|
|
374
|
+
|
|
375
|
+
agent = Agent(
|
|
376
|
+
task="Log into Stripe, enter credentials, and supply 2FA verification code using identity 'checkout-bot'",
|
|
377
|
+
controller=controller,
|
|
378
|
+
)
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 12. Playwright Python (Async)
|
|
382
|
+
|
|
383
|
+
```python
|
|
384
|
+
import asyncio
|
|
385
|
+
from playwright.async_api import async_playwright
|
|
386
|
+
from sentryrelay import AsyncSentryRelay, fill_otp_code
|
|
387
|
+
|
|
388
|
+
async def test_login():
|
|
389
|
+
async with async_playwright() as p:
|
|
390
|
+
browser = await p.chromium.launch()
|
|
391
|
+
page = await browser.new_page()
|
|
392
|
+
|
|
393
|
+
async with AsyncSentryRelay() as relay:
|
|
394
|
+
# 1. Trigger login form
|
|
395
|
+
await page.goto("https://app.target.com/login")
|
|
396
|
+
await page.fill('input[type="email"]', "checkout-bot@in.sentryrelay.com")
|
|
397
|
+
await page.click('button[type="submit"]')
|
|
398
|
+
|
|
399
|
+
# 2. Intercept OTP in <200ms of arrival
|
|
400
|
+
auth = await relay.wait("checkout-bot", sender="target.com", timeout=30)
|
|
401
|
+
|
|
402
|
+
# 3. Fill the OTP code into the challenge prompt
|
|
403
|
+
await fill_otp_code(page, 'input[name="otp"]', auth)
|
|
404
|
+
await page.click('button#verify')
|
|
405
|
+
|
|
406
|
+
await browser.close()
|
|
407
|
+
|
|
408
|
+
asyncio.run(test_login())
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## RFC 6238 TOTP Authenticator Vault
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
from sentryrelay import SentryRelay
|
|
417
|
+
|
|
418
|
+
relay = SentryRelay()
|
|
419
|
+
|
|
420
|
+
# Generate a live 6-digit TOTP code
|
|
421
|
+
# auto_wait_fresh_window=True automatically waits <4s if the current 30s period is expiring
|
|
422
|
+
totp = relay.totp.get("checkout-bot", "github_ops")
|
|
423
|
+
|
|
424
|
+
print(f"Code: {totp.code} ({totp.remaining_seconds}s remaining)")
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## API Reference
|
|
430
|
+
|
|
431
|
+
### `relay.identities`
|
|
432
|
+
|
|
433
|
+
- `relay.identities.list(limit=None, cursor=None)`
|
|
434
|
+
- `relay.identities.get(id_or_slug)`
|
|
435
|
+
- `relay.identities.create(name, slug=None, email_handle=None, fallback=None, custom_rules=None)`
|
|
436
|
+
- `relay.identities.update(id_or_slug, name=None, status=None, fallback=None, custom_rules=None)`
|
|
437
|
+
- `relay.identities.delete(id_or_slug)`
|
|
438
|
+
- `relay.identities.wait(id_or_slug, timeout=30, since=None, channel=None, sender=None, subject=None, consume=True)`
|
|
439
|
+
- `relay.identities.latest(id_or_slug, lookback_seconds=60, since=None, channel=None, sender=None, subject=None, consume=True)`
|
|
440
|
+
- `relay.identities.provision_sms_did(id_or_slug, area_code=None)`
|
|
441
|
+
- `relay.identities.release_sms_did(id_or_slug)`
|
|
442
|
+
|
|
443
|
+
### `relay.totp`
|
|
444
|
+
|
|
445
|
+
- `relay.totp.list(id_or_slug)`
|
|
446
|
+
- `relay.totp.create(id_or_slug, otpauth_uri=None, secret=None, issuer=None, ...)`
|
|
447
|
+
- `relay.totp.get(id_or_slug, secret_id, auto_wait_fresh_window=True, now_ms=None)`
|
|
448
|
+
- `relay.totp.delete(id_or_slug, secret_id)`
|
|
449
|
+
|
|
450
|
+
### `relay.webhooks`
|
|
451
|
+
|
|
452
|
+
- `relay.webhooks.list()`
|
|
453
|
+
- `relay.webhooks.create(target_url, events, scoped_identity_ids=None)`
|
|
454
|
+
- `relay.webhooks.delete(webhook_id)`
|
|
455
|
+
|
|
456
|
+
### `relay.audit_logs`
|
|
457
|
+
|
|
458
|
+
- `relay.audit_logs.list(identity_id=None, event_type=None, from_time=None, to_time=None, limit=None)`
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## License
|
|
463
|
+
|
|
464
|
+
MIT © [Sentry Relay](https://sentryrelay.com)
|