Hello everybody, I want to introduce you a tenor voice cam with a topic typed HTML in Python.
Get a warm applause.
Hi everyone, thanks for coming to my talk.
Hi, HTML in my Python.
If you know of us cam, I'm the tech lead for Germany at personal colon and today.
I'll talk to you a little bit about why typing is useful and how to get it in your templates.
So, we'll talk about what are the motivations behind even having static typing or behind using hdpi,
which is the tool that we're going to use for this and we're going to see hdpi in action.
And then I'll show you some patterns for success when using it so that it's most effective and useful for you.
I think it's just as important to tell you what we won't talk about today.
So we won't talk about a general overview of typing in Python, we don't have the time for that.
And we won't have any step-by-step guides, but please feel invited to look at the hdpi documentation,
which has lots of examples, maybe also for the web framework that you're already using.
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.
Let's get into the motivations.
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.
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.
We can already discover them in our CI or even locally when running my pie.
And when using hdpi, all of your HTML is just Python.
So we can use existing tools that your editor provides or your language server provides like refactoring, for example.
In particular, we're going to talk about hdpi, which does not introduce a new templating language.
It's Python, as you'll see on the next slide.
Hdpi itself doesn't care about typing.
I think you should care about typing, but if you don't, but still want to use hdpi, that's fine, that works.
And we use it at personal colon serving over 100,000 users in Sweden.
So it is battle tested, it does work, and we trust it enough to use it in production, and maybe you will as well.
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.
I promised you it doesn't introduce a new templating language, but how does it work then?
Obviously, HTML you can't just write it in your Python, and it definitely won't be typed if you do that.
So how does it work?
HTML attributes are specified by parentheses.
So just like you would when you call a method, and children are specified using square brackets, so the get item notation.
Here, I have a little example in the Ripple.
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.
And then we're defining a paragraph here.
As promised, we're using the calling notation to specify HTML attributes in this case the ID.
And we're specifying children using the square brackets in this case it is a string, hello.
And if we print that, so if we ask Python to please turn this interest string, we'll see this comes out as HTML.
HTML offers lots of different shorthands, so what you could also do instead of using the calling notation to specify the ID.
We could also, this shorthand we introduce specifically, you could also use CSS notation to specify all your classes and IDs.
Might be useful for you, might feel natural if you already used to writing CSS.
So here I added a class large as well.
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.
All of the standardized HTML tags, which put into hdpi for you already, so that you get auto completions.
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.
But you're not limited to those, so you can import anything.
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.
Obviously, we don't know about all of the possible HTML tags that your framework or your web components come with.
Well, we employed a little hack, which isn't really even a hack, it's just how Python works.
We defined Dunderget Attra to just give you the element that you ask it for at runtime.
So in this case, we're using a shoulase, large shoulase provides web components.
And hdpi doesn't know about this, but we can use dot notation just as we would expect.
So h dot SL underscore alert, with the attribute open equals true will turn into the SL alert web component as you would expect.
A little thing that you might note here, the equals true is another shorthand, so sometimes your attributes don't have a value.
They just are there and that already means something, so if you set it to true here, this is what will happen.
So as you see, open doesn't have a value itself, it's just there inside the tag.
The implementation, which I simplified a little bit here, also tells you tiny bit about how to go about this.
Underscores in the name that you use in Python are turned into a hyphen to make it a valid HTML tag.
The real implementation does a bit more validation, and if you're other fancy things, you can look at it.
It's not that big, actually, Python itself.
If you go to the documentation, you'll find the source code, of course.
And now we'll move on to show you a few patterns of success.
And it's a short little demo, and we'll start off by showing you the end result.
So what is going to come out of the following examples, so that might help you to follow along a little bit.
And I was thinking of an example where it is very obvious that avoidings takes by using static type checking would be very advisable.
So I don't know, if you have something in consequential like it to do with everything's probably string already anyway.
And if you mess something up, worst case, you need to use a piece of paper.
But when it comes to a medication planner, you don't want to mix up units, for example, like milligrams and grams,
could have pretty big consequences.
And in general, yeah, a medication planner has just a lot more mistakes have a lot more heft.
So we want to use static type checking here to avoid mistakes.
Our medication planner will feature the name of the medication, the active ingredient, the amount, and where the we've taken it.
So let's start out with the data, the domain of our application.
We'll start at the bottom, so we have medication objects, which of course have a name, and also an active ingredient.
And each active ingredient has an amount as specified in decimals.
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.
So really baking that in with static type checking, at least gives me a lot of peace of mind.
And now we're going to write our first component, and how do we do that?
We write a Python method.
So a component, in this case, the medication plan, is given a list of medications.
And nothing about this method is special, except for the fact what it returns, in this case, an HTTP element.
And that in itself isn't even that special, but yeah, the lack of specialists is maybe something to point out here.
We're using the square brackets notation to define children.
So our table has a table adding, which has a name, active ingredient, amount, and taken.
And we're using the call syntax here to specify the scope, so that this table becomes a little bit more accessible.
And we can use native language features.
So at the very bottom, you see that the table body, which, as you saw in the example, has multiple rows,
we're using a Python generator expression to turn our medication list into medication table rows.
And again, the lack of specialists is difficult to point it out, but we, yeah, we put the generator expression there.
And what you would expect to happen will happen.
And it is going to be resolved at the end into the list of table rows.
What does medication to our look like?
Again, it's a Python method.
In this case, it has passed a medication, as you saw on the previous slide.
And here, we are specifying that each table row should output the name, the name of the active ingredient and the amount.
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.
So when I write medication.a, it will suggest active ingredient.
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.
You didn't throw away the typing yet.
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.
So you'll also get the benefits of the correctness assurance.
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.
What I want to point out here is I didn't write the body of this method.
And again, the base template is also just a method, the Python method.
I didn't write it myself.
I copied that from the CSS library I was using, which had a little starter template, which was an HTML.
And I used HTML to HTTP, which comes with HTTP if you install it.
I piped the HTML in and it prints the HTTP Python to use standard out.
I just copied that through it in here.
And then what I did was add the main content section.
So your base template in real life probably has a few more things that you would pass to it than just the main content.
For example, the title would probably be something you want to change depending on the page.
Yeah, and here the main content is passed into the body.
And now we're going to put it all together by turning it into a method that is specific to a framework.
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.
In StarLat, it's Python.
So all of these Python web frameworks will work with it.
And here we call the base method, pass at the main content.
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.
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.
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.
So yeah, if you want to give this a spin, you can take a look at the HTTP documentation by scanning the QR code.
And if you have any questions, you can get in touch using the GitHub discussions, which are linked as well on the documentation.
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.
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.