Conjure Python Client
The Conjure Python Client (conjure-python-client) is a Python library that provides a simple interface for executing statically typed remote procedure calls (RPC) from Python. It acts as the RPC layer for clients generated by the `conjure-python` toolchain, leveraging the `requests` library for HTTP communication. Currently at version 3.3.0, the library is actively maintained with regular releases.
Common errors
-
TypeError: can't pickle 'ConjureHTTPError' object
cause Attempting to pass an instance of `ConjureHTTPError` between processes using Python's `multiprocessing` module with an older version of `conjure-python-client` (pre-3.2.0). The error object was not properly picklable.fixUpgrade `conjure-python-client` to version 3.2.0 or newer: `pip install --upgrade conjure-python-client`. -
HTTP 401 Unauthorized / HTTP 403 Forbidden
cause Incorrect or expired authentication credentials, missing `Authorization` header, or insufficient permissions for the client to access the requested Conjure service endpoint.fixVerify that the `Authorization` header is correctly formatted (e.g., 'Bearer <token>') and contains a valid, unexpired token. Ensure the client's credentials have the necessary permissions defined in your Conjure service policy. Check environment variables for token/key correctness. -
KeyError: 'some_expected_field_name' (during deserialization)
cause The JSON response from the Conjure service is missing an expected field, or there's a mismatch between the expected schema in the generated client and the actual data received. This can happen if the service API changes without a corresponding update to the client's API definition or if the service returns an unexpected error format.fixInspect the raw JSON response from the server to identify discrepancies. Regenerate your client code using the latest API definitions (`conjure-python`). Implement robust error handling for missing fields if the API contract allows for optionality or transient states.
Warnings
- breaking Version 3.0.0 was a major version bump, though its release notes for `conjure-python-client` indicated 'No documented user-facing changes'. However, major version changes often imply potential underlying shifts, especially as this client underpins code generated by `conjure-python`. Users upgrading from 2.x should exercise caution and thoroughly test their generated client integrations.
- gotcha Older versions (pre-3.2.0) of `ConjureHTTPError` could cause `PicklingError` when used in Python's `multiprocessing` module due to issues with its `__reduce__` method. This made passing these error objects between processes problematic.
- gotcha Prior to version 3.3.0, `conjure-python-client` might have had limited or broken compatibility when running on Windows operating systems.
Install
-
pip install conjure-python-client
Imports
- RequestsClient
from conjure_python_client import RequestsClient
- ServiceConfiguration
from conjure_python_client import ServiceConfiguration
Quickstart
import os
from conjure_python_client import RequestsClient, ServiceConfiguration
# Assume 'MyGeneratedService' is a service interface generated by conjure-python
# and imported from your project or another package.
# Example: from my_api_client import MyGeneratedService
# Define a dummy service for demonstration if MyGeneratedService isn't available
class MyGeneratedService:
def __init__(self, client):
self._client = client
def get_data(self, auth_header, query_param):
print(f"Making GET request for data with param: {query_param}")
# In a real scenario, this would call self._client._request(...)
if auth_header == 'Bearer valid-token':
return f"Successfully retrieved data for '{query_param}'"
else:
raise ValueError("Invalid authentication")
# Configure the service client
config = ServiceConfiguration()
config.uris = [os.environ.get('CONJURE_API_URI', 'http://localhost:8080/api')]
# Replace 'MyGeneratedService' with your actual generated service class
try:
service = RequestsClient.create(
MyGeneratedService,
user_agent="my-application/1.0.0",
service_config=config
)
# Example usage: making an authenticated call
auth_token = os.environ.get('CONJURE_AUTH_TOKEN', 'valid-token')
auth_header = f"Bearer {auth_token}"
result = service.get_data(auth_header, query_param="example_id")
print(result)
except Exception as e:
print(f"An error occurred: {e}")