11"""Registry API client."""
22
33import logging
4+ import os
45from typing import Optional
56
67import httpx
@@ -17,44 +18,79 @@ class RegistryClient:
1718
1819 Args:
1920 base_url: Base URL for the Registry API (default: staging registry)
20- auth_token: Optional Bearer token for authenticated operations
21+ auth_token: Optional Bearer token for authenticated operations (highest priority)
22+ auth: If True, load auth token from ~/.amp/cache (shared with TS CLI)
23+
24+ Authentication Priority (highest to lowest):
25+ 1. Explicit auth_token parameter
26+ 2. AMP_AUTH_TOKEN environment variable
27+ 3. auth=True - reads from ~/.amp/cache/amp_cli_auth
2128
2229 Example:
2330 >>> # Read-only operations (no auth required)
2431 >>> client = RegistryClient()
2532 >>> datasets = client.datasets.search('ethereum')
2633 >>>
27- >>> # Authenticated operations (publishing, etc.)
34+ >>> # Authenticated operations with explicit token
2835 >>> client = RegistryClient(auth_token='your-token')
2936 >>> client.datasets.publish(...)
37+ >>>
38+ >>> # Authenticated operations with auth file (auto-refresh)
39+ >>> client = RegistryClient(auth=True)
40+ >>> client.datasets.publish(...)
3041 """
3142
3243 def __init__ (
3344 self ,
3445 base_url : str = 'https://api.registry.amp.staging.thegraph.com' ,
3546 auth_token : Optional [str ] = None ,
47+ auth : bool = False ,
3648 ):
3749 """Initialize Registry client.
3850
3951 Args:
4052 base_url: Base URL for the Registry API
4153 auth_token: Optional Bearer token for authentication
54+ auth: If True, load auth token from ~/.amp/cache
55+
56+ Raises:
57+ ValueError: If both auth=True and auth_token are provided
4258 """
59+ if auth and auth_token :
60+ raise ValueError ('Cannot specify both auth=True and auth_token. Choose one authentication method.' )
61+
4362 self .base_url = base_url .rstrip ('/' )
44- self .auth_token = auth_token
4563
46- # Build headers
47- headers = {
48- 'Content-Type' : 'application/json' ,
49- 'Accept' : 'application/json' ,
50- }
64+ # Resolve auth token provider with priority: explicit param > env var > auth file
65+ self ._get_token = None
5166 if auth_token :
52- headers ['Authorization' ] = f'Bearer { auth_token } '
67+ # Priority 1: Explicit auth_token parameter (static token)
68+ def get_token ():
69+ return auth_token
5370
54- # Create HTTP client
71+ self ._get_token = get_token
72+ elif os .getenv ('AMP_AUTH_TOKEN' ):
73+ # Priority 2: AMP_AUTH_TOKEN environment variable (static token)
74+ env_token = os .getenv ('AMP_AUTH_TOKEN' )
75+
76+ def get_token ():
77+ return env_token
78+
79+ self ._get_token = get_token
80+ elif auth :
81+ # Priority 3: Load from ~/.amp/cache/amp_cli_auth (auto-refreshing)
82+ from amp .auth import AuthService
83+
84+ auth_service = AuthService ()
85+ self ._get_token = auth_service .get_token # Callable that auto-refreshes
86+
87+ # Create HTTP client (no auth header yet - will be added per-request)
5588 self ._http = httpx .Client (
5689 base_url = self .base_url ,
57- headers = headers ,
90+ headers = {
91+ 'Content-Type' : 'application/json' ,
92+ 'Accept' : 'application/json' ,
93+ },
5894 timeout = 30.0 ,
5995 )
6096
@@ -92,6 +128,12 @@ def _request(
92128 """
93129 url = path if path .startswith ('http' ) else f'{ self .base_url } { path } '
94130
131+ # Add auth header dynamically (auto-refreshes if needed)
132+ headers = kwargs .get ('headers' , {})
133+ if self ._get_token :
134+ headers ['Authorization' ] = f'Bearer { self ._get_token ()} '
135+ kwargs ['headers' ] = headers
136+
95137 try :
96138 response = self ._http .request (method , url , ** kwargs )
97139
0 commit comments