From 9b974e1065435fa33f9d79b108284a7878db7baa Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Wed, 17 Jan 2018 15:51:14 -0800 Subject: [PATCH 001/158] Moving docs out of the docs directory --- .gitignore | 149 ++ Gemfile | 3 + _config.yml | 17 + _includes/analytics.html | 7 + _includes/docs_menu.html | 73 + _includes/footer.html | 8 + _includes/head.html | 18 + _includes/header.html | 29 + _includes/icon-github.svg | 1 + _includes/search_form.html | 7 + _layouts/default.html | 34 + _layouts/docs.html | 31 + _layouts/home.html | 19 + _layouts/search.html | 43 + assets/logo.png | Bin 0 -> 2800 bytes css/api_ref.css | 709 +++++++ css/extra.css | 14 + css/github-highlight.css | 224 ++ css/main.css | 276 +++ docs/api-ref.md | 3070 ++++++++++++++++++++++++++++ docs/dev-guide.md | 96 + docs/filter-sort.md | 90 + docs/index.md | 76 + docs/page-through-results.md | 69 + docs/populate-connections-views.md | 45 + docs/samples.md | 55 + docs/search.md | 5 + docs/sign-in-out.md | 39 + docs/versions.md | 55 + index.md | 13 + js/lunr.min.js | 6 + js/redirect-to-search.js | 13 + js/search.js | 71 + 33 files changed, 5365 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 _config.yml create mode 100644 _includes/analytics.html create mode 100644 _includes/docs_menu.html create mode 100644 _includes/footer.html create mode 100644 _includes/head.html create mode 100644 _includes/header.html create mode 100644 _includes/icon-github.svg create mode 100644 _includes/search_form.html create mode 100644 _layouts/default.html create mode 100644 _layouts/docs.html create mode 100644 _layouts/home.html create mode 100644 _layouts/search.html create mode 100644 assets/logo.png create mode 100644 css/api_ref.css create mode 100644 css/extra.css create mode 100644 css/github-highlight.css create mode 100644 css/main.css create mode 100644 docs/api-ref.md create mode 100644 docs/dev-guide.md create mode 100644 docs/filter-sort.md create mode 100644 docs/index.md create mode 100644 docs/page-through-results.md create mode 100644 docs/populate-connections-views.md create mode 100644 docs/samples.md create mode 100644 docs/search.md create mode 100644 docs/sign-in-out.md create mode 100644 docs/versions.md create mode 100644 index.md create mode 100644 js/lunr.min.js create mode 100644 js/redirect-to-search.js create mode 100644 js/search.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..d7496406b --- /dev/null +++ b/.gitignore @@ -0,0 +1,149 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# PyCharm stuff +.idea/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject + + + +# macOS.gitignore from https://github.com/github/gitignore +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + + +# Windows.gitignore from https://github.com/github/gitignore +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Documentation +docs/_site/ +docs/.jekyll-metadata +docs/Gemfile.lock diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..775d954bf --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' +gem 'github-pages', group: :jekyll_plugins + diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..5ea15f228 --- /dev/null +++ b/_config.yml @@ -0,0 +1,17 @@ +# Site settings +title: Tableau Server Client Library (Python) +email: github@tableau.com +description: Simplify interactions with the Tableau Server REST API. +baseurl: "/server-client-python" +permalinks: pretty +defaults: + - + scope: + path: "" # Apply to all files + values: + layout: "default" + +# Build settings +markdown: kramdown +highlighter: rouge + diff --git a/_includes/analytics.html b/_includes/analytics.html new file mode 100644 index 000000000..0cdbad25d --- /dev/null +++ b/_includes/analytics.html @@ -0,0 +1,7 @@ + + + diff --git a/_includes/docs_menu.html b/_includes/docs_menu.html new file mode 100644 index 000000000..104a1f5b3 --- /dev/null +++ b/_includes/docs_menu.html @@ -0,0 +1,73 @@ +
+ {% include search_form.html %} + +
diff --git a/_includes/footer.html b/_includes/footer.html new file mode 100644 index 000000000..486c81d22 --- /dev/null +++ b/_includes/footer.html @@ -0,0 +1,8 @@ + + diff --git a/_includes/head.html b/_includes/head.html new file mode 100644 index 000000000..083e3f268 --- /dev/null +++ b/_includes/head.html @@ -0,0 +1,18 @@ + + + + + {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} + + + + + + + + + + + + +{% if jekyll.environment == "production" %}{% include analytics.html %}{% endif %} diff --git a/_includes/header.html b/_includes/header.html new file mode 100644 index 000000000..106578dfc --- /dev/null +++ b/_includes/header.html @@ -0,0 +1,29 @@ + diff --git a/_includes/icon-github.svg b/_includes/icon-github.svg new file mode 100644 index 000000000..4422c4f5d --- /dev/null +++ b/_includes/icon-github.svg @@ -0,0 +1 @@ + diff --git a/_includes/search_form.html b/_includes/search_form.html new file mode 100644 index 000000000..41bb34259 --- /dev/null +++ b/_includes/search_form.html @@ -0,0 +1,7 @@ +
+ +
+ diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 000000000..38ee020bb --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,34 @@ + + + + + {% include head.html %} + + + +
+ {% include header.html %} + + {% include footer.html %} +
+ + + diff --git a/_layouts/docs.html b/_layouts/docs.html new file mode 100644 index 000000000..5355f63df --- /dev/null +++ b/_layouts/docs.html @@ -0,0 +1,31 @@ +--- +layout: docs +--- + + + + + + {% include head.html %} + + + +
+ {% include header.html %} + {% include docs_menu.html %} + +
+

{{ page.title }}

+ +
+ {{ content }} + {% include footer.html %} +
+
+ + + diff --git a/_layouts/home.html b/_layouts/home.html new file mode 100644 index 000000000..c2cf32fcb --- /dev/null +++ b/_layouts/home.html @@ -0,0 +1,19 @@ +--- +layout: home +--- + + + + + {% include head.html %} + + + +
+ {% include header.html %} + {{ content }} + {% include footer.html %} +
+ + + diff --git a/_layouts/search.html b/_layouts/search.html new file mode 100644 index 000000000..96dbd94a1 --- /dev/null +++ b/_layouts/search.html @@ -0,0 +1,43 @@ +--- +layout: search +--- + + + + + + {% include head.html %} + + + + + + + +
+ {% include header.html %} + {% include docs_menu.html %} + +
+

+
+
+

Loading search results...

+
+ + {% include footer.html %} +
+
+ + diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..60761152152291896e7b27f94d981fc82e71a2dd GIT binary patch literal 2800 zcmb7GdpuNWA3rk7jj(zc zA_9#@6Cwf+j{N!tppenAD|!*Tt? zar#(2+n89aH%lSV-lRb3+Ff~Q<4W3MbT z@VqTFFgsTxdBECEUTw_=QFxAOl%7~&W%r{p6`lSZYEWfw_N(j+_voCtm@(sQg^ZaR zsIPw<-y$EgstQv?0+7GAo#~0Ybf<5&_#AxMFXwb?)9ujtx3<&f(hsV490=3nB^pAJ zMTU9sKs7)h8oMvf0Qh2Q4X6li#W2BNGXt$=HfdHSpi}0iurAQrwHK3}3Gfe>Z7BX< zq3$f|V$_05hx;%OITN-*535$zVg^snD5$=sNBEW(^)1Yyj%k;vy{wVRpW9#M8}ico z`xoM42SX)!goCAfAkAyd301SblpHR7C55iE*E9iL;}XNM-OoAN8fZ={l9N%*^3B|5 z+V!G$`?J+2lS2Zi$d%7H)4u(#VPVgB&d*}qPUgG#ThLM3Ie<@F!WLyAXzZ~#FYjD+ zIcvcy&*fuR^=SCM2%}Q-v zc6@V!Cjpy)p^eN{4k)7%h1+@LE#?q-XV*rWJ!rK@qaIQK(v4YOFAB7x9QfDe6NM9T z-$s!EQY1{y|L>u^zOJag>xEZBY%Z{hcR3Wh0HoqajIrx=-0Sw7LfNocy;ckD zlN=YnmJy+F`L(I;)F4-+U7OKAJsbV3r2%VZ}eDU0r44YGzvYI}6J8SJ|guC1AP%`f-qACE3fV`|%cn zrm1{UtI64mKbG$DOOHzKkquq?rE8foh%;9Zm5nB+dL)iK+JaZ!U~6g!!hIxBnI&b# z$l_tno&l91PI7OBh3n}-#xAoh>oCc6XWvxt`wJTuf^d(s<}9GdK6Q<@;aQV|ORNy{ zSCSp6KuQ-%D(pXbx-1S)|y2kxwzf%4+Yp1u28EW3orO>jQfZQH*0SGO#V6wj~LH z<)E0yt_=N*&R#lMQ)g8PJQE`8ISv+%*X0_3T9W3rIcWicZqKG%Yk(AR--d?gIh72) z2r+UimAg<>@mA|l^qZc=n4@o@>6*ej!eE54DU+`cUpewrq~Ax-pgA#OG0qwL6UKbl z=eL@fTZ+?e-#8TA!rJd7GLVpNwr!iz;6k09xMrmF4 zt`Smbk^5c}plr=9^O)~g_!J7(`n47)Ylp(22O5Cjh!n;$4dB}~!?dtq_0Gs8N3eQ1 zP17Ubq4G{@a|0!xqt}$?3}}UEp`@G7$sOPMYInvg^IFEIqhj{zM)b;clX8_^($FpV zt<%~0;HRkUMv~TXfd4S@#1#${xvfNjuoX5p@EfZjDDz}~u|v7Nrpl4=zes(cc3LCn9^5yHcG4y0kRne# ztY1!+o3y&qA zttx95Z>yADY4Q91Ulv7;c6mO(mRHs9)^Np*XLpaxze8FIHcYEz0#evG5M-$;1_?3( za|j;>1-mGX;#mPCHLIkrNa>*{o6z_CiqqjK0lkSx&FzkS7Yk+B-62H&(gnE395AbQp4>LZYT`AK6 z;mN3uerOU4Zk;)^D5Po7bTw{9&P-|lK+$M(zbm&!Xc)N6RXFL6Tkw02sw!d+QCar@ z5bLMn&_+=8JJX;%;!;wr(0~AiZc26oNF#=17!(BX|MH;|H80s{HcH;Y$85@-7/*! normalize.css v1.1.3 | MIT License | git.io/normalize */ +/* 2 */ +/* ========================================================================== Tables ========================================================================== */ +/** Remove most spacing between table cells. */ +table { border-collapse: collapse; border-spacing: 0; } + +/* Visual Studio-like style based on original C# coloring by Jason Diamond */ +.hljs { display: inline-block; padding: 0.5em; background: white; color: black; } + +.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket { color: #008000; } + +.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title { color: #00f; } + +.xml .hljs-tag { color: #00f; } +.xml .hljs-tag .hljs-value { color: #00f; } + +.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value { color: #a31515; } + +.ruby .hljs-symbol { color: #a31515; } +.ruby .hljs-symbol .hljs-string { color: #a31515; } + +.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute { color: #a31515; } + +.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt { color: #2b91af; } + +.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag { color: #808080; } + +.vhdl .hljs-typename { font-weight: bold; } +.vhdl .hljs-string { color: #666666; } +.vhdl .hljs-literal { color: #a31515; } +.vhdl .hljs-attribute { color: #00b0e8; } + +.xml .hljs-attribute { color: #f00; } + +.col > :first-child, .col-1 > :first-child, .col-2 > :first-child, .col-3 > :first-child, .col-4 > :first-child, .col-5 > :first-child, .col-6 > :first-child, .col-7 > :first-child, .col-8 > :first-child, .col-9 > :first-child, .col-10 > :first-child, .col-11 > :first-child, .tsd-panel > :first-child, ul.tsd-descriptions > li > :first-child, .col > :first-child > :first-child, .col-1 > :first-child > :first-child, .col-2 > :first-child > :first-child, .col-3 > :first-child > :first-child, .col-4 > :first-child > :first-child, .col-5 > :first-child > :first-child, .col-6 > :first-child > :first-child, .col-7 > :first-child > :first-child, .col-8 > :first-child > :first-child, .col-9 > :first-child > :first-child, .col-10 > :first-child > :first-child, .col-11 > :first-child > :first-child, .tsd-panel > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child, .col > :first-child > :first-child > :first-child, .col-1 > :first-child > :first-child > :first-child, .col-2 > :first-child > :first-child > :first-child, .col-3 > :first-child > :first-child > :first-child, .col-4 > :first-child > :first-child > :first-child, .col-5 > :first-child > :first-child > :first-child, .col-6 > :first-child > :first-child > :first-child, .col-7 > :first-child > :first-child > :first-child, .col-8 > :first-child > :first-child > :first-child, .col-9 > :first-child > :first-child > :first-child, .col-10 > :first-child > :first-child > :first-child, .col-11 > :first-child > :first-child > :first-child, .tsd-panel > :first-child > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child > :first-child { margin-top: 0; } +.col > :last-child, .col-1 > :last-child, .col-2 > :last-child, .col-3 > :last-child, .col-4 > :last-child, .col-5 > :last-child, .col-6 > :last-child, .col-7 > :last-child, .col-8 > :last-child, .col-9 > :last-child, .col-10 > :last-child, .col-11 > :last-child, .tsd-panel > :last-child, ul.tsd-descriptions > li > :last-child, .col > :last-child > :last-child, .col-1 > :last-child > :last-child, .col-2 > :last-child > :last-child, .col-3 > :last-child > :last-child, .col-4 > :last-child > :last-child, .col-5 > :last-child > :last-child, .col-6 > :last-child > :last-child, .col-7 > :last-child > :last-child, .col-8 > :last-child > :last-child, .col-9 > :last-child > :last-child, .col-10 > :last-child > :last-child, .col-11 > :last-child > :last-child, .tsd-panel > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child, .col > :last-child > :last-child > :last-child, .col-1 > :last-child > :last-child > :last-child, .col-2 > :last-child > :last-child > :last-child, .col-3 > :last-child > :last-child > :last-child, .col-4 > :last-child > :last-child > :last-child, .col-5 > :last-child > :last-child > :last-child, .col-6 > :last-child > :last-child > :last-child, .col-7 > :last-child > :last-child > :last-child, .col-8 > :last-child > :last-child > :last-child, .col-9 > :last-child > :last-child > :last-child, .col-10 > :last-child > :last-child > :last-child, .col-11 > :last-child > :last-child > :last-child, .tsd-panel > :last-child > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child > :last-child { margin-bottom: 0; } + +@media (max-width: 640px) { .container { padding: 0 20px; } } + +.container-main { padding-bottom: 200px; } + +.row { position: relative; margin: 0 -10px; } +.row:after { visibility: hidden; display: block; content: ""; clear: both; height: 0; } + +.col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11 { box-sizing: border-box; float: left; padding: 0 10px; } + +.col-1 { width: 8.33333%; } + +.offset-1 { margin-left: 8.33333%; } + +.col-2 { width: 16.66667%; } + +.offset-2 { margin-left: 16.66667%; } + +.col-3 { width: 25%; } + +.offset-3 { margin-left: 25%; } + +.col-4 { width: 33.33333%; } + +.offset-4 { margin-left: 33.33333%; } + +.col-5 { width: 41.66667%; } + +.offset-5 { margin-left: 41.66667%; } + +.col-6 { width: 50%; } + +.offset-6 { margin-left: 50%; } + +.col-7 { width: 58.33333%; } + +.offset-7 { margin-left: 58.33333%; } + +.col-8 { width: 66.66667%; } + +.offset-8 { margin-left: 66.66667%; } + +.col-9 { width: 75%; } + +.offset-9 { margin-left: 75%; } + +.col-10 { width: 83.33333%; } + +.offset-10 { margin-left: 83.33333%; } + +.col-11 { width: 91.66667%; } + +.offset-11 { margin-left: 91.66667%; } + +.tsd-kind-icon { display: block; position: relative; padding-left: 20px; text-indent: -20px; } +.tsd-kind-icon:before { content: ''; display: inline-block; vertical-align: middle; width: 17px; height: 17px; margin: 0 3px 2px 0; background-image: url(data:image/png;base64,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); } +@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-kind-icon:before { background-image: url(data:image/png;base64,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); background-size: 238px 204px; } } + +.tsd-signature.tsd-kind-icon:before { background-position: 0 -153px; } + +.tsd-kind-object-literal > .tsd-kind-icon:before { background-position: 0px -17px; } +.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -17px; } +.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -17px; } + +.tsd-kind-class > .tsd-kind-icon:before { background-position: 0px -34px; } +.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -34px; } +.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -34px; } + +.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -51px; } +.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -51px; } +.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -51px; } + +.tsd-kind-interface > .tsd-kind-icon:before { background-position: 0px -68px; } +.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -68px; } +.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -68px; } + +.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -85px; } +.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -85px; } +.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -85px; } + +.tsd-kind-module > .tsd-kind-icon:before { background-position: 0px -102px; } +.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; } +.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; } + +.tsd-kind-external-module > .tsd-kind-icon:before { background-position: 0px -102px; } +.tsd-kind-external-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; } +.tsd-kind-external-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; } + +.tsd-kind-enum > .tsd-kind-icon:before { background-position: 0px -119px; } +.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -119px; } +.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -119px; } + +.tsd-kind-enum-member > .tsd-kind-icon:before { background-position: 0px -136px; } +.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -136px; } +.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -136px; } + +.tsd-kind-signature > .tsd-kind-icon:before { background-position: 0px -153px; } +.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -153px; } +.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -153px; } + +.tsd-kind-type-alias > .tsd-kind-icon:before { background-position: 0px -170px; } +.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -170px; } +.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -170px; } + +.tsd-kind-variable > .tsd-kind-icon:before { background-position: -136px -0px; } +.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; } +.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; } +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; } +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; } +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; } +.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; } +.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; } +.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; } +.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; } + +.tsd-kind-property > .tsd-kind-icon:before { background-position: -136px -0px; } +.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; } +.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; } +.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; } +.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; } +.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; } +.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; } +.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; } +.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; } +.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; } +.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; } + +.tsd-kind-get-signature > .tsd-kind-icon:before { background-position: -136px -17px; } +.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -17px; } +.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -17px; } +.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -17px; } + +.tsd-kind-set-signature > .tsd-kind-icon:before { background-position: -136px -34px; } +.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -34px; } +.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -34px; } +.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -34px; } + +.tsd-kind-accessor > .tsd-kind-icon:before { background-position: -136px -51px; } +.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -51px; } +.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; } +.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -51px; } +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -51px; } +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -51px; } +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -51px; } +.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; } +.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -51px; } +.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -51px; } +.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; } +.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -51px; } +.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -51px; } + +.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -68px; } +.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; } +.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; } +.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; } +.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; } +.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; } +.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; } +.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; } +.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; } +.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; } + +.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -68px; } +.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; } +.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; } +.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; } +.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; } +.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; } +.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; } +.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; } +.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; } +.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; } + +.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -68px; } +.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; } +.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; } +.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; } + +.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; } +.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; } + +.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; } +.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; } + +.tsd-kind-constructor > .tsd-kind-icon:before { background-position: -136px -102px; } +.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; } +.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; } +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; } +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; } +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; } +.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; } +.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; } +.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; } +.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; } + +.tsd-kind-constructor-signature > .tsd-kind-icon:before { background-position: -136px -102px; } +.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; } +.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; } +.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; } + +.tsd-kind-index-signature > .tsd-kind-icon:before { background-position: -136px -119px; } +.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -119px; } +.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -119px; } +.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -119px; } + +.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -136px; } +.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -136px; } +.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; } +.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -136px; } +.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -136px; } +.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -136px; } +.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -136px; } +.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; } +.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -136px; } +.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -136px; } +.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; } +.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -136px; } +.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -136px; } + +.tsd-is-static > .tsd-kind-icon:before { background-position: -136px -153px; } +.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -153px; } +.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; } +.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -153px; } +.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -153px; } +.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -153px; } +.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -153px; } +.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; } +.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -153px; } +.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -153px; } +.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; } +.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -153px; } +.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -153px; } + +.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -170px; } +.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; } +.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; } +.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; } + +.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -170px; } +.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; } +.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; } +.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; } + +.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; } +.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; } + +.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -187px; } +.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -187px; } +.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -187px; } +.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -187px; } + +.no-transition { -webkit-transition: none !important; transition: none !important; } + +@-webkit-keyframes fade-in { + from { opacity: 0; } + to { opacity: 1; } } + +@keyframes fade-in { from { opacity: 0; } + to { opacity: 1; } } +@-webkit-keyframes fade-out { + from { opacity: 1; visibility: visible; } + to { opacity: 0; } } +@keyframes fade-out { from { opacity: 1; visibility: visible; } + to { opacity: 0; } } +@-webkit-keyframes fade-in-delayed { + 0% { opacity: 0; } + 33% { opacity: 0; } + 100% { opacity: 1; } } +@keyframes fade-in-delayed { 0% { opacity: 0; } + 33% { opacity: 0; } + 100% { opacity: 1; } } +@-webkit-keyframes fade-out-delayed { + 0% { opacity: 1; visibility: visible; } + 66% { opacity: 0; } + 100% { opacity: 0; } } +@keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; } + 66% { opacity: 0; } + 100% { opacity: 0; } } +@-webkit-keyframes shift-to-left { + from { -webkit-transform: translate(0, 0); transform: translate(0, 0); } + to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } } +@keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); } + to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } } +@-webkit-keyframes unshift-to-left { + from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } + to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } } +@keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } + to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } } +@-webkit-keyframes pop-in-from-right { + from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } + to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } } +@keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } + to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } } +@-webkit-keyframes pop-out-to-right { + from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; } + to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } } +@keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; } + to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } } + +.tsd-typography { line-height: 1.333em; } +.tsd-typography ul { list-style: square; padding: 0 0 0 20px; margin: 0; } +.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 { font-size: 1em; margin: 0; } +.tsd-typography h5, .tsd-typography h6 { font-weight: normal; } +.tsd-typography p, .tsd-typography ul, .tsd-typography ol { margin: 1em 0; } + +@media (min-width: 901px) and (max-width: 1024px) { html.default .col-content { width: 72%; } + html.default .col-menu { width: 28%; } + html.default .tsd-navigation { padding-left: 10px; } } +@media (max-width: 900px) { html.default .col-content { float: none; width: 100%; } + html.default .col-menu { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; z-index: 1024; top: 0 !important; bottom: 0 !important; left: auto !important; right: 0 !important; width: 100%; padding: 20px 20px 0 0; max-width: 450px; visibility: hidden; background-color: #fff; -webkit-transform: translate(100%, 0); -ms-transform: translate(100%, 0); transform: translate(100%, 0); } + html.default .col-menu > *:last-child { padding-bottom: 20px; } + html.default .overlay { content: ""; display: block; position: fixed; z-index: 1023; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.75); visibility: hidden; } + html.default.to-has-menu .overlay { -webkit-animation: fade-in 0.4s; animation: fade-in 0.4s; } + html.default.to-has-menu header, html.default.to-has-menu footer, html.default.to-has-menu .col-content { -webkit-animation: shift-to-left 0.4s; animation: shift-to-left 0.4s; } + html.default.to-has-menu .col-menu { -webkit-animation: pop-in-from-right 0.4s; animation: pop-in-from-right 0.4s; } + html.default.from-has-menu .overlay { -webkit-animation: fade-out 0.4s; animation: fade-out 0.4s; } + html.default.from-has-menu header, html.default.from-has-menu footer, html.default.from-has-menu .col-content { -webkit-animation: unshift-to-left 0.4s; animation: unshift-to-left 0.4s; } + html.default.from-has-menu .col-menu { -webkit-animation: pop-out-to-right 0.4s; animation: pop-out-to-right 0.4s; } + html.default.has-menu body { overflow: hidden; } + html.default.has-menu .overlay { visibility: visible; } + html.default.has-menu header, html.default.has-menu footer, html.default.has-menu .col-content { -webkit-transform: translate(-25%, 0); -ms-transform: translate(-25%, 0); transform: translate(-25%, 0); } + html.default.has-menu .col-menu { visibility: visible; -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); transform: translate(0, 0); } } + +.tsd-page-title { padding: 70px 0 20px 0; margin: 0 0 40px 0; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); } +.tsd-page-title h1 { margin: 0; } + +.tsd-breadcrumb { margin: 0; padding: 0; color: #808080; } +.tsd-breadcrumb a { color: #808080; text-decoration: none; } +.tsd-breadcrumb a:hover { text-decoration: underline; } +.tsd-breadcrumb li { display: inline; } +.tsd-breadcrumb li:after { content: " / "; } + +html.minimal .container-main { padding-bottom: 0; } +html.minimal .content-wrap { padding-left: 340px; } +html.minimal .tsd-navigation { position: fixed !important; float: left; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; box-sizing: border-box; z-index: 1; top: 60px; bottom: 0; width: 300px; padding: 20px; margin: 0; } +html.minimal .tsd-member .tsd-member { margin-left: 0; } +html.minimal .tsd-page-toolbar { position: fixed; z-index: 2; } +html.minimal #tsd-filter .tsd-filter-group { right: 0; -webkit-transform: none; -ms-transform: none; transform: none; } +html.minimal footer { background-color: transparent; } +html.minimal footer .container { padding: 0; } +html.minimal .tsd-generator { padding: 0; } +@media (max-width: 900px) { html.minimal .tsd-navigation { display: none; } + html.minimal .content-wrap { padding-left: 0; } } + +dl.tsd-comment-tags { overflow: hidden; } +dl.tsd-comment-tags dt { clear: both; float: left; padding: 1px 5px; margin: 0 10px 0 0; border-radius: 4px; border: 1px solid #808080; color: #808080; font-size: 0.8em; font-weight: normal; } +dl.tsd-comment-tags dd { margin: 0 0 10px 0; } +dl.tsd-comment-tags p { margin: 0; } + +.tsd-panel.tsd-comment .lead { font-size: 1.1em; line-height: 1.333em; margin-bottom: 2em; } +.tsd-panel.tsd-comment .lead:last-child { margin-bottom: 0; } + +.toggle-protected .tsd-is-private { display: none; } + +.toggle-public .tsd-is-private, .toggle-public .tsd-is-protected, .toggle-public .tsd-is-private-protected { display: none; } + +.toggle-inherited .tsd-is-inherited { display: none; } + +.toggle-only-exported .tsd-is-not-exported { display: none; } + +.toggle-externals .tsd-is-external { display: none; } + +#tsd-filter { position: relative; display: inline-block; height: 40px; vertical-align: bottom; } +.no-filter #tsd-filter { display: none; } +#tsd-filter .tsd-filter-group { display: inline-block; height: 40px; vertical-align: bottom; white-space: nowrap; } +#tsd-filter input { display: none; } +@media (max-width: 900px) { #tsd-filter .tsd-filter-group { display: block; position: absolute; top: 40px; right: 20px; height: auto; background-color: #fff; visibility: hidden; -webkit-transform: translate(50%, 0); -ms-transform: translate(50%, 0); transform: translate(50%, 0); box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); } + .has-options #tsd-filter .tsd-filter-group { visibility: visible; } + .to-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-in 0.2s; animation: fade-in 0.2s; } + .from-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-out 0.2s; animation: fade-out 0.2s; } + #tsd-filter label, #tsd-filter .tsd-select { display: block; padding-right: 20px; } } + +footer { background-color: #fff; } +footer.with-border-bottom { border-bottom: 1px solid #eee; margin-left: 20px } +footer .tsd-legend-group { font-size: 0; } +footer .tsd-legend { display: inline-block; width: 25%; padding: 0; font-size: 16px; list-style: none; line-height: 1.333em; vertical-align: top; } +@media (max-width: 900px) { footer .tsd-legend { width: 50%; } } + +.tsd-hierarchy { list-style: square; padding: 0 0 0 20px; margin: 0; } +.tsd-hierarchy .target { font-weight: bold; } + +.tsd-index-panel .tsd-index-content { margin-bottom: -30px !important; } +.tsd-index-panel .tsd-index-section { margin-bottom: 30px !important; } +.tsd-index-panel h3 { margin: 0 -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; } +.tsd-index-panel ul.tsd-index-list { -webkit-column-count: 3; -moz-column-count: 3; -ms-column-count: 3; column-count: 3; -webkit-column-gap: 20px; -moz-column-gap: 20px; -ms-column-gap: 20px; column-gap: 20px; padding: 0; list-style: none; line-height: 1.333em; } +@media (max-width: 900px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 1; -moz-column-count: 1; -ms-column-count: 1; column-count: 1; } } +@media (min-width: 901px) and (max-width: 1024px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 2; -moz-column-count: 2; -ms-column-count: 2; column-count: 2; } } +.tsd-index-panel ul.tsd-index-list li { -webkit-column-break-inside: avoid; -moz-column-break-inside: avoid; -ms-column-break-inside: avoid; -o-column-break-inside: avoid; column-break-inside: avoid; -webkit-page-break-inside: avoid; -moz-page-break-inside: avoid; -ms-page-break-inside: avoid; -o-page-break-inside: avoid; page-break-inside: avoid; } +.tsd-index-panel a, .tsd-index-panel .tsd-parent-kind-module a { color: #9600ff; } +.tsd-index-panel .tsd-parent-kind-interface a { color: #7da01f; } +.tsd-index-panel .tsd-parent-kind-enum a { color: #cc9900; } +.tsd-index-panel .tsd-parent-kind-class a { color: #4da6ff; } +.tsd-index-panel .tsd-kind-module a { color: #9600ff; } +.tsd-index-panel .tsd-kind-interface a { color: #7da01f; } +.tsd-index-panel .tsd-kind-enum a { color: #cc9900; } +.tsd-index-panel .tsd-kind-class a { color: #4da6ff; } +.tsd-index-panel .tsd-is-private a { color: #808080; } + +.tsd-flag { display: inline-block; padding: 1px 5px; border-radius: 4px; color: #fff; background-color: #808080; text-indent: 0; font-size: 14px; font-weight: normal; } + +.tsd-anchor { position: absolute; top: -100px; } + +.tsd-member { position: relative; } +.tsd-member .tsd-anchor + h3 { margin-top: 0; margin-bottom: 0; border-bottom: none; } + +.tsd-navigation { padding: 0 0 0 40px; } +.tsd-navigation a { display: block; padding-top: 2px; padding-bottom: 2px; border-left: 2px solid transparent; color: #222; text-decoration: none; -webkit-transition: border-left-color 0.1s; transition: border-left-color 0.1s; } +.tsd-navigation a:hover { text-decoration: underline; } +.tsd-navigation ul { margin: 0; padding: 0; list-style: none; } +.tsd-navigation li { padding: 0; } + +.tsd-navigation.primary { padding-bottom: 40px; } +.tsd-navigation.primary a { display: block; padding-top: 6px; padding-bottom: 6px; } +.tsd-navigation.primary ul li a { padding-left: 5px; } +.tsd-navigation.primary ul li li a { padding-left: 25px; } +.tsd-navigation.primary ul li li li a { padding-left: 45px; } +.tsd-navigation.primary ul li li li li a { padding-left: 65px; } +.tsd-navigation.primary ul li li li li li a { padding-left: 85px; } +.tsd-navigation.primary ul li li li li li li a { padding-left: 105px; } +.tsd-navigation.primary > ul { border-bottom: 1px solid #eee; } +.tsd-navigation.primary li { border-top: 1px solid #eee; } +.tsd-navigation.primary li.current > a { font-weight: bold; } +.tsd-navigation.primary li.label span { display: block; padding: 20px 0 6px 5px; color: #808080; } +.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a { padding-top: 20px; } + +.tsd-navigation.secondary ul { -webkit-transition: opacity 0.2s; transition: opacity 0.2s; } +.tsd-navigation.secondary ul li a { padding-left: 25px; } +.tsd-navigation.secondary ul li li a { padding-left: 45px; } +.tsd-navigation.secondary ul li li li a { padding-left: 65px; } +.tsd-navigation.secondary ul li li li li a { padding-left: 85px; } +.tsd-navigation.secondary ul li li li li li a { padding-left: 105px; } +.tsd-navigation.secondary ul li li li li li li a { padding-left: 125px; } +.tsd-navigation.secondary ul.current a { border-left-color: #eee; } +.tsd-navigation.secondary li.focus > a, .tsd-navigation.secondary ul.current li.focus > a { border-left-color: #000; } +.tsd-navigation.secondary li.current { margin-top: 20px; margin-bottom: 20px; border-left-color: #eee; } +.tsd-navigation.secondary li.current > a { font-weight: bold; } + +@media (min-width: 901px) { .menu-sticky-wrap { position: static; } + .no-csspositionsticky .menu-sticky-wrap.sticky { position: fixed; } + .no-csspositionsticky .menu-sticky-wrap.sticky-current { position: fixed; } + .no-csspositionsticky .menu-sticky-wrap.sticky-current ul.before-current, .no-csspositionsticky .menu-sticky-wrap.sticky-current ul.after-current { opacity: 0; } + .no-csspositionsticky .menu-sticky-wrap.sticky-bottom { position: absolute; top: auto !important; left: auto !important; bottom: 0; right: 0; } + .csspositionsticky .menu-sticky-wrap.sticky { position: -webkit-sticky; position: sticky; } + .csspositionsticky .menu-sticky-wrap.sticky-current { position: -webkit-sticky; position: sticky; } } + +.tsd-panel { margin: 20px 0; padding: 20px; background-color: #fff; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); } +.tsd-panel:empty { display: none; } +.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 { margin: 1.5em -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; } +.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature { margin-bottom: 0; border-bottom: 0; } +.tsd-panel table { display: block; width: 100%; overflow: auto; margin-top: 10px; word-break: normal; word-break: keep-all; } +.tsd-panel table th { font-weight: bold; } +.tsd-panel table th, .tsd-panel table td { padding: 6px 13px; border: 1px solid #ddd; } +.tsd-panel table tr { background-color: #fff; border-top: 1px solid #ccc; } +.tsd-panel table tr:nth-child(2n) { background-color: #f8f8f8; } + +.tsd-panel-group { margin: 30px 0; } +.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 { padding-left: 20px; padding-right: 20px; } + +#tsd-search { -webkit-transition: background-color 0.2s; transition: background-color 0.2s; } +#tsd-search .title { position: relative; z-index: 2; } +#tsd-search .field { position: absolute; left: 0; top: 0; right: 40px; height: 40px; } +#tsd-search .field input { box-sizing: border-box; position: relative; top: -50px; z-index: 1; width: 100%; padding: 0 10px; opacity: 0; outline: 0; border: 0; background: transparent; color: #222; } +#tsd-search .field label { position: absolute; overflow: hidden; right: -40px; } +#tsd-search .field input, #tsd-search .title { -webkit-transition: opacity 0.2s; transition: opacity 0.2s; } +#tsd-search .results { position: absolute; visibility: hidden; top: 40px; width: 100%; margin: 0; padding: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); } +#tsd-search .results li { padding: 0 10px; background-color: #fdfdfd; } +#tsd-search .results li:nth-child(even) { background-color: #fff; } +#tsd-search .results li.state { display: none; } +#tsd-search .results li.current, #tsd-search .results li:hover { background-color: #eee; } +#tsd-search .results a { display: block; } +#tsd-search .results a:before { top: 10px; } +#tsd-search .results span.parent { color: #808080; font-weight: normal; } +#tsd-search.has-focus { background-color: #eee; } +#tsd-search.has-focus .field input { top: 0; opacity: 1; } +#tsd-search.has-focus .title { z-index: 0; opacity: 0; } +#tsd-search.has-focus .results { visibility: visible; } +#tsd-search.loading .results li.state.loading { display: block; } +#tsd-search.failure .results li.state.failure { display: block; } + +.tsd-signature { margin: 0 0 1em 0; padding: 10px; border: 1px solid #eee; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; } +.tsd-signature.tsd-kind-icon { padding-left: 30px; } +.tsd-signature.tsd-kind-icon:before { top: 10px; left: 10px; } +.tsd-panel > .tsd-signature { margin-left: -20px; margin-right: -20px; border-width: 1px 0; } +.tsd-panel > .tsd-signature.tsd-kind-icon { padding-left: 40px; } +.tsd-panel > .tsd-signature.tsd-kind-icon:before { left: 20px; } + +.tsd-signature-symbol { color: #808080; font-weight: normal; } + +.tsd-signature-type { font-style: italic; font-weight: normal; } + +.tsd-signatures { padding: 0; margin: 0 0 1em 0; border: 1px solid #eee; } +.tsd-signatures .tsd-signature { margin: 0; border-width: 1px 0 0 0; -webkit-transition: background-color 0.1s; transition: background-color 0.1s; } +.tsd-signatures .tsd-signature:first-child { border-top-width: 0; } +.tsd-signatures .tsd-signature.current { background-color: #eee; } +.tsd-signatures.active > .tsd-signature { cursor: pointer; } +.tsd-panel > .tsd-signatures { margin-left: -20px; margin-right: -20px; border-width: 1px 0; } +.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { padding-left: 40px; } +.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { left: 20px; } +.tsd-panel > a.anchor + .tsd-signatures { border-top-width: 0; margin-top: -20px; } + +ul.tsd-descriptions { position: relative; overflow: hidden; -webkit-transition: height 0.3s; transition: height 0.3s; padding: 0; list-style: none; } +ul.tsd-descriptions.active > .tsd-description { display: none; } +ul.tsd-descriptions.active > .tsd-description.current { display: block; } +ul.tsd-descriptions.active > .tsd-description.fade-in { -webkit-animation: fade-in-delayed 0.3s; animation: fade-in-delayed 0.3s; } +ul.tsd-descriptions.active > .tsd-description.fade-out { -webkit-animation: fade-out-delayed 0.3s; animation: fade-out-delayed 0.3s; position: absolute; display: block; top: 0; left: 0; right: 0; opacity: 0; visibility: hidden; } +ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 { font-size: 16px; margin: 1em 0 0.5em 0; } + +ul.tsd-parameters, ul.tsd-type-parameters { list-style: square; margin: 0; padding-left: 20px; } +ul.tsd-parameters > li.tsd-parameter-siganture, ul.tsd-type-parameters > li.tsd-parameter-siganture { list-style: none; margin-left: -20px; } +ul.tsd-parameters h5, ul.tsd-type-parameters h5 { font-size: 16px; margin: 1em 0 0.5em 0; } +ul.tsd-parameters .tsd-comment, ul.tsd-type-parameters .tsd-comment { margin-top: -0.5em; } + +.tsd-sources { font-size: 14px; color: #808080; margin: 0 0 1em 0; } +.tsd-sources a { color: #808080; text-decoration: underline; } +.tsd-sources ul, .tsd-sources p { margin: 0 !important; } +.tsd-sources ul { list-style: none; padding: 0; } + +.tsd-page-toolbar { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 40px; color: #333; background: #fff; border-bottom: 1px solid #eee; } +.tsd-page-toolbar a { color: #333; text-decoration: none; } +.tsd-page-toolbar a.title { font-weight: bold; } +.tsd-page-toolbar a.title:hover { text-decoration: underline; } +.tsd-page-toolbar .table-wrap { display: table; width: 100%; height: 40px; } +.tsd-page-toolbar .table-cell { display: table-cell; position: relative; white-space: nowrap; line-height: 40px; } +.tsd-page-toolbar .table-cell:first-child { width: 100%; } + +.tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { content: ""; display: inline-block; width: 40px; height: 40px; margin: 0 -8px 0 0; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAAoCAQAAAAlSeuiAAABp0lEQVR4Ae3aUa3jQAyF4QNhIBTCQiiEQlgIhRAGhTAQBkIgBEIgDITZZGXNjZTePiSWYqn/54dGfbAq+SiTutWXAgAAAAAAAAAAAAA8NCz1UFSD2lKDS5d3NVzZj/BVNasaLoRZRUmj2lLrVVHWMUntQ13Wj/i1pWa9lprX6xMRnH4dx6Rjsn26+v+12ms+EcB37P0r+qH+DNQGXgMFcHzbregQ78B8eQCTJk0e979ZW7PdA2O49ceDsYexKgUNoI3EKYDWL3D8miaPh/uXtl6BHqEHFQvgXau/FsCiIWAAbST2fpQRT0sl70j3z5ZiBdD7CG5WZX8kxwmgjbiP5GQA9/3O2XaxnnHi53AEE0AbRh+JQwC3/fzC4hcb6xPvS4i3QaMdwX+0utsRPEY6gm2wNhKHAG77eUi7SIcK4G4NY4GMIan2u2Cxqzncl5DUn7Q8ArjvZ8JFOsl/Ed0jyBom+BomQKSto+9PcblHMM4iuu4X0QQw5hrGQY/gUxFkjZuf4m4alXVU+1De/VhEn5CvDSB/RsBzqWgAAAAAAAAAAAAAAACAfyyYJ5nhVuwIAAAAAElFTkSuQmCC); background-repeat: no-repeat; text-indent: -1024px; vertical-align: bottom; } +@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAABQCAMAAAC+sjQXAAAAM1BMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjBUbJAAAAEXRSTlMA3/+/UCBw7xCPYIBAMM+vn1qYQ7QAAALCSURBVHgB7MGBAAAAAICg/akXqQIAAAAAAAAAAAAAAAAAAJids9mdE4bhoDNZCITP93/aSmhV/9uwPWyi8jtkblws2IxsYpz9LwSAaJW8AreE16PxOsMYE6Q4DiYKF7X+8ZHXc/E608xv5snEyIuZrVwMZjbnujR6T3gsXmcLOIRNzD+Ig2UuVtt2+NbAiX/wVLzOlviD9L2BOfGBlL/3D1I+uDjGBJArBPxU3x+K15kCQFo2s21JAOHrKpz4SPrWv4IKA+uFaR6vMwMcb+emA2DWEfDglrkLqEBOKVslA8Dx14oPMiV4CtywWxdQgAwkq2QE0uTXUwJGk2G9s3mTFNBzAkC7HKPsX72AEVjMnAWIpsPCRRjXdQxcjCYpoOcEgHY5Rtk/slWSgM3M2aSeeVgjAOeVpKcdgGMdNAXMuIAqOcZzqF8L+WcAsi8wkTeheCWMegL6mgCorHHyEJ5TVfxrLWDrTUjZdhnhjYqAnlN8TaoELOLVC0gucmoz/3RKcPs2jAs4+J5ET8AEZF+TSgGLeC1V8YuGQQU2IV1Asq9JCwE9XitZVPxr34bpJRj8PqsFLOK108W9aVrWZRrR7Sm2HL4JCToCujHZ6gUs4jUz0P1TEvD+U5wMa363YeziBODIq1YbJrsv9QKW8Ry1nNp+GAHvuingRTfmYcjBf0QpAS37bdUL6PFKtHJq63EsZ5cxcKMkDVIClu1dAK1PcJ5TFQ0M9wZKDCPs3BD7MIJGTs3WfiTfDVQYx5q5ZekCauTU3P5Q0ukGCgh49oFURdobWBY9N/CxEuwGjpGLuPhTdwH1x7HqDDxNgRP2zQ8lraFyF/yJ9vH6QGqtgSbBOU8/j2VORz+Wqfle2d5Ae4R+ML0z7Y+W4P7XHN3AU+tzyK/24EAGAAAAYJC/9T2+CgAAAAAAAAAAAAAAAAAAAADgJpfzHyIKFFBKAAAAAElFTkSuQmCC); background-size: 320px 40px; } } + +.tsd-widget { display: inline-block; overflow: hidden; opacity: 0.6; height: 40px; -webkit-transition: opacity 0.1s, background-color 0.2s; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; } +.tsd-widget:hover { opacity: 0.8; } +.tsd-widget.active { opacity: 1; background-color: #eee; } +.tsd-widget.no-caption { width: 40px; } +.tsd-widget.no-caption:before { margin: 0; } +.tsd-widget.search:before { background-position: 0 0; } +.tsd-widget.menu:before { background-position: -40px 0; } +.tsd-widget.options:before { background-position: -80px 0; } +.tsd-widget.options, .tsd-widget.menu { display: none; } +@media (max-width: 900px) { .tsd-widget.options, .tsd-widget.menu { display: inline-block; } } +input[type=checkbox] + .tsd-widget:before { background-position: -120px 0; } +input[type=checkbox]:checked + .tsd-widget:before { background-position: -160px 0; } + +.tsd-select { position: relative; display: inline-block; height: 40px; -webkit-transition: opacity 0.1s, background-color 0.2s; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; } +.tsd-select .tsd-select-label { opacity: 0.6; -webkit-transition: opacity 0.2s; transition: opacity 0.2s; } +.tsd-select .tsd-select-label:before { background-position: -240px 0; } +.tsd-select.active .tsd-select-label { opacity: 0.8; } +.tsd-select.active .tsd-select-list { visibility: visible; opacity: 1; -webkit-transition-delay: 0s; transition-delay: 0s; } +.tsd-select .tsd-select-list { position: absolute; visibility: hidden; top: 40px; left: 0; margin: 0; padding: 0; opacity: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -webkit-transition: visibility 0s 0.2s, opacity 0.2s; transition: visibility 0s 0.2s, opacity 0.2s; } +.tsd-select .tsd-select-list li { padding: 0 20px 0 0; background-color: #fdfdfd; } +.tsd-select .tsd-select-list li:before { background-position: 40px 0; } +.tsd-select .tsd-select-list li:nth-child(even) { background-color: #fff; } +.tsd-select .tsd-select-list li:hover { background-color: #eee; } +.tsd-select .tsd-select-list li.selected:before { background-position: -200px 0; } +@media (max-width: 900px) { .tsd-select .tsd-select-list { top: 0; left: auto; right: 100%; margin-right: -5px; } + .tsd-select .tsd-select-label:before { background-position: -280px 0; } } diff --git a/css/extra.css b/css/extra.css new file mode 100644 index 000000000..804bb597f --- /dev/null +++ b/css/extra.css @@ -0,0 +1,14 @@ +pre code { + white-space: pre; + word-wrap: normal; + display: block; + padding: 12px; + font-size: 14px; +} + +code { + white-space: pre-wrap; + word-wrap: break-word; + padding: 2px 5px; + font-size: 16px; +} diff --git a/css/github-highlight.css b/css/github-highlight.css new file mode 100644 index 000000000..52b18879c --- /dev/null +++ b/css/github-highlight.css @@ -0,0 +1,224 @@ +pre { + border: none !important; + background-color: #fff !important; +} +code { + color: inherit !important; + background-color: #fff; +} +pre, code { + white-space: pre !important; +} +.highlight table pre { margin: 0; } +.highlight .cm { + color: #999988; + font-style: italic; +} +.highlight .cp { + color: #999999; + font-weight: bold; +} +.highlight .c1 { + color: #999988; + font-style: italic; +} +.highlight .cs { + color: #999999; + font-weight: bold; + font-style: italic; +} +.highlight .c, .highlight .cd { + color: #999988; + font-style: italic; +} +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} +.highlight .ge { + color: #000000; + font-style: italic; +} +.highlight .gr { + color: #aa0000; +} +.highlight .gh { + color: #999999; +} +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} +.highlight .go { + color: #888888; +} +.highlight .gp { + color: #555555; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gu { + color: #aaaaaa; +} +.highlight .gt { + color: #aa0000; +} +.highlight .kc { + color: #000000; + font-weight: bold; +} +.highlight .kd { + color: #000000; + font-weight: bold; +} +.highlight .kn { + color: #000000; + font-weight: bold; +} +.highlight .kp { + color: #000000; + font-weight: bold; +} +.highlight .kr { + color: #000000; + font-weight: bold; +} +.highlight .kt { + color: #445588; + font-weight: bold; +} +.highlight .k, .highlight .kv { + color: #000000; + font-weight: bold; +} +.highlight .mf { + color: #009999; +} +.highlight .mh { + color: #009999; +} +.highlight .il { + color: #009999; +} +.highlight .mi { + color: #009999; +} +.highlight .mo { + color: #009999; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #009999; +} +.highlight .sb { + color: #d14; +} +.highlight .sc { + color: #d14; +} +.highlight .sd { + color: #d14; +} +.highlight .s2 { + color: #d14; +} +.highlight .se { + color: #d14; +} +.highlight .sh { + color: #d14; +} +.highlight .si { + color: #d14; +} +.highlight .sx { + color: #d14; +} +.highlight .sr { + color: #009926; +} +.highlight .s1 { + color: #d14; +} +.highlight .ss { + color: #990073; +} +.highlight .s { + color: #d14; +} +.highlight .na { + color: #008080; +} +.highlight .bp { + color: #999999; +} +.highlight .nb { + color: #0086B3; +} +.highlight .nc { + color: #445588; + font-weight: bold; +} +.highlight .no { + color: #008080; +} +.highlight .nd { + color: #3c5d5d; + font-weight: bold; +} +.highlight .ni { + color: #800080; +} +.highlight .ne { + color: #990000; + font-weight: bold; +} +.highlight .nf { + color: #990000; + font-weight: bold; +} +.highlight .nl { + color: #990000; + font-weight: bold; +} +.highlight .nn { + color: #555555; +} +.highlight .nt { + color: #000080; +} +.highlight .vc { + color: #008080; +} +.highlight .vg { + color: #008080; +} +.highlight .vi { + color: #008080; +} +.highlight .nv { + color: #008080; +} +.highlight .ow { + color: #000000; + font-weight: bold; +} +.highlight .o { + color: #000000; + font-weight: bold; +} +.highlight .w { + color: #bbbbbb; +} +.highlight { + background-color: #fff; + padding-bottom: 0px; +} +.highlighter-rouge { + border: 1px solid #ccc; + margin-bottom: 1em; +} diff --git a/css/main.css b/css/main.css new file mode 100644 index 000000000..05fd446ec --- /dev/null +++ b/css/main.css @@ -0,0 +1,276 @@ +/* General CSS */ +@import url(https://fonts.googleapis.com/css?family=Open+Sans); + +body { + font-family: "Open Sans", Helvetica, Arial, sans-serif; +} + +img { + max-width: 90%; +} + +/* Custom CSS for home page */ +.hero-spacer { + margin-top: 50px; +} + +.hero-feature { + margin-bottom: 30px; +} + +.blog-content-wrap { + margin-top: 20px; + padding-top: 40px; +} + +/* Custom CSS for the docs */ + +.edit-links { + color: #cccccc; +} + +/* Prevent in-page links from scrolling under top nav */ +h2::before, h3::before { + display: block; + content: " "; + margin-top: -80px; + height: 80px; + visibility: hidden; +} + +/* Custom CSS for header and footer */ +.site-header +{ + width: 100%; + padding: 24px 0px; +} + +img.logo +{ + height: 28px; + margin-left: -18px; +} + +.icon > svg +{ + display: inline-block; + width: 28px; + height: 28px; +} + +.icon > svg path +{ + fill: #333333; +} + + +.thumb-home { + height: 340px; +} + +.img-home { + height: 150px !important; + margin: 10px; +} + +.tableauIcon { + margin-left: 18px; +} + +.jumbotron { + background-color: #fafafa; + border: 1px solid #e8e8e8; +} + +#community-jumbo { + background-color: #F0F8FF; +} + +footer { + margin: 30px 0; + text-align: center; +} + +.footer-hr { + width: 100%; + position: relative; +} + +table { + border: 1px solid #c2c2c2; + border-collapse: collapse; + margin: 1em 0px; +} + +th +{ + font-weight: bold; + border: 1px solid #c2c2c2; + text-align: left; + padding: .3em; + vertical-align: top; + background-color: #fafafa; +} + +td +{ + border: 1px solid #c2c2c2; + text-align: left; + padding: .3em; + vertical-align: top; +} + +/* So the scroll bar width doesn't cause the page to jump */ +html { + overflow-y: scroll; +} + +.label { + margin-right: 3px; +} + +/* to get right navbar icons to respect collapse */ +@media (max-width: 992px) { + .navbar-header { + float: none; + } + .navbar-left,.navbar-right { + float: none !important; + } + .navbar-toggle { + display: block; + } + .navbar-collapse { + border-top: 1px solid transparent; + box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); + } + .navbar-fixed-top { + top: 0; + border-width: 0 0 1px; + } + .navbar-collapse.collapse { + display: none!important; + } + .navbar-nav { + float: none!important; + margin-top: 7.5px; + } + .navbar-nav>li { + float: none; + } + .navbar-nav>li>a { + padding-top: 10px; + padding-bottom: 10px; + } + .collapse.in{ + display:block !important; + } +} + + +/* Custom css for news section */ +.blog-content { + margin-bottom: 70px; +} + +.blogul { + padding: 0px; +} + +.blogul h1 { + margin-top: 40px; +} + +.blog-content > h4 { + margin-top: 20px; +} + +.blog-content > ol { + margin-bottom: 20px; +} + + +/* Community connectors */ +.thumbnail { + background-color: #fff; + border: 1px solid #ccc; + margin: 12px; +} + +.thumbnail h2 { + border-left: 2px solid #337ab7; + text-decoration: none; + font-size: 20px; + padding: 6px; + margin-left: 10px; +} + +.thumbnail h2 a { + text-decoration: none; + color: #333333; +} + +.well { + background-color: #ffffff; + margin-bottom: 40px; +} + +.tsd-navigation { + padding: 10px !important; +} + +/* Media queries for responsive design */ +#grid[data-columns]::before { + content: '3 .column.size-1of3'; +} + +.column { float: left; } +.size-1of3 { width: 33.333%; } + + +@media screen and (max-width: 767px) { + #grid[data-columns]::before { + content: '1 .column.size-1of1'; + } + + /* Docs Menu*/ + .docs-menu, .tsd-navigation { + top: 20px; + position: relative; + } + +} +@media screen and (min-width: 769px) { + #grid[data-columns]::before { + content: '3 .column.size-1of3'; + } + + /* Docs Menu*/ + .docs-menu, .tsd-navigation { + position: fixed; + overflow: auto; + top: 90px; + max-height: 90%; + max-width: 250px; + } + + .content { + position: relative; + margin: 40px 0px 0px 275px; + max-width: 1000px; + } + + /* API Reference */ + + .ref-content { + margin: 40px 0px 0px 275px; + max-width: 1000px; + } +} + +.column { float: left; } +.size-1of1 { width: 100%; } +.size-1of2 { width: 50%; } +.size-1of3 { width: 33.333%; } + + diff --git a/docs/api-ref.md b/docs/api-ref.md new file mode 100644 index 000000000..d0ac648d1 --- /dev/null +++ b/docs/api-ref.md @@ -0,0 +1,3070 @@ +--- +title: API reference +layout: docs +--- + +
+ Important: More coming soon! This section is under active construction and might not reflect all the available functionality of the TSC library. + +
+ + + +The Tableau Server Client (TSC) is a Python library for the Tableau Server REST API. Using the TSC library, you can manage and change many of the Tableau Server and Tableau Online resources programmatically. You can use this library to create your own custom applications. + +The TSC API reference is organized by resource. The TSC library is modeled after the REST API. The methods, for example, `workbooks.get()`, correspond to the endpoints for resources, such as [workbooks](#workbooks), [users](#users), [views](#views), and [data sources](#data-sources). The model classes (for example, the [WorkbookItem class](#workbookitem-class) have attributes that represent the fields (`name`, `id`, `owner_id`) that are in the REST API request and response packages, or payloads. + +|:--- | +| **Note:** Some methods and features provided in the REST API might not be currently available in the TSC library (and in some cases, the opposite is true). In addition, the same limitations apply to the TSC library that apply to the REST API with respect to resources on Tableau Server and Tableau Online. For more information, see the [Tableau Server REST API Reference](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#API_Reference%3FTocPath%3DAPI%2520Reference%7C_____0){:target="_blank"}.| + + + +* TOC +{:toc } + +
+
+ + +## Authentication + +You can use the TSC library to sign in and sign out of Tableau Server and Tableau Online. The credentials for signing in are defined in the `TableauAuth` class and they correspond to the attributes you specify when you sign in using the Tableau Server REST API. + +
+
+ +### TableauAuth class + +```py +TableauAuth(username, password, site_id='', user_id_to_impersonate=None) +``` +The `TableauAuth` class defines the information you can set in a sign-in request. The class members correspond to the attributes of a server request or response payload. To use this class, create a new instance, supplying user name, password, and site information if necessary, and pass the request object to the [Auth.sign_in](#auth.sign-in) method. + + + **Note:** In the future, there might be support for additional forms of authorization and authentication (for example, OAuth). + +**Attributes** + +Name | Description +:--- | :--- +`username` | The name of the user whose credentials will be used to sign in. +`password` | The password of the user. +`site_id` | This corresponds to the `contentUrl` attribute in the Tableau REST API. The `site_id` is the portion of the URL that follows the `/site/` in the URL. For example, "MarketingTeam" is the `site_id` in the following URL *MyServer*/#/site/**MarketingTeam**/projects. To specify the default site on Tableau Server, you can use an empty string `''` (single quotes, no space). For Tableau Online, you must provide a value for the `site_id`. +`user_id_to_impersonate` | Specifies the id (not the name) of the user to sign in as. + +Source file: models/tableau_auth.py + +**Example** + +```py +import tableauserverclient as TSC +# create a new instance of a TableauAuth object for authentication + +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL') + +# create a server instance +# pass the "tableau_auth" object to the server.auth.sign_in() method +``` + +
+
+ +### Auth methods +The Tableau Server Client provides two methods for interacting with authentication resources. These methods correspond to the sign in and sign out endpoints in the Tableau Server REST API. + + +Source file: server/endpoint/auth_endpoint.py + +
+
+ +#### auth.sign in + +```py +auth.sign_in(auth_req) +``` + +Signs you in to Tableau Server. + + +The method signs into Tableau Server or Tableau Online and manages the authentication token. You call this method from the server object you create. For information about the server object, see [Server](#server). The authentication token keeps you signed in for 240 minutes, or until you call the `auth.sign_out` method. Before you use this method, you first need to create the sign-in request (`auth_req`) object by creating an instance of the `TableauAuth`. To call this method, create a server object for your server. For more information, see [Sign in and Out](sign-in-out). + +REST API: [Sign In](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Sign_In%3FTocPath%3DAPI%2520Reference%7C_____77){:target="_blank"} + +**Parameters** + +`auth_req` : The `TableauAuth` object that holds the sign-in credentials for the site. + + +**Example** + +```py +import tableauserverclient as TSC + +# create an auth object +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') + +# create an instance for your server +server = TSC.Server('http://SERVER_URL') + +# call the sign-in method with the auth object +server.auth.sign_in(tableau_auth) + +``` + + +**See Also** +[Sign in and Out](sign-in-out) +[Server](#server) + +
+
+ + +#### auth.sign out + +```py +auth.sign_out() +``` +Signs you out of the current session. + +The `sign_out()` method takes care of invalidating the authentication token. For more information, see [Sign in and Out](sign-in-out). + +REST API: [Sign Out](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Sign_Out%3FTocPath%3DAPI%2520Reference%7C_____78){:target="_blank"} + +**Example** + +```py + +server.auth.sign_out() + + +``` + + + + +**See Also** +[Sign in and Out](sign-in-out) +[Server](#server) + +
+
+ + + + +## Connections + +The connections for Tableau Server data sources and workbooks are represented by a `ConnectionItem` class. You can call data source and workbook methods to query or update the connection information. The `ConnectionCredentials` class represents the connection information you can update. + +### ConnectionItem class + +```py +ConnectionItem() +``` + +The `ConnectionItem` class corresponds to workbook and data source connections. + +In the Tableau Server REST API, there are separate endpoints to query and update workbook and data source connections. + +**Attributes** + +Name | Description + :--- | : --- +`datasource_id` | The identifier of the data source. +`datasource_name` | The name of the data source. +`id` | The identifier of the connection. +`connection_type` | The type of connection. +`username` | The username for the connection. +`password` | The password used for the connection. +`embed_password` | (Boolean) Determines whether to embed the password (`True`) for the workbook or data source connection or not (`False`). +`server_address` | The server address for the connection. +`server_port` | The port used for the connection. + +Source file: models/connection_item.py + +
+
+ + + +### ConnectionCredentials class + +```py +ConnectionCredentials(name, password, embed=True, oauth=False) +``` + + +The `ConnectionCredentials` class is used for workbook and data source publish requests. + + + +**Attributes** + +Attribute | Description +:--- | :--- +`name` | The username for the connection. +`embed_password` | (Boolean) Determines whether to embed the passowrd (`True`) for the workbook or data source connection or not (`False`). +`password` | The password used for the connection. +`server_address` | The server address for the connection. +`server_port` | The port used by the server. +`ouath` | (Boolean) Specifies whether OAuth is used for the data source of workbook connection. For more information, see [OAuth Connections](https://onlinehelp.tableau.com/current/server/en-us/protected_auth.htm?Highlight=oauth%20connections){:target="_blank"}. + + +Source file: models/connection_credentials.py + +
+
+ +## Data sources + +Using the TSC library, you can get all the data sources on a site, or get the data sources for a specific project. +The data source resources for Tableau Server are defined in the `DatasourceItem` class. The class corresponds to the data source resources you can access using the Tableau Server REST API. For example, you can gather information about the name of the data source, its type, its connections, and the project it is associated with. The data source methods are based upon the endpoints for data sources in the REST API and operate on the `DatasourceItem` class. + +
+ +### DatasourceItem class + +```py +DatasourceItem(project_id, name=None) +``` + +The `DatasourceItem` represents the data source resources on Tableau Server. This is the information that can be sent or returned in the response to an REST API request for data sources. When you create a new `DatasourceItem` instance, you must specify the `project_id` that the data source is associated with. + +**Attributes** + +Name | Description +:--- | :--- +`connections` | The list of data connections (`ConnectionItem`) for the specified data source. You must first call the `populate_connections` method to access this data. See the [ConnectionItem class](#connectionitem-class). +`content_url` | The name of the data source as it would appear in a URL. +`created_at` | The date and time when the data source was created. +`datasource_type` | The type of data source, for example, `sqlserver` or `excel-direct`. +`id` | The identifier for the data source. You need this value to query a specific data source or to delete a data source with the `get_by_id` and `delete` methods. +`name` | The name of the data source. If not specified, the name of the published data source file is used. +`project_id` | The identifier of the project associated with the data source. When you must provide this identifier when create an instance of a `DatasourceItem` +`project_name` | The name of the project associated with the data source. +`tags` | The tags that have been added to the data source. +`updated_at` | The date and time when the data source was last updated. + + +**Example** + +```py + import tableauserverclient as TSC + + # Create new datasource_item with project id '3a8b6148-493c-11e6-a621-6f3499394a39' + + new_datasource = TSC.DatasourceItem('3a8b6148-493c-11e6-a621-6f3499394a39') +``` + + +Source file: models/datasource_item.py + +
+
+ +### Datasources methods + +The Tableau Server Client provides several methods for interacting with data source resources, or endpoints. These methods correspond to endpoints in the Tableau Server REST API. + +Source file: server/endpoint/datasources_endpoint.py + +
+
+ +#### datasources.delete + +```py +datasources.delete(datasource_id) +``` + +Removes the specified data source from Tableau Server. + + +**Parameters** + +Name | Description +:--- | :--- +`datasource_id` | The identifier (`id`) for the `DatasourceItem` that you want to delete from the server. + + +**Exceptions** + +Error | Description + :--- | : --- +`Datasource ID undefined` | Raises an exception if a valid `datasource_id` is not provided. + + +REST API: [Delete Datasource](http://onlinehelp.tableau.com/v0.0/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Datasource%3FTocPath%3DAPI%2520Reference%7C_____19){:target="_blank"} + +
+
+ + +#### datasources.download + +```py +datasources.download(datasource_id, filepath=None, no_extract=False) + +``` +Downloads the specified data source in `.tdsx` format. + +REST API: [Download Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Download_Datasource%3FTocPath%3DAPI%2520Reference%7C_____34){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`datasource_id` | The identifier (`id`) for the `DatasourceItem` that you want to download from the server. +`filepath` | (Optional) Downloads the file to the location you specify. If no location is specified (the default is `Filepath=None`), the file is downloaded to the current working directory. +`no_extract` | (Optional) Specifies whether to download the file without the extract. When the data source has an extract, if you set the parameter `no_extract=True`, the extract is not included. You can use this parameter to improve performance if you are downloading data sources that have large extracts. The default is to include the extract, if present (`no_extract=False`). Available starting with Tableau Server REST API version 2.5. + +**Exceptions** + +Error | Description +:--- | :--- +`Datasource ID undefined` | Raises an exception if a valid `datasource_id` is not provided. + + +**Returns** + +The file path to the downloaded data source. The data source is downloaded in `.tdsx` format. + +**Example** + +```py + + file_path = server.datasources.download('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') + print("\nDownloaded the file to {0}.".format(file_path)) + +```` + + +
+
+ +#### datasources.get + +```py +datasources.get(req_options=None) +``` + +Returns all the data sources for the site. + +To get the connection information for each data source, you must first populate the `DatasourceItem` with connection information using the [populate_connections(*datasource_item*)](#populate-connections-datasource) method. For more information, see [Populate Connections and Views](populate-connections-views#populate-connections-for-data-sources) + +REST API: [Query Datasources](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasources%3FTocPath%3DAPI%2520Reference%7C_____49){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific data source, you could specify the name of the project or its id. + + +**Returns** + +Returns a list of `DatasourceItem` objects and a `PaginationItem` object. Use these values to iterate through the results. + + + + +**Example** + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('http://SERVERURL') + +with server.auth.sign_in(tableau_auth): + all_datasources, pagination_item = server.datasources.get() + print("\nThere are {} datasources on site: ".format(pagination_item.total_available)) + print([datasource.name for datasource in all_datasources]) +```` + + + +
+
+ + +#### datasources.get_by_id + +```py +datasources.get_by_id(datasource_id) +``` + +Returns the specified data source item. + +REST API: [Query Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource%3FTocPath%3DAPI%2520Reference%7C_____46){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`datasource_id` | The `datasource_id` specifies the data source to query. + + +**Exceptions** + +Error | Description +:--- | :--- +`Datasource ID undefined` | Raises an exception if a valid `datasource_id` is not provided. + + +**Returns** + +The `DatasourceItem`. See [DatasourceItem class](#datasourceitem-class) + + +**Example** + +```py + +datasource = server.datasources.get_by_id('59a57c0f-3905-4022-9e87-424fb05e9c0e') +print(datasource.name) + +``` + + +
+
+ + + +#### datasources.populate_connections + +```py +datasources.populate_connections(datasource_item) +``` + +Populates the connections for the specified data source. + +This method retrieves the connection information for the specified data source. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the connection information is not included. Use this method to retrieve the connections. The method adds the list of data connections to the data source item (`datasource_item.connections`). This is a list of `ConnectionItem` objects. + +REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource_Connections%3FTocPath%3DAPI%2520Reference%7C_____47){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`datasource_item` | The `datasource_item` specifies the data source to populate with connection information. + + + + +**Exceptions** + +Error | Description +:--- | :--- +`Datasource item missing ID. Datasource must be retrieved from server first.` | Raises an error if the datasource_item is unspecified. + + +**Returns** + +None. A list of `ConnectionItem` objects are added to the data source (`datasource_item.connections`). + + +**Example** + +```py +# import tableauserverclient as TSC + +# server = TSC.Server('http://SERVERURL') +# + ... + +# get the data source + datasource = server.datasources.get_by_id('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') + + +# get the connection information + server.datasources.populate_connections(datasource) + +# print the information about the first connection item + print(datasource.connections[0].connection_type) + print(datasource.connections[0].id) + print(datasource.connections[0].server_address) + + ... + +``` + +
+
+ +#### datasources.publish + +```py +datasources.publish(datasource_item, file_path, mode, connection_credentials=None) +``` + +Publishes a data source to a server, or appends data to an existing data source. + +This method checks the size of the data source and automatically determines whether the publish the data source in multiple parts or in one opeation. + +REST API: [Publish Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Datasource%3FTocPath%3DAPI%2520Reference%7C_____44){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`datasource_item` | The `datasource_item` specifies the new data source you are adding, or the data source you are appending to. If you are adding a new data source, you need to create a new `datasource_item` with a `project_id` of an existing project. The name of the data source will be the name of the file, unless you also specify a name for the new data source when you create the instance. See [DatasourceItem](#datasourceitem-class). +`file_path` | The path and name of the data source to publish. +`mode` | Specifies whether you are publishing a new data source (`CreateNew`), overwriting an existing data source (`Overwrite`), or appending data to a data source (`Append`). If you are appending to a data source, the data source on the server and the data source you are publishing must be be extracts (.tde files) and they must share the same schema. You can also use the publish mode attributes, for example: `TSC.Server.PublishMode.Overwrite`. +`connection_credentials` | (Optional) The credentials required to connect to the data source. The `ConnectionCredentials` object contains the authentication information for the data source (user name and password, and whether the credentials are embeded or OAuth is used). + + + +**Exceptions** + +Error | Description +:--- | :--- +`File path does not lead to an existing file.` | Raises an error of the file path is incorrect or if the file is missing. +`Invalid mode defined.` | Raises an error if the publish mode is not one of the defined options. +`Only .tds, tdsx, or .tde files can be published as datasources.` | Raises an error if the type of file specified is not supported. + + +**Returns** + +The `DatasourceItem` for the data source that was added or appended to. + + +**Example** + +```py + + import tableauserverclient as TSC + server = TSC.Server('http://SERVERURL') + + ... + + project_id = '3a8b6148-493c-11e6-a621-6f3499394a39' + file_path = r'C:\temp\WorldIndicators.tde' + + + # Use the project id to create new datsource_item + new_datasource = TSC.DatasourceItem(project_id) + + # publish data source (specified in file_path) + new_datasource = server.datasources.publish( + new_datasource, file_path, 'CreateNew') + + ... +``` + +
+
+ +#### datasources.update + +```py +datasource.update(datasource_item) +``` + +Updates the owner, or project of the specified data source. + +REST API: [Update Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Datasource%3FTocPath%3DAPI%2520Reference%7C_____79){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`datasource_item` | The `datasource_item` specifies the data source to update. + + + +**Exceptions** + +Error | Description + :--- | : --- +`Datasource item missing ID. Datasource must be retrieved from server first.` | Raises an error if the datasource_item is unspecified. Use the `Datasources.get()` method to retrieve that identifies for the data sources on the server. + + +**Returns** + +An updated `DatasourceItem`. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://SERVERURL') +# sign in ... + +# get the data source item to update + datasource = server.datasources.get_by_id('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') + +# do some updating + datasource.name = 'New Name' + +# call the update method with the data source item + updated_datasource = server.datasources.update(datasource) + + + +``` + + + +
+
+ +## Filters + +The TSC library provides a `Filter` class that you can use to filter results returned from the server. + +You can use the `Filter` and `RequestOptions` classes to filter and sort the following endpoints: + +- Users +- Datasources +- Workbooks +- Views + +For more information, see [Filter and Sort](filter-sort). + + +### Filter class + +```py +Filter(field, operator, value) +``` + +The `Filter` class corresponds to the *filter expressions* in the Tableau REST API. + + + +**Attributes** + +Name | Description +:--- | :--- +`Field` | Defined in the `RequestOptions.Field` class. +`Operator` | Defined in the `RequestOptions.Operator` class +`Value` | The value to compare with the specified field and operator. + + + + + +
+
+ + +## Groups + +Using the TSC library, you can get information about all the groups on a site, you can add or remove groups, or add or remove users in a group. + +The group resources for Tableau Server are defined in the `GroupItem` class. The class corresponds to the group resources you can access using the Tableau Server REST API. The group methods are based upon the endpoints for groups in the REST API and operate on the `GroupItem` class. + +
+
+ +### GroupItem class + +```py +GroupItem(name) +``` + +The `GroupItem` class contains the attributes for the group resources on Tableau Server. The `GroupItem` class defines the information you can request or query from Tableau Server. The class members correspond to the attributes of a server request or response payload. + +Source file: models/group_item.py + +**Attributes** + +Name | Description +:--- | :--- +`domain_name` | The name of the Active Directory domain (`local` if local authentication is used). +`id` | The id of the group. +`users` | The list of users (`UserItem`). +`name` | The name of the group. The `name` is required when you create an instance of a group. + + + +**Example** + +```py + newgroup = TSC.GroupItem('My Group') + + # call groups.create() with new group +``` + + + + +
+
+ +### Groups methods + +The Tableau Server Client provides several methods for interacting with group resources, or endpoints. These methods correspond to endpoints in the Tableau Server REST API. + + + +Source file: server/endpoint/groups_endpoint.py + +
+
+ +#### groups.add_user + +```py +groups.add_user(group_item, user_id): +``` + +Adds a user to the specified group. + + +REST API [Add User to Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Add_User_to_Group%3FTocPath%3DAPI%2520Reference%7C_____8){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`group_item` | The `group_item` specifies the group to update. +`user_id` | The id of the user. + + + + +**Returns** + +None. + + +**Example** + +```py +# Adding a user to a group +# +# get the group item + all_groups, pagination_item = server.groups.get() + mygroup = all_groups[1] + +# The id for Ian is '59a8a7b6-be3a-4d2d-1e9e-08a7b6b5b4ba' + +# add Ian to the group + server.groups.add_user(mygroup, '59a8a7b6-be3a-4d2d-1e9e-08a7b6b5b4ba') + + + +``` + +
+
+ +#### groups.create + +```py +create(group_item) +``` + +Creates a new group in Tableau Server. + + +REST API: [Create Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Group%3FTocPath%3DAPI%2520Reference%7C_____14){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`group_item` | The `group_item` specifies the group to add. You first create a new instance of a `GroupItem` and pass that to this method. + + + + +**Returns** +Adds new `GroupItem`. + + +**Example** + +```py + +# Create a new group + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + +# create a new instance with the group name + newgroup = TSC.GroupItem('My Group') + +# call the create method + newgroup = server.groups.create(newgroup) + +# print the names of the groups on the server + all_groups, pagination_item = server.groups.get() + for group in all_groups : + print(group.name, group.id) +``` + +
+
+ +#### groups.delete + +```py +groups.delete(group_id) +``` + +Deletes the group on the site. + +REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Site%3FTocPath%3DAPI%2520Reference%7C_____74){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`group_id` | The identifier (`id`) for the group that you want to remove from the server. + + +**Exceptions** + +Error | Description +:--- | :--- +`Group ID undefined` | Raises an exception if a valid `group_id` is not provided. + + +**Example** + +```py +# Delete a group from the site + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + server.groups.delete('1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d') + +``` +
+
+ +#### groups.get + +```py +groups.get(req_options=None) +``` + +Returns information about the groups on the site. + + +To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulateusers) method. + + +REST API: [Get Uers on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_on_Site%3FTocPath%3DAPI%2520Reference%7C_____41){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific group, you could specify the name of the group or the group id. + + +**Returns** + +Returns a list of `GroupItem` objects and a `PaginationItem` object. Use these values to iterate through the results. + + +**Example** + + +```py +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + + # get the groups on the server + all_groups, pagination_item = server.groups.get() + + # print the names of the first 100 groups + for group in all_groups : + print(group.name, group.id) +```` + + +
+
+ +#### groups.populate_users + +```py +groups.populate_users(group_item, req_options=None) +``` + +Populates the `group_item` with the list of users. + + +REST API: [Get Users in Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_in_Group){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`group_item` | The `group_item` specifies the group to populate with user information. +`req_options` | (Optional) Additional request options to send to the endpoint. + + + +**Exceptions** + +`Group item missing ID. Group must be retrieved from server first.` : Raises an error if the `group_item` is unspecified. + + +**Returns** + +None. A list of `UserItem` objects are added to the group (`group_item.users`). + + +**Example** + +```py +# import tableauserverclient as TSC + +# server = TSC.Server('http://SERVERURL') +# + ... + +# get the group + all_groups, pagination_item = server.groups.get() + mygroup = all_groups[1] + +# get the user information + pagination_item = server.groups.populate_users(mygroup) + + +# print the names of the users + for user in mygroup.users : + print(user.name) + + + + +``` + +
+
+ +#### groups.remove_user + +```py +groups.remove_user(group_item, user_id) +``` + +Removes a user from a group. + + + + +REST API: [Remove User from Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Group%3FTocPath%3DAPI%2520Reference%7C_____73){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`group_item` | The `group_item` specifies the group to remove the user from. +`user_id` | The id for the user. + + + +**Exceptions** + +Error | Description +:--- | :--- +`Group must be populated with users first.` | Raises an error if the `group_item` is unpopulated. + + +**Returns** + +None. The user is removed from the group. + + +**Example** + +```py +# Remove a user from the group + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + + # get the group + mygroup = server.groups.get_by_id('1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d') + + # remove user '9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d' + server.groups.remove_user(mygroup, '9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + +``` + +
+
+ + + +## Projects + +Using the TSC library, you can get information about all the projects on a site, or you can create, update projects, or remove projects. + +The project resources for Tableau are defined in the `ProjectItem` class. The class corresponds to the project resources you can access using the Tableau Server REST API. The project methods are based upon the endpoints for projects in the REST API and operate on the `ProjectItem` class. + + + + + +
+ +### ProjectItem class + +```py + +ProjectItem(name, description=None, content_permissions=None) + +``` +The project resources for Tableau are defined in the `ProjectItem` class. The class corresponds to the project resources you can access using the Tableau Server REST API. + +**Attributes** + +Name | Description +:--- | :--- +`content_permissions` | Sets or shows the permissions for the content in the project. The options are either `LockedToProject` or `ManagedByOwner`. +`name` | Name of the project. +`description` | The description of the project. +`id` | The project id. + + + +Source file: models/project_item.py + + +#### ProjectItem.ContentPermissions + +The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"} + +Name | Description +:--- | :--- +`ProjectItem.ContentPermissions.LockedToProject` | Locks all content permissions to the project. +`ProjectItem.ContentPermissions.ManagedByOwner` | Users can manage permissions for content that they own. This is the default. + +**Example** + +```py + +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc + + +locked_true = TSC.ProjectItem.ContentPermissions.LockedToProject +print(locked_true) +# prints 'LockedToProject' + +by_owner = TSC.ProjectItem.ContentPermissions.ManagedByOwner +print(by_owner) +# prints 'ManagedByOwner' + + +# pass the content_permissions to new instance of the project item. +new_project = TSC.ProjectItem(name='My Project', content_permissions=by_owner, description='Project example') + +``` + +
+
+ +### Project methods + +The project methods are based upon the endpoints for projects in the REST API and operate on the `ProjectItem` class. + + +Source files: server/endpoint/projects_endpoint.py + +
+
+ + +#### projects.create + +```py +projects.create(project_item) +``` + + +Creates a project on the specified site. + +To create a project, you first create a new instance of a `ProjectItem` and pass it to the create method. To specify the site to create the new project, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). + + +REST API: [Create Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`project_item` | Specifies the properties for the project. The `project_item` is the request package. To create the request package, create a new instance of `ProjectItem`. + + +**Returns** +Returns the new project item. + + + +**Example** + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL') +server = TSC.Server('http://SERVER') + +with server.auth.sign_in(tableau_auth): + # create project item + new_project = TSC.ProjectItem(name='Example Project', content_permissions='LockedToProject', description='Project created for testing') + # create the project + new_project = server.projects.create(new_project) + +``` + +
+
+ + +#### projects.get + +```py +projects.get() + +``` + +Return a list of project items for a site. + + +To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). + +REST API: [Query Projects](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Projects%3FTocPath%3DAPI%2520Reference%7C_____55){:target="_blank"} + + +**Parameters** + +None. + +**Returns** + +Returns a list of all `ProjectItem` objects and a `PaginationItem`. Use these values to iterate through the results. + + + + **Example** + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL') +server = TSC.Server('http://SERVER') + +with server.auth.sign_in(tableau_auth): + # get all projects on site + all_project_items, pagination_item = server.projects.get() + print([proj.name for proj in all_project_items]) + +``` + +
+
+ + +#### projects.update + +```py +projects.update(project_item) +``` + +Modify the project settings. + +You can use this method to update the project name, the project description, or the project permissions. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). + +REST API: [Update Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Project%3FTocPath%3DAPI%2520Reference%7C_____82){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`project_item` | The project item object must include the project ID. The values in the project item override the current project settings. + + +**Exceptions** + +Error | Description + :--- | : --- +`Project item missing ID.` | Raises an exception if the project item does not have an ID. The project ID is sent to the server as part of the URI. + + +**Returns** + +Returns the updated project information. + +See [ProjectItem class](#projectitem-class) + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc + + ... + # get list of projects + all_project_items, pagination_item = server.projects.get() + + + # update project item #7 with new name, etc. + my_project = all_projects[7] + my_project.name ='New name' + my_project.description = 'New description' + + # call method to update project + updated_project = server.projects.update(my_project) + + + + +``` +
+
+ + +#### projects.delete + +```py +projects.delete(project_id) +``` + +Deletes a project by ID. + + +To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). + + +REST API: [Delete Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Project%3FTocPath%3DAPI%2520Reference%7C_____24){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`project_id` | The ID of the project to delete. + + + + +**Exceptions** + +Error | Description +:--- | :--- +`Project ID undefined.` | Raises an exception if the project item does not have an ID. The project ID is sent to the server as part of the URI. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc. + + server.projects.delete('1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e') + +``` + + +
+
+ + +## Requests + +The TSC library provides a `RequestOptions` class that you can use to filter results returned from the server. + +You can use the `Sort` and `RequestOptions` classes to filter and sort the following endpoints: + +- Users +- Datasources +- Groups +- Workbooks +- Views + +For more information, see [Filter and Sort](filter-sort). + +
+ + +### RequestOptions class + +```py +RequestOptions(pagenumber=1, pagesize=100) + +``` + + + +**Attributes** + +Name | Description +:--- | :--- +`pagenumber` | The page number of the returned results. The defauilt value is 1. +`pagesize` | The number of items to return with each page (the default value is 100). +`sort()` | Returns a iterable set of `Sort` objects. +`filter()` | Returns an iterable set of `Filter` objects. + +
+
+ + + +#### RequestOptions.Field class + +The `RequestOptions.Field` class corresponds to the fields used in filter expressions in the Tableau REST API. For more information, see [Filtering and Sorting](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_concepts_filtering_and_sorting.htm%3FTocPath%3DConcepts%7C_____7){:target="_blank"} in the Tableau REST API. + +**Attributes** + +**Attributes** + +Field | Description +:--- | :--- +`CreatedAt` | Same as 'createdAt' in the REST API. TSC. `RequestOptions.Field.CreatedAt` +`LastLogin` | Same as 'lastLogin' in the REST API. `RequestOptions.Field.LastLogin` +`Name` | Same as 'name' in the REST API. `RequestOptions.Field.Name` +`OwnerName` | Same as 'ownerName' in the REST API. `RequestOptions.Field.OwnerName` +`SiteRole` | Same as 'siteRole' in the REST API. `RequestOptions.Field.SiteRole` +`Tags` | Same as 'tags' in the REST API. `RequestOptions.Field.Tags` +`UpdatedAt` | Same as 'updatedAt' in the REST API. `RequestOptions.Field.UpdatedAt` + + +
+
+ + + +#### RequestOptions.Operator class + +Specifies the operators you can use to filter requests. + + +**Attributes** + +Operator | Description +:--- | :--- +`Equals` | Sets the operator to equals (same as `eq` in the REST API). `TSC.RequestOptions.Operator.Equals` +`GreaterThan` | Sets the operator to greater than (same as `gt` in the REST API). `TSC.RequestOptions.Operator.GreaterThan` +`GreaterThanOrEqual` | Sets the operator to greater than or equal (same as `gte` in the REST API). `TSC.RequestOptions.Operator.GreaterThanOrEqual` +`LessThan` | Sets the operator to less than (same as `lt` in the REST API). `TSC.RequestOptions.Operator.LessThan` +`LessThanOrEqual` | Sets the operator to less than or equal (same as `lte` in the REST API). `TSC.RequestOptions.Operator.LessThanOrEqual` +`In` | Sets the operator to in (same as `in` in the REST API). `TSC.RequestOptions.Operator.In` + +
+
+ + + +#### RequestOptions.Direction class + +Specifies the direction to sort the returned fields. + + +**Attributes** + +Name | Description +:--- | :--- +`Asc` | Sets the sort direction to ascending (`TSC.RequestOptions.Direction.Asc`) +`Desc` | Sets the sort direction to descending (`TSC.RequestOptions.Direction.Desc`). + + +
+
+ + + +## Server + +In the Tableau REST API, the server (`http://MY-SERVER/`) is the base or core of the URI that makes up the various endpoints or methods for accessing resources on the server (views, workbooks, sites, users, data sources, etc.) +The TSC library provides a `Server` class that represents the server. You create a server instance to sign in to the server and to call the various methods for accessing resources. + + +
+
+ + +### Server class + +```py +Server(server_address) +``` +The `Server` class contains the attributes that represent the server on Tableau Server. After you create an instance of the `Server` class, you can sign in to the server and call methods to access all of the resources on the server. + +**Attributes** + +Attribute | Description +:--- | :--- +`server_address` | Specifies the address of the Tableau Server or Tableau Online (for example, `http://MY-SERVER/`). +`version` | Specifies the version of the REST API to use (for example, `'2.5'`). When you use the TSC library to call methods that access Tableau Server, the `version` is passed to the endpoint as part of the URI (`https://MY-SERVER/api/2.5/`). Each release of Tableau Server supports specific versions of the REST API. New versions of the REST API are released with Tableau Server. By default, the value of `version` is set to `'2.3'`, which corresponds to Tableau Server 10.0. You can view or set this value. You might need to set this to a different value, for example, if you want to access features that are supported by the server and a later version of the REST API. For more information, see [REST API Versions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_concepts_versions.htm){:target="_blank"} + + + +**Example** + +```py +import tableauserverclient as TSC + +# create a instance of server +server = TSC.Server('http://MY-SERVER') + + +# change the REST API version to 2.5 +server.version = '2.5' + + +``` + +#### Server.*Resources* + +When you create an instance of the `Server` class, you have access to the resources on the server after you sign in. You can select these resources and their methods as members of the class, for example: `server.views.get()` + + + +Resource | Description + :--- | : --- +*server*.auth | Sets authentication for sign in and sign out. See [Auth](#auththentication) | +*server*.views | Access the server views and methods. See [Views](#views) +*server*.users | Access the user resources and methods. See [Users](#users) +*server*.sites | Access the sites. See [Sites](#sites) +*server*.groups | Access the groups resources and methods. See [Groups](#groups) +*server*.workbooks | Access the resources and methods for workbooks. See [Workbooks](#workbooks) +*server*.datasources | Access the resources and methods for data sources. See [Data Sources](#data-sources) +*server*.projects | Access the resources and methods for projects. See [Projects](#projets) +*server*.schedules | Access the resources and methods for schedules. See [Schedules](#Schedules) +*server*.server_info | Access the resources and methods for server information. See [ServerInfo class](#serverinfo-class) + +
+
+ +#### Server.PublishMode + +The `Server` class has `PublishMode` class that enumerates the options that specify what happens when you publish a workbook or data source. The options are `Overwrite`, `Append`, or `CreateNew`. + + +**Properties** + +Resource | Description + :--- | : --- +`PublishMode.Overwrite` | Overwrites the workbook or data source. +`PublishMode.Append` | Appends to the workbook or data source. +`PublishMode.CreateNew` | Creates a new workbook or data source. + + +**Example** + +```py + + print(TSC.Server.PublishMode.Overwrite) + # prints 'Overwrite' + + overwrite_true = TSC.Server.PublishMode.Overwrite + + ... + + # pass the PublishMode to the publish workbooks method + new_workbook = server.workbooks.publish(new_workbook, args.filepath, overwrite_true) + + +``` + + +
+
+ + +### ServerInfoItem class + +```py +ServerInfoItem(product_version, build_number, rest_api_version) +``` +The `ServerInfoItem` class contains the build and version information for Tableau Server. The server information is accessed with the `server_info.get()` method, which returns an instance of the `ServerInfo` class. + +**Attributes** + +Name | Description +:--- | :--- +`product_version` | Shows the version of the Tableau Server or Tableau Online (for example, 10.2.0). +`build_number` | Shows the specific build number (for example, 10200.17.0329.1446). +`rest_api_version` | Shows the supported REST API version number. Note that this might be different from the default value specified for the server, with the `Server.version` attribute. To take advantage of new features, you should query the server and set the `Server.version` to match the supported REST API version number. + + +
+
+ + +### ServerInfo methods + +The TSC library provides a method to access the build and version information from Tableau Server. + +
+ +#### server_info.get + +```py +server_info.get() + +``` +Retrieve the build and version information for the server. + +This method makes an unauthenticated call, so no sign in or authentication token is required. + +REST API: [Server Info](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Server_Info%3FTocPath%3DAPI%2520Reference%7C_____76){:target="_blank"} + +**Parameters** + None + +**Exceptions** + +Error | Description +:--- | :--- +`404003 UNKNOWN_RESOURCE` | Raises an exception if the server info endpoint is not found. + +**Example** + +```py +import tableauserverclient as TSC + +# create a instance of server +server = TSC.Server('http://MY-SERVER') + +# set the version number > 2.3 +# the server_info.get() method works in 2.4 and later +server.version = '2.5' + +s_info = server.server_info.get() +print("\nServer info:") +print("\tProduct version: {0}".format(s_info.product_version)) +print("\tREST API version: {0}".format(s_info.rest_api_version)) +print("\tBuild number: {0}".format(s_info.build_number)) + +``` + + +
+
+ + +## Sites + +Using the TSC library, you can query a site or sites on a server, or create or delete a site on the server. + +The site resources for Tableau Server and Tableau Online are defined in the `SiteItem` class. The class corresponds to the site resources you can access using the Tableau Server REST API. The site methods are based upon the endpoints for sites in the REST API and operate on the `SiteItem` class. + +
+
+ +### SiteItem class + +```py +SiteItem(name, content_url, admin_mode=None, user_quota=None, storage_quota=None, + disable_subscriptions=False, subscribe_others_enabled=True, revision_history_enabled=False) +``` + +The `SiteItem` class contains the members or attributes for the site resources on Tableau Server or Tableau Online. The `SiteItem` class defines the information you can request or query from Tableau Server or Tableau Online. The class members correspond to the attributes of a server request or response payload. + +**Attributes** + +Attribute | Description +:--- | :--- +`name` | The name of the site. The name of the default site is "". +`content_url` | The path to the site. +`admin_mode` | (Optional) For Tableau Server only. Specify `ContentAndUsers` to allow site administrators to use the server interface and **tabcmd** commands to add and remove users. (Specifying this option does not give site administrators permissions to manage users using the REST API.) Specify `ContentOnly` to prevent site administrators from adding or removing users. (Server administrators can always add or remove users.) +`user_quota`| (Optional) Specifies the maximum number of users for the site. If you do not specify this value, the limit depends on the type of licensing configured for the server. For user-based license, the maximum number of users is set by the license. For core-based licensing, there is no limit to the number of users. If you specify a maximum value, only licensed users are counted and server administrators are excluded. +`storage_quota` | (Optional) Specifies the maximum amount of space for the new site, in megabytes. If you set a quota and the site exceeds it, publishers will be prevented from uploading new content until the site is under the limit again. +`disable_subscriptions` | (Optional) Specify `true` to prevent users from being able to subscribe to workbooks on the specified site. The default is `false`. +`subscribe_others_enabled` | (Optional) Specify `false` to prevent server administrators, site administrators, and project or content owners from being able to subscribe other users to workbooks on the specified site. The default is `true`. +`revision_history_enabled` | (Optional) Specify `true` to enable revision history for content resources (workbooks and datasources). The default is `false`. +`revision_limit` | (Optional) Specifies the number of revisions of a content source (workbook or data source) to allow. On Tableau Server, the default is 25. +`state` | Shows the current state of the site (`Active` or `Suspended`). + + +**Example** + +```py + +# create a new instance of a SiteItem + +new_site = TSC.SiteItem(name='Tableau', content_url='tableau', admin_mode='ContentAndUsers', user_quota=15, storage_quota=1000, disable_subscriptions=True) + +``` + +Source file: models/site_item.py + +
+
+ + +### Site methods + +The TSC library provides methods that operate on sites for Tableau Server and Tableau Online. These methods correspond to endpoints or methods for sites in the Tableau REST API. + + +Source file: server/endpoint/sites_endpoint.py + +
+
+ +#### sites.create + +```py +sites.create(site_item) +``` + +Creates a new site on the server for the specified site item object. + +Tableau Server only. + + +REST API: [Create Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Site%3FTocPath%3DAPI%2520Reference%7C_____17){:target="_blank"} + + + +**Parameters** + +Name | Description +:--- | :--- +`site_item` | The settings for the site that you want to create. You need to create an instance of `SiteItem` and pass the `create` method. + + +**Returns** + +Returns a new instance of `SiteItem`. + + +**Example** + +```py +import tableauserverclient as TSC + +# create an instance of server +server = TSC.Server('http://MY-SERVER') + +# create shortcut for admin mode +content_users=TSC.SiteItem.AdminMode.ContentAndUsers + +# create a new SiteItem +new_site = TSC.SiteItem(name='Tableau', content_url='tableau', admin_mode=content_users, user_quota=15, storage_quota=1000, disable_subscriptions=True) + +# call the sites create method with the SiteItem +new_site = server.sites.create(new_site) +``` +
+
+ +#### sites.get + +```py +sites.get() +``` + +Queries all the sites on the server. + + +REST API: [Query Sites](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Sites%3FTocPath%3DAPI%2520Reference%7C_____58){:target="_blank"} + + +**Parameters** + + None. + +**Returns** + +Returns a list of all `SiteItem` objects and a `PaginationItem`. Use these values to iterate through the results. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc. + + # query the sites + all_sites, pagination_item = server.sites.get() + + # print all the site names and ids + for site in TSC.Pager(server.sites): + print(site.id, site.name, site.content_url, site.state) + + +``` + +
+
+ + + +#### sites.get_by_id + +```py +sites.get_by_id(site_id) +``` + +Queries the site with the given ID. + + +REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Site){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`site_id` | The id for the site you want to query. + + +**Exceptions** + +Error | Description + :--- | : --- +`Site ID undefined.` | Raises an error if an id is not specified. + + +**Returns** + +Returns the `SiteItem`. + + +**Example** + +```py + +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc. + + a_site = server.sites.get_by_id('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d') + print("\nThe site with id '9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d' is: {0}".format(a_site.name)) + +``` + +
+
+ +#### sites.get_by_name + +```py +sites.get_by_name(site_name) +``` + +Queries the site with the specified name. + + +REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Site){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`site_name` | The name of the site you want to query. + + +**Exceptions** + +Error | Description + :--- | : --- +`Site Name undefined.` | Raises an error if an name is not specified. + + +**Returns** + +Returns the `SiteItem`. + + +**Example** + +```py + +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc. + + a_site = server.sites.get_by_name('MY_SITE') + + +``` + +
+
+ + + +#### sites.update + +```py +sites.update(site_item) +``` + +Modifies the settings for site. + + +The site item object must include the site ID and overrides all other settings. + + +REST API: [Update Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Site%3FTocPath%3DAPI%2520Reference%7C_____84){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`site_item` | The site item that you want to update. The settings specified in the site item override the current site settings. + + +**Exceptions** + +Error | Description +:--- | :--- +`Site item missing ID.` | The site id must be present and must match the id of the site you are updating. +`You cannot set admin_mode to ContentOnly and also set a user quota` | To set the `user_quota`, the `AdminMode` must be set to `ContentAndUsers` + + +**Returns** + +Returns the updated `site_item`. + + +**Example** + +```py +... + +# make some updates to an existing site_item +site_item.name ="New name" + +# call update +site_item = server.sites.update(site_item) + +... +``` + +
+
+ + + + +#### sites.delete + + +```py +Sites.delete(site_id) +``` + +Deletes the specified site. + + +REST API: [Delete Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Site%3FTocPath%3DAPI%2520Reference%7C_____27){:target="_name"} + + +**Parameters** + +Name | Description + :--- | : --- +`site_id` | The id of the site that you want to delete. + + + +**Exceptions** + +Error | Description +:--- | :--- +`Site ID Undefined.` | The site id must be present and must match the id of the site you are deleting. + + + +**Example** + +```py + +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, etc. + +server.sites.delete('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d') + +``` + +
+
+ + + + +## Sort + +The `Sort` class is used with request options (`RequestOptions`) where you can filter and sort on the results returned from the server. + +You can use the sort and request options to filter and sort the following endpoints: + +- Users +- Datasources +- Workbooks +- Views + +### Sort class + +```py +sort(field, direction) +``` + + + +**Attributes** + +Name | Description +:--- | :--- +`field` | Sets the field to sort on. The fields are defined in the `RequestOption` class. +`direction` | The direction to sort, either ascending (`Asc`) or descending (`Desc`). The options are defined in the `RequestOptions.Direction` class. + +**Example** + +```py + +# create a new instance of a request option object +req_option = TSC.RequestOptions() + +# add the sort expression, sorting by name and direction +req_option.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Direction.Asc)) +matching_workbooks, pagination_item = server.workbooks.get(req_option) + +for wb in matching_workbooks: + print(wb.name) +``` + +For information about using the `Sort` class, see [Filter and Sort](filter-sort). + +
+
+ + + +## Users + +Using the TSC library, you can get information about all the users on a site, and you can add or remove users, or update user information. + +The user resources for Tableau Server are defined in the `UserItem` class. The class corresponds to the user resources you can access using the Tableau Server REST API. The user methods are based upon the endpoints for users in the REST API and operate on the `UserItem` class. + + +### UserItem class + +```py +UserItem(name, site_role, auth_setting=None) +``` + +The `UserItem` class contains the members or attributes for the view resources on Tableau Server. The `UserItem` class defines the information you can request or query from Tableau Server. The class members correspond to the attributes of a server request or response payload. + +**Attributes** + +Name | Description +:--- | :--- +`auth_setting` | (Optional) This attribute is only for Tableau Online. The new authentication type for the user. You can assign the following values for tis attribute: `SAML` (the user signs in using SAML) or `ServerDefault` (the user signs in using the authentication method that's set for the server). These values appear in the **Authentication** tab on the **Settings** page in Tableau Online -- the `SAML` attribute value corresponds to **Single sign-on**, and the `ServerDefault` value corresponds to **TableauID**. +`domain_name` | The name of the site. +`external_auth_user_id` | Represents ID stored in Tableau's single sign-on (SSO) system. The `externalAuthUserId` value is returned for Tableau Online. For other server configurations, this field contains null. +`id` | The id of the user on the site. +`last_login` | The date and time the user last logged in. +`workbooks` | The workbooks the user owns. You must run the populate_workbooks method to add the workbooks to the `UserItem`. +`email` | The email address of the user. +`fullname` | The full name of the user. +`name` | The name of the user. This attribute is required when you are creating a `UserItem` instance. +`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `Viewer`, `ViewerWithPublish`, `Guest` + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('server') + +# create a new UserItem object. + newU = TSC.UserItem('Monty', 'Publisher') + + print(newU.name, newU.site_role) + +``` + +Source file: models/user_item.py + +
+
+ + +### Users methods + +The Tableau Server Client provides several methods for interacting with user resources, or endpoints. These methods correspond to endpoints in the Tableau Server REST API. + +Source file: server/endpoint/users_endpoint.py +
+
+ +#### users.add + +```py +users.add(user_item) +``` + +Adds the user to the site. + +To add a new user to the site you need to first create a new `user_item` (from `UserItem` class). When you create a new user, you specify the name of the user and their site role. For Tableau Online, you also specify the `auth_setting` attribute in your request. When you add user to Tableau Online, the name of the user must be the email address that is used to sign in to Tableau Online. After you add a user, Tableau Online sends the user an email invitation. The user can click the link in the invitation to sign in and update their full name and password. + +REST API: [Add User to Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Add_User_to_Site%3FTocPath%3DAPI%2520Reference%7C_____9){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`user_item` | You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific user, you could specify the name of the user or the user's id. + + +**Returns** + +Returns the new `UserItem` object. + + + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('server') +# login, etc. + +# create a new UserItem object. + newU = TSC.UserItem('Heather', 'Publisher') + +# add the new user to the site + newU = server.users.add(newU) + print(newU.name, newU.site_role) + +``` + +#### users.get + +```py +users.get(req_options=None) +``` + +Returns information about the users on the specified site. + +To get information about the workbooks a user owns or has view permission for, you must first populate the `UserItem` with workbook information using the [populate_workbooks(*user_item*)](#populate-workbooks-user) method. + + +REST API: [Get Users on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_on_Site%3FTocPath%3DAPI%2520Reference%7C_____41){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific user, you could specify the name of the user or the user's id. + + +**Returns** + +Returns a list of `UserItem` objects and a `PaginationItem` object. Use these values to iterate through the results. + + +**Example** + + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('http://SERVERURL') + +with server.auth.sign_in(tableau_auth): + all_users, pagination_item = server.users.get() + print("\nThere are {} user on site: ".format(pagination_item.total_available)) + print([user.name for user in all_users]) +```` + +
+
+ +#### users.get_by_id + +```py +users.get_by_id(user_id) +``` + +Returns information about the specified user. + +REST API: [Query User On Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_User_On_Site%3FTocPath%3DAPI%2520Reference%7C_____61){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`user_id` | The `user_id` specifies the user to query. + + +**Exceptions** + +Error | Description + :--- | : --- +`User ID undefined.` | Raises an exception if a valid `user_id` is not provided. + + +**Returns** + +The `UserItem`. See [UserItem class](#useritem-class) + + +**Example** + +```py + user1 = server.users.get_by_id('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + print(user1.name) + +``` + +
+
+ + +#### users.populate_favorites + +```py +users.populate_favorites(user_item) +``` + +Returns the list of favorites (views, workbooks, and data sources) for a user. + +*Not currently implemented* + +
+
+ + +#### users.populate_workbooks + +```py +users.populate_workbooks(user_item, req_options=None): +``` + +Returns information about the workbooks that the specified user owns and has Read (view) permissions for. + + +This method retrieves the workbook information for the specified user. The REST API is designed to return only the information you ask for explicitly. When you query for all the users, the workbook information for each user is not included. Use this method to retrieve information about the workbooks that the user owns or has Read (view) permissions. The method adds the list of workbooks to the user item object (`user_item.workbooks`). + +REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource_Connections%3FTocPath%3DAPI%2520Reference%7C_____47){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`user_item` | The `user_item` specifies the user to populate with workbook information. + + + + +**Exceptions** + +Error | Description + :--- | : --- +`User item missing ID.` | Raises an error if the `user_item` is unspecified. + + +**Returns** + +A list of `WorkbookItem` + +A `PaginationItem` that points (`user_item.workbooks`). See [UserItem class](#useritem-class) + + +**Example** + +```py +# first get all users, call server.users.get() +# get workbooks for user[0] + ... + + page_n = server.users.populate_workbooks(all_users[0]) + print("\nUser {0} owns or has READ permissions for {1} workbooks".format(all_users[0].name, page_n.total_available)) + print("\nThe workbooks are:") + for workbook in all_users[0].workbooks : + print(workbook.name) + + ... +``` + + + + +
+
+ +#### users.remove + +```py +users.remove(user_id) +``` + + + +Removes the specified user from the site. + +REST API: [Remove User from Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Site%3FTocPath%3DAPI%2520Reference%7C_____74){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`user_id` | The identifier (`id`) for the user that you want to remove from the server. + + +**Exceptions** + +Error | Description + :--- | : --- +`User ID undefined` | Raises an exception if a valid `user_id` is not provided. + + +**Example** + +```py +# Remove a user from the site + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + server.users.remove('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + +``` +
+
+ + + + +#### users.update + +```py +users.update(user_item, password=None) +``` + +Updates information about the specified user. + +The information you can modify depends upon whether you are using Tableau Server or Tableau Online, and whether you have configured Tableau Server to use local authentication or Active Directory. For more information, see [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_User%3FTocPath%3DAPI%2520Reference%7C_____86){:target="_blank"}. + + + +REST API: [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_User%3FTocPath%3DAPI%2520Reference%7C_____86){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`user_item` | The `user_item` specifies the user to update. +`password` | (Optional) The new password for the user. + + + +**Exceptions** + +Error | Description + :--- | : --- +`User item missing ID.` | Raises an error if the `user_item` is unspecified. + + +**Returns** + +An updated `UserItem`. See [UserItem class](#useritem-class) + + +**Example** + +```py + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + + # create a new user_item + user1 = TSC.UserItem('temp', 'Viewer') + + # add new user + user1 = server.users.add(user1) + print(user1.name, user1.site_role, user1.id) + + # modify user info + user1.name = 'Laura' + user1.fullname = 'Laura Rodriguez' + user1.email = 'laura@example.com' + + # update user + user1 = server.users.update(user1) + print("\Updated user info:") + print(user1.name, user1.fullname, user1.email, user1.id) + + +``` + + + +
+
+ + + + +## Views + +Using the TSC library, you can get all the views on a site, or get the views for a workbook, or populate a view with preview images. +The view resources for Tableau Server are defined in the `ViewItem` class. The class corresponds to the view resources you can access using the Tableau Server REST API, for example, you can find the name of the view, its id, and the id of the workbook it is associated with. The view methods are based upon the endpoints for views in the REST API and operate on the `ViewItem` class. + + +
+ +### ViewItem class + +``` +class ViewItem(object) + +``` + +The `ViewItem` class contains the members or attributes for the view resources on Tableau Server. The `ViewItem` class defines the information you can request or query from Tableau Server. The class members correspond to the attributes of a server request or response payload. + +Source file: models/view_item.py + +**Attributes** + +Name | Description +:--- | :--- +`id` | The identifier of the view item. +`name` | The name of the view. +`owner_id` | The id for the owner of the view. +`preview_image` | The thumbnail image for the view. +`total_views` | The usage statistics for the view. Indicates the total number of times the view has been looked at. +`workbook_id` | The id of the workbook associated with the view. + + +
+
+ + +### Views methods + +The Tableau Server Client provides two methods for interacting with view resources, or endpoints. These methods correspond to the endpoints for views in the Tableau Server REST API. + +Source file: server/endpoint/views_endpoint.py + +
+
+ +#### views.get +``` +views.get(req_option=None) +``` + +Returns the list of views items for a site. + + +REST API: [Query Views for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Views_for_Site%3FTocPath%3DAPI%2520Reference%7C_____64){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific view, you could specify the name of the view or its id. + + + +**Returns** + +Returns a list of all `ViewItem` objects and a `PaginationItem`. Use these values to iterate through the results. + +**Example** + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('username', 'password') +server = TSC.Server('http://servername') + +with server.auth.sign_in(tableau_auth): + all_views, pagination_item = server.views.get() + print([view.name for view in all_views]) + +```` + +See [ViewItem class](#viewitem-class) + + +
+
+ +#### views.populate_preview_image + +```py + views.populate_preview_image(view_item) + +``` + +Populates a preview image for the specified view. + +This method gets the preview image (thumbnail) for the specified view item. The method uses the `view.id` and `workbook.id` to identify the preview image. The method populates the `view.preview_image` for the view. + +REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Preview_Image%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`view_item` | The view item specifies the `view.id` and `workbook.id` that identifies the preview image. + + +**Exceptions** + +Error | Description +:--- | :--- +`View item missing ID or workbook ID` | Raises an error if the ID for the view item or workbook is missing. + + + +**Returns** + +None. The preview image is added to the view. + +See [ViewItem class](#viewitem-class) + +
+
+ + + + + +## Workbooks + +Using the TSC library, you can get information about a specific workbook or all the workbooks on a site, and you can publish, update, or delete workbooks. + +The project resources for Tableau are defined in the `WorkbookItem` class. The class corresponds to the workbook resources you can access using the Tableau REST API. The workbook methods are based upon the endpoints for projects in the REST API and operate on the `WorkbookItem` class. + + + + + +
+
+ +### WorkbookItem class + +```py + + WorkbookItem(project_id, name=None, show_tabs=False) + +``` +The workbook resources for Tableau are defined in the `WorkbookItem` class. The class corresponds to the workbook resources you can access using the Tableau REST API. Some workbook methods take an instance of the `WorkbookItem` class as arguments. The workbook item specifies the project + + +**Attributes** + +Name | Description +:--- | :--- +`connections` | The list of data connections (`ConnectionItem`) for the data sources used by the workbook. You must first call the [workbooks.populate_connections](#workbooks.populate_connections) method to access this data. See the [ConnectionItem class](#connectionitem-class). +`content_url` | The name of the data source as it would appear in a URL. +`created_at` | The date and time when the data source was created. +`id` | The identifier for the workbook. You need this value to query a specific workbook or to delete a workbook with the `get_by_id` and `delete` methods. +`name` | The name of the workbook. +`owner_id` | The ID of the owner. +`preview_image` | The thumbnail image for the view. You must first call the [workbooks.populate_preview_image](#workbooks.populate_preview_image) method to access this data. +`project_id` | The project id. +`project_name` | The name of the project. +`size` | The size of the workbook (in megabytes). +`show_tabs` | (Boolean) Determines whether the workbook shows tabs for the view. +`tags` | The tags that have been added to the workbook. +`updated_at` | The date and time when the workbook was last updated. +`views` | The list of views (`ViewItem`) for the workbook. You must first call the [workbooks.populate_views](#workbooks.populate_views) method to access this data. See the [ViewItem class](#viewitem-class). + + + + + +**Example** + +```py +# creating a new instance of a WorkbookItem +# +import tableauserverclient as TSC + +# Create new workbook_item with project id '3a8b6148-493c-11e6-a621-6f3499394a39' + + new_workbook = TSC.WorkbookItem('3a8b6148-493c-11e6-a621-6f3499394a39') + + +```` + +Source file: models/workbook_item.py + +
+
+ +### Workbook methods + +The Tableau Server Client (TSC) library provides methods for interacting with workbooks. These methods correspond to endpoints in the Tableau Server REST API. For example, you can use the library to publish, update, download, or delete workbooks on the site. +The methods operate on a workbook object (`WorkbookItem`) that represents the workbook resources. + + + +Source files: server/endpoint/workbooks_endpoint.py + +
+
+ +#### workbooks.get + +```py +workbooks.get(req_options=None) +``` + +Queries the server and returns information about the workbooks the site. + + + + + +REST API: [Query Workbooks for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbooks_for_Site%3FTocPath%3DAPI%2520Reference%7C_____70){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific workbook, you could specify the name of the workbook or the name of the owner. See [Filter and Sort](filter-sort) + + +**Returns** + +Returns a list of all `WorkbookItem` objects and a `PaginationItem`. Use these values to iterate through the results. + + +**Example** + +```py + +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') +server = TSC.Server('http://servername') + +with server.auth.sign_in(tableau_auth): + all_workbooks, pagination_item = server.workbooks.get() + # print names of first 100 workbooks + print([workbook.name for workbook in all_workbooks]) + + + +``` + +
+
+ + + +#### workbooks.get_by_id + +```py +workbooks.get_by_id(workbook_id) +``` + +Returns information about the specified workbook on the site. + +REST API: [Query Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook%3FTocPath%3DAPI%2520Reference%7C_____66){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`workbook_id` | The `workbook_id` specifies the workbook to query. The ID is a LUID (64-bit hexadecimal string). + + +**Exceptions** + +Error | Description + :--- | : --- +`Workbook ID undefined` | Raises an exception if a `workbook_id` is not provided. + + +**Returns** + +The `WorkbookItem`. See [WorkbookItem class](#workbookitem-class) + + +**Example** + +```py + +workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') +print(workbook.name) + +``` + + +
+
+ + +#### workbooks.publish + +```py +workbooks.publish(workbook_item, file_path, publish_mode) +``` + +Publish a workbook to the specified site. + +**Note:** The REST API cannot automatically include +extracts or other resources that the workbook uses. Therefore, + a .twb file that uses data from an Excel or csv file on a local computer cannot be published, +unless you package the data and workbook in a .twbx file, or publish the data source separately. + +For workbooks that are larger than 64 MB, the publish method automatically takes care of chunking the file in parts for uploading. Using this method is considerably more convenient than calling the publish REST APIs directly. + +REST API: [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Workbook%3FTocPath%3DAPI%2520Reference%7C_____45){:target="_blank"}, [Initiate File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Initiate_File_Upload%3FTocPath%3DAPI%2520Reference%7C_____43){:target="_blank"}, [Append to File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Append_to_File_Upload%3FTocPath%3DAPI%2520Reference%7C_____13){:target="_blank"} + + + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the workbook you are publishing. When you are adding a workbook, you need to first create a new instance of a `workbook_item` that includes a `project_id` of an existing project. The name of the workbook will be the name of the file, unless you also specify a name for the new workbook when you create the instance. See [WorkbookItem](#workbookitem-class). +`file_path` | The path and name of the workbook to publish. +`mode` | Specifies whether you are publishing a new workbook (`CreateNew`) or overwriting an existing workbook (`Overwrite`). You cannot appending workbooks. You can also use the publish mode attributes, for example: `TSC.Server.PublishMode.Overwrite`. +`connection_credentials` | (Optional) The credentials (if required) to connect to the workbook's data source. The `ConnectionCredentials` object contains the authentication information for the data source (user name and password, and whether the credentials are embeded or OAuth is used). + + + +**Exceptions** + +Error | Description +:--- | :--- +`File path does not lead to an existing file.` | Raises an error of the file path is incorrect or if the file is missing. +`Invalid mode defined.` | Raises an error if the publish mode is not one of the defined options. +`Workbooks cannot be appended.` | The `mode` must be set to `Overwrite` or `CreateNew`. +`Only .twb or twbx files can be published as workbooks.` | Raises an error if the type of file specified is not supported. + +See the REST API [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Workbook%3FTocPath%3DAPI%2520Reference%7C_____45){:target="_blank"} for additional error codes. + +**Returns** + +The `WorkbookItem` for the workbook that was published. + + +**Example** + +```py + +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') +server = TSC.Server('http://servername') + +with server.auth.sign_in(tableau_auth): + # create a workbook item + wb_item = TSC.WorkbookItem(name='Sample', project_id='1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e') + # call the publish method with the workbook item + wb_item = server.workbooks.publish(wb_item, 'SampleWB.twbx', 'Overwrite') +``` + +
+
+ + +#### workbooks.update + +```py +workbooks.update(workbook_item) +``` + + +Modifies an existing workbook. Use this method to change the owner or the project that the workbook belongs to, or to change whether the workbook shows views in tabs. The workbook item must include the workbook ID and overrides the existing settings. + +REST API: [Update Workbooks](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Workbook%3FTocPath%3DAPI%2520Reference%7C_____87){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the settings for the workbook you are updating. You can change the `owner_id`, `project_id`, and the `show_tabs` values. See [WorkbookItem](#workbookitem-class). + + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook item missing ID. Workbook must be retrieved from server first.` | Raises an error if the `workbook_item` is unspecified. Use the `workbooks.get()` or `workbooks.get_by_id()` methods to retrieve the workbook item from the server. + + +```py + +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') +server = TSC.Server('http://servername') + +with server.auth.sign_in(tableau_auth): + + # get the workbook item from the site + workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + print("\nUpdate {0} workbook. Project was {1}".format(workbook.name, workbook.project_name)) + + + # make an change, for example a new project ID + workbook.project_id = '1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e' + + # call the update method + workbook = server.workbooks.update(workbook) + print("\nUpdated {0} workbook. Project is now {1}".format(workbook.name, workbook.project_name)) + + +``` + + +
+
+ + + +#### workbooks.delete + +```py +workbooks.delete(workbook_id) +``` + +Deletes a workbook with the specified ID. + + + +To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). + + +REST API: [Delete Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Workbook%3FTocPath%3DAPI%2520Reference%7C_____31){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`workbook_id` | The ID of the workbook to delete. + + + + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook ID undefined.` | Raises an exception if the project item does not have an ID. The project ID is sent to the server as part of the URI. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# tableau_auth sign in, etc. + + server.workbooks.delete('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + +``` + + +
+
+ + +#### workbooks.download + +```py +workbooks.download(workbook_id, filepath=None, no_extract=False) +``` + +Downloads a workbook to the specified directory (optional). + + +REST API: [Download Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Download_Workbook%3FTocPath%3DAPI%2520Reference%7C_____36){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`workbook_id` | The ID for the `WorkbookItem` that you want to download from the server. +`filepath` | (Optional) Downloads the file to the location you specify. If no location is specified, the file is downloaded to the current working directory. The default is `Filepath=None`. +`no_extract` | (Optional) Specifies whether to download the file without the extract. When the workbook has an extract, if you set the parameter `no_extract=True`, the extract is not included. You can use this parameter to improve performance if you are downloading workbooks that have large extracts. The default is to include the extract, if present (`no_extract=False`). Available starting with Tableau Server REST API version 2.5. + + + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook ID undefined` | Raises an exception if a valid `datasource_id` is not provided. + + +**Returns** + +The file path to the downloaded workbook. + + +**Example** + +```py + + file_path = server.workbooks.download('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + print("\nDownloaded the file to {0}.".format(file_path)) + +```` + + +
+
+ + +#### workbooks.populate_views + +```py +workbooks.populate_views(workbook_item) +``` + +Populates (or gets) a list of views for a workbook. + +You must first call this method to populate views before you can iterate through the views. + +This method retrieves the view information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the view information is not included. Use this method to retrieve the views. The method adds the list of views to the workbook item (`workbook_item.views`). This is a list of `ViewItem`. + +REST API: [Query Views for Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Views_for_Workbook%3FTocPath%3DAPI%2520Reference%7C_____65){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the workbook to populate with views information. See [WorkbookItem class](#workbookitem-class). + + + + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook item missing ID. Workbook must be retrieved from server first.` | Raises an error if the `workbook_item` is unspecified. You can retrieve the workbook items using the `workbooks.get()` and `workbooks.get_by_id()` methods. + + +**Returns** + +None. A list of `ViewItem` objects are added to the workbook (`workbook_item.views`). + + +**Example** + +```py +# import tableauserverclient as TSC + +# server = TSC.Server('http://SERVERURL') +# + ... + +# get the workbook item + workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + + +# get the view information + server.workbooks.populate_views(workbook) + +# print information about the views for the work item + print("\nThe views for {0}: ".format(workbook.name)) + print([view.name for view in workbook.views]) + + ... + +``` + +
+
+ +#### workbooks.populate_connections + +```py +workbooks.populate_connections(workbook_item) +``` + +Populates a list of data source connections for the specified workbook. + +You must populate connections before you can iterate through the +connections. + +This method retrieves the data source connection information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query all the workbooks, the data source connection information is not included. Use this method to retrieve the connection information for any data sources used by the workbook. The method adds the list of data connections to the workbook item (`workbook_item.connections`). This is a list of `ConnectionItem`. + +REST API: [Query Workbook Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Connections%3FTocPath%3DAPI%2520Reference%7C_____67){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the workbook to populate with data connection information. + + + + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook item missing ID. Workbook must be retrieved from server first.` | Raises an error if the `workbook_item` is unspecified. + + +**Returns** + +None. A list of `ConnectionItem` objects are added to the data source (`workbook_item.connections`). + + +**Example** + +```py +# import tableauserverclient as TSC + +# server = TSC.Server('http://SERVERURL') +# + ... + +# get the workbook item + workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + + +# get the connection information + server.workbooks.populate_connections(workbook) + +# print information about the data connections for the workbook item + print("\nThe connections for {0}: ".format(workbook.name)) + print([connection.id for connection in workbook.connections]) + + + ... + +``` + +
+
+ + +#### workbooks.populate_preview_image + +```py +workbooks.populate_preview_image(workbook_item) +``` + +This method gets the preview image (thumbnail) for the specified workbook item. + +The method uses the `view.id` and `workbook.id` to identify the preview image. The method populates the `workbook_item.preview_image`. + +REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Preview_Image%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`view_item` | The view item specifies the `view.id` and `workbook.id` that identifies the preview image. + + + +**Exceptions** + +Error | Description +:--- | :--- +`View item missing ID or workbook ID` | Raises an error if the ID for the view item or workbook is missing. + + + +**Returns** + +None. The preview image is added to the view. + + + +**Example** + +```py + +# import tableauserverclient as TSC + +# server = TSC.Server('http://SERVERURL') + + ... + + # get the workbook item + workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + + # add the png thumbnail to the workbook item + server.workbooks.populate_preview_image(workbook) + + +``` + +#### workbooks.update_connection + +```py +workbooks.update_conn(workbook_item, connection_item) +``` + +Updates a workbook connection information (server address, server port, user name, and password). + +The workbook connections must be populated before the strings can be updated. See [workbooks.populate_connections](#workbooks.populate_connections) + +REST API: [Update Workbook Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Workbook_Connection%3FTocPath%3DAPI%2520Reference%7C_____88){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the workbook to populate with data connection information. +`connection_item` | The `connection_item` that has the information you want to update. + + + +**Returns** + +None. The connection information is updated with the information in the `ConnectionItem`. + + + + +**Example** + +```py + +# update connection item user name and password +workbook.connections[0].username = 'USERNAME' +workbook.connections[0].password = 'PASSWORD' + +# call the update method +server.workbooks.update_conn(workbook, workbook.connections[0]) +``` + +
+
+ + diff --git a/docs/dev-guide.md b/docs/dev-guide.md new file mode 100644 index 000000000..8b47609ce --- /dev/null +++ b/docs/dev-guide.md @@ -0,0 +1,96 @@ +--- +title: Developer Guide +layout: docs +--- + +This topic describes how to contribute to the Tableau Server Client (Python) project. + +* TOC +{:toc} + +## Submit your first patch + +1. Make sure you have [signed the CLA](http://tableau.github.io/#contributor-license-agreement-cla) + +1. Fork the repository. + + We follow the "Fork and Pull" model as described [here](https://help.github.com/articles/about-collaborative-development-models/). + +1. Clone your fork: + + ```shell + git clone git@github.com:/server-client-python.git + ``` + +1. Run the tests to make sure everything is peachy: + + ```shell + python setup.py test + ``` + +1. Set up the feature, fix, or documentation branch. + + It is recommended to use the format issue#-type-description (e.g. 13-fix-connection-bug) like so: + + ```shell + git checkout -b 13-feature-new-stuff + ``` + +1. Code and commit! + + Here's a quick checklist for ensuring a good pull request: + + - Only touch the minimal amount of files possible while still accomplishing the goal. + - Ensure all indentation is done as 4-spaces and your editor is set to unix line endings. + - The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle .` + - Keep commit messages clean and descriptive. + If the PR is accepted it will get 'Squashed' into a single commit before merging, the commit messages will be used to generate the Merge commit message. + +1. Add tests. + + All of our tests live under the `test/` folder in the repository. + We use `unittest` and the built-in test runner `python setup.py test`. + If a test needs a static file, like a twb/twbx, it should live under `test/assets/` + +1. Update the documentation. + + Our documentation is written in markdown and built with Jekyll on Github Pages. All of the documentation source files can be found in `docs/docs`. + + When adding a new feature or improving existing functionality we may ask that you update the documentation along with your code. + + If you are just making a PR for documentation updates (adding new docs, fixing typos, improving wording) the easiest method is to use the built in `Edit this file` in the Github UI + +1. Submit to your fork. + +1. Make a PR as described [here](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the 'development' branch. + +1. Wait for a review and address any feedback. + While we try and stay on top of all issues and PRs it might take a few days for someone to respond. Politely pinging + the PR after a few days with no response is OK, we'll try and respond with a timeline as soon as we are able. + +1. That's it! When the PR has received :rocket:'s from members of the core team they will merge the PR + + +## Add new features + +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. + +1. 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 and 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). + +1. Add testing by getting real xml responses from the server, and asserting that all properties are parsed and set + correctly. + +1. Add a sample to show users how to use the new feature. + + diff --git a/docs/filter-sort.md b/docs/filter-sort.md new file mode 100644 index 000000000..f63e32f19 --- /dev/null +++ b/docs/filter-sort.md @@ -0,0 +1,90 @@ +--- +title: Filter and Sort +layout: docs +--- +Use the `RequestOptions` object to define filtering and sorting criteria for an endpoint, +then pass the object to your endpoint as a parameter. + +* TOC +{:toc} + + +## Available endpoints and fields + +You can use the TSC library to filter and sort the following endpoints: + +* Users +* Datasources +* Workbooks +* Views + +For the above endpoints, you can filter or sort on the following +fields: + +* CreatedAt +* LastLogin +* Name +* OwnerName +* SiteRole +* Tags +* UpdatedAt + +**Important**: Not all of the fields are available for all endpoints. For more information, see the [REST +API help](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_concepts_filtering_and_sorting.htm). + +## Filtering + +To filter on a field, you need to specify the following criteria: + +### Operator criteria + +The operator that you want to use for that field. For example, you can use the Equals operator to get everything from the endpoint that matches exactly. + +The operator can be any of the following: + +* Equals +* GreaterThan +* GreaterThanOrEqual +* LessThan +* In + +### Value criteria + +The value that you want to filter on. This can be any valid string. + +### Filtering example + +The following code displays only the workbooks where the name equals Superstore: + +```py +req_option = TSC.RequestOptions() +req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Operator.Equals, + 'Superstore')) +matching_workbooks, pagination_item = server.workbooks.get(req_option) + +print(matching_workbooks[0].owner_id) +``` + +## Sorting + +To sort on a field, you need to specify the direction in which you want to sort. + +### Direction criteria + +This can be either `Asc` for ascending or `Desc` for descending. + +### Sorting example + +The following code sorts the workbooks in ascending order: + +```py +req_option = TSC.RequestOptions() +req_option.sort.add(TSC.Sort(TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Direction.Asc)) +matching_workbooks, pagination_item = server.workbooks.get(req_option) + +for wb in matching_workbooks: + print(wb.name) +``` + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..9fd8b699e --- /dev/null +++ b/docs/index.md @@ -0,0 +1,76 @@ +--- +title: Get Started +layout: docs +--- + +Use the Tableau Server Client (TSC) library to increase your productivity as you interact with the Tableau Server REST API. With +the TSC library you can do almost everything that you can do with the REST API, including: + +* Publish workbooks and data sources. +* Create users and groups. +* Query projects, sites, and more. + +This section describes how to: + +* TOC +{:toc} + +## Confirm prerequisites + +Before you install TSC, confirm that you have the following dependencies installed: + +* Python. You can use TSC with Python 2.7.9 or later and with Python 3.3 or later. These versions include pip, which is + the recommended means of installing TSC. +* Git. Optional, but recommended to download the samples or install from the source code. + + +## Install TSC + +You can install TSC with pip or from the source code. + +### Install with pip (recommended) + +Run the following command to install the latest stable version of TSC: + +``` +pip install tableauserverclient +``` + +### Install from the development branch + +You can install from the development branch for a preview of upcoming features. Run the following command +to install from the development branch: + +``` +pip install git+https://github.com/tableau/server-client-python.git@development +``` + +Note that the version from the development branch should not be used for production code. The methods and endpoints in the +development version are subject to change at any time before the next stable release. + +## Get the samples + +The TSC samples are included in the `samples` directory of the TSC repository on Github. You can run the following command to clone the +repository: + +``` +git clone git@github.com:tableau/server-client-python.git +``` + +For more information on the samples and how to run the samples, see [Samples]({{ site.baseurl }}/docs/samples). + +## Write your first program + +Run the following code to get a list of all the data sources on your installation of Tableau Server: + +```py +import tableauserverclient as TSC + +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('http://SERVER_URL') + +with server.auth.sign_in(tableau_auth): + all_datasources, pagination_item = server.datasources.get() + print("\nThere are {} datasources on site: ".format(pagination_item.total_available)) + print([datasource.name for datasource in all_datasources]) +``` diff --git a/docs/page-through-results.md b/docs/page-through-results.md new file mode 100644 index 000000000..b01a1455b --- /dev/null +++ b/docs/page-through-results.md @@ -0,0 +1,69 @@ +--- +title: Page through Results +layout: docs +--- + +Many of the calls that you make with the TSC library query for resources (like workbooks or data sources) on Tableau +Server. Because the number of resources on Tableau Server can be very large, Tableau Server only returns the first 100 +resources by default. To get all of the resources on Tableau Server, you need to page through the results. + +* TOC +{:toc} + +## The Pager generator + +The simplest way to page through results is to use the `Pager` generator on any endpoint with a `get` function. + +For example, to get all of the workbooks on Tableau Server, run the following code: + +```py +for wb in TSC.Pager(server.workbooks): + print(wb.name) +``` + +The `Pager` generator function returns one resource for each time that it is called. To get all the resources on the +server, you can make multiple calls to the `Pager` function. For example, you can use a `for ... in` loop to call the +`Pager` function until there are no resources remaining. Note that the `Pager` generator only makes calls to the Tableau +Server REST API when it runs out of resources--it does not make a call for each resource. + +**Tip**: For more information on generators, see the [Python wiki](https://wiki.python.org/moin/Generators). + +### Set pagination options + +You can set pagination options in the request options and then pass the request options to the `Pager` function as a +second optional parameter. + +For example, to set the page size to 1000 use the following code: + +```py +request_options = TSC.RequestOptions(pagesize=1000) +all_workbooks = list(TSC.Pager(server.workbooks, request_options)) +``` + +You can also set the page number where you want to start like so: + +```py +request_options = TSC.RequestOptions(pagenumber=5) +all_workbooks = list(TSC.Pager(server.workbooks, request_options)) +``` + +### Use list comprehensions and generator expressions + +The `Pager` generator can also be used in list comprehensions or generator expressions for compactness and easy +filtering. Generator expressions will use less memory than list comprehensions. The following example shows how to use +the `Pager` generator with list comprehensions and generator expressions: + +```py +# List comprehension +[wb for wb in TSC.Pager(server.workbooks) if wb.name.startswith('a')] + +# Generator expression +(wb for wb in TSC.Pager(server.workbooks) if wb.name.startswith('a')) +``` + +If you want to load all the resources returned by the `Pager` generator in memory (rather than one at a time), then you +can insert the elements into a list: + +```py +all_workbooks = list(TSC.Pager(server.workbooks)) +``` diff --git a/docs/populate-connections-views.md b/docs/populate-connections-views.md new file mode 100644 index 000000000..63e3fe8f4 --- /dev/null +++ b/docs/populate-connections-views.md @@ -0,0 +1,45 @@ +--- +title: Populate Connections and Views +layout: docs +--- + +When you get a workbook with the TSC library, the response from Tableau Server does not include information about the +views or connections that make up the workbook. Similarly, when you get a data source, the response does not include +information about the connections that make up the data source. This is a result of the design of the Tableau Server +REST API, which optimizes the size of responses by only returning what you ask for explicitly. + +As a result, if you want to get views and connections, you need to run the `populate_views` and `populate_connections` +functions. + +* TOC +{:toc} + +## Populate views for workbooks + +```py +workbook = server.workbooks.get_by_id('a1b2c3d4') +print(workbook.id) + +server.workbooks.populate_views(workbook) +print([view.name for view in workbook.views]) +``` + +## Populate connections for workbooks + +```py +workbook = server.workbooks.get_by_id('a1b2c3d4') +print(workbook.id) + +server.workbooks.populate_connections(workbook) +print([connection.datasource_name for connection in workbook.connections]) +``` + +## Populate connections for data sources + +```py +datasource = server.datasources.get_by_id('a1b2c3d4') +print(datasource.name) + +server.datasources.populate_connections(datasource) +print([connection.datasource_name for connection in datasource.connections]) +``` diff --git a/docs/samples.md b/docs/samples.md new file mode 100644 index 000000000..3ea908dd6 --- /dev/null +++ b/docs/samples.md @@ -0,0 +1,55 @@ +--- +title: Samples +layout: docs +--- + +The TSC samples are included in the `samples` directory of the TSC repository [on Github](https://github.com/tableau/server-client-python). + +* TOC +{:toc} + +## Run the samples + +Each of the samples requires the following arguments: + +* `--server`. The URL for the Tableau Server that you want to connect to. +* `--username`. The user name of the Tableau Server account that you want to use. When you run the samples, you are + prompted for a password for the user account that you enter. + +Additionally, some of the samples require that you enter other arguments when you run them. For more information about +the arguments required by a particular sample, run the sample with the `-h` flag to see the help output. + +For example, if you run the following command: + +``` +python samples/publish_workbook.py -h +``` + +You might see that you need to enter a server address, a user name, and a file path for the workbook that you want to +publish. + +## Samples list + +The following list describes the samples available in the repository: + +* `create_group.py`. Create a user group. + +* `create_schedules.py`. Create schedules for extract refreshes and subscriptions. + +* `explore_datasource.py`. Queries datasources, selects a datasource, populates connections for the datasource, then updates the datasource. + +* `explore_workbook.py`. Queries workbooks, selects a workbook, populates the connections and views for a workbook, then updates the workbook. + +* `move_workbook_projects.py`. Updates the properties of a workbook to move the workbook from one project to another. + +* `move_workbook_sites.py`. Downloads a workbook, stores it in-memory, and uploads it to another site. + +* `pagination_sample.py`. Use the Pager generator to iterate over all the items on the server. + +* `publish_workbook.py`. Publishes a Tableau workbook. + +* `set_http_options.py`. Sets HTTP options for the server and specifically for downloading workbooks. + +**Note**: For all of the samples, ensure that your Tableau Server user account has permission to access the resources +requested by the samples. + diff --git a/docs/search.md b/docs/search.md new file mode 100644 index 000000000..c35daec37 --- /dev/null +++ b/docs/search.md @@ -0,0 +1,5 @@ +--- +title: Search +layout: search +--- + diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md new file mode 100644 index 000000000..f619aaeab --- /dev/null +++ b/docs/sign-in-out.md @@ -0,0 +1,39 @@ +--- +title: Sign In and Out +layout: docs +--- + +To sign in and out of Tableau Server, call the `Auth.sign_in` and `Auth.sign_out` functions like so: + +```py +import tableauserverclient as TSC + +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('http://SERVER_URL') + +server.auth.sign_in(tableau_auth) + +# Do awesome things here! + +server.auth.sign_out() +``` + +
+ Note: When you sign in, the TSC library manages the authenticated session for you, however it is still + limited by the maximum session length (of four hours) on Tableau Server. +
+ + +Alternatively, for short programs, consider using a `with` block: + +```py +import tableauserverclient as TSC + +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('http://SERVER_URL') + +with server.auth.sign_in(tableau_auth): + # Do awesome things here! +``` + +The TSC library signs you out of Tableau Server when you exit out of the `with` block. diff --git a/docs/versions.md b/docs/versions.md new file mode 100644 index 000000000..aae5c3bf8 --- /dev/null +++ b/docs/versions.md @@ -0,0 +1,55 @@ +--- +title: Versions +layout: docs +--- + +Because the TSC library is a client for the Tableau Server REST API, you need to confirm that the version of the TSC +library that you use is compatible with the version of the REST API used by your installation of Tableau Server. + +* TOC +{:toc} + +## Display the REST API version + +To display the default version of the REST API used by TSC, run the following code: + +```py +import tableauserverclient as TSC + +server = TSC.Server('http://SERVER_URL') + +print(server.version) +``` + +For example, the code might display version `2.3`. + +## Use another version of the REST API + +To use another version of the REST API, set the version like so: + +```py +import tableauserverclient as TSC + +server = TSC.Server('http://SERVER_URL') + +<<<<<<< HEAD +server.version = 2.4 +======= + +server.version = '2.6' + + + +>>>>>>> 87acd20... Update versions.md (#195) +``` + +## Supported versions + +The current version of TSC only supports the following REST API and Tableau Server versions: + +|REST API version|Tableau Server version| +|---|---| +|2.3|10.0| +|2.4|10.1| +|2.5|10.2| +|2.6|10.3| diff --git a/index.md b/index.md new file mode 100644 index 000000000..c0f9a4431 --- /dev/null +++ b/index.md @@ -0,0 +1,13 @@ +--- +layout: home +indexed_by_search: false +--- + +
+

Tableau Server Client (Python)

+

The Tableau Server Client is a Python library for the Tableau Server REST API.

+
+ Get Started   + Download +
+ diff --git a/js/lunr.min.js b/js/lunr.min.js new file mode 100644 index 000000000..22776bb85 --- /dev/null +++ b/js/lunr.min.js @@ -0,0 +1,6 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.7.2 + * Copyright (C) 2016 Oliver Nightingale + * @license MIT + */ +!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.7.2",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){if(!arguments.length||null==e||void 0==e)return[];if(Array.isArray(e))return e.map(function(e){return t.utils.asString(e).toLowerCase()});var n=t.tokenizer.seperator||t.tokenizer.separator;return e.toString().trim().toLowerCase().split(n)},t.tokenizer.seperator=!1,t.tokenizer.separator=/[\s\-]+/,t.tokenizer.load=function(t){var e=this.registeredFunctions[t];if(!e)throw new Error("Cannot load un-registered function: "+t);return e},t.tokenizer.label="default",t.tokenizer.registeredFunctions={"default":t.tokenizer},t.tokenizer.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing tokenizer: "+n),e.label=n,this.registeredFunctions[n]=e},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,r=0;n>r;r++){for(var o=t[r],s=0;i>s&&(o=this._stack[s](o,r,t),void 0!==o&&""!==o);s++);void 0!==o&&""!==o&&e.push(o)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(o===t)return r;t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r]}return o===t?r:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,r=e+Math.floor(i/2),o=this.elements[r];i>1;)t>o&&(e=r),o>t&&(n=r),i=n-e,r=e+Math.floor(i/2),o=this.elements[r];return o>t?r:t>o?r+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,r=0,o=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>o-1||r>s-1)break;a[i]!==h[r]?a[i]h[r]&&r++:(n.add(a[i]),i++,r++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone();for(var r=0,o=n.toArray();rp;p++)c[p]===a&&d++;h+=d/f*l.boost}}this.tokenStore.add(a,{ref:o,tf:h})}n&&this.eventEmitter.emit("add",e,this)},t.Index.prototype.remove=function(t,e){var n=t[this._ref],e=void 0===e?!0:e;if(this.documentStore.has(n)){var i=this.documentStore.get(n);this.documentStore.remove(n),i.forEach(function(t){this.tokenStore.remove(t,n)},this),e&&this.eventEmitter.emit("remove",t,this)}},t.Index.prototype.update=function(t,e){var e=void 0===e?!0:e;this.remove(t,!1),this.add(t,!1),e&&this.eventEmitter.emit("update",t,this)},t.Index.prototype.idf=function(t){var e="@"+t;if(Object.prototype.hasOwnProperty.call(this._idfCache,e))return this._idfCache[e];var n=this.tokenStore.count(t),i=1;return n>0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(this.tokenizerFn(e)),i=new t.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*o,h=this,u=this.tokenStore.expand(e).reduce(function(n,r){var o=h.corpusTokens.indexOf(r),s=h.idf(r),u=1,l=new t.SortedSet;if(r!==e){var c=Math.max(3,r.length-e.length);u=1/Math.log(c)}o>-1&&i.insert(o,a*s*u);for(var f=h.tokenStore.get(r),d=Object.keys(f),p=d.length,v=0;p>v;v++)l.add(f[d[v]].ref);return n.union(l)},new t.SortedSet);r.push(u)},this);var a=r.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,r=new t.Vector,o=0;i>o;o++){var s=n.elements[o],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);r.insert(this.corpusTokens.indexOf(s),a*h)}return r},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,tokenizer:this.tokenizerFn.label,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",r=n+"[^aeiouy]*",o=i+"[aeiou]*",s="^("+r+")?"+o+r,a="^("+r+")?"+o+r+"("+o+")?$",h="^("+r+")?"+o+r+o+r,u="^("+r+")?"+i,l=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(u),p=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,g=/^(.+?)eed$/,m=/^(.+?)(ed|ing)$/,y=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),k=new RegExp("^"+r+i+"[^aeiouwxy]$"),x=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,F=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,_=/^(.+?)(s|t)(ion)$/,z=/^(.+?)e$/,O=/ll$/,P=new RegExp("^"+r+i+"[^aeiouwxy]$"),T=function(n){var i,r,o,s,a,h,u;if(n.length<3)return n;if(o=n.substr(0,1),"y"==o&&(n=o.toUpperCase()+n.substr(1)),s=p,a=v,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=g,a=m,s.test(n)){var T=s.exec(n);s=l,s.test(T[1])&&(s=y,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,u=k,a.test(n)?n+="e":h.test(n)?(s=y,n=n.replace(s,"")):u.test(n)&&(n+="e"))}if(s=x,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+t[r])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],r=T[2],s=l,s.test(i)&&(n=i+e[r])}if(s=F,a=_,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=z,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=P,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=O,a=c,s.test(n)&&a.test(n)&&(s=y,n=n.replace(s,"")),"y"==o&&(n=o.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.generateStopWordFilter=function(t){var e=t.reduce(function(t,e){return t[e]=e,t},{});return function(t){return t&&e[t]!==t?t:void 0}},t.stopWordFilter=t.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){return t.replace(/^\W+/,"").replace(/\W+$/,"")},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t.charAt(0),r=t.slice(1);return i in n||(n[i]={docs:{}}),0===r.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(r,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n" + title + ""; + container.innerHTML += "

" + getResultBlurb(search_blob[ref].content) + "...


"; + } + } + } else { + container.innerHTML += "
No results found.
"; + } + } + + addContentToIndex(); + window.addEventListener("load", function () { + displaySearchHeading(searchQuery); + displaySearchResults(getRawSearchResults(searchQuery)); + }); + +})(); From 45c63ebfb8952584ee9dc83b72de6f67730eb3b9 Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Tue, 10 Apr 2018 10:48:50 -0700 Subject: [PATCH 002/158] removing merge text Merge comments were added when content was updated on master. --- docs/versions.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/versions.md b/docs/versions.md index aae5c3bf8..a4eff325d 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -32,15 +32,9 @@ import tableauserverclient as TSC server = TSC.Server('http://SERVER_URL') -<<<<<<< HEAD -server.version = 2.4 -======= server.version = '2.6' - - ->>>>>>> 87acd20... Update versions.md (#195) ``` ## Supported versions From c8e05d55d35057b3606841aee656c37988a06073 Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Wed, 25 Apr 2018 17:06:09 -0700 Subject: [PATCH 003/158] D45 docs v06.1 (partial update) (#290) * Updating dev guide with gh-pages info for docs * Moving the Dev Guide up in the TOC pane * Update dev-guide.md Added Tyler's correction for pycodestyle. --- _includes/docs_menu.html | 15 ++++++++++++--- _layouts/docs.html | 2 +- docs/dev-guide.md | 39 ++++++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/_includes/docs_menu.html b/_includes/docs_menu.html index 104a1f5b3..2f5ab1b04 100644 --- a/_includes/docs_menu.html +++ b/_includes/docs_menu.html @@ -22,6 +22,9 @@
  • Samples
  • +
  • + Developer Guide +
  • API Reference
  • -
  • - Developer Guide -
  • diff --git a/_layouts/docs.html b/_layouts/docs.html index 5355f63df..d40bafbdf 100644 --- a/_layouts/docs.html +++ b/_layouts/docs.html @@ -17,7 +17,7 @@

    {{ page.title }}

    diff --git a/docs/dev-guide.md b/docs/dev-guide.md index 8b47609ce..3a51e86c6 100644 --- a/docs/dev-guide.md +++ b/docs/dev-guide.md @@ -8,8 +8,15 @@ This topic describes how to contribute to the Tableau Server Client (Python) pro * TOC {:toc} +--- + ## Submit your first patch + +This section will get you started with the basic workflow, describing how to create your own fork of the repository and how to open a pull request (PR) to add your contributions to the **development** branch. + +### Get the source code and set up your branch + 1. Make sure you have [signed the CLA](http://tableau.github.io/#contributor-license-agreement-cla) 1. Fork the repository. @@ -36,45 +43,47 @@ This topic describes how to contribute to the Tableau Server Client (Python) pro git checkout -b 13-feature-new-stuff ``` -1. Code and commit! +### Code and commit - Here's a quick checklist for ensuring a good pull request: + Here's a quick checklist to follow when coding to ensure a good pull request (PR): - - Only touch the minimal amount of files possible while still accomplishing the goal. + - Only touch the fewest number of files possible while still accomplishing the goal. - Ensure all indentation is done as 4-spaces and your editor is set to unix line endings. - - The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle .` + - The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle server-client-python test samples` - Keep commit messages clean and descriptive. If the PR is accepted it will get 'Squashed' into a single commit before merging, the commit messages will be used to generate the Merge commit message. -1. Add tests. +### Add tests All of our tests live under the `test/` folder in the repository. - We use `unittest` and the built-in test runner `python setup.py test`. - If a test needs a static file, like a twb/twbx, it should live under `test/assets/` + We use `pytest` and the built-in test runner `python setup.py test`. + If a test needs a static file, like a .twb/.twbx, it should live under `test/assets/` -1. Update the documentation. - - Our documentation is written in markdown and built with Jekyll on Github Pages. All of the documentation source files can be found in `docs/docs`. +### Update the documentation When adding a new feature or improving existing functionality we may ask that you update the documentation along with your code. - If you are just making a PR for documentation updates (adding new docs, fixing typos, improving wording) the easiest method is to use the built in `Edit this file` in the Github UI + Our documentation is written in markdown and built with Jekyll on GitHub Pages. All of the documentation source files can be found in `/docs` folder in the **gh-pages** branch. The docs are hosted on the following URL: [https://tableau.github.io/server-client-python](https://tableau.github.io/server-client-python) + + If you are just making documentation updates (adding new docs, fixing typos, improving wording) the easiest method is to use the built-in `Edit this file` feature right in GitHub (click the pencil icon). If you are viewing one of the pages on [https://tableau.github.io/server-client-python](https://tableau.github.io/server-client-python), clicking the **Edit this page** link at the top of the page will take you to the same place. -1. Submit to your fork. +### Commit changes to your fork and open a PR -1. Make a PR as described [here](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the 'development' branch. +1. Make a PR as described [here](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) against the **development** branch for code changes, or against **gh-pages** for documentation updates. 1. Wait for a review and address any feedback. While we try and stay on top of all issues and PRs it might take a few days for someone to respond. Politely pinging the PR after a few days with no response is OK, we'll try and respond with a timeline as soon as we are able. -1. That's it! When the PR has received :rocket:'s from members of the core team they will merge the PR +1. That's it! When the PR has received ![](https://assets-cdn.github.com/images/icons/emoji/unicode/1f680.png){:height="5%" width="5%"} (:rocket:'s) from members of the core team they will merge the PR + +--- ## Add new features 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, + has `get`, `post`, `update`, and `delete` operations that require making the url, creating the XML request if necessary, sending the request, and creating the target item object based on the server response. 1. Create an item class for the new feature, following the structure of the other item classes. Each item has properties From d09420ea1a8f326edf7b721953ba5b2949c2197c Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Mon, 4 Jun 2018 17:47:17 -0700 Subject: [PATCH 004/158] D45 docs v06.1 (#300) * Updating dev guide with gh-pages info for docs * Moving the Dev Guide up in the TOC pane * Update dev-guide.md Added Tyler's correction for pycodestyle. * Updating ref pages from v4.1 to v6.1 * Update dev-guide.md Updated command to: pycodestyle tableauserverclient test samples * Update versions.md updated example to use the more compact and elegant: `use_server_version=True` --- docs/api-ref.md | 747 +++++++++++++++++++++++++++++++++++++++++++--- docs/dev-guide.md | 2 +- docs/versions.md | 20 +- 3 files changed, 730 insertions(+), 39 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index d0ac648d1..9cb3daa06 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -25,6 +25,7 @@ The TSC API reference is organized by resource. The TSC library is modeled after

    +--- ## Authentication @@ -151,7 +152,7 @@ server.auth.sign_out()

    - +--- ## Connections @@ -217,6 +218,8 @@ Source file: models/connection_credentials.py

    +--- + ## Data sources Using the TSC library, you can get all the data sources on a site, or get the data sources for a specific project. @@ -238,7 +241,9 @@ Name | Description :--- | :--- `connections` | The list of data connections (`ConnectionItem`) for the specified data source. You must first call the `populate_connections` method to access this data. See the [ConnectionItem class](#connectionitem-class). `content_url` | The name of the data source as it would appear in a URL. -`created_at` | The date and time when the data source was created. +`created_at` | The date and time when the data source was created. +`certified` | A Boolean value that indicates whether the data source is certified. +`certification_note` | The optional note that describes the certified data source. `datasource_type` | The type of data source, for example, `sqlserver` or `excel-direct`. `id` | The identifier for the data source. You need this value to query a specific data source or to delete a data source with the `get_by_id` and `delete` methods. `name` | The name of the data source. If not specified, the name of the published data source file is used. @@ -305,10 +310,10 @@ REST API: [Delete Datasource](http://onlinehelp.tableau.com/v0.0/api/rest_api/en #### datasources.download ```py -datasources.download(datasource_id, filepath=None, no_extract=False) +datasources.download(datasource_id, filepath=None, include_extract=True, no_extract=None) ``` -Downloads the specified data source in `.tdsx` format. +Downloads the specified data source in `.tdsx` or `.hyper` format. REST API: [Download Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Download_Datasource%3FTocPath%3DAPI%2520Reference%7C_____34){:target="_blank"} @@ -318,7 +323,8 @@ Name | Description :--- | :--- `datasource_id` | The identifier (`id`) for the `DatasourceItem` that you want to download from the server. `filepath` | (Optional) Downloads the file to the location you specify. If no location is specified (the default is `Filepath=None`), the file is downloaded to the current working directory. -`no_extract` | (Optional) Specifies whether to download the file without the extract. When the data source has an extract, if you set the parameter `no_extract=True`, the extract is not included. You can use this parameter to improve performance if you are downloading data sources that have large extracts. The default is to include the extract, if present (`no_extract=False`). Available starting with Tableau Server REST API version 2.5. +`include_extract` | (Optional) Specifies whether to download the file with the extract. The default is to include the extract, if present (`include_extract=True`). When the data source has an extract, if you set the parameter `include_extract=False`, the extract is not included. You can use this parameter to improve performance if you are downloading data sources that have large extracts. Available starting with Tableau Server REST API version 2.5. +`no_extract` | (**Deprecated**) Use `include_extract` instead. The default value is to ignore this parameter (`no_extract=None`). If you set the parameter to `no_extract=True`, the download will not include an extract (if there is one). If set to `no_extract=False`, the download will include the extract (if there is one). Available starting with Tableau Server REST API version 2.5. **Exceptions** @@ -329,7 +335,7 @@ Error | Description **Returns** -The file path to the downloaded data source. The data source is downloaded in `.tdsx` format. +The file path to the downloaded data source. The data source is downloaded in `.tdsx` or `.hyper` format. **Example** @@ -338,10 +344,10 @@ The file path to the downloaded data source. The data source is downloaded in `. file_path = server.datasources.download('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') print("\nDownloaded the file to {0}.".format(file_path)) -```` +``` -
    +

    #### datasources.get @@ -365,7 +371,7 @@ Name | Description **Returns** -Returns a list of `DatasourceItem` objects and a `PaginationItem` object. Use these values to iterate through the results. +Returns a list of `DatasourceItem` objects and a `PaginationItem` object. Use these values to iterate through the results. @@ -381,12 +387,12 @@ with server.auth.sign_in(tableau_auth): all_datasources, pagination_item = server.datasources.get() print("\nThere are {} datasources on site: ".format(pagination_item.total_available)) print([datasource.name for datasource in all_datasources]) -```` +``` -
    -
    +
    +
    #### datasources.get_by_id @@ -514,7 +520,7 @@ Name | Description `datasource_item` | The `datasource_item` specifies the new data source you are adding, or the data source you are appending to. If you are adding a new data source, you need to create a new `datasource_item` with a `project_id` of an existing project. The name of the data source will be the name of the file, unless you also specify a name for the new data source when you create the instance. See [DatasourceItem](#datasourceitem-class). `file_path` | The path and name of the data source to publish. `mode` | Specifies whether you are publishing a new data source (`CreateNew`), overwriting an existing data source (`Overwrite`), or appending data to a data source (`Append`). If you are appending to a data source, the data source on the server and the data source you are publishing must be be extracts (.tde files) and they must share the same schema. You can also use the publish mode attributes, for example: `TSC.Server.PublishMode.Overwrite`. -`connection_credentials` | (Optional) The credentials required to connect to the data source. The `ConnectionCredentials` object contains the authentication information for the data source (user name and password, and whether the credentials are embeded or OAuth is used). +`connection_credentials` | (Optional) The credentials required to connect to the data source. The `ConnectionCredentials` object contains the authentication information for the data source (user name and password, and whether the credentials are embedded or OAuth is used). @@ -524,7 +530,7 @@ Error | Description :--- | :--- `File path does not lead to an existing file.` | Raises an error of the file path is incorrect or if the file is missing. `Invalid mode defined.` | Raises an error if the publish mode is not one of the defined options. -`Only .tds, tdsx, or .tde files can be published as datasources.` | Raises an error if the type of file specified is not supported. +`Only .tds, tdsx, .tde, or .hyper files can be published as datasources.` | Raises an error if the type of file specified is not supported. **Returns** @@ -607,8 +613,36 @@ An updated `DatasourceItem`. ``` +
    +
    + +#### datasource.update_connection + +```py +datasource.update_connection(datasource_item, connection_item) +``` + +Updates the server address, port, username, or password for the specified data source connection. + +REST API: [Update Datasource Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Datasource_Connection){:target="_blank"} +**Parameters** + +Name | Description + :--- | : --- +`datasource_item` | The `datasource_item` specifies the data source to update. +`connection_item` | The `connection_item` that has the information you want to update. + + +**Returns** + +An updated `ConnectionItem` for the data source. + +**Example** + +See the `update_connection.py` sample in the Samples directory. +

    @@ -622,7 +656,7 @@ You can use the `Filter` and `RequestOptions` classes to filter and sort the fol - Users - Datasources - Workbooks -- Views +- Views For more information, see [Filter and Sort](filter-sort). @@ -652,6 +686,7 @@ Name | Description

    +--- ## Groups @@ -738,7 +773,7 @@ None. ```py # Adding a user to a group -# +# # get the group item all_groups, pagination_item = server.groups.get() mygroup = all_groups[1] @@ -856,7 +891,7 @@ groups.get(req_options=None) Returns information about the groups on the site. -To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulateusers) method. +To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulate_users) method. REST API: [Get Uers on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_on_Site%3FTocPath%3DAPI%2520Reference%7C_____41){:target="_blank"} @@ -889,7 +924,7 @@ Returns a list of `GroupItem` objects and a `PaginationItem` object. Use these # print the names of the first 100 groups for group in all_groups : print(group.name, group.id) -```` +```
    @@ -1011,8 +1046,120 @@ None. The user is removed from the group.

    +--- + +## Jobs + +Using the TSC library, you can get information about an asynchronous process (or *job*) on the server. These jobs can be created when Tableau runs certain tasks that could be long running, such as importing or synchronizing users from Active Directory, or running an extract refresh. For example, the REST API methods to create or update groups, to run an extract refresh task, or to publish workbooks can take an `asJob` parameter (`asJob-true`) that creates a background process (the *job*) to complete the call. Information about the asynchronous job is returned from the method. + +If you have the identifer of the job, you can use the TSC library to find out the status of the asynchronous job. + +The job properties are defined in the `JobItem` class. The class corresponds to the properties for jobs you can access using the Tableau Server REST API. The job methods are based upon the endpoints for jobs in the REST API and operate on the `JobItem` class. + + +### JobItem class + +```py +JobItem(id, type, created_at, started_at=None, completed_at=None, finish_code=0) + +``` + +The `JobItem` class contains information about the specified job running on Tableau Server. The `JobItem` class defines the information you can query from Tableau Server. The class members correspond to the attributes of a server response payload. + +Source file: models/job_item.py + +**Attributes** + +Name | Description +:--- | :--- +`id` | The `id` of the job. +`type` | The type of task. The types correspond to the job type categories listed for the [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Job){:target="_blank"} REST API. +`created_at` | The time the job was created. +`started_at` | The time the job started. +`completed_at` | The time the job finished. +`finish_code` | The return code from job. + + +### Jobs methods +The Jobs methods are based upon the endpoints for jobs in the REST API and operate on the `JobItem` class. + + +Source files: server/endpoint/jobs_endpoint.py + +
    +
    + + +#### jobs.get + + +```py +jobs.get(job_id) + +``` + +Gets information about the specified job. + +REST API: [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Job){:target="_blank"} + + +**Parameters** + +Name | Description +:--- | :--- +`job_id` | The `job_id` specifies the id of the job that is returned from an asynchronous task, such as extract refresh, or an import or update to groups using Active Directory + + + + +**Exceptions** + +Error | Description +:--- | :--- +`404018 Resource Not Found` | Raises an error if the `job_id` is not found. + + +**Returns** + +Returns the `JobItem` requested. + + +**Example** + +```py +# Query a Job + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +# server = TSC.Server('http://SERVERURL') + + with server.auth.sign_in(tableau_auth): + + # get the id of the job from response to extract refresh task, + # or another asynchronous REST API call. + # in this case, "576b616d-341a-4539-b32c-1ed0eb9db548" + + + myJobId = '576b616d-341a-4539-b32c-1ed0eb9db548' + jobinfo = server.jobs.get(myJobID) + + print(jobinfo) + + # + + + + +``` + + +
    +
    + +--- + ## Projects Using the TSC library, you can get information about all the projects on a site, or you can create, update projects, or remove projects. @@ -1029,7 +1176,7 @@ The project resources for Tableau are defined in the `ProjectItem` class. The cl ```py -ProjectItem(name, description=None, content_permissions=None) +ProjectItem(name, description=None, content_permissions=None, parent_id=None) ``` The project resources for Tableau are defined in the `ProjectItem` class. The class corresponds to the project resources you can access using the Tableau Server REST API. @@ -1042,6 +1189,7 @@ Name | Description `name` | Name of the project. `description` | The description of the project. `id` | The project id. +`parent_id` | The id of the parent project. Use this option to create project hierarchies. For information about managing projects, project hierarchies, and permissions, see [Use Projects to Manage Content Access](http://onlinehelp.tableau.com/current/server/en-us/projects.htm){:target="_blank"}. @@ -1050,7 +1198,7 @@ Source file: models/project_item.py #### ProjectItem.ContentPermissions -The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"} +The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"}. Name | Description :--- | :--- @@ -1091,7 +1239,7 @@ The project methods are based upon the endpoints for projects in the REST API an Source files: server/endpoint/projects_endpoint.py
    -
    +
    #### projects.create @@ -1288,6 +1436,7 @@ Error | Description

    +--- ## Requests @@ -1301,11 +1450,16 @@ You can use the `Sort` and `RequestOptions` classes to filter and sort the follo - Workbooks - Views -For more information, see [Filter and Sort](filter-sort). + +You can use the `ImageRequestOptions` and `PDFRequestOptions` to set options for views returned as images and PDF files. + +For more information about filtering and sorting, see [Filter and Sort](filter-sort). +
    + ### RequestOptions class ```py @@ -1319,7 +1473,7 @@ RequestOptions(pagenumber=1, pagesize=100) Name | Description :--- | :--- -`pagenumber` | The page number of the returned results. The defauilt value is 1. +`pagenumber` | The page number of the returned results. The default value is 1. `pagesize` | The number of items to return with each page (the default value is 100). `sort()` | Returns a iterable set of `Sort` objects. `filter()` | Returns an iterable set of `Filter` objects. @@ -1387,10 +1541,299 @@ Name | Description `Desc` | Sets the sort direction to descending (`TSC.RequestOptions.Direction.Desc`). + +### ImageRequestOptions class + +```py +ImageRequestOptions(imageresolution=None) + +``` +Use this class to specify the resolution of the view returned as an image. See `views.populate_view`. + +**Attributes** + +Name | Description +:--- | :--- +`imageresolution` | The resolution of the view returned as an image. You set this option with the `Resolution` class. If unspecified, the `views.populate_view` method returns an image with standard resolution (the width of the returned image is 784 pixels). If you set this parameter value to high (`Resolution.High`), the width of the returned image is 1568 pixels. For both resolutions, the height varies to preserve the aspect ratio of the view. + + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, get a specific view, etc. + +# set the image request option +image_req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High) + +# retrieve the image for the view +server.views.populate_image(view_item, image_req_option) + +``` + +### PDFRequestOptions class + +```py +PDFRequestOptions(page_type=None, orientation=None) + +``` +Use this class to specify the format of the PDF that is returned for the view. See `views.populate_pdf`. + +**Attributes** + +Name | Description +:--- | :--- +`page_type` | The type of page returned in PDF format for the view. The page_type is set using the `PageType` class:
    `PageType.A3`
    `PageType.A4`
    `PageType.A5`
    `PageType.B5`
    `PageType.Executive`
    `PageType.Folio`
    `PageType.Ledger`
    `PageType.Legal`
    `PageType.Letter`
    `PageType.Note`
    `PageType.Quarto`
    `PageType.Tabloid` +`orientation` | The orientation of the page. The options are portrait and landscape. The options are set using the `Orientation` class:
    `Orientation.Portrait`
    `Orientation.Landscape` + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, get a specific view, etc. + +# set the PDF request options +pdf_req_option = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A4, orientation=TSC.PDFRequestOptions.Orientation.Landscape) + +# retrieve the PDF for a view +server.views.populate_pdf(view_item, pdf_req_option) + +``` + + +
    +
    + +--- + +## Schedules + +Using the TSC library, you can schedule extract refresh or subscription tasks on Tableau Server. You can also get and update information about the scheduled tasks, or delete scheduled tasks. + +If you have the identifer of the job, you can use the TSC library to find out the status of the asynchronous job. + +The schedule properties are defined in the `ScheduleItem` class. The class corresponds to the properties for schedules you can access in Tableau Server or by using the Tableau Server REST API. The Schedule methods are based upon the endpoints for jobs in the REST API and operate on the `JobItem` class. + + +### ScheduleItem class + +```py +ScheduleItem(name, priority, schedule_type, execution_order, interval_item) + +``` + +The `ScheduleItem` class contains information about the specified schedule running on Tableau Server. The `ScheduleItem` class defines the information you can query and set. The class members correspond to the attributes of a server response payload. + +Source file: models/schedule_item.py + +**Attributes** + +Name | Description +:--- | :--- +`name` | The `name` of the schedule. +`id` | The identifier for the schedule. Use the `schedules.get()` method to get the identifiers of the schedules on the server. +`schedule_type` | The type of task. The types are either an `Extract` for an extract refresh task or a `Subscription` for a scheduled subscription. +`execution_order` | Specifies how the scheduled task should run. The choices are `Parallel`which uses all available background processes for this scheduled task, or `Serial`, which limits this schedule to one background process. +`interval_item` | Specifies the frequency that the scheduled task should run. The `interval_item` is an instance of the `IntervalItem` class. The `interval_item` has properties for frequency (hourly, daily, weekly, monthly), and what time and date the scheduled item runs. You set this value by declaring an `IntervalItem` object that is one of the following: `HourlyInterval`, `DailyInterval`, `WeeklyInterval`, or `MonthlyInterval`. + + +#### IntervalItem class +This class sets the frequency and start time of the scheduled item. This class contains the classes for the hourly, daily, weekly, and monthly intervals. This class mirrors the options you can set using the REST API and the Tableau Server interface. + +**Attributes** + +Name | Description +:--- | :--- +`HourlyInterval` | Runs scheduled item hourly. To set the hourly interval, you create an instance of the `HourlyInterval` class and assign the following values: `start_time`, `end_time`, and `interval_value`. To set the `start_time` and `end_time`, assign the time value using this syntax: `start_time=time(`*hour*`,` *minute*`)` and `end_time=time(`*hour*`,` *minute*`)`. The *hour* is specified in 24 hour time. The `interval_value` specifies how often the to run the task within the start and end time. The options are expressed in hours. For example, `interval_value=.25` is every 15 minutes. The values are `.25`, `.5`, `1`, `2`, `4`, `6`, `8`, `12`. +`DailyInterval` | Runs the scheduled item daily. To set the daily interval, you create an instance of the `DailyInterval` and assign the `start_time`. The start time uses the syntax `start_time=time(`*hour*`,` *minute*`)`. +`WeeklyInterval` | Runs the scheduled item once a week. To set the weekly interval, you create an instance of the `WeeklyInterval` and assign the start time and multiple instances for the `interval_value` (days of week and start time). The start time uses the syntax `time(`*hour*`,` *minute*`)`. The `interval_value` is the day of the week, expressed as a `IntervalItem`. For example `TSC.IntervalItem.Day.Monday` for Monday. +`MonthlyInterval` | Runs the scheduled item once a month. To set the monthly interval, you create an instance of the `MonthlyInterval` and assign the start time and day. The + + + + +### Schedule methods + +The schedule methods are based upon the endpoints for schedules in the REST API and operate on the `ScheduleItem` class. + + +Source files: server/endpoint/schedules_endpoint.py + +#### schedule.create + +```py +schedule.create(schedule_item) +``` +Creates a new schedule for an extract refresh or a subscription. + + +REST API: [Create Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Schedule%3FTocPath%3DAPI%2520Reference%7C_____21){:target="_blank"} + + + +**Parameters** + +Name | Description +:--- | :--- +`schedule_item` | The settings for the schedule that you want to create. You need to create an instance of `schedule_item` and pass it to the `create` method. The `schedule_item` includes the `interval_item` which specifies the frequency, or interval, that the schedule should run. See `ScheduleItem` and `IntervalItem`. + + +**Returns** + +Returns a new instance of `schedule_item`. + +**Exceptions** + +Error | Description +:--- | :--- +`Interval item must be defined.` | Raises an exception if the `schedule_item.interval_item` is not specified. The interval item specifies whether the interval is hourly, daily, weekly, or monthly. + + +**Example** + +```py +import tableauserverclient as TSC +# sign in, etc. + # Create an interval to run every 2 hours between 2:30AM and 11:00PM + hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), + end_time=time(23, 0), + interval_value=2) + # Create schedule item + hourly_schedule = TSC.ScheduleItem("Hourly-Schedule", 50, TSC.ScheduleItem.Type.Extract, TSC.ScheduleItem.ExecutionOrder.Parallel, hourly_interval) + # Create schedule + hourly_schedule = server.schedules.create(hourly_schedule) +```

    +#### schedule.delete + +```py +schedule.delete(schedule_id) +``` + +Deletes an existing schedule for an extract refresh or a subscription. + + +REST API: [Delete Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Schedule%3FTocPath%3DAPI%2520Reference%7C_____31){:target="_blank"} + + + +**Parameters** + +Name | Description +:--- | :--- +`schedule_id` | The identifier (`schedule_item.id`) of the schedule to delete. Use the `schedule.get()` method to get the identifiers of the schedules on the server. + + +**Returns** + +None. + +**Exceptions** + +Error | Description +:--- | :--- +`Schedule ID undefined` | The identifier is not a valid identifier for a schedule on the server. + + +#### schedule.get + +```py +schedule.get([req_options=None]) +``` + +Returns all schedule items from the server. + + +REST API: [Query Schedules](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Schedules%3FTocPath%3DAPI%2520Reference%7C_____65){:target="_blank"} + + + +**Parameters** + +Name | Description +:--- | :--- +`req_options` | (Optional) To filter the return items, you can specify request options. See Requests and . + +#### schedule.update + +
    +
    + + +**Hourly schedule example** +```py +import tableauserverclient as TSC +# sign in, etc. + # Create an interval to run every 2 hours between 2:30AM and 11:00PM + hourly_interval = TSC.HourlyInterval(start_time=time(2, 30), + end_time=time(23, 0), + interval_value=2) + # Create schedule item + hourly_schedule = TSC.ScheduleItem("Hourly-Schedule", 50, TSC.ScheduleItem.Type.Extract, TSC.ScheduleItem.ExecutionOrder.Parallel, hourly_interval) + # Create schedule + hourly_schedule = server.schedules.create(hourly_schedule) +``` + +**Daily schedule example** +```py +import tableauserverclient as TSC +# sign in, etc. + # Create a daily interval to run every day at 12:30AM + Daily_interval = TSC.DailyInterval(start_time=time(0, 30)) + # Create schedule item using daily interval + daily_schedule = TSC.ScheduleItem("Daily-Schedule", 60, TSC.ScheduleItem.Type.Subscription, TSC.ScheduleItem.ExecutionOrder.Serial, daily_interval) + # Create daily schedule + daily_schedule = server.schedules.create(daily_schedule) + +``` + +**Weekly schedule example** +```py +import tableauserverclient as TSC +# sign in, etc. + # Create a weekly interval to run every Monday, Wednesday, and Friday at 7:15PM + weekly_interval = TSC.WeeklyInterval(time(19, 15), + TSC.IntervalItem.Day.Monday, + TSC.IntervalItem.Day.Wednesday, + TSC.IntervalItem.Day.Friday) + # Create schedule item using weekly interval + weekly_schedule = TSC.ScheduleItem("Weekly-Schedule", 70, + TSC.ScheduleItem.Type.Extract, + TSC.ScheduleItem.ExecutionOrder.Serial, weekly_interval) + # Create weekly schedule + weekly_schedule = server.schedules.create(weekly_schedule) + +``` + +**Monthly schedule example** +```py +import tableauserverclient as TSC +# sign in, etc. + # Create a monthly interval to run on the 15th of every month at 11:30PM + monthly_interval = TSC.MonthlyInterval(start_time=time(23, 30), + interval_value=15) + # Create schedule item using monthly interval + monthly_schedule = TSC.ScheduleItem("Monthly-Schedule", 80, + TSC.ScheduleItem.Type.Subscription + TSC.ScheduleItem.ExecutionOrder.Parallel, monthly_interval) + # Create monthly schedule + monthly_schedule = server.schedules.create(monthly_schedule) +``` + + + +
    +
    + +--- + ## Server @@ -1423,13 +1866,18 @@ Attribute | Description ```py import tableauserverclient as TSC + # create a instance of server server = TSC.Server('http://MY-SERVER') +# sign in, etc. -# change the REST API version to 2.5 -server.version = '2.5' +# change the REST API version to match the server +server.use_server_version() +# or change the REST API version to match a specific version +# for example, 2.8 +# server.version = '2.8' ``` @@ -1445,11 +1893,13 @@ Resource | Description *server*.views | Access the server views and methods. See [Views](#views) *server*.users | Access the user resources and methods. See [Users](#users) *server*.sites | Access the sites. See [Sites](#sites) -*server*.groups | Access the groups resources and methods. See [Groups](#groups) +*server*.groups | Access the groups resources and methods. See [Groups](#groups) +*server*.jobs | Access the jobs resources and methods. See [Jobs](#jobs) *server*.workbooks | Access the resources and methods for workbooks. See [Workbooks](#workbooks) *server*.datasources | Access the resources and methods for data sources. See [Data Sources](#data-sources) *server*.projects | Access the resources and methods for projects. See [Projects](#projets) *server*.schedules | Access the resources and methods for schedules. See [Schedules](#Schedules) +*server*.subscriptions | Access the resources and methods for subscriptions. See [Subscriptions](#subscriptions) *server*.server_info | Access the resources and methods for server information. See [ServerInfo class](#serverinfo-class)
    @@ -1472,7 +1922,9 @@ Resource | Description **Example** ```py - + import tableauserverclient as TSC + # login, etc. + print(TSC.Server.PublishMode.Overwrite) # prints 'Overwrite' @@ -1562,6 +2014,7 @@ print("\tBuild number: {0}".format(s_info.build_number))

    +--- ## Sites @@ -1642,7 +2095,7 @@ REST API: [Create Site](https://onlinehelp.tableau.com/current/api/rest_api/en-u Name | Description :--- | :--- -`site_item` | The settings for the site that you want to create. You need to create an instance of `SiteItem` and pass the `create` method. +`site_item` | The settings for the site that you want to create. You need to create an instance of `SiteItem` and pass it to the `create` method. **Returns** @@ -1702,7 +2155,7 @@ Returns a list of all `SiteItem` objects and a `PaginationItem`. Use these value all_sites, pagination_item = server.sites.get() # print all the site names and ids - for site in TSC.Pager(server.sites): + for site in all_sites): print(site.id, site.name, site.content_url, site.state) @@ -1906,7 +2359,7 @@ server.sites.delete('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d')

    - +--- ## Sort @@ -1956,8 +2409,228 @@ For information about using the `Sort` class, see [Filter and Sort](filter-sort)

    +--- + +## Subscriptions + +Using the TSC library, you can manage subscriptions to views or workbooks on a site. You can get information about all the subscriptions on a site, or information about a specific subscription on a site, and you can create, update, or delete subscriptions. + +### SubscriptionItem class + +The subscription resources for Tableau Server are defined in the `SubscriptionItem` class. The class corresponds to the subscription resources you can access using the Tableau Server REST API. The subscription methods are based upon the endpoints for subscriptions in the REST API and operate on the `SubscriptionItem` class. + +```py +SubscriptionItem(subject, schedule_id, user_id, target) + +``` + +**Attributes** + +Name | Description +:--- | :--- +`id` | The id of the subscription on the site. +`subject`| The subject of the subscription. This is the description that you provide to identify the subscription. +`schedule_id` | The identifier associated with the specific subscription. +`user_id` | The identifier of the user (person) who receives the subscription. +`target` | The target of the subscription, that is, the content that is subscribed to (view, workbook). The target is an instance of the `target` class. The `target` has two properties, the `id` of the workbook or view (`target.id`), and the `type` (`target.type`), which can either `view` or `workbook`. + + + + +Source files: server/endpoints/subscription_item.py + + +### Subscription methods + +The Tableau Server Client provides several methods for interacting with subscription resources, or endpoints. These methods correspond to endpoints in the Tableau Server REST API. + + + +Source files: server/endpoints/subscriptions_endpoint.py + +
    +
    + +#### subscription.create + +```py +subscription.create(subscription_item) +``` +Creates a subscription to a view or workbook for a specific user. +When a user is subscribed to the content, Tableau Server sends the content to the user in email on the schedule that's defined on Tableau Server and specified in the `subscription_item`. + +To create a new subscription you need to first create a new `subscription_item` (from `SubscriptionItem` class). + + +REST API: [Create Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Subscription%3FTocPath%3DAPI%2520Reference%7C_____23){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`subscription_item` | Specifies the user to subscribe, the content to subscribe to, the schedule to associate the subscription with, and the subject, or description for the subscription. + + +**Returns** + +Returns the new `SubscriptionItem` object. + + + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('server') +# create auth, specify site +# login, etc. + + +# create the target (content) of the subscription +# in this case, id of the workbook add the target type "workbook" + + target = ('c7a9327e-1cda-4504-b026-ddb43b976d1d', 'workbook') + +# the ids for the schedule and user + schedule = ('b60b4efd-a6f7-4599-beb3-cb677e7abac1') + user = 'b60b4efd-a6f7-4599-beb3-cb677e7abac1' + +# create a new SubscriptionItem object. + newSub = TSC.SubscriptionItem('My Subscription', schedule, user, target) + +# create the new subscription to the site + newSub = server.subscriptions.create(newSub) + print(newUSub.subject) + +``` + + +
    +
    + + + +#### subscriptions.delete + +```py +subscriptions.delete(subscription_id) +``` + + + +Deletes the specified subscription from the site. + +REST API: [Delete Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Subscription%3FTocPath%3DAPI%2520Reference%7C_____33){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`subscription_id` | The identifier (`id`) for the subscription that you want to remove from the site. + + +**Exceptions** + +Error | Description + :--- | : --- +`Subscription ID undefined` | Raises an exception if a valid `subscription_id` is not provided. + + +**Example** + +```py +# Remove a subscription from the site + +# import tableauserverclient as TSC +# tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='SITE') +# server = TSC.Server('http://SERVERURL') + + + with server.auth.sign_in(tableau_auth): + server.subscriptions.delete('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + +``` +
    +
    + +
    +
    + +#### subscription.get + +```py +subscription.get(req_options=None) +``` +Returns information about the subscriptions on the specified site. + + +REST API: [Query Subscriptions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Subscriptions%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific subscription, you could specify the subject of the subscription or the id of the subscription. + + +**Returns** +Returns a list of `SubscriptionItem` objects and a `PaginationItem` object. Use these values to iterate through the results. + + +
    +
    + +#### subscription.get_by_id + + +```py +subscription.get_by_id(subscription_id) +``` + +Returns information about the specified subscription. + +REST API: [Query Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Subscription%3FTocPath%3DAPI%2520Reference%7C_____68){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`subscription_id` | The `subscription_id` specifies the subscription to query. + + + +**Exceptions** + +Error | Description + :--- | : --- +`No Subscription ID provided.` | Raises an exception if a valid `subscription_id` is not provided. + + +**Returns** + +The `SubscriptionItem`. See [SubscriptionItem class](#subscriptionitem-class) + + +**Example** + +```py + sub1 = server.subscription.get_by_id('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + print(sub1.subject) + +``` + + + +
    +
    + +--- + ## Users Using the TSC library, you can get information about all the users on a site, and you can add or remove users, or update user information. @@ -1977,7 +2650,7 @@ The `UserItem` class contains the members or attributes for the view resources o Name | Description :--- | :--- -`auth_setting` | (Optional) This attribute is only for Tableau Online. The new authentication type for the user. You can assign the following values for tis attribute: `SAML` (the user signs in using SAML) or `ServerDefault` (the user signs in using the authentication method that's set for the server). These values appear in the **Authentication** tab on the **Settings** page in Tableau Online -- the `SAML` attribute value corresponds to **Single sign-on**, and the `ServerDefault` value corresponds to **TableauID**. +`auth_setting` | (Optional) This attribute is only for Tableau Online. The new authentication type for the user. You can assign the following values for this attribute: `SAML` (the user signs in using SAML) or `ServerDefault` (the user signs in using the authentication method that's set for the server). These values appear in the **Authentication** tab on the **Settings** page in Tableau Online -- the `SAML` attribute value corresponds to **Single sign-on**, and the `ServerDefault` value corresponds to **TableauID**. `domain_name` | The name of the site. `external_auth_user_id` | Represents ID stored in Tableau's single sign-on (SSO) system. The `externalAuthUserId` value is returned for Tableau Online. For other server configurations, this field contains null. `id` | The id of the user on the site. @@ -1986,7 +2659,7 @@ Name | Description `email` | The email address of the user. `fullname` | The full name of the user. `name` | The name of the user. This attribute is required when you are creating a `UserItem` instance. -`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `Viewer`, `ViewerWithPublish`, `Guest` +`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The specific roles vary depending upon the version of the REST API. For example, for version 2.8 and earlier, the `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `Viewer`, `ViewerWithPublish`, `Guest`. For REST API 3.0 and later, the `site_role` can be one of the following `Creator`, `Explorer`, `ExplorerCanPublish`, `ReadOnly`, `SiteAdministratorCreator`, `SiteAdministratorExplorer`, `UnlicensedWithPublish`. **Example** @@ -2095,13 +2768,14 @@ with server.auth.sign_in(tableau_auth): all_users, pagination_item = server.users.get() print("\nThere are {} user on site: ".format(pagination_item.total_available)) print([user.name for user in all_users]) -```` +```

    #### users.get_by_id + ```py users.get_by_id(user_id) ``` @@ -2331,7 +3005,7 @@ An updated `UserItem`. See [UserItem class](#useritem-class)
    - +--- ## Views @@ -2379,7 +3053,7 @@ Source file: server/endpoint/views_endpoint.py #### views.get ``` -views.get(req_option=None) +views.get(req_option=None, usage=False) ``` Returns the list of views items for a site. @@ -2392,6 +3066,7 @@ REST API: [Query Views for Site](http://onlinehelp.tableau.com/current/api/rest_ Name | Description :--- | :--- `req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific view, you could specify the name of the view or its id. +`usage` | (Optional) If true (`usage=True`) returns the usage statistics for the views. The default is `usage=False`. @@ -2456,7 +3131,7 @@ See [ViewItem class](#viewitem-class)
    - +--- ## Workbooks diff --git a/docs/dev-guide.md b/docs/dev-guide.md index 3a51e86c6..385222054 100644 --- a/docs/dev-guide.md +++ b/docs/dev-guide.md @@ -49,7 +49,7 @@ This section will get you started with the basic workflow, describing how to cre - Only touch the fewest number of files possible while still accomplishing the goal. - Ensure all indentation is done as 4-spaces and your editor is set to unix line endings. - - The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle server-client-python test samples` + - The code matches PEP8 style guides. If you cloned the repo you can run `pycodestyle tableauserverclient test samples` - Keep commit messages clean and descriptive. If the PR is accepted it will get 'Squashed' into a single commit before merging, the commit messages will be used to generate the Merge commit message. diff --git a/docs/versions.md b/docs/versions.md index a4eff325d..9fd8aae87 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -21,9 +21,21 @@ server = TSC.Server('http://SERVER_URL') print(server.version) ``` -For example, the code might display version `2.3`. +For example, the code might display version `2.3`. -## Use another version of the REST API +## Use the REST API version supported by the server + +To always use the latest version of the REST API that is supported by the instance of Tableau Server you are connecting to, set the version using the `use_server_version()` method. You can do this when you create the server instance by specifying `use_server_version=True` as one of the arguments. + +```py +import tableauserverclient as TSC + +server = TSC.Server('http://SERVER_URL', use_server_version=True) + + +``` + +## Use a specific version of the REST API To use another version of the REST API, set the version like so: @@ -47,3 +59,7 @@ The current version of TSC only supports the following REST API and Tableau Serv |2.4|10.1| |2.5|10.2| |2.6|10.3| +|2.7|10.4| +|2.8|10.5| +|3.0|2018.1| + From aa150644f7f6d1e57bf6281621dd101eb62055de Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Tue, 2 Oct 2018 15:10:18 -0700 Subject: [PATCH 005/158] Update footer.html --- _includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/footer.html b/_includes/footer.html index 486c81d22..ee1481e55 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -3,6 +3,6 @@

    This site is open source. Suggestions and pull requests are welcome on our GitHub page.

    -

    © 2016 Tableau.

    +

    © 2018 Tableau.

    From 071efc71dd0a8b14fa0a90cb7cc9e64282bae894 Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Tue, 2 Oct 2018 16:04:23 -0700 Subject: [PATCH 006/158] update link to latest release download zip file The download button on the page was linked to the oldest version, v0.1. Updated link to point to the latest version, v0.7. --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index c0f9a4431..eeceabaf4 100644 --- a/index.md +++ b/index.md @@ -8,6 +8,6 @@ indexed_by_search: false

    The Tableau Server Client is a Python library for the Tableau Server REST API.


    Get Started   - Download + Download From 0ae5477661a11b19aa637a3755ef4402c2cfa0eb Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Wed, 23 Jan 2019 14:26:43 -0800 Subject: [PATCH 007/158] Update api-ref.md (#386) fixed typo in link from *server*.auth to Authentication. --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 9cb3daa06..8cfe1b61e 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -1889,7 +1889,7 @@ When you create an instance of the `Server` class, you have access to the resour Resource | Description :--- | : --- -*server*.auth | Sets authentication for sign in and sign out. See [Auth](#auththentication) | +*server*.auth | Sets authentication for sign in and sign out. See [Auth](#authentication) | *server*.views | Access the server views and methods. See [Views](#views) *server*.users | Access the user resources and methods. See [Users](#users) *server*.sites | Access the sites. See [Sites](#sites) From 51883e9f5f61a3991c2692d217c35990d4599dee Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Fri, 25 Jan 2019 11:04:17 -0800 Subject: [PATCH 008/158] updating docs for view --- docs/api-ref.md | 208 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 177 insertions(+), 31 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 8cfe1b61e..f661768b0 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -3009,20 +3009,19 @@ An updated `UserItem`. See [UserItem class](#useritem-class) ## Views -Using the TSC library, you can get all the views on a site, or get the views for a workbook, or populate a view with preview images. -The view resources for Tableau Server are defined in the `ViewItem` class. The class corresponds to the view resources you can access using the Tableau Server REST API, for example, you can find the name of the view, its id, and the id of the workbook it is associated with. The view methods are based upon the endpoints for views in the REST API and operate on the `ViewItem` class. +Using the TSC library, you can get information about views in a site or a workbook. +The view resources for Tableau Server are defined in the `ViewItem` class. The class corresponds to the view resources you can access using the Tableau Server REST API. The view methods are based upon the endpoints for views in the REST API and operate on the `ViewItem` class.
    ### ViewItem class ``` -class ViewItem(object) - +ViewItem() ``` -The `ViewItem` class contains the members or attributes for the view resources on Tableau Server. The `ViewItem` class defines the information you can request or query from Tableau Server. The class members correspond to the attributes of a server request or response payload. +The `ViewItem` class contains the members or attributes for the view resources on Tableau Server. The `ViewItem` class defines the information you can request or query from Tableau Server. The class members correspond to the attributes of a server request or response payload. Source file: models/view_item.py @@ -3030,12 +3029,17 @@ Source file: models/view_item.py Name | Description :--- | :--- +`content_url` | The name of the view as it would appear in a URL. +`csv` | The CSV data of the view. You must first call the [views.populate_csv](#views.populate_csv) method to access the CSV data. `id` | The identifier of the view item. -`name` | The name of the view. -`owner_id` | The id for the owner of the view. -`preview_image` | The thumbnail image for the view. -`total_views` | The usage statistics for the view. Indicates the total number of times the view has been looked at. -`workbook_id` | The id of the workbook associated with the view. +`image` | The image of the view. You must first call the [views.populate_image](#views.populate_image) method to access the image. +`name` | The name of the view. +`owner_id` | The ID for the owner of the view. +`pdf` | The PDF of the view. You must first call the [views.populate_pdf](#views.populate_pdf) method to access the PDF content. +`preview_image` | The thumbnail image for the view. You must first call the [views.populate_preview_image](#views.populate_preview_image) method to access the preview image. +`project_id` | The ID of the project that contains the view. +`total_views` | The usage statistics for the view. Indicates the total number of times the view has been looked at. +`workbook_id` | The ID of the workbook associated with the view.
    @@ -3044,7 +3048,7 @@ Name | Description ### Views methods -The Tableau Server Client provides two methods for interacting with view resources, or endpoints. These methods correspond to the endpoints for views in the Tableau Server REST API. +The Tableau Server Client provides methods for interacting with view resources, or endpoints. These methods correspond to the endpoints for views in the Tableau Server REST API. Source file: server/endpoint/views_endpoint.py @@ -3053,26 +3057,30 @@ Source file: server/endpoint/views_endpoint.py #### views.get ``` -views.get(req_option=None, usage=False) +views.get(req_options=None, usage=False) ``` -Returns the list of views items for a site. +Returns the list of views items for a site. -REST API: [Query Views for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Views_for_Site%3FTocPath%3DAPI%2520Reference%7C_____64){:target="_blank"} +REST API: [Query Views for Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_views_for_site){:target="_blank"} -**Parameters** +**Version** + +This endpoint is available with REST API version 2.0 and up. + +**Parameters** Name | Description :--- | :--- -`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific view, you could specify the name of the view or its id. +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. For example, if you were searching for a specific view, you could specify the name of the view or its ID. `usage` | (Optional) If true (`usage=True`) returns the usage statistics for the views. The default is `usage=False`. **Returns** -Returns a list of all `ViewItem` objects and a `PaginationItem`. Use these values to iterate through the results. +Returns a list of all `ViewItem` objects and a `PaginationItem`. Use these values to iterate through the results. **Example** @@ -3082,10 +3090,17 @@ tableau_auth = TSC.TableauAuth('username', 'password') server = TSC.Server('http://servername') with server.auth.sign_in(tableau_auth): - all_views, pagination_item = server.views.get() - print([view.name for view in all_views]) + all_views, pagination_item = server.views.get() + print([view.name for view in all_views]) +``` -```` +**Example using Pager** + +You can also use the provided Pager generator to get all views on site, without having to page through the results. +```py +for view in TSC.Pager(server.views): + print(view.name) +``` See [ViewItem class](#viewitem-class) @@ -3097,39 +3112,170 @@ See [ViewItem class](#viewitem-class) ```py views.populate_preview_image(view_item) - ``` -Populates a preview image for the specified view. +Populates a preview image for the specified view. -This method gets the preview image (thumbnail) for the specified view item. The method uses the `view.id` and `workbook.id` to identify the preview image. The method populates the `view.preview_image` for the view. +This method gets the preview image (thumbnail) for the specified view item. The method uses the `id` and `workbook_id` fields to query the preview image. The method populates the `preview_image` for the view. -REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Preview_Image%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} +REST API: [Query View Preview Image](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_view_with_preview){:target="_blank"} -**Parameters** +**Version** + +This endpoint is available with REST API version 2.0 and up. + +**Parameters** Name | Description :--- | :--- -`view_item` | The view item specifies the `view.id` and `workbook.id` that identifies the preview image. - +`view_item` | Specified the view to populate. -**Exceptions** + +**Exceptions** Error | Description :--- | :--- -`View item missing ID or workbook ID` | Raises an error if the ID for the view item or workbook is missing. +`View item missing ID or workbook ID` | Raises an error if the ID of the view or workbook is missing. + - **Returns** -None. The preview image is added to the view. +None. The preview image is added to `view_item` and can be accessed by its `preview_image` field. See [ViewItem class](#viewitem-class)

    +#### views.populate_image + +```py +views.populate_image(view_item, req_options=None) +``` + +Populates the image of the specified view. + +This method uses the `id` field to query the image, and populates the image content as the `image` field. + +REST API: [Query View Image](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_view_image){:target="_blank"} + +**Version** + +This endpoint is available with REST API version 2.5 and up. + +**Parameters** + +Name | description +:--- | :--- +`view_item` | Specifies the view to populate. +`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. + +**Exceptions** + +Error | Description +:--- | :--- +`View item missing ID` | Raises an error if the ID of the view is missing. + +**Returns** + +None. The image is added to the `view_item` and can be accessed by its `image` field. + +**Example** + +Creating a request option for high resolution image: +```py +req_options = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High) +server.views.populate_image(view_item, req_options=req_options) +``` + +See [ViewItem class](#viewitem-class) + +
    +
    + +#### views.populate_csv +``` +views.populate_csv(view_item) +``` + +Populates the CSV data of the specified view. + +This method uses the `id` field to query the CSV data, and populates the data as the `csv` field. + +REST API: [Query View Data](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_view_data){:target="_blank"} + +**Version** + +This endpoint is available with REST API version 2.7 and up. + +**Parameters** + +Name | description +:--- | :--- +`view_item` | Specifies the view to populate. + +**Exceptions** + +Error | Description +:--- | :--- +`View item missing ID` | Raises an error if the ID of the view is missing. + +**Returns** + +None. The CSV data is added to the `view_item` and can be accessed by its `csv` field. + +See [ViewItem class](#viewitem-class) + +
    +
    + +#### views.populate_pdf +``` +views.populate_pdf(view_item, req_options=None) +``` + +Populates the PDF content of the specified view. + +This method uses the `id` field to query the PDF content, and populates the content as the `pdf` field. + +REST API: [Query View PDF](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_view_pdf){:target="_blank"} + +**Version** + +This endpoint is available with REST API version 2.7 and up. + +**Parameters** + +Name | description +:--- | :--- +`view_item` | Specifies the view to populate. +`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. + +**Exceptions** + +Error | Description +:--- | :--- +`View item missing ID` | Raises an error if the ID of the view is missing. + +**Returns** + +None. The PDF content is added to the `view_item` and can be accessed by its `pdf` field. + +**Example** + +Creating a request option for page type and orientation: +```py +req_options = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A5, + orientation=TSC.PDFRequestOptions.Orientation.Landscape) +server.views.populate_pdf(view_item, req_options=req_options) +``` + +See [ViewItem class](#viewitem-class) + +
    +
    + --- From e1222d14ed208b0f13903237487f90e17149a2fc Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Fri, 25 Jan 2019 11:23:13 -0800 Subject: [PATCH 009/158] fixed typos and links --- docs/api-ref.md | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index f661768b0..0c33791f3 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -3030,13 +3030,13 @@ Source file: models/view_item.py Name | Description :--- | :--- `content_url` | The name of the view as it would appear in a URL. -`csv` | The CSV data of the view. You must first call the [views.populate_csv](#views.populate_csv) method to access the CSV data. +`csv` | The CSV data of the view. You must first call the `views.populate_csv` method to access the CSV data. `id` | The identifier of the view item. -`image` | The image of the view. You must first call the [views.populate_image](#views.populate_image) method to access the image. +`image` | The image of the view. You must first call the `views.populate_image`method to access the image. `name` | The name of the view. `owner_id` | The ID for the owner of the view. -`pdf` | The PDF of the view. You must first call the [views.populate_pdf](#views.populate_pdf) method to access the PDF content. -`preview_image` | The thumbnail image for the view. You must first call the [views.populate_preview_image](#views.populate_preview_image) method to access the preview image. +`pdf` | The PDF of the view. You must first call the `views.populate_pdf` method to access the PDF content. +`preview_image` | The thumbnail image for the view. You must first call the `views.populate_preview_image` method to access the preview image. `project_id` | The ID of the project that contains the view. `total_views` | The usage statistics for the view. Indicates the total number of times the view has been looked at. `workbook_id` | The ID of the workbook associated with the view. @@ -3128,7 +3128,7 @@ This endpoint is available with REST API version 2.0 and up. Name | Description :--- | :--- -`view_item` | Specified the view to populate. +`view_item` | Specifies the view to populate. **Exceptions** @@ -3169,7 +3169,7 @@ This endpoint is available with REST API version 2.5 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. +`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. See [ImageRequestOptions class](#imagerequestoptions-class) **Exceptions** @@ -3181,14 +3181,6 @@ Error | Description None. The image is added to the `view_item` and can be accessed by its `image` field. -**Example** - -Creating a request option for high resolution image: -```py -req_options = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High) -server.views.populate_image(view_item, req_options=req_options) -``` - See [ViewItem class](#viewitem-class)
    @@ -3250,7 +3242,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. +`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. See [PDFRequestOptions class](#pdfrequestoptions-class) **Exceptions** @@ -3262,15 +3254,6 @@ Error | Description None. The PDF content is added to the `view_item` and can be accessed by its `pdf` field. -**Example** - -Creating a request option for page type and orientation: -```py -req_options = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A5, - orientation=TSC.PDFRequestOptions.Orientation.Landscape) -server.views.populate_pdf(view_item, req_options=req_options) -``` - See [ViewItem class](#viewitem-class)
    From 6aec8ba950b7854f70cd2850fb7e8d28683c872a Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Fri, 25 Jan 2019 11:27:46 -0800 Subject: [PATCH 010/158] minor fix --- docs/api-ref.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 0c33791f3..3a87733da 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -3169,7 +3169,7 @@ This endpoint is available with REST API version 2.5 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. See [ImageRequestOptions class](#imagerequestoptions-class) +`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. See [ImageRequestOptions class](#imagerequestoptions-class) for more details. **Exceptions** @@ -3242,7 +3242,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. See [PDFRequestOptions class](#pdfrequestoptions-class) +`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. **Exceptions** From 756bef6a7b0c4522b22425d430aa02f02d86bcad Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Fri, 25 Jan 2019 14:42:47 -0800 Subject: [PATCH 011/158] added info about view filters --- docs/api-ref.md | 87 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 3a87733da..21863efd8 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -1540,23 +1540,48 @@ Name | Description `Asc` | Sets the sort direction to ascending (`TSC.RequestOptions.Direction.Asc`) `Desc` | Sets the sort direction to descending (`TSC.RequestOptions.Direction.Desc`). +
    +
    + +### CSVRequestOptions class + +```py +CSVRequestOptions() +``` +Use this class to specify view filters to be applied when the CSV data is generated. See `views.populate_csv`. + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('http://MY-SERVER') +# sign in, get a specific view, etc. +# set view filters +csv_req_option = TSC.CSVRequestOptions() +csv_req_option.vf('Region', 'South') +csv_req_option.vf('Category', 'Furniture') + +# retrieve the csv data for the view +server.views.populate_csv(view_item, csv_req_option) +``` ### ImageRequestOptions class ```py ImageRequestOptions(imageresolution=None) - ``` -Use this class to specify the resolution of the view returned as an image. See `views.populate_view`. +Use this class to specify the resolution of the view returned as an image. You can also use this class to specify view filters to be applied when the image is generated. See `views.populate_image`. **Attributes** Name | Description :--- | :--- -`imageresolution` | The resolution of the view returned as an image. You set this option with the `Resolution` class. If unspecified, the `views.populate_view` method returns an image with standard resolution (the width of the returned image is 784 pixels). If you set this parameter value to high (`Resolution.High`), the width of the returned image is 1568 pixels. For both resolutions, the height varies to preserve the aspect ratio of the view. +`imageresolution` | The resolution of the view returned as an image. You set this option with the `Resolution` class. If unspecified, the `views.populate_image` method returns an image with standard resolution (the width of the returned image is 784 pixels). If you set this parameter value to high (`Resolution.High`), the width of the returned image is 1568 pixels. For both resolutions, the height varies to preserve the aspect ratio of the view. +**View Filters** +You can use the `vf('filter_name', 'filter_value')` method to add view filters. When the image is generated, the specified filters will be applied to the view. **Example** @@ -1568,6 +1593,9 @@ Name | Description # set the image request option image_req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High) +# (optional) set a view filter +image_req_option.vf('Category', 'Furniture') + # retrieve the image for the view server.views.populate_image(view_item, image_req_option) @@ -1577,7 +1605,6 @@ server.views.populate_image(view_item, image_req_option) ```py PDFRequestOptions(page_type=None, orientation=None) - ``` Use this class to specify the format of the PDF that is returned for the view. See `views.populate_pdf`. @@ -1588,6 +1615,8 @@ Name | Description `page_type` | The type of page returned in PDF format for the view. The page_type is set using the `PageType` class:
    `PageType.A3`
    `PageType.A4`
    `PageType.A5`
    `PageType.B5`
    `PageType.Executive`
    `PageType.Folio`
    `PageType.Ledger`
    `PageType.Legal`
    `PageType.Letter`
    `PageType.Note`
    `PageType.Quarto`
    `PageType.Tabloid` `orientation` | The orientation of the page. The options are portrait and landscape. The options are set using the `Orientation` class:
    `Orientation.Portrait`
    `Orientation.Landscape` +**View Filters** +You can use the `vf('filter_name', 'filter_value')` method to add view filters. When the PDF is generated, the specified filters will be applied to the view. **Example** @@ -1599,6 +1628,9 @@ Name | Description # set the PDF request options pdf_req_option = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A4, orientation=TSC.PDFRequestOptions.Orientation.Landscape) +# (optional) set a view filter +pdf_req_option.vf('Region', 'West') + # retrieve the PDF for a view server.views.populate_pdf(view_item, pdf_req_option) @@ -3138,11 +3170,20 @@ Error | Description `View item missing ID or workbook ID` | Raises an error if the ID of the view or workbook is missing. - **Returns** None. The preview image is added to `view_item` and can be accessed by its `preview_image` field. +**Example** +```py +# Sign in, get view, etc. + +# Populate and save the preview image as 'view_preview_image.png' +server.views.populate_preview_image(view_item) +with open('./view_preview_image.png', 'wb') as f: + f.write(view_item.preview_image) +``` + See [ViewItem class](#viewitem-class)
    @@ -3169,7 +3210,7 @@ This endpoint is available with REST API version 2.5 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. See [ImageRequestOptions class](#imagerequestoptions-class) for more details. +`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. You can also specify view filters to be applied when the image is generated. See [ImageRequestOptions class](#imagerequestoptions-class) for more details. **Exceptions** @@ -3181,6 +3222,16 @@ Error | Description None. The image is added to the `view_item` and can be accessed by its `image` field. +**Example** +```py +# Sign in, get view, etc. + +# Populate and save the view image as 'view_image.png' +server.views.populate_image(view_item) +with open('./view_image.png', 'wb') as f: + f.write(view_item.image) +``` + See [ViewItem class](#viewitem-class)
    @@ -3206,6 +3257,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. +`req_options` | (Optional) You can pass in a request object to specify view filters to be applied when the CSV data is generated. See [CSVRequestOptions class](#csvrequestoptions-class) for more details. **Exceptions** @@ -3217,6 +3269,17 @@ Error | Description None. The CSV data is added to the `view_item` and can be accessed by its `csv` field. +**Example** +```py +# Sign in, get view, etc. + +# Populate and save the CSV data as 'view_csv.csv' +server.views.populate_csv(view_item) +with open('./view_csv.csv', 'wb') as f: + # Perform byte join on the CSV data + f.write(b''.join(view_item.csv)) +``` + See [ViewItem class](#viewitem-class)
    @@ -3242,7 +3305,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. +`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. You can also specify view filters to be applied when the PDF is generated. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. **Exceptions** @@ -3254,6 +3317,16 @@ Error | Description None. The PDF content is added to the `view_item` and can be accessed by its `pdf` field. +**Example** +```py +# Sign in, get view, etc. + +# Populate and save the view pdf as 'view_pdf.pdf' +server.views.populate_pdf(view_item) +with open('./view_pdf.pdf', 'wb') as f: + f.write(view_item.pdf) +``` + See [ViewItem class](#viewitem-class)
    From 85d6cf263319fe001a864fb33a047df46f9c679b Mon Sep 17 00:00:00 2001 From: jsonhuff <47429419+jsonhuff@users.noreply.github.com> Date: Fri, 15 Feb 2019 15:22:59 -0800 Subject: [PATCH 012/158] Updated API versions for Tableau Server (#395) The API versions from 2018.2 and 2018.3 are taken from the REST API XML Schema doc: https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_schema.htm - Version 3.2 (Tableau Server 2018.3): ts-api_3_2.xsd - Version 3.1 (Tableau Server 2018.2): ts-api_3_1.xsd --- docs/versions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/versions.md b/docs/versions.md index 9fd8aae87..2519b5b80 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -62,4 +62,5 @@ The current version of TSC only supports the following REST API and Tableau Serv |2.7|10.4| |2.8|10.5| |3.0|2018.1| - +|3.1|2018.2| +|3.2|2018.3| From 0d6ffdef23748c910aa93fb4a0f0d714c22e02d9 Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Wed, 20 Feb 2019 08:25:49 -0800 Subject: [PATCH 013/158] Adding 2019.1 (v3.3) to docs --- docs/versions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/versions.md b/docs/versions.md index 2519b5b80..648945d7a 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -64,3 +64,4 @@ The current version of TSC only supports the following REST API and Tableau Serv |3.0|2018.1| |3.1|2018.2| |3.2|2018.3| +|3.3|2019.1| From e24efdfe332234261c70dddb4e84868a185dfbd7 Mon Sep 17 00:00:00 2001 From: Jared Dominguez Date: Wed, 13 Mar 2019 17:44:42 -0700 Subject: [PATCH 014/158] [Security] Fix DOM XSS vulnerability in search --- js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/search.js b/js/search.js index 76b0b6ea0..b73e673de 100644 --- a/js/search.js +++ b/js/search.js @@ -23,7 +23,7 @@ function displaySearchHeading(query) { var heading = document.getElementById("searchHeading"); - heading.innerHTML = "Search results for: " + query; + heading.textContent = "Search results for: " + query; } // Get the raw search results From ad51790d6880c252983e5188bcd8e70e855d3cc1 Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Mon, 8 Apr 2019 12:31:39 -0700 Subject: [PATCH 015/158] Fix misspelled anchors under the Server resource page (#410) Addressing PR #410: Fix the projects anchor under the Server resource page. Also fixed schedules and serverinfoitem-class anchors that were misspelled. --- docs/api-ref.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 21863efd8..b218117da 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -1929,10 +1929,10 @@ Resource | Description *server*.jobs | Access the jobs resources and methods. See [Jobs](#jobs) *server*.workbooks | Access the resources and methods for workbooks. See [Workbooks](#workbooks) *server*.datasources | Access the resources and methods for data sources. See [Data Sources](#data-sources) -*server*.projects | Access the resources and methods for projects. See [Projects](#projets) -*server*.schedules | Access the resources and methods for schedules. See [Schedules](#Schedules) +*server*.projects | Access the resources and methods for projects. See [Projects](#projects) +*server*.schedules | Access the resources and methods for schedules. See [Schedules](#schedules) *server*.subscriptions | Access the resources and methods for subscriptions. See [Subscriptions](#subscriptions) -*server*.server_info | Access the resources and methods for server information. See [ServerInfo class](#serverinfo-class) +*server*.server_info | Access the resources and methods for server information. See [ServerInfo class](#serverinfoitem-class)

    From d476a782a3e81993597c5f0d3c78e40f92d1eb9f Mon Sep 17 00:00:00 2001 From: Christian Oliff Date: Sat, 11 May 2019 11:44:22 +0900 Subject: [PATCH 016/158] Https link --- _includes/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/header.html b/_includes/header.html index 106578dfc..a42240f87 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -19,7 +19,7 @@
    From d7ebbe30a63cc388203ac2ab6c91b0dc876eb2a7 Mon Sep 17 00:00:00 2001 From: Dan Zucker Date: Thu, 13 Jun 2019 18:26:02 -0700 Subject: [PATCH 017/158] Fixing links to REST API reference pages in api-ref.md --- docs/api-ref.md | 116 ++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index b218117da..ea8e24a89 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -15,7 +15,7 @@ The Tableau Server Client (TSC) is a Python library for the Tableau Server REST The TSC API reference is organized by resource. The TSC library is modeled after the REST API. The methods, for example, `workbooks.get()`, correspond to the endpoints for resources, such as [workbooks](#workbooks), [users](#users), [views](#views), and [data sources](#data-sources). The model classes (for example, the [WorkbookItem class](#workbookitem-class) have attributes that represent the fields (`name`, `id`, `owner_id`) that are in the REST API request and response packages, or payloads. |:--- | -| **Note:** Some methods and features provided in the REST API might not be currently available in the TSC library (and in some cases, the opposite is true). In addition, the same limitations apply to the TSC library that apply to the REST API with respect to resources on Tableau Server and Tableau Online. For more information, see the [Tableau Server REST API Reference](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#API_Reference%3FTocPath%3DAPI%2520Reference%7C_____0){:target="_blank"}.| +| **Note:** Some methods and features provided in the REST API might not be currently available in the TSC library (and in some cases, the opposite is true). In addition, the same limitations apply to the TSC library that apply to the REST API with respect to resources on Tableau Server and Tableau Online. For more information, see the [Tableau Server REST API Reference](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#API_Reference0){:target="_blank"}.| @@ -90,7 +90,7 @@ Signs you in to Tableau Server. The method signs into Tableau Server or Tableau Online and manages the authentication token. You call this method from the server object you create. For information about the server object, see [Server](#server). The authentication token keeps you signed in for 240 minutes, or until you call the `auth.sign_out` method. Before you use this method, you first need to create the sign-in request (`auth_req`) object by creating an instance of the `TableauAuth`. To call this method, create a server object for your server. For more information, see [Sign in and Out](sign-in-out). -REST API: [Sign In](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Sign_In%3FTocPath%3DAPI%2520Reference%7C_____77){:target="_blank"} +REST API: [Sign In](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#sign_in){:target="_blank"} **Parameters** @@ -131,7 +131,7 @@ Signs you out of the current session. The `sign_out()` method takes care of invalidating the authentication token. For more information, see [Sign in and Out](sign-in-out). -REST API: [Sign Out](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Sign_Out%3FTocPath%3DAPI%2520Reference%7C_____78){:target="_blank"} +REST API: [Sign Out](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#ign_out){:target="_blank"} **Example** @@ -301,7 +301,7 @@ Error | Description `Datasource ID undefined` | Raises an exception if a valid `datasource_id` is not provided. -REST API: [Delete Datasource](http://onlinehelp.tableau.com/v0.0/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Datasource%3FTocPath%3DAPI%2520Reference%7C_____19){:target="_blank"} +REST API: [Delete Datasource](http://onlinehelp.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#delete_data_source){:target="_blank"}

    @@ -315,7 +315,7 @@ datasources.download(datasource_id, filepath=None, include_extract=True, no_extr ``` Downloads the specified data source in `.tdsx` or `.hyper` format. -REST API: [Download Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Download_Datasource%3FTocPath%3DAPI%2520Reference%7C_____34){:target="_blank"} +REST API: [Download Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_data_source){:target="_blank"} **Parameters** @@ -360,7 +360,7 @@ Returns all the data sources for the site. To get the connection information for each data source, you must first populate the `DatasourceItem` with connection information using the [populate_connections(*datasource_item*)](#populate-connections-datasource) method. For more information, see [Populate Connections and Views](populate-connections-views#populate-connections-for-data-sources) -REST API: [Query Datasources](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasources%3FTocPath%3DAPI%2520Reference%7C_____49){:target="_blank"} +REST API: [Query Datasources](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_sources){:target="_blank"} **Parameters** @@ -403,7 +403,7 @@ datasources.get_by_id(datasource_id) Returns the specified data source item. -REST API: [Query Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource%3FTocPath%3DAPI%2520Reference%7C_____46){:target="_blank"} +REST API: [Query Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source){:target="_blank"} **Parameters** @@ -450,7 +450,7 @@ Populates the connections for the specified data source. This method retrieves the connection information for the specified data source. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the connection information is not included. Use this method to retrieve the connections. The method adds the list of data connections to the data source item (`datasource_item.connections`). This is a list of `ConnectionItem` objects. -REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource_Connections%3FTocPath%3DAPI%2520Reference%7C_____47){:target="_blank"} +REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} **Parameters** @@ -511,7 +511,7 @@ Publishes a data source to a server, or appends data to an existing data source. This method checks the size of the data source and automatically determines whether the publish the data source in multiple parts or in one opeation. -REST API: [Publish Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Datasource%3FTocPath%3DAPI%2520Reference%7C_____44){:target="_blank"} +REST API: [Publish Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_data_source){:target="_blank"} **Parameters** @@ -572,7 +572,7 @@ datasource.update(datasource_item) Updates the owner, or project of the specified data source. -REST API: [Update Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Datasource%3FTocPath%3DAPI%2520Reference%7C_____79){:target="_blank"} +REST API: [Update Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source){:target="_blank"} **Parameters** @@ -624,7 +624,7 @@ datasource.update_connection(datasource_item, connection_item) Updates the server address, port, username, or password for the specified data source connection. -REST API: [Update Datasource Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Datasource_Connection){:target="_blank"} +REST API: [Update Datasource Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source_connection){:target="_blank"} **Parameters** @@ -752,7 +752,7 @@ groups.add_user(group_item, user_id): Adds a user to the specified group. -REST API [Add User to Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Add_User_to_Group%3FTocPath%3DAPI%2520Reference%7C_____8){:target="_blank"} +REST API [Add User to Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_group){:target="_blank"} **Parameters** @@ -799,7 +799,7 @@ create(group_item) Creates a new group in Tableau Server. -REST API: [Create Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Group%3FTocPath%3DAPI%2520Reference%7C_____14){:target="_blank"} +REST API: [Create Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_group){:target="_blank"} **Parameters** @@ -849,7 +849,7 @@ groups.delete(group_id) Deletes the group on the site. -REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Site%3FTocPath%3DAPI%2520Reference%7C_____74){:target="_blank"} +REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} **Parameters** @@ -894,7 +894,7 @@ Returns information about the groups on the site. To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulate_users) method. -REST API: [Get Uers on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_on_Site%3FTocPath%3DAPI%2520Reference%7C_____41){:target="_blank"} +REST API: [Get Uers on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} **Parameters** @@ -939,7 +939,7 @@ groups.populate_users(group_item, req_options=None) Populates the `group_item` with the list of users. -REST API: [Get Users in Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_in_Group){:target="_blank"} +REST API: [Get Users in Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_in_group){:target="_blank"} **Parameters** @@ -1000,7 +1000,7 @@ Removes a user from a group. -REST API: [Remove User from Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Group%3FTocPath%3DAPI%2520Reference%7C_____73){:target="_blank"} +REST API: [Remove User from Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_to_group){:target="_blank"} **Parameters** @@ -1073,7 +1073,7 @@ Source file: models/job_item.py Name | Description :--- | :--- `id` | The `id` of the job. -`type` | The type of task. The types correspond to the job type categories listed for the [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Job){:target="_blank"} REST API. +`type` | The type of task. The types correspond to the job type categories listed for the [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_job){:target="_blank"} REST API. `created_at` | The time the job was created. `started_at` | The time the job started. `completed_at` | The time the job finished. @@ -1102,7 +1102,7 @@ jobs.get(job_id) Gets information about the specified job. -REST API: [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Job){:target="_blank"} +REST API: [Query Job](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_job){:target="_blank"} **Parameters** @@ -1198,7 +1198,7 @@ Source file: models/project_item.py #### ProjectItem.ContentPermissions -The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"}. +The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"}. Name | Description :--- | :--- @@ -1254,7 +1254,7 @@ Creates a project on the specified site. To create a project, you first create a new instance of a `ProjectItem` and pass it to the create method. To specify the site to create the new project, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Create Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Project%3FTocPath%3DAPI%2520Reference%7C_____15){:target="_blank"} +REST API: [Create Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"} **Parameters** @@ -1299,7 +1299,7 @@ Return a list of project items for a site. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Query Projects](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Projects%3FTocPath%3DAPI%2520Reference%7C_____55){:target="_blank"} +REST API: [Query Projects](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_projects){:target="_blank"} **Parameters** @@ -1340,7 +1340,7 @@ Modify the project settings. You can use this method to update the project name, the project description, or the project permissions. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Update Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Project%3FTocPath%3DAPI%2520Reference%7C_____82){:target="_blank"} +REST API: [Update Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_project){:target="_blank"} **Parameters** @@ -1402,7 +1402,7 @@ Deletes a project by ID. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Delete Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Project%3FTocPath%3DAPI%2520Reference%7C_____24){:target="_blank"} +REST API: [Delete Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_project){:target="_blank"} **Parameters** @@ -1485,7 +1485,7 @@ Name | Description #### RequestOptions.Field class -The `RequestOptions.Field` class corresponds to the fields used in filter expressions in the Tableau REST API. For more information, see [Filtering and Sorting](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_concepts_filtering_and_sorting.htm%3FTocPath%3DConcepts%7C_____7){:target="_blank"} in the Tableau REST API. +The `RequestOptions.Field` class corresponds to the fields used in filter expressions in the Tableau REST API. For more information, see [Filtering and Sorting](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm){:target="_blank"} in the Tableau REST API. **Attributes** @@ -1703,7 +1703,7 @@ schedule.create(schedule_item) Creates a new schedule for an extract refresh or a subscription. -REST API: [Create Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Schedule%3FTocPath%3DAPI%2520Reference%7C_____21){:target="_blank"} +REST API: [Create Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_schedule){:target="_blank"} @@ -1752,7 +1752,7 @@ schedule.delete(schedule_id) Deletes an existing schedule for an extract refresh or a subscription. -REST API: [Delete Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Schedule%3FTocPath%3DAPI%2520Reference%7C_____31){:target="_blank"} +REST API: [Delete Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_schedule){:target="_blank"} @@ -1783,7 +1783,7 @@ schedule.get([req_options=None]) Returns all schedule items from the server. -REST API: [Query Schedules](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Schedules%3FTocPath%3DAPI%2520Reference%7C_____65){:target="_blank"} +REST API: [Query Schedules](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_schedules){:target="_blank"} @@ -1889,7 +1889,7 @@ The `Server` class contains the attributes that represent the server on Tableau Attribute | Description :--- | :--- `server_address` | Specifies the address of the Tableau Server or Tableau Online (for example, `http://MY-SERVER/`). -`version` | Specifies the version of the REST API to use (for example, `'2.5'`). When you use the TSC library to call methods that access Tableau Server, the `version` is passed to the endpoint as part of the URI (`https://MY-SERVER/api/2.5/`). Each release of Tableau Server supports specific versions of the REST API. New versions of the REST API are released with Tableau Server. By default, the value of `version` is set to `'2.3'`, which corresponds to Tableau Server 10.0. You can view or set this value. You might need to set this to a different value, for example, if you want to access features that are supported by the server and a later version of the REST API. For more information, see [REST API Versions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_concepts_versions.htm){:target="_blank"} +`version` | Specifies the version of the REST API to use (for example, `'2.5'`). When you use the TSC library to call methods that access Tableau Server, the `version` is passed to the endpoint as part of the URI (`https://MY-SERVER/api/2.5/`). Each release of Tableau Server supports specific versions of the REST API. New versions of the REST API are released with Tableau Server. By default, the value of `version` is set to `'2.3'`, which corresponds to Tableau Server 10.0. You can view or set this value. You might need to set this to a different value, for example, if you want to access features that are supported by the server and a later version of the REST API. For more information, see [REST API Versions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm){:target="_blank"} @@ -2011,7 +2011,7 @@ Retrieve the build and version information for the server. This method makes an unauthenticated call, so no sign in or authentication token is required. -REST API: [Server Info](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Server_Info%3FTocPath%3DAPI%2520Reference%7C_____76){:target="_blank"} +REST API: [Server Info](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#server_info){:target="_blank"} **Parameters** None @@ -2119,7 +2119,7 @@ Creates a new site on the server for the specified site item object. Tableau Server only. -REST API: [Create Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Site%3FTocPath%3DAPI%2520Reference%7C_____17){:target="_blank"} +REST API: [Create Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_site){:target="_blank"} @@ -2164,7 +2164,7 @@ sites.get() Queries all the sites on the server. -REST API: [Query Sites](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Sites%3FTocPath%3DAPI%2520Reference%7C_____58){:target="_blank"} +REST API: [Query Sites](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_sites){:target="_blank"} **Parameters** @@ -2207,7 +2207,7 @@ sites.get_by_id(site_id) Queries the site with the given ID. -REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Site){:target="_blank"} +REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_site){:target="_blank"} **Parameters** @@ -2253,7 +2253,7 @@ sites.get_by_name(site_name) Queries the site with the specified name. -REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Site){:target="_blank"} +REST API: [Query Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_site){:target="_blank"} **Parameters** @@ -2304,7 +2304,7 @@ Modifies the settings for site. The site item object must include the site ID and overrides all other settings. -REST API: [Update Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Site%3FTocPath%3DAPI%2520Reference%7C_____84){:target="_blank"} +REST API: [Update Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_site){:target="_blank"} **Parameters** @@ -2357,7 +2357,7 @@ Sites.delete(site_id) Deletes the specified site. -REST API: [Delete Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Site%3FTocPath%3DAPI%2520Reference%7C_____27){:target="_name"} +REST API: [Delete Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#Delete_Site27){:target="_name"} **Parameters** @@ -2494,7 +2494,7 @@ When a user is subscribed to the content, Tableau Server sends the content to th To create a new subscription you need to first create a new `subscription_item` (from `SubscriptionItem` class). -REST API: [Create Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Create_Subscription%3FTocPath%3DAPI%2520Reference%7C_____23){:target="_blank"} +REST API: [Create Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_subscription){:target="_blank"} **Parameters** @@ -2553,7 +2553,7 @@ subscriptions.delete(subscription_id) Deletes the specified subscription from the site. -REST API: [Delete Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Subscription%3FTocPath%3DAPI%2520Reference%7C_____33){:target="_blank"} +REST API: [Delete Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_subscription){:target="_blank"} **Parameters** @@ -2598,7 +2598,7 @@ subscription.get(req_options=None) Returns information about the subscriptions on the specified site. -REST API: [Query Subscriptions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Subscriptions%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} +REST API: [Query Subscriptions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_subscriptions){:target="_blank"} **Parameters** @@ -2623,7 +2623,7 @@ subscription.get_by_id(subscription_id) Returns information about the specified subscription. -REST API: [Query Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Subscription%3FTocPath%3DAPI%2520Reference%7C_____68){:target="_blank"} +REST API: [Query Subscription](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_subscription){:target="_blank"} **Parameters** @@ -2731,7 +2731,7 @@ Adds the user to the site. To add a new user to the site you need to first create a new `user_item` (from `UserItem` class). When you create a new user, you specify the name of the user and their site role. For Tableau Online, you also specify the `auth_setting` attribute in your request. When you add user to Tableau Online, the name of the user must be the email address that is used to sign in to Tableau Online. After you add a user, Tableau Online sends the user an email invitation. The user can click the link in the invitation to sign in and update their full name and password. -REST API: [Add User to Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Add_User_to_Site%3FTocPath%3DAPI%2520Reference%7C_____9){:target="_blank"} +REST API: [Add User to Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_site){:target="_blank"} **Parameters** @@ -2774,7 +2774,7 @@ Returns information about the users on the specified site. To get information about the workbooks a user owns or has view permission for, you must first populate the `UserItem` with workbook information using the [populate_workbooks(*user_item*)](#populate-workbooks-user) method. -REST API: [Get Users on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Get_Users_on_Site%3FTocPath%3DAPI%2520Reference%7C_____41){:target="_blank"} +REST API: [Get Users on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} **Parameters** @@ -2814,7 +2814,7 @@ users.get_by_id(user_id) Returns information about the specified user. -REST API: [Query User On Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_User_On_Site%3FTocPath%3DAPI%2520Reference%7C_____61){:target="_blank"} +REST API: [Query User On Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_user_on_site){:target="_blank"} **Parameters** @@ -2873,7 +2873,7 @@ Returns information about the workbooks that the specified user owns and has Rea This method retrieves the workbook information for the specified user. The REST API is designed to return only the information you ask for explicitly. When you query for all the users, the workbook information for each user is not included. Use this method to retrieve information about the workbooks that the user owns or has Read (view) permissions. The method adds the list of workbooks to the user item object (`user_item.workbooks`). -REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Datasource_Connections%3FTocPath%3DAPI%2520Reference%7C_____47){:target="_blank"} +REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} **Parameters** @@ -2930,7 +2930,7 @@ users.remove(user_id) Removes the specified user from the site. -REST API: [Remove User from Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Remove_User_from_Site%3FTocPath%3DAPI%2520Reference%7C_____74){:target="_blank"} +REST API: [Remove User from Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} **Parameters** @@ -2974,11 +2974,11 @@ users.update(user_item, password=None) Updates information about the specified user. -The information you can modify depends upon whether you are using Tableau Server or Tableau Online, and whether you have configured Tableau Server to use local authentication or Active Directory. For more information, see [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_User%3FTocPath%3DAPI%2520Reference%7C_____86){:target="_blank"}. +The information you can modify depends upon whether you are using Tableau Server or Tableau Online, and whether you have configured Tableau Server to use local authentication or Active Directory. For more information, see [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"}. -REST API: [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_User%3FTocPath%3DAPI%2520Reference%7C_____86){:target="_blank"} +REST API: [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"} **Parameters** @@ -3425,7 +3425,7 @@ Queries the server and returns information about the workbooks the site. -REST API: [Query Workbooks for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbooks_for_Site%3FTocPath%3DAPI%2520Reference%7C_____70){:target="_blank"} +REST API: [Query Workbooks for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbooks_for_site){:target="_blank"} **Parameters** @@ -3470,7 +3470,7 @@ workbooks.get_by_id(workbook_id) Returns information about the specified workbook on the site. -REST API: [Query Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook%3FTocPath%3DAPI%2520Reference%7C_____66){:target="_blank"} +REST API: [Query Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook){:target="_blank"} **Parameters** @@ -3521,7 +3521,7 @@ unless you package the data and workbook in a .twbx file, or publish the data so For workbooks that are larger than 64 MB, the publish method automatically takes care of chunking the file in parts for uploading. Using this method is considerably more convenient than calling the publish REST APIs directly. -REST API: [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Workbook%3FTocPath%3DAPI%2520Reference%7C_____45){:target="_blank"}, [Initiate File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Initiate_File_Upload%3FTocPath%3DAPI%2520Reference%7C_____43){:target="_blank"}, [Append to File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Append_to_File_Upload%3FTocPath%3DAPI%2520Reference%7C_____13){:target="_blank"} +REST API: [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"}, [Initiate File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#initiate_file_upload){:target="_blank"}, [Append to File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#append_to_file_upload){:target="_blank"} @@ -3545,7 +3545,7 @@ Error | Description `Workbooks cannot be appended.` | The `mode` must be set to `Overwrite` or `CreateNew`. `Only .twb or twbx files can be published as workbooks.` | Raises an error if the type of file specified is not supported. -See the REST API [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Publish_Workbook%3FTocPath%3DAPI%2520Reference%7C_____45){:target="_blank"} for additional error codes. +See the REST API [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"} for additional error codes. **Returns** @@ -3580,7 +3580,7 @@ workbooks.update(workbook_item) Modifies an existing workbook. Use this method to change the owner or the project that the workbook belongs to, or to change whether the workbook shows views in tabs. The workbook item must include the workbook ID and overrides the existing settings. -REST API: [Update Workbooks](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Workbook%3FTocPath%3DAPI%2520Reference%7C_____87){:target="_blank"} +REST API: [Update Workbooks](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook){:target="_blank"} **Parameters** @@ -3638,7 +3638,7 @@ Deletes a workbook with the specified ID. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Delete Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Delete_Workbook%3FTocPath%3DAPI%2520Reference%7C_____31){:target="_blank"} +REST API: [Delete Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#Delete_Workbook31){:target="_blank"} **Parameters** @@ -3682,7 +3682,7 @@ workbooks.download(workbook_id, filepath=None, no_extract=False) Downloads a workbook to the specified directory (optional). -REST API: [Download Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Download_Workbook%3FTocPath%3DAPI%2520Reference%7C_____36){:target="_blank"} +REST API: [Download Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_workbook){:target="_blank"} **Parameters** @@ -3733,7 +3733,7 @@ You must first call this method to populate views before you can iterate through This method retrieves the view information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the view information is not included. Use this method to retrieve the views. The method adds the list of views to the workbook item (`workbook_item.views`). This is a list of `ViewItem`. -REST API: [Query Views for Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Views_for_Workbook%3FTocPath%3DAPI%2520Reference%7C_____65){:target="_blank"} +REST API: [Query Views for Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_views_for_workbook){:target="_blank"} **Parameters** @@ -3796,7 +3796,7 @@ connections. This method retrieves the data source connection information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query all the workbooks, the data source connection information is not included. Use this method to retrieve the connection information for any data sources used by the workbook. The method adds the list of data connections to the workbook item (`workbook_item.connections`). This is a list of `ConnectionItem`. -REST API: [Query Workbook Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Connections%3FTocPath%3DAPI%2520Reference%7C_____67){:target="_blank"} +REST API: [Query Workbook Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_connections){:target="_blank"} **Parameters** @@ -3858,7 +3858,7 @@ This method gets the preview image (thumbnail) for the specified workbook item. The method uses the `view.id` and `workbook.id` to identify the preview image. The method populates the `workbook_item.preview_image`. -REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Query_Workbook_Preview_Image%3FTocPath%3DAPI%2520Reference%7C_____69){:target="_blank"} +REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_preview_image){:target="_blank"} **Parameters** @@ -3911,7 +3911,7 @@ Updates a workbook connection information (server address, server port, user nam The workbook connections must be populated before the strings can be updated. See [workbooks.populate_connections](#workbooks.populate_connections) -REST API: [Update Workbook Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/help.htm#REST/rest_api_ref.htm#Update_Workbook_Connection%3FTocPath%3DAPI%2520Reference%7C_____88){:target="_blank"} +REST API: [Update Workbook Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook_connection){:target="_blank"} **Parameters** From 73d7755a9debf1e20e3883b7a564b8a04ce10e82 Mon Sep 17 00:00:00 2001 From: Dan Zucker Date: Thu, 13 Jun 2019 18:32:48 -0700 Subject: [PATCH 018/158] convert http: to https globally --- docs/api-ref.md | 170 ++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index ea8e24a89..63412f95e 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -15,7 +15,7 @@ The Tableau Server Client (TSC) is a Python library for the Tableau Server REST The TSC API reference is organized by resource. The TSC library is modeled after the REST API. The methods, for example, `workbooks.get()`, correspond to the endpoints for resources, such as [workbooks](#workbooks), [users](#users), [views](#views), and [data sources](#data-sources). The model classes (for example, the [WorkbookItem class](#workbookitem-class) have attributes that represent the fields (`name`, `id`, `owner_id`) that are in the REST API request and response packages, or payloads. |:--- | -| **Note:** Some methods and features provided in the REST API might not be currently available in the TSC library (and in some cases, the opposite is true). In addition, the same limitations apply to the TSC library that apply to the REST API with respect to resources on Tableau Server and Tableau Online. For more information, see the [Tableau Server REST API Reference](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#API_Reference0){:target="_blank"}.| +| **Note:** Some methods and features provided in the REST API might not be currently available in the TSC library (and in some cases, the opposite is true). In addition, the same limitations apply to the TSC library that apply to the REST API with respect to resources on Tableau Server and Tableau Online. For more information, see the [Tableau Server REST API Reference](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#API_Reference0){:target="_blank"}.| @@ -90,7 +90,7 @@ Signs you in to Tableau Server. The method signs into Tableau Server or Tableau Online and manages the authentication token. You call this method from the server object you create. For information about the server object, see [Server](#server). The authentication token keeps you signed in for 240 minutes, or until you call the `auth.sign_out` method. Before you use this method, you first need to create the sign-in request (`auth_req`) object by creating an instance of the `TableauAuth`. To call this method, create a server object for your server. For more information, see [Sign in and Out](sign-in-out). -REST API: [Sign In](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#sign_in){:target="_blank"} +REST API: [Sign In](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#sign_in){:target="_blank"} **Parameters** @@ -106,7 +106,7 @@ import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') # create an instance for your server -server = TSC.Server('http://SERVER_URL') +server = TSC.Server('https://SERVER_URL') # call the sign-in method with the auth object server.auth.sign_in(tableau_auth) @@ -131,7 +131,7 @@ Signs you out of the current session. The `sign_out()` method takes care of invalidating the authentication token. For more information, see [Sign in and Out](sign-in-out). -REST API: [Sign Out](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#ign_out){:target="_blank"} +REST API: [Sign Out](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#ign_out){:target="_blank"} **Example** @@ -301,7 +301,7 @@ Error | Description `Datasource ID undefined` | Raises an exception if a valid `datasource_id` is not provided. -REST API: [Delete Datasource](http://onlinehelp.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#delete_data_source){:target="_blank"} +REST API: [Delete Datasource](https://onlinehelp.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#delete_data_source){:target="_blank"}

    @@ -315,7 +315,7 @@ datasources.download(datasource_id, filepath=None, include_extract=True, no_extr ``` Downloads the specified data source in `.tdsx` or `.hyper` format. -REST API: [Download Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_data_source){:target="_blank"} +REST API: [Download Datasource](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_data_source){:target="_blank"} **Parameters** @@ -360,7 +360,7 @@ Returns all the data sources for the site. To get the connection information for each data source, you must first populate the `DatasourceItem` with connection information using the [populate_connections(*datasource_item*)](#populate-connections-datasource) method. For more information, see [Populate Connections and Views](populate-connections-views#populate-connections-for-data-sources) -REST API: [Query Datasources](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_sources){:target="_blank"} +REST API: [Query Datasources](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_sources){:target="_blank"} **Parameters** @@ -381,7 +381,7 @@ Returns a list of `DatasourceItem` objects and a `PaginationItem` object. Use ```py import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -server = TSC.Server('http://SERVERURL') +server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): all_datasources, pagination_item = server.datasources.get() @@ -403,7 +403,7 @@ datasources.get_by_id(datasource_id) Returns the specified data source item. -REST API: [Query Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source){:target="_blank"} +REST API: [Query Datasource](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source){:target="_blank"} **Parameters** @@ -450,7 +450,7 @@ Populates the connections for the specified data source. This method retrieves the connection information for the specified data source. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the connection information is not included. Use this method to retrieve the connections. The method adds the list of data connections to the data source item (`datasource_item.connections`). This is a list of `ConnectionItem` objects. -REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} +REST API: [Query Datasource Connections](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} **Parameters** @@ -478,7 +478,7 @@ None. A list of `ConnectionItem` objects are added to the data source (`datasour ```py # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # ... @@ -511,7 +511,7 @@ Publishes a data source to a server, or appends data to an existing data source. This method checks the size of the data source and automatically determines whether the publish the data source in multiple parts or in one opeation. -REST API: [Publish Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_data_source){:target="_blank"} +REST API: [Publish Datasource](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_data_source){:target="_blank"} **Parameters** @@ -543,7 +543,7 @@ The `DatasourceItem` for the data source that was added or appended to. ```py import tableauserverclient as TSC - server = TSC.Server('http://SERVERURL') + server = TSC.Server('https://SERVERURL') ... @@ -572,7 +572,7 @@ datasource.update(datasource_item) Updates the owner, or project of the specified data source. -REST API: [Update Datasource](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source){:target="_blank"} +REST API: [Update Datasource](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source){:target="_blank"} **Parameters** @@ -598,7 +598,7 @@ An updated `DatasourceItem`. ```py # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # sign in ... # get the data source item to update @@ -624,7 +624,7 @@ datasource.update_connection(datasource_item, connection_item) Updates the server address, port, username, or password for the specified data source connection. -REST API: [Update Datasource Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source_connection){:target="_blank"} +REST API: [Update Datasource Connection](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source_connection){:target="_blank"} **Parameters** @@ -752,7 +752,7 @@ groups.add_user(group_item, user_id): Adds a user to the specified group. -REST API [Add User to Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_group){:target="_blank"} +REST API [Add User to Group](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_group){:target="_blank"} **Parameters** @@ -799,7 +799,7 @@ create(group_item) Creates a new group in Tableau Server. -REST API: [Create Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_group){:target="_blank"} +REST API: [Create Group](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_group){:target="_blank"} **Parameters** @@ -823,7 +823,7 @@ Adds new `GroupItem`. # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # create a new instance with the group name @@ -849,7 +849,7 @@ groups.delete(group_id) Deletes the group on the site. -REST API: [Delete Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} +REST API: [Delete Group](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} **Parameters** @@ -873,7 +873,7 @@ Error | Description # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): server.groups.delete('1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d') @@ -894,7 +894,7 @@ Returns information about the groups on the site. To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulate_users) method. -REST API: [Get Uers on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} +REST API: [Get Uers on Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} **Parameters** @@ -914,7 +914,7 @@ Returns a list of `GroupItem` objects and a `PaginationItem` object. Use these ```py # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): @@ -939,7 +939,7 @@ groups.populate_users(group_item, req_options=None) Populates the `group_item` with the list of users. -REST API: [Get Users in Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_in_group){:target="_blank"} +REST API: [Get Users in Group](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_in_group){:target="_blank"} **Parameters** @@ -965,7 +965,7 @@ None. A list of `UserItem` objects are added to the group (`group_item.users`). ```py # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # ... @@ -1000,7 +1000,7 @@ Removes a user from a group. -REST API: [Remove User from Group](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_to_group){:target="_blank"} +REST API: [Remove User from Group](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_to_group){:target="_blank"} **Parameters** @@ -1031,7 +1031,7 @@ None. The user is removed from the group. # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): @@ -1133,7 +1133,7 @@ Returns the `JobItem` requested. # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): @@ -1189,7 +1189,7 @@ Name | Description `name` | Name of the project. `description` | The description of the project. `id` | The project id. -`parent_id` | The id of the parent project. Use this option to create project hierarchies. For information about managing projects, project hierarchies, and permissions, see [Use Projects to Manage Content Access](http://onlinehelp.tableau.com/current/server/en-us/projects.htm){:target="_blank"}. +`parent_id` | The id of the parent project. Use this option to create project hierarchies. For information about managing projects, project hierarchies, and permissions, see [Use Projects to Manage Content Access](https://onlinehelp.tableau.com/current/server/en-us/projects.htm){:target="_blank"}. @@ -1198,7 +1198,7 @@ Source file: models/project_item.py #### ProjectItem.ContentPermissions -The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"}. +The `ProjectItem` class has a sub-class that defines the permissions for the project (`ProjectItem.ContentPermissions`). The options are `LockedToProject` and `ManagedByOwner`. For information on these content permissions, see [Lock Content Permissions to the Project](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"}. Name | Description :--- | :--- @@ -1210,7 +1210,7 @@ Name | Description ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc @@ -1254,7 +1254,7 @@ Creates a project on the specified site. To create a project, you first create a new instance of a `ProjectItem` and pass it to the create method. To specify the site to create the new project, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Create Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"} +REST API: [Create Project](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_project){:target="_blank"} **Parameters** @@ -1273,7 +1273,7 @@ Returns the new project item. ```py import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL') -server = TSC.Server('http://SERVER') +server = TSC.Server('https://SERVER') with server.auth.sign_in(tableau_auth): # create project item @@ -1299,7 +1299,7 @@ Return a list of project items for a site. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Query Projects](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_projects){:target="_blank"} +REST API: [Query Projects](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_projects){:target="_blank"} **Parameters** @@ -1317,7 +1317,7 @@ Returns a list of all `ProjectItem` objects and a `PaginationItem`. Use these va ```py import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='CONTENTURL') -server = TSC.Server('http://SERVER') +server = TSC.Server('https://SERVER') with server.auth.sign_in(tableau_auth): # get all projects on site @@ -1340,7 +1340,7 @@ Modify the project settings. You can use this method to update the project name, the project description, or the project permissions. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Update Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_project){:target="_blank"} +REST API: [Update Project](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_project){:target="_blank"} **Parameters** @@ -1366,7 +1366,7 @@ See [ProjectItem class](#projectitem-class) ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc ... @@ -1402,7 +1402,7 @@ Deletes a project by ID. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Delete Project](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_project){:target="_blank"} +REST API: [Delete Project](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_project){:target="_blank"} **Parameters** @@ -1425,7 +1425,7 @@ Error | Description ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc. server.projects.delete('1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e') @@ -1485,7 +1485,7 @@ Name | Description #### RequestOptions.Field class -The `RequestOptions.Field` class corresponds to the fields used in filter expressions in the Tableau REST API. For more information, see [Filtering and Sorting](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm){:target="_blank"} in the Tableau REST API. +The `RequestOptions.Field` class corresponds to the fields used in filter expressions in the Tableau REST API. For more information, see [Filtering and Sorting](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm){:target="_blank"} in the Tableau REST API. **Attributes** @@ -1554,7 +1554,7 @@ Use this class to specify view filters to be applied when the CSV data is genera ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, get a specific view, etc. # set view filters @@ -1587,7 +1587,7 @@ You can use the `vf('filter_name', 'filter_value')` method to add view filters. ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, get a specific view, etc. # set the image request option @@ -1622,7 +1622,7 @@ You can use the `vf('filter_name', 'filter_value')` method to add view filters. ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, get a specific view, etc. # set the PDF request options @@ -1703,7 +1703,7 @@ schedule.create(schedule_item) Creates a new schedule for an extract refresh or a subscription. -REST API: [Create Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_schedule){:target="_blank"} +REST API: [Create Schedule](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_schedule){:target="_blank"} @@ -1752,7 +1752,7 @@ schedule.delete(schedule_id) Deletes an existing schedule for an extract refresh or a subscription. -REST API: [Delete Schedule](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_schedule){:target="_blank"} +REST API: [Delete Schedule](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_schedule){:target="_blank"} @@ -1783,7 +1783,7 @@ schedule.get([req_options=None]) Returns all schedule items from the server. -REST API: [Query Schedules](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_schedules){:target="_blank"} +REST API: [Query Schedules](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_schedules){:target="_blank"} @@ -1869,7 +1869,7 @@ import tableauserverclient as TSC ## Server -In the Tableau REST API, the server (`http://MY-SERVER/`) is the base or core of the URI that makes up the various endpoints or methods for accessing resources on the server (views, workbooks, sites, users, data sources, etc.) +In the Tableau REST API, the server (`https://MY-SERVER/`) is the base or core of the URI that makes up the various endpoints or methods for accessing resources on the server (views, workbooks, sites, users, data sources, etc.) The TSC library provides a `Server` class that represents the server. You create a server instance to sign in to the server and to call the various methods for accessing resources. @@ -1888,7 +1888,7 @@ The `Server` class contains the attributes that represent the server on Tableau Attribute | Description :--- | :--- -`server_address` | Specifies the address of the Tableau Server or Tableau Online (for example, `http://MY-SERVER/`). +`server_address` | Specifies the address of the Tableau Server or Tableau Online (for example, `https://MY-SERVER/`). `version` | Specifies the version of the REST API to use (for example, `'2.5'`). When you use the TSC library to call methods that access Tableau Server, the `version` is passed to the endpoint as part of the URI (`https://MY-SERVER/api/2.5/`). Each release of Tableau Server supports specific versions of the REST API. New versions of the REST API are released with Tableau Server. By default, the value of `version` is set to `'2.3'`, which corresponds to Tableau Server 10.0. You can view or set this value. You might need to set this to a different value, for example, if you want to access features that are supported by the server and a later version of the REST API. For more information, see [REST API Versions](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm){:target="_blank"} @@ -1900,7 +1900,7 @@ import tableauserverclient as TSC # create a instance of server -server = TSC.Server('http://MY-SERVER') +server = TSC.Server('https://MY-SERVER') # sign in, etc. @@ -2028,7 +2028,7 @@ Error | Description import tableauserverclient as TSC # create a instance of server -server = TSC.Server('http://MY-SERVER') +server = TSC.Server('https://MY-SERVER') # set the version number > 2.3 # the server_info.get() method works in 2.4 and later @@ -2141,7 +2141,7 @@ Returns a new instance of `SiteItem`. import tableauserverclient as TSC # create an instance of server -server = TSC.Server('http://MY-SERVER') +server = TSC.Server('https://MY-SERVER') # create shortcut for admin mode content_users=TSC.SiteItem.AdminMode.ContentAndUsers @@ -2180,7 +2180,7 @@ Returns a list of all `SiteItem` objects and a `PaginationItem`. Use these value ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc. # query the sites @@ -2233,7 +2233,7 @@ Returns the `SiteItem`. ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc. a_site = server.sites.get_by_id('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d') @@ -2279,7 +2279,7 @@ Returns the `SiteItem`. ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc. a_site = server.sites.get_by_name('MY_SITE') @@ -2381,7 +2381,7 @@ Error | Description ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # sign in, etc. server.sites.delete('9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d') @@ -2577,7 +2577,7 @@ Error | Description # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', site_id='SITE') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): @@ -2731,7 +2731,7 @@ Adds the user to the site. To add a new user to the site you need to first create a new `user_item` (from `UserItem` class). When you create a new user, you specify the name of the user and their site role. For Tableau Online, you also specify the `auth_setting` attribute in your request. When you add user to Tableau Online, the name of the user must be the email address that is used to sign in to Tableau Online. After you add a user, Tableau Online sends the user an email invitation. The user can click the link in the invitation to sign in and update their full name and password. -REST API: [Add User to Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_site){:target="_blank"} +REST API: [Add User to Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#add_user_to_site){:target="_blank"} **Parameters** @@ -2774,7 +2774,7 @@ Returns information about the users on the specified site. To get information about the workbooks a user owns or has view permission for, you must first populate the `UserItem` with workbook information using the [populate_workbooks(*user_item*)](#populate-workbooks-user) method. -REST API: [Get Users on Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} +REST API: [Get Users on Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} **Parameters** @@ -2794,7 +2794,7 @@ Returns a list of `UserItem` objects and a `PaginationItem` object. Use these v ```py import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -server = TSC.Server('http://SERVERURL') +server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): all_users, pagination_item = server.users.get() @@ -2814,7 +2814,7 @@ users.get_by_id(user_id) Returns information about the specified user. -REST API: [Query User On Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_user_on_site){:target="_blank"} +REST API: [Query User On Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_user_on_site){:target="_blank"} **Parameters** @@ -2873,7 +2873,7 @@ Returns information about the workbooks that the specified user owns and has Rea This method retrieves the workbook information for the specified user. The REST API is designed to return only the information you ask for explicitly. When you query for all the users, the workbook information for each user is not included. Use this method to retrieve information about the workbooks that the user owns or has Read (view) permissions. The method adds the list of workbooks to the user item object (`user_item.workbooks`). -REST API: [Query Datasource Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} +REST API: [Query Datasource Connections](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_data_source_connections){:target="_blank"} **Parameters** @@ -2930,7 +2930,7 @@ users.remove(user_id) Removes the specified user from the site. -REST API: [Remove User from Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} +REST API: [Remove User from Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#remove_user_from_site){:target="_blank"} **Parameters** @@ -2954,7 +2954,7 @@ Error | Description # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): server.users.remove('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') @@ -2974,11 +2974,11 @@ users.update(user_item, password=None) Updates information about the specified user. -The information you can modify depends upon whether you are using Tableau Server or Tableau Online, and whether you have configured Tableau Server to use local authentication or Active Directory. For more information, see [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"}. +The information you can modify depends upon whether you are using Tableau Server or Tableau Online, and whether you have configured Tableau Server to use local authentication or Active Directory. For more information, see [Update User](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"}. -REST API: [Update User](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"} +REST API: [Update User](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_user){:target="_blank"} **Parameters** @@ -3007,7 +3007,7 @@ An updated `UserItem`. See [UserItem class](#useritem-class) # import tableauserverclient as TSC # tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') with server.auth.sign_in(tableau_auth): @@ -3119,7 +3119,7 @@ Returns a list of all `ViewItem` objects and a `PaginationItem`. Use these value ```py import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('username', 'password') -server = TSC.Server('http://servername') +server = TSC.Server('https://servername') with server.auth.sign_in(tableau_auth): all_views, pagination_item = server.views.get() @@ -3425,7 +3425,7 @@ Queries the server and returns information about the workbooks the site. -REST API: [Query Workbooks for Site](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbooks_for_site){:target="_blank"} +REST API: [Query Workbooks for Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbooks_for_site){:target="_blank"} **Parameters** @@ -3446,7 +3446,7 @@ Returns a list of all `WorkbookItem` objects and a `PaginationItem`. Use these v import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') -server = TSC.Server('http://servername') +server = TSC.Server('https://servername') with server.auth.sign_in(tableau_auth): all_workbooks, pagination_item = server.workbooks.get() @@ -3470,7 +3470,7 @@ workbooks.get_by_id(workbook_id) Returns information about the specified workbook on the site. -REST API: [Query Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook){:target="_blank"} +REST API: [Query Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook){:target="_blank"} **Parameters** @@ -3521,7 +3521,7 @@ unless you package the data and workbook in a .twbx file, or publish the data so For workbooks that are larger than 64 MB, the publish method automatically takes care of chunking the file in parts for uploading. Using this method is considerably more convenient than calling the publish REST APIs directly. -REST API: [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"}, [Initiate File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#initiate_file_upload){:target="_blank"}, [Append to File Upload](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#append_to_file_upload){:target="_blank"} +REST API: [Publish Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"}, [Initiate File Upload](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#initiate_file_upload){:target="_blank"}, [Append to File Upload](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#append_to_file_upload){:target="_blank"} @@ -3545,7 +3545,7 @@ Error | Description `Workbooks cannot be appended.` | The `mode` must be set to `Overwrite` or `CreateNew`. `Only .twb or twbx files can be published as workbooks.` | Raises an error if the type of file specified is not supported. -See the REST API [Publish Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"} for additional error codes. +See the REST API [Publish Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#publish_workbook){:target="_blank"} for additional error codes. **Returns** @@ -3558,7 +3558,7 @@ The `WorkbookItem` for the workbook that was published. import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') -server = TSC.Server('http://servername') +server = TSC.Server('https://servername') with server.auth.sign_in(tableau_auth): # create a workbook item @@ -3580,7 +3580,7 @@ workbooks.update(workbook_item) Modifies an existing workbook. Use this method to change the owner or the project that the workbook belongs to, or to change whether the workbook shows views in tabs. The workbook item must include the workbook ID and overrides the existing settings. -REST API: [Update Workbooks](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook){:target="_blank"} +REST API: [Update Workbooks](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook){:target="_blank"} **Parameters** @@ -3600,7 +3600,7 @@ Error | Description import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') -server = TSC.Server('http://servername') +server = TSC.Server('https://servername') with server.auth.sign_in(tableau_auth): @@ -3638,7 +3638,7 @@ Deletes a workbook with the specified ID. To specify the site, create a `TableauAuth` instance using the content URL for the site (`site_id`), and sign in to that site. See the [TableauAuth class](#tableauauth-class). -REST API: [Delete Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#Delete_Workbook31){:target="_blank"} +REST API: [Delete Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#Delete_Workbook31){:target="_blank"} **Parameters** @@ -3661,7 +3661,7 @@ Error | Description ```py # import tableauserverclient as TSC -# server = TSC.Server('http://MY-SERVER') +# server = TSC.Server('https://MY-SERVER') # tableau_auth sign in, etc. server.workbooks.delete('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') @@ -3682,7 +3682,7 @@ workbooks.download(workbook_id, filepath=None, no_extract=False) Downloads a workbook to the specified directory (optional). -REST API: [Download Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_workbook){:target="_blank"} +REST API: [Download Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#download_workbook){:target="_blank"} **Parameters** @@ -3733,7 +3733,7 @@ You must first call this method to populate views before you can iterate through This method retrieves the view information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query for all the data sources, the view information is not included. Use this method to retrieve the views. The method adds the list of views to the workbook item (`workbook_item.views`). This is a list of `ViewItem`. -REST API: [Query Views for Workbook](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_views_for_workbook){:target="_blank"} +REST API: [Query Views for Workbook](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_views_for_workbook){:target="_blank"} **Parameters** @@ -3761,7 +3761,7 @@ None. A list of `ViewItem` objects are added to the workbook (`workbook_item.vie ```py # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # ... @@ -3796,7 +3796,7 @@ connections. This method retrieves the data source connection information for the specified workbook. The REST API is designed to return only the information you ask for explicitly. When you query all the workbooks, the data source connection information is not included. Use this method to retrieve the connection information for any data sources used by the workbook. The method adds the list of data connections to the workbook item (`workbook_item.connections`). This is a list of `ConnectionItem`. -REST API: [Query Workbook Connections](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_connections){:target="_blank"} +REST API: [Query Workbook Connections](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_connections){:target="_blank"} **Parameters** @@ -3824,7 +3824,7 @@ None. A list of `ConnectionItem` objects are added to the data source (`workbook ```py # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') # ... @@ -3858,7 +3858,7 @@ This method gets the preview image (thumbnail) for the specified workbook item. The method uses the `view.id` and `workbook.id` to identify the preview image. The method populates the `workbook_item.preview_image`. -REST API: [Query View Preview Image](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_preview_image){:target="_blank"} +REST API: [Query View Preview Image](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_preview_image){:target="_blank"} **Parameters** @@ -3888,7 +3888,7 @@ None. The preview image is added to the view. # import tableauserverclient as TSC -# server = TSC.Server('http://SERVERURL') +# server = TSC.Server('https://SERVERURL') ... @@ -3911,7 +3911,7 @@ Updates a workbook connection information (server address, server port, user nam The workbook connections must be populated before the strings can be updated. See [workbooks.populate_connections](#workbooks.populate_connections) -REST API: [Update Workbook Connection](http://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook_connection){:target="_blank"} +REST API: [Update Workbook Connection](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_workbook_connection){:target="_blank"} **Parameters** From f4bcafe612d8e779779382966b0f35dbf9d7ef5c Mon Sep 17 00:00:00 2001 From: Irwin Dolobowsky Date: Fri, 2 Aug 2019 18:17:31 +0000 Subject: [PATCH 019/158] Update api-ref.md Updating datasource.update to be an update to ownerID instead of name as data sources can't be renamed. Also added a note that name cannot be changed in teh description. --- docs/api-ref.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 63412f95e..4be763c53 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -570,7 +570,7 @@ The `DatasourceItem` for the data source that was added or appended to. datasource.update(datasource_item) ``` -Updates the owner, or project of the specified data source. +Updates the owner or project of the specified data source. Data source name cannot be updated. REST API: [Update Datasource](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_source){:target="_blank"} @@ -605,7 +605,7 @@ An updated `DatasourceItem`. datasource = server.datasources.get_by_id('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') # do some updating - datasource.name = 'New Name' + datasource.owner_id = 'New Owner ID' # call the update method with the data source item updated_datasource = server.datasources.update(datasource) From 8b6747e37d1347e4acb129501977aaa1ec4a741d Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 5 Aug 2019 10:29:36 -0700 Subject: [PATCH 020/158] Update api-ref.md Fix site.get() code sample - remove extraneous ")" ```for site in all_sites):``` to ```for site in all_sites:``` --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 4be763c53..7915017df 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -2187,7 +2187,7 @@ Returns a list of all `SiteItem` objects and a `PaginationItem`. Use these value all_sites, pagination_item = server.sites.get() # print all the site names and ids - for site in all_sites): + for site in all_sites: print(site.id, site.name, site.content_url, site.state) From 9f42a46afd979d9335e92c6e6c8ee9f6576f774f Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Tue, 6 Aug 2019 14:06:13 -0700 Subject: [PATCH 021/158] Update sign-in-out.md Revised page to address Issue #355 (add site specification on sign in) --- docs/sign-in-out.md | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index f619aaeab..61a7e29ac 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -3,28 +3,32 @@ title: Sign In and Out layout: docs --- -To sign in and out of Tableau Server, call the `Auth.sign_in` and `Auth.sign_out` functions like so: +To sign in and out of Tableau Server, call the server's `.auth.signin` method in a`with` block. ```py import tableauserverclient as TSC -tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') -server = TSC.Server('http://SERVER_URL') +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', `SITENAME`) +server = TSC.Server('https://SERVER_URL') -server.auth.sign_in(tableau_auth) +with server.auth.sign_in(tableau_auth): + # Do awesome things here! +``` -# Do awesome things here! +The `SERVER_URL` is the URL of the Tableau server without subpaths. For local Tableau servers, in the form of: `https://www.MY_SERVER.com`. For Tableau Online, `https://10ax.online..tableau.com/`. -server.auth.sign_out() -``` +`SITENAME` is same as the `contentURL`, or site subpath, of your full site URL. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. + +Optionally, you can override the Tableau API version by adding `server.version = ''` before the `auth.signin` call. + +The TSC library signs you out of Tableau Server when you exit out of the `with` block.
    - Note: When you sign in, the TSC library manages the authenticated session for you, however it is still - limited by the maximum session length (of four hours) on Tableau Server. + Note: When you sign in, the TSC library manages the authenticated session for you, however the validity of the underlying + credentials token is limited by the maximum session length set on your Tableau Server (2 hours by default).
    - -Alternatively, for short programs, consider using a `with` block: +An option to using a `with` block is to call the `Auth.sign_in` and `Auth.sign_out` functions explicitly. ```py import tableauserverclient as TSC @@ -32,8 +36,9 @@ import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') server = TSC.Server('http://SERVER_URL') -with server.auth.sign_in(tableau_auth): - # Do awesome things here! -``` +server.auth.sign_in(tableau_auth) -The TSC library signs you out of Tableau Server when you exit out of the `with` block. +# Do awesome things here! + +server.auth.sign_out() +``` From fb8adbe83df77e5c2d8f4572f3a234ce6ad0b4e3 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Tue, 6 Aug 2019 17:12:31 -0700 Subject: [PATCH 022/158] Update sign-in-out.md small improvements --- docs/sign-in-out.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index 61a7e29ac..0d1304791 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -15,11 +15,11 @@ with server.auth.sign_in(tableau_auth): # Do awesome things here! ``` -The `SERVER_URL` is the URL of the Tableau server without subpaths. For local Tableau servers, in the form of: `https://www.MY_SERVER.com`. For Tableau Online, `https://10ax.online..tableau.com/`. +`SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. -`SITENAME` is same as the `contentURL`, or site subpath, of your full site URL. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. +`SITENAME` is the subpath of your site of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. -Optionally, you can override the Tableau API version by adding `server.version = ''` before the `auth.signin` call. +Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. The TSC library signs you out of Tableau Server when you exit out of the `with` block. @@ -28,7 +28,7 @@ The TSC library signs you out of Tableau Server when you exit out of the `with` credentials token is limited by the maximum session length set on your Tableau Server (2 hours by default). -An option to using a `with` block is to call the `Auth.sign_in` and `Auth.sign_out` functions explicitly. +An alternative to using a `with` block is to call the `Auth.sign_in` and `Auth.sign_out` functions explicitly. ```py import tableauserverclient as TSC From 5e1a2a58982563cfdb11cdc26f1ffd779414f341 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Tue, 6 Aug 2019 17:14:43 -0700 Subject: [PATCH 023/158] Update sign-in-out.md typo fix --- docs/sign-in-out.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index 0d1304791..61b65961e 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -17,7 +17,7 @@ with server.auth.sign_in(tableau_auth): `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. -`SITENAME` is the subpath of your site of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. +`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. From 8c5a159ae22aa9cc470ed8b15ad13facd57b4a35 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Wed, 7 Aug 2019 10:49:59 -0700 Subject: [PATCH 024/158] Update api-ref.md (#479) --- docs/api-ref.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 7915017df..14e48f031 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -249,7 +249,7 @@ Name | Description `name` | The name of the data source. If not specified, the name of the published data source file is used. `project_id` | The identifier of the project associated with the data source. When you must provide this identifier when create an instance of a `DatasourceItem` `project_name` | The name of the project associated with the data source. -`tags` | The tags that have been added to the data source. +`tags` | The tags (list of strings) that have been added to the data source. `updated_at` | The date and time when the data source was last updated. @@ -3449,9 +3449,9 @@ tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') server = TSC.Server('https://servername') with server.auth.sign_in(tableau_auth): - all_workbooks, pagination_item = server.workbooks.get() + all_workbooks_items, pagination_item = server.workbooks.get() # print names of first 100 workbooks - print([workbook.name for workbook in all_workbooks]) + print([workbook.name for workbook in all_workbooks_items]) From 60f0470c0d16b2e3622facbbbf4d720a07fcffee Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Fri, 9 Aug 2019 13:04:16 -0700 Subject: [PATCH 025/158] Update index.md (#481) * Update index.md Added *Install on an offline machine* in response to #365 Also added `SITENAME` and descriptive text to sign in of get started example per #355 * Update index.md (#482) Removed test dependencies in anticipation of @t8y8 's package with those dependencies unwired. --- docs/index.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 9fd8b699e..45d62e6b7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -48,6 +48,14 @@ pip install git+https://github.com/tableau/server-client-python.git@development Note that the version from the development branch should not be used for production code. The methods and endpoints in the development version are subject to change at any time before the next stable release. +### Install on an offline machine + +To install TSC onto a machine without internet connection, use the following steps: + +1) Download and manually install the **requests** python library (and its dependencies). +2) Download the [setup package](https://pypi.org/project/tableauserverclient/#files){:target="_blank"}. +3) Run `pip install ./downloads/tableauserverclient-x.x.tar.gz` + ## Get the samples The TSC samples are included in the `samples` directory of the TSC repository on Github. You can run the following command to clone the @@ -66,7 +74,7 @@ Run the following code to get a list of all the data sources on your installatio ```py import tableauserverclient as TSC -tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', 'SITENAME') server = TSC.Server('http://SERVER_URL') with server.auth.sign_in(tableau_auth): @@ -74,3 +82,7 @@ with server.auth.sign_in(tableau_auth): print("\nThere are {} datasources on site: ".format(pagination_item.total_available)) print([datasource.name for datasource in all_datasources]) ``` + +> `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. + +>`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a on premise Tableau server. From 14a1937dd5f498e138b6801343374ec49663a19f Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Fri, 9 Aug 2019 13:10:44 -0700 Subject: [PATCH 026/158] Update index.md --- docs/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.md b/docs/index.md index 45d62e6b7..25d16086b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -53,7 +53,9 @@ development version are subject to change at any time before the next stable rel To install TSC onto a machine without internet connection, use the following steps: 1) Download and manually install the **requests** python library (and its dependencies). + 2) Download the [setup package](https://pypi.org/project/tableauserverclient/#files){:target="_blank"}. + 3) Run `pip install ./downloads/tableauserverclient-x.x.tar.gz` ## Get the samples From c90fb3988d8c16b2c4ee900093a15e166c61160e Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 12 Aug 2019 10:08:26 -0700 Subject: [PATCH 027/158] Update sign-in-out.md (#480) change "locally installed" to "on premise" --- docs/sign-in-out.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index 61b65961e..12c19bf4c 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -17,7 +17,7 @@ with server.auth.sign_in(tableau_auth): `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. -`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a locally installed Tableau server. +`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. From ede678117156ef284420269ede8a0ed55edbef5e Mon Sep 17 00:00:00 2001 From: Albin Antony Date: Mon, 12 Aug 2019 22:48:21 +0530 Subject: [PATCH 028/158] Documentation: Update Write your first program (#474) * Documentation: Update Write your first program TableauAuth Class requires a third parameter site_id as given in the API reference. If only username and password is given it would lead to a Authentication Error. * Upadted Write your first program Added extra example for Tableau online. * Update index.md * Update in Write Your first program changed SITEID to SITE_NAME and made the explanation more clear. --- docs/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 25d16086b..43c8508b4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -84,7 +84,6 @@ with server.auth.sign_in(tableau_auth): print("\nThere are {} datasources on site: ".format(pagination_item.total_available)) print([datasource.name for datasource in all_datasources]) ``` - > `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. >`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of a on premise Tableau server. From ab84a68f948dbfd8ae6b1348d91168943e95cc1c Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 12 Aug 2019 10:25:07 -0700 Subject: [PATCH 029/158] Update sign-in-out.md --- docs/sign-in-out.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index 12c19bf4c..668325b86 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -15,9 +15,11 @@ with server.auth.sign_in(tableau_auth): # Do awesome things here! ``` -`SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. +> `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: + `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. -`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. +> `SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of + `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. From 98b5b9317dafe7e684e18e21e33dfc7b530fb02c Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 12 Aug 2019 10:46:00 -0700 Subject: [PATCH 030/158] Update sign-in-out.md --- docs/sign-in-out.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index 668325b86..ce8e7e960 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -15,11 +15,9 @@ with server.auth.sign_in(tableau_auth): # Do awesome things here! ``` -> `SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: - `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. +`SERVER_URL` is the URL of your Tableau server without subpaths. For local Tableau servers, an example would be: `https://www.MY_SERVER.com`. For Tableau Online, an example would be: `https://10ax.online.tableau.com/`. -> `SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of - `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. +`SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. From 079bf08b21087319513eeb528c5f2945318712a6 Mon Sep 17 00:00:00 2001 From: prae04 Date: Tue, 27 Aug 2019 12:43:07 -0400 Subject: [PATCH 031/158] Simple typo (#493) --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 14e48f031..d8e3fed81 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -894,7 +894,7 @@ Returns information about the groups on the site. To get information about the users in a group, you must first populate the `GroupItem` with user information using the [groups.populate_users](api-ref#groupspopulate_users) method. -REST API: [Get Uers on Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} +REST API: [Get Users on Site](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_users_on_site){:target="_blank"} **Parameters** From 308d3323982a646f7e4ab523140376eaa816ae66 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Wed, 28 Aug 2019 16:17:43 -0700 Subject: [PATCH 032/158] Gh pages samples and refresh (#495) * update samples page, add workbook.refresh, adddatasource.refresh * minor fix * fixed @shinchris comments --- docs/api-ref.md | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/samples.md | 47 ++++++++++++++++++------- 2 files changed, 127 insertions(+), 12 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index d8e3fed81..0bf6fd69b 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -564,6 +564,53 @@ The `DatasourceItem` for the data source that was added or appended to.

    +#### datasources.refresh + +```py +datasource.refresh(datasource_item) +``` + +Refreshes the data of the specified extract. + +REST API: [Update Data Source Now](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_datasources.htm#update_data_source_now){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`datasource_item` | The `datasource_item` specifies the data source to update. + + + +**Exceptions** + +Error | Description + :--- | : --- +`Datasource item missing ID. Datasource must be retrieved from server first.` | Raises an error if the datasource_item is unspecified. Use the `Datasources.get()` method to retrieve that identifies for the data sources on the server. + + +**Returns** + +A refreshed `DatasourceItem`. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('https://SERVERURL') +# sign in ... + +# get the data source item to update + datasource = server.datasources.get_by_id('1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b') + +# call the refresh method with the data source item + refreshed_datasource = server.datasources.refresh(datasource) + +``` +
    +
    + #### datasources.update ```py @@ -3570,6 +3617,51 @@ with server.auth.sign_in(tableau_auth):

    +#### workbooks.refresh + +```py +workbooks.refresh(workbook_item) +``` + + +Refreshes the extract of an existing workbook. + +REST API: [Update Workbook Now](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooksviews.htm#update_workbook_now){:target="_blank"} + +**Parameters** + +Name | Description +:--- | :--- +`workbook_item` | The `workbook_item` specifies the settings for the workbook you are refreshing. + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook item missing ID. Workbook must be retrieved from server first.` | Raises an error if the `workbook_item` is unspecified. Use the `workbooks.get()` or `workbooks.get_by_id()` methods to retrieve the workbook item from the server. + + +```py + +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('username', 'password', site_id='site') +server = TSC.Server('https://servername') + +with server.auth.sign_in(tableau_auth): + + # get the workbook item from the site + workbook = server.workbooks.get_by_id('1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d') + + # call the update method + workbook = server.workbooks.refresh(workbook) + print("\nThe data of workbook {0} is refreshed.".format(workbook.name)) + + +``` + + +
    +
    #### workbooks.update diff --git a/docs/samples.md b/docs/samples.md index 3ea908dd6..eede1cb04 100644 --- a/docs/samples.md +++ b/docs/samples.md @@ -3,7 +3,7 @@ title: Samples layout: docs --- -The TSC samples are included in the `samples` directory of the TSC repository [on Github](https://github.com/tableau/server-client-python). +The TSC samples are included in the `samples` directory of the TSC repository [on Github](https://github.com/tableau/server-client-python/tree/master/samples). * TOC {:toc} @@ -32,24 +32,47 @@ publish. The following list describes the samples available in the repository: -* `create_group.py`. Create a user group. +* `create_group.py` Create a user group. -* `create_schedules.py`. Create schedules for extract refreshes and subscriptions. +* `create_project.py` Creates a project in a site. -* `explore_datasource.py`. Queries datasources, selects a datasource, populates connections for the datasource, then updates the datasource. +* `create_schedules.py` Create schedules for extract refreshes and subscriptions. -* `explore_workbook.py`. Queries workbooks, selects a workbook, populates the connections and views for a workbook, then updates the workbook. +* `download_view_image.py` Downloads an image of a specified view. -* `move_workbook_projects.py`. Updates the properties of a workbook to move the workbook from one project to another. +* `explore_datasource.py` Queries datasources, selects a datasource, populates connections for the datasource, then updates the datasource. -* `move_workbook_sites.py`. Downloads a workbook, stores it in-memory, and uploads it to another site. +* `explore_workbook.py` Queries workbooks, selects a workbook, populates the connections and views for a workbook, then updates the workbook. -* `pagination_sample.py`. Use the Pager generator to iterate over all the items on the server. +* `export.py` Exports a view as an image, pdf, or csv. -* `publish_workbook.py`. Publishes a Tableau workbook. +* `export_wb.py` Exports a pdf containing all views in a workbook. -* `set_http_options.py`. Sets HTTP options for the server and specifically for downloading workbooks. +* `filter_sort_groups.py` Demonstrates selecting user groups as filters. -**Note**: For all of the samples, ensure that your Tableau Server user account has permission to access the resources -requested by the samples. +* `initialize_server.py` Sets up an existing server instance with site, workbooks and datasources. + +* `kill_all_jobs.py` Kills all running jobs. + +* `list.py` Lists all datasources or workbooks of a site. + +* `move_workbook_projects.py` Updates the properties of a workbook to move the workbook from one project to another. + +* `move_workbook_sites.py` Downloads a workbook, stores it in-memory, and uploads it to another site. + +* `pagination_sample.py` Use the Pager generator to iterate over all the items on the server. + +* `publish_workbook.py` Publishes a Tableau workbook. + +* `refresh.py` Refreshes a datasource or workbook. + +* `refresh_tasks.py` Lists and runs configured tasks on a server. + +* `set_http_options.py` Sets HTTP options for the server and specifically for downloading workbooks. + +* `set_refresh_schedule.py` Sets the schedule to refresh a datasource or workbook. + +* `update_connection.py` Updates and embeds connection credentials of a datasource. + +**Note**: For all of the samples, ensure that your Tableau Server user account has permission to access the resources. From 30c7b1d318ffdad42ba9373ce176c2d48f025e69 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Thu, 29 Aug 2019 09:47:44 -0700 Subject: [PATCH 033/158] Gh pages add owner_id to datasourceItem (#496) * update samples page, add workbook.refresh, adddatasource.refresh * add owner_id to attributes of datasourceItem --- docs/api-ref.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 0bf6fd69b..f0109bdac 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -247,7 +247,8 @@ Name | Description `datasource_type` | The type of data source, for example, `sqlserver` or `excel-direct`. `id` | The identifier for the data source. You need this value to query a specific data source or to delete a data source with the `get_by_id` and `delete` methods. `name` | The name of the data source. If not specified, the name of the published data source file is used. -`project_id` | The identifier of the project associated with the data source. When you must provide this identifier when create an instance of a `DatasourceItem` +`owner_id` | The identifier of the owner of the data source. +`project_id` | The identifier of the project associated with the data source. You must provide this identifier when you create an instance of a `DatasourceItem`. `project_name` | The name of the project associated with the data source. `tags` | The tags (list of strings) that have been added to the data source. `updated_at` | The date and time when the data source was last updated. From 1c9e688431bf16a1f19ae274559c5019b1b54bbd Mon Sep 17 00:00:00 2001 From: Jac Date: Tue, 5 Nov 2019 11:00:31 -0800 Subject: [PATCH 034/158] bump bootstrap to 3.4.1 address xss vulnerability in 3.3.6 --- _includes/head.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_includes/head.html b/_includes/head.html index 083e3f268..1321285cf 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -7,12 +7,12 @@ - + - + {% if jekyll.environment == "production" %}{% include analytics.html %}{% endif %} From fed76449f3e59d19cb61113091d58c86d261237f Mon Sep 17 00:00:00 2001 From: Martin Peters Date: Mon, 11 Nov 2019 20:36:34 +0000 Subject: [PATCH 035/158] Added tasks sections to api-ref.md --- docs/api-ref.md | 209 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/docs/api-ref.md b/docs/api-ref.md index f0109bdac..b4316a122 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -2709,6 +2709,215 @@ The `SubscriptionItem`. See [SubscriptionItem class](#subscriptionitem-class)

    +--- + +## Tasks + +Using the TSC library, you can get information about all the tasks on a site and you can remove tasks. To create new tasks see [Schedules](#schedules). + +The task resources for Tableau Server are defined in the `TaskItem` class. The class corresponds to the task resources you can access using the Tableau Server REST API. The task methods are based upon the endpoints for tasks in the REST API and operate on the `TaskItem` class. + +### TaskItem class + +```py +TaskItem(id, task_type, priority, consecutive_failed_count=0, schedule_id=None, target=None) +``` + +**Attributes** + +Name | Description +:--- | :--- +`consecutive_failed_count` | The number of failed consecutive executions. +`id` | The id of the task on the site. +`priority` | The priority of the task on the server. +`schedule_id` | The id of the schedule on the site. +`target` | An object, `datasource` or `workbook` which is associated to the task. Source file: models/target.py +`task_type` | Type of extract task - full or incremental refresh. + + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('server') + + task = server.tasks.get_by_id('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + print(task) + +``` + +Source file: models/task_item.py + +
    +
    + + +### Tasks methods + +The Tableau Server Client provides several methods for interacting with task resources, or endpoints. These methods correspond to endpoints in the Tableau Server REST API. + +Source file: server/endpoint/tasks_endpoint.py +
    +
    + +#### tasks.get + +```py +tasks.get(req_options=None) +``` + +Returns information about the tasks on the specified site. + +REST API: [Get Extract Refresh Tasks on Site](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_extract_refresh_tasks){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`req_option` | (Optional) You can pass the method a request object that contains additional parameters to filter the request. + + +**Returns** + +Returns a list of `TaskItem` objects and a `PaginationItem` object. Use these values to iterate through the results. + + +**Example** + + +```py +import tableauserverclient as TSC +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +server = TSC.Server('https://SERVERURL') + +with server.auth.sign_in(tableau_auth): + all_tasks, pagination_item = server.tasks.get() + print("\nThere are {} tasks on site: ".format(pagination_item.total_available)) + print([task.id for task in all_tasks]) +``` + +
    +
    + +#### tasks.get_by_id + + +```py +tasks.get_by_id(task_id) +``` + +Returns information about the specified task. + +REST API: [Query Extract Refresh Task On Site](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_extract_refresh_task){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`task_id` | The `task_id` specifies the task to query. + + +**Exceptions** + +Error | Description + :--- | : --- +`Task ID undefined.` | Raises an exception if a valid `task_id` is not provided. + + +**Returns** + +The `TaskItem`. See [TaskItem class](#taskitem-class) + + +**Example** + +```py + task1 = server.tasks.get_by_id('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + print(task1.task_type) + +``` + +
    +
    + +#### tasks.run + + +```py +tasks.run(task_item) +``` + +Runs the specified extract refresh task. + +To run a extract refresh task you need to first lookup the task `task_item` (`TaskItem` class). + +REST API: [Run Extract Refresh Task](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#run_extract_refresh_task){:target="_blank"} + + +**Parameters** + +Name | Description + :--- | : --- +`task_item` | You can pass the method a task object. + + +**Returns** + +Returns the REST API response. + +**Example** + +```py +# import tableauserverclient as TSC +# server = TSC.Server('server') +# login, etc. + + task = server.tasks.get_by_id('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + server.tasks.run(task) + +``` + +
    +
    + +#### tasks.delete + + +```py +tasks.delete(task_id) +``` + +Deletes an extract refresh task. + +REST API: [Run Extract Refresh Task](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_jobstasksschedules.htm#delete_workbook){:target="_blank"} + +**Parameters** + +Name | Description + :--- | : --- +`task_id` | The `task_id` specifies the task to delete. + + +**Exceptions** + +Error | Description + :--- | : --- +`Task ID undefined.` | Raises an exception if a valid `task_id` is not provided. + + +**Example** + +```py + server.tasks.delete('9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d') + +``` + +
    +
    + + --- ## Users From e4eacd3ad9a9355f7d2d9040a8204034d4fa52e7 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 10 Feb 2020 09:43:43 -0800 Subject: [PATCH 036/158] Update api-ref.md Fixed role description for `userItem`. --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index f0109bdac..9a51a43a9 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -2739,7 +2739,7 @@ Name | Description `email` | The email address of the user. `fullname` | The full name of the user. `name` | The name of the user. This attribute is required when you are creating a `UserItem` instance. -`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The specific roles vary depending upon the version of the REST API. For example, for version 2.8 and earlier, the `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `Viewer`, `ViewerWithPublish`, `Guest`. For REST API 3.0 and later, the `site_role` can be one of the following `Creator`, `Explorer`, `ExplorerCanPublish`, `ReadOnly`, `SiteAdministratorCreator`, `SiteAdministratorExplorer`, `UnlicensedWithPublish`. +`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The specific roles vary depending upon the version of the REST API. For example, for version 2.8 and earlier, the `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `ReadOnly`, `Viewer`, `ViewerWithPublish`, `Guest`. For REST API 3.0 and later, the `site_role` can be one of the following `Creator`, `Explorer`, `ExplorerCanPublish`, `Viewer`, `SiteAdministratorCreator`, `SiteAdministratorExplorer`, `UnlicensedWithPublish`. **Example** From 2bf76156a307c5a6d4d8573d7ba6c1f92c86b702 Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Mon, 10 Feb 2020 09:54:00 -0800 Subject: [PATCH 037/158] Update api-ref.md Fix to fix of UserItem role description. --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 9a51a43a9..e7488eb5a 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -2739,7 +2739,7 @@ Name | Description `email` | The email address of the user. `fullname` | The full name of the user. `name` | The name of the user. This attribute is required when you are creating a `UserItem` instance. -`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The specific roles vary depending upon the version of the REST API. For example, for version 2.8 and earlier, the `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `ReadOnly`, `Viewer`, `ViewerWithPublish`, `Guest`. For REST API 3.0 and later, the `site_role` can be one of the following `Creator`, `Explorer`, `ExplorerCanPublish`, `Viewer`, `SiteAdministratorCreator`, `SiteAdministratorExplorer`, `UnlicensedWithPublish`. +`site_role` | The role the user has on the site. This attribute is required with you are creating a `UserItem` instance. The specific roles vary depending upon the version of the REST API. For example, for version 2.8 and earlier, the `site_role` can be one of the following: `Interactor`, `Publisher`, `ServerAdministrator`, `SiteAdministrator`, `Unlicensed`, `UnlicensedWithPublish`, `Viewer`, `ViewerWithPublish`, `Guest`. For REST API 3.0 and later, the `site_role` can be one of the following `Creator`, `Explorer`, `ExplorerCanPublish`, `ReadOnly` *(viewers from previous API versions who do not have v3.0+ viewer permissions)*, `Viewer`, `SiteAdministratorCreator`, `SiteAdministratorExplorer`, `UnlicensedWithPublish`. **Example** From b923ca6ea4df0db62e90b5b203a9e76aaf0f4dea Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Tue, 25 Feb 2020 18:05:04 -0800 Subject: [PATCH 038/158] Update versions.md Adding supported versions --- docs/versions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/versions.md b/docs/versions.md index 648945d7a..5589985d0 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -65,3 +65,6 @@ The current version of TSC only supports the following REST API and Tableau Serv |3.1|2018.2| |3.2|2018.3| |3.3|2019.1| +|3.4|2019.2| +|3.5|2019.3| +|3.6|2019.4| From 0d0f118218047776e0f569909175aa29ad0e4f6f Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Fri, 28 Feb 2020 13:44:03 -0800 Subject: [PATCH 039/158] Update copyright date with script --- _includes/footer.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_includes/footer.html b/_includes/footer.html index ee1481e55..a3177d7f5 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -3,6 +3,7 @@

    This site is open source. Suggestions and pull requests are welcome on our GitHub page.

    -

    © 2018 Tableau.

    +

    © Copyright Tableau

    + Documentation last generated on: {{ site.time }}>
    From ec06b8035423448650d5612969940f976de54459 Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Fri, 28 Feb 2020 13:49:56 -0800 Subject: [PATCH 040/158] Update footer.html --- _includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/footer.html b/_includes/footer.html index a3177d7f5..35ea121c7 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -4,6 +4,6 @@

    This site is open source. Suggestions and pull requests are welcome on our GitHub page.

    © Copyright Tableau

    - Documentation last generated on: {{ site.time }}> + Documentation last generated on: {{ site.time }} From f002465525cff47f540fddec63b2c814af1fbd56 Mon Sep 17 00:00:00 2001 From: mbren Date: Fri, 28 Feb 2020 18:32:03 -0500 Subject: [PATCH 041/158] adding doc for the data acceleration sample --- docs/accelerate_workbook_doc.md | 499 ++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 docs/accelerate_workbook_doc.md diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md new file mode 100644 index 000000000..91a240207 --- /dev/null +++ b/docs/accelerate_workbook_doc.md @@ -0,0 +1,499 @@ +--- +title: Getting Started with Data Acceleration +layout: docs +--- + +* TOC +{:toc} + +## Introduction + +Administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. + +The easiest way to configure data acceleration is to use the `accelerate_workbook.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the Tableau Server REST API. + +Workbooks with published and live data sources (both with embedded credentials), and workbooks with embedded extracts are supported. Workbooks with embedded extracts do not need to be scheduled. Workbooks with published and live data sources need to have a data acceleration task added to a schedule. + +Not supported, are workbooks with encrypted extracts or workbooks that include user-based, now(), today() functions. Federated data sources are not supported. Data Blending is partially supported for acceleration; Data queried against the secondary data sources is not accelerated. + +## Limitations + +* Site and Server Administrator permission are required to control data acceleration. +* Only those workbooks with embedded credentials can be accelerated. +* The pre-computed data is saved into the Tableau Cache.  The cache is subject to the cache size limit and the cache expiration limit. We recommend that you review your configuration and recommend 2GB or larger. +* When you attach an acceleration schedule to a workbook, if that acceleration schedule interval exceeds the Tableau Server cache expiration time, the workbook will not be accelerated during the period between the cache expiration time and the next run of the acceleration schedule.  The workbook will revert to using the databases. By default, the Tableau Server cache expiration time is 12 hours (720 minutes). +* Workbooks using encrypted extracts or that include user-based, now(), today() functions are not supported currently and will not be accelerated. +* Federated Data Source is not supported for acceleration. When there is a workbook containing both federated data sources and other data sources, the data queried against federated data sources will not be accelerated. +* Data Blending is partially supported for acceleration. Data queried against the secondary data sources are not accelerated. +* Data acceleration schedules are not currently supported to be created in the Tableau Server schedules view.  + +## Prerequisites + +When using this feature, it is recommended to increase the size of the Tableau Server external cache to 2 GB or larger. + +View your current Tableau Server external cache size setting: +`tsm configuration get -k redis.max_memory_in_mb` + +Set the Tableau Server external cache size to 2 GB: +`tsm configuration set -k redis.max_memory_in_mb -v 2048` +`tsm pending-changes apply` + +## Quick Start Tutorial + +This tutorial shows you how to enable and schedule workbooks for data acceleration using the `accelerate_workbook.py` command line tool. + +Note: You must be signed in as a server administrator to create schedules or use site-level commands. For other commands, you can use the server administrator role or the site administrator role. + +### Sign Into Tableau Server + +`python accelerate_workbook.py --server --username --password --site ` + +For information about how to identify the site value, see [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out). If you don’t specify a site, you will be signed into the Default site.   + +### Enable Workbooks That Only Use Embedded Extracts + +When data acceleration is enabled, a workbook that only has data sources that are embedded extracts does not require an acceleration schedule. Tableau Server automatically identifies the changes to its content and data whenever the workbook is republished or its extracts are refreshed (manually or on a schedule) and it submits a background task for the data pre-computation.  Thus, this type of workbook can be accelerated by just enabling it with the command: + +`python accelerate_workbook.py --enable "My Project/Embedded Extract Workbook"` + +Note: If a workbook is in a nested project, its path may be like "Project 1/Project 2/Workbook Name". Workbook paths are case sensitive. + +The server will enable the workbook and you will see the following output: + +Workbooks enabled +Project/Workbook +My Project/Embedded Extract Workbook + +After the background task for pre-computation of the workbook's data is completed, subsequent loads of the workbooks will use those pre-computed results. The background task may take a few minutes to finish. + +### Schedule Workbooks With Published or Live Data Sources + +Workbooks with published or live data sources need to be scheduled for acceleration, which keeps their data fresh. + +This command will create an acceleration schedule called "My Schedule" that runs every 4 hours throughout the day. + +`python accelerate_workbook.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` + +Next, we'll associate this acceleration schedule with your workbooks: + +`python accelerate_workbook.py --add-to-schedule "My Schedule" "My Project/My Workbook"` + +You will see the following output: + +Workbooks added to schedule +Project/Workbook | Schedules +My Project/My Workbook | My Schedule + +Users can also attach multiple workbooks to "My Schedule" by using a path list. + +`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list pathfile.txt` + +In the 'pathfile.txt' file, each line defines a workbook path. + +My project/My Workbook +Finance Project/Expenses +Sales Project/Leads Per Region + +Note: If a workbook uses only embedded extracts then an acceleration schedule will not be attached even when the user issues the `--add-to-schedule command`. + +### Monitor Your Accelerated Workbooks + +To see which workbooks have been enabled, use the `--status`, and `--show-schedules` commands. + +Display all the workbooks that are enabled, and which acceleration schedules are associated. +`python accelerate_workbook.py --status` + +Display the accelerated schedules associated with workbooks. +`python accelerate_workbook.py --show-schedules` + +### Load Your Accelerated Workbooks and Check the Performance + +#### Tableau Server Administrator Views + +Tableau Server provides an administrator view to review the load times for workbooks. See [Stats for Load Times](https://help.tableau.com/current/server/en-us/adminview_stats_load_time.htm). + +### Sign Out of Tableau Server + +Log out of Tableau Server and end your session. +`python accelerate_workbook.py --logout` + +## Command Reference + +Note: Optional arguments are indicated with []. + +### Get Help + +Get a list of the available commands. + +`python accelerate_workbook.py --help` + +### Sign Into Tableau Server + +In Tableau Server, creating schedules and site level commands require the user to be signed in with an account with the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is required. + +`python accelerate_workbook.py [--server] [SERVER_URL] [--site] [SITE_NAME] [--username] [Username] [--password] [password]` + +SITE_NAME is the sub-path of your full site URL (also called contentURL in the REST API). Given the site URL 'https://my.tableauserver.com/MYSITE', 'MYSITE' is the site name. See [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out) for identifying the [SITE_NAME]. When `--site` is not specified or is specified with "" the Default site will be used. + +After a successful sign in, a session token file (".token_profile") will be created and saved in the same directory as `accelerate_workbook.py`. The token file will be deleted when you log out. + +Example: Sign into Tableau Server and the Default site + +`python accelerate_workbook.py --server https://server --site "" --username user1 --password password1` + +You can ignore the SSL Certificate by pressing the ENTER key when prompted. + +Example: Sign into Tableau Server with an SSL certificate + +`python accelerate_workbook.py --server https://server --site "" --username user1 --password password1 --ssl-cert-pem cert.pem` + +Example: Switch the site that you are logged into + +`python accelerate_workbook.py --server https://server --username user1 --password password1 --site different_site` + +Example: For some usernames and passwords it may be necessary to use double quotes. + +`python accelerate_workbook.py --server https://server --site "" --username "user space name" --password "password with spaces"` + +Example: Double quotes "" should not be used when prompted for input: + +`python accelerate_workbook.py --server https://server` + +site (hit enter for the Default site): +username: user space name +password: password with spaces +path to ssl certificate (hit enter to ignore): cert.pem + +### Sign Out of Tableau Server + +The session token file (".token_profile") created on login will be deleted when you log out. + +Example: Sign out of Tableau Server + +`python accelerate_workbook.py --logout` + +When successfully signed out of Tableau Server, you will see the following message, "Signed out from current connection to https://server successfully". If you are not connected to an existing server, you will see the following message, "No existing connection to any server." + +### Create Data Acceleration Schedules + +The following command is used to create a data acceleration schedule. + +`python accelerate_workbook.py --create-schedule SCHEDULE_NAME INTERVAL_TYPE [INTERVAL] [START_TIME] [END_TIME]` + +In Tableau Server, creating schedules requires the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is sufficient. + +INTERVAL_TYPE can be one of the four options below: +--hourly-interval with INTERVAL in {0.25,0.5,1,2,4,6,8,12}, the unit is hour. +--daily-interval, INTERVAL is not needed +--weekly-interval with INTERVAL as a non-empty subset of: +{Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} +--monthly-interval, INTERVAL is the starting day in a month. + +[START_TIME] is optional. If no starting time is specified, the default time 00:00:00 is used. To specify the starting time, --start-hour and --start-minute can be used to specify the time. + +[END_TIME] is optional. If no end time is specified, the end of the day will be used. To specify the ending time, --end-hour and --end-minute can be used to specify the time. END_TIME option is only useful for hourly interval. + +The warning, "Warning: The recurrence interval of the given schedule is larger than Vizql server data refresh interval of 720 minutes." will be displayed if the users try to create a schedule that exceeds the configured VizQL server data refresh interval. By default, this is set to 12 hours (720 minutes). + +Example 1: Create a scheduled pre-computation every 4 hours. + +In this example, a pre-computation background task will be submitted every 4 hours throughout the day. + +`python accelerate_workbook.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` + +After the acceleration schedule is created using the command line client, it can be viewed in the Tableau Server Schedules view. The scheduled task type will not currently be displayed. + +### Associate Workbooks to a Schedule + +You can associate a workbook to single or multiple data acceleration schedules. If your workbook has not been enabled for acceleration, the --add-schedule command will automatically enable the workbook. + +`python accelerate_workbook.py --add-to-schedule [SCHEDULE_NAME] --workbook-path WORKBOOK_PATH` + +`python accelerate_workbook.py --add-to-schedule [SCHEDULE_NAME] --path-list PATH_LIST` + +Example 1: Associate a workbook to a schedule + +`python accelerate_workbook.py --add-to-schedule "My Schedule" --workbook-path project/workbook1` + +```iecst +Workbooks added to schedule +Project/Workbook | Schedules +Default/my workbook1 | My Schedule +``` + +Example 2: Associate an acceleration schedule using a text file with a path list containing one or more workbooks. + +`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list path.txt` + +```iecst +Workbooks added to schedule +Project/Workbook Schedules +Default/my workbook1 My Schedule +Default/my workbook2 My Schedule +``` + +Example 3: Associate acceleration schedules with a workbook that is only extract data source based. + +Any workbook that uses only embedded extracts as its data source does not require an explicit acceleration schedule and thus it will only be enabled for acceleration without using an acceleration schedule. For these workbooks, the Tableau Server will automatically identify changes to the workbook content and data. Whenever the workbook is republished or its extract refreshes (manually or scheduled) a background task is submitted to pre-compute the data. + +In the example below, an attempt was made to add "My Schedule" to a workbook with only embedded extracts. The workbook is enabled for acceleration and it is not added to the "My Schedule" acceleration schedule. + +`python accelerate_workbook.py --add-to-schedule "My schedule" Default/WorkbookwithOnlyExtracts` + +```iecst +Workbooks added to schedule: None +Warning: Unable to add workbook "Default/WorkbookwithOnlyExtracts" to schedule due to Workbook with id 10000 uses only embedded extract(s) and does not need explicit scheduling for acceleration. It was enabled for acceleration but not attached to the given schedule. +``` + +`python accelerate_workbook.py --show-schedule` + +```iecst +Workbooks added to schedule +Project/Workbook Schedules +Default/my workbook1 My Schedule +Default/my workbook2 My Schedule +``` + +For workbooks that are not supported you will see the following warnings: + +Workbooks with encrypted embedded extracts: +`Unable to enable Default/Sales. Workbook 'Sales' is not supported for data acceleration because it only uses encrypted embedded extracts as data sources.` + +Workbooks where credentials are not embedded: +`Unable to enable Default/Finance. Workbook 'Finance' is not supported for data acceleration because it uses data sources without embedding credentials.` + +The following warning will be displayed if the users try to create a schedule that exceeds the configured VizQL server data refresh interval. By default, this is set to 12 hours (720 minutes). +`Warning: The recurrence interval of the given schedule is larger than Vizql server data refresh interval of 720 minutes.` + +### Enable Workbooks + +Enabling a workbook will opt in the workbook for acceleration. data acceleration will monitor the relevant Tableau events that could potentially change the data of the workbooks such as workbook publishing, extract refreshing (if the workbook has any) and web authoring. Pre-computation will be triggered after these events. However, the data source changes which are not managed by Tableau will not be monitored and the acceleration schedule is used for keeping the pre-computed data up to date in those scenarios. + +To enable one workbook: + +`python accelerate_workbook.py --enable [--workbook-path] WORKBOOK_PATH` + +To enable one or more workbooks in batches, you can provide a file specifying a list of workbooks. + +`python accelerate_workbook.py --enable [--path-list] PATH_LIST` + +Example 1: Enable a single workbook + +`python accelerate_workbook.py --enable Default/Workbook1` + +Example 2: Enable multiple workbooks + +Create a path file for example `paths.txt` using the format below project/workbook: +Default/Workbook1 +Default/Workbook2 +The following command will enable the workbooks defined in the paths.txt file. + +`python accelerate_workbook.py --enable --path-list paths.txt` + +```iecst +Workbooks enabled +Project/Workbook +Default/my workbook1 +Default/my workbook2 +``` + +For workbooks that are not currently supported, you will see the following warnings: + +Workbooks with encrypted embedded extracts: +`Unable to enable Default/Sales. Workbook 'Sales' is not supported for data acceleration because it only uses encrypted embedded extracts as data sources.` + +Workbooks where credentials are not embedded: +`Unable to enable Default/Finance. Workbook 'Finance' is not supported for data acceleration because it uses data sources without embedding credentials.` + +### Detach a Workbook from a Schedule + +Use the --remove-from-schedule command to detach a workbook from a schedule. + +`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME [--workbook-path] WORKBOOK_PATH` + +`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME [---path-list] PATH_LIST` + +`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME project/workbook` + +Example 1: Removing multiple workbooks from a schedule using --path-list. +In the example below "workbook1" and "workbook2" was detached from the acceleration schedule "My Schedule". Any workbooks included in the path list are not associated with "My Schedule". + +`python accelerate_workbook.py --remove-from-schedule "My Schedule" --path-list "paths.txt"` + +```iecst +Workbooks removed from schedule +Project/Workbook Schedules +Default/workbook1 My Schedule +Default/workbook2 My Schedule + +Workbooks not on schedule "My Schedule" +Project/Workbook +Default/extractworkbook +``` + +Example 2: Remove a workbook from a schedule + +`python accelerate_workbook.py --remove-from-schedule "My Schedule" Default/workbook1` + +```iecst +Workbooks removed to schedule +Project/Workbook Removed From Schedule +Default/my workbook1 My Schedule +``` + +Example 3: + +`python accelerate_workbook.py --remove-from-schedule "My Schedule" --workbook-path Default/workbook1` + +```iecst +Workbooks removed from schedule +Project/Workbook Schedules +Default/workbook1 My Schedule +``` + +### Accelerate On-Demand + +You can use --enable combined with --acceleration-now to submit a backgrounder pre-computation job on demand. This can be useful to trigger a pre-computation ahead of the next scheduled run. + +`python accelerate_workbook.py --enable --accelerate-now --path-list PATH_LIST` + +`python accelerate_workbook.py --enable WORKBOOK_PATH --accelerate-now` + +Example 1: + +`python accelerate_workbook.py --enable Default/workbook1 --accelerate-now` + +### Disable Workbooks + +Disabling a workbook stops accelerating the workbook. It detaches the workbook from the workbook's associated schedules and cleans up all of the acceleration artifacts related to the workbook. It will not remove entries from the Tableau query cache. + +`python accelerate_workbook.py --disable [--workbook-path] WORKBOOK_PATH` + +`python accelerate_workbook.py --disable --path-list PATH_LIST` + +`python accelerate_workbook.py --disable --workbook-path Default/workbook1` + +```iecst +Workbooks Disabled +Project/Workbook +Default/workbook1 +``` + +### Enable or Disable a Site for Data Acceleration + +The following commands are used to enable or disable a site for acceleration. + +`python accelerate_workbook.py --enable --site SITE_NAME --type site` + +`python accelerate_workbook.py --disable --site SITE_NAME --type site` + +Workbooks can only be enabled for acceleration if their site is enabled. Enabling a site will not enable any workbooks automatically. All sites are enabled for acceleration by default. Enabling a site is only needed when a site is explicitly disabled, or a site is imported from another Tableau Server. + +Disabling a site for acceleration will disable all workbooks that were currently enabled for acceleration. Once a site is disabled, no workbooks can be enabled on this site until this site is enabled again. All workbooks under that site will be disabled and detached from any accelerated schedules they are associated with. + +In Tableau Server, to enable or disable acceleration requires the user to be signed in with an account with the Server Administrator role. + +Example 1: Disable the Default site for acceleration + +`python accelerate_workbook.py --disable --site SITE_NAME --type site` + +Example 2: Enable the Default site for acceleration + +`python accelerate_workbook.py --enable --site SITE_NAME --type site` + +### Display Acceleration Schedules + +The --show-schedules command displays the schedule information for enabled workbooks associated with their accelerated schedules. The schedule information includes the schedule name associated with the workbooks and their next run time. + +`python accelerate_workbook.py --show-schedules` + +`python accelerate_workbook.py --show-schedules SCHEDULE_NAME [--workbook-path] [WORKBOOK_PATH]` + +`python accelerate_workbook.py --show-schedules SCHEDULE_NAME [---path-list] [PATH_LIST]` + +Note: If --workbook-path or –path-list are omitted, the command will show all the enabled workbooks with their schedule information. + +Example 1: When there are no data acceleration schedules associated with enabled workbooks + +`python accelerate_workbook.py --show-schedules` + +Scheduled Tasks for Data Acceleration: None + +Example 2: When there are enabled workbooks with data acceleration schedules + +```iecst +Scheduled Tasks for Data Acceleration + +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 +``` + +### Show Acceleration Status + +The --status command shows the list of workbooks enabled for acceleration and their associated schedules. When a workbook is enabled but not associated with any schedule, an asterisk '*' will be shown in the Schedule column. In that case, the pre-computed data for workbooks will be updated when the workbooks are re-published, or their extracts (if they have any) get refreshed. Workbooks that only contain embedded extracts will not be associated with schedules. + +`python accelerate_workbook.py --status` + +Example 1: Display the status of all enabled and scheduled accelerated workbooks. + +`python accelerate_workbook.py --status` + +```iecst +Data Acceleration is enabled for the following workbooks +Site Project/Workbook +Default Default/extractworkbook +Default Default/liveworkbook +Default Default/liveandextractworkbook + +Scheduled Tasks for Data Acceleration +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 + +*The Data Acceleration views for these workbooks will be updated when they are published, or when their extract is refreshed. +``` + +### Specify workbook paths + +This section describes how to specify the workbook path argument and the path list argument in the commands --add-to-schedule, --enable, --remove-from-schedule. + +--workbook-path +[WORKBOOK_PATH] is the path concatenating the project path and the workbook name by "/" where the project path is the path of the project directly containing the workbook to the root project. The path is in the form of "Project Name/Workbook Name". If a workbook is in a nested project, its path may be like "Project 1/Project 2/Workbook Name". Workbook paths are case sensitive. + +Double quotes are required for specifying the workbook path if it contains whitespace. + +`python accelerate_workbook.py --enable [--workbook-path] PATH_LIST` + +Example 1: Specifying --workbook-path + +`python accelerate_workbook.py --enable --workbook-path "project/workbook with spaces"` + +Example 2: --workbook-path is optional + +`python accelerate_workbook.py --enable project/workbook` + +Example 3: --workbook-path is optional + +`python accelerate_workbook.py --add-to-schedule "My Schedule" project/workbook` + +--path-list +PATH_LIST is a text file where each line is a workbook path. In the PATH_LIST, there is no need to use double quotes for workbook paths that contain whitespace. + +Here is an example paths text file: +projectLevel1/projectLevel2/workbook1 +project1/workbook2 + +Example 1: Enable multiple workbooks + +`python accelerate_workbook.py --enable --path-list paths.txt` + +Example 2: Add multiple workbooks to a schedule. + +`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list paths.txt` + +Example 3: Remove multiple workbooks from a schedule. + +`python accelerate_workbook.py –-remove-from-schedule "My Schedule" --path-list paths.txt` From 61d43e1b45828e8d73c9e7ee2a90c06a2f4f58b3 Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:10:11 -0500 Subject: [PATCH 042/158] Update accelerate_workbook_doc.md remove duplicated information and incorporate feedback. --- docs/accelerate_workbook_doc.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index 91a240207..e9101dc07 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -8,23 +8,21 @@ layout: docs ## Introduction -Administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. +Starting in Tableau Server version 2020.2 and later, administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. -The easiest way to configure data acceleration is to use the `accelerate_workbook.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the Tableau Server REST API. +The easiest way to configure data acceleration is to use the `accelerate_workbook.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the [Tableau Server REST API](https://help.tableau.com/v2020.2/api/rest_api/en-us/REST/rest_api.htm). Workbooks with published and live data sources (both with embedded credentials), and workbooks with embedded extracts are supported. Workbooks with embedded extracts do not need to be scheduled. Workbooks with published and live data sources need to have a data acceleration task added to a schedule. -Not supported, are workbooks with encrypted extracts or workbooks that include user-based, now(), today() functions. Federated data sources are not supported. Data Blending is partially supported for acceleration; Data queried against the secondary data sources is not accelerated. - ## Limitations * Site and Server Administrator permission are required to control data acceleration. * Only those workbooks with embedded credentials can be accelerated. * The pre-computed data is saved into the Tableau Cache.  The cache is subject to the cache size limit and the cache expiration limit. We recommend that you review your configuration and recommend 2GB or larger. * When you attach an acceleration schedule to a workbook, if that acceleration schedule interval exceeds the Tableau Server cache expiration time, the workbook will not be accelerated during the period between the cache expiration time and the next run of the acceleration schedule.  The workbook will revert to using the databases. By default, the Tableau Server cache expiration time is 12 hours (720 minutes). -* Workbooks using encrypted extracts or that include user-based, now(), today() functions are not supported currently and will not be accelerated. -* Federated Data Source is not supported for acceleration. When there is a workbook containing both federated data sources and other data sources, the data queried against federated data sources will not be accelerated. -* Data Blending is partially supported for acceleration. Data queried against the secondary data sources are not accelerated. +* Workbooks using encrypted extracts or that include user-based, now(), today() functions are not supported. +* Federated data sources are not supported. When there is a workbook containing both federated data sources and other data sources, the data queried against federated data sources will not be accelerated. +* Data Blending is partially supported for acceleration. Data queried against the secondary data sources is not accelerated. * Data acceleration schedules are not currently supported to be created in the Tableau Server schedules view.  ## Prerequisites From 172a4808e7ca2ed0e6f343e2e0230842df25c7df Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:19:58 -0500 Subject: [PATCH 043/158] Update accelerate_workbook_doc.md incorporate feedback --- docs/accelerate_workbook_doc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index e9101dc07..49de9a06b 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -422,10 +422,10 @@ Example 2: When there are enabled workbooks with data acceleration schedules ```iecst Scheduled Tasks for Data Acceleration -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 ``` ### Show Acceleration Status From 2b2164b09ce41c5a96f026502f182a6880bb9324 Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:27:05 -0500 Subject: [PATCH 044/158] Update accelerate_workbook_doc.md incorporated feedback. --- docs/accelerate_workbook_doc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index 49de9a06b..ac275a187 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -8,7 +8,7 @@ layout: docs ## Introduction -Starting in Tableau Server version 2020.2 and later, administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. +Starting in Tableau Server version 2020.2, administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. The easiest way to configure data acceleration is to use the `accelerate_workbook.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the [Tableau Server REST API](https://help.tableau.com/v2020.2/api/rest_api/en-us/REST/rest_api.htm). @@ -27,7 +27,7 @@ Workbooks with published and live data sources (both with embedded credentials), ## Prerequisites -When using this feature, it is recommended to increase the size of the Tableau Server external cache to 2 GB or larger. +When using this feature, it is recommended to increase the size of the Tableau Server external query cache to 2 GB or larger because it is used to store the results from acceleration. Query results that exceed this limit will not be cached. The result of not having enough storage for query results is that precomputed results are not cached and those queries will be executed as normal against the data source. View your current Tableau Server external cache size setting: `tsm configuration get -k redis.max_memory_in_mb` From be4b93cd254e74255bddd9ab22b49fcd50723a34 Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:30:04 -0500 Subject: [PATCH 045/158] Update accelerate_workbook_doc.md incorporate feedback --- docs/accelerate_workbook_doc.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index ac275a187..21f51a7e0 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -424,7 +424,7 @@ Scheduled Tasks for Data Acceleration Project/Workbook Schedule Next Run Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 ``` @@ -446,10 +446,10 @@ Default Default/liveworkbook Default Default/liveandextractworkbook Scheduled Tasks for Data Acceleration -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 *The Data Acceleration views for these workbooks will be updated when they are published, or when their extract is refreshed. ``` From 6195dc5ee579de58ad74014d3bb2228351c042ef Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:32:13 -0500 Subject: [PATCH 046/158] Update accelerate_workbook_doc.md added feedback --- docs/accelerate_workbook_doc.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index 21f51a7e0..8c3043989 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -422,10 +422,10 @@ Example 2: When there are enabled workbooks with data acceleration schedules ```iecst Scheduled Tasks for Data Acceleration -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 +Project/Workbook | Schedule | Next Run +Default/extractworkbook | * +Default/liveworkbook | My Schedule | 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook | My Schedule | 2020-01-22 16:00:00-08:00 ``` ### Show Acceleration Status @@ -446,10 +446,10 @@ Default Default/liveworkbook Default Default/liveandextractworkbook Scheduled Tasks for Data Acceleration -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 +Project/Workbook | Schedule | Next Run +Default/extractworkbook | * +Default/liveworkbook | My Schedule | 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook | My Schedule | 2020-01-22 16:00:00-08:00 *The Data Acceleration views for these workbooks will be updated when they are published, or when their extract is refreshed. ``` From 90aa35d2786934801224c20f3fe1bc17dc4457da Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Mon, 2 Mar 2020 15:35:57 -0500 Subject: [PATCH 047/158] Update accelerate_workbook_doc.md fix table formatting --- docs/accelerate_workbook_doc.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index 8c3043989..1a65a20dd 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -422,10 +422,10 @@ Example 2: When there are enabled workbooks with data acceleration schedules ```iecst Scheduled Tasks for Data Acceleration -Project/Workbook | Schedule | Next Run -Default/extractworkbook | * -Default/liveworkbook | My Schedule | 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook | My Schedule | 2020-01-22 16:00:00-08:00 +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 ``` ### Show Acceleration Status @@ -446,10 +446,10 @@ Default Default/liveworkbook Default Default/liveandextractworkbook Scheduled Tasks for Data Acceleration -Project/Workbook | Schedule | Next Run -Default/extractworkbook | * -Default/liveworkbook | My Schedule | 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook | My Schedule | 2020-01-22 16:00:00-08:00 +Project/Workbook Schedule Next Run +Default/extractworkbook * +Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 +Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 *The Data Acceleration views for these workbooks will be updated when they are published, or when their extract is refreshed. ``` From c824c654a9e5dac8ba7ac2bd5081313e85c80a4d Mon Sep 17 00:00:00 2001 From: mbren Date: Fri, 6 Mar 2020 15:51:10 -0500 Subject: [PATCH 048/158] fix script name --- docs/accelerate_workbook_doc.md | 122 ++++++++++++++++---------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md index 91a240207..aac277c4a 100644 --- a/docs/accelerate_workbook_doc.md +++ b/docs/accelerate_workbook_doc.md @@ -8,9 +8,9 @@ layout: docs ## Introduction -Administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. +Tableau Server administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. -The easiest way to configure data acceleration is to use the `accelerate_workbook.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the Tableau Server REST API. +The easiest way to configure data acceleration is to use the `accelerate_workbooks.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the Tableau Server REST API. Workbooks with published and live data sources (both with embedded credentials), and workbooks with embedded extracts are supported. Workbooks with embedded extracts do not need to be scheduled. Workbooks with published and live data sources need to have a data acceleration task added to a schedule. @@ -40,13 +40,13 @@ Set the Tableau Server external cache size to 2 GB: ## Quick Start Tutorial -This tutorial shows you how to enable and schedule workbooks for data acceleration using the `accelerate_workbook.py` command line tool. +This tutorial shows you how to enable and schedule workbooks for data acceleration using the `accelerate_workbooks.py` command line tool. Note: You must be signed in as a server administrator to create schedules or use site-level commands. For other commands, you can use the server administrator role or the site administrator role. ### Sign Into Tableau Server -`python accelerate_workbook.py --server --username --password --site ` +`python accelerate_workbooks.py --server --username --password --site ` For information about how to identify the site value, see [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out). If you don’t specify a site, you will be signed into the Default site.   @@ -54,7 +54,7 @@ For information about how to identify the site value, see [Sign In and Out](ht When data acceleration is enabled, a workbook that only has data sources that are embedded extracts does not require an acceleration schedule. Tableau Server automatically identifies the changes to its content and data whenever the workbook is republished or its extracts are refreshed (manually or on a schedule) and it submits a background task for the data pre-computation.  Thus, this type of workbook can be accelerated by just enabling it with the command: -`python accelerate_workbook.py --enable "My Project/Embedded Extract Workbook"` +`python accelerate_workbooks.py --enable "My Project/Embedded Extract Workbook"` Note: If a workbook is in a nested project, its path may be like "Project 1/Project 2/Workbook Name". Workbook paths are case sensitive. @@ -72,11 +72,11 @@ Workbooks with published or live data sources need to be scheduled for accel This command will create an acceleration schedule called "My Schedule" that runs every 4 hours throughout the day. -`python accelerate_workbook.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` +`python accelerate_workbooks.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` Next, we'll associate this acceleration schedule with your workbooks: -`python accelerate_workbook.py --add-to-schedule "My Schedule" "My Project/My Workbook"` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" "My Project/My Workbook"` You will see the following output: @@ -86,7 +86,7 @@ My Project/My Workbook | My Schedule Users can also attach multiple workbooks to "My Schedule" by using a path list. -`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list pathfile.txt` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list pathfile.txt` In the 'pathfile.txt' file, each line defines a workbook path. @@ -101,10 +101,10 @@ Note: If a workbook uses only embedded extracts then an acceleration To see which workbooks have been enabled, use the `--status`, and `--show-schedules` commands. Display all the workbooks that are enabled, and which acceleration schedules are associated. -`python accelerate_workbook.py --status` +`python accelerate_workbooks.py --status` Display the accelerated schedules associated with workbooks. -`python accelerate_workbook.py --show-schedules` +`python accelerate_workbooks.py --show-schedules` ### Load Your Accelerated Workbooks and Check the Performance @@ -115,7 +115,7 @@ Tableau Server provides an administrator view to review the load times for workb ### Sign Out of Tableau Server Log out of Tableau Server and end your session. -`python accelerate_workbook.py --logout` +`python accelerate_workbooks.py --logout` ## Command Reference @@ -125,39 +125,39 @@ Note: Optional arguments are indicated with []. Get a list of the available commands. -`python accelerate_workbook.py --help` +`python accelerate_workbooks.py --help` ### Sign Into Tableau Server In Tableau Server, creating schedules and site level commands require the user to be signed in with an account with the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is required. -`python accelerate_workbook.py [--server] [SERVER_URL] [--site] [SITE_NAME] [--username] [Username] [--password] [password]` +`python accelerate_workbooks.py [--server] [SERVER_URL] [--site] [SITE_NAME] [--username] [Username] [--password] [password]` SITE_NAME is the sub-path of your full site URL (also called contentURL in the REST API). Given the site URL 'https://my.tableauserver.com/MYSITE', 'MYSITE' is the site name. See [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out) for identifying the [SITE_NAME]. When `--site` is not specified or is specified with "" the Default site will be used. -After a successful sign in, a session token file (".token_profile") will be created and saved in the same directory as `accelerate_workbook.py`. The token file will be deleted when you log out. +After a successful sign in, a session token file (".token_profile") will be created and saved in the same directory as `accelerate_workbooks.py`. The token file will be deleted when you log out. Example: Sign into Tableau Server and the Default site -`python accelerate_workbook.py --server https://server --site "" --username user1 --password password1` +`python accelerate_workbooks.py --server https://server --site "" --username user1 --password password1` You can ignore the SSL Certificate by pressing the ENTER key when prompted. Example: Sign into Tableau Server with an SSL certificate -`python accelerate_workbook.py --server https://server --site "" --username user1 --password password1 --ssl-cert-pem cert.pem` +`python accelerate_workbooks.py --server https://server --site "" --username user1 --password password1 --ssl-cert-pem cert.pem` Example: Switch the site that you are logged into -`python accelerate_workbook.py --server https://server --username user1 --password password1 --site different_site` +`python accelerate_workbooks.py --server https://server --username user1 --password password1 --site different_site` Example: For some usernames and passwords it may be necessary to use double quotes. -`python accelerate_workbook.py --server https://server --site "" --username "user space name" --password "password with spaces"` +`python accelerate_workbooks.py --server https://server --site "" --username "user space name" --password "password with spaces"` Example: Double quotes "" should not be used when prompted for input: -`python accelerate_workbook.py --server https://server` +`python accelerate_workbooks.py --server https://server` site (hit enter for the Default site): username: user space name @@ -170,7 +170,7 @@ The session token file (".token_profile") created on login will be deleted when Example: Sign out of Tableau Server -`python accelerate_workbook.py --logout` +`python accelerate_workbooks.py --logout` When successfully signed out of Tableau Server, you will see the following message, "Signed out from current connection to https://server successfully". If you are not connected to an existing server, you will see the following message, "No existing connection to any server." @@ -178,7 +178,7 @@ When successfully signed out of Tableau Server, you will see the following messa The following command is used to create a data acceleration schedule. -`python accelerate_workbook.py --create-schedule SCHEDULE_NAME INTERVAL_TYPE [INTERVAL] [START_TIME] [END_TIME]` +`python accelerate_workbooks.py --create-schedule SCHEDULE_NAME INTERVAL_TYPE [INTERVAL] [START_TIME] [END_TIME]` In Tableau Server, creating schedules requires the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is sufficient. @@ -199,7 +199,7 @@ Example 1: Create a scheduled pre-computation every 4 hours. In this example, a pre-computation background task will be submitted every 4 hours throughout the day. -`python accelerate_workbook.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` +`python accelerate_workbooks.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` After the acceleration schedule is created using the command line client, it can be viewed in the Tableau Server Schedules view. The scheduled task type will not currently be displayed. @@ -207,13 +207,13 @@ After the acceleration schedule is created using the command line client, it can You can associate a workbook to single or multiple data acceleration schedules. If your workbook has not been enabled for acceleration, the --add-schedule command will automatically enable the workbook. -`python accelerate_workbook.py --add-to-schedule [SCHEDULE_NAME] --workbook-path WORKBOOK_PATH` +`python accelerate_workbooks.py --add-to-schedule [SCHEDULE_NAME] --workbook-path WORKBOOK_PATH` -`python accelerate_workbook.py --add-to-schedule [SCHEDULE_NAME] --path-list PATH_LIST` +`python accelerate_workbooks.py --add-to-schedule [SCHEDULE_NAME] --path-list PATH_LIST` Example 1: Associate a workbook to a schedule -`python accelerate_workbook.py --add-to-schedule "My Schedule" --workbook-path project/workbook1` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" --workbook-path project/workbook1` ```iecst Workbooks added to schedule @@ -223,7 +223,7 @@ Default/my workbook1 | My Schedule Example 2: Associate an acceleration schedule using a text file with a path list containing one or more workbooks. -`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list path.txt` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list path.txt` ```iecst Workbooks added to schedule @@ -238,14 +238,14 @@ Any workbook that uses only embedded extracts as its data source does not requir In the example below, an attempt was made to add "My Schedule" to a workbook with only embedded extracts. The workbook is enabled for acceleration and it is not added to the "My Schedule" acceleration schedule. -`python accelerate_workbook.py --add-to-schedule "My schedule" Default/WorkbookwithOnlyExtracts` +`python accelerate_workbooks.py --add-to-schedule "My schedule" Default/WorkbookwithOnlyExtracts` ```iecst Workbooks added to schedule: None Warning: Unable to add workbook "Default/WorkbookwithOnlyExtracts" to schedule due to Workbook with id 10000 uses only embedded extract(s) and does not need explicit scheduling for acceleration. It was enabled for acceleration but not attached to the given schedule. ``` -`python accelerate_workbook.py --show-schedule` +`python accelerate_workbooks.py --show-schedule` ```iecst Workbooks added to schedule @@ -271,15 +271,15 @@ Enabling a workbook will opt in the workbook for acceleration. data acceleration To enable one workbook: -`python accelerate_workbook.py --enable [--workbook-path] WORKBOOK_PATH` +`python accelerate_workbooks.py --enable [--workbook-path] WORKBOOK_PATH` To enable one or more workbooks in batches, you can provide a file specifying a list of workbooks. -`python accelerate_workbook.py --enable [--path-list] PATH_LIST` +`python accelerate_workbooks.py --enable [--path-list] PATH_LIST` Example 1: Enable a single workbook -`python accelerate_workbook.py --enable Default/Workbook1` +`python accelerate_workbooks.py --enable Default/Workbook1` Example 2: Enable multiple workbooks @@ -288,7 +288,7 @@ Default/Workbook1 Default/Workbook2 The following command will enable the workbooks defined in the paths.txt file. -`python accelerate_workbook.py --enable --path-list paths.txt` +`python accelerate_workbooks.py --enable --path-list paths.txt` ```iecst Workbooks enabled @@ -309,16 +309,16 @@ Workbooks where credentials are not embedded: Use the --remove-from-schedule command to detach a workbook from a schedule. -`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME [--workbook-path] WORKBOOK_PATH` +`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME [--workbook-path] WORKBOOK_PATH` -`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME [---path-list] PATH_LIST` +`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME [---path-list] PATH_LIST` -`python accelerate_workbook.py --remove-from-schedule SCHEDULE_NAME project/workbook` +`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME project/workbook` Example 1: Removing multiple workbooks from a schedule using --path-list. In the example below "workbook1" and "workbook2" was detached from the acceleration schedule "My Schedule". Any workbooks included in the path list are not associated with "My Schedule". -`python accelerate_workbook.py --remove-from-schedule "My Schedule" --path-list "paths.txt"` +`python accelerate_workbooks.py --remove-from-schedule "My Schedule" --path-list "paths.txt"` ```iecst Workbooks removed from schedule @@ -333,7 +333,7 @@ Default/extractworkbook Example 2: Remove a workbook from a schedule -`python accelerate_workbook.py --remove-from-schedule "My Schedule" Default/workbook1` +`python accelerate_workbooks.py --remove-from-schedule "My Schedule" Default/workbook1` ```iecst Workbooks removed to schedule @@ -343,7 +343,7 @@ Default/my workbook1 My Schedule Example 3: -`python accelerate_workbook.py --remove-from-schedule "My Schedule" --workbook-path Default/workbook1` +`python accelerate_workbooks.py --remove-from-schedule "My Schedule" --workbook-path Default/workbook1` ```iecst Workbooks removed from schedule @@ -355,23 +355,23 @@ Default/workbook1 My Schedule You can use --enable combined with --acceleration-now to submit a backgrounder pre-computation job on demand. This can be useful to trigger a pre-computation ahead of the next scheduled run. -`python accelerate_workbook.py --enable --accelerate-now --path-list PATH_LIST` +`python accelerate_workbooks.py --enable --accelerate-now --path-list PATH_LIST` -`python accelerate_workbook.py --enable WORKBOOK_PATH --accelerate-now` +`python accelerate_workbooks.py --enable WORKBOOK_PATH --accelerate-now` Example 1: -`python accelerate_workbook.py --enable Default/workbook1 --accelerate-now` +`python accelerate_workbooks.py --enable Default/workbook1 --accelerate-now` ### Disable Workbooks Disabling a workbook stops accelerating the workbook. It detaches the workbook from the workbook's associated schedules and cleans up all of the acceleration artifacts related to the workbook. It will not remove entries from the Tableau query cache. -`python accelerate_workbook.py --disable [--workbook-path] WORKBOOK_PATH` +`python accelerate_workbooks.py --disable [--workbook-path] WORKBOOK_PATH` -`python accelerate_workbook.py --disable --path-list PATH_LIST` +`python accelerate_workbooks.py --disable --path-list PATH_LIST` -`python accelerate_workbook.py --disable --workbook-path Default/workbook1` +`python accelerate_workbooks.py --disable --workbook-path Default/workbook1` ```iecst Workbooks Disabled @@ -383,9 +383,9 @@ Default/workbook1 The following commands are used to enable or disable a site for acceleration. -`python accelerate_workbook.py --enable --site SITE_NAME --type site` +`python accelerate_workbooks.py --enable --site SITE_NAME --type site` -`python accelerate_workbook.py --disable --site SITE_NAME --type site` +`python accelerate_workbooks.py --disable --site SITE_NAME --type site` Workbooks can only be enabled for acceleration if their site is enabled. Enabling a site will not enable any workbooks automatically. All sites are enabled for acceleration by default. Enabling a site is only needed when a site is explicitly disabled, or a site is imported from another Tableau Server. @@ -395,27 +395,27 @@ In Tableau Server, to enable or disable acceleration requires the user to be sig Example 1: Disable the Default site for acceleration -`python accelerate_workbook.py --disable --site SITE_NAME --type site` +`python accelerate_workbooks.py --disable --site SITE_NAME --type site` Example 2: Enable the Default site for acceleration -`python accelerate_workbook.py --enable --site SITE_NAME --type site` +`python accelerate_workbooks.py --enable --site SITE_NAME --type site` ### Display Acceleration Schedules The --show-schedules command displays the schedule information for enabled workbooks associated with their accelerated schedules. The schedule information includes the schedule name associated with the workbooks and their next run time. -`python accelerate_workbook.py --show-schedules` +`python accelerate_workbooks.py --show-schedules` -`python accelerate_workbook.py --show-schedules SCHEDULE_NAME [--workbook-path] [WORKBOOK_PATH]` +`python accelerate_workbooks.py --show-schedules SCHEDULE_NAME [--workbook-path] [WORKBOOK_PATH]` -`python accelerate_workbook.py --show-schedules SCHEDULE_NAME [---path-list] [PATH_LIST]` +`python accelerate_workbooks.py --show-schedules SCHEDULE_NAME [---path-list] [PATH_LIST]` Note: If --workbook-path or –path-list are omitted, the command will show all the enabled workbooks with their schedule information. Example 1: When there are no data acceleration schedules associated with enabled workbooks -`python accelerate_workbook.py --show-schedules` +`python accelerate_workbooks.py --show-schedules` Scheduled Tasks for Data Acceleration: None @@ -434,11 +434,11 @@ Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 The --status command shows the list of workbooks enabled for acceleration and their associated schedules. When a workbook is enabled but not associated with any schedule, an asterisk '*' will be shown in the Schedule column. In that case, the pre-computed data for workbooks will be updated when the workbooks are re-published, or their extracts (if they have any) get refreshed. Workbooks that only contain embedded extracts will not be associated with schedules. -`python accelerate_workbook.py --status` +`python accelerate_workbooks.py --status` Example 1: Display the status of all enabled and scheduled accelerated workbooks. -`python accelerate_workbook.py --status` +`python accelerate_workbooks.py --status` ```iecst Data Acceleration is enabled for the following workbooks @@ -465,19 +465,19 @@ This section describes how to specify the workbook path argument and the path li Double quotes are required for specifying the workbook path if it contains whitespace. -`python accelerate_workbook.py --enable [--workbook-path] PATH_LIST` +`python accelerate_workbooks.py --enable [--workbook-path] PATH_LIST` Example 1: Specifying --workbook-path -`python accelerate_workbook.py --enable --workbook-path "project/workbook with spaces"` +`python accelerate_workbooks.py --enable --workbook-path "project/workbook with spaces"` Example 2: --workbook-path is optional -`python accelerate_workbook.py --enable project/workbook` +`python accelerate_workbooks.py --enable project/workbook` Example 3: --workbook-path is optional -`python accelerate_workbook.py --add-to-schedule "My Schedule" project/workbook` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" project/workbook` --path-list PATH_LIST is a text file where each line is a workbook path. In the PATH_LIST, there is no need to use double quotes for workbook paths that contain whitespace. @@ -488,12 +488,12 @@ project1/workbook2 Example 1: Enable multiple workbooks -`python accelerate_workbook.py --enable --path-list paths.txt` +`python accelerate_workbooks.py --enable --path-list paths.txt` Example 2: Add multiple workbooks to a schedule. -`python accelerate_workbook.py --add-to-schedule "My Schedule" --path-list paths.txt` +`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list paths.txt` Example 3: Remove multiple workbooks from a schedule. -`python accelerate_workbook.py –-remove-from-schedule "My Schedule" --path-list paths.txt` +`python accelerate_workbooks.py –-remove-from-schedule "My Schedule" --path-list paths.txt` From 530147f578d9a8321b69fb3328cfa064edfa0d9c Mon Sep 17 00:00:00 2001 From: mbren Date: Wed, 11 Mar 2020 15:54:55 -0400 Subject: [PATCH 049/158] remove old documentation --- docs/accelerate_workbook_doc.md | 497 -------------------------------- 1 file changed, 497 deletions(-) delete mode 100644 docs/accelerate_workbook_doc.md diff --git a/docs/accelerate_workbook_doc.md b/docs/accelerate_workbook_doc.md deleted file mode 100644 index 26dc0bda3..000000000 --- a/docs/accelerate_workbook_doc.md +++ /dev/null @@ -1,497 +0,0 @@ ---- -title: Getting Started with Data Acceleration -layout: docs ---- - -* TOC -{:toc} - -## Introduction - -Starting in Tableau Server version 2020.2, administrators can enable data acceleration for specific workbooks. An accelerated workbook loads faster because Tableau Server pre-computes the workbook's data in a background process. - -The easiest way to configure data acceleration is to use the `accelerate_workbooks.py` sample in the Tableau Server Client library. It is also possible to configure data acceleration using the [Tableau Server REST API](https://help.tableau.com/v2020.2/api/rest_api/en-us/REST/rest_api.htm). - -Workbooks with published and live data sources (both with embedded credentials), and workbooks with embedded extracts are supported. Workbooks with embedded extracts do not need to be scheduled. Workbooks with published and live data sources need to have a data acceleration task added to a schedule. - -## Limitations - -* Site and Server Administrator permission are required to control data acceleration. -* Only those workbooks with embedded credentials can be accelerated. -* The pre-computed data is saved into the Tableau Cache.  The cache is subject to the cache size limit and the cache expiration limit. We recommend that you review your configuration and recommend 2GB or larger. -* When you attach an acceleration schedule to a workbook, if that acceleration schedule interval exceeds the Tableau Server cache expiration time, the workbook will not be accelerated during the period between the cache expiration time and the next run of the acceleration schedule.  The workbook will revert to using the databases. By default, the Tableau Server cache expiration time is 12 hours (720 minutes). -* Workbooks using encrypted extracts or that include user-based, now(), today() functions are not supported. -* Federated data sources are not supported. When there is a workbook containing both federated data sources and other data sources, the data queried against federated data sources will not be accelerated. -* Data Blending is partially supported for acceleration. Data queried against the secondary data sources is not accelerated. -* Data acceleration schedules are not currently supported to be created in the Tableau Server schedules view.  - -## Prerequisites - -When using this feature, it is recommended to increase the size of the Tableau Server external query cache to 2 GB or larger because it is used to store the results from acceleration. Query results that exceed this limit will not be cached. The result of not having enough storage for query results is that precomputed results are not cached and those queries will be executed as normal against the data source. - -View your current Tableau Server external cache size setting: -`tsm configuration get -k redis.max_memory_in_mb` - -Set the Tableau Server external cache size to 2 GB: -`tsm configuration set -k redis.max_memory_in_mb -v 2048` -`tsm pending-changes apply` - -## Quick Start Tutorial - -This tutorial shows you how to enable and schedule workbooks for data acceleration using the `accelerate_workbooks.py` command line tool. - -Note: You must be signed in as a server administrator to create schedules or use site-level commands. For other commands, you can use the server administrator role or the site administrator role. - -### Sign Into Tableau Server - -`python accelerate_workbooks.py --server --username --password --site ` - -For information about how to identify the site value, see [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out). If you don't specify a site, you will be signed into the Default site.   - -### Enable Workbooks That Only Use Embedded Extracts - -When data acceleration is enabled, a workbook that only has data sources that are embedded extracts does not require an acceleration schedule. Tableau Server automatically identifies the changes to its content and data whenever the workbook is republished or its extracts are refreshed (manually or on a schedule) and it submits a background task for the data pre-computation.  Thus, this type of workbook can be accelerated by just enabling it with the command: - -`python accelerate_workbooks.py --enable "My Project/Embedded Extract Workbook"` - -Note: If a workbook is in a nested project, its path may be like "Project 1/Project 2/Workbook Name". Workbook paths are case sensitive. - -The server will enable the workbook and you will see the following output: - -Workbooks enabled -Project/Workbook -My Project/Embedded Extract Workbook - -After the background task for pre-computation of the workbook's data is completed, subsequent loads of the workbooks will use those pre-computed results. The background task may take a few minutes to finish. - -### Schedule Workbooks With Published or Live Data Sources - -Workbooks with published or live data sources need to be scheduled for acceleration, which keeps their data fresh. - -This command will create an acceleration schedule called "My Schedule" that runs every 4 hours throughout the day. - -`python accelerate_workbooks.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` - -Next, we'll associate this acceleration schedule with your workbooks: - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" "My Project/My Workbook"` - -You will see the following output: - -Workbooks added to schedule -Project/Workbook | Schedules -My Project/My Workbook | My Schedule - -Users can also attach multiple workbooks to "My Schedule" by using a path list. - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list pathfile.txt` - -In the 'pathfile.txt' file, each line defines a workbook path. - -My project/My Workbook -Finance Project/Expenses -Sales Project/Leads Per Region - -Note: If a workbook uses only embedded extracts then an acceleration schedule will not be attached even when the user issues the `--add-to-schedule command`. - -### Monitor Your Accelerated Workbooks - -To see which workbooks have been enabled, use the `--status`, and `--show-schedules` commands. - -Display all the workbooks that are enabled, and which acceleration schedules are associated. -`python accelerate_workbooks.py --status` - -Display the accelerated schedules associated with workbooks. -`python accelerate_workbooks.py --show-schedules` - -### Load Your Accelerated Workbooks and Check the Performance - -#### Tableau Server Administrator Views - -Tableau Server provides an administrator view to review the load times for workbooks. See [Stats for Load Times](https://help.tableau.com/current/server/en-us/adminview_stats_load_time.htm). - -### Sign Out of Tableau Server - -Log out of Tableau Server and end your session. -`python accelerate_workbooks.py --logout` - -## Command Reference - -Note: Optional arguments are indicated with []. - -### Get Help - -Get a list of the available commands. - -`python accelerate_workbooks.py --help` - -### Sign Into Tableau Server - -In Tableau Server, creating schedules and site level commands require the user to be signed in with an account with the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is required. - -`python accelerate_workbooks.py [--server] [SERVER_URL] [--site] [SITE_NAME] [--username] [Username] [--password] [password]` - -SITE_NAME is the sub-path of your full site URL (also called contentURL in the REST API). Given the site URL 'https://my.tableauserver.com/MYSITE', 'MYSITE' is the site name. See [Sign In and Out](https://tableau.github.io/server-client-python/docs/sign-in-out) for identifying the [SITE_NAME]. When `--site` is not specified or is specified with "" the Default site will be used. - -After a successful sign in, a session token file (".token_profile") will be created and saved in the same directory as `accelerate_workbooks.py`. The token file will be deleted when you log out. - -Example: Sign into Tableau Server and the Default site - -`python accelerate_workbooks.py --server https://server --site "" --username user1 --password password1` - -You can ignore the SSL Certificate by pressing the ENTER key when prompted. - -Example: Sign into Tableau Server with an SSL certificate - -`python accelerate_workbooks.py --server https://server --site "" --username user1 --password password1 --ssl-cert-pem cert.pem` - -Example: Switch the site that you are logged into - -`python accelerate_workbooks.py --server https://server --username user1 --password password1 --site different_site` - -Example: For some usernames and passwords it may be necessary to use double quotes. - -`python accelerate_workbooks.py --server https://server --site "" --username "user space name" --password "password with spaces"` - -Example: Double quotes "" should not be used when prompted for input: - -`python accelerate_workbooks.py --server https://server` - -site (hit enter for the Default site): -username: user space name -password: password with spaces -path to ssl certificate (hit enter to ignore): cert.pem - -### Sign Out of Tableau Server - -The session token file (".token_profile") created on login will be deleted when you log out. - -Example: Sign out of Tableau Server - -`python accelerate_workbooks.py --logout` - -When successfully signed out of Tableau Server, you will see the following message, "Signed out from current connection to https://server successfully". If you are not connected to an existing server, you will see the following message, "No existing connection to any server." - -### Create Data Acceleration Schedules - -The following command is used to create a data acceleration schedule. - -`python accelerate_workbooks.py --create-schedule SCHEDULE_NAME INTERVAL_TYPE [INTERVAL] [START_TIME] [END_TIME]` - -In Tableau Server, creating schedules requires the Server Administrator role. For other commands the Server Administrator role or the Site Administrator role is sufficient. - -INTERVAL_TYPE can be one of the four options below: ---hourly-interval with INTERVAL in {0.25,0.5,1,2,4,6,8,12}, the unit is hour. ---daily-interval, INTERVAL is not needed ---weekly-interval with INTERVAL as a non-empty subset of: -{Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} ---monthly-interval, INTERVAL is the starting day in a month. - -[START_TIME] is optional. If no starting time is specified, the default time 00:00:00 is used. To specify the starting time, --start-hour and --start-minute can be used to specify the time. - -[END_TIME] is optional. If no end time is specified, the end of the day will be used. To specify the ending time, --end-hour and --end-minute can be used to specify the time. END_TIME option is only useful for hourly interval. - -The warning, "Warning: The recurrence interval of the given schedule is larger than Vizql server data refresh interval of 720 minutes." will be displayed if the users try to create a schedule that exceeds the configured VizQL server data refresh interval. By default, this is set to 12 hours (720 minutes). - -Example 1: Create a scheduled pre-computation every 4 hours. - -In this example, a pre-computation background task will be submitted every 4 hours throughout the day. - -`python accelerate_workbooks.py --create-schedule "My Schedule" --hourly-interval 4 --start-hour 0 --end-hour 23 --end-minute 45` - -After the acceleration schedule is created using the command line client, it can be viewed in the Tableau Server Schedules view. The scheduled task type will not currently be displayed. - -### Associate Workbooks to a Schedule - -You can associate a workbook to single or multiple data acceleration schedules. If your workbook has not been enabled for acceleration, the --add-schedule command will automatically enable the workbook. - -`python accelerate_workbooks.py --add-to-schedule [SCHEDULE_NAME] --workbook-path WORKBOOK_PATH` - -`python accelerate_workbooks.py --add-to-schedule [SCHEDULE_NAME] --path-list PATH_LIST` - -Example 1: Associate a workbook to a schedule - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" --workbook-path project/workbook1` - -```iecst -Workbooks added to schedule -Project/Workbook | Schedules -Default/my workbook1 | My Schedule -``` - -Example 2: Associate an acceleration schedule using a text file with a path list containing one or more workbooks. - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list path.txt` - -```iecst -Workbooks added to schedule -Project/Workbook Schedules -Default/my workbook1 My Schedule -Default/my workbook2 My Schedule -``` - -Example 3: Associate acceleration schedules with a workbook that is only extract data source based. - -Any workbook that uses only embedded extracts as its data source does not require an explicit acceleration schedule and thus it will only be enabled for acceleration without using an acceleration schedule. For these workbooks, the Tableau Server will automatically identify changes to the workbook content and data. Whenever the workbook is republished or its extract refreshes (manually or scheduled) a background task is submitted to pre-compute the data. - -In the example below, an attempt was made to add "My Schedule" to a workbook with only embedded extracts. The workbook is enabled for acceleration and it is not added to the "My Schedule" acceleration schedule. - -`python accelerate_workbooks.py --add-to-schedule "My schedule" Default/WorkbookwithOnlyExtracts` - -```iecst -Workbooks added to schedule: None -Warning: Unable to add workbook "Default/WorkbookwithOnlyExtracts" to schedule due to Workbook with id 10000 uses only embedded extract(s) and does not need explicit scheduling for acceleration. It was enabled for acceleration but not attached to the given schedule. -``` - -`python accelerate_workbooks.py --show-schedule` - -```iecst -Workbooks added to schedule -Project/Workbook Schedules -Default/my workbook1 My Schedule -Default/my workbook2 My Schedule -``` - -For workbooks that are not supported you will see the following warnings: - -Workbooks with encrypted embedded extracts: -`Unable to enable Default/Sales. Workbook 'Sales' is not supported for data acceleration because it only uses encrypted embedded extracts as data sources.` - -Workbooks where credentials are not embedded: -`Unable to enable Default/Finance. Workbook 'Finance' is not supported for data acceleration because it uses data sources without embedding credentials.` - -The following warning will be displayed if the users try to create a schedule that exceeds the configured VizQL server data refresh interval. By default, this is set to 12 hours (720 minutes). -`Warning: The recurrence interval of the given schedule is larger than Vizql server data refresh interval of 720 minutes.` - -### Enable Workbooks - -Enabling a workbook will opt in the workbook for acceleration. data acceleration will monitor the relevant Tableau events that could potentially change the data of the workbooks such as workbook publishing, extract refreshing (if the workbook has any) and web authoring. Pre-computation will be triggered after these events. However, the data source changes which are not managed by Tableau will not be monitored and the acceleration schedule is used for keeping the pre-computed data up to date in those scenarios. - -To enable one workbook: - -`python accelerate_workbooks.py --enable [--workbook-path] WORKBOOK_PATH` - -To enable one or more workbooks in batches, you can provide a file specifying a list of workbooks. - -`python accelerate_workbooks.py --enable [--path-list] PATH_LIST` - -Example 1: Enable a single workbook - -`python accelerate_workbooks.py --enable Default/Workbook1` - -Example 2: Enable multiple workbooks - -Create a path file for example `paths.txt` using the format below project/workbook: -Default/Workbook1 -Default/Workbook2 -The following command will enable the workbooks defined in the paths.txt file. - -`python accelerate_workbooks.py --enable --path-list paths.txt` - -```iecst -Workbooks enabled -Project/Workbook -Default/my workbook1 -Default/my workbook2 -``` - -For workbooks that are not currently supported, you will see the following warnings: - -Workbooks with encrypted embedded extracts: -`Unable to enable Default/Sales. Workbook 'Sales' is not supported for data acceleration because it only uses encrypted embedded extracts as data sources.` - -Workbooks where credentials are not embedded: -`Unable to enable Default/Finance. Workbook 'Finance' is not supported for data acceleration because it uses data sources without embedding credentials.` - -### Detach a Workbook from a Schedule - -Use the --remove-from-schedule command to detach a workbook from a schedule. - -`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME [--workbook-path] WORKBOOK_PATH` - -`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME [---path-list] PATH_LIST` - -`python accelerate_workbooks.py --remove-from-schedule SCHEDULE_NAME project/workbook` - -Example 1: Removing multiple workbooks from a schedule using --path-list. -In the example below "workbook1" and "workbook2" was detached from the acceleration schedule "My Schedule". Any workbooks included in the path list are not associated with "My Schedule". - -`python accelerate_workbooks.py --remove-from-schedule "My Schedule" --path-list "paths.txt"` - -```iecst -Workbooks removed from schedule -Project/Workbook Schedules -Default/workbook1 My Schedule -Default/workbook2 My Schedule - -Workbooks not on schedule "My Schedule" -Project/Workbook -Default/extractworkbook -``` - -Example 2: Remove a workbook from a schedule - -`python accelerate_workbooks.py --remove-from-schedule "My Schedule" Default/workbook1` - -```iecst -Workbooks removed to schedule -Project/Workbook Removed From Schedule -Default/my workbook1 My Schedule -``` - -Example 3: - -`python accelerate_workbooks.py --remove-from-schedule "My Schedule" --workbook-path Default/workbook1` - -```iecst -Workbooks removed from schedule -Project/Workbook Schedules -Default/workbook1 My Schedule -``` - -### Accelerate On-Demand - -You can use --enable combined with --acceleration-now to submit a backgrounder pre-computation job on demand. This can be useful to trigger a pre-computation ahead of the next scheduled run. - -`python accelerate_workbooks.py --enable --accelerate-now --path-list PATH_LIST` - -`python accelerate_workbooks.py --enable WORKBOOK_PATH --accelerate-now` - -Example 1: - -`python accelerate_workbooks.py --enable Default/workbook1 --accelerate-now` - -### Disable Workbooks - -Disabling a workbook stops accelerating the workbook. It detaches the workbook from the workbook's associated schedules and cleans up all of the acceleration artifacts related to the workbook. It will not remove entries from the Tableau query cache. - -`python accelerate_workbooks.py --disable [--workbook-path] WORKBOOK_PATH` - -`python accelerate_workbooks.py --disable --path-list PATH_LIST` - -`python accelerate_workbooks.py --disable --workbook-path Default/workbook1` - -```iecst -Workbooks Disabled -Project/Workbook -Default/workbook1 -``` - -### Enable or Disable a Site for Data Acceleration - -The following commands are used to enable or disable a site for acceleration. - -`python accelerate_workbooks.py --enable --site SITE_NAME --type site` - -`python accelerate_workbooks.py --disable --site SITE_NAME --type site` - -Workbooks can only be enabled for acceleration if their site is enabled. Enabling a site will not enable any workbooks automatically. All sites are enabled for acceleration by default. Enabling a site is only needed when a site is explicitly disabled, or a site is imported from another Tableau Server. - -Disabling a site for acceleration will disable all workbooks that were currently enabled for acceleration. Once a site is disabled, no workbooks can be enabled on this site until this site is enabled again. All workbooks under that site will be disabled and detached from any accelerated schedules they are associated with. - -In Tableau Server, to enable or disable acceleration requires the user to be signed in with an account with the Server Administrator role. - -Example 1: Disable the Default site for acceleration - -`python accelerate_workbooks.py --disable --site SITE_NAME --type site` - -Example 2: Enable the Default site for acceleration - -`python accelerate_workbooks.py --enable --site SITE_NAME --type site` - -### Display Acceleration Schedules - -The --show-schedules command displays the schedule information for enabled workbooks associated with their accelerated schedules. The schedule information includes the schedule name associated with the workbooks and their next run time. - -`python accelerate_workbooks.py --show-schedules` - -`python accelerate_workbooks.py --show-schedules SCHEDULE_NAME [--workbook-path] [WORKBOOK_PATH]` - -`python accelerate_workbooks.py --show-schedules SCHEDULE_NAME [---path-list] [PATH_LIST]` - -Note: If --workbook-path or –path-list are omitted, the command will show all the enabled workbooks with their schedule information. - -Example 1: When there are no data acceleration schedules associated with enabled workbooks - -`python accelerate_workbooks.py --show-schedules` - -Scheduled Tasks for Data Acceleration: None - -Example 2: When there are enabled workbooks with data acceleration schedules - -```iecst -Scheduled Tasks for Data Acceleration - -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 -``` - -### Show Acceleration Status - -The --status command shows the list of workbooks enabled for acceleration and their associated schedules. When a workbook is enabled but not associated with any schedule, an asterisk '*' will be shown in the Schedule column. In that case, the pre-computed data for workbooks will be updated when the workbooks are re-published, or their extracts (if they have any) get refreshed. Workbooks that only contain embedded extracts will not be associated with schedules. - -`python accelerate_workbooks.py --status` - -Example 1: Display the status of all enabled and scheduled accelerated workbooks. - -`python accelerate_workbooks.py --status` - -```iecst -Data Acceleration is enabled for the following workbooks -Site Project/Workbook -Default Default/extractworkbook -Default Default/liveworkbook -Default Default/liveandextractworkbook - -Scheduled Tasks for Data Acceleration -Project/Workbook Schedule Next Run -Default/extractworkbook * -Default/liveworkbook My Schedule 2020-01-22 16:00:00-08:00 -Default/liveandextractworkbook My Schedule 2020-01-22 16:00:00-08:00 - -*The Data Acceleration views for these workbooks will be updated when they are published, or when their extract is refreshed. -``` - -### Specify workbook paths - -This section describes how to specify the workbook path argument and the path list argument in the commands --add-to-schedule, --enable, --remove-from-schedule. - ---workbook-path -[WORKBOOK_PATH] is the path concatenating the project path and the workbook name by "/" where the project path is the path of the project directly containing the workbook to the root project. The path is in the form of "Project Name/Workbook Name". If a workbook is in a nested project, its path may be like "Project 1/Project 2/Workbook Name". Workbook paths are case sensitive. - -Double quotes are required for specifying the workbook path if it contains whitespace. - -`python accelerate_workbooks.py --enable [--workbook-path] PATH_LIST` - -Example 1: Specifying --workbook-path - -`python accelerate_workbooks.py --enable --workbook-path "project/workbook with spaces"` - -Example 2: --workbook-path is optional - -`python accelerate_workbooks.py --enable project/workbook` - -Example 3: --workbook-path is optional - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" project/workbook` - ---path-list -PATH_LIST is a text file where each line is a workbook path. In the PATH_LIST, there is no need to use double quotes for workbook paths that contain whitespace. - -Here is an example paths text file: -projectLevel1/projectLevel2/workbook1 -project1/workbook2 - -Example 1: Enable multiple workbooks - -`python accelerate_workbooks.py --enable --path-list paths.txt` - -Example 2: Add multiple workbooks to a schedule. - -`python accelerate_workbooks.py --add-to-schedule "My Schedule" --path-list paths.txt` - -Example 3: Remove multiple workbooks from a schedule. - -`python accelerate_workbooks.py –-remove-from-schedule "My Schedule" --path-list paths.txt` From 56512127715ba2d6c6cd06427081cc65d456a696 Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Mon, 27 Apr 2020 10:26:23 -0700 Subject: [PATCH 050/158] [DOC] Fix connection usage in docs Fixing errors in the sample code for using datasource/workbook connections. The populate_connections method for workbook/datasource is implemented using the fetcher pattern, so it is best practice to save the connection items in a separate variable. --- docs/api-ref.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index e7488eb5a..ebb3d97c5 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -491,9 +491,10 @@ None. A list of `ConnectionItem` objects are added to the data source (`datasour server.datasources.populate_connections(datasource) # print the information about the first connection item - print(datasource.connections[0].connection_type) - print(datasource.connections[0].id) - print(datasource.connections[0].server_address) + connection = datasource.connections[0] + print(connection.connection_type) + print(connection.id) + print(connection.server_address) ... @@ -4026,12 +4027,16 @@ None. The connection information is updated with the information in the `Connect ```py +# query for workbook connections +server.workbooks.populate_connections(workbook) + # update connection item user name and password -workbook.connections[0].username = 'USERNAME' -workbook.connections[0].password = 'PASSWORD' +connection = workbook.connections[0] +connection.username = 'USERNAME' +connection.password = 'PASSWORD' # call the update method -server.workbooks.update_conn(workbook, workbook.connections[0]) +server.workbooks.update_conn(workbook, connection) ```
    From 95f0dacf59b5717c8b825a4354f58ff708b81daf Mon Sep 17 00:00:00 2001 From: Jac Date: Tue, 28 Apr 2020 10:34:00 -0700 Subject: [PATCH 051/158] Remove statement that you can use python 2.x (#605) * Remove statement that you can use python 2.x * Update index.md --- docs/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 43c8508b4..aec722ade 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,8 +19,7 @@ This section describes how to: Before you install TSC, confirm that you have the following dependencies installed: -* Python. You can use TSC with Python 2.7.9 or later and with Python 3.3 or later. These versions include pip, which is - the recommended means of installing TSC. +* Python. You can use TSC with Python 3.5 or later. * Git. Optional, but recommended to download the samples or install from the source code. From 9906ba62e2fd5754a393d97add73bb9eaf00972f Mon Sep 17 00:00:00 2001 From: Jac Date: Tue, 28 Apr 2020 10:34:40 -0700 Subject: [PATCH 052/158] Add Personal Access Token to the Auth page (#604) * Add Personal Access Token to the Auth page * fix code! --- docs/sign-in-out.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/sign-in-out.md b/docs/sign-in-out.md index ce8e7e960..a664a2cf4 100644 --- a/docs/sign-in-out.md +++ b/docs/sign-in-out.md @@ -9,6 +9,8 @@ To sign in and out of Tableau Server, call the server's `.auth.signin` method in import tableauserverclient as TSC tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD', `SITENAME`) +# or for a personal access token +# tableau_auth = TSC.PersonalAccessTokenAuth('TOKEN_NAME', 'TOKEN_VALUE', 'SITENAME') server = TSC.Server('https://SERVER_URL') with server.auth.sign_in(tableau_auth): @@ -19,6 +21,8 @@ with server.auth.sign_in(tableau_auth): `SITENAME` is the subpath of your full site URL (also called `contentURL` in the REST API). `MYSITE` would be the site name of `https://10ax.online.tableau.com/MYSITE`. This parameter can be omitted when signing in to the Default site of an in premise Tableau server. +'TOKEN_NAME' and 'TOKEN_VALUE' are your Personal Access Token values, generated in your Account Settings. + Optionally, you can override the version of Tableau API you are authorizing against by adding `server.version = ''` before the `auth.signin` call. The TSC library signs you out of Tableau Server when you exit out of the `with` block. @@ -33,7 +37,7 @@ An alternative to using a `with` block is to call the `Auth.sign_in` and `Auth.s ```py import tableauserverclient as TSC -tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') +tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD') # with no site name, this will try to log the user into the Default site server = TSC.Server('http://SERVER_URL') server.auth.sign_in(tableau_auth) From 5223ce1c4fee38833d0f376121f3d4dcd526fc1e Mon Sep 17 00:00:00 2001 From: dzucker-tab <49076749+dzucker-tab@users.noreply.github.com> Date: Thu, 30 Apr 2020 15:30:01 -0700 Subject: [PATCH 053/158] Add 2020.1 to API to release version mapping table --- docs/versions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/versions.md b/docs/versions.md index 5589985d0..aeab32836 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -68,3 +68,4 @@ The current version of TSC only supports the following REST API and Tableau Serv |3.4|2019.2| |3.5|2019.3| |3.6|2019.4| +|3.7|2020.1| From 3a6272d8808c895c0b3238ab73c928d2cf6ec91e Mon Sep 17 00:00:00 2001 From: mbren Date: Wed, 6 May 2020 15:31:27 -0400 Subject: [PATCH 054/158] add note that hourly interval schedules must start at top of hour --- docs/api-ref.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index ebb3d97c5..b571905fc 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -1729,7 +1729,7 @@ This class sets the frequency and start time of the scheduled item. This class c Name | Description :--- | :--- -`HourlyInterval` | Runs scheduled item hourly. To set the hourly interval, you create an instance of the `HourlyInterval` class and assign the following values: `start_time`, `end_time`, and `interval_value`. To set the `start_time` and `end_time`, assign the time value using this syntax: `start_time=time(`*hour*`,` *minute*`)` and `end_time=time(`*hour*`,` *minute*`)`. The *hour* is specified in 24 hour time. The `interval_value` specifies how often the to run the task within the start and end time. The options are expressed in hours. For example, `interval_value=.25` is every 15 minutes. The values are `.25`, `.5`, `1`, `2`, `4`, `6`, `8`, `12`. +`HourlyInterval` | Runs scheduled item hourly. To set the hourly interval, you create an instance of the `HourlyInterval` class and assign the following values: `start_time`, `end_time`, and `interval_value`. To set the `start_time` and `end_time`, assign the time value using this syntax: `start_time=time(`*hour*`,` *minute*`)` and `end_time=time(`*hour*`,` *minute*`)`. The *hour* is specified in 24 hour time. The `interval_value` specifies how often the to run the task within the start and end time. The options are expressed in hours. For example, `interval_value=.25` is every 15 minutes. The values are `.25`, `.5`, `1`, `2`, `4`, `6`, `8`, `12`. Hourly schedules that run more frequently than every 60 minutes must have start and end times that are on the hour. `DailyInterval` | Runs the scheduled item daily. To set the daily interval, you create an instance of the `DailyInterval` and assign the `start_time`. The start time uses the syntax `start_time=time(`*hour*`,` *minute*`)`. `WeeklyInterval` | Runs the scheduled item once a week. To set the weekly interval, you create an instance of the `WeeklyInterval` and assign the start time and multiple instances for the `interval_value` (days of week and start time). The start time uses the syntax `time(`*hour*`,` *minute*`)`. The `interval_value` is the day of the week, expressed as a `IntervalItem`. For example `TSC.IntervalItem.Day.Monday` for Monday. `MonthlyInterval` | Runs the scheduled item once a month. To set the monthly interval, you create an instance of the `MonthlyInterval` and assign the start time and day. The From d63d9824da90ddbb48575f95cab097c4ba81e0e1 Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Tue, 19 May 2020 10:37:46 -0700 Subject: [PATCH 055/158] Adding legal and privacy links to footer Doc update: - For GDPR compliance, adding links to legal and privacy pages - Updating styles and formatting to match other Tableau assets --- _includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/footer.html b/_includes/footer.html index 35ea121c7..b73489dc7 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -3,7 +3,7 @@

    This site is open source. Suggestions and pull requests are welcome on our GitHub page.

    -

    © Copyright Tableau

    +

    LEGAL PRIVACY © 2003– TABLEAU SOFTWARE LLC. ALL RIGHTS RESERVED

    Documentation last generated on: {{ site.time }}
    From 116df2a827824a4180e0a6f066e86ac7b001b29f Mon Sep 17 00:00:00 2001 From: Dave Hagen Date: Tue, 19 May 2020 10:39:22 -0700 Subject: [PATCH 056/158] Update main.css --- css/main.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/css/main.css b/css/main.css index 05fd446ec..f9a61e939 100644 --- a/css/main.css +++ b/css/main.css @@ -273,4 +273,8 @@ html { .size-1of2 { width: 50%; } .size-1of3 { width: 33.333%; } - +/* Legal and Privacy Links */ +.aLegal { + word-spacing: 8px; + padding-right: 8px; +} From 585a6220768ce133ccc344d252225410af38f5a1 Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Mon, 29 Jun 2020 15:38:28 -0700 Subject: [PATCH 057/158] Update docs with maxage info (#640) * Update docs with maxage info Docs for #635 and #639 * Addresses feedback for request options part of docs * Addresses remaining feedback to view and workbook methods --- docs/api-ref.md | 84 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index b571905fc..51e4b4e26 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -1595,9 +1595,15 @@ Name | Description ### CSVRequestOptions class ```py -CSVRequestOptions() +CSVRequestOptions(maxage=-1) ``` -Use this class to specify view filters to be applied when the CSV data is generated. See `views.populate_csv`. +Use this class to specify view filters to be applied when the CSV data is generated. Optionally, you can specify the maximum age of the CSV data cached on the server by providing a `maxage` value. See `views.populate_csv`. + +**Attributes** + +Name | Description +:--- | :--- +`maxage` | Optional. The maximum number of minutes the CSV data will be cached on the server before being refreshed. The value must be an integer between `1` and `240` minutes. `0` will be interpreted as 1 minute on server, as that is the shortest interval allowed. By default, `maxage` is set to `-1`, indicating the default behavior configured in server settings. **Example** @@ -1607,7 +1613,7 @@ Use this class to specify view filters to be applied when the CSV data is genera # sign in, get a specific view, etc. # set view filters -csv_req_option = TSC.CSVRequestOptions() +csv_req_option = TSC.CSVRequestOptions(maxage=5) csv_req_option.vf('Region', 'South') csv_req_option.vf('Category', 'Furniture') @@ -1618,15 +1624,16 @@ server.views.populate_csv(view_item, csv_req_option) ### ImageRequestOptions class ```py -ImageRequestOptions(imageresolution=None) +ImageRequestOptions(imageresolution=None, maxage=-1) ``` -Use this class to specify the resolution of the view returned as an image. You can also use this class to specify view filters to be applied when the image is generated. See `views.populate_image`. +Use this class to specify the resolution of the view and, optionally, the maximum age of the image cached on the server. You can also use this class to specify view filters to be applied when the image is generated. See `views.populate_image`. **Attributes** Name | Description :--- | :--- `imageresolution` | The resolution of the view returned as an image. You set this option with the `Resolution` class. If unspecified, the `views.populate_image` method returns an image with standard resolution (the width of the returned image is 784 pixels). If you set this parameter value to high (`Resolution.High`), the width of the returned image is 1568 pixels. For both resolutions, the height varies to preserve the aspect ratio of the view. +`maxage` | Optional. The maximum number of minutes the image will be cached on the server before being refreshed. The value must be an integer between `1` and `240` minutes. `0` will be interpreted as 1 minute on server, as that is the shortest interval allowed. By default, `maxage` is set to `-1`, indicating the default behavior configured in server settings. **View Filters** @@ -1640,7 +1647,7 @@ You can use the `vf('filter_name', 'filter_value')` method to add view filters. # sign in, get a specific view, etc. # set the image request option -image_req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High) +image_req_option = TSC.ImageRequestOptions(imageresolution=TSC.ImageRequestOptions.Resolution.High, maxage=1) # (optional) set a view filter image_req_option.vf('Category', 'Furniture') @@ -1653,9 +1660,9 @@ server.views.populate_image(view_item, image_req_option) ### PDFRequestOptions class ```py -PDFRequestOptions(page_type=None, orientation=None) +PDFRequestOptions(page_type=None, orientation=None, maxage=-1) ``` -Use this class to specify the format of the PDF that is returned for the view. See `views.populate_pdf`. +Use this class to specify the format of the PDF that is returned for the view. Optionally, you can specify the maximum age of the rendered PDF that is cached on the server by providing a `maxage` value. See `views.populate_pdf`. **Attributes** @@ -1663,6 +1670,7 @@ Name | Description :--- | :--- `page_type` | The type of page returned in PDF format for the view. The page_type is set using the `PageType` class:
    `PageType.A3`
    `PageType.A4`
    `PageType.A5`
    `PageType.B5`
    `PageType.Executive`
    `PageType.Folio`
    `PageType.Ledger`
    `PageType.Legal`
    `PageType.Letter`
    `PageType.Note`
    `PageType.Quarto`
    `PageType.Tabloid` `orientation` | The orientation of the page. The options are portrait and landscape. The options are set using the `Orientation` class:
    `Orientation.Portrait`
    `Orientation.Landscape` +`maxage` | Optional. The maximum number of minutes the rendered PDF will be cached on the server before being refreshed. The value must be an integer between `1` and `240` minutes. `0` will be interpreted as 1 minute on server, as that is the shortest interval allowed. By default, `maxage` is set to `-1`, indicating the default behavior configured in server settings. **View Filters** You can use the `vf('filter_name', 'filter_value')` method to add view filters. When the PDF is generated, the specified filters will be applied to the view. @@ -1675,7 +1683,9 @@ You can use the `vf('filter_name', 'filter_value')` method to add view filters. # sign in, get a specific view, etc. # set the PDF request options -pdf_req_option = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A4, orientation=TSC.PDFRequestOptions.Orientation.Landscape) +pdf_req_option = TSC.PDFRequestOptions(page_type=TSC.PDFRequestOptions.PageType.A4, + orientation=TSC.PDFRequestOptions.Orientation.Landscape, + maxage=1) # (optional) set a view filter pdf_req_option.vf('Region', 'West') @@ -3259,7 +3269,7 @@ This endpoint is available with REST API version 2.5 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify a high resolution image. By default, the image will be in low resolution. You can also specify view filters to be applied when the image is generated. See [ImageRequestOptions class](#imagerequestoptions-class) for more details. +`req_options` | (Optional) You can pass in request options to specify the image resolution and the maximum age of the view image cached on the server. By default, the image will be in low resolution. The maximum image cache time is the value of `maxage` in minutes, and must be an integer between 1 and 240. A value of zero will cause the minimum cache time of 1 minute. A value of -1 will cache images for the time configured in server settings. You can also specify view filters to be applied when the image is generated. See [ImageRequestOptions class](#imagerequestoptions-class) for more details. **Exceptions** @@ -3306,7 +3316,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify view filters to be applied when the CSV data is generated. See [CSVRequestOptions class](#csvrequestoptions-class) for more details. +`req_options` | (Optional) You can pass in request options to specify the maximum age of the CSV cached on the server. The maximum CSV cache time is the value of `maxage` in minutes, and must be an integer between 1 and 240. A value of zero will cause the minimum cache time of 1 minute. A value of -1 will cache CSV files for the time configured in server settings. You can also specify view filters to be applied when the data is generated. See [CSVRequestOptions class](#csvrequestoptions-class) for more details. **Exceptions** @@ -3341,7 +3351,7 @@ views.populate_pdf(view_item, req_options=None) Populates the PDF content of the specified view. -This method uses the `id` field to query the PDF content, and populates the content as the `pdf` field. +This method populates a PDF with image(s) of the view you specify. REST API: [Query View PDF](https://onlinehelp.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#query_view_pdf){:target="_blank"} @@ -3354,7 +3364,7 @@ This endpoint is available with REST API version 2.7 and up. Name | description :--- | :--- `view_item` | Specifies the view to populate. -`req_options` | (Optional) You can pass in a request object to specify the page type and orientation of the PDF content. If not specified, PDF content will have default page type and orientation. You can also specify view filters to be applied when the PDF is generated. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. +`req_options` | (Optional) You can pass in request options to specify the page type and orientation of the PDF content, as well as the maximum age of the PDF rendered on the server. If not specified, PDF content will have default page type and orientation. The maximum PDF cache time is the value of `maxage` in minutes, and must be an integer between 1 and 240. A value of zero will cause the minimum cache time of 1 minute. A value of -1 will cache PDF files for the time configured in server settings. You can also specify view filters to be applied when the PDF is generated. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. **Exceptions** @@ -3995,6 +4005,9 @@ None. The preview image is added to the view. ``` +
    +
    + #### workbooks.update_connection ```py @@ -4042,4 +4055,49 @@ server.workbooks.update_conn(workbook, connection)

    +#### workbooks.populate_pdf +``` +workbooks.populate_pdf(workbook_item, req_options=None) +``` + +Populates the PDF content of the specified workbook. + +This method populates a PDF with image(s) of the workbook view(s) you specify. + +REST API: [Download Workbook PDF](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooksviews.htm#download_workbook_pdf){:target="_blank"} + +**Version** + +This endpoint is available with REST API version 3.4 and up. + +**Parameters** + +Name | description +:--- | :--- +`workbook_item` | Specifies the workbook to populate. +`req_options` | (Optional) You can pass in request options to specify the page type and orientation of the PDF content, as well as the maximum age of the PDF rendered on the server. If not specified, PDF content will have default page type and orientation. The maximum PDF cache time is the value of `maxage` in minutes, and must be an integer between 1 and 240. A value of zero will cause the minimum cache time of 1 minute. A value of -1 will cache PDF files for the time configured in server settings. See [PDFRequestOptions class](#pdfrequestoptions-class) for more details. + +**Exceptions** + +Error | Description +:--- | :--- +`Workbook item missing ID` | Raises an error if the ID of the workbook is missing. + +**Returns** + +None. The PDF content is added to the `workbook_item` and can be accessed by its `pdf` field. + +**Example** +```py +# Sign in, get view, etc. + +# Populate and save the workbook pdf as 'workbook_pdf.pdf' +server.workbooks.populate_pdf(workbook_item) +with open('./workbook_pdf.pdf', 'wb') as f: + f.write(workbook_item.pdf) +``` + +
    +
    + From c93464893b8ae91b110ad9688869ebcec5767167 Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Tue, 21 Jul 2020 10:02:11 -0700 Subject: [PATCH 058/158] Update download file in docs to latest (v0.12) Download link in docs was pointing to v0.7; latest is v0.12 --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index eeceabaf4..9ab8dbb70 100644 --- a/index.md +++ b/index.md @@ -8,6 +8,6 @@ indexed_by_search: false

    The Tableau Server Client is a Python library for the Tableau Server REST API.


    Get Started   - Download + Download From b90818a35251c1148f2ba2c8ee96926baebc081a Mon Sep 17 00:00:00 2001 From: Chris Shin Date: Wed, 22 Jul 2020 15:53:01 -0700 Subject: [PATCH 059/158] Update download link to always point to latest --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 9ab8dbb70..c19b7f087 100644 --- a/index.md +++ b/index.md @@ -8,6 +8,6 @@ indexed_by_search: false

    The Tableau Server Client is a Python library for the Tableau Server REST API.


    Get Started   - Download + Download From b6a454678b00b4c94a8fab87edd7af707e5e6542 Mon Sep 17 00:00:00 2001 From: Brian Cantoni Date: Wed, 5 Aug 2020 17:47:54 -0700 Subject: [PATCH 060/158] Doc pages cleanup and minor editing - minor content edits - update Tableau doc links - update dev community forum links - add missing samples to samples.md list --- .gitignore | 6 +- _includes/docs_menu.html | 4 +- _includes/header.html | 2 +- docs/api-ref-x.md | 4103 ++++++++++++++++++++++++++++ docs/api-ref.md | 136 +- docs/api-ref.md.orig | 4103 ++++++++++++++++++++++++++++ docs/api-ref.md.rej | 68 + docs/dev-guide.md | 14 +- docs/filter-sort.md | 8 +- docs/index.md | 3 +- docs/page-through-results.md | 8 +- docs/patch | 612 +++++ docs/populate-connections-views.md | 2 +- docs/samples.md | 59 +- docs/sign-in-out.md | 16 +- docs/versions.md | 31 +- 16 files changed, 9021 insertions(+), 154 deletions(-) create mode 100644 docs/api-ref-x.md create mode 100644 docs/api-ref.md.orig create mode 100644 docs/api-ref.md.rej create mode 100644 docs/patch diff --git a/.gitignore b/.gitignore index d7496406b..e7dc31618 100644 --- a/.gitignore +++ b/.gitignore @@ -144,6 +144,6 @@ $RECYCLE.BIN/ *.lnk # Documentation -docs/_site/ -docs/.jekyll-metadata -docs/Gemfile.lock +_site/ +.jekyll-metadata +Gemfile.lock diff --git a/_includes/docs_menu.html b/_includes/docs_menu.html index 2f5ab1b04..5693ee67e 100644 --- a/_includes/docs_menu.html +++ b/_includes/docs_menu.html @@ -11,7 +11,7 @@ Versions
  • - Page through Results + Page Through Results
  • Populate Connections and Views @@ -53,7 +53,7 @@ Requests
  • - Schedules + Schedules
  • Server diff --git a/_includes/header.html b/_includes/header.html index a42240f87..b8ad08f65 100644 --- a/_includes/header.html +++ b/_includes/header.html @@ -15,7 +15,7 @@