google-adk-extras 0.2.6__tar.gz → 0.3.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.
- {google_adk_extras-0.2.6/src/google_adk_extras.egg-info → google_adk_extras-0.3.0}/PKG-INFO +84 -34
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/README.md +82 -32
- google_adk_extras-0.3.0/docs/auth.md +79 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/examples.md +1 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/index.md +6 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/README.md +1 -1
- google_adk_extras-0.3.0/examples/adk_server_8015.py +43 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/mkdocs.yml +1 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/pyproject.toml +16 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/__init__.py +3 -3
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/adk_builder.py +15 -292
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/local_folder_artifact_service.py +0 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/mongo_artifact_service.py +0 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/s3_artifact_service.py +0 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/sql_artifact_service.py +0 -1
- google_adk_extras-0.3.0/src/google_adk_extras/auth/__init__.py +10 -0
- google_adk_extras-0.3.0/src/google_adk_extras/auth/attach.py +227 -0
- google_adk_extras-0.3.0/src/google_adk_extras/auth/config.py +45 -0
- google_adk_extras-0.3.0/src/google_adk_extras/auth/jwt_utils.py +36 -0
- google_adk_extras-0.3.0/src/google_adk_extras/auth/sql_store.py +183 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/custom_agent_loader.py +1 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_adk_web_server.py +0 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_fastapi.py +6 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/mongo_memory_service.py +0 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/sql_memory_service.py +1 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/yaml_file_memory_service.py +1 -3
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/mongo_session_service.py +0 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/redis_session_service.py +1 -1
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/yaml_file_session_service.py +0 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/streaming/streaming_controller.py +2 -2
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0/src/google_adk_extras.egg-info}/PKG-INFO +84 -34
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/SOURCES.txt +7 -9
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/tests/test_a2a_helpers.py +1 -2
- google_adk_extras-0.2.6/docs/credentials.md +0 -31
- google_adk_extras-0.2.6/examples/credentials/google_oauth2.py +0 -27
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/__init__.py +0 -34
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/github_oauth2_credential_service.py +0 -213
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/google_oauth2_credential_service.py +0 -216
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/http_basic_auth_credential_service.py +0 -388
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/jwt_credential_service.py +0 -345
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/microsoft_oauth2_credential_service.py +0 -250
- google_adk_extras-0.2.6/src/google_adk_extras/credentials/x_oauth2_credential_service.py +0 -240
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/LICENSE +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/MANIFEST.in +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/agent-loading.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/fastapi.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/getting-started.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/quickstarts.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/services.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/streaming.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/troubleshooting.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/uris.md +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/consume_remote_a2a.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/custom_loader.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/fastapi_app.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/programmatic_a2a_expose.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/runner_basic.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/artifacts_local.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/memory_yaml.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/sessions_sql.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/streaming_sse_ws.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/setup.cfg +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/setup.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/__init__.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/base_custom_artifact_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/credentials/base_custom_credential_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_runner.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/__init__.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/base_custom_memory_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/redis_memory_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/__init__.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/base_custom_session_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/sql_session_service.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/streaming/__init__.py +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/dependency_links.txt +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/requires.txt +0 -0
- {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: google-adk-extras
|
3
|
-
Version: 0.
|
4
|
-
Summary: Production-ready services
|
3
|
+
Version: 0.3.0
|
4
|
+
Summary: Production-ready services and FastAPI wiring for Google ADK
|
5
5
|
Home-page: https://github.com/DeadMeme5441/google-adk-extras
|
6
6
|
Author: DeadMeme5441
|
7
7
|
Author-email: DeadMeme5441 <deadunderscorememe@gmail.com>
|
@@ -49,7 +49,7 @@ Dynamic: requires-python
|
|
49
49
|
[](https://deadmeme5441.github.io/google-adk-extras/)
|
50
50
|
[](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml)
|
51
51
|
|
52
|
-
Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory)
|
52
|
+
Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory) and clean FastAPI wiring (with optional streaming) so you can run ADK agents with real storage.
|
53
53
|
|
54
54
|
What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tools and callbacks, and drops in where ADK expects services and a web server.
|
55
55
|
|
@@ -58,10 +58,9 @@ What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tool
|
|
58
58
|
|
59
59
|
ADK provides the core primitives (Runner, Session/State, MemoryService, ArtifactService, CredentialService, Agents/Tools, callbacks, Dev UI, and deployment paths). See the official ADK docs for concepts and APIs.
|
60
60
|
|
61
|
-
This package focuses on
|
61
|
+
This package focuses on a few gaps common in real apps:
|
62
62
|
- Durable storage backends beyond in‑memory defaults
|
63
|
-
-
|
64
|
-
- FastAPI integration that accepts your credential service without hacks
|
63
|
+
- FastAPI integration with optional streaming (SSE/WS)
|
65
64
|
|
66
65
|
|
67
66
|
## Features
|
@@ -69,8 +68,7 @@ This package focuses on three gaps common in real apps:
|
|
69
68
|
- Session services: SQL (SQLite/Postgres/MySQL), MongoDB, Redis, YAML files
|
70
69
|
- Artifact services: Local folder (versioned), S3‑compatible, SQL, MongoDB
|
71
70
|
- Memory services: SQL, MongoDB, Redis, YAML files (term search over text parts)
|
72
|
-
-
|
73
|
-
- Enhanced FastAPI wiring that respects a provided credential service
|
71
|
+
- Enhanced FastAPI wiring for ADK apps (with optional streaming)
|
74
72
|
- Fluent builder (`AdkBuilder`) to assemble a FastAPI app or a Runner
|
75
73
|
- A2A helpers for exposing/consuming agents (see below)
|
76
74
|
|
@@ -95,17 +93,18 @@ If you plan to use specific backends, also install their clients (examples):
|
|
95
93
|
- MongoDB: `uv pip install pymongo`
|
96
94
|
- Redis: `uv pip install redis`
|
97
95
|
- S3: `uv pip install boto3`
|
98
|
-
|
96
|
+
|
97
|
+
Note on credentials (0.3.0): Outbound credentials for tools remain ADK’s concern (use ADK’s BaseCredentialService). Inbound API authentication is now available as an optional FastAPI layer in this package (see Auth below). You can run fully open (no auth) or enable API Key, Basic, or JWT (including first‑party issuance backed by SQL).
|
99
98
|
|
100
99
|
|
101
100
|
## Quickstart (FastAPI)
|
102
101
|
|
103
|
-
Use the fluent builder to wire services
|
102
|
+
Use the fluent builder to wire services. Then run with uvicorn.
|
104
103
|
|
105
104
|
```python
|
106
105
|
# app.py
|
107
106
|
from google_adk_extras import AdkBuilder
|
108
|
-
from google_adk_extras.
|
107
|
+
from google_adk_extras.auth import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
|
109
108
|
|
110
109
|
app = (
|
111
110
|
AdkBuilder()
|
@@ -113,11 +112,7 @@ app = (
|
|
113
112
|
.with_session_service("sqlite:///./sessions.db") # or: mongodb://, redis://, yaml://
|
114
113
|
.with_artifact_service("local://./artifacts") # or: s3://bucket, mongodb://, sql://
|
115
114
|
.with_memory_service("yaml://./memory") # or: redis://, mongodb://, sql://
|
116
|
-
|
117
|
-
client_id="…apps.googleusercontent.com",
|
118
|
-
client_secret="…",
|
119
|
-
scopes=["openid", "email", "profile"],
|
120
|
-
))
|
115
|
+
# credentials: rely on ADK defaults or pass an ADK BaseCredentialService if needed
|
121
116
|
.with_web_ui(True) # serve ADK’s dev UI if assets available
|
122
117
|
.with_agent_reload(True)
|
123
118
|
.build_fastapi_app()
|
@@ -133,6 +128,77 @@ uvicorn app:app --reload
|
|
133
128
|
If you don’t keep agents on disk, register them programmatically and use a custom loader (see below).
|
134
129
|
|
135
130
|
|
131
|
+
## Auth (optional)
|
132
|
+
|
133
|
+
Auth is entirely optional. By default, all endpoints are open (no auth). To enable protection, pass `auth_config` into `get_enhanced_fast_api_app` via the builder or directly.
|
134
|
+
|
135
|
+
Supported inbound methods:
|
136
|
+
- API Key: `X-API-Key: <key>` header (or `?api_key=` query). Keys can be static via config, or issued/rotated via SQL‑backed endpoints.
|
137
|
+
- HTTP Basic: `Authorization: Basic base64(user:pass)` for quick human/internal testing. Can validate against in‑memory map or the SQL users table.
|
138
|
+
- Bearer JWT (validate): Accept JWTs from Google/Auth0/Okta/etc. via JWKS, or HS256 secret in dev. Enforces iss/aud/exp/nbf.
|
139
|
+
- Bearer JWT (issue): First‑party issuer with HS256, tokens minted from `/auth/token`, users stored in SQL (SQLite/Postgres/MySQL).
|
140
|
+
|
141
|
+
Minimal enablement (JWT validate only):
|
142
|
+
|
143
|
+
```python
|
144
|
+
from google_adk_extras.auth import AuthConfig, JwtValidatorConfig
|
145
|
+
|
146
|
+
auth = AuthConfig(
|
147
|
+
enabled=True,
|
148
|
+
jwt_validator=JwtValidatorConfig(
|
149
|
+
jwks_url="https://accounts.google.com/.well-known/openid-configuration", # example
|
150
|
+
issuer="https://accounts.google.com",
|
151
|
+
audience="your-api-audience",
|
152
|
+
),
|
153
|
+
)
|
154
|
+
|
155
|
+
app = (
|
156
|
+
AdkBuilder()
|
157
|
+
.with_agents_dir("./agents")
|
158
|
+
.build_fastapi_app()
|
159
|
+
)
|
160
|
+
```
|
161
|
+
|
162
|
+
First‑party issuer + validate (single shared HS256 secret) with SQL connector:
|
163
|
+
|
164
|
+
```python
|
165
|
+
from google_adk_extras.auth import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
|
166
|
+
|
167
|
+
issuer = JwtIssuerConfig(
|
168
|
+
enabled=True,
|
169
|
+
issuer="https://local-issuer",
|
170
|
+
audience="adk-api",
|
171
|
+
algorithm="HS256",
|
172
|
+
hs256_secret="topsecret",
|
173
|
+
database_url="sqlite:///./auth.db", # also supports Postgres/MySQL
|
174
|
+
)
|
175
|
+
validator = JwtValidatorConfig(
|
176
|
+
issuer=issuer.issuer,
|
177
|
+
audience=issuer.audience,
|
178
|
+
hs256_secret=issuer.hs256_secret,
|
179
|
+
)
|
180
|
+
|
181
|
+
auth = AuthConfig(enabled=True, jwt_issuer=issuer, jwt_validator=validator)
|
182
|
+
|
183
|
+
app = (
|
184
|
+
AdkBuilder()
|
185
|
+
.with_agents_dir("./agents")
|
186
|
+
.build_fastapi_app()
|
187
|
+
)
|
188
|
+
```
|
189
|
+
|
190
|
+
Issuing and using tokens/keys at runtime:
|
191
|
+
- Register user: `POST /auth/register?username=alice&password=wonder`
|
192
|
+
- Token (password): `POST /auth/token?grant_type=password&username=alice&password=wonder`
|
193
|
+
- Refresh: `POST /auth/refresh?user_id=<uid>&refresh_token=<jti>`
|
194
|
+
- Create API key: `POST /auth/api-keys` (auth required) → returns `{ id, api_key }` (plaintext shown once)
|
195
|
+
- List keys: `GET /auth/api-keys` (auth required)
|
196
|
+
- Revoke key: `DELETE /auth/api-keys/{id}` (auth required)
|
197
|
+
- Use API key: add `X-API-Key: <api_key>` to any protected route (keys currently allow full access)
|
198
|
+
|
199
|
+
Protected routes include `/run`, `/run_sse`, all `/apps/...` session/artifact/eval endpoints, `/debug/*`, `/builder/*`, and optionally `/list-apps` and `/apps/{app}/metrics-info`.
|
200
|
+
|
201
|
+
|
136
202
|
## Quickstart (Runner)
|
137
203
|
|
138
204
|
Create a Runner wired with your chosen backends. Use agent name (filesystem loader) or pass an agent instance.
|
@@ -251,24 +317,8 @@ app = (
|
|
251
317
|
```
|
252
318
|
|
253
319
|
|
254
|
-
|
255
|
-
|
256
|
-
If you prefer URIs instead of constructing services:
|
257
|
-
|
258
|
-
- Google OAuth2: `oauth2-google://client_id:secret@scopes=openid,email,profile`
|
259
|
-
- GitHub OAuth2: `oauth2-github://client_id:secret@scopes=user,repo`
|
260
|
-
- Microsoft OAuth2: `oauth2-microsoft://<tenant>/<client_id>:<secret>@scopes=User.Read`
|
261
|
-
- X OAuth2: `oauth2-x://client_id:secret@scopes=tweet.read,users.read`
|
262
|
-
- JWT: `jwt://<secret>@algorithm=HS256&issuer=my-app&audience=api.example.com&expiration_minutes=60`
|
263
|
-
- Basic: `basic-auth://username:password@realm=My%20API`
|
264
|
-
|
265
|
-
```python
|
266
|
-
cred = (
|
267
|
-
AdkBuilder()
|
268
|
-
.with_credential_service_uri("jwt://secret@issuer=my-app")
|
269
|
-
._create_credential_service()
|
270
|
-
)
|
271
|
-
```
|
320
|
+
<!-- Credential URI helpers removed. Use ADK’s BaseCredentialService directly if needed,
|
321
|
+
and handle inbound API authentication at FastAPI level. -->
|
272
322
|
|
273
323
|
|
274
324
|
## Notes & limitations
|
@@ -6,7 +6,7 @@
|
|
6
6
|
[](https://deadmeme5441.github.io/google-adk-extras/)
|
7
7
|
[](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml)
|
8
8
|
|
9
|
-
Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory)
|
9
|
+
Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory) and clean FastAPI wiring (with optional streaming) so you can run ADK agents with real storage.
|
10
10
|
|
11
11
|
What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tools and callbacks, and drops in where ADK expects services and a web server.
|
12
12
|
|
@@ -15,10 +15,9 @@ What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tool
|
|
15
15
|
|
16
16
|
ADK provides the core primitives (Runner, Session/State, MemoryService, ArtifactService, CredentialService, Agents/Tools, callbacks, Dev UI, and deployment paths). See the official ADK docs for concepts and APIs.
|
17
17
|
|
18
|
-
This package focuses on
|
18
|
+
This package focuses on a few gaps common in real apps:
|
19
19
|
- Durable storage backends beyond in‑memory defaults
|
20
|
-
-
|
21
|
-
- FastAPI integration that accepts your credential service without hacks
|
20
|
+
- FastAPI integration with optional streaming (SSE/WS)
|
22
21
|
|
23
22
|
|
24
23
|
## Features
|
@@ -26,8 +25,7 @@ This package focuses on three gaps common in real apps:
|
|
26
25
|
- Session services: SQL (SQLite/Postgres/MySQL), MongoDB, Redis, YAML files
|
27
26
|
- Artifact services: Local folder (versioned), S3‑compatible, SQL, MongoDB
|
28
27
|
- Memory services: SQL, MongoDB, Redis, YAML files (term search over text parts)
|
29
|
-
-
|
30
|
-
- Enhanced FastAPI wiring that respects a provided credential service
|
28
|
+
- Enhanced FastAPI wiring for ADK apps (with optional streaming)
|
31
29
|
- Fluent builder (`AdkBuilder`) to assemble a FastAPI app or a Runner
|
32
30
|
- A2A helpers for exposing/consuming agents (see below)
|
33
31
|
|
@@ -52,17 +50,18 @@ If you plan to use specific backends, also install their clients (examples):
|
|
52
50
|
- MongoDB: `uv pip install pymongo`
|
53
51
|
- Redis: `uv pip install redis`
|
54
52
|
- S3: `uv pip install boto3`
|
55
|
-
|
53
|
+
|
54
|
+
Note on credentials (0.3.0): Outbound credentials for tools remain ADK’s concern (use ADK’s BaseCredentialService). Inbound API authentication is now available as an optional FastAPI layer in this package (see Auth below). You can run fully open (no auth) or enable API Key, Basic, or JWT (including first‑party issuance backed by SQL).
|
56
55
|
|
57
56
|
|
58
57
|
## Quickstart (FastAPI)
|
59
58
|
|
60
|
-
Use the fluent builder to wire services
|
59
|
+
Use the fluent builder to wire services. Then run with uvicorn.
|
61
60
|
|
62
61
|
```python
|
63
62
|
# app.py
|
64
63
|
from google_adk_extras import AdkBuilder
|
65
|
-
from google_adk_extras.
|
64
|
+
from google_adk_extras.auth import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
|
66
65
|
|
67
66
|
app = (
|
68
67
|
AdkBuilder()
|
@@ -70,11 +69,7 @@ app = (
|
|
70
69
|
.with_session_service("sqlite:///./sessions.db") # or: mongodb://, redis://, yaml://
|
71
70
|
.with_artifact_service("local://./artifacts") # or: s3://bucket, mongodb://, sql://
|
72
71
|
.with_memory_service("yaml://./memory") # or: redis://, mongodb://, sql://
|
73
|
-
|
74
|
-
client_id="…apps.googleusercontent.com",
|
75
|
-
client_secret="…",
|
76
|
-
scopes=["openid", "email", "profile"],
|
77
|
-
))
|
72
|
+
# credentials: rely on ADK defaults or pass an ADK BaseCredentialService if needed
|
78
73
|
.with_web_ui(True) # serve ADK’s dev UI if assets available
|
79
74
|
.with_agent_reload(True)
|
80
75
|
.build_fastapi_app()
|
@@ -90,6 +85,77 @@ uvicorn app:app --reload
|
|
90
85
|
If you don’t keep agents on disk, register them programmatically and use a custom loader (see below).
|
91
86
|
|
92
87
|
|
88
|
+
## Auth (optional)
|
89
|
+
|
90
|
+
Auth is entirely optional. By default, all endpoints are open (no auth). To enable protection, pass `auth_config` into `get_enhanced_fast_api_app` via the builder or directly.
|
91
|
+
|
92
|
+
Supported inbound methods:
|
93
|
+
- API Key: `X-API-Key: <key>` header (or `?api_key=` query). Keys can be static via config, or issued/rotated via SQL‑backed endpoints.
|
94
|
+
- HTTP Basic: `Authorization: Basic base64(user:pass)` for quick human/internal testing. Can validate against in‑memory map or the SQL users table.
|
95
|
+
- Bearer JWT (validate): Accept JWTs from Google/Auth0/Okta/etc. via JWKS, or HS256 secret in dev. Enforces iss/aud/exp/nbf.
|
96
|
+
- Bearer JWT (issue): First‑party issuer with HS256, tokens minted from `/auth/token`, users stored in SQL (SQLite/Postgres/MySQL).
|
97
|
+
|
98
|
+
Minimal enablement (JWT validate only):
|
99
|
+
|
100
|
+
```python
|
101
|
+
from google_adk_extras.auth import AuthConfig, JwtValidatorConfig
|
102
|
+
|
103
|
+
auth = AuthConfig(
|
104
|
+
enabled=True,
|
105
|
+
jwt_validator=JwtValidatorConfig(
|
106
|
+
jwks_url="https://accounts.google.com/.well-known/openid-configuration", # example
|
107
|
+
issuer="https://accounts.google.com",
|
108
|
+
audience="your-api-audience",
|
109
|
+
),
|
110
|
+
)
|
111
|
+
|
112
|
+
app = (
|
113
|
+
AdkBuilder()
|
114
|
+
.with_agents_dir("./agents")
|
115
|
+
.build_fastapi_app()
|
116
|
+
)
|
117
|
+
```
|
118
|
+
|
119
|
+
First‑party issuer + validate (single shared HS256 secret) with SQL connector:
|
120
|
+
|
121
|
+
```python
|
122
|
+
from google_adk_extras.auth import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
|
123
|
+
|
124
|
+
issuer = JwtIssuerConfig(
|
125
|
+
enabled=True,
|
126
|
+
issuer="https://local-issuer",
|
127
|
+
audience="adk-api",
|
128
|
+
algorithm="HS256",
|
129
|
+
hs256_secret="topsecret",
|
130
|
+
database_url="sqlite:///./auth.db", # also supports Postgres/MySQL
|
131
|
+
)
|
132
|
+
validator = JwtValidatorConfig(
|
133
|
+
issuer=issuer.issuer,
|
134
|
+
audience=issuer.audience,
|
135
|
+
hs256_secret=issuer.hs256_secret,
|
136
|
+
)
|
137
|
+
|
138
|
+
auth = AuthConfig(enabled=True, jwt_issuer=issuer, jwt_validator=validator)
|
139
|
+
|
140
|
+
app = (
|
141
|
+
AdkBuilder()
|
142
|
+
.with_agents_dir("./agents")
|
143
|
+
.build_fastapi_app()
|
144
|
+
)
|
145
|
+
```
|
146
|
+
|
147
|
+
Issuing and using tokens/keys at runtime:
|
148
|
+
- Register user: `POST /auth/register?username=alice&password=wonder`
|
149
|
+
- Token (password): `POST /auth/token?grant_type=password&username=alice&password=wonder`
|
150
|
+
- Refresh: `POST /auth/refresh?user_id=<uid>&refresh_token=<jti>`
|
151
|
+
- Create API key: `POST /auth/api-keys` (auth required) → returns `{ id, api_key }` (plaintext shown once)
|
152
|
+
- List keys: `GET /auth/api-keys` (auth required)
|
153
|
+
- Revoke key: `DELETE /auth/api-keys/{id}` (auth required)
|
154
|
+
- Use API key: add `X-API-Key: <api_key>` to any protected route (keys currently allow full access)
|
155
|
+
|
156
|
+
Protected routes include `/run`, `/run_sse`, all `/apps/...` session/artifact/eval endpoints, `/debug/*`, `/builder/*`, and optionally `/list-apps` and `/apps/{app}/metrics-info`.
|
157
|
+
|
158
|
+
|
93
159
|
## Quickstart (Runner)
|
94
160
|
|
95
161
|
Create a Runner wired with your chosen backends. Use agent name (filesystem loader) or pass an agent instance.
|
@@ -208,24 +274,8 @@ app = (
|
|
208
274
|
```
|
209
275
|
|
210
276
|
|
211
|
-
|
212
|
-
|
213
|
-
If you prefer URIs instead of constructing services:
|
214
|
-
|
215
|
-
- Google OAuth2: `oauth2-google://client_id:secret@scopes=openid,email,profile`
|
216
|
-
- GitHub OAuth2: `oauth2-github://client_id:secret@scopes=user,repo`
|
217
|
-
- Microsoft OAuth2: `oauth2-microsoft://<tenant>/<client_id>:<secret>@scopes=User.Read`
|
218
|
-
- X OAuth2: `oauth2-x://client_id:secret@scopes=tweet.read,users.read`
|
219
|
-
- JWT: `jwt://<secret>@algorithm=HS256&issuer=my-app&audience=api.example.com&expiration_minutes=60`
|
220
|
-
- Basic: `basic-auth://username:password@realm=My%20API`
|
221
|
-
|
222
|
-
```python
|
223
|
-
cred = (
|
224
|
-
AdkBuilder()
|
225
|
-
.with_credential_service_uri("jwt://secret@issuer=my-app")
|
226
|
-
._create_credential_service()
|
227
|
-
)
|
228
|
-
```
|
277
|
+
<!-- Credential URI helpers removed. Use ADK’s BaseCredentialService directly if needed,
|
278
|
+
and handle inbound API authentication at FastAPI level. -->
|
229
279
|
|
230
280
|
|
231
281
|
## Notes & limitations
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Auth (Optional)
|
2
|
+
|
3
|
+
Inbound API authentication is optional. If you don’t pass an `auth_config`, all routes are open (useful for local dev). When enabled, the middleware protects sensitive routes and enforces identity where appropriate.
|
4
|
+
|
5
|
+
Supported methods:
|
6
|
+
- API Key
|
7
|
+
- Send `X-API-Key: <token>` header or `?api_key=<token>` query.
|
8
|
+
- Keys can be static via config or issued/rotated via SQL‑backed endpoints.
|
9
|
+
- HTTP Basic
|
10
|
+
- `Authorization: Basic base64(user:pass)`.
|
11
|
+
- Checks an in‑memory map or the SQL users table when configured.
|
12
|
+
- Bearer JWT (validate)
|
13
|
+
- Validate JWTs from OIDC providers (Google, Auth0, Okta, etc.) via JWKS.
|
14
|
+
- Or use HS256 with a shared secret in dev.
|
15
|
+
- Bearer JWT (issue)
|
16
|
+
- First‑party issuer backed by SQL; exposes `/auth/register`, `/auth/token`, `/auth/refresh`.
|
17
|
+
|
18
|
+
## Quick examples
|
19
|
+
|
20
|
+
### Enable JWT validate only
|
21
|
+
```python
|
22
|
+
from google_adk_extras import AdkBuilder
|
23
|
+
from google_adk_extras.auth import AuthConfig, JwtValidatorConfig
|
24
|
+
|
25
|
+
auth = AuthConfig(
|
26
|
+
enabled=True,
|
27
|
+
jwt_validator=JwtValidatorConfig(
|
28
|
+
jwks_url="https://YOUR_ISSUER/.well-known/jwks.json",
|
29
|
+
issuer="https://YOUR_ISSUER",
|
30
|
+
audience="your-api-audience",
|
31
|
+
),
|
32
|
+
)
|
33
|
+
|
34
|
+
app = AdkBuilder().with_agents_dir("./agents").build_fastapi_app()
|
35
|
+
```
|
36
|
+
|
37
|
+
### First‑party issuer + validate (HS256) and SQL store
|
38
|
+
```python
|
39
|
+
from google_adk_extras import AdkBuilder
|
40
|
+
from google_adk_extras.auth import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
|
41
|
+
|
42
|
+
issuer = JwtIssuerConfig(
|
43
|
+
enabled=True,
|
44
|
+
issuer="https://local-issuer",
|
45
|
+
audience="adk-api",
|
46
|
+
algorithm="HS256",
|
47
|
+
hs256_secret="topsecret",
|
48
|
+
database_url="sqlite:///./auth.db",
|
49
|
+
)
|
50
|
+
validator = JwtValidatorConfig(issuer=issuer.issuer, audience=issuer.audience, hs256_secret=issuer.hs256_secret)
|
51
|
+
|
52
|
+
auth = AuthConfig(enabled=True, jwt_issuer=issuer, jwt_validator=validator)
|
53
|
+
|
54
|
+
app = AdkBuilder().with_agents_dir("./agents").build_fastapi_app()
|
55
|
+
```
|
56
|
+
|
57
|
+
### API key management endpoints (SQL store)
|
58
|
+
- `POST /auth/api-keys` → `{ id, api_key }` (plaintext shown once)
|
59
|
+
- `GET /auth/api-keys` → list metadata
|
60
|
+
- `DELETE /auth/api-keys/{id}` → revoke
|
61
|
+
|
62
|
+
Use `X-API-Key: <api_key>` (or `?api_key=`) to access protected routes.
|
63
|
+
|
64
|
+
## What’s protected
|
65
|
+
- Always: `POST /run`, `POST /run_sse`, `GET/POST/DELETE /apps/...`, `/debug/*`, `/builder/*`.
|
66
|
+
- Optional: `/list-apps` and `/apps/{app}/metrics-info` (toggled in `AuthConfig`).
|
67
|
+
- Ownership: when the URL contains `/users/{user_id}/...`, the `sub` from the token must match `user_id` (API key bypass permitted).
|
68
|
+
|
69
|
+
## Optional by design
|
70
|
+
- No‑auth is the default. Enable auth only when you’re ready.
|
71
|
+
- You can mix modes: e.g., JWT for users and API keys for automation.
|
72
|
+
|
73
|
+
```python
|
74
|
+
# Direct call if not using the builder
|
75
|
+
from google_adk_extras.enhanced_fastapi import get_enhanced_fast_api_app
|
76
|
+
from google_adk_extras.auth import AuthConfig
|
77
|
+
app = get_enhanced_fast_api_app(..., auth_config=AuthConfig(enabled=True, api_keys=["test"]))
|
78
|
+
```
|
79
|
+
|
@@ -6,6 +6,6 @@ These examples are kept small and runnable; see the `examples/` folder.
|
|
6
6
|
- `examples/runner_basic.py` — runner without FastAPI.
|
7
7
|
- `examples/custom_loader.py` — programmatic agents.
|
8
8
|
- `examples/services/` — focused snippets per backend.
|
9
|
-
|
9
|
+
(credential service examples removed; rely on ADK defaults)
|
10
10
|
|
11
11
|
Install extras to match what you run, e.g. `uv pip install google-adk-extras[sql,yaml,web]`.
|
@@ -14,6 +14,11 @@ What this is not: a fork of ADK. It builds on top of google-adk.
|
|
14
14
|
- `EnhancedAdkWebServer`
|
15
15
|
- `EnhancedRunner` (thin wrapper)
|
16
16
|
- `CustomAgentLoader` (programmatic agents)
|
17
|
-
- Services via subpackages: `sessions`, `artifacts`, `memory
|
17
|
+
- Services via subpackages: `sessions`, `artifacts`, `memory` (optional inbound auth lives under `auth/`)
|
18
18
|
|
19
19
|
See Quickstarts for copy‑paste examples.
|
20
|
+
|
21
|
+
Additional guides:
|
22
|
+
- [FastAPI Integration](fastapi.md)
|
23
|
+
- [Streaming](streaming.md)
|
24
|
+
- [Auth (Optional)](auth.md)
|
@@ -2,7 +2,7 @@ Examples
|
|
2
2
|
|
3
3
|
This folder contains small, runnable examples that mirror the documentation. They are intentionally minimal and designed to be copy–pasted into your app.
|
4
4
|
|
5
|
-
- fastapi_app.py — Build a FastAPI app with durable services
|
5
|
+
- fastapi_app.py — Build a FastAPI app with durable services.
|
6
6
|
- runner_basic.py — Build a Runner for programmatic use without FastAPI.
|
7
7
|
- custom_loader.py — Register programmatic agents with `CustomAgentLoader`.
|
8
8
|
- services/ — Focused snippets for sessions, artifacts, memory backends.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""Spin up an ADK FastAPI server on 127.0.0.1:8015 with in-memory services.
|
2
|
+
|
3
|
+
This script uses google_adk_extras.get_enhanced_fast_api_app with a simple
|
4
|
+
programmatic agent loader. It is intended only to inspect the OpenAPI schema
|
5
|
+
and enumerate endpoints exposed by the ADK web server.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import AsyncGenerator, Optional
|
9
|
+
|
10
|
+
from fastapi import FastAPI
|
11
|
+
|
12
|
+
from google.genai import types
|
13
|
+
from google.adk.events.event import Event
|
14
|
+
from google.adk.agents.base_agent import BaseAgent
|
15
|
+
|
16
|
+
from google_adk_extras.custom_agent_loader import CustomAgentLoader
|
17
|
+
from google_adk_extras.enhanced_fastapi import get_enhanced_fast_api_app
|
18
|
+
|
19
|
+
|
20
|
+
class _DummyAgent(BaseAgent):
|
21
|
+
"""Minimal agent; not used for OpenAPI generation, but loadable if needed."""
|
22
|
+
|
23
|
+
def __init__(self, name: str = "dummy"):
|
24
|
+
super().__init__(name)
|
25
|
+
|
26
|
+
async def run_async(self, ctx) -> AsyncGenerator[Event, None]:
|
27
|
+
# Emit a trivial final event; unlikely to be executed in this script.
|
28
|
+
content = types.Content(parts=[types.Part(text="ok")])
|
29
|
+
yield Event(author=self.name, content=content)
|
30
|
+
|
31
|
+
|
32
|
+
def build_app() -> FastAPI:
|
33
|
+
loader = CustomAgentLoader()
|
34
|
+
app = get_enhanced_fast_api_app(
|
35
|
+
agent_loader=loader,
|
36
|
+
web=False, # no static UI
|
37
|
+
enable_streaming=False, # focus on ADK core endpoints
|
38
|
+
allow_origins=["*"]
|
39
|
+
)
|
40
|
+
return app
|
41
|
+
|
42
|
+
|
43
|
+
app = build_app()
|
@@ -17,7 +17,6 @@ nav:
|
|
17
17
|
- Streaming: streaming.md
|
18
18
|
- Services:
|
19
19
|
- Durable Services: services.md
|
20
|
-
- Credentials: credentials.md
|
21
20
|
- Programmatic Agents: agent-loading.md
|
22
21
|
- URIs & Configuration: uris.md
|
23
22
|
- Examples: examples.md
|
@@ -50,7 +49,7 @@ plugins:
|
|
50
49
|
Durable Services:
|
51
50
|
- services.md: Sessions, artifacts, memory backends and trade-offs
|
52
51
|
Credentials:
|
53
|
-
|
52
|
+
# credentials docs removed; use ADK documentation for outbound creds
|
54
53
|
Programmatic Agents:
|
55
54
|
- agent-loading.md: Custom loaders and in-memory registrations
|
56
55
|
Configuration:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
[project]
|
2
2
|
name = "google-adk-extras"
|
3
|
-
version = "0.
|
4
|
-
description = "Production-ready services
|
3
|
+
version = "0.3.0"
|
4
|
+
description = "Production-ready services and FastAPI wiring for Google ADK"
|
5
5
|
readme = "README.md"
|
6
6
|
requires-python = ">=3.10,<3.13"
|
7
7
|
authors = [
|
@@ -38,6 +38,20 @@ all = [
|
|
38
38
|
"google-adk-extras[sql,mongodb,redis,yaml,s3,jwt,web,docs]",
|
39
39
|
]
|
40
40
|
|
41
|
+
[tool.ruff]
|
42
|
+
line-length = 100
|
43
|
+
target-version = "py312"
|
44
|
+
|
45
|
+
[tool.ruff.lint]
|
46
|
+
select = ["E", "F"]
|
47
|
+
ignore = [
|
48
|
+
"F401", # unused-import (common in optional backends)
|
49
|
+
"F841", # unused-variable (tests and examples)
|
50
|
+
"F821", # undefined-name (forward-ref type strings in optional extras)
|
51
|
+
"E402", # module-import-not-at-top-of-file (test-only patterns)
|
52
|
+
"E501", # line-too-long (permissive until we tighten rules)
|
53
|
+
]
|
54
|
+
|
41
55
|
[build-system]
|
42
56
|
requires = ["setuptools>=45", "wheel"]
|
43
57
|
build-backend = "setuptools.build_meta"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
"""Production-ready services
|
1
|
+
"""Production-ready services and FastAPI wiring for Google ADK.
|
2
2
|
|
3
3
|
Public API surface:
|
4
4
|
- AdkBuilder
|
@@ -11,7 +11,7 @@ Service groups are exposed via subpackages:
|
|
11
11
|
- google_adk_extras.sessions
|
12
12
|
- google_adk_extras.artifacts
|
13
13
|
- google_adk_extras.memory
|
14
|
-
|
14
|
+
(credential services are provided by ADK; no custom extras here)
|
15
15
|
"""
|
16
16
|
|
17
17
|
from .adk_builder import AdkBuilder
|
@@ -28,4 +28,4 @@ __all__ = [
|
|
28
28
|
"CustomAgentLoader",
|
29
29
|
]
|
30
30
|
|
31
|
-
__version__ = "0.
|
31
|
+
__version__ = "0.3.0"
|