Jigna: a seamless Python-JS bridge to create rich HTML UIs for Python apps
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 88 | |
Number of Parts | 119 | |
Author | ||
License | CC Attribution 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/20020 (DOI) | |
Publisher | ||
Release Date | ||
Language | ||
Production Place | Berlin |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
| |
Keywords |
EuroPython 201487 / 119
1
2
9
10
11
13
15
17
22
23
24
27
28
41
44
46
49
56
78
79
80
81
84
97
98
99
101
102
104
105
107
109
110
111
112
113
116
118
119
00:00
Route of administrationSurjective functionUser interfaceUser interfaceCartesian coordinate systemQuicksortComputer animationLecture/Conference
00:36
Newton's law of universal gravitationSoftware developerVacuumData modelBridging (networking)State of matterElectric currentGUI widgetElement (mathematics)CodePixelTime domainDivision (mathematics)Direction (geometry)User interfaceUser interfaceFunction (mathematics)Bridging (networking)Template (C++)DivergenceState of matterOcean currentDistribution (mathematics)VideoconferencingInteractive televisionLevel (video gaming)Software frameworkLatent heatEndliche ModelltheorieoutputWave packetContent (media)Cartesian coordinate systemQuicksortEstimatorSoftware developerMedical imagingTape driveSet (mathematics)IterationMathematicsDomain nameWeb pageVisualization (computer graphics)CASE <Informatik>Library (computing)Model theoryFluid staticsAttribute grammarWeb 2.0Mobile appAuthorizationGUI widgetType theorySocial classDeclarative programmingPlug-in (computing)Web-DesignerInstance (computer science)2 (number)WritingWebsiteTask (computing)CodeGoodness of fitBitElement (mathematics)Archaeological field surveyDebuggerComputer animation
06:04
Time domainData modelDivision (mathematics)Core dumpDot productInterior (topology)CAN busRAIDView (database)Keyboard shortcutCodeVacuumMenu (computing)GUI widgetLibrary (computing)World Wide Web ConsortiumSoftware frameworkMetropolitan area networkTemplate (C++)Computer clusterProxy serverSocial classSynchronizationSystem callError messageElectronic mailing listPrimitive (album)Variable (mathematics)Event horizonDemo (music)Mobile appSuite (music)Stiff equationEndliche ModelltheorieMathematicsAutomationTemplate (C++)State of matterCovering spaceDomain nameScripting languageExtension (kinesiology)Letterpress printingJava appletBitSingle-precision floating-point formatEvent horizonSoftware frameworkCartesian coordinate systemInstance (computer science)Right angleWeb browserProcess (computing)Complete metric spaceLibrary (computing)Electronic mailing listMobile appSystem callInformation securityForcing (mathematics)Hydraulic jumpEuler anglesView (database)Proxy serverObject (grammar)Mathematical optimizationHTTP cookiePredictabilityEstimatorCondition numberFlow separationDifferent (Kate Ryan album)Identity managementArithmetic meanVelocityNumberMixture modelRegular graphString (computer science)Context awarenessUser interfaceCodeKeyboard shortcutSimilarity (geometry)GUI widgetMachine codeFirst-order logicCommunications protocolAttribute grammarMechanism designCross-site scriptingDemo (music)Web 2.0Error messageSoftware developerBridging (networking)Computer animation
11:32
LaptopWindowExecution unitCommunications protocolMobile appDedekind cutSpecial unitary groupPointer (computer programming)Value-added networkCAN busTheory of everythingMaß <Mathematik>Computer iconDot productChi-squared distribution8 (number)Computer-assisted translationInterior (topology)Inclusion mapInstallation artArc (geometry)Division (mathematics)Programmable read-only memoryMotion blurScalable Coherent InterfaceArtificial neural networkComputer iconGroup actionLoop (music)Order (biology)Object (grammar)CodeMobile appSystem callArithmetic progressionDivision (mathematics)Endliche ModelltheorieWeb 2.0Data managementProgrammschleifeClique-widthUser interfaceData storage deviceVideo game consoleMedical imagingTemplate (C++)Attribute grammarSource codeBootingProxy serverIntegrated development environmentIntegerFood energyDisk read-and-write headBit rateMappingWeb serviceObservational studyPoint (geometry)Dependent and independent variablesInternetworkingCausalityGreatest elementMereologyMoment (mathematics)Computer animation
14:45
Dot productComputer iconCAN busChi-squared distributionNewton's law of universal gravitationMobile appInclusion mapUniform resource nameVacuumNormed vector spaceSpecial unitary groupScalable Coherent InterfaceError messageScripting languageMenu (computing)Endliche ModelltheorieProxy serverNatural languageObject (grammar)Data managementBit ratePhysical systemModel theoryMultiplication signAttribute grammarRight angleMobile appThread (computing)WritingRadical (chemistry)Event horizonSystem callDot product
17:02
Data modelProxy serverTime domainPoint (geometry)Template (C++)Module (mathematics)GUI widgetDemo (music)Discrete element methodCASE <Informatik>Cellular automatonConvex setGUI widgetDemosceneObject (grammar)Embedded systemFactory (trading post)Demo (music)PlotterComputer animation
17:50
Error messageCAN busScalable Coherent InterfaceObject (grammar)Einbettung <Mathematik>Interior (topology)Special unitary groupComputer iconMIDIGUI widgetMaxima and minimaSystem on a chipDot productMenu (computing)Object (grammar)Factory (trading post)Attribute grammarEndliche ModelltheorieSinc functionGUI widget
18:19
SynchronizationError messagePrimitive (album)Electronic mailing listVariable (mathematics)Event horizonDemo (music)Mobile appGUI widgetRevision controlWeb browserReverse engineeringRegular graphView (database)Mobile appRepository (publishing)GUI widgetWeb browserSoftware repositoryRevision controlPresentation of a groupEmbedded systemServer (computing)Medical imagingSoftware developerComputer animation
19:17
Einbettung <Mathematik>Dot productInterior (topology)Computer iconVacuumCAN busTotal S.A.Web browserRevision controlDemo (music)LaptopGUI widgetWeb 2.0GUI widgetLaptopRevision controlDemo (music)Data storage deviceWeb browserMobile appSoftware developerSoftware testingEvent horizonComputer animation
19:59
LaptopHookingProjective planeEndliche ModelltheorieTemplate (C++)Attribute grammarGraph (mathematics)Object (grammar)Context awarenessDigitizingPlotterActive contour modelChainVideoconferencingDivisorElectronic visual displayGoodness of fitParameter (computer programming)Scaling (geometry)NumberFunctional (mathematics)Figurate numberArtistic renderingWeb 2.0View (database)LaptopEntire functionInteractive televisionComputer animation
22:49
GUI widgetLaptopSource codeCovering spaceCodeOpen sourceMultiplication signComputer animationLecture/Conference
Transcript: English(auto-generated)
00:15
Okay, so very good afternoon, hope you had a nice lunch.
00:22
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 round of hands, how many people have done any sort of user interface development in Python?
00:40
A lot, okay. So I'll start with a little bit of a personal introduction, I'm a developer at NThought India Mumbai for the last two years, NThought is a company which has a Python distribution called NThought canopy and so I've been working on NThought canopy and NThought training on
01:04
demand which is the online training, online Python training, I've been mostly working on the front end development for that and before this I completed my masters and bachelors in aerospace engineering from IIT, but aerospace engineering to UI development, I don't know
01:23
how it happened. So for Jigna, the two team members are Prabhu Ramachandran, he is also an author of Mayavi, which is a 3D visualisation library and he is a professor at IIT Bombay, was
01:42
also one of my ex-project guides, and Martin Schilvers, who is author of Envisage, a plugin based framework. So what is Jigna, basically it is a bridge which lets you write user interfaces in HTML for your Python models, but why HTML?
02:04
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
02:26
is nice for you to get started, 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
02:43
set that is provided by the toolkit, the code is mainly procedural, so if you were to add widget at this position, which is not really helpful because when you are trying to design something, you want to see it, how it will look, so declarative code is
03:05
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,
03:27
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
03:46
widget set, so 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.
04:02
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.
04:24
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 are mainly limited to the web technologies
04:42
and the desktop applications lag behind. You don't have the kind of richness for the desktop apps. What if you could bridge that gap, which is where Jigna comes in. So let's say you have this domain model, a simple class employee with a name and survey.
05:04
This is, by the way, NTHOR traits. So it has some nice features like automatic notification when the attribute changes and the static declaration of the types and all that. So you can check out NTHOR traits, but this talks not about traits.
05:24
So what I'm trying to say is you have this domain model and what if you could have a 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.
05:42
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.
06:03
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,
06:22
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.
06:40
The HTML template is live, which means whenever the model changes, the HTML changes and the HTML can call methods in the model. The code is declarative, of course, because it's all HTML. And let's face it, developers write the worst user interfaces.
07:01
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.
07:27
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.
07:42
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.
08:01
Other is we are not doing web. So a lot of things that Django and 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.
08:22
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.
08:40
So whenever this employee 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.
09:05
AngularJS makes sure that whenever the JavaScript object changes, it updates the HTML. And for connection between JavaScript to Python, we use Qt's QWebView.
09:22
QWebView is basically just a browser, 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.
09:43
So let's say you want to populate what employee.name is. So AngularJS will ask the JavaScript what is employee.name. And employee.name is a getter function, which will in turn ask from the Python domain model, what is employee.name.
10:01
And Python model will basically tell this is employee.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 trait change.
10:22
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.
10:41
I'll cover some of these things in the demo. For real applications, 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.
11:04
And you want to attach some success callback, error callback, event handling. So let's start this application here.
11:22
Is it too small? OK, so nothing much to read here. 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.
11:41
And an app manager, which has a startup. So in order to show these two apps, there is this is an AngularJS construct, ng-repeat, which is like a for loop for AngularJS. It loops through the app manager installed apps.
12:03
Now app manager installed apps is an attribute of the app 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 and the source, which is the source of the image tag is
12:25
app dot icon URL, which will fetch the icon URL for this app and the app dot name. And you can define the click behavior on the button click, which will call the startup method of the app.
12:41
So basically, a simple dynamic template which talks directly to the Python object. So if I click here, it will start the app. It says hello Berlin. And so and if you you can also install some apps.
13:04
So you go to the store. Now here, when I click down, 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.
13:21
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.
13:44
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 have a fetch action which will update the progress and progress is
14:03
progress is an integer. So in order to show that nicely 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.
14:23
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.
14:40
There is you can go to the you can go to the console here and see that the app manager object is available as Jigna dot models dot app manager.
15:01
So Jigna dot 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.
15:20
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 in the HTML. So you can say app zero equal to Jigna dot installed, sorry,
15:49
app manager dot installed apps zero, which will give you the first app.
16:02
And then you can simply say from the terminal here, app manager dot start app, sorry.
16:23
Yeah. So it's like a little toy in JavaScript for Python objects, which is cool. And you can attach success callbacks.
16:44
So you saw the slow method call. If you want to call it, you will write Jigna dot threaded, which will call this slow method in a thread so that your UI does not block.
17:01
And you have and so you can attach success or callbacks and also do some event handling. You can check out the report for that.
17:22
Um, 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 a demo here which shows how to embed QT widgets with Jigna. So let's say you have an existing QT widget.
17:41
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 dot create scene widget. So it takes a factory which will generate the Q widget, and it will embed it inside
18:04
the object tag. So and so basically, since everything is bound, n-meridional is an attribute in the model, you change it, the widget automatically updates and everything is live.
18:27
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.
18:40
So this is a QT, an app developed in pure QT. And if you click on this button, it will embed that Jigna HTML view here and everything will work as before. Browser version.
19:02
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.
19:25
So you can directly call this method. So I can show you the app store demo in the browser version. But in the lack of time, I'd rather skip to the next demo, which I think is cooler,
19:40
as live Python 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 everything, notebook widgets.
20:03
So if you have seen either the 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.
20:21
And I display I call display Jigna with this context in this template. Now, this shows me this UI. This could be any fancy UI. And if I say name is Freddie, and I want to print the name Freddie here. So this name automatically updates since the UI was updated.
20:40
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.
21:04
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 notebook, you say the scaling factor equal to 15.
21:25
It will update the graph and the entire view everything. So you'll have richer iPad and notebooks using this. One last example is Miami on the web. This is an experimental one.
21:41
So you'll see a little warning here. But so basically, you have nice web GL, the GL rendering of a Miami object. And you have a model attribute called N contour.
22:06
And if you change the value of the contour, the figure updates. And later in the iPad and notebook, if you say equal to three, it updates the sorry.
22:28
Oh, yeah, yeah. So plotter dot plotter dot N contour three, which will update the figure here.
22:41
So you can have rich stories, rich iPad and notebooks. And that's all for today. The code is on GitHub. Everything's open source. There are a lot of examples you can try. Thank you.
23:11
Thanks a lot for your talk. Unfortunately, we are very late and there won't be any time for questions and answers.
23:20
But I'd suggest if you have any questions, you can come to him later. Sure. Thank you. Thanks a lot.