Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions modules/tutorials/pages/rest-api/rest-api-intro.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

:page-title: ThoughtSpot REST API tutorials
:page-pageid: rest-api__intro
:page-description: This lesson covers the security setup necessary to embed ThoughtSpot into TSE applications.
:page-description: Hands-on tutorial for using ThoughtSpot REST API V2.0 with Python and JavaScript.

This tutorial is a hands-on guide to practically working with the ThoughtSpot V2.0 REST API.

Expand All @@ -15,18 +15,18 @@ Once completed, you will be able to use the ThoughtSpot V2.0 REST API via Python
1. xref:rest-api_lesson-01.adoc[REST API Overview]
2. xref:rest-api_lesson-02.adoc[Simple Python implementation]
3. xref:rest-api_lesson-03.adoc[Complex REST API Workflows]
4. xref:rest-api_lesson-04.adoc[Browser JavaScript REST API implementation]
4. xref:rest-api_lesson-04.adoc[Browser JavaScript REST API implementation]
// 5. TypeScript SDK

== Pre-requisites for the tutorial
== Prerequisites for the tutorial
Your setup must have the following applications and tools installed:

* Chrome or Firefox
* Python 3.8 or higher
* link:https://code.visualstudio.com/[Visual Studio Code, window=_blank] or link:https://www.jetbrains.com/pycharm/[PyCharm, window=_blank]
* link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[The `thoughtspot_rest_api_v1` GitHub repo, window=_blank] library (capable of REST API V1 and V2.0) in your local Python environment
* link:https://github.com/thoughtspot/thoughtspot_rest_api_python[The `thoughtspot_rest_api` GitHub repository, window=_blank] (supports REST API V1 and V2.0) in your local Python environment

Download the entire link:https://github.com/thoughtspot/tse-api-tutorial[tse-api-tutorial directory^] as a ZIP file from GitHub, then unzip on your system:
Download the entire link:https://github.com/thoughtspot/tse-api-tutorial[tse-api-tutorial repository, window=_blank] as a ZIP file from GitHub, then unzip it on your system:

[.widthAuto]
[.bordered]
Expand Down
38 changes: 19 additions & 19 deletions modules/tutorials/pages/rest-api/rest-api_lesson-02.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ We'll use the files from the link:https://github.com/thoughtspot/tse-api-tutoria

. Open your IDE +
Visual Studio Code will be used in all images and instructions.
The files for this lesson are `api_training_python_1_begin.py` and `api_training_python_1_end.py`
The files for this lesson are `api_training_python_1_begin.py` and `api_training_python_1_end.py`.
. Open up your command line or terminal environment as well.

[NOTE]
Expand All @@ -24,7 +24,7 @@ Please adjust all Python commands according to your own environment.
== 01 - Imports and variables
At the top of `api_training_python_1_begin.py`, there is a set of *imports* and *variables* that configure the overall script.

=== Import Requests library
=== Import Requests library
To issue HTTP commands in a given programming language, you must use a library that sends and receives HTTP.

For this lesson, we'll use link:https://requests.readthedocs.io/en/latest/[Requests, window=_blank], the most commonly used high-level HTTP library for Python.
Expand All @@ -38,11 +38,11 @@ import json
----

==== Install requests package
If you followed the prerequisites and installed the link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot_rest_api_v1 package, window=_blank] using your command line or terminal:
If you followed the prerequisites and installed the link:https://github.com/thoughtspot/thoughtspot_rest_api_python[thoughtspot_rest_api package, window=_blank] using your command line or terminal:

[code,bash]
----
pip install thoughtspot_rest_api_v1
pip install thoughtspot_rest_api
----

The `requests` package should have automatically been installed along with the other requirements.
Expand All @@ -57,7 +57,7 @@ pip install requests --upgrade
=== Set global variables
It is very convenient to declare global variables at the beginning of a script so that they can be reused throughout.

The URL of the ThoughtSpot instance is always necessary to send a REST API command, and if the instance has Orgs enabled, you need to send the `org_id` when you request a login token. We'll set those as global variables along with the `api_version` (which hasn't changed ever at this point).
The URL of the ThoughtSpot instance is always necessary to send a REST API command, and if the instance has Orgs enabled, you need to send the `org_id` when you request a login token. We'll set those as global variables along with the `api_version` (which has remained unchanged so far).

[,python]
----
Expand All @@ -82,13 +82,13 @@ api_headers = {
}
----

== 02 - Use a Session object
== 02 - Use a Session object

Rather than set the full configuration of each HTTP request you make, you can construct a `Session` object from the `requests` library, which an open HTTP connection and maintains settings like headers and cookies between individual HTTP actions.
Rather than setting the full configuration for each HTTP request, you can construct a `Session` object from the `requests` library, which keeps an open HTTP connection and maintains settings like headers and cookies between individual HTTP actions.

You send HTTP commands by calling the `.get()`, `.post()`, `.put()` and `.delete()` methods of the `Session` object.

All of those methods will return a Response object, which you assign to a variable to do further processing. This will look something the following:
All of those methods return a Response object, which you assign to a variable for further processing. This will look something like the following:

[,python]
----
Expand All @@ -109,7 +109,7 @@ resp = requests_session.post(url=url, json=json_post_data)
----

== 03 - Authenticate into ThoughtSpot REST API
There are two ways of establishing authentication with ThoughtSpot's REST API, `cookie-based` with session cookies and `cookieless` using a bearer token in the headers.
There are two ways to establish authentication with ThoughtSpot's REST API: `cookie-based` with session cookies, and `cookieless` using a bearer token in the headers.

For backend scripts, we prefer the bearer token approach:

Expand All @@ -123,8 +123,8 @@ In the REST API V2.0 Playground:

. Go to *Authentication* > *Get Full Access Token*.
. Specify the parameters.
. Copy the JSON body from the right side of the Playground, Python Dict uses the same syntax, but you must update the booleans to be *uppercase*.
. Replace any of the hard-coded values with the *global variables* you declared so that you can change your requests in an easy way at the top of your script and make sure the values change in all the necessary places:
. Copy the JSON body from the right side of the Playground. Python dicts use the same syntax, but you must update booleans to be *uppercase*.
. Replace any hard-coded values with the *global variables* you declared so that you can easily update requests at the top of your script and ensure those values change everywhere they are used:
+
[,python]
----
Expand All @@ -146,7 +146,7 @@ json_post_data = {
We expect a JSON response on success, which you can access using the `.json()` method of the `Response` object.
+

From the Playground, we can see that there is `token` property in the response.
From the Playground, we can see that there is a `token` property in the response.

. Create a variable for the `token` value to use in the headers as the Bearer token.
+
Expand Down Expand Up @@ -178,7 +178,7 @@ Almost all REST API endpoints other than the token requests require authenticati

You need to update the `Session` object with this new header while keeping the original ones.

Use the `token` variable from above to form the exact header to update the original `api_headers` Dict, then use the `.headers.update()` method of the `Session` object:
Use the `token` variable from above to form the exact header to update the original `api_headers` dict, then use the `.headers.update()` method of the `Session` object:

[,python]
----
Expand All @@ -203,7 +203,7 @@ Python code raises `link:https://docs.python.org/3/tutorial/errors.html[Exceptio

If an `Exception` is raised and is not *handled*, the script exits and displays the message provided with the Exception and other details of what failed.

A `try...except block` encloses a set of lines that may result in a known `Exception` in the `try` portion, and then the `except` line defines which `Exception` type to listen for and how to proceed if the `Exception` is thrown.
A `try...except` block encloses a set of lines that may result in a known `Exception` in the `try` portion, and then the `except` line defines which `Exception` type to listen for and how to proceed if the `Exception` is thrown.

Every HTTP request can potentially result in an error, and we don't want to continue within the script as planned if the expected action on the ThoughtSpot server did not complete correctly.

Expand All @@ -227,7 +227,7 @@ The `requests` library does not raise an `Exception` when an HTTP request comple

However, as you saw in the previous lesson, HTTP responses include a *Status Code* that indicates if the requested action was a *Success* or an *Error*.

To cause `Exceptions` if the response does not include a *Success* status code, call the `Response.raise_for_status()` method for each call, which will throw the specifc `requests.exceptions.HTTPError` `Exception` when a 400 series or 500 status code is returned:
To raise `Exceptions` when the response does not include a *Success* status code, call the `Response.raise_for_status()` method for each call, which throws the specific `requests.exceptions.HTTPError` `Exception` when a 400 series or 500 status code is returned:

[source,python]
----
Expand Down Expand Up @@ -269,14 +269,14 @@ json_post_data = {
}

try:
# requests returns back Response object
# requests returns a Response object
resp = requests_session.post(url=url, json=json_post_data)

# This method causes Python Exception to throw if status not 2XX
# This method raises a Python exception if status is not 2XX
resp.raise_for_status()

# Retrieve the JSON body of response and convert into Dict
# Some endpoints returns 204 not 200 for success, with no body, will error if you call .json() method
# Retrieve the JSON body of the response and convert it into a dict
# Some endpoints return 204 instead of 200 for success, with no body, which errors if you call .json()
resp_json = resp.json()

# You can just print(resp_json) to see the Python Dict
Expand Down
Loading
Loading