Leveraging R & Python in Tableau with RStudio Connect | James Blair | RStudio
Leveraging R & Python in Tableau with RStudio Connect Overview Demo / Q&A with James Blair Tableau combines the ease of drag-and-drop visual analytics with an open, extensible platform. RStudio develops free and open tools for data science, including the world’s most popular IDE for R. RStudio also develops an enterprise-ready, modular data science platform to help data science teams using R and Python scale and share their work. Now, with new functionality in RStudio Connect, users can have the best of both worlds. Tableau users can call R and Python APIs from Tableau calculated fields, getting access to all the power and analytic depth of these open-source data science ecosystems in real-time. For Tableau users, this makes it easy to add dynamic, advanced analytic features from R and Python to a Tableau dashboard, such as scoring predictive models on Tableau data. They can leverage all the great work done by their organization’s data science team and even call both R and Python APIs from a single dashboard. Data science teams can continue to use the code-first development and deployment tools from RStudio that they know and love. Using these tools, they can build and share R APIs (using the plumber package) and Python APIs (using the FastAPI framework). Speaker Bio: James is a Solutions Engineer at RStudio, where he focuses on helping RStudio commercial customers successfully manage RStudio products. He is passionate about connecting R to other toolchains through tools like ODBC and APIs. He has a background in statistics and data science and finds any excuse he can to write R code. A few other helpful links: Tableau Integration Documentation: https://docs.rstudio.com/rsc/integration/tableau/ Tableau / RStudio Connect Blog Post: https://blog.rstudio.com/2021/10/12/rstudio-connect-2021-09-0-tableau-analytics-extensions/ Embedding Shiny Apps in Tableau using shinytableau blog: https://blog.rstudio.com/2021/10/21/embedding-shiny-apps-in-tableau-dashboards-using-shinytableau/ James' slides: https://github.com/blairj09-talks/rstudio-tableau-webinar
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Thanks, I'm really happy to be here and excited to share the work that we've been, we spent a lot of time on what we're going to be sharing today. So we're excited to have a chance to talk to you all about it and demonstrate some of what we've been doing. But like Rachel indicated, the idea here is going to be leveraging R and Python in Tableau using RStudio Connect.
So this will be kind of, you know, the contents of today will heavily feature RStudio Connect, which is a paid product. But there's also some open source offerings that exist based on the work that we've done. And we'll highlight those as well. And to kind of start off with, I want to, I want to say that I think, you know, when we look at RStudio, and when we look at the R language itself, and Python as well, I think a lot of, or at least one common theme that I see is this idea of being able to use the right tool for the job, right?
There's an ever increasing number of R packages and ever increasing number of Python packages that exist to make data analysis work more efficient, more straightforward, and things of that nature. And at RStudio, we've really embraced that. And we've extended that idea of using the right tool for the job to our professional tooling. So tools like RStudio Workbench offer additional environments beyond just RStudio for doing your work in that includes tools like VS Code and Jupyter Notebooks and JupyterLab. The reticulate package was created in an effort to make it again, allow flexibility in determining what what tools the best tool for the job that you do you happen to be working on.
Just to kind of highlight this, here's an example of some of the different, you know, packages and frameworks that we see in use today. On the R and Python side, and all of these that we have listed here on the screen are packages that have support inside of RStudio Connect as a publishing platform. So data scientists and analysts and developers today can build tooling in Shiny or plumber or Flask or FastAPI or Dash or Streamlit or TensorFlow or any of these different numbers of content types, share these types of content on RStudio Connect and allow business users to browse, investigate, explore, make use of whatever it is that's been developed and shared in that environment.
Now, we're going to continue this kind of theme of extending our tooling and our capabilities by bringing Tableau into this mixture as well, right? Again, following this theme of what what tool is the right tool for the job. And there are many use cases where Tableau makes a lot of sense when we're looking at creating dynamic data visualizations that can be easily shared throughout our organization and easily accessed from business users all the way up to high-level executives. This is something that we've heard a lot from our customers, this request for better Tableau integration or just questions that we receive are, you know, how do we use Tableau alongside RStudio? How does RStudio position itself alongside Tableau?
Questions like that. And this is something that we've, like I said, spent a lot of time thinking about and are excited to share the work that we've done here today. Now, here's kind of where we're going, right? Here's an example. We'll look at an example of this same dashboard again, kind of towards the end of our conversation today. But in this particular example here that we're looking at, we have this customer analysis that's looking at customer sales performance and comparing profit and sales and determining which customers are performing well and which customers maybe need a little bit of help.
But the really interesting thing about this particular setup here is the fact that there are these two different views here, these two scatter plots that are based on extensions that are built in R and Python and then hosted inside of RStudio Connect. So, on one side, we have an R extension that's doing some outlier detection. So, you'll notice that these points here are colored a little bit differently. The blue points are non-outliers, the orange points are outliers. And that outlier detection is happening in real time based on an extension built in R that's being hosted on RStudio Connect. And we're going to showcase what that process looks like as we go through our conversation today.
The other component here is this other extension that's built in Python. This extension is built on top of a machine learning model that takes some set of inputs about a given customer and their transactional history and then predicts their expected profit as an output. And so, on this left-hand scatter plot, what we're looking at is actual profit for a given transaction versus predicted profit. And that can allow us to do things like identify customers that are over or underperforming. And again, all of this is being driven in real time by extensions executing R and Python code, all hosted on RStudio Connect. And we're going to look at how we get there as we go through the conversation today.
Existing Tableau-R/Python integration approaches
So, before we go there, let's step back to the beginning a little bit and kind of look at what has led us to the point where we are today and the work that we've done to make these types of extensions possible. And so, to really kind of start at the beginning, there are two existing mechanisms for integrating Python and R code into a Tableau workbook. Tabpy is an open source Tableau package, or excuse me, open source Python package that is built and maintained and developed by Tableau themselves. And this basically exists to allow you to execute arbitrary Python code from a Tableau workbook, view the results response back into your Tableau environment. RServe is a very similar type of functionality where you open up an RServe server in some environment, and then you submit arbitrary code for execution into that environment.
And here's an example pull from Tableau's documentation on how these types of extensions might be invoked. So, we have this script function here, and then we, in this case, this is an extension using Tabpy. So, we define our entire Python process or entire Python script here in this string. We submit that to our interpreter that ingests the string, interprets and executes the code, returns the result, and then we pass in individual values or arrays of values from our Tableau workbook.
Now, there's a few challenges with this approach. I'm not going to enumerate everything, but one of them that immediately becomes apparent is the fact that if I'm a Tableau user, like, I have to know at least enough R or Python to be able to write my code into this particular extension or into this script function. So, that makes it a little bit challenging because I can't, like, I have to have some knowledge of these scripting languages to really use this, or I have to know somebody that has enough knowledge to give me some sort of copy and pasteable piece of code that I can then execute here.
And then beyond that, the development process of this code can be a little bit difficult, right? There's not really a good way for me to validate this code. There's not really a good way for me to debug this code if there are errors. I'm not really working inside of a development environment. Rather, I'm working inside of Tableau and passing in some sort of plain text string that is then going to be executed as code on the back end. A couple of other challenges that we've heard from customers about security with this type of model can be a little bit difficult to maintain the appropriate levels of enterprise security, particularly when it comes to RServe. And so, again, we've heard from customers that these types of integrations, being able to execute R code, being able to execute Python code in a secure, manageable way from Tableau Workbooks is something that we want.
The Tableau Analytics Extensions API
Now, moving forward, right? Again, we've started back at the beginning. Tableau released this Tableau Analytics Extensions API, I think it's now been a couple of years ago. And this is really kind of the building block for all the work that we're going to highlight today. This Analytics Extensions API is actually the kind of the foundational piece of the TabPy integration that they've done. And so, this same framework is what we've used to provide access to the extensions that we're going to highlight today.
The main thing I think to understand here is that this Extensions API is really just a contract that exists between Tableau and some external service, right? It doesn't matter what that service is. It doesn't matter what it's implemented in. It doesn't matter what language is it. It doesn't matter what it's doing, right? As long as it obeys the contract, it works. And the contract is that Tableau will make two different requests to two different endpoints. It's going to make a request to an info endpoint to understand information about the service that's running. And it's going to make a request to the evaluate endpoint that is expected to return some modified version of the input data, right? So, this evaluate request is the request that then returns back or that submits data from Tableau to the service. The service is expected to respond in a way that Tableau can understand and reinsert that data back into the workbook of the Tableau environment.
this Extensions API is really just a contract that exists between Tableau and some external service, right? It doesn't matter what that service is. It doesn't matter what it's implemented in. As long as it obeys the contract, it works.
There's a lot more detail and documentation on the Tableau Analytics Extensions GitHub site that walks through all the different components here. But I think it's useful to understand just for the context of our conversation here today, that this external service, again, can be whatever it needs to be, as long as it follows the guidelines set forth in this Tableau Analytics Extension.
Introducing plumber.tableau and fastapitableau
So, what do we do when we have, you know, some sort of repeatable behavior that we want to provide access to end users? You know, again, if we want to create an easy way for users to build extensions that obey this contract, what's the best way for us to do that? And the natural response as an R user and R developer is to put it in a package, right? Like, let's see if we can make some sort of a package or create some sort of reproducible behavior that will make it easy for people to build tools that meet this contract that Tableau is expecting us to meet. And so, that's exactly what we've done. We have a couple of different packages that we're going to highlight and introduce today. The first is a package called Plumber Tableau. This is an R package that is built on top of the Tableau, or excuse me, built on top of the plumber package. So, if you've ever used plumber before, plumber is an R package for building interactive web APIs using R. And this Plumber Tableau package simply extends plumber a little bit by adding a few additional tools that will allow us to easily make extensions for Tableau.
I'm going to go ahead and switch over into a development environment now and kind of showcase what this looks like and how we might go about building this up and highlight some of the features of what this package offers and how it works. Okay. So, here's, again, this is my development environment. We're inside of RStudio Workbench here. If I wanted to create a new, we're going to just use a really simple use case here. Let's say that I want to create some sort of a function that takes some input, some string input, and capitalizes it.
Okay. So, if I have, we'll call this CAPS. This is a function, and we want some string. And then, in R, this is a fairly straightforward task to do. We could just say we're going to call this toUpperStringInput, right? And really, we're just wrapping this toUpper function here. And if we run this, we end up with this CAPS function. If we say CAPS World, we end up with the capitalized version of that string, right? Again, very basic, very straightforward. We're not trying to do anything terribly complex here because the focus is less on what we're doing and more on how we turn this into an extension.
So, let's say now that we want to take this function that we just created and turn this into a Tableau extension that we can use from inside of a Tableau workbook. We can come in here, and we can say, let's first bring in a couple of packages. So, we need the plumber package. We also need the Plumber Tableau package in here, okay? And then, plumber is run. If you haven't seen plumber before, some of this might feel a little bit unfamiliar, but it hopefully should seem fairly straightforward.
plumber works off of special comments that identify different attributes of the API. So, here we can say the API title is example Tableau extension. All right, okay. And we could say that the API description is simple virtualization extension. Okay, there we have that. And then, for this particular endpoint, we need to define a couple of things. One is, let's give it a brief description. So, capitalize input. And then, we need to define how this particular function will be invoked. So, we're going to respond to post requests at capitalize.
So, this here, again, this is all, we haven't done anything unique to Tableau yet. This is all just standard plumber definitions. But here, we're identifying that this is going to respond to post requests at this capitalize path. And then, there are a few new kind of special comments that we've introduced with the Plumber Tableau package. The first is Tableau r. And this allows us to define arguments that we expect Tableau to submit. And in this case, that Tableau argument is this string input value that we have here. So, here we can say, we're going to call this string input. We expect this to be a character value. And then, these are the strings. And then, we also have Tableau return. We're going to return a character value. And this character value is a capitalize. Let's call this capitalize.
Okay. So, here's the, so far, all we've done is created this endpoint here that allows us to submit data and return and receive back the capitalized input. And if we run this right now, let's save it. So, let's save this as Plumber r. Okay. So, if we run this API inside of RStudio, we end up with this nice little, you know, user interface over here on the right-hand side. We can see our little capitalized endpoint here. We can come in and we can try it out. We can say the string input is hello world. We can go ahead and execute this. And we should see this output that is the capitalized version of that input. Right? Everything's good.
Now, there's one critical piece that we're missing in order for this to be a valid extension for Tableau. And that is, we need to do one more thing here. And this is highlighted in all the documentation for the package. But we can use this little plumber annotation. And then we add Tableau extension. Okay. So, this Tableau extension function modifies our existing API so that it meets the contract that Tableau has established. Right? We need to be able to respond to requests in a certain way. And we need to be able to accept certain types of requests. This function here is what allows this package to handle all that for you. The goal of this package has been to make it as easy as possible for our developers to build these Tableau extensions without needing to worry about how Tableau is actually formatting its requests and how it's actually expecting response. All we need to do is write our code and then let the package take care of the rest.
And if we run this API again, we'll see that things have changed a little bit in our user interface. We have some links that have appeared up here that give us access to additional pieces of documentation. And if we open up our endpoint here, it's actually changed quite a bit because now we are using an example request that matches the type of request that Tableau would send. So, Tableau sends requests that are JSON objects that contain two different fields or two different values, script and data. And here we formatted an example request that will mimic what Tableau actually said. So, in here, if we wanted to test this out again, we could come in and add hello world into our data values. We could try this out. Let me find my execute button. There we go. Try this out. And again, we see back this hello world type response.
Okay. Now, we have done everything we need to to build a Tableau extension in R. And I want to highlight a couple of things. One, it was really a matter of writing an R function, adding a few comments, and loading the right libraries. The only really critical piece here that might be a little bit unfamiliar is the fact that we have this requirement that we use this Tableau extension modifier here. That just is, again, this is an instruction to plumber to say, look, take the existing API that we've already defined and modify it using this function. And this function comes from this Plumber Tableau package. But once we've done that, we have a running, capable, fully functioning Tableau extension.
Publishing to RStudio Connect
The only challenge now is that this extension isn't in a place that Tableau can reach out to, right? This extension is still living in my development environment. I need somewhere where this extension can be hosted. And that's where RStudio Connect comes in. So, if I take this extension that I've just built, we can come up here and we can say, let's publish this to RStudio Connect. We're going to publish our plumber API. I'm going to call this example. Let's call it example. All right. We'll go ahead and publish.
This is going to deploy this API to RStudio Connect. Because this is really just a plumber API at its core, there's not anything different or any sort of unique adjustment that I need to make in order for this to publish. We can see that it published relatively quickly. And if I come open up RStudio Connect and refresh here, we should see this example Tableau extension listed here at the top. Now, if we open this here, we'll notice immediately that things are a little bit different. One, we're not seeing if you've ever published a plumber API to RStudio Connect before, you're likely familiar with the fact that in most cases, what you see here is the same sort of interface that we saw inside of RStudio, this Swagger interface that we see over here. When we publish Tableau extensions to RStudio Connect, instead of that Swagger interface, what we get is we get this Tableau user guide. And the intention here is that this is now documentation for the Tableau developer so that they know how to use the extension that we just published.
All of this information here is information that, again, is specific to the Tableau developer to say, here's how you might use this particular extension. In fact, this extension here can be used by copying and pasting this line into a calculated field inside of a Tableau workbook. In fact, let's try this. Let's come into Tableau. We're going to create a new workbook in here. This will take just a minute. So this is Tableau Online. I'm going to create this new workbook. This extension we created, remember, just takes some input text and capitalizes it. So we're not doing anything really exciting or crazy. It doesn't really matter the data source that we select to connect to. So I'm just going to connect to this superstore data set that Tableau comes with automatically.
Let's save our workbook so that we can... I'll just call this example extension Tableau. Go ahead and hit save. Then the other thing that we need to do is we need to set up what type of analytics extension we want this workbook to use. I'm not going to go through the entire process of how you set this up for Tableau Online. We have detailed instructions on what needs to happen from the administrative level to make sure that RStudio Connect is set up appropriately to interact with Tableau. But from my workbook, I can come in here and say manage analytics extensions connections, choose the connection that I want, and then I'm ready to go.
So now I just need to create my extension. The first thing I'm going to do just to make things a little bit more interesting for us is I'm going to create this parameter. We'll call this text input. We'll expect this to be a string. Example value will be hello world. And then we'll go ahead and show this here. So over here on the right-hand side, now we have this little text input. Let me zoom in a little bit, maybe. So we have this text input that shows over here on the right-hand side. And now let's create some part of our workbook that references this extension. So we'll come in. We'll create a calculated field. We'll call this to upper. This can be named whatever. And then let's come back into RStudio Connect, and we can just grab this little script right here, drop it into our workbook.
Let me expand this a little bit. And then string input is the name of the parameter in our R function, if we remember correctly. But now we need to make an adjustment because now that we're in Tableau, this has some sort of a, oops, this has a different name now that we're in Tableau. So we're going to call this text, I think is what we called it. There we go. Go ahead and hit OK. Now we have this function to upper. Let's drag it into our worksheet. This is now going to submit a request to our extension being hosted on RStudio Connect. That request will include this hello world string and expect that request to come back as an uppercase version. We see in fact that it did. Now it's formatted a little bit funny because Tableau has by default selected that this value should be mapped to color. We're going to change this to label so that we'll get some text output here in our workbook. And now we see this to upper field contains the value hello world. And if we adjust this and say something like hi there instead, then we'll see that this field adjusts to say hi there.
Not anything crazy. We're just taking lowercase letters and making them capitalized. But the interesting thing here is the fact that we have real-time interaction happening between our Tableau environment and our RStudio Connect workbook. Now, one thing that I will highlight here that I think is kind of interesting is if we come back to RStudio Connect, we might want to, because we have two different components here. We have a Tableau environment that as the R developer we may or may not have control over or be involved in. We have the Tableau environment and then we also have this extension being hosted on Connect. And sometimes it can be difficult to diagnose if something goes wrong what is actually happening. How do we debug these types of extensions?
And one of the things that I think is really kind of interesting and unique to the Plumber Tableau package is that it has some built-in debug logging that we can actually choose to activate on the RStudio Connect side. So if I come in here, I can come into this variables panel here. I can set the debugme environment variable to contain the value Plumber Tableau. Go ahead and add this. Save this change. What this does is this inserts this new environment variable called debugme with the value of Plumber Tableau into RStudio Connect for this particular extension. And when I do that and I look at my logs here, I end up with, let's go back to our to our little workbook here. Let's send another request. Let's say good morning. It's morning where I am. I know we have folks from all over the world here. So it might be afternoon, it might be evening, it might be the middle of the night, but for me it's morning. So we'll say good morning here. And if I come back into RStudio Connect now, let's go ahead and refresh the page.
Okay. So if I look over here on the right-hand side, I can see this output that wasn't here before. I should have highlighted that this wasn't here before, but I see this Plumber Tableau, all these Plumber Tableau messages in the log output. And this is messaging that was enabled by us setting that environment variable inside of the environment variables panel here in RStudio Connect. So now what we've done is we've increased the amount of logging that we're getting out of this extension so that we can diagnose anything that might be going wrong. And all this information, so we get back information about what types of requests are being made. Here we have a post request being made to evaluate. Again, we talked earlier about how Tableau makes every request to evaluate. We've done some work in both the R package and RStudio Connect to intercept those requests and reroute them to the right location.
So we have this post request coming in. We can see that the body of the request is right here. It's this JSON object that includes good morning as this data value. And then we can see that we're rerouting this evaluate request to capitalize because that's what we actually requested in our extension. We can see that if we look at our... Let's come back in here. If we look at the definition of our to upper function inside of Tableau, we can see that we request the capitalize endpoint on this particular extension. So here's the extension name. We're requesting capitalize. That's how RStudio Connect and the R package know where to send this request when it's received. And then the argument that we're passing in again is this text input here.
One other thing that I'll highlight here, and then we're going to go back and look at some of the other tooling that exists here, is if we come back into our access settings here, we can actually adjust the URL for this. This feels really clunky, right? Content, a bunch of random numbers and letters, and then capitalize. So if instead we wanted something that was a little bit more straightforward, we could come in here and we could say, I'm going to call this James Tableau webinar. Go ahead and save that. Once we make this change, the documentation will reload and we see that our URL has adjusted, right? So now if we wanted to use this extension from Tableau, we could use this much more easy-to-understand script.
We could bring that back in. Let's fix that. All right. So now we have a much easier-to-read path to our extension here. Everything else remains the same. We can go ahead and apply this, and we'll see that the behavior remains consistent with what we saw before. We're submitting requests here. Let's just verify again, and we see hello world returned back over here.
The FastAPI Tableau Python package
Okay, excellent. So let's come back to our slides now. That's Plumber Tableau, right? Now, I mentioned there were two open source components to this. One is what we just looked at, which is Plumber Tableau. The other is this new Python package that we've created called FastAPI Tableau. Now, as the name would suggest, this is a Python package built as an extension to the FastAPI Python package that allows us to do the same exact thing that we've just done in R, but using Python, right? We can build these Tableau extensions using Python, using a Python framework that we're comfortable and familiar with, and we can submit those, and we can publish those extensions to RStudio Connect.
I'm not going to walk through that whole process again on the Python side, just because it very closely mirrors and mimics what we did on the R side, but I will pull open an example for us to look at. So let me just showcase what this would look like here. So here is, and all of these examples that we walk through are available in a GitHub repository, I'll share the link to that at the end of the talk here, so you'll have access to all the example code that we've explored. Let me find what I'm looking for. There we go. Okay, so if we look at this, all right, so here is a Python script that does the exact same thing that we did on the R side, takes some input text, capitalizes it, and returns the result. Again, not anything exciting in terms of functionality, but this does highlight how we would use this FastAPI Tableau package to build these kinds of extensions.
And what's really kind of cool about this is the fact that the only real difference between a Tableau extension built using FastAPI Tableau and a regular FastAPI router is that we import FastAPI Tableau instead of FastAPI, and we instantiate our app with FastAPI Tableau instead of FastAPI. These two changes are the only things that change between a traditional FastAPI router and one that can function as a Tableau analytics extension.
the only real difference between a Tableau extension built using FastAPI Tableau and a regular FastAPI router is that we import FastAPI Tableau instead of FastAPI, and we instantiate our app with FastAPI Tableau instead of FastAPI. These two changes are the only things that change between a traditional FastAPI router and one that can function as a Tableau analytics extension.
And again, if you're curious about the technical details and implementation of the package and what the package is actually doing behind the scenes, the GitHub documentation walks through some of that and can highlight the components there. But this extension here, this Python script, again, does the same thing. If we look at this on RStudio Connect, we've already published a version of this. Let me pull that open here. Let's come back to just content I own. Okay. So we have, here's our capitalized endpoint that we've created in Python. You'll notice when this pulls open that this documentation and interface looks different from what we saw on the R side. The goal is that those two differences, those two packages, Plumber Tableau and FastAPI Tableau, are going to converge as we continue to kind of iterate on them. It so happens that the way that we went through our development cycle, the R package was developed first, the Python package was developed second. We introduced some new things into the Python package that we're now working on porting back into the R package. And those changes will be made in the near future.
Comparing old and new approaches
So, here's a kind of a more comprehensive example. We'll take a look at this dashboard here in just a moment. But here's an example where, and this goes back to the Tableau workbook that we looked at kind of at the very beginning, where we are submitting information about a given customer and their transactions to a machine learning model that was built in Python, or generating predictions based on that input data, submitting those predictions back to Tableau, and then visualizing them in that Tableau environment. And here we see, again, the same pattern. We use this script function in our calculated fields, and then we define the path to the endpoint that we want to, or the path to the extension that we want to use, and then the values from our workbook that we want to pass into that extension.
So, let's contrast for a moment the two different approaches, right? We talked about how, in the beginning, we have tabpy, we have rserv as existing integration points for executing R and Python code within Tableau. The pattern for those extensions is what we're seeing here, right? I have some script function, and then the first argument to that script function is the full script that I want executed. In this case, it's the entire Python script that allows me to do this clustering of data points.
Just to reiterate some of the challenges of this particular approach, it requires that, as the Tableau user, I have the ability to, or I have the understanding and the knowledge, to write the script, or I have the ability to rely on somebody else that can write the script, and then I can copy and paste it in. I don't really have a great way of debugging this, right? I can submit the script. If it errors out, Tableau will tell me that an error occurred, but it doesn't give me a lot of additional information about where that error happened or what the cause of the error was, and it becomes a very kind of repetitive trial and error process to get something like this working. I also don't have any sort of syntax highlighting or any other developer help when it comes to writing and creating the script inside of Tableau.
The last thing, this is just, this is my own kind of, you know, again, personal perspective on this, is it's also a little bit nerve-wracking to me that this is just arbitrary code execution in some sort of remote environment. I don't know what I'm, I could put anything in this string, and my remote server is going to try to execute that. Hopefully, I'm not putting anything malicious here, but if I am, it's still going to try to execute it on the back end. This new approach that we're suggesting and that we've highlighted today is that instead of submitting arbitrary code for execution, we instead provide a path to a predefined extension that we would like to execute.
In this case, that extension, if we were going to take the same example where we're doing this cluster analysis of spatial data points, we could create that extension using something like FastAPI Tableau, we could host that extension on in an environment like RStudio Connect, and then we could simply refer to that by name. We're reaching out to this location in our extension environment, which is RStudio Connect, and we're passing these values in. And hopefully, we're able to kind of see the difference in these two approaches. Right here, even if I don't have any understanding of Python or R or FastAPI or plumber or any of these tools, I can still use this extension. If I'm really great at Tableau, but I never spend time in R, I can still make use of what my R developer has done if I want or Python developer has done, whatever the case is, because all I need to know is what the name of the extension is and then what values I want to I need to pass into it.
Advantages of the RStudio Connect approach
So, what are some of the advantages of this particular approach? Well, we've talked about some of them, but just to kind of revisit a few. One is, this is the only solution that exists today where you could use both R and Python extensions from the same exact Tableau workbook. Right? The other solutions, the existing solutions today, like RServe and TabPy work. We've seen customers utilize those, but you have to choose one or the other. You can't support RServe and TabPy execution from the same workbook or from the same Tableau worksheet. It has to be one or the other. With the extensions that are hosted on RStudio Connect, because you can host R and Python extensions in the same location, you can use R and Python extensions alongside one another inside the same Tableau workbook.
You also have the advantage of the enterprise-level security that RStudio Connect provides. Access control, you have a very, all processes on RStudio Connect are sandboxed. You're not allowing arbitrary code execution, but rather you have a predefined functionality within an extension. That extension gets invoked when it's called from Tableau, but Tableau users don't have the ability to pass arbitrary code into RStudio Connect. And then all of these extensions are behind the authentication layer that RStudio Connect implements. So, when we set up RStudio Connect to refer to these extensions, we do so by supplying an API key that is then used whenever these extensions are invoked.
This third point is one that I think is most significant, and that's the fact that R and Python developers can be separate from your Tableau developers, right? We could have a team of statisticians and data scientists that are building these kinds of extensions and providing them on RStudio Connect, and those developers can be entirely separate from the business analysts that are using Tableau or the Tableau developers that are building the workbooks. I don't have to be an expert in both sides, right? Personally, I find myself doing a lot of R and Python development. I don't spend a lot of time in Tableau, right? I don't consider myself a great Tableau developer, even now after spending a lot of time in the product as we've worked through this process. But what that means is I can use what works for me, right? I can use the tool that's right for me, and I can build machine learning models, I can build business logic, I can build whatever I want to using R and Python, and then I can easily make that functionality available to my Tableau developers, who might not spend a lot of time in R and Python, but they're really, really good