View Filters on parameters
Describe the bug Filtering on workbook parameters doesn't work. Current workaround is to use the .vf() method and prepend the filter name with "Parameters."
To Reproduce with server.auth.sign_in(tableau_auth): logger.info(f"Signed in to Tableau Server: {SERVER_URL}") view_item = server.views.get_by_id(VIEW_ID) logger.info(f"Fetched view: {view_item.name} (ID: {view_item.id})")
# Set up image request options
image_req = TSC.ImageRequestOptions()
image_req.vf('Parameters.field_name', 'value')
# Download the image
server.views.populate_image(view_item, image_req)
image_data = view_item.image
Results No error is received
Source code -> def append_view_filters(self, params) -> None: for name, value in self.view_filters: params["vf" + name] = value for name, value in self.view_parameters: params[name] = value
Might need to be -> def append_view_filters(self, params) -> None: for name, value in self.view_filters: params["vf" + name] = value for name, value in self.view_parameters: params["vf_Parameters." + name] = value
Have you tried using .parameters to apply the parameters instead of .vf? .vf is intended for things like quick filters.
Yes and I was unable to successfully get it to work. I had to resort to using .vf and prepending "Parameters." to the name of the parameter. Sorry I shared the work around rather than the code to reproduce.
https://github.com/tableau/server-client-python/blob/master/tableauserverclient/server/request_options.py
this is the current implementation of the class
class _DataExportOptions(RequestOptionsBase):
def __init__(self, maxage: int = -1):
super().__init__()
self.view_filters: list[tuple[str, str]] = []
self.view_parameters: list[tuple[str, str]] = []
self.max_age: Optional[int] = maxage
"""
This setting will affect the contents of the workbook as they are exported.
Valid language values are tableau-supported languages like de, es, en
If no locale is specified, the default locale for that language will be used
"""
self.language: Optional[str] = None
@property
def max_age(self) -> int:
return self._max_age
@max_age.setter
@property_is_int(range=(0, 240), allowed=[-1])
def max_age(self, value):
self._max_age = value
def get_query_params(self):
params = {}
if self.max_age != -1:
params["maxAge"] = self.max_age
if self.language:
params["language"] = self.language
self._append_view_filters(params)
return params
def vf(self, name: str, value: str) -> Self:
"""Apply a filter based on a column within the view.
Note that when filtering on a boolean type field, the only valid values are 'true' and 'false'
For more detail see: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm#Filter-query-views
Parameters
----------
name: str
The name of the column to filter on
value: str
The value to filter on
Returns
-------
Self
The current object
"""
self.view_filters.append((name, value))
return self
def parameter(self, name: str, value: str) -> Self:
"""Apply a filter based on a parameter within the workbook.
Note that when filtering on a boolean type field, the only valid values are 'true' and 'false'
Parameters
----------
name: str
The name of the parameter to filter on
value: str
The value to filter on
Returns
-------
Self
The current object
"""
self.view_parameters.append((name, value))
return self
def _append_view_filters(self, params) -> None:
for name, value in self.view_filters:
params["vf_" + name] = value
for name, value in self.view_parameters:
params[name] = value
i believe changing the final line would fix it
params["vf_Parameters." + name] = value
Thanks @dawilson23. I see the issue now and confirmed the behavior. I will work on a resolution soon.
This shouldn't have changed. What server versions are you seeing it on?
I saw this on 2023.3.8.
Also tested against the 10ax pod of Cloud. Here is the script I used. Verified that it doesn't behave as expected on the development branch, but does with the fixes in #1633
import os
from dotenv import load_dotenv
import tableauserverclient as TSC
load_dotenv()
server = TSC.Server(os.environ["TABLEAU_SERVER"], use_server_version=True)
auth = TSC.PersonalAccessTokenAuth(os.environ["TOKEN_NAME"], os.environ["TOKEN_SECRET"], site_id=os.environ["TABLEAU_SITE"])
with server.auth.sign_in(auth):
view = server.views.filter(name="test", workbook_name="Superstore", project_name="Samples")[0]
opts = TSC.CSVRequestOptions()
opts.parameter("Check", "sent")
server.views.populate_csv(view, opts)
for line in view.csv:
print(line.decode("utf-8").strip())