agentadmit 1.0.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.
@@ -0,0 +1,56 @@
1
+ AgentAdmit Proprietary License
2
+
3
+ Copyright (c) 2026 AgentAdmit LLC. All rights reserved.
4
+
5
+ Patent Pending — U.S. Application No. 19/660,916
6
+
7
+ TERMS OF USE
8
+
9
+ 1. GRANT OF LICENSE. AgentAdmit LLC ("Licensor") grants you a limited,
10
+ non-exclusive, non-transferable, revocable license to use this software
11
+ development kit ("SDK") solely for the purpose of integrating with the
12
+ AgentAdmit hosted service (api.agentadmit.com).
13
+
14
+ 2. RESTRICTIONS. You may not:
15
+ (a) Use this SDK with any service other than the AgentAdmit hosted service;
16
+ (b) Modify, adapt, or create derivative works of this SDK for the purpose
17
+ of building or operating a competing service;
18
+ (c) Reverse engineer, decompile, or disassemble the AgentAdmit protocol
19
+ or service architecture;
20
+ (d) Remove or alter any proprietary notices, labels, or marks;
21
+ (e) Redistribute this SDK as a standalone product or as part of a
22
+ competing authorization service.
23
+
24
+ 3. PERMITTED USES. You may:
25
+ (a) Install and use this SDK in your applications;
26
+ (b) Include this SDK as a dependency in your projects;
27
+ (c) Distribute your applications that incorporate this SDK, provided
28
+ those applications connect to the AgentAdmit hosted service.
29
+
30
+ 4. AGENTADMIT SERVICE REQUIRED. This SDK is designed exclusively for use
31
+ with the AgentAdmit hosted service. An AgentAdmit account and valid API
32
+ keys are required. Sign up at https://agentadmit.com.
33
+
34
+ 5. INTELLECTUAL PROPERTY. The AgentAdmit protocol, user-mediated token
35
+ delivery mechanism, mandatory introspection architecture, and related
36
+ inventions are protected by pending U.S. patent(s) and other intellectual
37
+ property rights. This license does not grant any rights to the underlying
38
+ patents or trade secrets.
39
+
40
+ 6. NO WARRANTY. THIS SDK IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
41
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
42
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
43
+
44
+ 7. LIMITATION OF LIABILITY. IN NO EVENT SHALL AGENTADMIT LLC BE LIABLE FOR
45
+ ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES
46
+ ARISING FROM YOUR USE OF THIS SDK.
47
+
48
+ 8. TERMINATION. This license terminates automatically if you violate any
49
+ of its terms. Upon termination, you must cease all use and destroy all
50
+ copies of this SDK in your possession.
51
+
52
+ 9. GOVERNING LAW. This license is governed by the laws of the State of
53
+ California, United States.
54
+
55
+ For licensing inquiries: legal@agentadmit.com
56
+ For developer support: https://agentadmit.com/docs
@@ -0,0 +1,286 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentadmit
3
+ Version: 1.0.0
4
+ Summary: AgentAdmit SDK — User-mediated AI agent authorization for any app
5
+ Author: Christopher Emerson
6
+ License: Proprietary
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: fastapi<1.0.0,>=0.100.0
11
+ Requires-Dist: PyJWT<3.0.0,>=2.8.0
12
+ Requires-Dist: cryptography<45.0.0,>=41.0.0
13
+ Requires-Dist: PyYAML<7.0,>=6.0
14
+ Requires-Dist: pymongo<5.0.0,>=4.0.0
15
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
16
+ Requires-Dist: starlette<1.0.0,>=0.27.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest<9.0,>=7.0; extra == "dev"
19
+ Requires-Dist: httpx<1.0.0,>=0.24.0; extra == "dev"
20
+ Requires-Dist: uvicorn<1.0.0,>=0.23.0; extra == "dev"
21
+ Dynamic: license-file
22
+
23
+ # AgentAdmit SDK for Python
24
+
25
+ User-mediated AI agent authorization for Python apps. Supports **FastAPI**, **Flask**, and **Django**.
26
+
27
+ > **Get started:** Sign up at [agentadmit.com](https://agentadmit.com) → Get your test keys → Install the SDK → Build.
28
+ > Test keys are available immediately after signup. Live keys become available when you subscribe an app.
29
+
30
+ ## Quick Start
31
+
32
+ ```bash
33
+ pip install agentadmit
34
+ agentadmit init
35
+ ```
36
+
37
+ Edit `agentadmit.yaml` to define your scopes, then add to your FastAPI app:
38
+
39
+ ```python
40
+ from fastapi import FastAPI, Depends
41
+ from agentadmit import AgentAdmitMiddleware, require_scope_if_agent, get_current_user_or_agent
42
+
43
+ app = FastAPI()
44
+
45
+ # One-line setup
46
+ app.add_middleware(
47
+ AgentAdmitMiddleware,
48
+ config_path="agentadmit.yaml",
49
+ get_current_user=your_auth_dependency,
50
+ verify_user_token=your_token_verifier,
51
+ users_collection="users",
52
+ )
53
+
54
+ # Add scope enforcement to any route
55
+ @app.get("/api/orders")
56
+ async def get_orders(
57
+ auth_ctx=Depends(get_current_user_or_agent),
58
+ _scope=Depends(require_scope_if_agent("read:orders")),
59
+ ):
60
+ user = auth_ctx["user"]
61
+ # Your existing logic — unchanged
62
+ return {"orders": get_orders_for_user(user["user_id"])}
63
+ ```
64
+
65
+ Your app now supports AI agent connections with:
66
+ - Scoped access control (you define the scopes)
67
+ - User-controlled connection duration
68
+ - Token generation and exchange
69
+ - Revocation
70
+ - Audit logging
71
+ - Discovery endpoint
72
+
73
+ ## How It Works
74
+
75
+ 1. User clicks "AgentAdmit" in your app
76
+ 2. Selects scopes and connection duration
77
+ 3. Gets a token to give to their AI agent
78
+ 4. Agent exchanges the token for scoped API access
79
+ 5. User revokes anytime
80
+
81
+ The token goes to the human, not the agent. No automated delivery = no prompt injection surface.
82
+
83
+ ## CLI
84
+
85
+ ```bash
86
+ agentadmit init # Generate config and keys
87
+ agentadmit keys # Regenerate RS256 key pair
88
+ agentadmit check # Validate configuration
89
+ ```
90
+
91
+ ## Flask Integration
92
+
93
+ ```python
94
+ from flask import Flask
95
+ from agentadmit.integrations.flask_integration import AgentAdmitFlask
96
+
97
+ app = Flask(__name__)
98
+ aa = AgentAdmitFlask(app, config_path="agentadmit.yaml")
99
+
100
+ @app.route('/api/orders')
101
+ @aa.require_scope_if_agent('read:orders')
102
+ def get_orders():
103
+ return get_user_orders()
104
+ ```
105
+
106
+ ## Django Integration
107
+
108
+ ```python
109
+ # settings.py
110
+ AGENTADMIT = {
111
+ 'APP_ID': 'app_yourappid',
112
+ 'API_KEY': 'aa_test_yourkey',
113
+ 'VERIFY_URL': 'https://api.agentadmit.com/v1/verify',
114
+ }
115
+
116
+ # views.py
117
+ from agentadmit.integrations.django_integration import require_scope_if_agent
118
+
119
+ @require_scope_if_agent('read:orders')
120
+ def get_orders(request):
121
+ return get_user_orders(request)
122
+ ```
123
+
124
+ ## MCP Server Integration
125
+
126
+ Building an MCP server in Python? AgentAdmit is the auth layer. MCP servers are app owners. Same SDK, same pricing.
127
+
128
+ For **STDIO transport** (most MCP servers), the agent includes the token in tool arguments:
129
+
130
+ ```python
131
+ import requests
132
+ import os
133
+
134
+ AGENTADMIT_VERIFY_URL = "https://api.agentadmit.com/v1/verify"
135
+ AGENTADMIT_API_KEY = os.environ["AGENTADMIT_API_KEY"]
136
+
137
+ def handle_tool_call(name: str, arguments: dict) -> dict:
138
+ # 1. Extract token from tool arguments
139
+ token = arguments.pop("agentadmit_token", None)
140
+ if not token:
141
+ raise PermissionError("agentadmit_token required")
142
+
143
+ # 2. Validate via AgentAdmit hosted service
144
+ resp = requests.post(
145
+ AGENTADMIT_VERIFY_URL,
146
+ headers={
147
+ "Authorization": f"Bearer {AGENTADMIT_API_KEY}",
148
+ "Content-Type": "application/json",
149
+ },
150
+ json={"token": token},
151
+ timeout=5,
152
+ )
153
+ if resp.status_code != 200:
154
+ raise PermissionError("Invalid or expired token")
155
+ ctx = resp.json()
156
+
157
+ # 3. Check scope for this tool
158
+ required_scope = SCOPE_MAP.get(name)
159
+ if required_scope and required_scope not in ctx.get("scopes", []):
160
+ raise PermissionError(f"Missing scope '{required_scope}'")
161
+
162
+ # 4. Run the tool
163
+ return TOOL_HANDLERS[name](arguments, ctx)
164
+ ```
165
+
166
+ For **HTTP transport** (FastAPI-based MCP servers), use the full SDK middleware. The agent sends the token via `Authorization: Bearer` header, same as any HTTP API.
167
+
168
+ Full MCP integration guide with complete before/after examples: `agentadmit.com/docs/mcp-guide`
169
+
170
+ **MCP operators:** You also get the embeddable admin panel with revoke capability, admin scopes for your own AI agent to monitor your server, and full audit trail for billing. See the Admin Revocation and Embeddable Admin Panel sections below.
171
+
172
+ ## Important
173
+
174
+ **Mandatory introspection.** All token validation goes through api.agentadmit.com. There is no self-hosted mode. No local JWT validation. No bypass. This is required for security, audit logging, and scope enforcement.
175
+
176
+ **Admin revocation.** As the app operator, you can revoke any user's agent connection via `DELETE /agentadmit/admin/connections/{connection_id}` (requires admin role or `manage:connections` scope). Your own AI agent can also revoke connections if given this scope.
177
+
178
+ **Embeddable admin panel.** Drop the `<AgentAdmitAdminPanel>` React component into your admin section to view all agent connections, usage metrics, billing status, and revoke any connection without leaving your app. See the React SDK for details.
179
+
180
+ **In-app AI scopes.** If your app has built-in AI features (analysis, plan generation, photo recognition), do not expose those as agent scopes. The user's AI agent can read the raw data and do the analysis itself. Exposing in-app AI endpoints to agents creates double cost.
181
+
182
+ ## Rate Limiting
183
+
184
+ The AgentAdmit introspection endpoint enforces rate limits. The Python SDK handles HTTP 429 responses **automatically** with exponential backoff and jitter — no changes needed in your app code.
185
+
186
+ ### Retry behavior
187
+
188
+ | Parameter | Default | Description |
189
+ |-----------|---------|-------------|
190
+ | Initial delay | 1 second | First retry wait |
191
+ | Backoff multiplier | 2× | Doubles each retry |
192
+ | Cap | 30 seconds | Maximum wait per retry |
193
+ | Jitter | 0–500 ms | Random addition to each delay |
194
+ | Max retries | **3** | Configurable |
195
+
196
+ The SDK also respects the `Retry-After` response header — if present, it overrides the computed backoff delay.
197
+
198
+ ### Configuring max retries
199
+
200
+ In `agentadmit.yaml`:
201
+
202
+ ```yaml
203
+ max_retries: 5 # default: 3. Set to 0 to disable retries.
204
+ ```
205
+
206
+ ### Handling exhausted retries
207
+
208
+ When all retries are exhausted, the SDK raises `RateLimitError`:
209
+
210
+ ```python
211
+ from agentadmit.exceptions import RateLimitError
212
+
213
+ try:
214
+ # Any endpoint protected with require_scope / get_agentadmit_user
215
+ ...
216
+ except RateLimitError as e:
217
+ print(f"Rate limited. Retry after {e.retry_after}s")
218
+ print(f"Limit: {e.limit}, Remaining: {e.remaining}, Reset: {e.reset}")
219
+ # Return 429 to the caller or queue for retry
220
+ ```
221
+
222
+ `RateLimitError` attributes:
223
+ - `retry_after` — seconds from `Retry-After` header (or `None`)
224
+ - `limit` — `X-RateLimit-Limit` header value (or `None`)
225
+ - `remaining` — `X-RateLimit-Remaining` header value (or `None`)
226
+ - `reset` — `X-RateLimit-Reset` Unix timestamp (or `None`)
227
+
228
+ ## Route Registration Order (FastAPI)
229
+
230
+ When using `create_agentadmit_router()`, the SDK registers default endpoints for
231
+ `/agentadmit/scopes`, `/agentadmit/connections/generate-token`, etc.
232
+
233
+ If you need to **override** any SDK endpoint with your own (e.g., a user-aware
234
+ `/scopes` endpoint), register your route **before** calling `app.include_router()`.
235
+ FastAPI resolves routes in registration order — the first matching route wins.
236
+
237
+ ```python
238
+ # ✅ CORRECT — custom /scopes registered before SDK router
239
+ @app.get("/agentadmit/scopes")
240
+ async def my_scopes(current_user: dict = Depends(get_current_user)):
241
+ # your user-aware logic
242
+ ...
243
+
244
+ wellknown_router, agentadmit_router = create_agentadmit_router(...)
245
+ app.include_router(wellknown_router)
246
+ app.include_router(agentadmit_router, prefix="/agentadmit")
247
+
248
+ # ❌ WRONG — custom route registered AFTER SDK router (shadowed, never reached)
249
+ wellknown_router, agentadmit_router = create_agentadmit_router(...)
250
+ app.include_router(agentadmit_router, prefix="/agentadmit") # SDK route wins
251
+ @app.get("/agentadmit/scopes") # never reached
252
+ async def my_scopes(): ...
253
+ ```
254
+
255
+ **Tip:** Use the `filter_scopes_for_user` callback parameter on
256
+ `create_agentadmit_router()` as a cleaner alternative to overriding `/scopes`
257
+ entirely — the SDK handles the endpoint and calls your function to filter results.
258
+
259
+ ## Documentation
260
+
261
+ Full integration guide: https://agentadmit.com/docs/app-owner-guide
262
+
263
+
264
+ ## Data Collection & Privacy
265
+
266
+ The AgentAdmit Python SDK runs server-side and does not interact with app stores or end-user devices directly.
267
+
268
+ ### What the SDK does
269
+ - Validates AgentAdmit tokens presented by AI agents
270
+ - Enforces scope-based access control on your API routes
271
+ - Manages connection lifecycle (create, revoke, audit)
272
+
273
+ ### What the SDK does NOT do
274
+ - Does not collect end-user data
275
+ - Does not send telemetry or analytics
276
+ - Does not phone home to AgentAdmit servers (all operations use your configured keys and storage)
277
+ - Does not track users or devices
278
+
279
+ ### Privacy impact
280
+ Since this SDK runs on your server, it has no direct App Store or Play Store compliance surface. Your client-side integration (e.g., the AgentAdmit React SDK) handles privacy manifest and data safety requirements.
281
+
282
+ For complete compliance guidance, see our [compliance guide](https://agentadmit.com/docs/compliance).
283
+
284
+ ## License
285
+
286
+ All rights reserved. Patent pending.
@@ -0,0 +1,264 @@
1
+ # AgentAdmit SDK for Python
2
+
3
+ User-mediated AI agent authorization for Python apps. Supports **FastAPI**, **Flask**, and **Django**.
4
+
5
+ > **Get started:** Sign up at [agentadmit.com](https://agentadmit.com) → Get your test keys → Install the SDK → Build.
6
+ > Test keys are available immediately after signup. Live keys become available when you subscribe an app.
7
+
8
+ ## Quick Start
9
+
10
+ ```bash
11
+ pip install agentadmit
12
+ agentadmit init
13
+ ```
14
+
15
+ Edit `agentadmit.yaml` to define your scopes, then add to your FastAPI app:
16
+
17
+ ```python
18
+ from fastapi import FastAPI, Depends
19
+ from agentadmit import AgentAdmitMiddleware, require_scope_if_agent, get_current_user_or_agent
20
+
21
+ app = FastAPI()
22
+
23
+ # One-line setup
24
+ app.add_middleware(
25
+ AgentAdmitMiddleware,
26
+ config_path="agentadmit.yaml",
27
+ get_current_user=your_auth_dependency,
28
+ verify_user_token=your_token_verifier,
29
+ users_collection="users",
30
+ )
31
+
32
+ # Add scope enforcement to any route
33
+ @app.get("/api/orders")
34
+ async def get_orders(
35
+ auth_ctx=Depends(get_current_user_or_agent),
36
+ _scope=Depends(require_scope_if_agent("read:orders")),
37
+ ):
38
+ user = auth_ctx["user"]
39
+ # Your existing logic — unchanged
40
+ return {"orders": get_orders_for_user(user["user_id"])}
41
+ ```
42
+
43
+ Your app now supports AI agent connections with:
44
+ - Scoped access control (you define the scopes)
45
+ - User-controlled connection duration
46
+ - Token generation and exchange
47
+ - Revocation
48
+ - Audit logging
49
+ - Discovery endpoint
50
+
51
+ ## How It Works
52
+
53
+ 1. User clicks "AgentAdmit" in your app
54
+ 2. Selects scopes and connection duration
55
+ 3. Gets a token to give to their AI agent
56
+ 4. Agent exchanges the token for scoped API access
57
+ 5. User revokes anytime
58
+
59
+ The token goes to the human, not the agent. No automated delivery = no prompt injection surface.
60
+
61
+ ## CLI
62
+
63
+ ```bash
64
+ agentadmit init # Generate config and keys
65
+ agentadmit keys # Regenerate RS256 key pair
66
+ agentadmit check # Validate configuration
67
+ ```
68
+
69
+ ## Flask Integration
70
+
71
+ ```python
72
+ from flask import Flask
73
+ from agentadmit.integrations.flask_integration import AgentAdmitFlask
74
+
75
+ app = Flask(__name__)
76
+ aa = AgentAdmitFlask(app, config_path="agentadmit.yaml")
77
+
78
+ @app.route('/api/orders')
79
+ @aa.require_scope_if_agent('read:orders')
80
+ def get_orders():
81
+ return get_user_orders()
82
+ ```
83
+
84
+ ## Django Integration
85
+
86
+ ```python
87
+ # settings.py
88
+ AGENTADMIT = {
89
+ 'APP_ID': 'app_yourappid',
90
+ 'API_KEY': 'aa_test_yourkey',
91
+ 'VERIFY_URL': 'https://api.agentadmit.com/v1/verify',
92
+ }
93
+
94
+ # views.py
95
+ from agentadmit.integrations.django_integration import require_scope_if_agent
96
+
97
+ @require_scope_if_agent('read:orders')
98
+ def get_orders(request):
99
+ return get_user_orders(request)
100
+ ```
101
+
102
+ ## MCP Server Integration
103
+
104
+ Building an MCP server in Python? AgentAdmit is the auth layer. MCP servers are app owners. Same SDK, same pricing.
105
+
106
+ For **STDIO transport** (most MCP servers), the agent includes the token in tool arguments:
107
+
108
+ ```python
109
+ import requests
110
+ import os
111
+
112
+ AGENTADMIT_VERIFY_URL = "https://api.agentadmit.com/v1/verify"
113
+ AGENTADMIT_API_KEY = os.environ["AGENTADMIT_API_KEY"]
114
+
115
+ def handle_tool_call(name: str, arguments: dict) -> dict:
116
+ # 1. Extract token from tool arguments
117
+ token = arguments.pop("agentadmit_token", None)
118
+ if not token:
119
+ raise PermissionError("agentadmit_token required")
120
+
121
+ # 2. Validate via AgentAdmit hosted service
122
+ resp = requests.post(
123
+ AGENTADMIT_VERIFY_URL,
124
+ headers={
125
+ "Authorization": f"Bearer {AGENTADMIT_API_KEY}",
126
+ "Content-Type": "application/json",
127
+ },
128
+ json={"token": token},
129
+ timeout=5,
130
+ )
131
+ if resp.status_code != 200:
132
+ raise PermissionError("Invalid or expired token")
133
+ ctx = resp.json()
134
+
135
+ # 3. Check scope for this tool
136
+ required_scope = SCOPE_MAP.get(name)
137
+ if required_scope and required_scope not in ctx.get("scopes", []):
138
+ raise PermissionError(f"Missing scope '{required_scope}'")
139
+
140
+ # 4. Run the tool
141
+ return TOOL_HANDLERS[name](arguments, ctx)
142
+ ```
143
+
144
+ For **HTTP transport** (FastAPI-based MCP servers), use the full SDK middleware. The agent sends the token via `Authorization: Bearer` header, same as any HTTP API.
145
+
146
+ Full MCP integration guide with complete before/after examples: `agentadmit.com/docs/mcp-guide`
147
+
148
+ **MCP operators:** You also get the embeddable admin panel with revoke capability, admin scopes for your own AI agent to monitor your server, and full audit trail for billing. See the Admin Revocation and Embeddable Admin Panel sections below.
149
+
150
+ ## Important
151
+
152
+ **Mandatory introspection.** All token validation goes through api.agentadmit.com. There is no self-hosted mode. No local JWT validation. No bypass. This is required for security, audit logging, and scope enforcement.
153
+
154
+ **Admin revocation.** As the app operator, you can revoke any user's agent connection via `DELETE /agentadmit/admin/connections/{connection_id}` (requires admin role or `manage:connections` scope). Your own AI agent can also revoke connections if given this scope.
155
+
156
+ **Embeddable admin panel.** Drop the `<AgentAdmitAdminPanel>` React component into your admin section to view all agent connections, usage metrics, billing status, and revoke any connection without leaving your app. See the React SDK for details.
157
+
158
+ **In-app AI scopes.** If your app has built-in AI features (analysis, plan generation, photo recognition), do not expose those as agent scopes. The user's AI agent can read the raw data and do the analysis itself. Exposing in-app AI endpoints to agents creates double cost.
159
+
160
+ ## Rate Limiting
161
+
162
+ The AgentAdmit introspection endpoint enforces rate limits. The Python SDK handles HTTP 429 responses **automatically** with exponential backoff and jitter — no changes needed in your app code.
163
+
164
+ ### Retry behavior
165
+
166
+ | Parameter | Default | Description |
167
+ |-----------|---------|-------------|
168
+ | Initial delay | 1 second | First retry wait |
169
+ | Backoff multiplier | 2× | Doubles each retry |
170
+ | Cap | 30 seconds | Maximum wait per retry |
171
+ | Jitter | 0–500 ms | Random addition to each delay |
172
+ | Max retries | **3** | Configurable |
173
+
174
+ The SDK also respects the `Retry-After` response header — if present, it overrides the computed backoff delay.
175
+
176
+ ### Configuring max retries
177
+
178
+ In `agentadmit.yaml`:
179
+
180
+ ```yaml
181
+ max_retries: 5 # default: 3. Set to 0 to disable retries.
182
+ ```
183
+
184
+ ### Handling exhausted retries
185
+
186
+ When all retries are exhausted, the SDK raises `RateLimitError`:
187
+
188
+ ```python
189
+ from agentadmit.exceptions import RateLimitError
190
+
191
+ try:
192
+ # Any endpoint protected with require_scope / get_agentadmit_user
193
+ ...
194
+ except RateLimitError as e:
195
+ print(f"Rate limited. Retry after {e.retry_after}s")
196
+ print(f"Limit: {e.limit}, Remaining: {e.remaining}, Reset: {e.reset}")
197
+ # Return 429 to the caller or queue for retry
198
+ ```
199
+
200
+ `RateLimitError` attributes:
201
+ - `retry_after` — seconds from `Retry-After` header (or `None`)
202
+ - `limit` — `X-RateLimit-Limit` header value (or `None`)
203
+ - `remaining` — `X-RateLimit-Remaining` header value (or `None`)
204
+ - `reset` — `X-RateLimit-Reset` Unix timestamp (or `None`)
205
+
206
+ ## Route Registration Order (FastAPI)
207
+
208
+ When using `create_agentadmit_router()`, the SDK registers default endpoints for
209
+ `/agentadmit/scopes`, `/agentadmit/connections/generate-token`, etc.
210
+
211
+ If you need to **override** any SDK endpoint with your own (e.g., a user-aware
212
+ `/scopes` endpoint), register your route **before** calling `app.include_router()`.
213
+ FastAPI resolves routes in registration order — the first matching route wins.
214
+
215
+ ```python
216
+ # ✅ CORRECT — custom /scopes registered before SDK router
217
+ @app.get("/agentadmit/scopes")
218
+ async def my_scopes(current_user: dict = Depends(get_current_user)):
219
+ # your user-aware logic
220
+ ...
221
+
222
+ wellknown_router, agentadmit_router = create_agentadmit_router(...)
223
+ app.include_router(wellknown_router)
224
+ app.include_router(agentadmit_router, prefix="/agentadmit")
225
+
226
+ # ❌ WRONG — custom route registered AFTER SDK router (shadowed, never reached)
227
+ wellknown_router, agentadmit_router = create_agentadmit_router(...)
228
+ app.include_router(agentadmit_router, prefix="/agentadmit") # SDK route wins
229
+ @app.get("/agentadmit/scopes") # never reached
230
+ async def my_scopes(): ...
231
+ ```
232
+
233
+ **Tip:** Use the `filter_scopes_for_user` callback parameter on
234
+ `create_agentadmit_router()` as a cleaner alternative to overriding `/scopes`
235
+ entirely — the SDK handles the endpoint and calls your function to filter results.
236
+
237
+ ## Documentation
238
+
239
+ Full integration guide: https://agentadmit.com/docs/app-owner-guide
240
+
241
+
242
+ ## Data Collection & Privacy
243
+
244
+ The AgentAdmit Python SDK runs server-side and does not interact with app stores or end-user devices directly.
245
+
246
+ ### What the SDK does
247
+ - Validates AgentAdmit tokens presented by AI agents
248
+ - Enforces scope-based access control on your API routes
249
+ - Manages connection lifecycle (create, revoke, audit)
250
+
251
+ ### What the SDK does NOT do
252
+ - Does not collect end-user data
253
+ - Does not send telemetry or analytics
254
+ - Does not phone home to AgentAdmit servers (all operations use your configured keys and storage)
255
+ - Does not track users or devices
256
+
257
+ ### Privacy impact
258
+ Since this SDK runs on your server, it has no direct App Store or Play Store compliance surface. Your client-side integration (e.g., the AgentAdmit React SDK) handles privacy manifest and data safety requirements.
259
+
260
+ For complete compliance guidance, see our [compliance guide](https://agentadmit.com/docs/compliance).
261
+
262
+ ## License
263
+
264
+ All rights reserved. Patent pending.
@@ -0,0 +1,61 @@
1
+ """
2
+ AgentAdmit SDK for Python
3
+ =========================
4
+
5
+ User-mediated AI agent authorization. Plug-and-play for any FastAPI app.
6
+
7
+ Quick Start:
8
+ from agentadmit import AgentAdmitMiddleware, require_scope, require_scope_if_agent
9
+
10
+ app.add_middleware(AgentAdmitMiddleware, config_path="agentadmit.yaml")
11
+
12
+ @app.get("/api/orders")
13
+ async def get_orders(
14
+ auth_ctx=Depends(get_current_user_or_agent),
15
+ _scope=Depends(require_scope_if_agent("read:orders")),
16
+ ):
17
+ ...
18
+ """
19
+
20
+ __version__ = "0.1.0"
21
+
22
+ from agentadmit.config import AgentAdmitConfig, load_config
23
+ from agentadmit.middleware import AgentAdmitMiddleware
24
+ from agentadmit.auth import (
25
+ get_agentadmit_user,
26
+ get_current_user_or_agent,
27
+ require_scope,
28
+ require_scope_if_agent,
29
+ log_agent_access,
30
+ check_connection_cap,
31
+ )
32
+ from agentadmit.routes import create_agentadmit_router
33
+ # keys.py is deprecated — AgentAdmit is a hosted service, no local keys needed
34
+ from agentadmit.exceptions import (
35
+ AgentAdmitError,
36
+ InvalidTokenError,
37
+ InsufficientScopeError,
38
+ ConnectionRevokedError,
39
+ ConnectionLimitError,
40
+ ConfigurationError,
41
+ )
42
+
43
+ __all__ = [
44
+ "AgentAdmitMiddleware",
45
+ "AgentAdmitConfig",
46
+ "load_config",
47
+ "get_agentadmit_user",
48
+ "get_current_user_or_agent",
49
+ "require_scope",
50
+ "require_scope_if_agent",
51
+ "log_agent_access",
52
+ "check_connection_cap",
53
+ "create_agentadmit_router",
54
+
55
+ "AgentAdmitError",
56
+ "InvalidTokenError",
57
+ "InsufficientScopeError",
58
+ "ConnectionRevokedError",
59
+ "ConnectionLimitError",
60
+ "ConfigurationError",
61
+ ]