google-adk-extras 0.3.0__py3-none-any.whl → 0.3.1__py3-none-any.whl

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.
@@ -28,4 +28,4 @@ __all__ = [
28
28
  "CustomAgentLoader",
29
29
  ]
30
30
 
31
- __version__ = "0.3.0"
31
+ __version__ = "0.3.1"
@@ -683,6 +683,7 @@ class AdkBuilder:
683
683
  eval_storage_uri=self._eval_storage_uri,
684
684
  allow_origins=self._allow_origins,
685
685
  web=self._web_ui,
686
+ # Expose future override via builder when needed
686
687
  a2a=self._a2a,
687
688
  programmatic_a2a=self._a2a_expose_programmatic,
688
689
  programmatic_a2a_mount_base=self._a2a_programmatic_mount_base,
@@ -9,7 +9,7 @@ from starlette.middleware.base import BaseHTTPMiddleware
9
9
 
10
10
  from .config import AuthConfig, JwtIssuerConfig, JwtValidatorConfig
11
11
  from .jwt_utils import decode_jwt, encode_jwt, now_ts
12
- from .sql_store import AuthStore
12
+ from typing import Any
13
13
 
14
14
 
15
15
  def attach_auth(app: FastAPI, cfg: Optional[AuthConfig]) -> None:
@@ -25,9 +25,14 @@ def attach_auth(app: FastAPI, cfg: Optional[AuthConfig]) -> None:
25
25
  issuer_cfg = cfg.jwt_issuer
26
26
  api_keys = set(cfg.api_keys or [])
27
27
  basic_users = cfg.basic_users or {}
28
- auth_store: Optional[AuthStore] = None
28
+ auth_store: Optional[Any] = None
29
29
  if issuer_cfg and issuer_cfg.database_url:
30
- auth_store = AuthStore(issuer_cfg.database_url)
30
+ try:
31
+ from .sql_store import AuthStore # type: ignore
32
+ auth_store = AuthStore(issuer_cfg.database_url)
33
+ except Exception:
34
+ # SQL store not available; API key issuance and password grants will be unavailable.
35
+ auth_store = None
31
36
 
32
37
  # Security helpers
33
38
  api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
@@ -5,8 +5,16 @@ import json
5
5
  import time
6
6
  from typing import Any, Dict, Optional
7
7
 
8
- import jwt
9
- from jwt import PyJWKClient
8
+ # Lazy import PyJWT to keep this optional when auth is not used.
9
+ def _import_pyjwt():
10
+ try:
11
+ import jwt # type: ignore
12
+ from jwt import PyJWKClient # type: ignore
13
+ return jwt, PyJWKClient
14
+ except Exception as e:
15
+ raise ImportError(
16
+ "PyJWT is required for JWT encode/decode. Install with: pip install PyJWT"
17
+ ) from e
10
18
 
11
19
 
12
20
  def _b64url(data: bytes) -> str:
@@ -14,11 +22,13 @@ def _b64url(data: bytes) -> str:
14
22
 
15
23
 
16
24
  def encode_jwt(payload: Dict[str, Any], *, algorithm: str, key: str, headers: Optional[Dict[str, Any]] = None) -> str:
25
+ jwt, _PyJWKClient = _import_pyjwt()
17
26
  return jwt.encode(payload, key, algorithm=algorithm, headers=headers)
18
27
 
19
28
 
20
29
  def decode_jwt(token: str, *, issuer: Optional[str] = None, audience: Optional[str] = None,
21
30
  jwks_url: Optional[str] = None, hs256_secret: Optional[str] = None) -> Dict[str, Any]:
31
+ jwt, PyJWKClient = _import_pyjwt()
22
32
  options = {"verify_signature": True, "verify_exp": True, "verify_nbf": True}
23
33
  if jwks_url:
24
34
  jwk_client = PyJWKClient(jwks_url)
@@ -33,4 +43,3 @@ def decode_jwt(token: str, *, issuer: Optional[str] = None, audience: Optional[s
33
43
  def now_ts() -> int:
34
44
  return int(time.time())
35
45
 
36
-
@@ -10,7 +10,7 @@ import logging
10
10
  import os
11
11
  from pathlib import Path
12
12
  import shutil
13
- from typing import Any, Mapping, Optional, List, Callable, Dict
13
+ from typing import Any, Mapping, Optional, List, Callable, Dict, Union
14
14
 
15
15
  import click
16
16
  from fastapi import FastAPI
@@ -57,6 +57,7 @@ def get_enhanced_fast_api_app(
57
57
  eval_storage_uri: Optional[str] = None,
58
58
  allow_origins: Optional[List[str]] = None,
59
59
  web: bool = True,
60
+ web_assets_dir: Optional[Union[str, Path]] = None,
60
61
  a2a: bool = False,
61
62
  programmatic_a2a: bool = False,
62
63
  programmatic_a2a_mount_base: str = "/a2a",
@@ -305,20 +306,53 @@ def get_enhanced_fast_api_app(
305
306
  tear_down_observer=tear_down_observer,
306
307
  )
307
308
 
308
- if web:
309
+ def _auto_find_web_assets() -> Optional[Path]:
309
310
  try:
310
- # Try to find ADK's web assets
311
- from google.adk.cli.fast_api import BASE_DIR
312
- ANGULAR_DIST_PATH = BASE_DIR / "browser"
313
- except (ImportError, AttributeError):
314
- # Fallback if ADK structure changes
315
- BASE_DIR = Path(__file__).parent.resolve()
316
- ANGULAR_DIST_PATH = BASE_DIR / "browser"
317
-
318
- if ANGULAR_DIST_PATH.exists():
319
- extra_fast_api_args.update(web_assets_dir=ANGULAR_DIST_PATH)
311
+ # Prefer importlib.resources so this works across ADK versions
312
+ import importlib.resources as r
313
+ try:
314
+ import google.adk.cli.fast_api as fast_api_pkg # type: ignore
315
+ base = r.files(fast_api_pkg)
316
+ candidates = [
317
+ base / "browser",
318
+ base / "static" / "browser",
319
+ ]
320
+ except Exception:
321
+ import google.adk.cli as cli_pkg # type: ignore
322
+ base = r.files(cli_pkg) / "fast_api"
323
+ candidates = [
324
+ base / "browser",
325
+ base / "static" / "browser",
326
+ ]
327
+ for p in candidates:
328
+ if p.exists() and (p / "index.html").exists():
329
+ # Convert to real filesystem Path if possible
330
+ try:
331
+ return Path(str(p))
332
+ except Exception:
333
+ continue
334
+ except Exception:
335
+ pass
336
+ # Fallback to local relative path (for dev builds of this package)
337
+ local = Path(__file__).parent / "browser"
338
+ if local.exists() and (local / "index.html").exists():
339
+ return local
340
+ return None
341
+
342
+ if web:
343
+ chosen: Optional[Path] = None
344
+ if web_assets_dir is not None:
345
+ p = Path(web_assets_dir)
346
+ if p.exists():
347
+ chosen = p
348
+ if chosen is None:
349
+ chosen = _auto_find_web_assets()
350
+ if chosen is not None:
351
+ extra_fast_api_args.update(web_assets_dir=chosen)
320
352
  else:
321
- logger.warning("Web UI assets not found, web interface will not be available")
353
+ logger.warning(
354
+ "Web UI assets not found; set web_assets_dir or install an ADK build that ships fast_api/browser"
355
+ )
322
356
 
323
357
  # Create FastAPI app
324
358
  app = adk_web_server.get_fast_api_app(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-adk-extras
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
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
@@ -1,8 +1,8 @@
1
- google_adk_extras/__init__.py,sha256=deMaothLZ-UWkfMdfIV186oMu9ueatO1pT8mpBrJnw8,851
2
- google_adk_extras/adk_builder.py,sha256=Ax5e_NegGZcdb_xm4t4e18gpJjcR5ICn0Zefy6VuLh4,30068
1
+ google_adk_extras/__init__.py,sha256=GbBnzocuEjf2RphvKaL9-DoDtsq0FVz2QO0uVTe66sQ,851
2
+ google_adk_extras/adk_builder.py,sha256=OR8ZSgaZJwjVpbfoTHOjgIisO_2sPUxegS0_ngCAco4,30129
3
3
  google_adk_extras/custom_agent_loader.py,sha256=e_sgA58RmDzCUHCySAi3Hruxumtozw3UScZV2vxlCbw,5991
4
4
  google_adk_extras/enhanced_adk_web_server.py,sha256=4QxTADlQv6oXaAEVMQc7-bpf84jCrTkN6pJC6R2jmww,5348
5
- google_adk_extras/enhanced_fastapi.py,sha256=xoWh9wibhxc48fEpLyQrkb2gB8Cas75_fwZzKWoRMic,28454
5
+ google_adk_extras/enhanced_fastapi.py,sha256=8JCkGOtzUaQM68BanhPaii1xBziPelXAYIbyUeUMEO0,29748
6
6
  google_adk_extras/enhanced_runner.py,sha256=b7O1a9-4S49LduILOEDs6IxjCI4w_E39sc-Hs4y3Rys,1410
7
7
  google_adk_extras/artifacts/__init__.py,sha256=_IsKDgf6wanWR0HXvSpK9SiLa3n5URKLtazkKyH1P-o,931
8
8
  google_adk_extras/artifacts/base_custom_artifact_service.py,sha256=O9rkc250B3yDRYbyDI0EvTrCKvnih5_DQas5OF-hRMY,9721
@@ -11,9 +11,9 @@ google_adk_extras/artifacts/mongo_artifact_service.py,sha256=K46Ycl7gkzCbCweVL0G
11
11
  google_adk_extras/artifacts/s3_artifact_service.py,sha256=inIc2KL3OdIQGkCA_HYJE0ZfGFQ3YcX_SFZEFVUb0T8,15655
12
12
  google_adk_extras/artifacts/sql_artifact_service.py,sha256=OovKSzM0nib2c-pzkv7NYyiHi8kFK-k3SFOMi92U4Mk,11980
13
13
  google_adk_extras/auth/__init__.py,sha256=PQQmFAjOPrt9tAGHOtQC-_U7fpRd8Dt_vh973b2pSnc,202
14
- google_adk_extras/auth/attach.py,sha256=eEnT7vvsb0ZQUKQI8ijgIziTrRTiyc1aPV0LwXBWtmU,10020
14
+ google_adk_extras/auth/attach.py,sha256=wSb2jKziGXqhRzu8XCBVuoHXyJa7T6CrGGbRhsfp_50,10235
15
15
  google_adk_extras/auth/config.py,sha256=JGJefyExVG3QFjmAkgTT-yaMivCvkOs4E7HwMlqVES0,1573
16
- google_adk_extras/auth/jwt_utils.py,sha256=sWIQWa1lGrottv6kzxo6cgTZFBa7J7wSa2-aJIVxfM8,1290
16
+ google_adk_extras/auth/jwt_utils.py,sha256=B3Iyu0GRqDU0EstGxfMUKm_w58z4l6WQGRAQvlcwvYk,1701
17
17
  google_adk_extras/auth/sql_store.py,sha256=-LouLrcT4gBBGrwG4kqbMyjVo1W1BbugPCKZUUFklWs,6693
18
18
  google_adk_extras/credentials/base_custom_credential_service.py,sha256=iYHacJAsZmDfpxLOPYx4tQpbtWTbwC75tRp6hlZFoSg,4014
19
19
  google_adk_extras/memory/__init__.py,sha256=2FFJXw9CZHctKXmCuc-lrdETeQ5xqdivy3oarHJz5gs,994
@@ -30,8 +30,8 @@ google_adk_extras/sessions/sql_session_service.py,sha256=TaOeEVWnwQ_8nvDZBW7e3qh
30
30
  google_adk_extras/sessions/yaml_file_session_service.py,sha256=g65ptJWAMVN4XQmCxQ0UwnSC2GU1NJ6QRvrwfzSK_xo,11797
31
31
  google_adk_extras/streaming/__init__.py,sha256=rcjmlCJHTlvUiCrx6qNGw5ObCnEtfENkGTvzfEiGL0M,461
32
32
  google_adk_extras/streaming/streaming_controller.py,sha256=Z72k5QgvWBIU2YP8iXlc3D3oWxDYWJo9eygj_KzALYA,10489
33
- google_adk_extras-0.3.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
34
- google_adk_extras-0.3.0.dist-info/METADATA,sha256=EX-DwXDezDXZVSLkGwTb36T-4pS_DWQgXRmCPDx5Gcw,12867
35
- google_adk_extras-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- google_adk_extras-0.3.0.dist-info/top_level.txt,sha256=DDWgVkz8G8ihPzznxAWyKa2jgJW3F6Fwy__qMddoKTs,18
37
- google_adk_extras-0.3.0.dist-info/RECORD,,
33
+ google_adk_extras-0.3.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
34
+ google_adk_extras-0.3.1.dist-info/METADATA,sha256=jN02PjbEwa6Lm-2rEpLV-bCBhRmNM9U3bd7u9RpxsS8,12867
35
+ google_adk_extras-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ google_adk_extras-0.3.1.dist-info/top_level.txt,sha256=DDWgVkz8G8ihPzznxAWyKa2jgJW3F6Fwy__qMddoKTs,18
37
+ google_adk_extras-0.3.1.dist-info/RECORD,,