8000 new sample & new feature instructions · jgchavez-cl/server-client-python@818645b · GitHub
[go: up one dir, main page]

8000
Skip to content

Commit 818645b

Browse files
committed
new sample & new feature instructions
Added a new sample (Initialize Server) and added instructions to the readme for how to add new features to the project.
1 parent 114922b commit 818645b

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,13 @@ Move Workbook | [move_workbook_projects.py](./samples/move_workbook_projects.py)
5757
Set HTTP Options | [set_http_options.py](./samples/set_http_options.py) | Sets HTTP options on server and downloads workbooks.
5858
Explore Datasource | [explore_datasource.py](./samples/explore_datasource.py) | Demonstrates working with Tableau Datasource. Queries all datasources, picks one and populates its connections, then updates the datasource. Has additional flags for publish and download.
5959
Explore Workbook | [explore_workbook.py](./samples/explore_workbook.py) | Demonstrates working with Tableau Workbook. Queries all workbooks, picks one and populates its connections/views, then updates the workbook. Has additional flags for publish, download, and getting the preview image. Note: if you don't have permissions on the workbook the script retrieves from the server, the script will result in a 403033 error. This is expected.
60+
Initialize Server | [initialize_server.py](./samples/initialize_server.py) | Shows how to intialize a Tableau Server with datasources and workbooks from the local file system.
61+
62+
63+
64+
###Adding New Features
65+
66+
1. Create an endpoint class for the new feature, following the structure of the other endpoints. Each endpoint usually has get, post, update, and delete operations that require making the url, creating the xml request if necesssary, sending the request and creating the target item object based on the server response.
67+
2. Create an item class for the new feature, following the structure of the other item classes. Each item has properties that correspond to what attributes are sent to/received from the server (refer to docs amd Postman for attributes). Some items also require constants for user input that are limited to specific strings. After making all the properties, make the parsing method that takes the server response and creates an instances of the target item. If the corresponding endpoint class has an update function, then parsing is broken into multiple parts (refer to another item like workbook or datasource for example).
68+
3. Add testing by getting real xml responses from the server, and asserting that all properties are parsed and set correctly.
69+
4. Add samples to show users how to use the new feature.

samples/initialize_server.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
####
2+
# This script sets up a server. It uploads datasources and workbooks from the local filesystem.
3+
#
4+
# By default, all content is published to the Default project on the Default site.
5+
####
6+
7+
import tableauserverclient as TSC
8+
import argparse
9+
import getpass
10+
import logging
11+
import glob
12+
13+
def main():
14+
parser = argparse.ArgumentParser(description='Initialize a server with content.')
15+
parser.add_argument('--server', '-s', required=True, help='server address')
16+
parser.add_argument('--datasources-folder', '-df', required=True, help='folder containing datasources')
17+
parser.add_argument('--workbooks-folder', '-wf', required=True, help='folder containing workbooks')
18+
parser.add_argument('--site', '-si', required=False, default='Default', help='site to use')
19+
parser.add_argument('--project', '-p', required=False, default='Default', help='project to use')
20+
parser.add_argument('--username', '-u', required=True, help='username to sign into server')
21+
parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error',
22+
help='desired logging level (set to error by default)')
23+
args = parser.parse_args()
24+
25+
password = getpass.getpass("Password: ")
26+
27+
# Set logging level based on user input, or error by default
28+
logging_level = getattr(logging, args.logging_level.upper())
29+
logging.basicConfig(level=logging_level)
30+
31+
################################################################################
32+
# Step 1: Sign in to server.
33+
################################################################################
34+
tableau_auth = TSC.TableauAuth(args.username, password)
35+
server = TSC.Server(args.server)
36+
37+
with server.auth.sign_in(tableau_auth):
38+
39+
################################################################################
40+
# Step 2: Create the site we need only if it doesn't exist
41+
################################################################################
42+
print("Checking to see if we need to create the site...")
43+
44+
all_sites, _ = server.sites.get()
45+
existing_site = next((s for s in all_sites if s.name == args.site), None)
46+
47+
# Create the site if it doesn't exist
48+
if existing_site is None:
49+
print("Site not found: {0} Creating it...").format(args.site)
50+
new_site = TSC.SiteItem(name=args.site, content_url=args.site.replace(" ", ""), admin_mode=TSC.SiteItem.AdminMode.ContentAndUsers)
51+
server.sites.create(new_site)
52+
else:
53+
print("Site {0} exists. Moving on...").format(args.site)
54+
55+
56+
################################################################################
57+
# Step 3: Sign-in to our target site
58+
################################################################################
59+
print("Starting our content upload...")
60+
server_upload = TSC.Server(args.server)
61+
tableau_auth.site = args.site
62+
63+
with server_upload.auth.sign_in(tableau_auth):
64+
65+
################################################################################
66+
# Step 4: Create the project we need only if it doesn't exist
67+
################################################################################
68+
all_projects, _ = server_upload.projects.get()
69+
project = next((p for p in all_projects if p.name == args.project), None)
70+
71+
# Create our project if it doesn't exist
72+
if project is None:
73+
print("Project not found: {0} Creating it...").format(args.project)
74+
new_project = TSC.ProjectItem(name=args.project)
75+
project = server_upload.projects.create(new_project)
76+
77+
################################################################################
78+
# Step 5: Set up our content
79+
# Publish datasources to our site and project
80+
# Publish workbooks to our site and project
81+
################################################################################
82+
publish_datasources_to_site(server_upload, project, args.datasources_folder)
83+
publish_workbooks_to_site(server_upload, project, args.workbooks_folder)
84+
85+
def publish_datasources_to_site(server_object, project, folder):
86+
path = folder + '/*.tds*'
87+
88+
for fname in glob.glob(path):
89+
new_ds = TSC.DatasourceItem(project.id)
90+
new_ds = server_object.datasources.publish(new_ds, fname, server_object.PublishMode.Overwrite)
91+
print("Datasource published. ID: {0}".format(new_ds.id))
92+
93+
94+
def publish_workbooks_to_site(server_object, project, folder):
95+
path = folder + '/*.twb*'
96+
97+
for fname in glob.glob(path):
98+
new_workbook = TSC.WorkbookItem(project.id)
99+
new_workbook.show_tabs = True
100+
new_workbook = server_object.workbooks.publish(new_workbook, fname, server_object.PublishMode.Overwrite)
101+
print("Workbook published. ID: {0}".format(new_workbook.id))
102+
103+
104+
if __name__ == "__main__":
105+
main()

0 commit comments

Comments
 (0)
0