 Hello, everyone. Welcome, everybody, to the UseR 2021 shiny session. I'm your host for this session. So I will just give some keywords about myself. My full name is Mohamed Nassoudiri Adadan. I'm a data scientist at a company called SSW Trading, and we do a lot of shiny and web application development. We are so very excited with this session. I will be helping with two great co-hosts. So Chibuakum Ben-Uba and Juan Pablo Narváez Gomez. So a big thanks to both of you. So just to remind you, there is a code of conduct for this session and for the conference as well. So too long. Don't read. Just be kind to each other and respectful and everything will be fine. Also, I will just give a few things to our sponsor of today. So a huge thanks to Absalon and Open Analytics for sponsoring this session. So as you see, we have four presentations. We will start with the first one. So we have like a group of researchers from Germany, from Fort Wagen University in Germany, namely Veronica Schari, Philippe Pascali, and Matthias Kohl. They will talk about a smartphone-based system in which they've used this smartphone-based system to detect early diseases and they relied heavily on shiny application and shiny mobile. It's really interesting to talk. So I'm excited for it. So let's discover it. So I will ask Ben if you can share the first presentation. Hello everyone. My name is Veronica Schari and today I will present with my colleague Philippe Pascali the all-in-one smartphone-based system for quantitative analysis of point-of-care diagnostics. First, we want to introduce the research groups which cooperated with us. And two groups come from the Institute of Precision Medicine, which is based at the Hochschule Fort Wagen University, which is in the Black Forest in Germany. Our group is the Data Science for Life Science group, and it consists of Professor Matthias Kohl, myself, Veronica Schari, and Philippe Pascali. And we do data science and bioinformatics for the most part. We get our data from the DIGNA lab, which includes Professor Hans-Peter DIGNA, Simone Rentschler, and Christoph Ruppert. For these experiments they performed for this project. And they did the development of the point-of-care diagnostics and the experimental work. Another group which cooperated with us was from the Institute of Hygiene, Microbiology, and Environmental Medicine from the Medical University of Graz, Austria. There we cooperated with Professor Ivo Steinmetz and Dr. Gabriel Wagner-Lichtenegger, and they also provided us with point-of-care diagnostics and did experimental work. So what are point-of-care diagnostics or POC devices? POC tests are performed at the site of patient care, for example at the bedside. That's why they're called point-of-care diagnostics, and they offer a very straightforward result. So either positive or negative, so they only answer yes or no questions. In particular, lateral flow assays, which will be called LFA in this presentation, are a great opportunity for rapid, low-cost, and accessible diagnosis. LFAs contain a carrier material with dry reagents activated by the liquid sample. This simple test setup creates the bands. Here we have two examples of lateral flow assays. On the left, there is a test for Malaya dosis, which is from a colleague Gabriel Wagner. And a more known example is, for example, the pregnancy test or in our pandemic times, the COVID quick tests. So how do we analyze these assays? With our smartphone reader. And our smartphone reader system consists of a 3D-printed photo box for standardized positioning and lighting of the assays. Then, of course, a smartphone for image acquisition and our R Shiny app with modular customizable workflow for image editing, analysis, data extraction, calibration, and quantification. On the left, we have this 3D-printed photo box with the smartphone on top and everything is photographed from above. And on the smartphone, there is this LFA, which is, in our case, illuminated with a LED device. And on the right, there is our smartphone with the LFA in the mobile version. And now, Philip will continue with the presentation of the application. We developed a new application that includes all tools needed for full LFA image analysis. If the users don't want to perform full image analysis, they can still choose one of the simplified sub versions. There are LFA core, which includes image editing, thresholding, and intensity extraction, LFA app calibration, which includes all the modules from core and calibration, LFA app quantification, core plus quantification module, and LFA app analysis, which includes all modules. On the right side is LFA Shiny desktop application, developed with Shiny package, and on the left side is LFA app mobile analysis, developed with Shiny mobile. Now, I will show a sample workflow of our application. This is LFA analysis, a version that includes all modules required to perform full LFA image analysis. Each of these modules will be explained further during this demonstration. First, we start by uploading an image. Then we select the area, and by double clicking, we zoom in, and then we can precisely select the region of interest. It is important the area in between the lines to remain empty because it's used by one of our background correction methods. If we work with images from different flow arrays that contains more than one strip, we can adjust accordingly in the side panel. Now we continue with the background selection. In the background selection tab, first we select the strip, then we select what kind of image we use. We have also options to convert the image to one of different modes or by choosing one of the channels. Then if we need to invert the colors in the image, we use, yes, in the lines are darker than the background. This is needed when working with some images with fluorescent dyes, and then we select one of four thresholding methods. Then we can apply the threshold. When we apply threshold, on the main menu, it's shown first the threshold of both lines. Then we can see the signal intensity above background from line one and line two. And below that, we can see the signal after background subtraction. In the bottom, mean and median intensities of both lines are shown. If we are happy with our result, we can include it to intensity data. Then we can load another image and continue with our analysis. When we finish with the background correction of all images, we can switch to intensity data. In the intensity data, we can find a table which includes all metadata as well as values extracted from the images. Then we can save this table or continue to experiment info. In experiment info, we can upload information about experiments such as concentration or the name of the sample. This table can be merged with our intensity data, and then we can proceed with calibration. In the calibration tab, first thing to do is to set working directory or use the default one. We can also upload an existing merge data and run the calibration. In our case, we are working with technical replicates, so we would like to average them. We choose average technical replicates, we choose the column with sample information, the number of analytes, and the column with color information. Then I will select mean as a measure for averaging. When we average the technical replicates, now we would like to reshape from long to white. So I will use the column color and reshape the table, and then I will proceed with calibration. We can start the calibration by assigning analysis name and choosing one of the three models. Then we should select the column with the concentration. I will use here IL-6. We can also logarithmize concentration, and then we can specify the response variable. The response variable is our expression, and then that allows us to use any complex formula. In this case, I will use a rather simple formula. So I will use mean of the first line by using red channel, and I will divide that with the sum of the both lines. And then I will start the calibration. The results tab consists of calibration model summary, a plot with calibration curve, and limit of blank, limit of detection, and limit of quantification are shown below the calibration curve. We can also open the analysis report, which is a markdown file that documents transparently all the operations that happen under the hood, which can be used later as documentation. When the calibration finishes, the results are saved as well as the model, and then the model can be used in our quantification module. In the quantification tab, we can use intensity data extracted with our application, or we can upload a CSV file with intensity data. Then we can upload a model, which is RDS file, and run the prediction. The predicted concentration is always added as the last column of this table, which at the end can be downloaded. That was a demonstration of the workflow of our application, and now back to Veronica. Okay, so what does the future hold for us? What are our outlooks and what are for the project of ours? Of course, our first priority is to optimize the application and to do further improvements on it based on feedback. For example, we used the application in one of our master's programs, and we immediately had some more bugs, which we needed to fix. For example, the first thing we needed to do was to implement an autosave, because for many students the application crashed, and then they needed to start from the complete beginning, and this was one of the first things we needed to arrange. Of course, from the knowledge we got from the band-based essay application, we now started to work on applications for spot detection in these array formats. An example of an array format, in this case a protein array, is here on the slide. Next steps would also include automatic spot or band detection, for example, via machine learning, and the use of other applications with spots or bands, for example, gel electrophoresis images. And this project and hopefully many more projects were funded by the Bundesministerium für Bildung und Forschung. In the end, we want to tell you a bit about all the packages we used, and of course, if you're interested in more about the topic, here are some resources for you. So of course, we needed shiny and shiny mobile for the application, shiny jays, shiny themes, EBI image for image editing and stuff, are marked down to create the report, DT, GGplot2, FS, and MGCV. And I thank you very much for your attention. We hope you liked our presentation, and we wish you a really good time at the conference. So I will just check the question so far. So personally, I have a question. To be honest, I have never used shiny mobile. I have been always interested by it, but I have never used it. How was your experience with this package? Was it smooth? Yeah, actually, the package was really smooth. And it uses the shiniest base. And actually, most of the elements are converted to F7 widgets. So, yeah, there was no problem. Almost everything is converted. They don't always aesthetically look perfect, but in general, everything was good. The one problem that we noticed was that the touch screen is not registered when we use interactive plot, but that can be solved with short JavaScript that converts clicks or touch to clicks. Thank you so much. I have seen that you are using very complex shiny apps. But it's really awesome to see you're not from computer science or any related field. You're a biologist, if I can say, or a medical scientist. Yeah, how did you get there? How did you master this shiny knowledge? I mean, it requires a lot of skills to to sketch up all these kind of applications and behaviors and this kind of situation. How did you manage to learn that? Okay, so for me, it was, I did my master thesis at the lab of Professor Matthias Kohl, and he suggested that I should check out this. So basically, he's a statistics professor at a university, and he is doing data science and and are all the time. And he suggested to do this are shiny application as a topic for my master thesis. And from this topic, actually this package also arose. So I was more on the side of the spot detection. And this what I said in the last part of the presentation. And then from this, we also did in parallel this project with this line detection. Yeah, so yeah, we had a few courses with statistics and our data science in our master degree. But other than that, it was just the inspiration of Professor Kohl, basically. And I think for Philip, it was similar. I mean, you had you had interest on your own, but basically through your master thesis as well, right? Yeah, my background is a bit different. So Veronica is a biologist and I am a medical doctor. But I did a master thesis in Germany, the same as Veronica. And my thesis topic was a bit quite different. So I did some deep learning methods for segmentation by using Python. But then after my thesis, I started working with Professor Kohl. And yeah, he really loves R. And he converted us and like we are using now R for one year, I could say like, yeah, before that, we didn't have much experience. So I could say we learned a lot from this application. And now the next application that we do like, really we can implement everything that we learned and we can make them like optimized, but shiny. I'm fascinated how simple it is, like, even for beginners, it's easy to understand it and to combine the widgets and things. And even if you want to scale it more and to make it more advanced, yeah, nobody, there is no limitations. Yeah, and also the modularity of it because you can do very complex things, but you can also do very, very simple things basically with the shiny applications. And that's really, really an opportunity also for life science field. Yeah. Nice. In this context, there is an interesting question from Nono Gué. He's asking, would you consider your app a production app or is it still a proof of concept? I would say that it's still in better phase because we gave it to the students one time a month ago or two months ago. So a lot of students tested it, I would say around a lot of 50, more than 50 students. And there are many bugs and problems in the application. We solved almost all of them. And right now, the last feature that we implemented was autosave features. So right now, I could say that even we can start to use it like production because every issue was solved and now I don't see a problem to start using it. I mean, it's also work in progress because, for example, our partners in Austria, they use it also or we will continue to work with them to adjust to their needs. But it's still like, okay, can you insert this feature as well? And can you do this as well? And so it's always changing and always updated all the time. So it's really a work version all the time. And the question where it is hosted right now, it's right now hosted on GitHub, on Philips account. Thank you so much Veronica and Philips. We will go now to our next speaker, who is Jonathan CD. Jonathan CD is, of course, just to remind everyone, I'm sorry, I couldn't, we couldn't answer all the questions because of time schedule, but feel free to ask later in the Slack channel. So I will just introduce Jonathan. I think he's really famous in the R community. He has developed many great packages, especially related to Shiny. And I have used to be honest, many of these packages, which I was always satisfied. He's a great developer. And he will talk about unit testing Shiny application reactivity, which is a really, really interesting talk. I want to sit by that because reactivity is a beast in Shiny. So testing this kind of behavior would be just perfect to improve the robustness of Shiny application. So Jonathan, whenever you want to share your screen. Okay. So hello, my name is Yanni City. I'm a director of modeling and simulation at a pharmaceutical company called Sage Therapeutics based in Cambridge, Massachusetts. This talk is going to be about unit testing Shiny app reactivity. So the motivation for this talk is the ability to diagnose and resolve cascading reactivity and Shiny applications, which is an integral part of a good application development preventing the waste of resources and negative user experiences. What is cascading reactivity? It's when elements in a Shiny app trigger each other in a manner that the developer did not intend. So unit testing is something that a lot of package developers are used to either through test that or tiny test. And it's a way to create short expectations that can test different parts of a package. And using this type of framework, this package reactor is creating the same type of outline and framework in order to diagnose and resolve reactivity problems in Shiny. The added benefit of having this type of unit testing is that it creates a defensive development that can be applied to Shiny applications for both to plan and preserve reactivity with multiple developers working on the applications. So in many of my open source activities and also at production level, many people are creating at the same time the same Shiny app. And when you commit code to a repository, it could be that you are breaking part of the app and breaking it in the reactivity level and not necessarily the objects that it creates. So this package comes to answer this problem. There are different types of packages out in the ARB and CRAN. Most of them are actually testing that after reactivity has occurred and they're testing that output is as expected, be it a UI object such as a graph, a plot, or some kind of different UI element. And not necessarily that it's being triggered correctly, that it's not calling the same UI over and over again, which has second order effects on the app and can slow it down a lot. So now we'll go through the API and of the package. And what it is is so you load the reactor and then you initialize a reactor, which is basically an R6 object. And you can see it is expecting to be populated by two objects, the application that you're using and the driver, which has specifications for either an R selenium or a puppeteer. The application can be either using run app arguments. So you have a path to the app directory or you can use the Golem package after you build your Shiny as a package. And then you set Golem args in order to define the place of where your app is located. What's going on under the hood is that reactor is setting a test port, a test path, an IP, and the directory. And this is all the information needed in order to run your app in a process X in the background. So you can have your current session running and while that's running, your Shiny app is running in a different session. The driver is chosen X and you can use either a Chrome driver or a Firefox driver currently. And all you have to do is take your object that you initialize and pipe that into a set Chrome driver or a Firefox. Then you can control headless mode. So with this, you can run the app either headless or not headless, which is one of the options that you can use with the package. Starting reactor, so once we have specifications in place, both for the app and for the driver, they're both running in background processes and then we can manipulate the Shiny app as it runs. So right now, the way that it's set up, our Selenium can be used. In the same way, the reactor also works with Cry, which is an open source that was created, which works much the same way our Selenium does. And you can see how it works on the GitHub repository. Interacting with the application, so the reactor comes with pre-built common actions that lowers the threshold for working with the application. So you can either inject commands into the app, so you can set ID values or execute JavaScript calls, or you can query different elements inside the app at the same time while it's running. So you can query the input names or the output names, either all of them or a specific one by the ID. And then you can also query anything in the app using JavaScript, raw JavaScript that you can call. Closing the reactor is simple, just kill the app, which kills both the child processes that are running in the background that the reactor is using. Constructing the pipelines in order to work with the apps while they're running. So this is an example of a full pipeline. So you're initializing the reactor, you're setting the application, you're adding the Chrome driver, you're starting the reactor, and then in this case it's manipulating the input and then it's closing the app. This same pipeline can be used in order to test expectations on the app while it's running. So here I added two lines where after setting the initial, after setting the ID value N to a new value, I test the expectation that there was one hit to the reactivity of the output hits. I change the value again and I test the reactivity that happened the second time. So there's an internal counter that is checking how often an input is being hit or changed. Another way to test expectations is to test how long is Shiny busy for a single interaction event or the cumulative time that it was busy throughout the app while it was running. So again, after setting the, after starting the reactor and changing the input value, I can expect that the time that Shiny was busy was 0.1 seconds. And then after I test the time, I can write along the same pipeline test that it was, that his was hit one time. All of this can then be added into a test that integration. So I can put that same exact pipeline into test that and create a test that flow in order to test my Shiny app now. So here I'm adding the describe and it framework for test that reactive hits in a plot for reactive chunk. And I'm testing that if that, if his was hit twice, the way that reactor understands that and helps test that understand that there's two different types of tests because maybe you have a package and you have a Shiny app that you have in the same directory. You, such as a Golem application, you can, a reactor has a prefix reactor instead of test. And that way tests that you won't by accident trigger the reactivity tests as you're running your regular unit tests for the app. This creates an isolated reactivity area in order to test your activity and it will not interact with cover because that's expecting a test prefix to. So here's an example of running test apps. And here you, and it's running against two different types of apps. One is expected to fail and one is accepted to pass. So here you can see that it's the same exact output you would get through test that and running and so you know what to expect when you're running it. And here one failed and one passed. And finally, there's there's continuous integration. So you can run this whole workflow through, for example, here this is GitHub actions. So as you commit, you can have GitHub GitHub actions test your activity for every commit or pull request that you have. So the idea being that what if I commit something to a repository and working with 10 other people on, it is guarded against anything that I do that would break the reactivity that is already in the system. And in that way we can have a better collaboration across multiple users. So as a conclusion, reactor simplifies diagnosing reactivity issues in shiny. It creates a framework to store and reproduce testing of shiny apps can be applied to continuous integration. And it creates a safer shiny development practices for teams to collaborate. Thanks. Thank you so much, Jonathan. Really, it's really an impressive product to be honest. We did a lot with the activity and reactivity cascading and like when the app grows, I must admit that it became insanely hard to manage and to maintain, to be honest. I have the first question that came in my mind. It's a bit silly question, but for example, the function that you use, expect time busy. And you have provided like a fixed unit. Is it like an estimation of the time or because we can't be certain of the exact amount of time? How does it work exactly? Yeah, so you have to give up front for the expectation. You have to give up front. What is the expected time that you have for a certain reactivity to take place? So you have to give that to the expectation just like any other expectation and test that you have to know the answer to test against it, right? Cool. But my question is that this kind of estimation or time, the time process may depends on several other factors. For example, the internet bandwidth, I don't know, the computer RAM, et cetera. So how we can manage that from one user to another? Yeah, so if it is used in the continuous integration framework, then you do have a consistent machine working on the cloud. So you're testing the same machine over and over again? Perfect. Thank you so much. So there is another question here in the chat. So is it possible from Thomas Capreto? He said, is it possible to test input outputs inside modules? Yes. So you can query any input or output, the names of them during the shiny up run. So even if it's in a module, it still has an address for the shiny users in order to have the shiny up run properly. So you will be able to use the right input name inside the modules. Thank you. And there is another question from Jonas Hagenberg. Can you also set the values of reactive value and reactive values? Yeah, so you can, using set, the injecting, there's a set value by ID. So you can give the ID of an object inside the app and you can set the value of that. So it can be a number or a text or whatever the type that the element is expecting, you can add it. You can update it. So you can update even slide bar or anything that there is in China. You can update through JavaScript. You just need to, so the set ID helps you, gives you a simpler way of doing it. But if you need something more elaborate, you can inject the JavaScript directly. Cool. So there is another question from Samuel Calderon. What would be the minimum upscale recommended for starting using this kind of test? I use it for even small ones. So it's much like a package. You start doing unit tests even from the small, because once it gets big, even for in a package settings, it gets too big. And then you're basically overwhelmed by how many unit tests you have to do. So I would recommend even starting with small and then building out as you add more features to your app. You're guarding against different scenarios that the app may have. Thank you. Is the back edge stable? I mean, can we use it in production environment or is it in a development process? So will it be on cram? It will be on cram. Currently it's on GitHub. The main thing that I've run into, I use Firefox more often than Chrome. With Chrome and Arsalanium, there is a lot of times synchronization problems with the version of Chrome that Arsalanium uses. So I would personally, I would recommend using a GECO driver in order to use the package, but it will be on cram. It's pretty close to being production-ready. The API is stable and it's just a matter of me finding time in order to submit it to Chrome. To understand. The last question, if I might, what are the next steps? Are there any new features that you are planning or in the future? Right now, I'm more using it in my own packages and then seeing that it's being able to interact with Cullen's Cry package that has a similar features. So having it be able to interact with a lot of different types of packages in the ecosystem. But for right now, it's pretty stable and it's just a matter of getting more users to bang it around in order to see that there's no blind spots. Thank you so much, Jonathan. I can't wait to use the package in a production environment and see it's magic operate. So thank you again. We would now introduce our next speaker who is Leon Binder. He will present us his package, Shiny Quickstarter, which allows us to create Shiny application UI and server integration through click and drop, which is pretty impressive. To be honest, I have tested it just yesterday. It is working. I don't know how is it possible, but it works. It is really like impressive. So now let's go with Shiny Quickstarter. Hello and welcome. My name is Leon Binder. I am from the TTC Gravenau, part of the Technodorf Institute of Technology in Bavaria, Germany. And today I can proudly present to you the Shiny Quickstarter, which is a studio add-in for building Shiny apps per drag and drop. This add-in tries to integrate a few different parts. For one, it automizes the folder setup. Then you can create the UI of your Shiny app with drag and drop. The add-in itself also shows you some documentation to the elements that you used. And you can adapt the elements that you use. For example, changing the input IDs, the labels, or other options that those UI elements have. And in the end, you can export your code and immediately start with implementing your actual program logic. I put the focus of this add-in on two main parts. That's the usability doing the entire app development process. So you can use it for some initial prototyping, just playing around with the UI elements, then the initial setup of a Shiny app at day one, and every time you want to extend it later on. The second main focus is on the user experience of this add-in. I've tried to design it in a way so it's beginner-friendly, so new developers who never actually created a Shiny app but know a little bit about it can use it, but also it should have sufficient functionality that advanced developers that have created multiple Shiny apps can get something out of it. So what code can be generated? Looking at the global file, what I can do is generate some library imports based on what UI elements that you used, and I can add some very basic code snippets like sourcing or functions or modules in their respective folders. What I cannot really optimize is loading data or pre-processing data because that's very different from project to project. Looking at the UI definition, I can pretty much generate the whole UI. The only exceptions are if you want to use some UI elements that are not included in the Shiny Quick Starter right now, or if you want to add some custom Hottie ML, CSS, or JavaScript. Then the server file, the server file, I cannot actually generate the program logic, but I can generate the basic layout of the server file. So if you, for example, use or plot the output, then I know that you also need a render plotly function on the same ID. Then if you want to create a module, it's pretty much the same. The UI module function can be generated fully or almost fully and for the server module function, I can generate the very basic layout. So let's jump right in into a little demonstration. You can install the package currently only from CRAN with the install package command and then launch the add-in through the Shiny Quick Starter function or through RStudio itself with clicking on the add-ins drop-down menu and then build Shiny Apps per track and drop. So when you launch the Shiny Quick Starter, it's going to open in your default browser and already show you a little help to it. I would really recommend going through it at least once when you use the add-in for the first time because it leads you through the add-in and pretty much tells you everything that you need to know to use it. And then the next time you can just click anywhere else and it's going to close. So the first decision to make is to decide what page type you want to use. So you have the choices between a few Planco pages, like a Fluid or Fix page, and then an Afbar, Dashboard or Mini page. Those have a top level navigation built in or if you want to extend an existing app, you can set a tag list and it's going to create a Shiny module for you. So let's say we want to create an Afbar page. Clicking on it then shows in this navigation hierarchy in the top left corner that there's an Afbar page and within a top panel. I can click on Afbar page and then it highlights it in the drop area and on the right side it shows me options that I could set. So this Afbar page, it has a title. So let's say I call it user 2021 and it immediately updates this title in the navigation bar and then I can say, okay, I want to use a dark background and I want to make it collapsible. The Snuff bar page would also have a few more arguments. Those are listed down here under all the arguments that can actually change and those if you want to maybe change the theme, then you have to do that yourself. It's not included in the Shiny Quickstart right now. Then I can click on top panel. It's going to highlight the top panel in the drop area and show me the options to this specific top panel. So let's say I want to delete the title and say that it should have the home icon as button up here. So let's say I want to add layout elements. They just make the design a little bit more different. So for example, I want to use a sidebar layout. So I click on it and go to my drop area and then where I want to put it, it gets highlighted in yellow and I can drop it and so like release the left mouse button and then it actually inserts it. This sidebar layout, it also needs a sidebar panel and a main panel inside. So those are added automatically. So I could now change if I want to have the sidebar panel on the right or the left side and for those panels they only have like a this option that I could adjust. So going to inputs, there are a lot of inputs mostly because ShinyWidgets has a lot of them. So here the search can come in handy. So let's say I want to use a select input. So I put it maybe in the sidebar panel and then it shows me the options for the select input. So the first thing is that I need to change the input ID. It right now gave it a random input ID. So maybe I say that it says some aggregation level that's saved in this form element and then I can also change the label. I could also say already some choices that I know beforehand like I want to aggregate data by days, weeks, months or years. So those choices are going to be added and I want to have 100% width of this element. So it's like 100% of the width of the parent the sidebar panel. So next up I might want to add an output. I might want to like add a plotly output. So I drag and drop that into the main panel. Outputs also they have like an ID. Currently it's randomly set. So I just call it very uncreatively plot for this example. And then adjust also the height of it because it's a little bit too high. Outputs are a little bit special because they don't they have UI and UI element. So the plotly output and those have like arguments but they also have a function in the server. So in this case random plotly. So plotly output for it I can change to I can like a select an expression. So if I already know okay I want to aggregate some data that I have loaded based on some time frame and then I want to show a basic bar plot. So I select that and it's going to add this code with some example data. If I'm finished with the app I can also go into display mode. It then shows me how the app looks and it's a little bit more realistic. There are not those element box around it. If I want to look at the code I go to the top code UI and then it shows me the code that's going to be generated for the UI definition. I can also go to server and it shows me the code that's generated for the server and if I would create a module then it would only show me this module top. If I want to export my code I go to the export top and there are two sub tabs. So the first one is folders. So here I can select some directory where I want to put my new app and say maybe I want to create a sub folder. So I just call it use 2021. I also want to maybe create and do our studio project with the same name and I want to create folders for my data, my functions, modules and for some other web assets. So I click on export folders. It shows me what folders and files are going to be created and gives me a warning that existing files are going to be overwritten. So I confirm it and now this folder structure is set up. I can go to the export code top and here I select this folder that I just created and then I can decide what do I want to put my global UI and serve a code in one file or multiple files and what code snippets do I want to have in my global file. So like switching all functions and modules and maybe clearing all objects from the workspace before I start the app. So I can also click on export code. It shows me what files are going to be generated and then I can say export code and now it's fully set up my app. So I can switch over to our studio and here it shows me my newly created folder use R 2021. In it I have those folders. I have our project file and I have my global, my UI and my server file. So the UI file it added those very basic code snippets and said what libraries I need for this app to run successfully. Then the UI here could now add somehow TML, CSS or JavaScript or like adjusted like I needed and the server file with this one random lovely function. So I can click on one app and it's going to start it in a browser and here's my app, my very, very simplistic app that I just created. Obviously there's no program logic behind it. So now I would have to make some connections. So if this input aggregation is days then I aggregate by days and re-render this plotly output. So obviously this add-in can be further developed. Besides some code optimizations and bug fixes here and there, I hope that I can also extend the add-in by the shiny dashboard plus package because it would be a really nice extension of like the general shiny dashboard package. Then it would also be nice to have an export input functionality, not off the code itself, but like the current state of your created app in the Shiny Quick Starter. So like what elements have you used and what arguments values have you set. Then the third point would be to allow movement of UI elements because currently if you want to move an element you need to remove it and then add a new one and make those adjustments again because and that's can be a little bit tedious. Another point with a lower priority is like enabling connections between inputs and outputs in the add-in itself. So like saying some data table should only re-render if I click on a button because there's time consuming calculation behind it for example and the last point to add arguments and a return statement for modules. So if you have further ideas or like notes for me you can clearly contact me otherwise thank you for listening and I hope that the Shiny Quick Starter will help you from time to time. Well thank you so much Leon it's really impressive how fast and how easy can one build like a shiny app or the structure of shiny app. So it's really really impressive. There are many questions so the first one from the Slack channel. So Leon it seems that the quick shiny UI cannot autosave. Is there any chance it can save the work in progress? Currently it's unfortunately cannot but I'm hoping that I can include that it should be pretty easy just saving two data tables. So that's definitely a feature that I want to include. Thanks so there is another question. Is it possible to open and modify an already existing app? That's not possible and probably also will not be possible in the future because it gets really complicated if your existing app has some UI elements which I don't support in the Shiny Quick Starter it would then maybe delete it or I don't know how it would handle it. So it's it's really just for the initial setup and then every time you want to extend your app with a new module you can do that and existing apps modifying that you have to do in our studio itself. There is another question from Riyadh. He said, whoa magic is there certain apps where you recommend or you don't recommend using this add in? Well I wouldn't really recommend building a huge complex app with it because it could be that it's crashing at some point but if you start with a simple app like a dashboard page for example with a few menu points and then you extend it after what's with like new modules that's working pretty well. So and also for like simplistic apps it's working fine. That's really great. So there is another question from Nanu Gui. He's asking, I'm sorry, great job Leon, very impressive work. Are you planning to add the ability for the app to create modules from the add in in the initial setup? In the initial setup not. It's really better to divide those two parts. So you first set up your shiny app, a simple one with a basic layout and then further on you make modules because mostly you will not really know what modules and parts you want to have at the initial setup but more like later on when you are expanding your existing app. Cool, so I have a question personally. So is there any work in progress to for example add some external files to the shiny app interactively? So from the UI like for example add an image here put it like for I don't know, some CSS and see the result immediately on the screen. Is there any meaning the future or something? I have that on a list, a very long list of future features that I might want to include but it has a lower priority right now. It has lower priority? Yes. Great. Let me see if there is another question because we still have one minute. So I would ask like a quick question. So you have used like the shiny widgets package? Yes. So I assume it is possible to integrate other packages? Yes. So in the back end I thought about how to develop this package for a few weeks. So I decided to have one big X list where I add all the UI elements that I want to include or include right now and then have different aspects that I categorize them. So for example a box you can only use in the dashboard page but you can put other elements into a box but then an action button you can use everywhere but you cannot put something into an action button and also for those arguments I listed them and then said what of them are required and default values. So when I added those widgets from the shiny widgets package I could add just 70% of those UI elements just by adding it to this X list and then restarting the app and see if it broke something but like in 70% it worked really well but then every once in a while there's a UI element which is kind of different from the other ones and then it means I need to adjust some code here and there. Well it really looks impressive and thank you so much for your work and for your contribution. I hope it will grow and we will like be able to build shiny apps very complex using just the click and the mouse. So thank you so much for making this abstraction especially for newcomers. So I will just introduce now the next speaker. So the next speaker is Tobias de Koenig. He works at Open Analytics and he will talk about the good news about Shiny Proxy. Okay hello Vuran, I'm Tobias de Koenig, I work for Open Analytics and I'm going to present Shiny Proxy Good News Show. So let me first introduce Open Analytics. We are a data science consultancy company based in Belgium. We have a strong track record in AR and one of the things we do is developing open source projects for using AR in enterprise context. This talk is about Shiny Proxy which is a web application to deploy shiny apps in an enterprise context. Every app is a self-contained Docker image and this flexibility allows you to host Shiny apps, dash apps, Jupyter notebooks, Arc Studio, 3-init Zeppelin notebooks. Yeah, you name it. These apps run on Docker, AutoCache, RAM or communities and therefore Shiny Proxy is a very scalable solution. We support several authentication options and that ensures that you can run Shiny Proxy in your existing infrastructure. So here you see a screenshot of Shiny Proxy. Yeah, basically when you open Shiny Proxy you get a list of applications and you can launch an application as you can see in this screenshot where I launched a Shiny application. Okay so in this talk I want to demonstrate the highlights of our latest release and some upcoming exciting features. So the first thing I want to discuss is a Shiny Proxy operator for Kubernetes and basically the idea of the operator is to ensure your cluster doesn't look like this yeah doesn't end like this ship. Okay so maybe first explain what Kubernetes is. So Kubernetes defines itself as an open source system for automating deployments, scaling and management of containerized applications. So yeah it's indeed an ideal platform for running Shiny Proxy. Okay what's in Kubernetes operator then? Well we define it as a small piece of software that extends the Kubernetes API in order to fully automate the operation of a complex application. So basically the operator will manage the lifecycle of Shiny Proxy servers and yeah the reason we need it basically is to ensure that you can update the configuration of Shiny Proxy without affecting the session of the user. So when an administrator updates the configuration of a Shiny Proxy the operator creates a new Shiny Proxy server but it gives the existing server as long as users are using it. So those users which are running an app will stay on the old server and can keep using that application. Okay that's nice but what if existing users want to start using an app from the new Shiny Proxy server well they get a notification on the main page and they can decide their self that they want to switch to the new server and use a new application. Another reason why we need the operator is to allow seamless updates of the Shiny Proxy server itself so to basically update the version of Shiny Proxy. Yeah the operator also allows you to to multi-tenant hosting of Shiny Proxy. Yeah you can yeah this allows you to run multiple Shiny Proxy servers on each other. Each server has their own configuration and is fully isolated. And finally another reason is that you can allow app developers to easily add or update apps. So app developers not system administrators they can really easily update the Shiny Proxy configuration because they only have to change a YAML file. The operator will take care of launching the new server and the very nice thing is that errors in the configuration will not cause downtime because the operator will never route users to an unreachable instance. Okay that sounds nice but how does it work? Well we have three components first of all we have the Shiny Proxy operator which is a basically a Kotlin application packaged into a Docker container. Then we have Skipper which is an ingress controller for Kubernetes. And this yeah this skipper handles the routing of users to the correct Shiny Proxy server. And finally we need Redis for the session persistence so that the user stays logged in when they are transferred to a new server. Okay now let's look at the demo. Okay for the demo of the operator I'm first going to show you the tool I use to visualize the Kubernetes cluster. So as you can see we have basically three components we have the skipper ingress component the race component and the operator itself. Here you can also see the logs of the operator. Yeah so okay to start I'm going to deploy a Shiny Proxy server and to do that we need a YAML file with the specification of the Shiny Proxy server. So this YAML file is very similar to the usual application.YAML file of Shiny Proxy it only contains some extra metadata for the Kubernetes API. Okay so I created I have the file ready I'm now going to create it in the Kubernetes cluster. So I just with the kubectl command tool so I created it and now you can see the operator is working and it's creating a new Shiny Proxy server. So now we have to wait until that server is ready. Okay we see that the Shiny Proxy server is ready you can now access it using our browser. I'm going to login as check and launch an application. The application is launched I'm going to add an ingredient let's say apple voila and now I'm going to add the new application to the Shiny Proxy configuration. So again I'm going to my Shiny Proxy file and I'm going to add our studio. I added the specification now I'm going to update the resource inside Kubernetes. So we will now see in the UI that the operator is creating a new Shiny Proxy server but we will also see that the existing application is still working and we can for example add a new ingredient to prove that. We will add a banana and you will see that it recomputes the nutrition. So the app is still working. Now you just have to wait until the new server is ready. Okay Shiny Proxy server is ready and we can see that this old server is still running. We can go back to the application add a new ingredient and indeed it still works in recomputes and nutrition. Let's say we are now an other user and I'm going to login in a private tab as a chef and indeed we see that our studio is in the list of applications. So I can launch the application. A lot of applications launched and we can use our studio. Now you can have a look at the main page of the check user and we will see that our studio isn't in the list of applications. That is because the user is still having an application on the old server so they are using the old server and they don't see our studio. The user can choose to switch to the new version by clicking this button and accepting the warning that they still have one application running and now they are transferred to the new server and indeed our studio is in the list of applications. So we can again launch the application and now the application launch and if you now go to the UI for communities we will see soon that the old server is cleaned up. Well the old server will be cleaned up as soon as the application is gone so we will need to wait for the time out. Okay see that the Shiny Poxy, the old Shiny Poxy server is being removed because it's no longer running any applications so now we are only left with one Shiny Poxy server running our studio. Now we can talk a bit more about Shiny Poxy as a first class Kubernetes citizen. This is something which was released in some in the latest versions. We introduced two new configuration options, the Kubernetes spot patches and the Kubernetes additional manifest option and these options basically allow you to modify the pods created by Shiny Poxy and with this option you can create persistent workspaces for users which is very useful in our studio or Jupyter notebooks. It allows you to set a custom service account for each user or each app. It's allowed you to set up a custom namespace and so on. The possibilities are endless, you only have to use your creativity. We also introduced the readiness and lifeless probes. These are like the mechanism to indicate to Kubernetes when Shiny Poxy is ready to accept traffic and this is important for the operator in order to spend downtime when the operator updates Shiny Poxy. Another thing we introduced in the latest versions is better observability of Shiny Poxy so we can export Prometheus metrics and we also added more metadata to the application like the containers which are created by Shiny Poxy and these features allow you to create very nice dashboards for example in Grafana where you can upload the startup time, the usage time, the amount of users and so on. Okay now let's have a look at features that we are going to introduce soon in our future release. One of these features is to run multiple instances of an app. So for many multiple instances of an application, the workflow is very similar. First of all we start an application like the RStudio application. We wait until it's ready and then we can use this RStudio server example to do some fairly advanced computations. Then we can click the switch instance button and you see here we have the default instance. We have a button to stop the app and it will restart the app. First of all we are going to stop a new instance, give it a name test and we click the submit button. So now a new instance is launched and we will see that indeed we have a new ARC session and we don't have the computations we did earlier. Again we can do some computations. I can launch a third instance and as you can see my ITC set-win can configure a maximum amount of instances. In this case the maximum amount is five instances and I'm running two instances. Okay so you can see we have the stop app and restart buttons. I will press the restart button of this app. Yeah we get a confirmation. Okay and the app will start. This is useful if you want to start with a fresh ARC session. For example if you had something wrong and you want to restart. Okay then we can also press the stop app button and this will simply stop the app. Voila the app is stopped it's cleaned up everything is gone and we can restart the app again. We can also stop apps that are not currently running in the current tab. For example the app started early on and this is useful to clean up any apps you forgot about or basically that. Another feature we introduce is a reconnecting web socket feature. This mechanism allows automatically reconnects when the web socket connection of an application is disconnected. For example when the Wi-Fi connection of a user is unstable this mechanism will kick in and automatically reconnect your connection. The last feature I want to show you is the apricopry feature. When enabled this will restore any running application when you restore Shiny Proxy. Okay you are at the end of my talk. I try to cover some of the exciting news around Shiny Proxy. If you want to know all the details please have a look at their website where we also will announce a new release with all new features and of course provide some extensive documentation. Thank you for coming to the talk and have a nice conference. Thank you so much Tobias. It's really interesting to be honest. We use Shiny Proxy when I'm working right now and it's really effective and it's also how it is easy to update the Shiny app and put it into production just with a few comments so really really a great product. I will jump to the questions right now. There is a question which I think you already answered but it would be great if the audience can hear the answer. So the question states, Tobias how does the operator handle scaling application support? Does it support horizontal pod autoscaler resources for application? How does it load balance session across multiple application pods? Okay so currently the operator doesn't support scaling. We have some plans for it and making Shiny Proxy available and that will allow to scale Shiny Proxy. So currently it isn't there yet and yeah with respect to load balance we currently use Skiper for hooting the HTTP traffic so once we introduce scaling that will also be used for load balancing. Thank you. So I would check if there is another question. I think we don't have another one but I will ask just I'm not really an expert in show app deployment to be honest but I think Shiny Proxy were with Docker containers right? So could you please in few words explain how these two I mean distinct products interact with Shiny Proxy? Yes so the idea of having the apps in your Docker containers is that like every app or every instance of your app is isolated from any other app so that you can use a different version for two apps or a different version of Shiny or even apps that are not Shiny apps like Python apps or Dash apps and so on. And also like the second thing is that we can because they are all like small containers running an app we can really scale the servers on which the apps are running so you are not limited to one server running Shiny Proxy and all apps or all barcode but you can have a cluster of multiple servers running yeah multiple instances of an app and scaling yeah upscaling the servers for needs for example you have customers that maybe they use a few apps but sometimes they have to give a training or a demo and then at one point like 30 or 50 users start using every user starts using an application and then the back end servers like the not the servers but the physical servers are scaling up and there are small resources to run the app and that's also one future that we we can provide because you are using Docker. Thank you I would just check if there is another question from the chat. For now I think but I will ask another question so what are if you can just cite a few advantages or disadvantages could you make a comparison between Shiny Proxy and for example another deployment product for example RStudio Connect or what are the advantages of using Shiny Proxy over RStudio Connect for example. I'm not an expert in the other products but I think one example is that like with Shiny Proxy every feature is open source and freely available so you can use any feature without limitation for example I think we have like support for different authentication backends like SAML and LDAP and so on that allows you to integrate with your existing infrastructure in your existing authentication I think that's one limitation of the other products and also yeah we allow running different kind of apps so we see people using Shiny apps but also RStudio itself and like Python apps and yeah in the version we are currently working on will allow you to run multiple instances of an app so that you can one creating is to run multiple instances of RStudio which I think is also an invitation of the other product you're only in the paid version I guess so there are some differences. Yeah thank you thank you so much Tobiya maybe the last question I have seen in the your abstract that you that Shiny Proxy can deploy as to a way of new application I think it's only available for now in Python so when it will be available on R so Shiny Proxy will be able to to serve this kind of application. So like Shiny Proxy is not limited to R applications and if you can package it into an R into the container and run it as a web server you can run it in Shiny Proxy so you can also run Python applications without having them to like be limited to something. Ah yeah so we just need like a Docker container and then we can use for example Django I don't know if ask any web app deployments anything. Yes anything that's possible. That's great that's great I didn't know that to be honest so I think if there is any other question I think people can ask you and meet you in this lap so I think I will just ask my co-host if there is another time for Q&A or should we just wrap up the session. We can wrap up awesome thank you thank you so much everyone for for joining us I would like to thank everyone every person involved in organizing this event so there are too many to two sides and it's like I would say that it's like a tremendous work and being able to see it like in action and live streaming like that is really great so thank you so much everyone and thank you for all the people who are here thank you so much