Table Extension - Full Workflow is Unclear
stephenlprice opened this issue · comments
Environment information:
- OS: macOS Big Sur 11.7.1
- Python version: unknown (deployed with the easy button to Heroku, methods to gather this information are not documented)
- TabPy release: I assume the latest as of today (2.5.0) since it was auto-provisioned via Heroku
Describe the issue
-
I followed the steps for setting up an Analytical Extension on my Tableau Cloud site and Tableau Desktop (Heroku deployment docs are really sparse so I first tried port
9004
(as described here), then I tried port443
since HTTPS is included with this deployment option. Testing the connection in Desktop results in a successful connection response with port443
. At this point, I assume the connectivity to TabPy has been established. -
I then followed the steps to add a Table Extension to a published workbook.
-
Using this example as a reference I started out just importing the dependencies I needed to run my script since the example shows
sklearn
andnumpy
imports without needing to call on a deployed function. However, when I run the script requesting data from the OpenWeather API I get an error response:
An error occurred while communicating with the Analytics Extension data source 'Analytics Extension'
Error Code: 15823CAD
<title>405: Method Not Allowed</title>405: Method Not Allowed
Analytics extension script is invalid
** Questions***
- Do I need to deploy a function to my TabPy instance using
Tabpy Tools
? - Are any packages installed out of the box on every TabPy deployment? If so, what do you think of adding support for commonly used
requests
andpandas
? - If deployed functions are a requirement (understandable), could you provide some language descriptive of this workflow early in the documentation such as in
about.md
rather than buried in the docs forTabpy Tools
? - Where can I find docs explaining how to update python and Tabpy releases for Heroku deployments? Would I have to clone from the Heroku remote and push changes back up?
To Reproduce
Follow the steps described in the above section and then try to run this script in Tableau Desktop without calling on a deployed function:
NOTE: this may not be optimal but it's a quick test. I am sure someone with more pandas
experience can use a normalize function with a few parameters to get the same result. Share feedback if you got any.
def current_weather():
import requests
import pandas as pd
api_key = "API KEY"
# creates a data frame from current weather data
def current(api_key):
payload = rest_current(api_key)
data = transform_current(payload)
return data
# gets current weather data for the specified geolocation
def rest_current(api_key):
url = f'https://api.openweathermap.org/data/2.5/weather?lat=30.2711286&lon=-97.7436995&appid={api_key}'
response = requests.get(url)
payload = response.json()
return payload
# creates a dataframe from the JSON payload with current weather
def transform_current(payload):
# coordinates
coord = payload["coord"]
coord["row"] = 1
coord = pd.DataFrame.from_dict([coord])
# weather results
weather = payload["weather"][0]
del weather["id"]
weather["row"] = 1
weather = pd.DataFrame.from_dict([weather])
# main weather data
main = payload["main"]
main["row"] = 1
main = pd.DataFrame.from_dict([main])
# visibility
visibility = {}
visibility["visibility"] = payload["visibility"]
visibility["row"] = 1
visibility = pd.DataFrame.from_dict([visibility])
# wind
wind = {}
wind["wind speed"] = payload["wind"]["speed"]
wind["wind deg"] = payload["wind"]["deg"]
wind["row"] = 1
wind = pd.DataFrame.from_dict([wind])
# clouds
clouds = {}
clouds["clouds"] = payload["clouds"]["all"]
clouds["row"] = 1
clouds = pd.DataFrame.from_dict([clouds])
# country
country = {}
country["country"] = payload["sys"]["country"]
country["row"] = 1
country = pd.DataFrame.from_dict([country])
# name (city)
name = {}
name["name"] = payload["name"]
name["row"] = 1
name = pd.DataFrame.from_dict([name])
# joins the dataframes into a single row of data
data = pd.merge(coord, weather, left_on='row', right_on='row', sort=False)
data = pd.merge(data, main, left_on='row', right_on='row', sort=False)
data = pd.merge(data, visibility, left_on='row', right_on='row', sort=False)
data = pd.merge(data, wind, left_on='row', right_on='row', sort=False)
data = pd.merge(data, clouds, left_on='row', right_on='row', sort=False)
data = pd.merge(data, country, left_on='row', right_on='row', sort=False)
data = pd.merge(data, name, left_on='row', right_on='row', sort=False)
return data
# runs the workflow
return current(api_key)
Expected behavior
The above script returns a dataframe that can be consumed by Tableau Desktop via a Table Extension and that can then be published to Tableau Cloud configured with the same Analytical Extension.
Additional context
The goal is to test Table Extensions for connectivity to web services via Tableau.
I believe the / should be removed from the hostname. It should be "tableau-tabpy-herokuapp.com" instead of "tableau-tabpy-heroku.com/"