# Search And Triggers

Key Point

How to search for a term and how to view all database items with a collection.

💡 5 min read

# Requirements

In this chapter, you'll search your Datasource for a term that only shows up in one file.

You'll also view all the items in your Datasource. Then you'll look at Smart Actions in the system by inspecting the output from the @data?types=Rule endpoint.

Finally, you'll set up a Smart Action (via a Rule) and add a file to our Datasource that should trigger the Smart Action.


You'll need to have a workspace and Datasource set up, and identifiers for these stored in variables for the http calls in this chapter to work correctly.

Please follow the steps in How to create a Static Datasource.

If you're already comfortable with the Onna API, please add a workspace and Datasource and upload the files found in the chapter How to create a Static Datasource.

Please download Dogs.txt and put it in the same directory you run your code from.

Make sure that workspace_id and canonical_ds_id both have values.


Uploaded files enter a processing queue and are searchable only after they exit the processing pipeline.

There might be some time between the two events.

You can always check the results of the API calls on your Onna account.

Make sure that you're authenticated with your Onna instance and that your code has the following:

import cgi
import io
import os
import json
import requests


workspace_id = ...
canonical_ds_id = ...

You'll set up a search for the term 'sightless creature', which only occurs in one of the resources in our Datasource.

Onna searches are conducted via a POST to the @frontsearch endpoint.

payload = {
    "facets": [],
    "size": 10,
    "from": 0,
    "hide_children": True,
    "advanced": {"and": [{"text_contains": [{"var": "extracted_text"},"sightless"]},
                         {"text_contains": [{"var": "extracted_text"},"creature"]},
                         {"and_not": [{"text_contains": [{"var":"subresource"},"quip"]}]}
resp = requests.post(f'{base_url}/api/{container}/{account}/@frontsearch', headers=headers, data=json.dumps(payload))
resource = resp.json()['member'][0]['@name']
print(f"View search results {resource}")

Next, you'll GET the resource and inspect its title.

# get the resource so you can ensure that its the one you want
resp = requests.get(f"{base_url}/api/{container}/{account}/{canonical_ds_id}/{resource}", headers=headers)
assert resp.json['title'] == 'A_Quiet_Place.txt'


The assert on the title of the matched document isn't necessary.

Searching is a significant function of the Onna platform -this barely scratches the surface of the search functionality!

# Smart Action

In this step, you're going to list any Rules. Rules are used in Smart Actions to set up the criteria of the action you wish to take. In this case, you're building a Rule to match on a specific term and upload a file that matches the criteria you've established.

resp = requests.get(f'{base_url}/api/{container}/{account}/@data?types=Rule', headers=headers)

The response from the GET may be empty, or it may have content if there are existing triggers.

{'updates': [{'@type': 'Rule', '@name': 'calling-all-dogs', '@uid': '87e3fa89b82a4ce79a7d1f70fd3eedd9', 'local_shared': True, 'creation_date': '2020-03-26T17:00:03.569936+00:00', 'modification_date': '2020-03-26T17:00:03.569936+00:00', 'creators': ['you@onna.com'], '@behaviors': [], 'query': {'and': [{'text_contains': [{'var': 'extracted_text'}, 'dog']}]}, 'description': 'it will let me know about dogs', 'facets': [{'facetType': 'workspaces', 'facetsSelected': ['7d3ee01ca6264c2999cf01beae56c0a4']}], 'advanced_search': True, 'trigger': True, 'rule_link': None, 'actions': [{'type': 'email', 'active': True, 'recipient_list': ['test.user@onna.com'], 'data': ''}], 'title': 'Calling all dogs', '@users-permissions': {'guillotina.ModifyContent': True, 'guillotina.DeleteContent': True, 'guillotina.AddContent': True, 'guillotina.SeePermissions': True, 'guillotina.ChangePermissions': True, 'onna.SendToSpyder': True}, '@path': '/test.admin@onna.com/calling-all-dogs', '@timestamp': '2020-03-26T17:00:03.578200', '@cursor': '2020-03-26 17:00:03.5782//87e3fa89b82a4ce79a7d1f70fd3eedd9', '@assigned-roles': {'guillotina.Owner': ['you@onna.com']}, '@id': 'https://enterprise.onna.com/api/container/account/you@onna.com/calling-all-dogs'}], 'total': 1, 'deleted': [], 'cursor': None}

You're going to set up a Smart Action and then upload a file that matches the criteria you set up.


Rules are stored on the user account. The facets in our query simply restricts the query to a specific Datasource, it can be a workspace instead or can be everywhere (no restriction).

The Smart Action's ID is 'Dogs' and will send an email to the recipient_list when a resource matches the criteria containing the word 'dogs' in the extracted text.

# set up a trigger on the word 'dogs', send email when a document has the word in its extracted text
user = "you@example.com"

payload = {"@type": "Rule",
           "title": "test",
           "trigger": True,
           "description": "Notify me of any documents containing dogs",
           "query": {"and":[{"text_contains":
                           [{"var":"extracted_text"}, "dogs"]
           "facets":[{"facetType": "sources",
                      "facetsSelected": [f"{canonical_ds_id}"]}],
           "actions":[{"type": "email", "active": True, "recipient_list": ["test.user@onna.com"], "data": ""}],
resp = requests.post(f'{base_url}/api/{container}/{account}/{user}', headers=headers, data=json.dumps(payload))

The resp.json() it should look something like this sample response:

{"@id": "https://enterprise.onna.com/api/{container}/{account}/{user}/Dogs",
 "@name": "Dogs",
 "@type": "Rule",
 "@uid": "86b475bff6874161806cc68aaa66ec5b",
 "UID": "86b475bff6874161806cc68aaa66ec5b"}

Now you'll upload a file that matches our criteria.

# Upload Another File

Uploading a file via the API requires two calls - POST to create the file, PATCH to provide the content for it.

First, POST the file to our Datasource

# upload a file with the word dogs in it

with open('Dogs.txt', "rb") as read_file:
    fd = read_file.read()

headers = {'Accept': 'application/json', 'Authorization': "Bearer {}".format(jwt_token)}
payload = {
    '@type': 'Resource',
    '@behaviors': ['onna.canonical.behaviors.metadata.IMetadata'],
    'title': 'Dogs.txt'
resp = requests.post(f'{base_url}/api/{container}/{account}/{workspace_id}/{canonical_ds_id}', headers=headers, data=json.dumps(payload))
upload_resource_id = resp.json()['@id'] # full url
upload_resource_name = resp.json()['@name']

Next, PATCH the file with content

headers = {'Accept': 'text/plain', 'Authorization': "Bearer {}".format(jwt_token),
        'Content-Type': 'application/octet-stream',
        'x-upload-size': str(os.path.getsize('Dogs.txt')),
        'x-upload-filename': 'Dogs.txt'
resp = requests.patch(f'{base_url}/api/{container}/{account}/{workspace_id}/{canonical_ds_id}/{upload_resource_name}/@upload/file', headers=headers, data=fd)

Once the uploaded file has been processed, check your email!

You should have a notification from Onna like this one:

Integrations Diagram

# Recap

You set up a search to find a particular resource and downloaded it. You then set up a Smart Action via a Rule and uploaded a file that matched the criteria you set up.

Workspaces and sharing describes the sharing API endpoints.

Custom fields provides endpoints to define additional fields on resources.

Last Updated: 5/18/2020, 1:34:58 PM