chore: import upstream snapshot with attribution
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / Pre-commit Linter (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.10) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.11) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.12) (push) Has been cancelled
Continuous Integration / Mypy Check (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.12) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / Unit Tests (Python 3.14) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.10) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.11) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.12) (push) Has been cancelled
Copybara PR Handler / close-imported-pr (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.13) (push) Has been cancelled
Continuous Integration / A2A v0.3 Tests (Python 3.14) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# OAuth2 Client Credentials Weather Agent
|
||||
|
||||
This sample demonstrates OAuth2 client credentials flow with ADK's `AuthenticatedFunctionTool` using a practical weather assistant agent.
|
||||
|
||||
## Overview
|
||||
|
||||
The OAuth2 client credentials grant type is used for server-to-server authentication where no user interaction is required. This demo shows:
|
||||
|
||||
- How to configure OAuth2 client credentials in ADK
|
||||
- Using `AuthenticatedFunctionTool` for automatic token management
|
||||
- Transparent authentication in a practical weather assistant
|
||||
- Testing the OAuth2 client credentials implementation
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
[WeatherAssistant] -> [AuthenticatedFunctionTool] -> [OAuth2CredentialExchanger] -> [OAuth2 Server] -> [Weather API]
|
||||
```
|
||||
|
||||
1. **WeatherAssistant** calls weather tool when user asks for weather data
|
||||
1. **AuthenticatedFunctionTool** automatically handles OAuth2 flow
|
||||
1. **OAuth2CredentialExchanger** exchanges client credentials for access token
|
||||
1. **Authenticated requests** are made to weather API
|
||||
|
||||
## Files
|
||||
|
||||
### `agent.py` - WeatherAssistant Agent
|
||||
|
||||
Weather assistant agent that demonstrates OAuth2 client credentials flow transparently:
|
||||
|
||||
- **OAuth2 Configuration**: Client credentials setup with token URL and scopes
|
||||
- **Weather Tool**: Single `get_weather_data` tool for fetching weather information
|
||||
- **Agent Definition**: ADK LLM agent focused on providing weather information
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- Automatic token exchange using client ID and secret
|
||||
- Bearer token authentication
|
||||
- Transparent OAuth2 handling (invisible to the model)
|
||||
- Practical use case demonstrating machine-to-machine authentication
|
||||
|
||||
### `main.py` - CLI Interface
|
||||
|
||||
Command-line interface for running the WeatherAssistant agent:
|
||||
|
||||
```bash
|
||||
# Ask for weather
|
||||
python contributing/samples/oauth2_client_credentials/main.py "What's the weather in Tokyo?"
|
||||
```
|
||||
|
||||
**Requirements:**
|
||||
|
||||
- LLM API key (Google AI or Vertex AI)
|
||||
- OAuth2 test server running
|
||||
|
||||
### `oauth2_test_server.py` - Local OAuth2 Server
|
||||
|
||||
Mock OAuth2 server for testing the client credentials flow:
|
||||
|
||||
```bash
|
||||
python contributing/samples/oauth2_client_credentials/oauth2_test_server.py
|
||||
```
|
||||
|
||||
**Features:**
|
||||
|
||||
- OIDC discovery endpoint (`/.well-known/openid_configuration`)
|
||||
- Client credentials token exchange (`/token`)
|
||||
- Protected weather API (`/api/weather`)
|
||||
- Supports both `authorization_code` and `client_credentials` grant types
|
||||
- Test credentials: `client_id="test_client"`, `client_secret="test_secret"`
|
||||
|
||||
**Endpoints:**
|
||||
|
||||
- `GET /.well-known/openid_configuration` - OIDC discovery
|
||||
- `POST /token` - Token exchange
|
||||
- `GET /api/weather` - Weather API (requires Bearer token)
|
||||
- `GET /` - Server info
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Start the OAuth2 server:**
|
||||
```bash
|
||||
python contributing/samples/oauth2_client_credentials/oauth2_test_server.py &
|
||||
```
|
||||
1. Create a `.env` file in the project root with your API credentials:
|
||||
|
||||
```bash
|
||||
# Choose Model Backend: 0 -> ML Dev, 1 -> Vertex
|
||||
GOOGLE_GENAI_USE_ENTERPRISE=1
|
||||
|
||||
# ML Dev backend config
|
||||
GOOGLE_API_KEY=your_google_api_key_here
|
||||
|
||||
# Vertex backend config
|
||||
GOOGLE_CLOUD_PROJECT=your_project_id
|
||||
GOOGLE_CLOUD_LOCATION=us-central1
|
||||
```
|
||||
|
||||
3. **Run the agent:**
|
||||
|
||||
```bash
|
||||
# Ask for weather
|
||||
python contributing/samples/oauth2_client_credentials/main.py "What's the weather in Tokyo?"
|
||||
```
|
||||
|
||||
1. **Interactive demo (use ADK commands):**
|
||||
|
||||
```bash
|
||||
# Interactive CLI
|
||||
adk run contributing/samples/oauth2_client_credentials
|
||||
|
||||
# Interactive web UI
|
||||
adk web contributing/samples
|
||||
```
|
||||
|
||||
## OAuth2 Configuration
|
||||
|
||||
The agent uses these OAuth2 settings (configured in `agent.py`):
|
||||
|
||||
```python
|
||||
flows = OAuthFlows(
|
||||
clientCredentials=OAuthFlowClientCredentials(
|
||||
tokenUrl="http://localhost:8000/token",
|
||||
scopes={
|
||||
"read": "Read access to weather data",
|
||||
"write": "Write access for data updates",
|
||||
"admin": "Administrative access",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
raw_credential = AuthCredential(
|
||||
auth_type=AuthCredentialTypes.OAUTH2,
|
||||
oauth2=OAuth2Auth(
|
||||
client_id="test_client",
|
||||
client_secret="test_secret",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
## Authentication Flow
|
||||
|
||||
1. **Weather Request**: User asks WeatherAssistant for weather information
|
||||
1. **Tool Invocation**: Agent calls `get_weather_data` authenticated function tool
|
||||
1. **Credential Loading**: CredentialManager loads OAuth2 configuration
|
||||
1. **Token Exchange**: OAuth2CredentialExchanger uses client credentials to get access token
|
||||
1. **Request Enhancement**: AuthenticatedFunctionTool adds `Authorization: Bearer <token>` header
|
||||
1. **API Call**: Weather API accessed with valid token
|
||||
1. **Response**: Weather data returned to user
|
||||
Reference in New Issue
Block a user