Skip to content

Instantly share code, notes, and snippets.

@kylenstone
Created November 24, 2020 19:02
Show Gist options
  • Save kylenstone/04a0ec34ff42ca5fde75e986c83ef3b5 to your computer and use it in GitHub Desktop.
Save kylenstone/04a0ec34ff42ca5fde75e986c83ef3b5 to your computer and use it in GitHub Desktop.
Enriching Frame.io comments data with Zapier and Excel Online
import requests
import json
"""
This code demonstrates how to catch Frame.io comments in Zapier
to route them to another app such as Google Docs or Excel.
The following refactors could improve this code:
1. input_data (populated by Zapier) should be presumed to be a comment_id,
not an asset_id. This would simplify the code and reduce API calls.
2. Frame.io API supports query strings to help reduce the required number of round trip requests
when fetching resources. This code is intended to be inserted as one specific Step in a Zap --
moving more of the work into Code would reduce the number of API requests.
Caveats:
- Our comments API returns has_reply = true/false in the comment API payload.
This data is difficult to use in the context of a real-time Zapier integration,
but the same info can be deduced from whether or not a comment has
a parent_id value or a null value. Read the walk_up_asset_tree function for details.
- Helper functions are borrowed from our Python SDK. See for details: https://github.com/Frameio/python-frameio-client
"""
# Testing this script locally you won't have access to Zapier input_data so uncomment here:
# input_data = {
# "asset_id":'<ASSET_ID_HERE>'
# "FIO_TOKEN":'<YOUR_TOKEN_HERE>'
# }
def _api_call(method, endpoint, payload={}):
url = 'http://api.frame.io/v2' + endpoint
headers = {
'Authorization': 'Bearer {}'.format(token)
}
r = requests.request(
method,
url,
json=payload,
headers=headers
)
if r.ok:
return r.json()
return r.raise_for_status()
def get_asset(asset_id):
"""
Get an asset by id.
:Args:
asset_id (string): The asset id.
"""
endpoint = '/assets/{}'.format(asset_id)
return _api_call('get', endpoint)
def get_comment(comment_id, **kwargs):
"""
Get a comment.
:Args:
comment_id (string): The comment id.
"""
endpoint = '/comments/{}'.format(comment_id)
return _api_call('get', endpoint, **kwargs)
def get_comments(self, asset_id, **kwargs):
"""
Get an asset's comments.
:Args:
asset_id (string): The asset id.
"""
endpoint = '/assets/{}/comments'.format(asset_id)
return _api_call('get', endpoint, **kwargs)
def walk_up_asset_tree(asset_id, nested_folder_levels=3, client=None, token=None):
dir_tree = {
}
current = asset_id
cur_level = nested_folder_levels
while cur_level > 0:
try:
parent = get_asset(get_asset(current).get('parent_id'))
if not parent:
raise Exception("Could not get parent for asset {}".format(asset_id))
print("appending folder name {} to tree at level {} for parent ID {}".format(parent.get('name'), cur_level, parent.get('id')))
dir_tree[cur_level] = parent.get('name')
cur_level-=1
current = parent.get('id')
except Exception as e:
print(e)
break
return dir_tree
try:
asset_id = input_data.get('asset_id')
token = input_data.get('FIO_TOKEN')
dir_tree = walk_up_asset_tree(asset_id)
except Exception as e:
print(e)
# Zapier output must be returned as a dict
return dir_tree
@kylenstone
Copy link
Author

Example of what the Zap might look like in Zapier:

Screen Shot 2020-11-24 at 12 03 14 PM

Example of how Task Logs appear in Zapier:

Screen Shot 2020-11-24 at 12 04 28 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment