Looker SDK
The Looker SDK for Typescript/Javascript provides a convenient way to communicate with the Looker API available on your
Looker server. The SDK is written in Typescript and uses the Node request and
request promise native modules for processing HTTP requests.
DISCLAIMER: This is an experimental version of the Looker SDK, using a new code generator developed by Looker.
You should expect some things to just not work, and foresee drastic changes to the SDK source code until an official
beta begins.
Getting started
The Looker SDK can be used in a node application in 3 steps:
Install the Looker SDK into your node application
Using npm
:
npm install @looker/sdk
Using yarn
:
yarn add @looker/sdk
Configure the SDK for your Looker server
Create a looker.ini
file with your server URL and API credentials assigned as shown in this example.
[Looker]
api_version=3.1
base_url=https://<your-looker-server>:19999
client_id=your_API3_client_id
client_secret=your_API3_client_secret
embed_secret=your_embed_SSO_secret
Note: If the application using the Looker SDK is going to be committed to a version control system, be sure to
ignore the looker.ini
file so the API credentials aren't unintentionally published.
Use the SDK in your code
When the SDK is installed and the server location and API credentials are configured in your looker.ini
file,
it's ready to be used.
Verify authentication works and that API calls will succeed with code similar to the following:
import { LookerNodeSDK } from '@looker/sdk'
(async () => {
const sdk = LookerNodeSDK.createClient()
const me = await sdk.ok(sdk.me(
"id, first_name, last_name, display_name, email, personal_space_id, home_space_id, group_ids, role_ids"))
console.log({me})
const dashboards = await sdk.ok(
sdk.search_dashboards({title: 'My SDK dashboard'})
)
if (dashboards.length === 0) {
console.log('Dashboard not found')
}
const [ dashboard ] = dashboards
...
await sdk.authSession.logout()
if (!sdk.authSession.isAuthenticated()) {
console.log('Logout successful')
}
})()
Using AuthSession for automatic authentication
NOTE: As we secure the design of the Looker SDK's authentication practices, the authentication behavior described
in this section will likely change.
Almost all requests to Looker's API require an access token. This token is established when the login
endpoint
is called with correct API3 credentials for client_id
and client_secret
. When login
is successful, the
user whose API3 credentials are provided is considered the active user. For this discussion of AuthSession
, we'll
call this user the API User.
The settings
provided to the AuthSession
class include the base URL for the Looker instance, and the API3 credentials.
When API requests are made, if the auth session is not yet established, AuthSession
will automatically authenticate
the API User. The AuthSession
also directly support logging in as another user, usually called sudo as
another
user in the Looker browser application.
API users with appropriate permissions can sudo
as another user by specifying a specific user ID in the
AuthSession.login()
method. Only one user can be impersonated at a time via AuthSession
. When a sudo
session is
active, all SDK methods will be processed as that user.
Sudo behavior with AuthSession
The rest of this section shows sample code for typical use cases for authentication and sudo. This code sample is extracted
directly from the sdk methods Jest tests, and assumes apiUser
is the default authenticated user record with sudo
abilities,
and sudoA
and sudoB
are other enabled Looker user records.
describe('sudo', () => {
it('login/logout', async () => {
const sdk = new LookerSDK(session)
const apiUser = await sdk.ok(sdk.me())
let all = await sdk.ok(
sdk.all_users({
fields: 'id,is_disabled'
})
)
const others = all
.filter(u => u.id !== apiUser.id && (!u.is_disabled))
.slice(0,2)
expect(others.length).toEqual(2)
if (others.length > 1) {
const [ sudoA, sudoB ] = others
await sdk.authSession.login(sudoA.id.toString())
let sudo = await sdk.ok(sdk.me())
expect(sudo.id).toEqual(sudoA.id)
await sdk.authSession.login(sudoB.id)
sudo = await sdk.ok(sdk.me())
expect(sudo.id).toEqual(sudoB.id)
await sdk.authSession.logout()
let user = await sdk.ok(sdk.me())
expect(sdk.authSession.isAuthenticated()).toEqual(true)
expect(user).toEqual(apiUser)
await sdk.authSession.login(sudoA.id)
sudo = await sdk.ok(sdk.me())
expect(sudo.id).toEqual(sudoA.id)
await sdk.authSession.login()
user = await sdk.ok(sdk.me())
expect(sdk.authSession.isAuthenticated()).toEqual(true)
expect(user.id).toEqual(apiUser.id)
}
await sdk.authSession.logout()
expect(sdk.authSession.isAuthenticated()).toEqual(false)
}, testTimeout)
})
Securing your SDK credentials
Looker improves on the security of the generated code for SDKs by never storing your server location or API credentials
in the source code generated by the Looker code generator. The SDKs also provide some simplified support for providing
location and credential information to the SDK.
Please consult with the security professionals in your organization to determine the best way to secure your credentials
for your own Looker SDK usage.
Warnings for using .ini
files to configure the SDK
To streamline getting started with the Looker SDKs, support for reading SDK credentials from an .ini
file is included
as a simple method for providing access information (server url and API credentials) to the SDK. If the source code to
your Looker SDK application is shared in a version control system, the .ini
file should be ignored so it never gets
inadvertently published.
If the SDK application using an .ini
file is available publicly, download or viewing of this .ini
file should also
be prohibited by the server hosting the application.
Warnings for using Environment variables to configure the SDK
If the host environment for a Looker SDK supports environment variables, the SDK can also read environment variables
to retrieve the server url and API credentials. Environment variables could also be visible to intrusive malware that
may penetrate your application, so this option for providing credentials should also be used with caution.