 Okay, so very good afternoon, hope you had a nice lunch. So today I'm going to talk about Jigna, that is a way to create rich HTML user interfaces for Python applications. So can I get a kind of hands, how many people have done any sort of user interface development in Python? Lot, okay. So I'll start with a little bit of a personal introduction. I am a developer at N-Thought India Mumbai for the last two years. N-Thought is a company which has a Python distribution called N-Thought Canopy. And so I've been working on N-Thought Canopy and N-Thought Training on Demand, which is the online Python training. I've been mostly working on the front end development for that. And before this, I completed my master's and bachelor's in aerospace engineering from IIT Bombay. But aerospace engineering to UI development, I don't know how it happened. So for Jigna, the two team members are Prabhu Ramachandran. He is also an author of Mayavi, which is a 3D visualization library. And he is a professor at IIT Bombay, was also one of my ex-project guides. And Martin Shilvers, who is author of Envisage, a plugin-based framework. Sorry. So what is Jigna? So basically it is a bridge which lets you write user interfaces in HTML for your Python models. But why HTML? So if you look at the current state of UI development in Python, you basically have like QT, WX Python, PyGTK, Tkinter. And most of them look more or less like this, where you have widgets for your common tasks and buttons and menus and everything, which is nice for you to get started. You can have, you can get a reasonable user interface fairly easily. But if you want to have rich user interactions, then you are kind of limited by the widget set that is provided by the toolkit. The code is mainly procedural. So if you were to add a widget here, you write qwidget.addWidget at this position, which is not really helpful because when you're trying to design something, you wanna see it, how it will look. So declarative code is usually better for UI. And again, for toolkit-specific development, the community of designers is limited. I'm comparing this with the web developers. So if you consider the web applications, see the kind of richness you have in web applications. You'll have videos here, hexagonal elements there, canvas, SVGs, and all the cool things that everyone is working on. So all in all, you have a very rich user interaction and HTML is not limited by a widget set. So it gives, it uses the power of CSS and JavaScript so that the designer can design the widgets just how they want it, not like standard buttons or everything. So each website can have its unique feel to it. And the most important thing is that it's much, much easier to find HTML designers. If you want to go to a room and shout how many HTML developers there, you have a lot of hands up, but ask how many QT developers, good luck. And again, the code is declarative. So very easy for non-programmers, who are designers to get started on HTML. So you have a very nice bridge of HTML technologies, but they're mainly limited to the web technologies and the desktop applications lag behind. You don't have the kind of richness for the desktop apps. What if we could bridge that gap? Which is where Jigna comes in. So let's say you have this domain model, simple class employee with a name and cell V. This is, by the way, and thought traits. So it has some nice features like automatic notification when the attribute changes and the static declaration of the types and all that. But so you can check out and thought traits, but this talk's not about traits. So what I'm trying to say is you have this domain model and what if you could have this sort of HTML interface to it? Where let's say you have employee.name within the braces. This is a template, but this is not a static template. So let's say it is bound to the name attribute of employee. So whenever employee.name changes, the value gets updated and you can call methods here. You can call the Python methods directly from the HTML. So I'll start with a small demo here. And so you see you have employee.name is Tom, which is the name of the instance here and salary is 2000. You click on update salary. It will call the method on the Python side, update the attribute and since the template is bound to the employee.salary attribute, it will automatically get updated. So the thing to notice here is the model view binding is automatic. You don't have to write any special code for binding the particular template to the model attribute. The HTML template is live, which means whenever the model changes, the HTML changes and the HTML can call methods in the model. Code is declarative of course, because it's all HTML. And let's face it, developers write the worst user interfaces. So since it's all in HTML, this all can be handed off to an HTML designer, which is cool because there is nice model view separation. And it's not just for traits. So if you have a regular Python model, it will work just as good for them, just that the automatic model change attribute, you have to bind it to update the HTML. So we have an example for that. And before going further, what it is not, it is not another UI toolkit. The UI toolkit is HTML, so you don't have to learn new ways of creating widgets or anything. It's not a widget library. And it's not a web framework like Django and Flask. Mainly because of two reasons. One, that Django and Flask give you a static template, where here the template is dynamic, is always live. Other is we are not doing web. So a lot of things that Django Flask handle like security, cross-site prediction and cookies and all that, we don't handle all that. This is purely desktop UI stuff. So how does it work? You have the Python domain model on the left and the HTML live template. You write a little bit of binding code, which kind of creates an app with this template and this template will be rendered with this context. So the string employee is bound to the Python object employee here. So whenever this employee dot name changes, this template automatically updates. And under the covers, we have a JavaScript proxy for the Python model. So basically if you have an employee object there, you'll have a similar object in JavaScript. So between JavaScript and HTML, there is AngularJS MVC framework. AngularJS is basically, it makes sure that whenever the JavaScript object changes, it updates the HTML. And for connection between JavaScript to Python, we use Qt's Q WebView. Q WebView is basically just a browser which allows you to, which allows the Python model, Python to execute some JavaScript and for JavaScript to call methods in the Python or access attributes in the Python. So we are using just that small bridge protocol. So let's say you want to populate what employee dot name is. So AngularJS will ask the JavaScript what is employee dot name. And employee dot name is a getter function which will in turn ask from the Python domain model what is employee dot name. And the Python model will basically till this is employee dot name. And accordingly the HTML template will be updated. And let's say the model changes on the Python side. So traits has this mechanism of how to handle change handlers. So whenever let's say salary changes, traits fires an event on trade change. And this will signal the model update to JavaScript. And accordingly we'll have the Angular update the template. So you have a nice live HTML template which talks directly to the Python model. So I have a small demo here. I'll cover some of these things in the demo. For real applications you need to bind, you need to have proxies for lists, instances of objects. You need to call methods on the Python model. You need to call methods that are slow. So you can't afford to have the UI blocked while the method is executing. And you want to attach some success callback, error callback, event handling. So let's start this application here. Is it too small? I'll, okay. So nothing much to read here. Basically there are two apps and I'll read out the code here. So we have a simple app object with name, URL icon and things like that. And an app manager which has a startup. So in order to show these two apps, there is, this is an AngularJS construct and grepeat which is like a for loop for AngularJS. It loops through the app manager.installedapps. Now app manager.installedapps is an attribute of the Python object which is a list. So each app is a proxy to the Python app object. And for this you can write ngsrc which is the source of the image tag is app.iconurl which will fetch the icon URL for this app and the app.name. And you can define the click behavior on the button click which will call the start app method of the app. So basically a simple dynamic template which talks directly to the Python object. So if I click here, it will start the app which is hello Berlin. And so, and if you, you can also install some apps. So you go to the store. Now here when I click on go to store you saw a little loader, right? So when you click go to store, it calls a method connect here which has some slow I've marked it here but basically you would be contacting some web services but you cannot afford to block the user interface. So we provide a way to call this method asynchronously so that you can have the UI loader and then the apps in the store appear. You can click install which will show you a nice progress dialog. Now this progress dialog is also, so when you click install, this is also an asynchronous call. You'll have a fetch action which will update the progress and progress is an integer. So in order to show that nicely with progress bar the code is like this. So you have a div and a style which says width is bound to the progress percentage of the model. So whatever the progress is, the width of that block the green part there will be updated accordingly. So and this app is installed. You can remove it. If you want to feel adventurous, there is, you can go to the, sorry, you can go to the console here and see that the app manager object is available as jigna.models.appmanager. So jigna.models is where we save all the Python model proxies and this object is just a regular proxy for this Python object. So you have attributes like available apps, install apps, connected, all that. And all of these attributes are defined lazily. So if you have a deep nested object, we don't serialize it all at once. So you will only serialize what is needed on the HTML. So you can say app zero equal to jigna.installed, sorry, appmanager.installed apps zero, which will give you the first app and then you can simply say from the terminal here, appmanager.startapp, app, sorry, yeah. So it's like a little toy and JavaScript repel for Python objects, which is cool. And you can attach success callbacks. So you saw the slow method call. If you want to call it, you will write jigna.threaded, which will call this slow method in a thread so that your UI does not block. And you have, and so you can attach successor callbacks and also do some event handling. You can check out the repo for that. Of course you can, I know it's hard to port everything instantly. So there has to be good interfacing with existing Qt widgets. So I have demo here, which shows how to embed Qt widgets with jigna. So let's say you have an existing Qt widget. In this case, I have a Maya v plot here, which is a Qt widget. And you can embed it within jigna by saying object widget factory equal to scene.create scene widget. So it takes a factory which will generate the Q widget and it will embed it inside the object tag. So basically since everything is bound, n meridional is an attribute in the model. You change it, the widget automatically updates and everything is wave. And you can also embed jigna widgets within Qt, which is the reverse. So jigna widgets are just like regular Qt widgets. So they will behave, they will give you a regular Qt widget API. So this is an app developed in pure Qt. And if you click on this button, it will embed in that jigna HTML view here and everything will work as before. Browser version. So what do you think this presentation is running on? The same thing, jigna. So when I click on example, I have an example server running, which takes a pool of examples from the repo. And the examples viewer here is basically, it just runs that example from the repository. So you can directly call this method. So I can show you the app store demo in the browser version, but in the lap of time, I'll rather skip to the next demo, which I think is cooler as live IPerthon notebook widgets. So since you can do it on the web as well, but we don't advertise it as a web UI development because you will not solve all the problems that the web world has because it's all local. So, but you can have cool things like IPerthon notebook widgets. So if you have seen IPerthon notebook display HTML or display JavaScript functions, this is similar. So what you can do is you can have nice interactive widgets, HTML widgets, which are live. So here I have a person object and I call displayJignav with this context and this template. Now this shows me this UI, this could be any fancy UI. And if I say name is Freddy, and I want to print the name Freddy here. So this name automatically updates since the UI was updated. So the user, you can have richer stories about your data since you can express everything graphically. Let's say you change it to foo. It automatically updates the value here. I have another example which is matplotlib plot example. So you have a plot and you have a model attribute called scaling factor. And you change the scaling factor, the plot automatically updates. So, and the scaling factor is updated according to the new values. And let's say you later in your IPaitha notebook, you say scaling factor equal to 15. It will update the graph and the entire view everything. So you'll have richer IPaitha notebooks using this. One last example is Mayavi on the web. This is an experimental one. So you'll see a little warning here. But so basically you have a nice WebGL rendering of a Mayavi object and you have a model attribute called n-contour. And if you change the value of the contour, the figure updates and later in the IPaitha notebook if you say equal to three, it updates the, sorry, sorry. Oh yeah, yeah. So plotter.n-contour3 which will update the figure here. So you can have rich stories, rich IPaitha notebooks, this. And that's all for today. The code is on GitHub, everything's open source. There are a lot of examples you can try. And it's on, thank you. Thanks a lot for your talk. Unfortunately, we are very late and there won't be any time for questions and answers. But I'd suggest if you have any questions you can come to him later. Sure, thank you. Thanks a lot.