No project description provided
Project description
Paid is the all-in-one, drop-in Business Engine for AI Agents that handles your pricing, subscriptions, margins, billing, and renewals with just 5 lines of code. The Paid Python library provides convenient access to the Paid API from Python applications.
Documentation
See the full API docs here
Installation
You can install the package using pip:
pip install paid-python
Usage
The client needs to be configured with your account's API key, which is available in the Paid dashboard.
from paid import Paid
client = Paid(token="API_KEY")
client.customers.create(
name="name"
)
Request And Response Types
The SDK provides Python classes for all request and response types. These are automatically handled when making API calls.
# Example of creating a customer
response = client.customers.create(
name="John Doe",
)
# Access response data
print(response.name)
print(response.email)
Exception Handling
When the API returns a non-success status code (4xx or 5xx response), the SDK will raise an appropriate error.
try:
client.customers.create(...)
except paid.Error as e:
print(e.status_code)
print(e.message)
print(e.body)
print(e.raw_response)
Logging
Supported log levels are DEBUG, INFO, WARNING, ERROR, and CRITICAL.
For example, to set the log level to debug, you can set the environment variable:
export PAID_LOG_LEVEL=DEBUG
Defaults to ERROR.
Cost Tracking via OTEL tracing
Simple Decorator Method
The easiest way to add cost tracking is using the @paid_tracing decorator:
from paid.tracing import paid_tracing
@paid_tracing("<external_customer_id>", "<optional_external_agent_id>") # add this line
def some_agent_workflow(): # your function
# Your logic - use any AI providers with Paid wrappers or send signals with Paid.signal().
# This function is typically an event processor that should lead to AI calls or events emitted as Paid signals
- Initializes tracing using your API key you provided to the Paid client, falls back to
PAID_API_KEYenvironment variable. - Handles both sync and async functions
- Gracefully falls back to normal execution if tracing fails
Using the Paid wrappers
You can track usage costs by using Paid wrappers around your AI provider's SDK. As of now, the following SDKs' APIs are wrapped:
openai
openai-agents
anthropic
langchain (as a callback)
llamaindex
bedrock (boto3)
mistral
gemini (google-genai)
Example usage:
from openai import OpenAI
from paid.tracing.wrappers import PaidOpenAI
openAIClient = PaidOpenAI(OpenAI(
# This is the default and can be omitted
api_key="<OPENAI_API_KEY>",
))
@paid_tracing("your_external_customer_id", "your_external_agent_id")
def image_generate():
response = openAIClient.images.generate(
model="dall-e-3",
prompt="A sunset over mountains",
size="1024x1024",
quality="hd",
style="vivid",
n=1
)
return response
image_generate()
Alternatively, instead of the decorators you can use the paid.trace() function (more control by wrapping with a callback).
from openai import OpenAI
from paid import Paid
from paid.tracing.wrappers import PaidOpenAI
# Initialize Paid SDK
client = Paid(token="PAID_API_KEY")
openAIClient = PaidOpenAI(OpenAI(
# This is the default and can be omitted
api_key="<OPENAI_API_KEY>",
))
# Initialize tracing, must be after initializeing Paid SKD
client.initialize_tracing()
def image_generate():
response = openAIClient.images.generate(
model="dall-e-3",
prompt="A sunset over mountains",
size="1024x1024",
quality="hd",
style="vivid",
n=1
)
return response
# Finally, capture the traces!
_ = client.trace(external_customer_id = "<your_external_customer_id>",
external_agent_id = "<your_external_agent_id>", # can optionally include external_agent_id to enable agent-level cost tracking
fn = lambda: image_generate())
Signaling via OTEL tracing
A more reliable and user-friendly way to send signals is to send them from within the traces.
This allows you to send signals with the same customer and agent IDs as the trace, with less arguments and boilerplate.
The interface is Paid.signal(), which takes in signal name and optional data.
Paid.signal() has to be called within a trace - meaning inside of a callback to Paid.trace().
In contrast to Paid.usage.record_bulk(), Paid.signal() is using OpenTelemetry to provide reliable delivery.
Here's an example of how to use it:
from paid import Paid
# Initialize Paid SDK
client = Paid(token="PAID_API_KEY")
@paid_tracing("your_external_customer_id", "your_external_agent_id") # external_agent_id is necessary for sending signals
def do_work():
# ...do some work...
client.signal(
event_name="<your_signal_name>",
data={ } # optional data (ex. manual cost tracking data)
)
do_work()
Same, but using callback to specify the function to trace:
from paid import Paid
# Initialize Paid SDK
client = Paid(token="PAID_API_KEY")
# Initialize tracing, must be after initializing Paid SDK
client.initialize_tracing()
def do_work():
# ...do some work...
client.signal(
event_name="<your_signal_name>",
data={ } # optional data (ex. manual cost tracking data)
)
# Finally, capture the traces!
_ = client.trace(external_customer_id = "<your_external_customer_id>",
external_agent_id = "<your_external_agent_id>", # external_agent_id is required for signals
fn = lambda: do_work())
Manual Cost Tracking
Manual cost tracking allow to insert your own costs to the usage data and cost traces will be created based on that info.
from paid import Paid, Signal
client = Paid(token="<PAID_API_KEY>")
signal = Signal(
event_name="<your_signal_name>",
agent_id="<your_agent_id>",
customer_id="<your_external_customer_id>",
data = {
"costData": {
"vendor": "<any_vendor_name>", # can be anything
"cost": {
"amount": 0.002,
"currency": "USD"
},
"gen_ai.response.model": "<ai_model_name>",
}
}
)
_ = client.usage.record_bulk(signals=[signal])
Contributing
While we value open-source contributions to this SDK, this library is generated programmatically. Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!
On the other hand, contributions to the README are always very welcome!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paid_python-0.0.5a28.tar.gz.
File metadata
- Download URL: paid_python-0.0.5a28.tar.gz
- Upload date:
- Size: 50.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.9.23 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c34ead466a93f4ca27e86dd9188d93b1fa1e3b72b966a0bab8c28a35e382a663
|
|
| MD5 |
7f304135902e02ef9108fa2e01f42236
|
|
| BLAKE2b-256 |
faa0ff9c2ad2ccb572333cfb521678318b48ef30d96890fd3a58d3ce98e01ffd
|
File details
Details for the file paid_python-0.0.5a28-py3-none-any.whl.
File metadata
- Download URL: paid_python-0.0.5a28-py3-none-any.whl
- Upload date:
- Size: 81.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.5.1 CPython/3.9.23 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c08b75b6274e4d306557dcd2a3729c0f9fde0f3a4d976055af6b2a3db6c4621
|
|
| MD5 |
60d6eaae304ec72036cdf97fad8334a0
|
|
| BLAKE2b-256 |
feb70bc753f8f7276699b0177be341817468feaace46028bd6e6711a1c19e4a8
|