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.
Files changed (77) hide show
  1. {google_adk_extras-0.2.6/src/google_adk_extras.egg-info → google_adk_extras-0.3.0}/PKG-INFO +84 -34
  2. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/README.md +82 -32
  3. google_adk_extras-0.3.0/docs/auth.md +79 -0
  4. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/examples.md +1 -1
  5. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/index.md +6 -1
  6. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/README.md +1 -1
  7. google_adk_extras-0.3.0/examples/adk_server_8015.py +43 -0
  8. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/mkdocs.yml +1 -2
  9. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/pyproject.toml +16 -2
  10. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/__init__.py +3 -3
  11. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/adk_builder.py +15 -292
  12. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/local_folder_artifact_service.py +0 -2
  13. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/mongo_artifact_service.py +0 -1
  14. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/s3_artifact_service.py +0 -1
  15. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/sql_artifact_service.py +0 -1
  16. google_adk_extras-0.3.0/src/google_adk_extras/auth/__init__.py +10 -0
  17. google_adk_extras-0.3.0/src/google_adk_extras/auth/attach.py +227 -0
  18. google_adk_extras-0.3.0/src/google_adk_extras/auth/config.py +45 -0
  19. google_adk_extras-0.3.0/src/google_adk_extras/auth/jwt_utils.py +36 -0
  20. google_adk_extras-0.3.0/src/google_adk_extras/auth/sql_store.py +183 -0
  21. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/custom_agent_loader.py +1 -1
  22. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_adk_web_server.py +0 -2
  23. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_fastapi.py +6 -1
  24. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/mongo_memory_service.py +0 -1
  25. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/sql_memory_service.py +1 -1
  26. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/yaml_file_memory_service.py +1 -3
  27. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/mongo_session_service.py +0 -1
  28. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/redis_session_service.py +1 -1
  29. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/yaml_file_session_service.py +0 -2
  30. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/streaming/streaming_controller.py +2 -2
  31. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0/src/google_adk_extras.egg-info}/PKG-INFO +84 -34
  32. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/SOURCES.txt +7 -9
  33. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/tests/test_a2a_helpers.py +1 -2
  34. google_adk_extras-0.2.6/docs/credentials.md +0 -31
  35. google_adk_extras-0.2.6/examples/credentials/google_oauth2.py +0 -27
  36. google_adk_extras-0.2.6/src/google_adk_extras/credentials/__init__.py +0 -34
  37. google_adk_extras-0.2.6/src/google_adk_extras/credentials/github_oauth2_credential_service.py +0 -213
  38. google_adk_extras-0.2.6/src/google_adk_extras/credentials/google_oauth2_credential_service.py +0 -216
  39. google_adk_extras-0.2.6/src/google_adk_extras/credentials/http_basic_auth_credential_service.py +0 -388
  40. google_adk_extras-0.2.6/src/google_adk_extras/credentials/jwt_credential_service.py +0 -345
  41. google_adk_extras-0.2.6/src/google_adk_extras/credentials/microsoft_oauth2_credential_service.py +0 -250
  42. google_adk_extras-0.2.6/src/google_adk_extras/credentials/x_oauth2_credential_service.py +0 -240
  43. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/LICENSE +0 -0
  44. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/MANIFEST.in +0 -0
  45. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/agent-loading.md +0 -0
  46. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/fastapi.md +0 -0
  47. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/getting-started.md +0 -0
  48. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/quickstarts.md +0 -0
  49. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/services.md +0 -0
  50. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/streaming.md +0 -0
  51. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/troubleshooting.md +0 -0
  52. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/docs/uris.md +0 -0
  53. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/consume_remote_a2a.py +0 -0
  54. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/custom_loader.py +0 -0
  55. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/fastapi_app.py +0 -0
  56. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/programmatic_a2a_expose.py +0 -0
  57. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/runner_basic.py +0 -0
  58. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/artifacts_local.py +0 -0
  59. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/memory_yaml.py +0 -0
  60. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/services/sessions_sql.py +0 -0
  61. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/examples/streaming_sse_ws.py +0 -0
  62. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/setup.cfg +0 -0
  63. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/setup.py +0 -0
  64. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/__init__.py +0 -0
  65. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/artifacts/base_custom_artifact_service.py +0 -0
  66. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/credentials/base_custom_credential_service.py +0 -0
  67. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/enhanced_runner.py +0 -0
  68. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/__init__.py +0 -0
  69. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/base_custom_memory_service.py +0 -0
  70. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/memory/redis_memory_service.py +0 -0
  71. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/__init__.py +0 -0
  72. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/base_custom_session_service.py +0 -0
  73. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/sessions/sql_session_service.py +0 -0
  74. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras/streaming/__init__.py +0 -0
  75. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/dependency_links.txt +0 -0
  76. {google_adk_extras-0.2.6 → google_adk_extras-0.3.0}/src/google_adk_extras.egg-info/requires.txt +0 -0
  77. {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.2.6
4
- Summary: Production-ready services, credentials, and FastAPI wiring for Google ADK
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
  [![Docs](https://img.shields.io/badge/docs-site-brightgreen)](https://deadmeme5441.github.io/google-adk-extras/)
50
50
  [![Docs Build](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml/badge.svg)](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), practical credential services (OAuth2/JWT/Basic), and clean FastAPI wiring so you can run ADK agents with real storage and auth.
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 three gaps common in real apps:
61
+ This package focuses on a few gaps common in real apps:
62
62
  - Durable storage backends beyond in‑memory defaults
63
- - Usable credential flows (Google/GitHub/Microsoft/X OAuth2, JWT, Basic)
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
- - Credential services: Google/GitHub/Microsoft/X (OAuth2), JWT, HTTP Basic
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
- - JWT: `uv pip install PyJWT`
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 and credentials. Then run with uvicorn.
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.credentials import GoogleOAuth2CredentialService
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
- .with_credential_service(GoogleOAuth2CredentialService(
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
- ## Credential URI cheatsheet (optional)
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
  [![Docs](https://img.shields.io/badge/docs-site-brightgreen)](https://deadmeme5441.github.io/google-adk-extras/)
7
7
  [![Docs Build](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml/badge.svg)](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), practical credential services (OAuth2/JWT/Basic), and clean FastAPI wiring so you can run ADK agents with real storage and auth.
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 three gaps common in real apps:
18
+ This package focuses on a few gaps common in real apps:
19
19
  - Durable storage backends beyond in‑memory defaults
20
- - Usable credential flows (Google/GitHub/Microsoft/X OAuth2, JWT, Basic)
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
- - Credential services: Google/GitHub/Microsoft/X (OAuth2), JWT, HTTP Basic
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
- - JWT: `uv pip install PyJWT`
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 and credentials. Then run with uvicorn.
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.credentials import GoogleOAuth2CredentialService
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
- .with_credential_service(GoogleOAuth2CredentialService(
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
- ## Credential URI cheatsheet (optional)
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
- - `examples/credentials/` focused credential usage.
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`, `credentials`
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 and optional credentials.
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
- - credentials.md: OAuth2 (Google/GitHub/Microsoft/X), JWT, Basic Auth
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.2.6"
4
- description = "Production-ready services, credentials, and FastAPI wiring for Google ADK"
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, credentials, and FastAPI wiring for Google ADK.
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
- - google_adk_extras.credentials
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.2.6"
31
+ __version__ = "0.3.0"