Python SDK for the Ouro API

Last updated 16h ago

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:

File ID in the details dropdown

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 endpoint
  • input_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 text
  • new_code_block: adds a code block
  • new_table: adds a table from a pandas DataFrame
  • new_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