Skip to content

Instantly share code, notes, and snippets.

@tfoldi
Created March 20, 2015 22:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfoldi/6ba63db4cc129a1b31e4 to your computer and use it in GitHub Desktop.
Save tfoldi/6ba63db4cc129a1b31e4 to your computer and use it in GitHub Desktop.
Tableau Server Rest API from Clojure - Example
(ns tabsync.tableau
(:require [clj-http.client :as client]
[clojure.zip :refer [xml-zip]]
[clojure.data.zip.xml :refer [xml-> xml1-> attr ]]
[clojure.data.xml :as xml])
)
(defn tableau-url-for
"Constructs server API url. Target can be hostname or session returned from logon-to-server"
[target api-path]
(if (= (type target) java.lang.String)
; connect to host
(str target "/api/2.0/" api-path )
; connect to already established session (target is a session)
(str (get target :host) "/api/2.0/sites/" (get target :siteid) "/" api-path)
)
)
(defn get-zip
"Get xml-zip from http.client response"
[http-response]
(-> (get http-response :body)
xml/parse-str
xml-zip
)
)
(defn http
"Perform a http call to tableau server. Host can be hostname or session"
[method host api-path http-params]
(get-zip
(
(resolve (symbol (str "client/" method)))
(tableau-url-for host api-path)
(merge http-params {:headers {"X-Tableau-Auth" (get host :token)}})
)
)
)
(defn logindata
"Creates XML request for logon call"
[name password]
(xml/emit-str
(xml/element :tsRequest {}
(xml/element :credentials {:name name
:password password}
(xml/element :site {:contentUrl ""})))) ; "" means Default site
)
(defn logon-to-server
"Logon to tableau server by invoking /auth/signin, returns map with token,
site id and hostname"
[host name password]
(let [ts-response (http "post" host "/auth/signin" {:multipart [{:name "title"
:content (logindata name password)}]})
]
{:token (xml1-> ts-response
:credentials (attr :token)
)
:siteid (xml1-> ts-response
:credentials
:site (attr :id))
:host host
}
)
)
(defn get-users
"Iterates on site users defined by session. Page size is 10"
[session]
(loop [page-number 1]
(let [ts-response (http "get" session "/users/"
{:query-params {:pageSize 10
:pageNumber page-number}})]
(println (str "On page " page-number " -> " ts-response))
(if (> (* 10 page-number) (read-string (xml1-> ts-response
:pagination
(attr :totalAvailable)
)))
(println "All users downloaded")
(recur (inc page-number ))
)
)
)
)
(defn signout
"Logoff from server"
[session]
(http "get" session "/auth/signout" {})
)
; Well, logon to server, get users and log off
(let [session (logon-to-server "http://server" "user" "pass")]
(get-users session )
(logoff signout)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment