-
Notifications
You must be signed in to change notification settings - Fork 198
feat: Cloud Functions Examples (User Provisioner) #849
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
Merged
lanlooker
merged 14 commits into
looker-open-source:main
from
lanlooker:izzy/python_cloudfunction
Oct 24, 2021
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
6ffc206
draft 1 cloud function
235d588
cf update
1eaa2c5
README python examples update
4f3aedf
refactor examples, include screenshots, and unit tests
lanlooker a136709
Update main.py
lanlooker 9ce64fc
change read me
lanlooker 849b27c
Merge branch 'main' into izzy/python_cloudfunction
lanlooker 1018d06
Fix typo
lanlooker 23e9ab6
Update comment
lanlooker 9f5b3bc
Apply suggestions from code review
lanlooker fe20625
Change to use f-string
lanlooker a965d1b
Merge branch 'main' into izzy/python_cloudfunction
lanlooker 16842de
Merge branch 'main' into izzy/python_cloudfunction
lanlooker cee7ecc
Merge branch 'main' into izzy/python_cloudfunction
lanlooker File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Cloud Function Example: User Provisioner | ||
|
|
||
| This repository contains a [Google Cloud Function](https://cloud.google.com/functions) that leverages Looker Python SDK. The repository can be used as a starter template to build serverless microservices that interact with Looker through the following workflow: | ||
|
|
||
| 1. Send a POST request to trigger an HTTP-based Cloud Function | ||
| 2. Initialize the Looker Python SDK | ||
| 3. Call Looker SDK methods and build custom logic to manage users, content, queries, etc. | ||
|
|
||
| In this repository, the `main.py` file takes an email address as an input and checks if this email has been registered with an existing Looker user. If an exisiting user is found, an email to reset the password will be sent to the user. Otherwise, a new user will be created, and a setup email will be sent. | ||
|
|
||
| For more use cases and Python examples, check out [Looker's Python SDK examples](https://github.com/looker-open-source/sdk-codegen/tree/main/examples/python). | ||
|
|
||
| ## Demo | ||
|
|
||
| <p align="center"> | ||
| <img src="https://storage.googleapis.com/tutorials-img/Cloud%20Function%20Demo%20-%20SD%20480p.gif" alt="Demo"> | ||
| </p> | ||
|
|
||
|
|
||
| ## Setup | ||
|
|
||
| The following steps assume deployment using Google Cloud UI Console. Check out ["Your First Function: Python"](https://cloud.google.com/functions/docs/first-python) for steps to deploy using the `gcloud` command line tool | ||
|
|
||
| 1. Obtain a [Looker API3 Key](https://docs.looker.com/admin-options/settings/users#api3_keys) | ||
|
|
||
| 2. Follow the steps [provided here](https://cloud.google.com/functions/docs/quickstart-python) to create a new Google Cloud Function | ||
|
|
||
| 3. Configure runtime environment variables using the Cloud Function UI: Edit > Configuration > Runtime, build, connections and security settings > Runtime environment variables. Alternatively, environtment variables can be configured through the `os` module or a `.ini`. Check out [Configuring Looker Python SDK](https://github.com/looker-open-source/sdk-codegen/tree/main/python#configuring-the-sdk) to learn more | ||
|
|
||
| <p align="center"> | ||
| <img src="https://storage.googleapis.com/tutorials-img/Cloud%20Function_env%20-%20SD%20480p.gif" alt="Setting environmental variables in Cloud Function UI"> | ||
| </p> | ||
|
|
||
| 4. Copy and paste the contents of `main.py` in this repository into `main.py` file once inside Cloud Function's inline editor. Change the "Entry point" in the top right to `main`. `main.py` is executed once the function is triggered | ||
|
|
||
| 5. Copy and paste the contents of `requirements.txt` in this repository to the `requirements.txt` file once inside Cloud Function's inline editor. This file is used to install neccessary libraries to execute the function | ||
|
|
||
| 6. Deploy and test the function. Check out [this article](https://cloud.google.com/functions/docs/quickstart-python#test_the_function) for instruction | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| """This Cloud Function leverages Looker Python SDK to manage user provision. The | ||
| `main` function is used as the entry point to the code. It takes an email address | ||
| as an input through a POST request, then checks if this email has been associated | ||
| with an existing Looker user. If an exisiting user is found, then an email to | ||
| reset password will be sent. Otherwise, a new user will be created, and a setup email | ||
| will be sent. | ||
|
|
||
| HTTP Cloud Functions: https://cloud.google.com/functions/docs/writing/http#sample_usage""" | ||
|
|
||
| import looker_sdk | ||
| sdk = looker_sdk.init40() | ||
|
|
||
| def main(request): | ||
| try: | ||
| request_json = request.get_json() | ||
| email = request_json["email"] | ||
| result = looker_user_provision(email=email) | ||
| return result | ||
| except: | ||
| return 'Please provide JSON in the format of {"email":"test@test.com"}' | ||
|
|
||
| def looker_user_provision(email): | ||
| user_id = search_users_by_email(email=email) | ||
| if user_id is not None: | ||
| sdk.send_user_credentials_email_password_reset(user_id=user_id) | ||
| return f'A user with this email: {email} already existed; Password reset sent.' | ||
| else: | ||
| create_users(email=email) | ||
| return f'New user created; Setup/Welcome email sent to {email}.' | ||
|
|
||
| def search_users_by_email(email): | ||
| """An email can only be assigned to one user in a Looker instance. | ||
| Therefore, search_user(email=test@test.com) will result in either | ||
| an empty dictionary, or a dictionary containing one user at index 0""" | ||
| users = sdk.search_users(email=email) | ||
| if len(users) == 0: | ||
| return None | ||
| else: | ||
| return users[0]["id"] | ||
|
|
||
| def create_users(email): | ||
| new_user = sdk.create_user( | ||
| body=looker_sdk.models40.WriteUser( | ||
| credentials_email=looker_sdk.models40.WriteCredentialsEmail( | ||
| email=email, | ||
| forced_password_reset_at_next_login=False | ||
| ), | ||
| is_disabled=False, | ||
| models_dir_validated=False | ||
| ) | ||
| ) | ||
|
|
||
| # Create email credentials for the new user | ||
| sdk.create_user_credentials_email( | ||
| user_id=new_user.id, | ||
| body=looker_sdk.models40.WriteCredentialsEmail( | ||
| email=email, | ||
| forced_password_reset_at_next_login=False | ||
| )) | ||
|
|
||
| # Send a welcome/setup email | ||
| sdk.send_user_credentials_email_password_reset(user_id=new_user["id"]) | ||
|
|
4 changes: 4 additions & 0 deletions
4
examples/python/cloud-function-user-provision/requirements.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Function dependencies, for example: | ||
| # package>=version | ||
| looker_sdk | ||
| requests |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.