Skip to main content

Python API Client

Glean's Python API client provides a Pythonic interface to Glean's Client API, making it easy to integrate enterprise search and AI capabilities into your Python applications.

glean-api-client

Official Python client for Glean's Client API

info

Authentication Required: You'll need a Client API token to use this library.

Installation

pip install glean-api-client

Quick Start

1

Set up environment variables

export GLEAN_SERVER_URL="https://your-server-id-be.glean.com"
export GLEAN_API_TOKEN="your-token-here"
2

Basic usage

from glean.api_client import Glean
import os

with Glean(
api_token=os.getenv("GLEAN_API_TOKEN"),
server_url=os.getenv("GLEAN_SERVER_URL"),
) as client:
response = client.client.chat.create(
messages=[{
"fragments": [{"text": "What are our company values?"}]
}],
timeout_millis=30000
)
print(response)

Core Features

Chat API

Build conversational AI applications:

# Simple chat
response = client.client.chat.create(
messages=[{"fragments": [{"text": "Explain our Q4 strategy"}]}]
)

# Streaming chat for real-time responses
for chunk in client.client.chat.stream(
messages=[{"fragments": [{"text": "What are our priorities?"}]}]
):
print(chunk.text, end="", flush=True)

Search API

Integrate enterprise search:

results = client.client.search.search(
query="quarterly business review",
page_size=10
)

for result in results.results:
print(f"Title: {result.title}")
print(f"URL: {result.url}")

Agents API

Execute pre-built agents:

response = client.client.agents.create_and_wait_run(
agent_id="your-agent-id",
inputs={"query": "Analyze sales performance"}
)

Framework Integrations

FastAPI

from fastapi import FastAPI
from glean.api_client import Glean
from pydantic import BaseModel

app = FastAPI()

class ChatRequest(BaseModel):
message: str

@app.post("/chat")
async def chat_endpoint(request: ChatRequest):
with Glean(
api_token=os.getenv("GLEAN_API_TOKEN"),
server_url=os.getenv("GLEAN_SERVER_URL"),
) as client:
response = client.client.chat.create(
messages=[{"fragments": [{"text": request.message}]}]
)
return {"response": response.text}

Django

from django.http import JsonResponse
from glean.api_client import Glean
import json

def chat_view(request):
data = json.loads(request.body)
message = data.get('message')

with Glean(
api_token=os.getenv("GLEAN_API_TOKEN"),
server_url=os.getenv("GLEAN_SERVER_URL"),
) as client:
response = client.client.chat.create(
messages=[{"fragments": [{"text": message}]}]
)

return JsonResponse({'response': response.text})

Streamlit

import streamlit as st
from glean.api_client import Glean

st.title("Company Knowledge Assistant")

user_input = st.text_input("Ask a question:")

if user_input:
with Glean(
api_token=os.getenv("GLEAN_API_TOKEN"),
server_url=os.getenv("GLEAN_SERVER_URL"),
) as client:
response = client.client.chat.create(
messages=[{"fragments": [{"text": user_input}]}]
)
st.write(response.text)

Authentication

User-Scoped Tokens

client = Glean(
api_token="your-user-token",
server_url="https://your-server-id-be.glean.com"
)

Global Tokens with ActAs

response = client.client.chat.create(
messages=[{"fragments": [{"text": "Hello"}]}],
http_headers={"X-Glean-ActAs": "user@company.com"}
)

OAuth Access Tokens

An OAuth access token is a bearer credential, so it goes in the same api_token field:

client = Glean(
api_token=oauth_access_token,
server_url="https://your-server-id-be.glean.com",
)

Tokens issued by the Glean OAuth Authorization Server (including tokens obtained via Dynamic Client Registration) are detected automatically. Tokens issued by an external identity provider (Google, Okta, Azure, etc.) additionally require the X-Glean-Auth-Type: OAUTH header on each request:

response = client.client.chat.create(
messages=[{"fragments": [{"text": "Hello"}]}],
http_headers={"X-Glean-Auth-Type": "OAUTH"}
)

See the OAuth authentication guide for identity-provider setup.

Complete Example: Authorization Code with PKCE

This example uses Authlib with Flask. Setting code_challenge_method enables PKCE; Authlib stores the verifier and state in the session and verifies them on the callback. Point OAUTH_METADATA_URL at the Glean OAuth Authorization Server metadata (https://your-server-id-be.glean.com/.well-known/oauth-authorization-server) or your IdP's discovery document.

import os
from flask import Flask, jsonify, url_for
from authlib.integrations.flask_client import OAuth
from glean.api_client import Glean

app = Flask(__name__)
app.secret_key = os.urandom(24)

oauth = OAuth(app)
oauth.register(
name="glean",
client_id=os.environ["OAUTH_CLIENT_ID"],
client_secret=os.environ.get("OAUTH_CLIENT_SECRET"), # omit for a public client
server_metadata_url=os.environ["OAUTH_METADATA_URL"],
client_kwargs={
"scope": "openid offline_access SEARCH", # SEARCH lets the token call /search (a Glean scope); offline_access requests a refresh token
"code_challenge_method": "S256", # enable PKCE
},
)

@app.route("/login")
def login():
return oauth.glean.authorize_redirect(url_for("callback", _external=True))

@app.route("/callback")
def callback():
token = oauth.glean.authorize_access_token() # verifies state + PKCE, exchanges code

with Glean(
api_token=token["access_token"],
server_url=os.environ["GLEAN_SERVER_URL"],
) as glean:
results = glean.client.search.query(
query="quarterly reports",
page_size=10,
# Omit this header when the token is from the Glean Authorization Server.
http_headers={"X-Glean-Auth-Type": "OAUTH"},
)
titles = [r.title for r in (results.results or [])]

return jsonify({"titles": titles})

if __name__ == "__main__":
app.run(port=5000)
tip

Access tokens expire. The token dict includes refresh_token when you request the offline_access scope; use it to obtain new access tokens before expiry.

Error Handling

from glean.api_client.exceptions import GleanAPIError

try:
response = client.client.chat.create(messages=[...])
except GleanAPIError as e:
print(f"API error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")

Testing

Unit Testing with Mocks

import pytest
from unittest.mock import patch, MagicMock

@pytest.fixture
def mock_glean_client():
with patch('your_app.Glean') as mock:
client_instance = MagicMock()
mock.return_value.__enter__.return_value = client_instance
yield client_instance

def test_chat_service(mock_glean_client):
mock_response = MagicMock()
mock_response.text = "Test response"
mock_glean_client.client.chat.create.return_value = mock_response

result = send_message("Hello")
assert result == "Test response"

Additional Resources