Search and set up triggers
Learn how to search for a term and view all the database items within a collection
# 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.
Info
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 (opens new window) and put it in the same directory you run your code from.
Make sure that workspace_id
and canonical_ds_id
both have values.
Info
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 = ...
2
3
4
5
6
7
8
9
10
11
# Search
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 (opens new window).
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}")
2
3
4
5
6
7
8
9
10
11
12
13
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)
resp.json()['title']
assert resp.json['title'] == 'A_Quiet_Place.txt'
2
3
4
Info
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)
resp.json()
2
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': ['user@domain.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': ['user@domain.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': '/user@domain.com/calling-all-dogs', '@timestamp': '2020-03-26T17:00:03.578200', '@cursor': '2020-03-26 17:00:03.5782//87e3fa89b82a4ce79a7d1f70fd3eedd9', '@assigned-roles': {'guillotina.Owner': ['user@domain.com']}, '@id': 'https://enterprise.onna.com/api/container/account/user@domain.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.
Info
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": ["user@domain.com"], "data": ""}],
"id":"Dogs"}
resp = requests.post(f'{base_url}/api/{container}/{account}/{user}', headers=headers, data=json.dumps(payload))
print(resp.json())
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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"}
2
3
4
5
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']
2
3
4
5
6
7
8
9
10
11
12
13
14
Next, PATCH
the file with content
# PATCH
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)
resp.status_code
2
3
4
5
6
7
8
Once the uploaded file has been processed, check your email!
You should have a notification from Onna like this one:
# 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.