Python SDK for the Ouro API
Learn how to use the Ouro API in Python.
Before working with any of the methods outlined below, you'll need to initialize the Ouro client.
Make sure you've updated ouro-py
to the latest version as we are consistently making updates.
More details can be found in the quickstart.
from ouro import Ouro
ouro = Ouro(api_key=os.environ.get("OURO_API_KEY"))
Assets
There are four categories of assets on Ouro. Starting from the most fundamental, there are files, datasets, APIs, posts, and conversations.
For every asset on the platform, Ouro stores the following information:
- ID
- Name
- Description (optional)
- Metadata (asset specific details, like file size or number of rows)
- Visibility (public, private, monetized, or organization)
- Created at
- Updated at
- Owner
- Organization
- Team
- Price (if monetized)
Unless specifically working in an organizational context, assets are created within a global organization that includes all users on Ouro. You can control who sees the asset by adjusting the visibility.
Choosing the right team for an asset helps track a team's activity and make sure the right people find the right assets.
Files
Files are the most basic asset on Ouro. Just like the files on your computer, any file is fair game. Many files types have rich visualizations on the web platform.
Create a file
You can upload any file, up to 5GB in size.
file = ouro.files.create(
name="cif file",
description="Test file",
visibility="public",
file_path="./Fe.cif",
)
print(file)
file_path
is the path to the file on your local machine.
If you need to upload multiple files at once, currently the best way is to compress them into a .zip
file and upload that.
If you run into issues uploading large files, you can upload them using the web interface. After upload, you'll be able to find the file ID in the details dropdown (cog icon) on the file page header. Once you have the file ID, you can use it to interact with the file programmatically.
Read a file
id = '48ec6563-5520-4756-ac7f-b38f4933ac95'
file = ouro.files.retrieve(id)
# file is an object with properties like:
# file.id, file.name, file.description, file.metadata, file.visibility, file.created_at, file.user
If you created the file from the SDK, the ouro.files.create
response will be a file object which has the ID in the id
field.
If you uploaded the file using the web interface, or the asset was created by another user, you can find its ID in the file page header details dropdown (cog icon).
See the highlighted section in the screenshot below:
Once you've retrieved a file object with ouro.files.retrieve
, you can read its data using the read_data
method.
file_data = file.read_data()
print(file_data.url)
The read_data
method returns a FileData
object which has a url
property that you can use to download the file.
import requests
url = file_data.url
response = requests.get(url)
print(response.content)
Update a file
To be able to update a file, you must have admin or write permission on the file. As the creator of a file, you are automatically granted admin permissions.
file_id = file.id
updated_file = ouro.files.update(
id=file_id,
file_path="./Fe2BiNi.cif",
name="Fe2BiNi (Pmmm) updated"
)
# Returns the updated file object
print(updated_file)
You can update the file object with any of asset properties using named parameters. Only id
is required.
file_path
is a special property for files that allows you to update the file data with a new file. This is also optional.
Delete a file
You must have admin permissions on the file to delete it. This will completely remove the file from the platform.
ouro.files.delete(id=file.id)
Assets that may have referenced the file will no longer show a connection to the file.
Datasets
Documentation coming soon
Services
External APIs on Ouro are organized with two asset types: services and routes.
A service is a collection of routes that all share the same base URL. Routes are individual endpoints of the API defined by a HTTP method, path, and optional URL and query parameters and a body.
Ouro makes no guarantees about the stability of the APIs added to the platform. Make sure you trust the source/creator of the API before sending any sensitive data. You don't need to worry about the security of your account as no Ouro credentials are shared with the API.
If the API endpoint is monetized, you'll only be charged for successful requests.
Create a service
Not yet supported from the SDK. Use the web interface to create a service.
You can learn more about creating services with our guide How to monetize APIs. While focused on monetizing existing APIs, it covers the basics of creating and adding an API to Ouro.
Read a service
service_id = "438e454b-cf9e-40d9-b53d-b9b250087179"
service = ouro.services.retrieve(service_id)
Like the file object, using ouro.services.retrieve
will return a service object with the same base asset properties.
Once you've retrieved a service object, you can interact with routes
property.
# Returns a list of Route objects
service_routes = service.read_routes()
# Returns a dictionary with the OpenAPI specification, can be converted to JSON
service_spec = service.read_spec()
You can use the functionality of a service's endpoint with the use_route
method.
route = service_routes[0]
response = service.use_route(
route.id,
body={"composition": "Fe2Ni", "temperature": 0.8, "max_new_tokens": 3000}
)
# Returns a dictionary with the response from the endpoint
More details on using route functionality is in the routes section.
Update a service
Not yet supported from the SDK. Use the web interface to update a service. Navigate the asset and click the edit icon in the asset's header. You'll be able to adjust things like base URL, name, description, and authentication.
To update an individual route, navigate to the route and click the edit button to use the edit form.
Delete a service
Not yet supported from the SDK. Use the web interface to delete a service. Navigate the asset and click the delete button in the settings dropdown in the asset's header.
Routes
Routes are the individual endpoints of a service. These represents a single HTTP endpoint of the underlying web API.
Create a route
Not yet supported from the SDK. Use the web interface to create a route.
Navigate the service you want to add the route to and click the Add Route
button above the service's route table.
Read a route
To get the details of a route, use the ouro.routes.retrieve
method.
You can supply either the route ID or the asset identifier which consists of the creator and the route name + method.
The identifier is the section of the URL after routes/
.
Unless you own the route, it's best practice to use the ID as it will remain fixed even if the name of the asset changes.
When the name of an asset changes, it's identifier and URL will also change.
route_id = "2443b425-a2bf-4a6f-8202-3ba8b36c921f" # CrystaLLM generate route
route = ouro.routes.retrieve(route_id)
# OR
route_identifier = "mmoderwell/post-generate"
route = ouro.routes.retrieve(route_identifier)
# Returns a Route object
Update a route
Not yet supported from the SDK. Use the web interface to update a route. Navigate the route and click the edit button to use the edit form.
Delete a route
Not yet supported from the SDK. Use the web interface to delete a route.
Use a route
You can use the functionality of a route with the use
method.
route = ouro.routes.retrieve("mmoderwell/post-generate")
# Returns a dictionary with the response from the endpoint
generation = route.use(
body={
"composition": "Fe2Ni", "temperature": 0.8, "max_new_tokens": 3000
}
)
Other supported parameter to the use method are:
parameters
: a dictionary of URL parameters to pass to the endpointinput_asset
: an asset object to pass to the endpoint
You can chain together multiple routes to create custom workflows. Many routes create assets like files or datasets as output. The Python SDK will automatically add the asset's data to the route response.
generation_route = ouro.routes.retrieve("mmoderwell/post-generate")
generation = generation_route.use(
body={
"composition": "Fe2Ni", "temperature": 0.8, "max_new_tokens": 3000
}
)
# Get the file id from the generation. Added as a file object in dictionary format.
file_id = generation["file"]["id"]
prediction_route = ouro.routes.retrieve("mmoderwell/post-magnetism-curie-temperature")
prediction = prediction_route.use(
input_asset={
"assetId": file_id,
"assetType": "file"
}
)
print(prediction)
Read a route's actions
Every time a route is used, Ouro will store the request and response in an action object. Actions help keep track of what inputs created what outputs, including connections to the assets that may have been created by using a route.
actions = route.read_actions()
# Returns a list of dictionary objects with the action details
print(actions)
Actions are especially useful for long running routes. If the route takes longer than 10 minutes to complete, waiting for a response can be troublesome. Actions allow developers to poll the status of a route use and retrieve the response when it's ready.
Posts
Posts on Ouro are a way to share rich text-focused content with the Ouro community. Just like with every other kind of asset, you can create posts with a text editor on the web interface or use the SDK to create them programmatically.
The SDK exposes an Editor
class that allows you to construct a document block by block.
Blocks are things like paragraphs, headings, lists, or references to other assets.
import pandas as pd
content = ouro.posts.Editor()
content.new_header(level=1, text="Hello World")
content.new_paragraph(text="This is a paragraph")
content.new_code_block(language="python", code="print('Hello, World!')")
content.new_table(pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}))
content.new_inline_asset(id="438e454b-cf9e-40d9-b53d-b9b250087179", asset_type="service", view_mode="default")
content.new_inline_asset(id="8891046c-b52c-432f-b9b0-ca9515bb1c20", asset_type="file", view_mode="chart")
Valid methods of the Editor
class are:
new_header
: adds a header block of specified level (1-3)new_paragraph
: adds a paragraph of textnew_code_block
: adds a code blocknew_table
: adds a table from a pandas DataFramenew_inline_asset
: adds an Ouro asset with an optional visualization of the data (view_mode="chart")
Using the editor only creates a local object with your content.
You can view your content as JSON and Markdown text using the to_dict
method.
Create a post
Before you can create a post, you need to have the content you want to post.
The Editor
class explained above is one way, or you can use Ouro utils to convert a markdown string to a Content
object.
markdown_string = """
# Hello World
This is a test post from the Python SDK
"""
conversion = ouro.client.post(
"/utilities/convert/from-markdown", json={"markdown": markdown_string}
).json()
content = ouro.posts.Editor(text=markdown_string, json=conversion["json"])
This utility is useful for converting the output of an LLM. You can instruct the LLM to output an Ouro-extended version of Markdown with a prompt like the following:
Write your responses in extended markdown, using additional syntax when
referencing Ouro users and assets. For users, inline a reference with inline
code: `@{username}` For assets (files, datasets, posts, routes, services), use
a codeblock with a JSON config:
```assetComponent
{
"id": string uuid,
"assetType": 'post' | 'file' | 'dataset' | 'route' | 'service',
"viewMode": 'chart' | 'default'
}
```
When you embed an asset, you don't need to provide the title, description, or
link as it will be done in the embed. For files and datasets, prefer the chart
view mode, otherwise default.
Once you have your content, you save it to Ouro with the ouro.posts.create
method.
post = ouro.posts.create(
content=content,
name="Hello World",
description="This is a post from the Python SDK",
visibility="public",
)
# Returns a Post object
print(post)
Note: If you start your content with an H1, the name of the post should match the H1.
Read a post
You can read a post with the ouro.posts.retrieve
method.
You can find the ID of a post in the response of the ouro.posts.create
method or from the web interface.
post_id = "0190ea44-bfef-7f8b-9e5f-503fc20a4d91"
post = ouro.posts.retrieve(post_id)
# Returns a Post object
print(post)
You will find the post's content in the content
property of the post object.
You can get a markdown representation of the content with the text
property.
post_markdown = post.content.text
print(post_markdown)
Update a post
You can update a post with the ouro.posts.update
method.
updated_post = ouro.posts.update(
post.id,
description="This is a post from the Python SDK that is now private",
visibility="private"
)
# Returns the updated post object
print(updated_post)
You can update any of the post's properties, including the content, using the same approach used to create it.
Delete a post
You can delete a post with the ouro.posts.delete
method. You must be an admin of the post to delete it.
ouro.posts.delete(post.id)
Conversations
Coming soon
Comments
Coming soon
Teams
Coming soon
Users
Coming soon