Workplace Search APIs

edit

On this page

Initializing the Client

edit

The WorkplaceSearch client can either be configured directly:

# Use the Workplace client directly:
from elastic_enterprise_search import WorkplaceSearch

workplace_search = WorkplaceSearch(
    "http://localhost:3002"
)
# Now call API methods
workplace_search.search(..., http_auth="<oauth-access-token>")

…​or can be used via a configured EnterpriseSearch.workplace_search instance:

from elastic_enterprise_search import EnterpriseSearch

ent_search = EnterpriseSearch("http://localhost:3002")

# Now call API methods
ent_search.workplace_search.search(..., http_auth="<oauth-access-token>")

Document APIs

edit

To ingest documents into Workplace Search with the API you must first create a Custom Content Source and get the Content Source ID and Content Source Access Token.

In the examples below assume that CONTENT_SOURCE_ID is the Content Source ID and CONTENT_SOURCE_ACCESS_TOKEN is the Content Source Access Token from above.

Create or update Documents

edit

To create new documents or update existing documents use the index_documents() method.

The _allow_permissions and _deny_permissions properties can be used to control visibility of the documents for users. See the Permissions section below for more information on Permissions.

# Request:
workplace_search.index_documents(
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>",
    content_source_id="<CONTENT_SOURCE_ID>",
    documents=[
      {
        "_allow_permissions": ["permission1"],
        "_deny_permissions": [],
        "id" : 1234,
        "title" : "The Meaning of Time",
        "body" : "Not much. It is a made up thing.",
        "url" : "https://example.com/meaning/of/time",
        "created_at": "2019-06-01T12:00:00+00:00",
        "type": "list"
      },
      {
        "_allow_permissions": [],
        "_deny_permissions": ["permission2"],
        "id" : 1235,
        "title" : "The Meaning of Sleep",
        "body" : "Rest, recharge, and connect to the Ether.",
        "url" : "https://example.com/meaning/of/sleep",
        "created_at": "2019-06-01T12:00:00+00:00",
        "type": "list"
      }
    ]
)

# Response:
{
  "results": [
    {
       "id":"1234",
       "errors":[]
    },
    {
       "id":"1235",
       "errors":[]
    }
  ]
}

Get Document

edit

To get a single document by ID use the get_document() method:

# Request:
workplace_search.get_document(
    content_source_id="<CONTENT_SOURCE_ID>",
    document_id="<DOCUMENT_ID>"
)

# Response:
{
  "id":  "<DOCUMENT_ID>",
  "source": "custom",
  "content_source_id": "<CONTENT_SOURCE_ID>",
  "last_updated": "2021-03-02T22:41:16+00:00",
  "text_field": "some text value",
  "number_field": 42,
  "date_field": "2021-03-02T22:41:16+00:00",
  "geolocation_field": "44.35,-68.21",
  "_allow_permissions": ["perm1", "perm2"],
  "_deny_permissions": ["perm3", "perm4"]
}

List Documents

edit

List documents inside a Content Source

# Request:
workplace_search.list_documents(
    content_source_id="<CONTENT_SOURCE_ID>"
)

# Response:
{
  "meta": {
    "page": {
      "current": 1,
      "total_pages": 1,
      "total_results": 2,
      "size": 10
    },
    "warnings": [],
    "cursor": {
      "current": null,
      "next": "eyJzb3J0Ijp7Il9zY29yZSI6ImRlc2MifSwic2VhcmNoX2FmdGVyIjpbMS4wLCJkb2MtNjFiY2VkNjQ1MzU5OTEyMjlmNTM1MWEzIl19"
    }
  },
  "results": [
    {
      "last_updated": "2021-12-17T20:04:37+00:00",
      "updated_at": "2021-12-17T20:04:37+00:00",
      "content_source_id": "61bced325359912c2f5351a0",
      "source": "custom",
      "id": "doc-61bced5553599152f25351a2"
    },
    ...
  ]
}

Delete documents

edit

To remove documents from a custom content source use the delete_documents() method and supply a list of document IDs to body:

# Request:
workplace_search.delete_documents(
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>",
    content_source_id="<CONTENT_SOURCE_ID>",
    document_ids=[1234, 1235]
)

# Response:
{
  "results": [
    {
      "id": 1234,
      "success": True
    },
    {
      "id": 1235,
      "success": True
    }
  ]
}

Delete documents by Query

edit

Deletes documents that match a query or filters

# Request
workplace_search.delete_documents_by_query(
    content_source_id="<CONTENT_SOURCE_ID>",
    body={
        "filters": {
            "last_updated_at": {
                "from": "2020-06-01T12:00:00+00:00"
            }
        }
    }
)

# Response
{"total": 100, "deleted": 100, "failures": []}

Delete all documents

edit

Deletes all the documents in a Content Source

workplace_search.delete_documents_by_query(
    content_source_id="<CONTENT_SOURCE_ID>",
    body={}
)

Content Source APIs

edit

Create Content Source

edit
workplace_search.create_content_source(
    body={
        "name": "Content Source Name",
        "schema": {
            "title": "text",
            "body": "text",
            "url": "text"
        },
        "display": {
            "title_field": "title",
            "url_field": "url",
            "color": "#f00f00"
        },
        "is_searchable": True
    }
)

Get Content Source

edit
workplace_search.get_content_source(
    content_source_id="<CONTENT_SOURCE_ID>"
)

List Content Sources

edit
# Request:
workplace_search.list_content_sources()

# Response:
{
  "meta": {
    "page": {
      "current": 1,
      "total_pages": 1,
      "total_results": 4,
      "size": 25
    }
  },
  "results": [
    { <CONTENT SOURCE> },
    ...
  ]
}

Update Content Source

edit
workplace_search.put_content_source(
    content_source_id="<CONTENT_SOURCE_ID>",
    body={
        "name": "Content Source Name",
        "schema": {
            "title": "text",
            "body": "text",
            "url": "text"
        },
        "display": {
            "title_field": "title",
            "url_field": "url",
            "color": "#f00f00"
        },
        "is_searchable": True
    }
)

Delete Content Source

edit
workplace_search.delete_content_source(
    content_source_id="<CONTENT_SOURCE_ID>"
)

Upload Content Source Icons

edit

The data for the Content Source icons must be a PNG that is encoded in base64.

import base64

# Read 'main-icon.png' and 'alt-icon.png' and base64-encode the data
with open("main-icon.png", "rb") as f:
    main_icon = base64.b64encode(f.read()).decode()
with open("alt-icon.png", "rb") as f:
    alt_icon = base64.b64encode(f.read()).decode()

workplace_search.put_content_source_icon(
    content_source_id="<CONTENT_SOURCE_ID>",
    body={
        "main_icon": main_icon,
        # This icon is optional, if not provided 'main_icon' will be used.
        "alt_icon": alt_icon
    }
)

Search APIs

edit

Search requires an OAuth access token in the http_auth parameter to authenticate.

# Request:
workplace_search.search(
    body={
        "query": "sleep"
    }
)

# Response:
{
  "meta": {
    ...
  },
  "results": [
    {
      "title": {
        "raw": "The Meaning of Sleep",
        "snippet": "The Meaning of <em>Sleep</em>",
      },
      "_meta": {
        "source": "custom-source",
        "last_updated": "2020-03-27T20:10:33+00:00",
        "content_source_id": "<CONTENT_SOURCE_ID>",
        "id": "1235",
        "score": 6.359234
      },
      "source": {
        "raw": "custom-source"
      },
      "content_source_id": {
        "raw": "<CONTENT_SOURCE_ID>"
      },
      "id": {
        "raw": "park_american-samoa"
      },
      ...
    },
    ...
  ]
}

Permissions APIs

edit

Permissions can be set per-user and then applied to documents either by _allow_permissions or _deny_permissions to control access to documents.

Add Permission to User

edit

To add permissions to a user example.user use the add_user_permissions() method:

# Request:
workplace_search.add_user_permissions(
    content_source_id="<CONTENT_SOURCE_ID>",
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>",
    user="example.user",
    body={
        "permissions": ["permission1", "permission2"]
    }
)

# Response:
{
 "user": "example.user",
 "permissions": [
   "permission1",
   "permission2"
 ]
}

Get User Permissions

edit

To view a users permissions use the get_permissions() method:

# Request:
workplace_search.get_user_permissions(
    content_source_id="<CONTENT_SOURCE_ID>",
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>",
    user="example.user"
)

# Response:
{
 "user": "example.user",
 "permissions": [
   "permission1",
   "permission2"
 ]
}

Listing Permissions for Content Source

edit

To view all users permissions for a custom content source use the list_permissions() method:

# Request:
workplace_search.list_permissions(
    content_source_id="<CONTENT_SOURCE_ID>",
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>"
)

# Response:
[
  {
   "user": "example.user",
   "permissions": [
     "permission1",
     "permission2"
   ]
  }
]

Remove Permissions from User

edit

To remove one or more permissions from a user use the delete_user_permissions() method:

# Request:
workplace_search.delete_user_permissions(
    content_source_id="<CONTENT_SOURCE_ID>",
    http_auth="<CONTENT_SOURCE_ACCESS_TOKEN>",
    user="example.user",
    body={
        "permissions": ["permission2"]
    }
)

# Response:
{
  "user": "example.user",
  "permissions": [
    "permission1"
  ]
}

Get current User

edit

Gets the currently authenticated user

# Request
workplace_search.get_current_user()

# Response
{"email": "email@example.com", "username": "example"}

Synonyms APIs

edit

Create Synonym Set

edit
# Request
workplace_search.create_batch_synonym_sets(
    body={
        "synonym_sets": [
            {"synonyms": ["house", "home", "abode"]},
            {"synonyms": ["cat", "feline", "kitty"]}
        ]
    }
)

# Response
{
    "has_errors": True,
    "synonym_sets": [
        {
            "synonyms": ["house","home","abode"],
            "errors": [
                "Duplicate terms - the following terms already exist in an existing synonym set: house, home"
            ]
        },
        {"id": "<ID>", "synonyms": ["cat","feline","kitty"]}
    ]
}

Get Synonym Set

edit
# Request
workplace_search.get_synonym_set(
    synonym_set_id="<ID>"
)

# Response
{
    "id": "<ID>",
    "synonyms": ["house","home","abode"],
    "created_at": "2021-01-02T10:00:00Z",
    "updated_at": "2021-04-22T00:00:05Z"
}

List Synonym Sets

edit
# Request
workplace_search.list_synonym_sets(
    body={
        "filter": {
            "terms": ["home"]
        }
    }
)

# Response
{
  "meta": {
    "page": {
      "current": 1,
      "total_pages": 1,
      "total_results": 10,
      "size": 25
    },
    "filter": { "terms": ["house", "books"] },
    "sort": {
      { "updated_at": "desc" },
      { "created_at": "asc" }
    }
  },
  "results": [
    {
        "id": "<ID>",
        "synonyms": ["house","home","abode"],
        "created_at": "2021-01-02T10:00:00Z",
        "updated_at": "2021-04-22T00:00:05Z"
    }, ...
  ]
}

Delete Synonym Set

edit
workplace_search.delete_synonym_set(
    synonym_set_id="<ID>"
)

Update Synonym Set

edit
workplace_search.put_synonym_set(
    synonym_set_id="<ID>",
    body={
        "synonyms": ["mouses", "mice", "rat"]
    }
)

OAuth Applications with Workplace Search

edit

Workplace Search supports creating an OAuth Application and authenticating users via OAuth. The Workplace Search Python client has helper methods that make using OAuth easier.

The below example uses the recommended Confidential Flow and assumes an OAuth application has already been created and the values for Client ID, Client Secret, and Redirect URI have been gathered:

from elastic_enterprise_search import WorkplaceSearch

workplace_search = WorkplaceSearch(
    "https://<...>.ent-search.us-central1.gcp.cloud.es.io"
)
url = workplace_search.oauth_authorize_url(
    response_type="code",
    client_id="<client_id>",
    redirect_uri="<redirect_uri>"
)
# Redirect user via HTTP redirect with 'Location: <url>'

# ...When user is redirected back to <redirect_uri>
# get the '?code=...' from the request query parameters:
code = "<code>"

# Exchange the 'code' for an 'access_token':
resp = workplace_search.oauth_exchange_for_access_token(
    client_id="<client_id>",
    client_secret="<client_secret>",
    redirect_uri="<redirect_uri>",
    code=code
)

# Store these values somewhere for this user:
access_token = resp["access_token"]
refresh_token = resp["refresh_token"]

# Use the 'access_token' to make search requests
results = workplace_search.search(
    body={
        "query": "Things I want to find"
    },
    http_auth=access_token
)

# When the access token eventually expires, use the
# 'refresh_token' to get a new access token:
resp = workplace_search.oauth_exchange_for_access_token(
    client_id="<client_id>",
    client_secret="<client_secret>",
    redirect_uri="<redirect_uri>",
    refresh_token=refresh_token
)

# Update the stored values with new ones:
access_token = resp["access_token"]
refresh_token = resp["refresh_token"]