Summary
Right now, to my knowledge, we have to get items via the filter. I'd like to just get_project("/path/to/project")
Description
I have my own created already but figured I'd make sure this is something that might be of value for others. It might need some clean up in order to fit y'alls standards but like I do something like this.
class myTSC(TSC.Server):
"""A subclass of the tableau server client that adds some functionality"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def get_project(self, path:Union[PurePath, str], parent_id=None, has_cxn:bool=False)->TSC.ProjectItem:
""" gets a project via a path
ARGS:
path - can either be a pathlib.PurePath or a string of the fully scoped path to the project
'/A/B/C' (with or without the root is fine, it will assume root if parent_id is not given)
parent_id - if you already know the parent id, you can pass it in
has_cxn - if you already have a connection (used by the wrapper)
RETURNS:
TSC.ProjectItem - so to get the project id you'd do project.id
EXAMPLE:
> get_project('/path/to/my/project')
> get_project(Path('/path/to/my/project'))
"""
assert isinstance(path, (PurePath, str)), 'path must be Path or string'
parts = Path(path).parts
# we should warn
if parent_id is None:
if not (str(path).startswith('/') or str(path).startswith('\\')):
warn(f"When 'parent_id' is None, 'path' should start with '/' for '{path}'")
elif str(path).startswith('/') or str(path).startswith('\\'):
raise ValueError('parent_id was given but path looks to be a root')
else:
assert isinstance(parent_id, str), "parent_id must be None or string"
if parts[0] in ('\\', '/'): # let people put in a root if they want
parts = parts[1:]
for pp in parts: ## just for through the path parts and go deeper and deeper and check that it exists
project_found = False
for p in TSC.Pager(self.projects):
if p.name == pp and p.parent_id == parent_id:
project = p
parent_id = project.id # setting the parent ID for the next project level
project_found = True
logger.debug(f"Found Project {pp}")
break
if not project_found: # fail if it doesn't find one
raise EndpointUnavailableError('Project "'+'/'.join(parts[:parts.index(pp)+1])+'" Not Found')
return project
new_server = myTSC(server.server_address, use_server_version=True)
with new_server.auth.sign_in(tableau_auth):
project = new_server.get_project(Path('/path/to/my/project'))
Use case
I often have to pull very specific data sources and manipulate them in python. Then push them back up to tableau somewhere else.
This makes the configs for those projects much easier. If there's an easier way to do this I'd also be interested in that.
Summary
Right now, to my knowledge, we have to get items via the filter. I'd like to just
get_project("/path/to/project")Description
I have my own created already but figured I'd make sure this is something that might be of value for others. It might need some clean up in order to fit y'alls standards but like I do something like this.
Use case
I often have to pull very specific data sources and manipulate them in python. Then push them back up to tableau somewhere else.
This makes the configs for those projects much easier. If there's an easier way to do this I'd also be interested in that.