Opencode Python SDK

repository·main·Indexed 42 days ago

https://github.com/anomalyco/opencode-sdk-python

The official Python library for the Opencode REST API, providing a typed, high-level interface for synchronous and asynchronous workflows. Version 0.1.0-alpha.36 supports session management, codebase search (files, symbols, text), TUI interaction, and streaming responses via SSE. It includes built-in support for httpx and aiohttp backends, automatic retries with exponential backoff, and comprehensive API error handling.

Tokens
12.2K
Snippets
59
Records
67
Agent score
52%

What's inside Opencode

  1. Access raw response data and headers

    main

    To access raw HTTP response data (like headers) instead of the parsed model, prefix your method call with .with_raw_response. This returns an APIResponse (or AsyncAPIResponse) object. Use .parse() to get the standard typed object.

    from opencode_ai import Opencode
    
    client = Opencode()
    response = client.session.with_raw_response.list()
    print(response.headers.get('X-My-Header'))
    
    session = response.parse()  # get the object that `session.list()` would have returned
    print(session)
  2. Handle API errors and connection issues

    main

    All errors inherit from opencode_ai.APIError. Use specific subclasses to handle different failure modes:

    • APIConnectionError: Network problems or timeouts.
    • APIStatusError: Non-success status codes (4xx or 5xx). Contains status_code and response properties.
    • RateLimitError: Specifically for 429 status codes.

    Common status code mappings:

    Status CodeError Type
    400BadRequestError
    401AuthenticationError
    403PermissionDeniedError
    404NotFoundError
    422UnprocessableEntityError
    429RateLimitError
    >=500InternalServerError
    N/AAPIConnectionError
    import opencode_ai
    from opencode_ai import Opencode
    
    client = Opencode()
    
    try:
        client.session.list()
    except opencode_ai.APIConnectionError as e:
        print("The server could not be reached")
        print(e.__cause__)  # underlying Exception (e.g. httpx)
    except opencode_ai.RateLimitError as e:
        print("A 429 status code was received; we should back off a bit.")
    except opencode_ai.APIStatusError as e:
        print("Another non-200-range status code was received")
        print(e.status_code)
        print(e.response)
  3. Configure retries and timeouts

    main

    Certain errors (Connection errors, 408, 409, 429, and >=500) are retried 2 times by default with exponential backoff.

    Use max_retries to configure retry settings and timeout to set request timeouts (default is 1 minute). Both can be set globally on the client or per-request using .with_options().

    from opencode_ai import Opencode
    import httpx
    
    # Configure global defaults
    client = Opencode(
        max_retries=0,
        timeout=20.0,
    )
    
    # More granular timeout using httpx.Timeout
    client = Opencode(
        timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
    )
    
    # Override per-request
    client.with_options(max_retries=5, timeout=5.0).session.list()
  4. Use aiohttp as the async HTTP backend

    main

    By default, the async client uses httpx. For improved concurrency performance, you can use aiohttp by installing the aiohttp extra and passing DefaultAioHttpClient() to the client constructor.

    # install from PyPI
    pip install --pre opencode-ai[aiohttp]
    import asyncio
    from opencode_ai import DefaultAioHttpClient
    from opencode_ai import AsyncOpencode
    
    async def main() -> None:
        async with AsyncOpencode(
            http_client=DefaultAioHttpClient(),
        ) as client:
            sessions = await client.session.list()
    
    asyncio.run(main())
  5. Stream response bodies with `.with_streaming_response`

    main

    To avoid eagerly reading the full response body into memory, use .with_streaming_response. This requires a context manager to ensure the response is closed. You can then iterate over lines or bytes.

    with client.session.with_streaming_response.list() as response:
        print(response.headers.get("X-My-Header"))
    
        for line in response.iter_lines():
            print(line)
  6. Make custom or undocumented requests

    main

    If you need to access undocumented endpoints or parameters, use the client's HTTP verb methods (client.get, client.post, etc.).

    • Undocumented endpoints: Use client.post("/path", ...).
    • Extra parameters: Use extra_query, extra_body, or extra_headers in request options.
    • Undocumented response properties: Access them via response.unknown_prop or by checking response.model_extra (a dictionary of extra fields).
    import httpx
    
    # Undocumented endpoint
    response = client.post(
        "/foo",
        cast_to=httpx.Response,
        body={"my_param": True},
    )
    print(response.headers.get("x-foo"))
  7. Configure the HTTP client and base URL

    main

    You can customize the underlying httpx client for proxies, custom transports, or to change the base_url. You can also use the OPENCODE_BASE_URL environment variable.

    import httpx
    from opencode_ai import Opencode, DefaultHttpxClient
    
    client = Opencode(
        base_url="http://my.test.server.example.com:8083",
        http_client=DefaultHttpxClient(
            proxy="http://my.test.proxy.example.com",
            transport=httpx.HTTPTransport(local_address="0.0.0.0"),
        ),
    )
    
    # Per-request customization
    client.with_options(http_client=DefaultHttpxClient(...))
  8. Iterate over synchronous streaming responses with Stream

    main

    The Stream[_T] class provides a synchronous interface for iterating over Server-Sent Event (SSE) responses. It automatically decodes the stream and casts each chunk to the specified type _T.

    Key features:

    • Type Casting: You can specify the expected type for the yielded items using the cast_to parameter during initialization.
    • Context Management: Supports the with statement to ensure the underlying httpx.Response is closed correctly.
    • Manual Closing: You can call .close() to release the connection. This is also automatically called if the stream is read to completion.

    Note: The Stream class is typically instantiated by the Opencode client during streaming API calls.

    # Example conceptual usage
    with client.some_streaming_method(cast_to=MyDataType) as stream:
        for item in stream:
            print(item)  # item is of type MyDataType
  9. Iterate over asynchronous streaming responses with AsyncStream

    main

    The AsyncStream[_T] class provides an asynchronous interface for iterating over SSE responses. It is designed for use with async/await syntax and the AsyncOpencode client.

    Key features:

    • Async Iteration: Use async for item in stream: to consume events.
    • Type Casting: Specify the expected type for yielded items via cast_to.
    • Context Management: Supports async with to ensure the connection is closed.
    • Manual Closing: Use await stream.close() to release the connection.

    Note: The AsyncStream class is typically instantiated by the AsyncOpencode client during streaming API calls.

    # Example conceptual usage
    async with async_client.some_streaming_method(cast_to=MyDataType) as stream:
        async for item in stream:
            print(item)  # item is of type MyDataType
  10. Access streaming responses from FileResource

    main

    To avoid eagerly reading the entire response body into memory, use the .with_streaming_response property as a prefix to your method calls. This is useful for handling large files. This is available for both FileResource and AsyncFileResource.

    # Synchronous streaming
    with client.files.with_streaming_response.read(path="path/to/file.txt") as stream:
        # handle stream
        pass
    
    # Asynchronous streaming
    async with await client.files.with_streaming_response.read(path="path/to/file.txt") as stream:
        # handle stream
        pass
  11. Access raw or streaming responses from TUI resources

    main

    If you need to access the underlying HTTP response (e.g., to read headers) or handle a streaming response without eagerly reading the body, use the .with_raw_response or .with_streaming_response properties on the TUI resource.

    • .with_raw_response: Returns the raw response object instead of the parsed content.
    • .with_streaming_response: An alternative that does not eagerly read the response body.
    # Accessing raw response
    raw_response = tui.with_raw_response.append_prompt(text="hello")
    
    # Accessing streaming response
    stream = tui.with_streaming_response.append_prompt(text="hello")