Skip to main content

Pagination and Filtering

Set up

The following instructions assume that the Pipeline, Agent, and LLM object from the Quick Start example already exist and there is a Foundation4.ai API Server successfully running and accepting connections. Please see the installation instructions for details on how to set up the API server and the quick start example for instructions on how to create the necessary objects.

Test the connection

In order to ensure that the server is reachable, connecting to the API endpoint directly identifies the server.

import json
import os
import ssl
import httpx
import truststore

FOUNDATION4AI_API = os.environ.get('FOUNDATION4AI_API', 'https://api.foundation4ai.example.com') # replace with running server endpoint
FOUNDATION4AI_API = FOUNDATION4AI_API.strip('/')

api_key = os.environ.get('FOUNDATION4AI_API_KEY', '00000000-0000-0000-0000-000000000000') # replace with API KEY id
api_key_secret = os.environ.get('FOUNDATION4AI_API_SECRET', 'VERY SECRET PASSPHRASE') # replace with API KEY SECRET
HEADERS = {"x-api-key": api_key,"x-api-key-secret": api_key_secret}

ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client = httpx.Client(verify=ctx, headers=HEADERS)

res = client.get(FOUNDATION4AI_API)
assert res.status_code == 200 and res.json()["message"] == "Foundation4.ai Server"

Check all objects from the quick start exist

res = client.get(f'{FOUNDATION4AI_API}/llms?name=Quick Start LLM Endpoint')
llm_id = res.json()['data'][0]['id']

res = client.get(f'{FOUNDATION4AI_API}/pipelines?name=Quick Start Pipeline')
pipeline_id = res.json()['data'][0]['id']

res = client.get(f'{FOUNDATION4AI_API}/agents?name=Quick Start Basic Agent')
agent_id = res.json()['data'][0]['id']


print("LLM id :", llm_id)
print("Pipeline id:", pipeline_id)
print("Agent id :", agent_id)

LLM id : 2fd5b72c-3ed6-482d-b7bd-d29eabc8823f Pipeline id: 8dd356cd-f345-4302-8c8c-5eb754eafdff Agent id : a2a40d9e-8540-4f7f-9684-7064dd3f21dc

Filtering on GET Endpoints

GET endpoints that return multiple objects can be filtered by appending appropriate query strings. Each field supports a different set of operations based on the returned fields.

Filters are named according to <field>$<operation> or simply <field> if the operation is equality. Supported fields for pipelines are:

  • name: name equals
  • name$contains: name contains string
  • name$startswith: name starts with
  • name$gt: name is greater than
  • name$lt: name is less than
  • name$ge: name is greater or equal than
  • name$le: name is less or equal than
  • description: description equals
  • description_contains: description contains string

Pagination

The REST api supports pagination for GET endpoints that return multiple objects. There are two types of pagination supported, offsets and cursor pagination. For both pagination types, we can specify an order field as well as count=True to retrieve the total number of records.

Offset-based pagination

Offset-based pagination uses the traditional order, offset and limit constructs. To use it, append the following query strings:

  • offset=<number>: how many records to skip (defaults to 0)
  • limit=<number>: number of records to include (defaults to 25 if not specified)
  • order=<-field>,<+field>,...: fields to order by, - for descending, + for ascending

For large collections, this pagination type can have performance downsides. Additionally, if new records are added to the database after the user has made a request for a page of results, offset calculations will be invalid and cause records to show up repeatedly or skipped altogether.

Cursor-based pagination

Cursor-based pagination uses opaque cursors that encode the ordering and row pointed to. It relies on the fields first, after, last, before, and order. The first field should be combined with after and last combined with before. Specifying both first and last is not supported.

Opaque cursors should be obtained from previous calls. For example, specifying first or last results in a response with a page_field similar to

  "page_info": {
"after": "WyIxMWU4MTlmYy00MGMxLTRmZWYtODU0Mi1kMjQyNTFhZjcwZDgiXQ",
"before": "WyIwYTYzYzJkNy1kZDQzLTQ3MDQtOGI2NS1jNzM2OWI0NjkyZTgiXQ",
"count": 75,
"has_next": true,
"has_prev": false
}

For subsequent calls, one can use the after opaque cursor to get the next page.