Skip to main content

ClimateClaw Client

License docs codecov

A Python client library for interacting with the ClimateClaw backend. This library provides both synchronous and asynchronous interfaces for communicating with a ClimateClaw chatbot instance.

Features:

  • Synchronous client (ClimateClaw) with full API support
  • Asynchronous client (AsyncClimateClaw) with full API support
  • OIDC authentication via py-oidc-auth-client
  • Thread management (create, retrieve, list, search, fork, and delete conversation threads)
  • Streaming and non-streaming prompt responses
  • Thread operations (stop active conversations, set thread topics, edit/fork threads)
  • User feedback (submit positive/negative feedback on assistant messages)
  • Rich message types with markdown rendering support

Requirements

  • Python 3.10+

Dependencies

  • httpx - HTTP client for making requests
  • pydantic - Data validation and message modeling
  • py_oidc_auth_client - OIDC authentication handling

Installation

Currently, this package is in development and must be installed from source:

git clone https://github.com/freva-org/climateclaw-client.git
cd climateclaw-client
pip install -e .

Or using uv:

uv pip install -e .

Usage

Initialization

from climateclaw_client.client import ClimateClaw

# Create a client instance
cc = ClimateClaw(
    base_url="https://your-climate-claw-backend.com",
    token_store_path="~/.cache/climateclaw-client/token-store.json",  # Optional: path to store auth tokens
)

# Authenticate with the backend (triggers OIDC flow)
cc.authenticate()

Available Models

# List available chatbot models
models = cc.available_models
print(f"Available models: {models}")

# Set a default model for the client
cc.model = "gpt-4.1"

Prompting the Backend

Non-streamed Response

# Send a prompt and get the complete conversation
conversation = cc.prompt(
    "Please calculate the average temperature over Germany for the years 1990-2020!"
)
# Render the entire answer as a human-readable string
print(conversation)

# Access the individual messages
for message in conversation.messages:
    print(f"{message.variant}: {message.content}")

# Get markdown representation
markdown = conversation.repr_markdown()
print(markdown)

Streamed Response

# Send a prompt with streaming enabled
stream_conv = cc.prompt(
    "Please explain the ENSO phenomenon to me and give examples of how to quantify it!", stream=True
)

# Iterate over markdown-ready chunks as they arrive
with stream_conv as stream:
    for markdown_chunk in stream.iter_for_markdown():
        print(markdown_chunk)

# After streaming completes, access the full conversation
full_conversation = stream_conv.translate_to_conversation()
print(full_conversation.repr_markdown())

Thread Management

Create a New Thread

# Create a new conversation thread
thread_id = cc.newthread()
print(f"New thread ID: {thread_id}")

Get a Thread

# Retrieve an existing thread by ID
thread_id = "your-thread-id"
conversation = cc.getthread(thread_id=thread_id)

# Or use the current active thread
conversation = cc.getthread()

# Print all messages
print(conversation)

Prompt in a Specific Thread

# Continue a conversation in an existing thread
response = cc.prompt(
    "Please explain how the SOI can be calculated and run an example analysis.",
    thread_id=thread_id,  # optional: uses thread of active conversation otherwise
)

List User Threads

# List all your conversation threads
total_threads, user_threads = cc.getuserthreads(num_threads=10)
print(f"A total number of {total_threads} threads was retrieved.")
# access individual threads (which are Conversation objects)
print(user_threads[0])

Search Threads

# Search for threads by topic
total_results, matching_threads = cc.searchthreads(query="climate analysis", num_threads=5)

Set Thread Topic

# Set a topic for a thread (useful for searching later)
cc.setthreadtopic("ENSO analysis", thread_id=thread_id)

Delete a Thread

# Delete a thread on the backend when you're done with it
cc.deletethread(thread_id=thread_id)

Working with Message Types

The client provides rich message types that can be rendered in different formats:

from climateclaw_client.client import ClimateClaw

# Create a client instance
cc = ClimateClaw(base_url="https://your-climate-claw-backend.com")

# Authenticate with the backend
cc.authenticate()

# List available models
print(f"Available models: {cc.available_models}")
cc.model = cc.available_models[0]

# Start a conversation
response = cc.prompt(
    "Show me a code example of using the xarray library for analysing climate data!"
)

# Access individual messages
initial_response = response[0]

# String representation (for Python sessions)
print(str(initial_response))

# Markdown representation (for rendering)
print(initial_response.repr_markdown())

# Access content directly
print(initial_response.content)

# Extract code cells from Assistant messages
for code_cell in initial_response.message.code_cells:
    print(f"Code cell: {code_cell}")

Handling Images

Image messages have special methods:

# If the response contains an image
if response.messages[1].variant == "Image":
    image_message = conversation.messages[1]

    # Get markdown representation (base64 embedded)
    md = image_message.repr_markdown()

    # Save to file
    image_message.save_to_file("output.png")

Raw Message Access

# Access raw message chunks (before aggregation)
response = cc.prompt("Hello ClimateClaw! What is your function?")

for raw_msg in conversation.raw_messages:
    print(raw_msg.message.variant)
    print(raw_msg.message.content)

Message Types

The library supports the following message variants:

Variant Description Special Methods
Prompt Initial user prompt repr_content(), repr_markdown()
User User message repr_content(), repr_markdown()
Assistant Assistant response code_cells property, repr_content(), repr_markdown()
Code Python code code_cells property, repr_markdown() renders as code block
CodeOutput Code execution output repr_markdown() renders as blockquote
Image Base64-encoded image repr_markdown(), save_to_file()
ServerError Server error message repr_content(), repr_markdown()
OpenAIError OpenAI error message repr_content(), repr_markdown()
CodeError Code execution error repr_content(), repr_markdown()
StreamEnd Stream completion marker repr_markdown()
ServerHint Backend hint data (such as server heartbeats) repr_markdown()

Asynchronous Client

The library includes an AsyncClimateClaw class for async operations, providing the same functionality as the synchronous client but with async/await syntax:

import asyncio
from climateclaw_client import AsyncClimateClaw


async def main():
    # Create an async client instance
    cc = AsyncClimateClaw(
        base_url="https://your-climate-claw-backend.com",
        token_store_path="~/.cache/climateclaw-client/token-store.json",
    )

    # Authenticate with the backend
    await cc.authenticate()

    # List available models
    print(f"Available models: {cc.available_models}")
    cc.model = cc.available_models[0]

    # Send a prompt
    response = await cc.prompt(
        "Please calculate the average temperature over Germany for 1990-2020!"
    )
    print(response)

    # Send a streaming prompt
    stream_resp = await cc.prompt("Please explain the ENSO phenomenon to me!", stream=True)
    async with stream_resp as stream:
        async for markdown_chunk in stream.aiter_for_markdown():
            print(markdown_chunk)

    # Thread management
    thread_id = await cc.newthread()
    response = await cc.prompt(
        "Please explain how the SOI can be calculated.",
        thread_id=thread_id,
    )


# Run the async main function
asyncio.run(main())

Note: The async client uses httpx.AsyncClient under the hood and provides all the same methods as the synchronous ClimateClaw client, but as coroutines that must be awaited.

Configuration Options

Parameter Type Default Description
base_url str/URL Required Base URL of the ClimateClaw backend
token_store_path str "" Path to store OIDC tokens
follow_redirects bool True Whether to follow HTTP redirects
timeout float 30.0 Request timeout in seconds
max_retries int 3 Maximum retry attempts for failed requests
http_client httpx.Client / httpx.AsyncClient None Pre-configured HTTP client (Optional)
thread_id str None Default thread ID for conversations
model str None Default model for prompts

Note: For AsyncClimateClaw, the http_client parameter should be an httpx.AsyncClient instance, while for ClimateClaw it should be an httpx.Client instance.

Project Links

License

This project is licensed under the European Union Public Licence 1.2 (EUPL-1.2).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

climateclaw_client-0.1.1.tar.gz (37.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

climateclaw_client-0.1.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file climateclaw_client-0.1.1.tar.gz.

File metadata

  • Download URL: climateclaw_client-0.1.1.tar.gz
  • Upload date:
  • Size: 37.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for climateclaw_client-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c68c78dbfd103cce3178dba0dbc4aadf11c592b1ad7c4fde505d5587c71810c0
MD5 675ec25fe1c08681ca5a503060029d35
BLAKE2b-256 9461dbb8a0f3d31c478c46a11053898dc83c37737c950a31fb1e309602fc00ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for climateclaw_client-0.1.1.tar.gz:

Publisher: publish.yml on freva-org/climateclaw-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file climateclaw_client-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for climateclaw_client-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 79e69a065f57e7567e9dba7c88ad77f7624e47ca79147cdee3dfa89a5d06770b
MD5 a3b395cd9c4785cf359aad9cc08aad08
BLAKE2b-256 6ac2e89a4efe0d45e374d78a8f229ab301e0ea1bfd85800d35795a309a18741a

See more details on using hashes here.

Provenance

The following attestation bundles were made for climateclaw_client-0.1.1-py3-none-any.whl:

Publisher: publish.yml on freva-org/climateclaw-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

This release

0.1.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page