Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add 2 Python examples (pause/copy schedules, kill queries) #757

Merged
merged 21 commits into from
Jul 20, 2021
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
21 changes: 14 additions & 7 deletions examples/python/README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
# Python Examples for the Looker API

You can find Python language examples in this folder.
You can find Python language examples in this folder.

## Connection Management
The full details of all Looker API endpoints are listed in Looker Docs: [Version 3.1](https://docs.looker.com/reference/api-and-integration/api-reference/v3.1), [Version 4.0](https://docs.looker.com/reference/api-and-integration/api-reference/v4.0)

## Connection : Manage Database Connections

- [Test a specified connection](test_connection.py)

## Content Access Management
## Content : Manage Content

- [Add a board or dashboard to Favorites for a list of users](add_contents_to_favorite.py)
- [Output permission access for folders](folder_permission_access.py)

## Dashboards Management
## Dashboard : Manage Dashboards

- [Soft delete dashboard](soft_delete_dashboard.py)

## Render Tasks Management
## Query : Run and Manage Queries
- [Killing all running queries](kill_queries.py)

## RenderTask : Manage Render Tasks

- [Download dashboard tile in specified format](download_tile.py)
- [Download look in specified format](download_look.py)
- [Generate and download dashboard PDFs](download_dashboard_pdf.py)

## Schedules Management
## ScheduledPlan : Manage Scheduled Plans

- [Transfer all schedules of a user to another user](transfer_all_schedules.py)
- [Pause/Resume or Copy Schedules](manage_schedules.py)


## User Management
## User : Manage Users

- [Disable all active user sessions](logout_all_users.py)

Expand Down
41 changes: 41 additions & 0 deletions examples/python/kill_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
This script demonstrates examples with canceling queries using Python SDK

Example:
Kill all running queries in a Looker instance, or kill queries selectively with optional arguments ('user_id' and 'source')
Usecase: Running an excessive amount of queries simultaneously may lead to degraded Looker instance performance, especially queries run
by an API user to send out schedules or queries requiring post-processing features (such as merged results, custom fields, and table calculations).
In these situations, the fastest way to bring an instance back to a normal stage is to kill all running qeuries to help with restoring CPU and memory.

Authors: Lan

Last modified: July 18, 2021
"""

import looker_sdk
from looker_sdk import models40
sdk = looker_sdk.init40(config_file='../looker.ini', section='Looker')


def kill_queries(user_id=None, source=None):

"""Kill running queries in an instance.

Args:
user_id(int): id of the user whose queries are to be killed
source(str): common values are 'merge_query', 'explore', 'dashboard', 'look', 'regenerator'
"""

queries = sdk.all_running_queries()

if len(queries) == 0:
print('Currently, there is no running query in the instance')

else:
for i in range(0, len(queries)):
if queries[i]['source'] == source or queries[i]['user']['id'] == user_id:
sdk.kill_query(queries[i]['query_task_id'])
print('Killed query task id' + queries[i]['query_task_id'])

else:
print('Currently, there are no running queries that meet the conditions')
121 changes: 121 additions & 0 deletions examples/python/manage_schedules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"""
This script demonstrates examples with configuring Looker Schedule Plans using Python SDK

Example:
Pause/Resume all schedules of a Look or a Dashboard:
Usecase: Admins want to temporarily bulk-pausing all schedules when there are changes in ETL or LookML projects
that would lead to errors in sending schedules. Currently, there is no option in Looker UI to bulk-disable/enable schedules
Copy all schedule settings of a Look (or a Dashboard) to another Look (or a Dashboard)
Usecase: Admins want to copy all schedule settings (destination plans, recipients, result options, etc.) of a Look or
a Dashboard to another Look or Dashboard. Currently, there is no option in Looker UI to "copy" all schedules.

Authors: Lan

Last modified: July 18, 2021
"""

import looker_sdk
from looker_sdk import models40
sdk = looker_sdk.init40(config_file='../looker.ini', section='Looker')


def get_schedules(id, content, user_id=None, all_users=True):

""" Get all schedule plans of a Looker content owned by user_id

Args:
id: id of the Looker content containing schedules
content(str): 'look', 'dashboard', or 'lookml_dashboard'
user_id(int, optional): If user_id is None then return schedules owned by the user calling the API
all_users(bool, optional): If all_user is True then return schedules owned by all users
"""

if content == 'look':
schedules = sdk.scheduled_plans_for_look(id, user_id=user_id, all_users=all_users)
elif content == 'dashboard':
schedules = sdk.scheduled_plans_for_dashboard(id, user_id=user_id, all_users=all_users)
elif content == 'lookml_dashboard':
schedules = sdk.schedule_plans_for_lookml_dashboard(id, user_id=user_id, all_users=all_users)
return schedules


def resume_schedules(id, content, enabled, user_id=None, all_users=True):

""" Pause or resume all schedules of a Look, or a dashboard

Args:
id: id of the Looker content containing schedules
content(str): 'look', 'dashboard', or 'lookml_dashboard'
enabled (bool): set "True" to resume schedule, or "False" to pause schedule

Notes: Schedules with "enabled = False" will disappear from Admin > Schedules in Looker UI but
their data can be retrived in Looker's System Activity. Once schedules are resumed with "enabled = True",
they will be sent once and reappear in Admin > Schedules
"""

"Get all schedules of a Looker content"
schedules = get_schedules(id=id, content=content)

for i in range(0, len(schedules)):
sdk.update_scheduled_plan(
scheduled_plan_id=schedules[i]['id'],
body=models40.WriteScheduledPlan(
enabled = enabled
))

string = "Successfully set all schedules of {content} id {id} to enabled={enabled}".format(content=content, id =id, enabled=enabled)
print(string)



def copy_schedules(from_id, to_id, content, user_id=None, all_users=True):

""" Copy schedules from one Looker content to another content.
This script has only been tested for content of the same type (i.e.: look to look, dashboard to dashboard)

Args:
from_id: id of the Looker content containing schedules
to_id: id of the Looker content which schedules will be copied to
content(str): 'look', 'dashboard', or 'lookml_dashboard'
user_id(int, optional): If user_id is None then schedules owned by the user calling the API will be returned
all_users(bool, optional): If all_user is True then return schedules owned by all users
"""

"Get all schedules of a Looker content"
schedules = get_schedules(id=from_id, content=content, user_id=user_id, all_users=all_users)


for i in range(0, len(schedules)):

# Write the base schedule plans with all required fields
body = models40.WriteScheduledPlan(

# Required fields for all content type
name = schedules[i]['name'],
crontab = schedules[i]['crontab'],
datagroup = schedules[i]['datagroup'],
scheduled_plan_destination = schedules[i]['scheduled_plan_destination'],

# Additional required fields for content type Look
require_no_results = schedules[i]['require_no_results'],
require_change = schedules[i]['require_change'],
require_results = schedules[i]['require_no_results']
)

# Additional required field for each content type
if content == 'look':
body['look_id'] = to_id
elif content == 'dashboard':
body['dashboard_id'] = to_id
elif content == 'lookml_dashboard':
body['lookml_dashboard_id'] = to_id

"""Additional parameters can be added in the models40.WriteScheduledPlan() method for 'body',
or through Python's dictionary syntax: body[parameter] = value """


#Create new schedule plans
sdk.create_scheduled_plan(body=body)

string = "Successfully copy schedules of {content} id {from_id} to {content} id {to_id}".format(content=content, from_id=from_id, to_id=to_id)
print(string)