Making HTTP requests#

The Tonita API can also be accessed via HTTP (e.g., using a tool like cURL). HTTP requests to Tonita servers should adhere to the guidelines below.

Tip

See Quickstart for examples of Tonita API requests made using cURL.

Endpoint URLs#

Each function in the Tonita Python library corresponds to its own URL to which HTTP requests can be sent. The hostname of each URL is api.tonita.co. The URL path for a given function is exactly its path in the tonita package.

For example, the URL path for tonita.listings.add() will be listings/add, so that sending a request to:

https://api.tonita.co/listings/add

will be equivalent to calling tonita.listings.add(). Likewise, the URL path for tonita.search() is:

https://api.tonita.co/search

Request method#

Every HTTP request to Tonita servers must be made using POST, regardless of whether any data is sent with the request.

Headers#

Data representation#

Any data sent in a request must be in JSON format. This should be denoted by setting the value of the Content-Type representation header to application/json.

API key#

All requests must contain the x-api-key header. Its value will be the API key provided to you by Tonita. If you do not have an API key, please obtain one.

Corpus ID#

For all listing, search, and evaluation operations, the corpus ID is required and should be provided in your request as the value to the corpus-id header. The value should be the ID of the corpus that the particular operation pertains to.

For corpus operations, the corpus ID should be provided in the body of the request if it is required by the operation (see examples below).

Sending and receiving data#

As mentioned in Data representation, if some operation requires data (i.e., the corresponding Python function has required parameters), that data must be sent in the request body in JSON format. The keys and values of the JSON for a given operation will be exactly the parameter names and argument values, respectively, of the corresponding Python function (except for the API key and, in the case of corpus operations, the corpus ID).

For example, consider the following call to tonita.search():

tonita.search(
    query='sunny 1 bedroom on a quiet street near parks',
    max_results=2,
    corpus_id="new_york",
    api_key="my_api_key"
)

This is equivalent to:

curl -X POST \
    -H "content-type: application/json" \
    -H "x-api-key: my_api_key" \
    -H "corpus-id: new_york" \
    -d '{"query": "sunny 1 bedroom on a quiet street near parks", "max_results": 2}' \
    https://api.tonita.co/search

Let’s also look at two corpus operations. tonita.corpora.get() requires a corpus ID, and so a cURL request would look like:

curl -X POST \
    -H "content-type: application/json" \
    -H "x-api-key: my_api_key" \
    -d '{"corpus_id": "my_corpus_id"}' \
    https://api.tonita.co/corpora/get

On the other hand, tonita.corpora.list() does not, and so the request would look like:

curl -X POST \
    -H "content-type: application/json" \
    -H "x-api-key: my_api_key" \
    https://api.tonita.co/corpora/list

Dataclasses and JSONs#

For complex request and response objects (e.g., tonita.datatypes.search.SearchRequest), note that all Tonita dataclasses ultimately wrap primitive datatypes. Therefore, any dataclass from the Tonita library can be reduced to JSON format: the keys of the JSON will exactly be the fields in the dataclass, and nested dataclasses can be represented by nested JSON objects.

For example, consider the following tonita.datatypes.search.SearchResponse:

from tonita.datatypes.search import SearchResponse, SearchResponseItem, Snippet

SearchResponse(
    items=[
        SearchResponseItem(
            listing_id="foo",
            score=0.8,
            categories=["romance", "comedy"],
            snippets=[Snippet(display_string="Lorem ipsum")]
        ),
        SearchResponseItem(
            listing_id="bar",
            score=0.6,
            categories=["drama"],
            snippets=[
                Snippet(display_string="dolor sit amet"),
                Snippet(display_string="consectetur adipiscing elit.")
            ]
        )
    ]
)

This structure is equivalent to the following JSON:

{
    "items": [
        {
            "listing_id": "foo",
            "score": 0.8,
            "categories": [
                "romance",
                "comedy"
            ],
            "snippets": [
                {
                    "display_string": "Lorem ipsum"
                }
            ]
        },
        {
            "listing_id": "bar",
            "score": 0.6,
            "categories": [
                "drama"
            ],
            "snippets": [
                {
                    "display_string": "dolor sit amet"
                },
                {
                    "display_string": "consectetur adipiscing elit."
                }
            ]
        }
    ]
}

To cast a dataclass as a dictionary, and then to serialize that dictionary to JSON, you can use dataclasses.asdict() and json.dumps().