WEBVTT

00:00.000 --> 00:15.000
Hello everybody, I want to introduce you a tenor voice cam with a topic typed HTML in Python.

00:15.000 --> 00:22.000
Get a warm applause.

00:22.000 --> 00:25.000
Hi everyone, thanks for coming to my talk.

00:25.000 --> 00:28.000
Hi, HTML in my Python.

00:28.000 --> 00:33.000
If you know of us cam, I'm the tech lead for Germany at personal colon and today.

00:33.000 --> 00:39.000
I'll talk to you a little bit about why typing is useful and how to get it in your templates.

00:39.000 --> 00:46.000
So, we'll talk about what are the motivations behind even having static typing or behind using hdpi,

00:46.000 --> 00:51.000
which is the tool that we're going to use for this and we're going to see hdpi in action.

00:51.000 --> 00:57.000
And then I'll show you some patterns for success when using it so that it's most effective and useful for you.

00:57.000 --> 01:02.000
I think it's just as important to tell you what we won't talk about today.

01:02.000 --> 01:07.000
So we won't talk about a general overview of typing in Python, we don't have the time for that.

01:07.000 --> 01:14.000
And we won't have any step-by-step guides, but please feel invited to look at the hdpi documentation,

01:14.000 --> 01:20.000
which has lots of examples, maybe also for the web framework that you're already using.

01:21.000 --> 01:31.000
And on the first-end page for this talk, you'll find also the demo application as a Python script so you can try it out yourself.

01:31.000 --> 01:33.000
Let's get into the motivations.

01:33.000 --> 01:41.000
I mean, static type checks in and on itself, at least for me, are a motivation running my pie and seeing that no issues were found in all of my source files.

01:41.000 --> 01:48.000
It's pretty awesome. And of course, why it doesn't feel awesome, it means lots of errors that would otherwise only be discovered during runtime.

01:48.000 --> 01:54.000
We can already discover them in our CI or even locally when running my pie.

01:54.000 --> 01:59.000
And when using hdpi, all of your HTML is just Python.

01:59.000 --> 02:09.000
So we can use existing tools that your editor provides or your language server provides like refactoring, for example.

02:09.000 --> 02:16.000
In particular, we're going to talk about hdpi, which does not introduce a new templating language.

02:17.000 --> 02:20.000
It's Python, as you'll see on the next slide.

02:20.000 --> 02:24.000
Hdpi itself doesn't care about typing.

02:24.000 --> 02:31.000
I think you should care about typing, but if you don't, but still want to use hdpi, that's fine, that works.

02:31.000 --> 02:37.000
And we use it at personal colon serving over 100,000 users in Sweden.

02:37.000 --> 02:44.000
So it is battle tested, it does work, and we trust it enough to use it in production, and maybe you will as well.

02:45.000 --> 02:52.000
If you scan the QR code, you'll go to the documentation, but you'll get a second chance that's scanning this at the end of the talk.

02:52.000 --> 02:57.000
I promised you it doesn't introduce a new templating language, but how does it work then?

02:57.000 --> 03:02.000
Obviously, HTML you can't just write it in your Python, and it definitely won't be typed if you do that.

03:02.000 --> 03:05.000
So how does it work?

03:06.000 --> 03:09.000
HTML attributes are specified by parentheses.

03:09.000 --> 03:18.000
So just like you would when you call a method, and children are specified using square brackets, so the get item notation.

03:18.000 --> 03:22.000
Here, I have a little example in the Ripple.

03:22.000 --> 03:32.000
So we first import hdpi as h, which is need a little shorthand if you don't want to import each element on its own, which you could also do.

03:33.000 --> 03:36.000
And then we're defining a paragraph here.

03:36.000 --> 03:43.000
As promised, we're using the calling notation to specify HTML attributes in this case the ID.

03:43.000 --> 03:50.000
And we're specifying children using the square brackets in this case it is a string, hello.

03:50.000 --> 04:00.000
And if we print that, so if we ask Python to please turn this interest string, we'll see this comes out as HTML.

04:00.000 --> 04:10.000
HTML offers lots of different shorthands, so what you could also do instead of using the calling notation to specify the ID.

04:10.000 --> 04:20.000
We could also, this shorthand we introduce specifically, you could also use CSS notation to specify all your classes and IDs.

04:20.000 --> 04:25.000
Might be useful for you, might feel natural if you already used to writing CSS.

04:25.000 --> 04:28.000
So here I added a class large as well.

04:29.000 --> 04:46.000
And I turned the explicit definition of ID equals greeting into Hashtag greeting, pound greeting, so now it becomes the ID anyway, because that's how it's as notation works.

04:46.000 --> 04:54.000
All of the standardized HTML tags, which put into hdpi for you already, so that you get auto completions.

04:54.000 --> 05:04.000
So if you import hdpi sht and then you write h dot and then something your editor will suggest all of the existing standardized HTML elements.

05:04.000 --> 05:08.000
But you're not limited to those, so you can import anything.

05:08.000 --> 05:18.000
You can custom hdml tags, which might be relevant if you want to use web components, so web components aren't a problem at all.

05:18.000 --> 05:26.000
Obviously, we don't know about all of the possible HTML tags that your framework or your web components come with.

05:26.000 --> 05:31.000
Well, we employed a little hack, which isn't really even a hack, it's just how Python works.

05:31.000 --> 05:38.000
We defined Dunderget Attra to just give you the element that you ask it for at runtime.

05:38.000 --> 05:45.000
So in this case, we're using a shoulase, large shoulase provides web components.

05:45.000 --> 05:51.000
And hdpi doesn't know about this, but we can use dot notation just as we would expect.

05:51.000 --> 06:03.000
So h dot SL underscore alert, with the attribute open equals true will turn into the SL alert web component as you would expect.

06:03.000 --> 06:12.000
A little thing that you might note here, the equals true is another shorthand, so sometimes your attributes don't have a value.

06:12.000 --> 06:18.000
They just are there and that already means something, so if you set it to true here, this is what will happen.

06:18.000 --> 06:26.000
So as you see, open doesn't have a value itself, it's just there inside the tag.

06:26.000 --> 06:33.000
The implementation, which I simplified a little bit here, also tells you tiny bit about how to go about this.

06:33.000 --> 06:46.000
Underscores in the name that you use in Python are turned into a hyphen to make it a valid HTML tag.

06:46.000 --> 06:50.000
The real implementation does a bit more validation, and if you're other fancy things, you can look at it.

06:50.000 --> 06:53.000
It's not that big, actually, Python itself.

06:53.000 --> 06:57.000
If you go to the documentation, you'll find the source code, of course.

06:57.000 --> 07:02.000
And now we'll move on to show you a few patterns of success.

07:02.000 --> 07:08.000
And it's a short little demo, and we'll start off by showing you the end result.

07:08.000 --> 07:15.000
So what is going to come out of the following examples, so that might help you to follow along a little bit.

07:15.000 --> 07:23.000
And I was thinking of an example where it is very obvious that avoidings takes by using static type checking would be very advisable.

07:23.000 --> 07:31.000
So I don't know, if you have something in consequential like it to do with everything's probably string already anyway.

07:31.000 --> 07:36.000
And if you mess something up, worst case, you need to use a piece of paper.

07:36.000 --> 07:42.000
But when it comes to a medication planner, you don't want to mix up units, for example, like milligrams and grams,

07:42.000 --> 07:44.000
could have pretty big consequences.

07:44.000 --> 07:50.000
And in general, yeah, a medication planner has just a lot more mistakes have a lot more heft.

07:50.000 --> 07:53.000
So we want to use static type checking here to avoid mistakes.

07:53.000 --> 08:01.000
Our medication planner will feature the name of the medication, the active ingredient, the amount, and where the we've taken it.

08:01.000 --> 08:07.000
So let's start out with the data, the domain of our application.

08:07.000 --> 08:16.000
We'll start at the bottom, so we have medication objects, which of course have a name, and also an active ingredient.

08:17.000 --> 08:22.000
And each active ingredient has an amount as specified in decimals.

08:22.000 --> 08:29.000
And the unit, because we don't want to mix this up, you don't want to take a few grams of some medication that you're supposed to take a few milligrams of.

08:29.000 --> 08:37.000
So really baking that in with static type checking, at least gives me a lot of peace of mind.

08:37.000 --> 08:42.000
And now we're going to write our first component, and how do we do that?

08:42.000 --> 08:44.000
We write a Python method.

08:44.000 --> 08:50.000
So a component, in this case, the medication plan, is given a list of medications.

08:50.000 --> 08:59.000
And nothing about this method is special, except for the fact what it returns, in this case, an HTTP element.

08:59.000 --> 09:07.000
And that in itself isn't even that special, but yeah, the lack of specialists is maybe something to point out here.

09:07.000 --> 09:11.000
We're using the square brackets notation to define children.

09:11.000 --> 09:18.000
So our table has a table adding, which has a name, active ingredient, amount, and taken.

09:18.000 --> 09:26.000
And we're using the call syntax here to specify the scope, so that this table becomes a little bit more accessible.

09:26.000 --> 09:29.000
And we can use native language features.

09:29.000 --> 09:37.000
So at the very bottom, you see that the table body, which, as you saw in the example, has multiple rows,

09:37.000 --> 09:48.000
we're using a Python generator expression to turn our medication list into medication table rows.

09:48.000 --> 09:55.000
And again, the lack of specialists is difficult to point it out, but we, yeah, we put the generator expression there.

09:55.000 --> 09:59.000
And what you would expect to happen will happen.

09:59.000 --> 10:04.000
And it is going to be resolved at the end into the list of table rows.

10:04.000 --> 10:07.000
What does medication to our look like?

10:07.000 --> 10:11.000
Again, it's a Python method.

10:11.000 --> 10:15.000
In this case, it has passed a medication, as you saw on the previous slide.

10:15.000 --> 10:24.000
And here, we are specifying that each table row should output the name, the name of the active ingredient and the amount.

10:24.000 --> 10:33.000
And what you'll note here is when you have nested objects like this, you will really appreciate that all of your data is still its original data.

10:33.000 --> 10:38.000
So when I write medication.a, it will suggest active ingredient.

10:38.000 --> 10:47.000
When I write a dot, it will already suggest name when I'm using the autocompletions of my editor because it knows about the structure of the data.

10:47.000 --> 10:49.000
You didn't throw away the typing yet.

10:49.000 --> 11:01.000
And of course, this again allows my Python check that you're not trying to access some attributes that are accessed or trying to convert something into a string that you can't.

11:01.000 --> 11:07.000
So you'll also get the benefits of the correctness assurance.

11:07.000 --> 11:18.000
And of course, we'll have a base template as well to throw some title into our HTML and the CSS that makes it look a little bit prettier.

11:19.000 --> 11:24.000
What I want to point out here is I didn't write the body of this method.

11:24.000 --> 11:28.000
And again, the base template is also just a method, the Python method.

11:28.000 --> 11:30.000
I didn't write it myself.

11:30.000 --> 11:37.000
I copied that from the CSS library I was using, which had a little starter template, which was an HTML.

11:37.000 --> 11:44.000
And I used HTML to HTTP, which comes with HTTP if you install it.

11:44.000 --> 11:51.000
I piped the HTML in and it prints the HTTP Python to use standard out.

11:51.000 --> 11:53.000
I just copied that through it in here.

11:53.000 --> 11:57.000
And then what I did was add the main content section.

11:57.000 --> 12:05.000
So your base template in real life probably has a few more things that you would pass to it than just the main content.

12:05.000 --> 12:11.000
For example, the title would probably be something you want to change depending on the page.

12:11.000 --> 12:16.000
Yeah, and here the main content is passed into the body.

12:16.000 --> 12:24.000
And now we're going to put it all together by turning it into a method that is specific to a framework.

12:24.000 --> 12:34.000
So what I should note here is everything you've seen before this point was completely agnostic of whether you will use it in Django and past API and Flask or as this example will show.

12:34.000 --> 12:38.000
In StarLat, it's Python.

12:38.000 --> 12:42.000
So all of these Python web frameworks will work with it.

12:42.000 --> 12:50.000
And here we call the base method, pass at the main content.

12:50.000 --> 13:01.000
And in this case it's a list of any HTTP elements, which can be a function call, a method call like the medication plan.

13:01.000 --> 13:14.000
But I can also write h.h1 in here to give the page a title or a paragraph to give the page a little warning that this is actually not medical advice.

13:14.000 --> 13:27.000
And I think it's quite neat that up until this point I could have given you a slide with any web framework in Python because all of this is compatible with each other.

13:27.000 --> 13:35.000
So yeah, if you want to give this a spin, you can take a look at the HTTP documentation by scanning the QR code.

13:35.000 --> 13:43.000
And if you have any questions, you can get in touch using the GitHub discussions, which are linked as well on the documentation.

13:43.000 --> 13:52.000
And if you want to get in touch with me, if you have any questions, I'm Athena Valskamp, you can find all of my socials behind the QR code or on my website.

13:52.000 --> 14:03.000
I'll be right there after the lightning talk. You can follow me on the Fedivers and that's all I have to tell you for today. Thanks for listening.

