Current section
Files
Jump to
Current section
Files
lib/gemini/auth.ex
defmodule Gemini.Auth do
@moduledoc """
Authentication strategy behavior and implementations for Gemini and Vertex AI.
This module provides a unified interface for different authentication methods:
- Gemini API: Simple API key authentication
- Vertex AI: OAuth2/Service Account authentication
"""
@type auth_type :: :gemini | :vertex_ai
@type credentials ::
%{
api_key: String.t()
}
| %{
access_token: String.t(),
project_id: String.t(),
location: String.t()
}
defmodule Strategy do
@moduledoc """
Behavior for authentication strategies.
"""
@callback headers(credentials :: map()) :: [{String.t(), String.t()}]
@callback base_url(credentials :: map()) :: String.t()
@callback build_path(model :: String.t(), endpoint :: String.t(), credentials :: map()) ::
String.t()
@callback refresh_credentials(credentials :: map()) :: {:ok, map()} | {:error, term()}
end
@doc """
Get the appropriate authentication strategy based on configuration.
"""
@spec get_strategy(auth_type()) :: module()
def get_strategy(auth_type) do
case auth_type do
:gemini -> Gemini.Auth.GeminiStrategy
:vertex_ai -> Gemini.Auth.VertexStrategy
:vertex -> Gemini.Auth.VertexStrategy
_ -> raise ArgumentError, "Unknown authentication type: #{inspect(auth_type)}"
end
end
@doc """
Get the appropriate authentication strategy based on configuration.
(Alias for get_strategy/1 for backward compatibility)
"""
@spec strategy(auth_type()) :: module()
def strategy(auth_type) do
case auth_type do
:gemini -> Gemini.Auth.GeminiStrategy
:vertex -> Gemini.Auth.VertexStrategy
:vertex_ai -> Gemini.Auth.VertexStrategy
_ -> raise ArgumentError, "Unsupported auth type: #{inspect(auth_type)}"
end
end
@doc """
Authenticate using the given strategy and configuration.
"""
@spec authenticate(module(), map()) :: {:ok, map()} | {:error, term()}
def authenticate(strategy_module, config) do
strategy_module.authenticate(config)
end
@doc """
Get base URL using the given strategy and configuration.
"""
@spec base_url(module(), map()) :: String.t() | {:error, term()}
def base_url(strategy_module, config) do
strategy_module.base_url(config)
end
@doc """
Build authenticated headers for the given strategy and credentials.
"""
@spec build_headers(auth_type(), map()) :: [{String.t(), String.t()}]
def build_headers(auth_type, credentials) do
strategy = get_strategy(auth_type)
strategy.headers(credentials)
end
@doc """
Get the base URL for the given strategy and credentials.
"""
@spec get_base_url(auth_type(), map()) :: String.t() | {:error, term()}
def get_base_url(auth_type, credentials) do
strategy = get_strategy(auth_type)
strategy.base_url(credentials)
end
@doc """
Build the full path for an API endpoint.
"""
@spec build_path(auth_type(), String.t(), String.t(), map()) :: String.t()
def build_path(auth_type, model, endpoint, credentials) do
strategy = get_strategy(auth_type)
strategy.build_path(model, endpoint, credentials)
end
@doc """
Refresh credentials if needed (mainly for Vertex AI OAuth tokens).
"""
@spec refresh_credentials(auth_type(), map()) :: {:ok, map()} | {:error, term()}
def refresh_credentials(auth_type, credentials) do
strategy = get_strategy(auth_type)
strategy.refresh_credentials(credentials)
end
end