<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<link href="https://perlmaven.com/atom" rel="self" />
<title>Perl</title>
<id>https://perlmaven.com</id>
<updated>2026-09-08T09:00:02</updated>

  <entry>
    <title>Async, Type-Safe, and Secure: Perl&#39;s Answer to FastAPI</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-09-08T09:00:02Z</updated>
    <pubDate>2026-09-08T09:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/async-type-safe-and-secure-perls-answer-to-fastapi" />
    <id>https://perlmaven.com/async-type-safe-and-secure-perls-answer-to-fastapi</id>
    <content type="html"><![CDATA[<h2 class="title is-4">Description</h2>
<p>This is a practical exploration of PAGI::FastAPI and its latest addition PAGI::FastAPI::Security that introduces you to modern asynchronous Perl web development if you have been using FastAPI in Python asking yourself why this can't be done in Perl. (Spoiler: it can now)</p>
<h2 class="title is-4">Bio</h2>
<p><a href="https://www.linkedin.com/in/mohammadanwar/">Mohammad Sajid Anwar</a> is a CPAN author and White Camel award recipient, recognised for his sustained contributions to the Perl community. He is the author of &quot;Design Patterns in Modern Perl&quot; and the creator of &quot;The Weekly Challenge&quot;, a long-running initiative since 2019. He is an editor of the Perl Weekly newsletter. He speaks regularly at Perl conferences and is an active mentor and contributor across the CPAN ecosystem.</p>
<h2 class="title is-4">Length</h2>
<p>30 min</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/uWkalm3XIW0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<h2 class="title is-4">Participants Geo</h2>
<p>David is a bit of geo-nerd so he collected the places that people joined from:</p>
<p>Ukraine (Kiev), Stockholm, UK (London &amp; Norfolk), USA (New York, Minneapolis, Chicago, Lansing &amp; Miami), Netherlands, Israel (Haifa &amp; Modiin), Dublin, Barcelona, Munich, Hungary (Budapest), Germany and Nigeria (Lagos)!</p>
<h2 class="title is-4">Questions and comments</h2>
<ul>
<li>
<p>Is PAGI or PAGI::FastAPI reverse proxy aware? Like PAGI talking HTTP to HAProxy and HAProxy talks to clients over HTTPS</p>
</li>
<li>
<p>How do I customise the automated docs? E.g. I want to add a description or request examples.</p>
</li>
<li>
<p>What about nested data validation? A flaw in using Type::Tiny for schema validation is that there isn’t a way to model &quot;presence&quot; (afaik, I could be wrong though).</p>
</li>
<li>
<p>I was a huge fan of Data::FormValidator (back in the day) :-)</p>
</li>
<li>
<p>Is event loop an internal detail? Can the program hook to it to wait for other events, e.g. file system?</p>
<ul>
<li>Yes, you can hook into IO::Async::Loop, but it doesn't happen automatically, you would have to use a filesystem module designed to work with IO::Async::Loop.</li>
<li>You need a loop to be async, when you make db/file system calls you can create a promise but that promise lives in the servers event loop (or should to be efficient async) Most async modules have a loop parameter.</li>
<li>This is why Mojo:Pg, Mojo::mysql, etc, were created. Because most things in Perl aren't asynchronous, you have to recreate everything to become async AND because there isn't a single standard event loop you have to design them to work with specific loops (e.g., IO::Async::Loop, Mojo::IOLoop, etc).</li>
</ul>
</li>
<li>
<p>Next to authentication, what about authorization and audit (AAA)?</p>
</li>
<li>
<p>Does PAGI or PAGI::FastAPI allow 'under' like Mojolicous?</p>
</li>
<li>
<p>I wanted to try it right now but unfortunately it's using Perl 5.38 and my system has 5.34. But definitely will try. I dont think its a big issue 🙂</p>
</li>
<li>
<p>Thank you Mohammad. This has been very informative. And thank you for the Weekly Challenge. I have learned much from them.</p>
</li>
<li>
<p>It encourages us to move upwards faster!</p>
</li>
<li>
<p>Very cool Mohammad!</p>
</li>
<li>
<p>Thank you Mohammad. Great work!</p>
</li>
<li>
<p>Thank you, Mohammad! Great thing!</p>
</li>
<li>
<p>Thank you</p>
</li>
<li>
<p>Nice work, Mohammad. Many thanks.</p>
</li>
<li>
<p>Thanks!</p>
</li>
<li>
<p>Mohammad Anwar:	Thank you everyone</p>
</li>
</ul>
<h2 class="title is-4">Transcript</h2>
<p>WEBVTT</p>
<p>1
00:00:00.000 --&gt; 00:00:02.600
Mohammad Anwar: Hi everyone, this is Mohammad. Being recorded.</p>
<p>2
00:00:03.030 --&gt; 00:00:18.229
Gabor Szabo: Okay, so hi everyone. My name is Gabor Szabo. Welcome to the Code Maven channel, if you're watching on YouTube, and to the Perl Maven subsection of it, if you're watching live.</p>
<p>3
00:00:18.380 --&gt; 00:00:30.690
Gabor Szabo: Thank you for joining. It's absolutely great to have so many people interested in this topic, and thank you, Mohammad, for agreeing to giving this presentation.</p>
<p>4
00:00:30.690 --&gt; 00:00:41.350
Gabor Szabo: As I said also earlier, the advantage of being here is that you can ask questions in the chat, and we had a nice</p>
<p>5
00:00:41.350 --&gt; 00:00:53.630
Gabor Szabo: mutual introduction section before, and after the video, we stop the video recording, people can stay around, so next time, those people who are watching the video now, please join the…</p>
<p>6
00:00:53.630 --&gt; 00:01:03.060
Gabor Szabo: the next event… the upcoming events. You can find below the video, you will find a link to the upcoming events, and also for notes</p>
<p>7
00:01:03.060 --&gt; 00:01:13.760
Gabor Szabo: about this event, so check that out. With that said, I think I should welcome Mohammad again, and give you the</p>
<p>8
00:01:13.760 --&gt; 00:01:15.530
Gabor Szabo: stage.</p>
<p>9
00:01:17.030 --&gt; 00:01:20.620
Mohammad Anwar: Thank you, Gabor. Thank you for the opportunity, and…</p>
<p>10
00:01:21.910 --&gt; 00:01:25.369
Mohammad Anwar: Do I need to share my screen first?</p>
<p>11
00:01:29.020 --&gt; 00:01:33.609
Gabor Szabo: You can share the screen, you can introduce yourself as, in any order you like.</p>
<p>12
00:01:34.790 --&gt; 00:01:35.810
Mohammad Anwar: Hi, good.</p>
<p>13
00:01:44.200 --&gt; 00:01:51.699
Gabor Szabo: So while Mohammad is looking for the share, it's usually at the bottom, it's a… But,</p>
<p>14
00:01:51.700 --&gt; 00:01:53.060
Mohammad Anwar: Yeah, I see ya.</p>
<p>15
00:01:53.060 --&gt; 00:01:53.460
Gabor Szabo: Yeah.</p>
<p>16
00:01:53.540 --&gt; 00:01:55.000
Mohammad Anwar: So if you have a…</p>
<p>17
00:01:55.000 --&gt; 00:02:04.940
Gabor Szabo: all kinds of other events, and that's what I mentioned, both in Perl and in other languages, about other languages, so you can find all those sessions.</p>
<p>18
00:02:10.749 --&gt; 00:02:11.299
Mohammad Anwar: Into…</p>
<p>19
00:02:18.210 --&gt; 00:02:21.779
Gabor Szabo: Okay, I can see you now, I can see myself now in the screen.</p>
<p>20
00:02:22.230 --&gt; 00:02:24.530
Mohammad Anwar: So, let me get this.</p>
<p>21
00:02:24.680 --&gt; 00:02:25.800
Gabor Szabo: Yeah, okay.</p>
<p>22
00:02:26.030 --&gt; 00:02:28.549
Mohammad Anwar: Alright, so, let's start this.</p>
<p>23
00:02:30.270 --&gt; 00:02:31.050
Mohammad Anwar: But…</p>
<p>24
00:02:31.670 --&gt; 00:02:38.339
Mohammad Anwar: Thing is, I'm not able to see anything, anybody, but it's alright. You guys can see my screen, right?</p>
<p>25
00:02:38.680 --&gt; 00:02:42.110
Gabor Szabo: We can see your screen, what we'll cover, and…</p>
<p>26
00:02:42.430 --&gt; 00:02:44.660
Gabor Szabo: If you really want, we can see you as well.</p>
<p>27
00:02:44.660 --&gt; 00:02:45.540
Mohammad Anwar: Okay.</p>
<p>28
00:02:45.810 --&gt; 00:02:47.879
Mohammad Anwar: So, yeah, thank you, everybody.</p>
<p>29
00:02:48.040 --&gt; 00:02:57.430
Mohammad Anwar: for… Joining this session, and… Just to give a… the… the background, how and…</p>
<p>30
00:02:57.620 --&gt; 00:03:01.630
Mohammad Anwar: how I started into this PHIE Forest API.</p>
<p>31
00:03:02.150 --&gt; 00:03:02.939
Mohammad Anwar: And, I don't know.</p>
<p>32
00:03:02.940 --&gt; 00:03:09.679
Gabor Szabo: Sorry, Mohammad, there is a note at the top of the screen. You are sharing your entire screen.</p>
<p>33
00:03:10.210 --&gt; 00:03:10.830
Gabor Szabo: Okay.</p>
<p>34
00:03:10.830 --&gt; 00:03:11.360
Mohammad Anwar: Yay.</p>
<p>35
00:03:11.360 --&gt; 00:03:12.550
Gabor Szabo: Can you move that?</p>
<p>36
00:03:12.880 --&gt; 00:03:17.709
Gabor Szabo: Maybe you can click on the minus sign and it will hopefully disappear.</p>
<p>37
00:03:25.120 --&gt; 00:03:26.050
Gabor Szabo: Can you see it?</p>
<p>38
00:03:27.240 --&gt; 00:03:29.650
Mohammad Anwar: I don't see a money sign anywhere.</p>
<p>39
00:03:30.060 --&gt; 00:03:39.590
Gabor Szabo: Okay, well, I'll… it's not a problem right now, so go ahead, and then I'll tell you if it hides something on the screen, okay?</p>
<p>40
00:03:39.740 --&gt; 00:03:40.989
Mohammad Anwar: Okay, fair enough.</p>
<p>41
00:03:42.420 --&gt; 00:03:49.290
Mohammad Anwar: So, the whole idea for this… web framework was. Before…</p>
<p>42
00:03:50.320 --&gt; 00:03:59.690
Mohammad Anwar: this, I was mostly into Donset 2, so whenever I had to build a web framework, I would just go… go to Donset 2, and my…</p>
<p>43
00:03:59.840 --&gt; 00:04:12.540
Mohammad Anwar: job is done. It's… it's… it's quite easy to get… get a site up and running in no time, so… so when I… when I started working on, I believe, a couple of months, a few months ago, on</p>
<p>44
00:04:12.850 --&gt; 00:04:15.499
Mohammad Anwar: DBIX class async.</p>
<p>45
00:04:15.660 --&gt; 00:04:18.500
Mohammad Anwar: And I got into this whole async business.</p>
<p>46
00:04:19.550 --&gt; 00:04:28.600
Mohammad Anwar: And I… every time I looked into my web application, I thought, what if I can turn this into a synchronous web framework?</p>
<p>47
00:04:29.420 --&gt; 00:04:41.370
Mohammad Anwar: And I've been thinking about doing this, and then when somebody introduced me about the Python Fast API, I thought, wow, this is what I should be working on next, after my…</p>
<p>48
00:04:42.210 --&gt; 00:04:50.680
Mohammad Anwar: DBIC async, project. So, even though I'm not, a Python developer, I…</p>
<p>49
00:04:51.190 --&gt; 00:04:59.590
Mohammad Anwar: I know a little bit of Python, I can read Python, I can… but I'm not an expert in Python, but I still want to do</p>
<p>50
00:05:00.050 --&gt; 00:05:08.699
Mohammad Anwar: understand what Fast API is doing, and how I can build in, in my Perl site, port it into Perl.</p>
<p>51
00:05:08.880 --&gt; 00:05:09.830
Mohammad Anwar: So…</p>
<p>52
00:05:09.940 --&gt; 00:05:21.680
Mohammad Anwar: Before that, I was… I had a little bit, like, introduction of PAGI. I'm sure you guys have known what is a synchronous Gateway Interface.</p>
<p>53
00:05:22.330 --&gt; 00:05:29.349
Mohammad Anwar: And the guy who created this specification page is specification, John Napierogosi.</p>
<p>54
00:05:30.420 --&gt; 00:05:38.690
Mohammad Anwar: I had a quick chat with him, and he kind of introduced me. He kind of guided me about the whole.</p>
<p>55
00:05:38.840 --&gt; 00:05:47.380
Mohammad Anwar: specification, and how I can use that as a… as a foundation for my, this fast API port.</p>
<p>56
00:05:47.830 --&gt; 00:05:53.140
Mohammad Anwar: two points, so… so the whole… web framework is…</p>
<p>57
00:05:53.370 --&gt; 00:06:05.300
Mohammad Anwar: is based on… is a foundation on paging. So everything is… be, like, an asynchronous form using paging specifications, so… so that's where it all started, and…</p>
<p>58
00:06:06.510 --&gt; 00:06:13.530
Mohammad Anwar: Even though it… from the feature point of view, I think I have covered almost everything that</p>
<p>59
00:06:14.000 --&gt; 00:06:27.039
Mohammad Anwar: a Python Fast API has, but may not be complete. So, I must have just touched the surface, but not implemented everything that you find in Python FastAPI. So, probably you… if you know</p>
<p>60
00:06:27.110 --&gt; 00:06:34.600
Mohammad Anwar: Python faster, you can probably tell me, okay, what bit is missing, and I probably… and maybe I next… next time, I'll try to…</p>
<p>61
00:06:34.930 --&gt; 00:06:36.509
Mohammad Anwar: Fill the gap, gap.</p>
<p>62
00:06:36.790 --&gt; 00:06:40.549
Mohammad Anwar: So, in this presentation, probably, I'm gonna go through</p>
<p>63
00:06:40.990 --&gt; 00:06:48.630
Mohammad Anwar: this four-part session. First is going to be the foundation, where I'm gonna go through from the…</p>
<p>64
00:06:49.020 --&gt; 00:06:54.580
Mohammad Anwar: Beginning from 0 to… Where we have now, and then we're gonna meet</p>
<p>65
00:06:54.770 --&gt; 00:07:00.630
Mohammad Anwar: with my web framework, where I'm going to show you the basic,</p>
<p>66
00:07:00.950 --&gt; 00:07:04.709
Mohammad Anwar: Routing and everything, and all the dependency injections, and</p>
<p>67
00:07:05.060 --&gt; 00:07:10.190
Mohammad Anwar: And all other web frameworks, common web framework features, and all things.</p>
<p>68
00:07:11.340 --&gt; 00:07:17.469
Mohammad Anwar: And one thing that really… got me into this. It was this security,</p>
<p>69
00:07:17.650 --&gt; 00:07:28.190
Mohammad Anwar: features, security schemes that I had to build because FastAPI has those kind of schemes. So those… those are the interesting things that I'm going to show… share with you.</p>
<p>70
00:07:28.860 --&gt; 00:07:34.810
Mohammad Anwar: And, yeah. So, let's start with the first… So…</p>
<p>71
00:07:37.410 --&gt; 00:07:46.270
Mohammad Anwar: So, basically, so we start with the framework. I'm sure you all know what The framework is… is… Basically.</p>
<p>72
00:07:48.080 --&gt; 00:07:50.889
Mohammad Anwar: You, you get a brother send a request.</p>
<p>73
00:07:51.940 --&gt; 00:07:56.629
Mohammad Anwar: And then somebody accepts those requests and do something, and then you get a result back.</p>
<p>74
00:07:56.790 --&gt; 00:08:00.750
Mohammad Anwar: So this… something in between is your web framework.</p>
<p>75
00:08:01.180 --&gt; 00:08:05.720
Mohammad Anwar: So, this particular web framework, where…</p>
<p>76
00:08:06.380 --&gt; 00:08:12.110
Mohammad Anwar: We are gonna… we… we're gonna deal… work with it. So, basically.</p>
<p>77
00:08:18.020 --&gt; 00:08:18.880
Mohammad Anwar: Bear with me.</p>
<p>78
00:08:23.900 --&gt; 00:08:29.159
Mohammad Anwar: So this whole asynchronous business is where you don't wait for any</p>
<p>79
00:08:30.730 --&gt; 00:08:33.510
Mohammad Anwar: one, request to process. You can…</p>
<p>80
00:08:33.659 --&gt; 00:08:41.679
Mohammad Anwar: fire off a request, and then you can move on to your next task without waiting for it to finish it. So, that's how the whole</p>
<p>81
00:08:43.250 --&gt; 00:08:58.329
Mohammad Anwar: asynchronous web framework is based on. So, this is where the Pagy fast API is going to help us, where you have multiple requests coming through and not waiting for it to finish, and then you move on to your next, actions.</p>
<p>82
00:08:58.520 --&gt; 00:09:00.660
Mohammad Anwar: That's where it's gonna work out.</p>
<p>83
00:09:03.180 --&gt; 00:09:10.219
Mohammad Anwar: So… so… so… so what is Pager? It's this, like, per asynchronous gateway interface, which is… which is…</p>
<p>84
00:09:10.320 --&gt; 00:09:15.880
Mohammad Anwar: Which is like a Act like a socket, where Anybody…</p>
<p>85
00:09:16.590 --&gt; 00:09:19.819
Mohammad Anwar: Speaking, application can talk.</p>
<p>86
00:09:20.250 --&gt; 00:09:26.750
Mohammad Anwar: You can plug into this socket where you can get your applications running.</p>
<p>87
00:09:28.120 --&gt; 00:09:35.530
Mohammad Anwar: And also, you don't actually… create a page directly, and you… framework, like.</p>
<p>88
00:09:35.630 --&gt; 00:09:41.569
Mohammad Anwar: the one I created, the PG files, API can… Help you… Talk to Beijing.</p>
<p>89
00:09:46.580 --&gt; 00:09:50.679
Mohammad Anwar: So… These are the layers. So, first is your…</p>
<p>90
00:09:51.280 --&gt; 00:09:58.550
Mohammad Anwar: routes and business logic, where your application, you create your applications. And then, FastAPI, PG FastAP, where we help you</p>
<p>91
00:09:58.710 --&gt; 00:10:04.140
Mohammad Anwar: Create a routing, and all the type validations, dependency, injections.</p>
<p>92
00:10:04.520 --&gt; 00:10:09.389
Mohammad Anwar: And also, you get, automated documentation, which I'm going to show you.</p>
<p>93
00:10:09.660 --&gt; 00:10:10.610
Mohammad Anwar: Later.</p>
<p>94
00:10:12.410 --&gt; 00:10:20.510
Mohammad Anwar: And the pay… the… the… the whole, Peggy First API are views, There's a…</p>
<p>95
00:10:21.200 --&gt; 00:10:24.320
Mohammad Anwar: there's a Pagy server that comes with Pagy,</p>
<p>96
00:10:24.570 --&gt; 00:10:34.180
Mohammad Anwar: tools, which I've used it, to run my page-y fast API applications, so… That's where I'm gonna see.</p>
<p>97
00:10:37.070 --&gt; 00:10:47.180
Mohammad Anwar: So, this is what… this is how you can just create your Hello World kind of application, web application, if you want to start with the PG Fast API. So, just install it, and then…</p>
<p>98
00:10:47.490 --&gt; 00:10:49.570
Mohammad Anwar: Create an op… create an,</p>
<p>99
00:10:49.960 --&gt; 00:10:52.730
Mohammad Anwar: fast API applications, which is giving</p>
<p>100
00:10:53.490 --&gt; 00:10:59.210
Mohammad Anwar: And start giving a route, and then have a handler where it's a synchronous subroutine.</p>
<p>101
00:10:59.660 --&gt; 00:11:06.200
Mohammad Anwar: Which has a context, you get a context, and then you work… You worked with it.</p>
<p>102
00:11:06.840 --&gt; 00:11:11.320
Mohammad Anwar: context, and then display it. So this is where you get the hello world message.</p>
<p>103
00:11:11.780 --&gt; 00:11:14.680
Mohammad Anwar: And then, once you have this application.</p>
<p>104
00:11:14.910 --&gt; 00:11:21.090
Mohammad Anwar: Run it as a PG server. By default, it listens to 5,000 port.</p>
<p>105
00:11:21.310 --&gt; 00:11:26.060
Mohammad Anwar: And then, this is how you… you access your route.</p>
<p>106
00:11:26.920 --&gt; 00:11:28.150
Mohammad Anwar: Underlooker has.</p>
<p>107
00:11:33.300 --&gt; 00:11:38.510
Mohammad Anwar: Also, when you created a route, You… you can access the…</p>
<p>108
00:11:39.460 --&gt; 00:11:42.990
Mohammad Anwar: The, the parameters, routing parameters.</p>
<p>109
00:11:43.250 --&gt; 00:12:01.399
Mohammad Anwar: Just like this. And then, for example, here you're creating a route where you access a particular specific item, where you have an ID as a unique item ID, and that get access… you can access it in a context. This $C is the page E context.</p>
<p>110
00:12:01.890 --&gt; 00:12:10.159
Mohammad Anwar: excuse me, page context, and then you can figure out what the ID is as a… that you received as a routing parameter.</p>
<p>111
00:12:10.290 --&gt; 00:12:12.850
Mohammad Anwar: So, currently, you can create</p>
<p>112
00:12:13.200 --&gt; 00:12:20.750
Mohammad Anwar: Get, post, boot, patch, and delete, and all these, actions that you can create in your applications.</p>
<p>113
00:12:21.550 --&gt; 00:12:26.269
Mohammad Anwar: And they all are async by default, so it's non-blocking.</p>
<p>114
00:12:32.510 --&gt; 00:12:38.900
Mohammad Anwar: The best thing about it is you get automatic validations, which is…</p>
<p>115
00:12:39.000 --&gt; 00:12:47.269
Mohammad Anwar: built in, so you don't need to do any kind of validations manually, so just… just say, okay, so when you, when you…</p>
<p>116
00:12:47.610 --&gt; 00:12:52.970
Mohammad Anwar: For example, in this example, I'm just saying, I'm posting data.</p>
<p>117
00:12:53.080 --&gt; 00:13:00.600
Mohammad Anwar: something in these actions, and you… you can specify your key, and then your data type.</p>
<p>118
00:13:01.020 --&gt; 00:13:03.660
Mohammad Anwar: For this, we are using type dining.</p>
<p>119
00:13:03.880 --&gt; 00:13:11.780
Mohammad Anwar: For all the… The type validation is done by the type dining, so that's where you get the</p>
<p>120
00:13:12.350 --&gt; 00:13:16.979
Mohammad Anwar: All the type dining, validations you get by default.</p>
<p>121
00:13:20.840 --&gt; 00:13:25.330
Mohammad Anwar: Next is the dependency injection, which is, I think, one of the</p>
<p>122
00:13:26.680 --&gt; 00:13:34.740
Mohammad Anwar: core feature of FastAPI. This was something new for me. I was… I never heard of this before.</p>
<p>123
00:13:34.850 --&gt; 00:13:39.960
Mohammad Anwar: Which I find it very handy in case of, like, for example, when you</p>
<p>124
00:13:41.130 --&gt; 00:13:47.940
Mohammad Anwar: When you have, like, a database connection that you want to inject, and every…</p>
<p>125
00:13:49.630 --&gt; 00:13:53.420
Mohammad Anwar: And then that get injected, and then you can use it instead of…</p>
<p>126
00:13:54.890 --&gt; 00:14:02.299
Mohammad Anwar: Doing, as global, so… so you just declare it once, and then you can inject in every method that you want.</p>
<p>127
00:14:02.650 --&gt; 00:14:08.809
Mohammad Anwar: that object, to be available. So, for example, in… in an application where you…</p>
<p>128
00:14:08.830 --&gt; 00:14:23.570
Mohammad Anwar: you will interact with database every time, so you can just inject that database handle, and then inside the handler, you can access that object, and then start… you can interact with the database. So this is quite handy if you have any kind of</p>
<p>129
00:14:23.950 --&gt; 00:14:27.820
Mohammad Anwar: Code that you want to inject into any Rude.</p>
<p>130
00:14:31.640 --&gt; 00:14:37.670
Mohammad Anwar: And also, You, you get the default, support for the middleware and the cores.</p>
<p>131
00:14:38.460 --&gt; 00:14:42.290
Mohammad Anwar: So, for… if you want to add any middleware you have, you can just…</p>
<p>132
00:14:42.750 --&gt; 00:14:46.029
Mohammad Anwar: Call this add middleware method, and then pass on your</p>
<p>133
00:14:46.150 --&gt; 00:14:50.290
Mohammad Anwar: Your subroutine, and then you can work on</p>
<p>134
00:14:50.530 --&gt; 00:14:57.350
Mohammad Anwar: this add middleware features. Also, similar way, you can add course as well, if you want to have</p>
<p>135
00:14:57.830 --&gt; 00:15:05.369
Mohammad Anwar: anything, just call add course, and then you can pass whatever parameters you need to pass on. So this is how you can add the course.</p>
<p>136
00:15:06.760 --&gt; 00:15:18.190
Mohammad Anwar: I'm just going through the basic thing. If you want a fully functional application, if you go to the CPAN and go to the Peggy First API, there's a… there's a whole bunch of,</p>
<p>137
00:15:19.220 --&gt; 00:15:33.689
Mohammad Anwar: fully functional applications, where I'm going… I've gone through each of these features in detail, so you will have proper… for working core application, where you can see how it actually works in a toy application.</p>
<p>138
00:15:36.580 --&gt; 00:15:38.720
Mohammad Anwar: Next is the rate limiting.</p>
<p>139
00:15:39.030 --&gt; 00:15:43.250
Mohammad Anwar: So, the… the… This kind of thing, I…</p>
<p>140
00:15:43.400 --&gt; 00:15:46.780
Mohammad Anwar: I really liked it, because I remember when</p>
<p>141
00:15:47.530 --&gt; 00:15:54.509
Mohammad Anwar: I was building my personal website where I had to put some rate-limiting things, so…</p>
<p>142
00:15:54.620 --&gt; 00:16:01.010
Mohammad Anwar: I had to do everything by hand. So this… this… this page… page… first API.</p>
<p>143
00:16:01.150 --&gt; 00:16:06.500
Mohammad Anwar: help me not to create a boilerplate code, and then I just have everything</p>
<p>144
00:16:07.390 --&gt; 00:16:16.159
Mohammad Anwar: handy, so you don't need to do anything manually. So just add limit rate, and then you can say… you can add limit rate.</p>
<p>145
00:16:16.320 --&gt; 00:16:17.590
Mohammad Anwar: as, as an,</p>
<p>146
00:16:17.920 --&gt; 00:16:23.129
Mohammad Anwar: Per route, or you can… you can do as an overall as well… as well.</p>
<p>147
00:16:23.300 --&gt; 00:16:30.620
Mohammad Anwar: By default, the limiting is happening in memory, but you can create, other,</p>
<p>148
00:16:30.880 --&gt; 00:16:44.919
Mohammad Anwar: schema as a driver as well. So there are two separate, distributions I've created, one in CHI and one in Redis, if you want… if you want, like, an extended driver for rate limited.</p>
<p>149
00:16:48.260 --&gt; 00:16:49.730
Mohammad Anwar: Next is this.</p>
<p>150
00:16:49.830 --&gt; 00:16:54.680
Mohammad Anwar: CSRRI protection, which is also built in. By default,</p>
<p>151
00:16:54.870 --&gt; 00:16:57.219
Mohammad Anwar: It infosed, like, as a header.</p>
<p>152
00:16:57.930 --&gt; 00:16:58.640
Mohammad Anwar: And…</p>
<p>153
00:16:58.870 --&gt; 00:17:09.579
Mohammad Anwar: Now, also, it's like a double submit cookie, where it… it set the, header, and also set the token, token as well.</p>
<p>154
00:17:11.319 --&gt; 00:17:17.989
Mohammad Anwar: And this is… that's… you just call enable CSRF, and you assign the secret, whatever secret it is.</p>
<p>155
00:17:21.060 --&gt; 00:17:31.759
Mohammad Anwar: This one was… I think it's not part of the FOST API, but I added it because I thought it's quite handy if you're building a web framework and</p>
<p>156
00:17:32.170 --&gt; 00:17:34.149
Mohammad Anwar: To have this boat protection.</p>
<p>157
00:17:34.450 --&gt; 00:17:37.300
Mohammad Anwar: is… is not… Like, a complete,</p>
<p>158
00:17:37.760 --&gt; 00:17:53.640
Mohammad Anwar: implementation. It's just a basic one for now. Probably, I'm going to extend it, as I go. So, you have a difficulty level, and you can assign a boat, environmental variable as a secret, and that is used,</p>
<p>159
00:17:53.860 --&gt; 00:17:54.910
Mohammad Anwar: Every time.</p>
<p>160
00:17:55.160 --&gt; 00:17:56.889
Mohammad Anwar: Somebody tried to attack.</p>
<p>161
00:18:00.190 --&gt; 00:18:04.429
Mohammad Anwar: This is… next is the… the applications,</p>
<p>162
00:18:04.790 --&gt; 00:18:07.469
Mohammad Anwar: Lifespan, where you can just have a…</p>
<p>163
00:18:07.740 --&gt; 00:18:11.930
Mohammad Anwar: on startup and on shutdown. This is quite handy if you…</p>
<p>164
00:18:12.140 --&gt; 00:18:28.930
Mohammad Anwar: If you have, like, a… if you have, database interaction, so mostly, like, on startup, you can just set up your database instance, and on shutdown, you can probably, clean up your database handle once everything is… is done, so you have a nice…</p>
<p>165
00:18:29.470 --&gt; 00:18:36.829
Mohammad Anwar: like, entry point on startup and shutdown. So you can use this, on startup and on shutdown method.</p>
<p>166
00:18:36.970 --&gt; 00:18:39.120
Mohammad Anwar: To do this kind of operation.</p>
<p>167
00:18:42.150 --&gt; 00:18:47.720
Mohammad Anwar: Next is the WebSocket. I have been playing with the WebSocket.</p>
<p>168
00:18:48.110 --&gt; 00:18:58.519
Mohammad Anwar: in the recent past. So, when I was doing this, I thought, why not implement a WebSocket as well on top of this PG FAST API? So, this is where</p>
<p>169
00:18:58.820 --&gt; 00:19:06.020
Mohammad Anwar: Basically, I'm… I'm using, the, there's a Pagy WebSocket, distribution already.</p>
<p>170
00:19:06.360 --&gt; 00:19:16.020
Mohammad Anwar: available from Pagey tools, from the PG specification, so nothing is done here. Everything is delegated to that PG web socket.</p>
<p>171
00:19:16.200 --&gt; 00:19:19.719
Mohammad Anwar: And that's where everything is happening, so you just…</p>
<p>172
00:19:19.830 --&gt; 00:19:25.929
Mohammad Anwar: create a web… call a WebSocket method, and just pass in the handler, and that will do.</p>
<p>173
00:19:26.260 --&gt; 00:19:28.779
Mohammad Anwar: the WebSocket functionality for you.</p>
<p>174
00:19:31.990 --&gt; 00:19:34.860
Mohammad Anwar: Next is SSE, again.</p>
<p>175
00:19:35.310 --&gt; 00:19:40.150
Mohammad Anwar: This is, again, delegated to the PG SSI, which… from Pagey Tools.</p>
<p>176
00:19:40.690 --&gt; 00:19:41.849
Mohammad Anwar: Not from the…</p>
<p>177
00:19:42.150 --&gt; 00:19:48.910
Mohammad Anwar: PG Fast API, but this is quite handy, and you get, by default, if you… if you have</p>
<p>178
00:19:49.130 --&gt; 00:19:59.359
Mohammad Anwar: if you want a SSE functionality in AGFAST API, you just create a method, and then root, and then you provide a handler where you can</p>
<p>179
00:19:59.460 --&gt; 00:20:03.559
Mohammad Anwar: do all kind of SSE-related operations inside this handler.</p>
<p>180
00:20:03.740 --&gt; 00:20:06.499
Mohammad Anwar: As an asynchronous, mode.</p>
<p>181
00:20:09.910 --&gt; 00:20:27.520
Mohammad Anwar: this is something, I… was not 100% sure, but then, after talking to John, the creator of Pengie, and I thought, okay, basically, I did… I don't want to keep, like, a…</p>
<p>182
00:20:27.660 --&gt; 00:20:28.610
Mohammad Anwar: Later, yes.</p>
<p>183
00:20:29.480 --&gt; 00:20:33.680
Mohammad Anwar: Basic… I didn't want to have, like, a proper…</p>
<p>184
00:20:34.280 --&gt; 00:20:43.400
Mohammad Anwar: whether to use a feature I.O. or iOSync. So, eventually, we decided that it's better to keep a feature I.O.</p>
<p>185
00:20:43.720 --&gt; 00:20:45.369
Mohammad Anwar: As, as my,</p>
<p>186
00:20:45.670 --&gt; 00:20:56.860
Mohammad Anwar: all the IO sync thingy. So it's… so for all the event loops, everything is dependent on feature I.O. as a baseline.</p>
<p>187
00:20:59.330 --&gt; 00:21:07.900
Mohammad Anwar: are also… with, first, PG Fast API, you get the… by… by default, you get the…</p>
<p>188
00:21:09.100 --&gt; 00:21:13.159
Mohammad Anwar: the documentation, so I get documentation for free.</p>
<p>189
00:21:13.470 --&gt; 00:21:19.820
Mohammad Anwar: And… just get a slash docs and slash open API JSON you get by default.</p>
<p>190
00:21:20.370 --&gt; 00:21:26.469
Mohammad Anwar: So it's quite handy if you have… if you… you don't need to build the Sawyer interface by hand, you just get</p>
<p>191
00:21:26.850 --&gt; 00:21:27.969
Mohammad Anwar: by default.</p>
<p>192
00:21:31.800 --&gt; 00:21:36.330
Mohammad Anwar: So… Again, as a recap, I'm going to say…</p>
<p>193
00:21:37.650 --&gt; 00:21:44.389
Mohammad Anwar: Why picking FastAPI? Because it's async and it's non-blocking, which is the main features.</p>
<p>194
00:21:44.900 --&gt; 00:21:49.740
Mohammad Anwar: You get a database injection, dependency injection, as a second feature.</p>
<p>195
00:21:50.110 --&gt; 00:21:53.850
Mohammad Anwar: Third is this… is… is it type safe. You can… you can…</p>
<p>196
00:21:54.050 --&gt; 00:21:56.699
Mohammad Anwar: You, you get a default,</p>
<p>197
00:21:56.870 --&gt; 00:21:59.940
Mohammad Anwar: type checks using the TypeTiny module.</p>
<p>198
00:22:00.060 --&gt; 00:22:02.830
Mohammad Anwar: And you get automated documentation.</p>
<p>199
00:22:06.280 --&gt; 00:22:09.390
Mohammad Anwar: So one thing that was missing was this.</p>
<p>200
00:22:09.890 --&gt; 00:22:11.250
Mohammad Anwar: security thing.</p>
<p>201
00:22:11.910 --&gt; 00:22:21.050
Mohammad Anwar: So, so far, we never… we haven't touched the… The security pathway, how to…</p>
<p>202
00:22:21.200 --&gt; 00:22:26.619
Mohammad Anwar: to process the session and everything. So, I really wanted to build in</p>
<p>203
00:22:27.420 --&gt; 00:22:35.899
Mohammad Anwar: the authorizations. For this, I created a separate distribution called PG Fast API Security, which is</p>
<p>204
00:22:37.370 --&gt; 00:22:48.440
Mohammad Anwar: separate distribution outside of PG FastAPI that handles all four common schemes that is in the Python Fast API.</p>
<p>205
00:22:49.290 --&gt; 00:22:57.150
Mohammad Anwar: these are the four… the four schemes that for HTTP bearer, HTTP basic API key, and odd.</p>
<p>206
00:22:57.900 --&gt; 00:22:59.980
Mohammad Anwar: And… These are…</p>
<p>207
00:23:00.590 --&gt; 00:23:07.590
Mohammad Anwar: like, implemented as a separate distribution page for the API security. You can… you get all those</p>
<p>208
00:23:08.000 --&gt; 00:23:11.199
Mohammad Anwar: Four schemes, depending on how you want to use it.</p>
<p>209
00:23:11.660 --&gt; 00:23:18.060
Mohammad Anwar: One thing is there is the… and all… this PG8 Fast API Security, we… we actually</p>
<p>210
00:23:18.540 --&gt; 00:23:28.109
Mohammad Anwar: don't do any verification. It's just… we do this, just extract. We just, find out what is in there, and we just…</p>
<p>211
00:23:30.120 --&gt; 00:23:36.609
Mohammad Anwar: we just fetch the security details and doesn't do any checks. Checking is done by</p>
<p>212
00:23:36.950 --&gt; 00:23:40.030
Mohammad Anwar: The applications on top of it.</p>
<p>213
00:23:41.710 --&gt; 00:23:43.230
Mohammad Anwar: For example, here.</p>
<p>214
00:23:43.370 --&gt; 00:23:43.840
Mohammad Anwar: And then…</p>
<p>215
00:23:43.840 --&gt; 00:23:49.379
Gabor Szabo: Sorry. No, but actually, go on, I'll ask you the questions after.</p>
<p>216
00:23:51.030 --&gt; 00:23:54.390
Mohammad Anwar: Okay, so for example, here in this,</p>
<p>217
00:23:54.750 --&gt; 00:23:58.140
Mohammad Anwar: We're creating a STT bearer scheme.</p>
<p>218
00:23:58.600 --&gt; 00:24:05.059
Mohammad Anwar: as there, and then we inject that, as the token gets injected as dependencies.</p>
<p>219
00:24:05.400 --&gt; 00:24:06.090
Mohammad Anwar: And…</p>
<p>220
00:24:06.410 --&gt; 00:24:20.119
Mohammad Anwar: Here, if you see, we're calling the verify JWT, which is Java token verification, which is outside of this… this framework. So you… this scheme doesn't</p>
<p>221
00:24:20.420 --&gt; 00:24:39.389
Mohammad Anwar: give you this default, you have to create your own verification logic, and… and once you're done, and then you just… if… if it… if there is any issue, you just, you don't die, you actually set the status, and then return the details. That's how you… you handle the…</p>
<p>222
00:24:39.520 --&gt; 00:24:45.460
Mohammad Anwar: any… Error, or any… any issue with the verifications. If anything.</p>
<p>223
00:24:46.330 --&gt; 00:24:48.429
Mohammad Anwar: Anything, needs to be handled.</p>
<p>224
00:24:52.050 --&gt; 00:24:55.499
Gabor Szabo: Okay, maybe now is the time to ask the questions, right?</p>
<p>225
00:24:55.670 --&gt; 00:24:58.319
Gabor Szabo: Because you're in between two topics.</p>
<p>226
00:24:58.430 --&gt; 00:25:06.179
Gabor Szabo: The first question was, is PUGI, I don't know, PAGI? Fast PAGI?</p>
<p>227
00:25:06.350 --&gt; 00:25:09.149
Gabor Szabo: Fast API reverse proxy Aware.</p>
<p>228
00:25:11.220 --&gt; 00:25:12.800
Mohammad Anwar: Right now, no.</p>
<p>229
00:25:14.680 --&gt; 00:25:23.250
Gabor Szabo: So does it mean that you have to put it in front of the… so that that's the front first thing on the internet? So you can't put a reverse proxy in front of it?</p>
<p>230
00:25:24.480 --&gt; 00:25:25.110
Gabor Szabo: Okay.</p>
<p>231
00:25:25.110 --&gt; 00:25:26.589
Mohammad Anwar: At this point, no.</p>
<p>232
00:25:28.700 --&gt; 00:25:37.100
Gabor Szabo: Okay, and then it continues, like, PHEI talking to… talking HTTP to a HA proxy.</p>
<p>233
00:25:37.330 --&gt; 00:25:41.309
Gabor Szabo: And then HAProxy talks to clients over HTTPS.</p>
<p>234
00:25:42.130 --&gt; 00:25:42.720
Mohammad Anwar: Yeah.</p>
<p>235
00:25:43.270 --&gt; 00:25:44.660
Gabor Szabo: If that's possible?</p>
<p>236
00:25:45.930 --&gt; 00:25:50.140
Mohammad Anwar: I've not tried it, maybe I'll give it a try, see if it's possible.</p>
<p>237
00:25:50.520 --&gt; 00:25:51.789
Mohammad Anwar: I think it should be.</p>
<p>238
00:25:53.090 --&gt; 00:25:58.979
Gabor Szabo: Okay. The other question is, how do I customize the automated docs?</p>
<p>239
00:25:59.380 --&gt; 00:26:04.370
Gabor Szabo: E.g, I want to add a description or request example.</p>
<p>240
00:26:05.920 --&gt; 00:26:13.899
Mohammad Anwar: You, you can. I'm going to show you later, where I have created another application where</p>
<p>241
00:26:14.430 --&gt; 00:26:26.560
Mohammad Anwar: I'm going to show you how I've described all the description of the doc where you can see everything, how you can manage, set up everything in an application. I'm going to show you.</p>
<p>242
00:26:26.750 --&gt; 00:26:27.500
Gabor Szabo: Okay.</p>
<p>243
00:26:28.800 --&gt; 00:26:35.569
Mohammad Anwar: So… later, after this, security schemes, I even…</p>
<p>244
00:26:36.080 --&gt; 00:26:38.409
Mohammad Anwar: I added these to type bot.</p>
<p>245
00:26:38.960 --&gt; 00:26:43.639
Mohammad Anwar: and then response model, and all those features. So…</p>
<p>246
00:26:44.390 --&gt; 00:26:51.309
Mohammad Anwar: with this type path, this… either this pagey fast API type path, where you can check the,</p>
<p>247
00:26:51.780 --&gt; 00:27:00.850
Mohammad Anwar: the data type, as well, of the, of the, the root, Root, pathroot.</p>
<p>248
00:27:00.960 --&gt; 00:27:06.700
Mohammad Anwar: So, for example, here I'm checking whether the item ID is integer,</p>
<p>249
00:27:07.410 --&gt; 00:27:14.099
Mohammad Anwar: So this kind of validation can be done as a part of dependency. You can check all those… the key.</p>
<p>250
00:27:14.370 --&gt; 00:27:27.059
Mohammad Anwar: And with the response model, with this, another distribution, which is PG Fast API response model, with this method, with response model, we can add… we can… we can add and make it as a handler, and then</p>
<p>251
00:27:27.390 --&gt; 00:27:33.179
Mohammad Anwar: that further checks can be done, like, for example, ID should be in an integer, name should be in a string.</p>
<p>252
00:27:33.810 --&gt; 00:27:41.220
Mohammad Anwar: So, that can be done as well, with these two handy path and response model distribution package.</p>
<p>253
00:27:45.140 --&gt; 00:27:53.470
Mohammad Anwar: So… The full picture is, basically, you create your application where you define your rules and business logic.</p>
<p>254
00:27:54.010 --&gt; 00:27:58.970
Mohammad Anwar: And then Fast API… page… PG-fast API security.</p>
<p>255
00:27:59.140 --&gt; 00:28:03.209
Mohammad Anwar: Help you with, with the defense and,</p>
<p>256
00:28:03.350 --&gt; 00:28:09.420
Mohammad Anwar: And you can check the… extract the auth key, auth token, everything.</p>
<p>257
00:28:09.530 --&gt; 00:28:18.030
Mohammad Anwar: And then, first API, FastAPI, PG Fast API can help you doing the routing and all validations and injections.</p>
<p>258
00:28:18.370 --&gt; 00:28:20.959
Mohammad Anwar: And finally, with a PG server.</p>
<p>259
00:28:21.410 --&gt; 00:28:26.240
Mohammad Anwar: Your application can start… you can restart running your application there.</p>
<p>260
00:28:29.030 --&gt; 00:28:30.840
Mohammad Anwar: Okay… Food.</p>
<p>261
00:28:31.730 --&gt; 00:28:34.539
Mohammad Anwar: These are my common questions, okay.</p>
<p>262
00:28:35.700 --&gt; 00:28:39.990
Mohammad Anwar: how does this compare? I mean, it's exactly the same thing,</p>
<p>263
00:28:40.260 --&gt; 00:28:45.120
Mohammad Anwar: what I have found out in Python FastAPI. I might have missed something.</p>
<p>264
00:28:45.820 --&gt; 00:28:51.910
Mohammad Anwar: So if you find anything missing, probably you can tell me, and then I can… Fill those gaps.</p>
<p>265
00:28:53.260 --&gt; 00:29:00.130
Mohammad Anwar: And… as I say, maybe you don't need to learn iOS or feature async deeply, so just</p>
<p>266
00:29:01.960 --&gt; 00:29:08.749
Mohammad Anwar: Peggy Sabo owns all the event loops, so everything is done, so you don't need to be worrying anything.</p>
<p>267
00:29:09.870 --&gt; 00:29:12.310
Mohammad Anwar: And… Authentication built in.</p>
<p>268
00:29:12.700 --&gt; 00:29:16.200
Mohammad Anwar: Not by design, but you can create a schema.</p>
<p>269
00:29:16.660 --&gt; 00:29:20.120
Mohammad Anwar: And then use a middleware, and depends.</p>
<p>270
00:29:20.610 --&gt; 00:29:21.950
Mohammad Anwar: For security ads.</p>
<p>271
00:29:26.240 --&gt; 00:29:36.500
Mohammad Anwar: for Perl version, I… the whole, the whole framework are used The latest world-class field… world-class…</p>
<p>272
00:29:37.120 --&gt; 00:29:39.420
Mohammad Anwar: New per class, so, method.</p>
<p>273
00:29:40.280 --&gt; 00:29:49.000
Mohammad Anwar: Feature, experimental feature, or… And for that, I see… the minimum is 538 is what you need, and then…</p>
<p>274
00:29:49.220 --&gt; 00:29:54.289
Mohammad Anwar: That's the minimum is… you can… you have to have to run this PGA.</p>
<p>275
00:29:54.520 --&gt; 00:29:55.710
Mohammad Anwar: Bonsai APA.</p>
<p>276
00:29:57.680 --&gt; 00:30:03.380
Mohammad Anwar: And also for… For rate limit, by default,</p>
<p>277
00:30:03.910 --&gt; 00:30:13.609
Mohammad Anwar: By default, you get an in-memory rate limit, but you can have a ready source CHI as well, if you want to have that backend for rate limit.</p>
<p>278
00:30:15.830 --&gt; 00:30:21.800
Mohammad Anwar: You can, of course, you can ask any bug… you can report your bug to the GitHub repository.</p>
<p>279
00:30:22.020 --&gt; 00:30:29.730
Mohammad Anwar: Which is a pagey-fast API issues, where you can… you can report any issues or any requests you have, yeah.</p>
<p>280
00:30:31.710 --&gt; 00:30:32.679
Mohammad Anwar: the… the name?</p>
<p>281
00:30:32.680 --&gt; 00:30:34.060
Gabor Szabo: Another question.</p>
<p>282
00:30:34.250 --&gt; 00:30:46.500
Gabor Szabo: Sorry, another question. What about nested data validation? A flow in using TypeTiny for schema validation is that there isn't a way to model presence.</p>
<p>283
00:30:47.810 --&gt; 00:30:54.319
Gabor Szabo: As far… if I… as far as I know. I could be wrong, though. That's the com… that's the question.</p>
<p>284
00:30:55.780 --&gt; 00:30:58.190
Mohammad Anwar: So you're saying… sorry, I didn't get the question.</p>
<p>285
00:30:59.050 --&gt; 00:31:03.230
Gabor Szabo: Yeah, so the question is, is there nested data validation?</p>
<p>286
00:31:04.400 --&gt; 00:31:06.910
Mohammad Anwar: No, no, not at the moment, not currently.</p>
<p>287
00:31:07.320 --&gt; 00:31:08.100
Gabor Szabo: Okay.</p>
<p>288
00:31:08.360 --&gt; 00:31:11.490
Mohammad Anwar: So it's just… just key value, key value.</p>
<p>289
00:31:13.040 --&gt; 00:31:18.620
Mohammad Anwar: Not as an estate one right now, but yeah, maybe in future we can support that.</p>
<p>290
00:31:19.950 --&gt; 00:31:26.509
Mohammad Anwar: So, I think the latest version is 1.73 is the latest on CPAN.</p>
<p>291
00:31:27.360 --&gt; 00:31:32.740
Mohammad Anwar: And we… Yes.</p>
<p>292
00:31:34.090 --&gt; 00:31:37.480
Mohammad Anwar: Does the type path replace query? No, it's parameter.</p>
<p>293
00:31:38.270 --&gt; 00:31:41.110
Mohammad Anwar: So you're still using type R, type training.</p>
<p>294
00:31:41.930 --&gt; 00:31:52.819
Mohammad Anwar: Exception Handler? Yes, we have Exception Handler, this package, for… For this… That's it.</p>
<p>295
00:31:55.140 --&gt; 00:31:56.370
Mohammad Anwar: I'm sure.</p>
<p>296
00:31:58.190 --&gt; 00:31:59.440
Mohammad Anwar: to desire them.</p>
<p>297
00:32:01.260 --&gt; 00:32:08.500
Mohammad Anwar: my GitHub repository for Fast API… PG Fast API, and PG Fast API Security.</p>
<p>298
00:32:09.860 --&gt; 00:32:13.110
Mohammad Anwar: And before I cut that, let me…</p>
<p>299
00:32:16.550 --&gt; 00:32:18.810
Mohammad Anwar: Can… can I… can you see my screen?</p>
<p>300
00:32:22.280 --&gt; 00:32:23.720
Mohammad Anwar: Can you see my screen?</p>
<p>301
00:32:23.720 --&gt; 00:32:25.420
Gabor Szabo: Yes, we can see him at the CPU.</p>
<p>302
00:32:25.420 --&gt; 00:32:30.100
Mohammad Anwar: So, this is my, C-pen, metal C-pen, where…</p>
<p>303
00:32:30.240 --&gt; 00:32:32.540
Mohammad Anwar: first API. I'm going to show you</p>
<p>304
00:32:33.440 --&gt; 00:32:36.819
Mohammad Anwar: In my presentation, I've only touched</p>
<p>305
00:32:38.010 --&gt; 00:32:41.909
Mohammad Anwar: this, surface. So, if you want to go in details.</p>
<p>306
00:32:41.910 --&gt; 00:32:53.690
Gabor Szabo: Wait a second, there is a very… another question here. Is the event loop an internal detail? Can the program hook to it to wait for other events, like file system?</p>
<p>307
00:32:59.830 --&gt; 00:33:02.159
Mohammad Anwar: Sorry, I didn't… I didn't understand whatsoever's question.</p>
<p>308
00:33:02.160 --&gt; 00:33:16.559
Gabor Szabo: Yeah, I'm not sure that I understand totally the question, but the question is, is the event loop internal… an internal detail? And then the continuation is, can the program hook to it to wait for other events?</p>
<p>309
00:33:16.840 --&gt; 00:33:17.290
Mohammad Anwar: None.</p>
<p>310
00:33:17.290 --&gt; 00:33:17.730
Gabor Szabo: by, you know.</p>
<p>311
00:33:17.960 --&gt; 00:33:20.840
Mohammad Anwar: N-No, no, no, not at the moment.</p>
<p>312
00:33:21.120 --&gt; 00:33:31.379
Gabor Szabo: No, I mean, okay, so that's strange to me. So if you have a… so it's only async on the website? If you go to the database, it's not a sync?</p>
<p>313
00:33:32.030 --&gt; 00:33:35.059
Mohammad Anwar: It is… no, from the database side, yes, it is a sync, yeah.</p>
<p>314
00:33:35.310 --&gt; 00:33:42.309
Gabor Szabo: And if you want… so also, if you have an async database access… sorry, file system access, that's also async, right?</p>
<p>315
00:33:43.420 --&gt; 00:33:45.010
Mohammad Anwar: Yes, that's true, yeah.</p>
<p>316
00:33:45.010 --&gt; 00:33:49.509
Gabor Szabo: Yeah, so, yeah, but you don't hook into the… into the event loop.</p>
<p>317
00:33:50.020 --&gt; 00:33:50.750
Mohammad Anwar: No, you don.</p>
<p>318
00:33:50.750 --&gt; 00:33:57.969
Gabor Szabo: you can have the… you can have async methods, so I'm not sure I understand the question totally.</p>
<p>319
00:33:58.760 --&gt; 00:34:03.329
Gabor Szabo: But you can… can have… use other async methods, right?</p>
<p>320
00:34:03.840 --&gt; 00:34:09.160
Mohammad Anwar: Yes. So, for example, in this application, you can find it on the…</p>
<p>321
00:34:09.280 --&gt; 00:34:14.239
Mohammad Anwar: in the distribution, where I am… I'm showing,</p>
<p>322
00:34:15.370 --&gt; 00:34:21.460
Mohammad Anwar: So, if… if you can see, I… have a DBIC async,</p>
<p>323
00:34:22.570 --&gt; 00:34:30.899
Mohammad Anwar: handler, class, where I'm having a database connection to a SQLite, and running as an async, Divic.</p>
<p>324
00:34:31.480 --&gt; 00:34:42.260
Mohammad Anwar: And then… I bought… one route which I'm posting data, and second is on Fitching a user ID.</p>
<p>325
00:34:44.310 --&gt; 00:34:48.580
Mohammad Anwar: If I can… maybe I can run this application.</p>
<p>326
00:34:48.909 --&gt; 00:34:50.059
Mohammad Anwar: Maybe not.</p>
<p>327
00:34:50.300 --&gt; 00:34:55.679
Mohammad Anwar: So, so, for example, so these are the examples you can find, And the…</p>
<p>328
00:34:56.080 --&gt; 00:35:00.030
Mohammad Anwar: in the MetaCPN, distribution, for all this.</p>
<p>329
00:35:00.980 --&gt; 00:35:14.800
Mohammad Anwar: CSRF, if you want to look into the details how you can implement CSRF using PG Fast API, you can look into these examples, or if you're looking at the DBK Sync integration, or you can look into the</p>
<p>330
00:35:14.860 --&gt; 00:35:21.229
Mohammad Anwar: the docs, how the docs get created for… that's what the Giver was asking. So, for example, if I…</p>
<p>331
00:35:21.910 --&gt; 00:35:29.170
Mohammad Anwar: Open up here, so… this… this is quite, this is interesting, and I got quite a…</p>
<p>332
00:35:29.470 --&gt; 00:35:45.790
Mohammad Anwar: nice, working example. So you can go into the details in these examples where you can find, exactly how you can implement. There's another example called where you have a rate limit, how you implement the rate limit using the pages.</p>
<p>333
00:35:46.340 --&gt; 00:35:47.540
Mohammad Anwar: first API.</p>
<p>334
00:35:47.670 --&gt; 00:35:53.200
Mohammad Anwar: Similarly, you have an example, complete application where you can implement the SSE.</p>
<p>335
00:35:54.120 --&gt; 00:36:14.030
Mohammad Anwar: and all the webhook examples, WebSocket examples. So, quite a lot of working examples here, where you can explore how this fast API, PG Fast API, can be used to build, like, fully functional applications, where you have an asynchronous, operations.</p>
<p>336
00:36:14.350 --&gt; 00:36:32.030
Mohammad Anwar: and integrate it with the database as well. If the database… database can be asynchronous as well, like what the Gabor was saying. So, you can… you can use… you can use, like, a regular database, or you can use an asynchronous, like, DB class async as well, with your web applications.</p>
<p>337
00:36:32.650 --&gt; 00:36:34.430
Mohammad Anwar: That's why you can use it.</p>
<p>338
00:36:34.710 --&gt; 00:36:38.579
Mohammad Anwar: And if… if you really want to… I've got this,</p>
<p>339
00:36:39.940 --&gt; 00:36:43.149
Mohammad Anwar: my blog web, page, where I…</p>
<p>340
00:36:44.070 --&gt; 00:36:57.510
Mohammad Anwar: gone through individual, features of FastAPI. For example, if you're interested to know how Webhook works with Pagey FastAPI, you can go through individual blog posts where I have webhook, MessageQ,</p>
<p>341
00:36:57.570 --&gt; 00:37:08.879
Mohammad Anwar: API Gateway you can build with FastAPI, and then WebSocket, and also how to integrate your DBIX class async, with the Fast API, PG Fast API. So all…</p>
<p>342
00:37:09.290 --&gt; 00:37:15.169
Mohammad Anwar: This… this blog post, can take you through the details, how you can</p>
<p>343
00:37:15.690 --&gt; 00:37:22.719
Mohammad Anwar: and go through buildup from the scratch using the PG Fast API, these features.</p>
<p>344
00:37:25.120 --&gt; 00:37:27.950
Mohammad Anwar: So, these are… these are the first API.</p>
<p>345
00:37:28.400 --&gt; 00:37:32.530
Mohammad Anwar: And… you have a security where I have…</p>
<p>346
00:37:32.670 --&gt; 00:37:36.590
Mohammad Anwar: these are the schemes currently. We've got API key.</p>
<p>347
00:37:36.820 --&gt; 00:37:40.019
Mohammad Anwar: basics, barrier, and OAuth schemes.</p>
<p>348
00:37:40.920 --&gt; 00:37:48.979
Mohammad Anwar: And again, you have working examples here where you can go through, because S… The examples are…</p>
<p>349
00:37:49.300 --&gt; 00:38:01.890
Mohammad Anwar: It's a complete application, so you can go through how everything can be plugged together to give you a complete application using all these different schemes, security schemes you have.</p>
<p>350
00:38:03.720 --&gt; 00:38:04.680
Mohammad Anwar: So, yeah.</p>
<p>351
00:38:04.880 --&gt; 00:38:07.560
Mohammad Anwar: So that's… that's what I have so far.</p>
<p>352
00:38:07.850 --&gt; 00:38:08.770
Mohammad Anwar: Thank you.</p>
<p>353
00:38:20.690 --&gt; 00:38:23.400
Mohammad Anwar: So that's it for me. Any questions?</p>
<p>354
00:38:24.350 --&gt; 00:38:26.050
Gabor Szabo: Then please stop sharing.</p>
<p>355
00:38:29.140 --&gt; 00:38:30.010
Gabor Szabo: Okay.</p>
<p>356
00:38:30.430 --&gt; 00:38:43.479
Gabor Szabo: If there are questions, please ask in the chat. There are some comments, so I can read them out in the meantime. So there was a comment that, yes, you can hook into the IO async loop.</p>
<p>357
00:38:43.560 --&gt; 00:38:52.090
Gabor Szabo: But it doesn't happen automatically. You would have to use a file system module designed to work with iOSync Loop.</p>
<p>358
00:38:52.700 --&gt; 00:39:09.909
Gabor Szabo: And then, this is why Mojo PG, or Mojo MySQL, and so on, were created, because most things in Perl aren't asynchronous. You have to recreate everything to become a sync, and because there isn't a single standard event loop.</p>
<p>359
00:39:09.910 --&gt; 00:39:18.109
Gabor Szabo: You have to design them to work with the specific loops, for example, the IO async loop, or the module I.O. loop, and so on.</p>
<p>360
00:39:18.610 --&gt; 00:39:33.189
Gabor Szabo: And then another comment here related to this, you need a loop to be a sync. When you make DB file system calls, you can create a promise, but that promise lives in the server's event loop.</p>
<p>361
00:39:33.550 --&gt; 00:39:38.870
Gabor Szabo: Or should be, or should to be efficient, I think.</p>
<p>362
00:39:39.130 --&gt; 00:39:42.630
Gabor Szabo: Most async modules have a loop barometer.</p>
<p>363
00:39:44.120 --&gt; 00:39:45.389
Gabor Szabo: That's the comment.</p>
<p>364
00:39:47.030 --&gt; 00:39:50.960
Mohammad Anwar: I think this… I think this is… Very well explained by…</p>
<p>365
00:39:52.160 --&gt; 00:39:55.589
Mohammad Anwar: Yeah, Newkirk… I don't know how you call it, Newk.</p>
<p>366
00:39:55.590 --&gt; 00:39:57.199
Gabor Szabo: Yeah, yeah, yeah.</p>
<p>367
00:39:57.200 --&gt; 00:39:57.840
Mohammad Anwar: Yeah.</p>
<p>368
00:39:58.120 --&gt; 00:40:07.219
Gabor Szabo: Yeah, we can discuss it afterwards. If there are any more comments that you would like to ask, anything else you would like to say, Mohammad, I think…</p>
<p>369
00:40:08.030 --&gt; 00:40:11.950
Gabor Szabo: From my side, I really enjoyed it. I learned how to</p>
<p>370
00:40:12.330 --&gt; 00:40:27.980
Gabor Szabo: I should now go and play with it. I don't know if I will have the time. I would really like to see a bunch of applications, and some people demoing how to, how to use that. Okay, someone says that ask two questions.</p>
<p>371
00:40:28.340 --&gt; 00:40:30.050
Gabor Szabo: But,</p>
<p>372
00:40:30.940 --&gt; 00:40:31.390
Mohammad Anwar: Yeah, dude.</p>
<p>373
00:40:31.390 --&gt; 00:40:33.159
Gabor Szabo: After that, yeah, yeah, I owe them.</p>
<p>374
00:40:33.160 --&gt; 00:40:37.780
Mohammad Anwar: If you really want to play with it, I would suggest</p>
<p>375
00:40:38.140 --&gt; 00:40:57.390
Mohammad Anwar: to look into the examples that are… that's shipped with the distributions. They are quite… they're quite a good starting point if you want to explore how to do certain features in using Peggy FastAPI. They are, like, complete applications. Like, it's… it's a toy application, but it's complete.</p>
<p>376
00:40:57.390 --&gt; 00:41:08.980
Mohammad Anwar: So you get to know exactly how to… to bring in all the features that are supported by the Pagey Fast API, and how you can plug in each other, and then you get a final, like, feature function.</p>
<p>377
00:41:09.020 --&gt; 00:41:09.610
Mohammad Anwar: So, yeah.</p>
<p>378
00:41:09.610 --&gt; 00:41:16.390
Gabor Szabo: I sort of meant, like, real-world application deployed, making tons of money.</p>
<p>379
00:41:16.650 --&gt; 00:41:22.390
Gabor Szabo: That's what I meant. Not just examples, but that's a good start.</p>
<p>380
00:41:24.420 --&gt; 00:41:29.920
Gabor Szabo: I'm just calling for all the other people who are here, so…</p>
<p>381
00:41:30.450 --&gt; 00:41:39.230
Gabor Szabo: Okay, maybe I missed those questions. Next to authentication, what about authorization and audit AA? That's another question.</p>
<p>382
00:41:39.790 --&gt; 00:41:45.389
Gabor Szabo: Next to authentication, what about authorization and audit?</p>
<p>383
00:41:46.920 --&gt; 00:41:53.539
Mohammad Anwar: Okay, so… Is, right now, we don't do that.</p>
<p>384
00:41:53.750 --&gt; 00:41:57.420
Mohammad Anwar: We're also only doing authentication, not authorization at the moment.</p>
<p>385
00:41:59.190 --&gt; 00:42:07.140
Gabor Szabo: Okay, and does PAGI or PAGI FastAPI allow under, like in modularysis? There's an under…</p>
<p>386
00:42:07.420 --&gt; 00:42:09.849
Gabor Szabo: I don't know, it's method or whatever, it's a feature.</p>
<p>387
00:42:11.180 --&gt; 00:42:17.369
Mohammad Anwar: I've not… I've not tried it. I don't know whether it's gonna… how it's gonna behave. I have to try, see if…</p>
<p>388
00:42:20.540 --&gt; 00:42:25.860
Gabor Szabo: Okay, then someone is, has a 538, and so…</p>
<p>389
00:42:25.860 --&gt; 00:42:26.470
Mohammad Anwar: Yeah.</p>
<p>390
00:42:26.470 --&gt; 00:42:27.400
Gabor Szabo: They can't use it.</p>
<p>391
00:42:27.400 --&gt; 00:42:35.470
Mohammad Anwar: I don't know, I don't know why I picked 538, it's just because I want to try the new class syntax.</p>
<p>392
00:42:35.940 --&gt; 00:42:36.690
Mohammad Anwar: I mean…</p>
<p>393
00:42:36.690 --&gt; 00:42:56.630
Gabor Szabo: It shouldn't be a big issue at the end. You can use Docker if you just want to make a totally isolated version of Perl that you can get rid of easily. I have this Docker image that I use for all the things that I play with.</p>
<p>394
00:42:57.090 --&gt; 00:43:03.399
Gabor Szabo: when I play with various things with Sperm, so they will be separated from my regular.</p>
<p>395
00:43:03.400 --&gt; 00:43:14.249
Mohammad Anwar: If it becomes a blocker, I'll probably drop this restriction and go back to, like, a regular, like, a piled object, rather than using this new</p>
<p>396
00:43:14.620 --&gt; 00:43:20.040
Mohammad Anwar: shiny Perl class syntax, if that is, like, a big issue.</p>
<p>397
00:43:20.300 --&gt; 00:43:29.749
Mohammad Anwar: It's just for fun, I said, okay, why not? Because I've never used this in my… any of my distributions. So I thought, let's… let's try. So I… I started using this class.</p>
<p>398
00:43:31.590 --&gt; 00:43:32.510
Gabor Szabo: Okay.</p>
<p>399
00:43:32.540 --&gt; 00:43:55.939
Gabor Szabo: Well, thank you very much. I think we can finish the video recording at least now. Thank you very much for this presentation. Those people who are here in the live session, you can stay around after the session is over, after I stop the recording, then I will turn on the videos again, so you can turn on your video and your mic.</p>
<p>400
00:43:55.940 --&gt; 00:44:06.669
Gabor Szabo: And then we can go and have a conversation. And those people who are watching the video, please like it and follow the channel, and below the video, you will find links to future events.</p>
<p>401
00:44:06.670 --&gt; 00:44:16.310
Gabor Szabo: And also for details about this event that links and whatever, for example, to the profile of Mohammad, in case you would like to get in touch with him.</p>
<p>402
00:44:17.790 --&gt; 00:44:19.019
Gabor Szabo: Thank you very much.</p>
<p>403
00:44:20.590 --&gt; 00:44:31.880
Mohammad Anwar: Thank you, everybody, thank you. As I said, I was nervous when I saw so many people register, and you could tell from my presentation, I did.</p>
<p>404
00:44:32.000 --&gt; 00:44:32.920
Mohammad Anwar: Pause.</p>
<p>405
00:44:33.140 --&gt; 00:44:35.880
Mohammad Anwar: And I was… you can tell I was quite…</p>
<p>406
00:44:36.100 --&gt; 00:44:42.510
Mohammad Anwar: having anxiety, I mean, I didn't know what I'm talking about, but… Very fair, brother.</p>
<p>407
00:44:42.580 --&gt; 00:44:45.670
Gabor Szabo: It worked well. Thank you very much. Goodbye for everyone.</p>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Punk: Perl MVC, compiled at boot</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-08-12T11:00:02Z</updated>
    <pubDate>2026-08-12T11:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/punk-perl-mvc-compiled-at-boot" />
    <id>https://perlmaven.com/punk-perl-mvc-compiled-at-boot</id>
    <content type="html"><![CDATA[<h2 class="title is-4">Description:</h2>
<p>In this presentation we will dive into the <a href="https://punkperl.com">Punk</a> ecosystem: an open source MVC web framework with first class openAPI integration, template engine, job queue, json codec, non blocking data layer and http client all built on a highly optimised event-loop web server.</p>
<h2 class="title is-4">Bio:</h2>
<p><a href="https://www.linkedin.com/in/lnation--/">Robert Acock</a> (<a href="https://metacpan.org/author/LNATION">LNATION</a>) is a CPAN author with over 250 contributions. They run their own contracting company, LNATION LTD, which also recently launched <a href="https://openapi-proxy.com">OpenAPI Proxy</a>. They like to experiment with C/XS, writing Perl as fast as it can be.</p>
<h2 class="title is-4">Length</h2>
<p>1 hour</p>
<p><a class="button is-primary" href="https://luma.com/o4k2uute">register</a></p>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>MCP - Model Context Protocol in Perl: From Web App to AI Tools with Dave Cross</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-08-06T16:40:02Z</updated>
    <pubDate>2026-08-06T16:40:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/mcp-model-context-protocol-in-perl-from-web-app-to-ai-tools" />
    <id>https://perlmaven.com/mcp-model-context-protocol-in-perl-from-web-app-to-ai-tools</id>
    <content type="html"><![CDATA[<h2 class="title is-4">Description</h2>
<p>The Model Context Protocol (MCP) has rapidly become the standard way for AI assistants to interact with external applications. But how do you add MCP support to an application that already exists?</p>
<p>In this practical workshop we'll take a real Dancer2 application and add an MCP server that exposes its existing functionality to AI clients. Along the way we'll look at the MCP protocol, JSON-RPC, tool discovery, schema design and request handling, while keeping the implementation cleanly separated from the application's existing business logic.</p>
<p>We'll see how a YAML-driven design allows a single source of truth for tool definitions and documentation, and why adding MCP often turns out to be far less work than you'd expect when your application's architecture is already sound.</p>
<p>By the end of the session you'll understand the MCP protocol, know how to implement an MCP server in Perl, and have a design you can adapt to your own applications.</p>
<h2 class="title is-4">Speaker:</h2>
<p><a href="https://www.linkedin.com/in/davorg/">Dave Cross</a> has been writing Perl professionally for more than thirty years. He is the author of several Perl books, including Data Munging with Perl (Manning) and Perl Template Toolkit (O'Reilly), and has been speaking at Perl conferences around the world since the late 1990s.</p>
<p>He builds web applications with Dancer2, contributes to open source, and has recently been exploring how established Perl applications can integrate with modern AI technologies such as the Model Context Protocol (MCP). His Line of Succession website now exposes its data through an MCP server, allowing AI assistants to query Britain's royal succession directly from the site's underlying database.</p>
<p>Dave believes the best way to learn a new technology is to build something real with it, and this workshop is based on exactly that experience.</p>
<h2 class="title is-4">Length</h2>
<p>1 hour</p>
<p><a class="button is-primary" href="https://luma.com/6qqyscbm">register</a></p>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Perl development using Codex by Emmanuel Thouraud</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-08-03T12:40:02Z</updated>
    <pubDate>2026-08-03T12:40:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/perl-development-using-codex-by-emmanuel" />
    <id>https://perlmaven.com/perl-development-using-codex-by-emmanuel</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="https://www.youtube.com/embed/l4kBbjgZntU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<p>This was an ad-hoc presentation and thus we did not have an abstract for it.</p>
<ul>
<li><a href="https://www.linkedin.com/in/emmanuel-thouraud/">Emmanuel Thouraud</a></li>
<li><a href="https://github.com/M-M-M-M/perl-agents-md/">AGENTS.md of Emmanuel</a></li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Setup GitHub Actions with Dist::Zilla, how to advance PRs</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-02-11T08:00:02Z</updated>
    <pubDate>2026-02-11T08:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/github-action-with-dist-zilla-video" />
    <id>https://perlmaven.com/github-action-with-dist-zilla-video</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="https://www.youtube.com/embed/ciQw5DMvRm8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<ul>
<li>
<p>00:00 Introduction</p>
</li>
<li>
<p>01:30 <a href="https://osdc.code-maven.com/perl">OSDC Perl</a>, mention last week</p>
</li>
<li>
<p>03:00 Nikolai Shaplov <a href="https://metacpan.org/author/NATARAJ">NATARAJ</a>, one of our guests author of <a href="https://metacpan.org/dist/Lingua-StarDict-Writer">Lingua-StarDict-Writer</a> on GitLab.</p>
</li>
<li>
<p>04:30 Nikolai explaining his goals about security <a href="https://github.com/radiator-software/p5-net-ssleay/pull/509">memory leak in Net::SSLeay</a></p>
</li>
<li>
<p>05:58 What we did earlier. (Low hanging fruits.)</p>
</li>
<li>
<p>07:00 Let's take a look at the <a href="https://github.com/radiator-software/p5-net-ssleay">repository of Net::SSLeay</a></p>
</li>
<li>
<p>08:00 Try understand what happens in the repository?</p>
</li>
<li>
<p>09:15 A bit of explanation about adopting a module. (co-maintainer, unauthorized uploads)</p>
</li>
<li>
<p>11:00 <a href="https://pause.perl.org/">PAUSE</a></p>
</li>
<li>
<p>15:30 Check the &quot;river&quot; status of the distribution. (reverse dependency)</p>
</li>
<li>
<p>17:20 You can CC-me in your correspondence.</p>
</li>
<li>
<p>18:45 Ask people to review your pull-requests.</p>
</li>
<li>
<p>21:30 Mention the issue with DBIx::Class and how to take over a module.</p>
</li>
<li>
<p>23:50 A bit about the OSDC Perl page.</p>
</li>
<li>
<p>24:55 <a href="https://cpandashboard.com/">CPAN Dashboard</a> and how to add yourself to it.</p>
</li>
<li>
<p>27:40 Show the issues I opened asking author if they are interested in setting up GitHub Actions.</p>
</li>
<li>
<p>29:25 Start working on <a href="https://metacpan.org/dist/Dancer-Template-Mason">Dancer-Template-Mason</a></p>
</li>
<li>
<p>30:00 clone it</p>
</li>
<li>
<p>31:15 perl-tester Docker image.</p>
</li>
<li>
<p>33:30 Installing the dependencies in the Docker container</p>
</li>
<li>
<p>34:40 Create the GitHub Workflow file. Add to git. Push it out to GitHub.</p>
</li>
<li>
<p>40:55 First failure in the CI which is unclear.</p>
</li>
<li>
<p>42:30 Verifying the problem locally.</p>
</li>
<li>
<p>43:10 Open an issue.</p>
</li>
<li>
<p>58:25 Can you talk about dzil and Dist::Zilla?</p>
</li>
<li>
<p>1:02:25 We get back to working in the CI.</p>
</li>
<li>
<p>1:03:25 Add <code>--notest</code> to make installations run faster.</p>
</li>
<li>
<p>1:05:30 Add the git configuration to the CI workflow.</p>
</li>
<li>
<p>1:06:32 Is it safe to use <code>--notest</code> when installing dependencies?</p>
</li>
<li>
<p>1:11:05 git rebase squashing the commits into one commit</p>
</li>
<li>
<p>1:13:35 <code>git push --force</code></p>
</li>
<li>
<p>1:14:10 Send the <a href="https://github.com/yanick/Dancer-Template-Mason/pull/8">pull-request</a>.</p>
</li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Add META data, .gitignore and GitHub Actions to Common::CodingTools</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-02-01T22:00:02Z</updated>
    <pubDate>2026-02-01T22:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/meta-data-and-github-actions-for-common-codingtools-video" />
    <id>https://perlmaven.com/meta-data-and-github-actions-for-common-codingtools-video</id>
    <content type="html"><![CDATA[<p><a href="https://osdc.code-maven.com/perl">OSDC Perl</a>.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/fW3uCc-Vw-g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<ul>
<li>00:00 Introduction to OSDC</li>
<li>01:30 Introducing myself <a href="https://perlmaven.com/">Perl Maven</a>, <a href="https://perlweekly.com/">Perl Weekly</a></li>
<li>02:10 The earlier issues.</li>
<li>03:10 How to select a project to contribute to?</li>
<li>04:50 Chat on <a href="https://osdc.zulipchat.com/">OSDC Zulip</a></li>
<li>06:45 How to select a Perl project?</li>
<li>09:20 <a href="https://cpan-digger.perlmaven.com/">CPAN::Digger</a></li>
<li>10:10 Modules that don't have a link to their VCS.</li>
<li>13:00 Missing CI - GitHub Actions or GitLab Pipeline and Travis-CI.</li>
<li>14:00 Look at Term-ANSIEncode by Richard Kelsch - How to find the repository of this project?</li>
<li>15:38 Switching top look at Common-CodingTools by mistake.</li>
<li>16:30 How MetaCPAN knows where is the repository?</li>
<li>17:52 Clone the repository.</li>
<li>18:15 Use the <a href="https://github.com/szabgab/perl-docker-on-ubuntu/">szabgab/perl</a> Docker container.</li>
<li>22:10 Run <code>perl Makefile.PL</code>, install dependency, run <code>make</code> and <code>make distdir</code>.</li>
<li>23:40 See the generated <code>META.json</code> file.</li>
<li>24:05 Edit the <code>Makefile.PL</code></li>
<li>24:55 Explaining my method of cloning first (calling it <code>origin</code>) and forking later and calling that <code>fork</code>.</li>
<li>27:00 Really edit <code>Makefile.PL</code> and add the <code>META_MERGE</code> section and verify the generated <code>META.json</code> file.</li>
<li>29:00 Create a branch locally. Commit the change.</li>
<li>30:10 Create a fork on GitHub.</li>
<li>31:45 Add the <code>fork</code> as a remote repository and push the branch to it.</li>
<li>33:20 Linking to the PR on the <a href="https://osdc.code-maven.com/perl">OSDC Perl report page</a>.</li>
<li>35:00 Planning to add <code>.gitignore</code> and maybe setting up GitHub Action.</li>
<li>36:00 Start from the <code>main</code> branch, create the <code>.gitignore</code> file.</li>
<li>39:00 Run the tests locally. Set up GitHub Actions to run the tests on every push.</li>
<li>44:00 Editing the GHA configuration file.</li>
<li>48:30 Commit, push to the fork, check the results of GitHub Action in my fork on GitHub.</li>
<li>51:45 Look at the version of the <a href="https://hub.docker.com/r/perldocker/perl-tester/">perldocker/perl-tester</a> Docker image.</li>
<li>54:40 Update list of Perl versions in the CI. See the results on GitHub.</li>
<li>55:30 Show the version number of perl.</li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Perl-related GitHub organizations</title>
    <summary type="html"><![CDATA[A list of GitHub organization containing Perl projects]]></summary>
    <updated>2026-01-31T10:00:02Z</updated>
    <pubDate>2026-01-31T10:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/github-organizations" />
    <id>https://perlmaven.com/github-organizations</id>
    <content type="html"><![CDATA[<p>Most projects are started by a single person in a GitHub repository of that person. Later for various reasons people establish GitHub organizations
and move the projects there.
Sometimes the organization contains a set of sub-projects related to a central project. (e.g. A web framework and its extensions or database access.)
Sometimes it is a collection of projects related to a single topic. (e.g. testing or IDE support.)
Sometimes it is just a random collection of project where people band together in the hope that no project will be left behind. (e.g. the CPAN Authors organization.)</p>
<p>Organizations make it easier to have multiple maintainers and thus ensuring continuity of project, but it might also mean that none of the members really
feel the urge to continue working on something.</p>
<p>In any case, I tried to collect all the Perl-related GitHub organizations.</p>
<p>Hopefully in ABC order...</p>
<ul>
<li>
<p><a href="https://github.com/beyondgrep">Beyond grep</a> - It is mostly for <code>ack</code>, a <code>better grep</code> developed by Andy Lester. No public members. 4 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perl-catalyst/">Catalyst</a> - Catalyst is a web-framework. Its runtime and various extensions are maintained in this organization. 10 members and 39 repositories.</p>
</li>
<li>
<p><a href="https://github.com/cpan-authors/">cpan-authors</a> - A place for CPAN authors to collaborate more easily. 4 members and 9 repositories.</p>
</li>
<li>
<p><a href="https://github.com/davorg-cpan">davorg cpan</a> - Organisation for maintaining Dave Cross's CPAN modules. No public members and 47 repositories.</p>
</li>
<li>
<p><a href="https://github.com/exiftool">ExifTool</a> - No public members. 3 repositories.</p>
</li>
<li>
<p><a href="https://github.com/foswiki">Foswiki</a> - The Foswiki and related projects. 13 members and 649 repositories.</p>
</li>
<li>
<p><a href="https://github.com/gitpan">gitpan</a> - An archive of CPAN modules - 2 members and 5k+ read-only repositories.</p>
</li>
<li>
<p><a href="https://github.com/Kelp-framework">Kelp framework</a> - a web development framework. 1 member and 12 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Metacpan">MetaCPAN</a> - The source of the MetaCPAN site - 9 member and 56 rpositories.</p>
</li>
<li>
<p><a href="https://github.com/mojolicious">Mojolicious</a> - Some Perl and many JavaScript projects. 5 members and 29 repositories.</p>
</li>
<li>
<p><a href="https://github.com/moose/">Moose</a> - Moose,<code>MooseX-*</code>, Moo, etc. 11 members and 69 repositories.</p>
</li>
<li>
<p><a href="https://github.com/netdisco">Netdisco</a> - Netdisco and SNMP-Info projects. 10 members and 14 repositories.</p>
</li>
<li>
<p><a href="https://github.com/PadreIDE">PadreIDE</a> - Padre, the Perl IDE. 13 members and 102 repositories.</p>
</li>
<li>
<p><a href="https://github.com/paracamelus">Paracamelus</a> - No public members. 2 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Perl/">Perl</a> - Perl 5 itself, Docker images, etc. 20 members, 8 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perl-actions/">Perl Actions</a> - GitHub Actions to be used in workflows. 5 members and 9 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perladvent/">Perl Advent Calendar</a> - including the source of <a href="https://perl.com/">perl.com</a>. 3 members and 8 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Perl-Bitcoin">Perl Bitcoin</a> - Perl Bitcoin Toolchain Collective. 3 members and 7 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Perl-Toolchain-Gang">Perl Toolchain Gang</a> - ExtUtils::MakeMaker, Module::Build, etc. 27 members and 41 repositories.</p>
</li>
<li>
<p><a href="https://github.com/PerlToolsTeam/">Perl Tools Team</a> - source of planetperl , perl-ads  etc. No public members. 6 repositories.</p>
</li>
<li>
<p><a href="https://github.com/PerlDancer/">Perl Dancer</a> - Dancer, Dancer2,  many plugins. 30 members and 79 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perltidy">perltidy</a> - Only for Perl::Tidy. No public members. 1 repository.</p>
</li>
<li>
<p><a href="https://github.com/perl5-dbi/">perl5-dbi</a> - DBI, several <code>DBD::*</code> modules, and some related modules. 7 members and 15 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perlorg/">perl.org</a> - also cpan.org and perldoc.perl.org. 3 members and 7 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Perl5">Perl5</a> - DBIx-Class and DBIx-Class-Historic. No public members. 2 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perl5-utils/">perl5-utils</a> - List::MoreUtils, File::ShareDir etc. 2 members and 22 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Perl-Critic">Perl-Critic</a> - PPI, Perl::Critic and related. 7 members and 5 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perl-ide">perl-ide</a> - Perl Development Environments. 26 members and 13 repositories.</p>
</li>
<li>
<p><a href="https://github.com/perl-pod">perl-pod</a> - Pod::Simple, Test::Pod. 1 member and 4 repositories.</p>
</li>
<li>
<p><a href="https://github.com/PerlPkgConfig">PkgConfig</a> - 1 member 1 repository.</p>
</li>
<li>
<p><a href="https://github.com/plack/">plack</a> - psgi-specs, Plack and a few middlewares. 5 members and 7 repositories.</p>
</li>
<li>
<p><a href="https://github.com/RexOps">RexOps</a> - Rex, Rexify and related projects. 1 member and 46 repositories.</p>
</li>
<li>
<p><a href="https://github.com/sqitchers/">Sqitch </a> - Sqitch for Sensible database change management and related projects. No public members. 16 repositories.</p>
</li>
<li>
<p><a href="https://github.com/StrawberryPerl/">StrawberryPerl</a> - The Perl distribution for MS Windows. 4 members and 10 repositories.</p>
</li>
<li>
<p><a href="https://github.com/Test-More">Test-More</a> - Test::Builder, Test::Simple, Test2 etc. - 4 members, 27 repositories.</p>
</li>
<li>
<p><a href="https://github.com/EnlightenedPerlOrganisation">The Enlightened Perl Organisation</a> - Task::Kensho and <code>Task::Kensho::*</code>. 1 member and 1 repository.</p>
</li>
<li>
<p><a href="https://github.com/Thunderhorse-Framework">Thunderhorse Framework</a> - a modern web development framework. No public members. 4 repositories.</p>
</li>
<li>
<p><a href="https://github.com/webmin">Webmin</a> - Webmin is a web-based system administration tool for Unix-like servers. - 5 repositories.</p>
</li>
</ul>
<h2 class="title is-4">Companies</h2>
<p>These are bot Perl-specific GitHub organizations, but some of the repositories are in Perl.</p>
<ul>
<li>
<p><a href="https://github.com/cpanel">cPanel</a> - Open Source Software provided by cPanel. 1 member and 22 repositories.</p>
</li>
<li>
<p><a href="https://github.com/orgs/duckduckgo/">DuckDuckGo</a> - The search engine. 19 members and 122 repositories.</p>
</li>
<li>
<p><a href="https://github.com/fastmail">Fastmail</a> - Open-source software developed at Fastmail. 4 members and 38 repositories.</p>
</li>
<li>
<p><a href="https://github.com/RotherOSS">RotherOSS</a> - Otobo (OTRS fork). No public members. 47 repositories.</p>
</li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Lock and unlock hash using Hash::Util</title>
    <summary type="html"><![CDATA[lock_hash and unlock_hash to avoid accidental changes]]></summary>
    <updated>2026-01-28T18:00:02Z</updated>
    <pubDate>2026-01-28T18:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/lock-and-unlock-hash" />
    <id>https://perlmaven.com/lock-and-unlock-hash</id>
    <content type="html"><![CDATA[<p>If you don't like the <a href="/autovivification">autovivification</a> or simply would like to make sure the code does not accidentally alter a
hash the <a href="https://metacpan.org/pod/Hash::Util">Hash::Util</a> module is for you.</p>
<p>You can <code>lock_hash</code> and later you can <code>unlock_hash</code> if you'd like to make some changes to it.</p>
<p>In this example you can see 3 different actions commented out.
Each one would raise an exception if someone tries to call them on a locked hash.
After we unlock the hash we can execute those actions again.</p>
<p>I tried this both in perl 5.40 and 5.42.</p>
<p><strong><a href="https://github.com/szabgab/perlmaven.com/tree/main/examples/locking_hash.pl">examples/locking_hash.pl</a></strong></p>
<pre><code class="language-perl">use strict;
use warnings;
use feature 'say';

use Hash::Util qw(lock_hash unlock_hash);
use Data::Dumper qw(Dumper);


my %person = (
    fname =&gt; &quot;Foo&quot;,
    lname =&gt; &quot;Bar&quot;,
);
lock_hash(%person);

print Dumper \%person;
print &quot;$person{fname} $person{lname}\n&quot;;
say &quot;fname exists &quot;, exists $person{fname};
say &quot;language exists &quot;, exists $person{language};

# $person{fname} = &quot;Peti&quot;;     # Modification of a read-only value attempted
# delete $person{lname};       # Attempt to delete readonly key 'lname' from a restricted hash
# $person{language} = &quot;Perl&quot;;  # Attempt to access disallowed key 'language' in a restricted hash

unlock_hash(%person);

$person{fname} = &quot;Peti&quot;;     # Modification of a read-only value attempted
delete $person{lname};       # Attempt to delete readonly key 'lname' from a restricted hash
$person{language} = &quot;Perl&quot;;  # Attempt to access disallowed key 'language' in a restricted hash

print Dumper \%person;

</code></pre>
<pre><code class="language-perl">$VAR1 = {
          'lname' =&gt; 'Bar',
          'fname' =&gt; 'Foo'
        };
Foo Bar
fname exists 1
language exists
$VAR1 = {
          'language' =&gt; 'Perl',
          'fname' =&gt; 'Peti'
        };
</code></pre>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Open Source contribution - Perl - Tree-STR, JSON-Lines, and Protocol-Sys-Virt - Setup GitHub Actions</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-01-25T11:00:02Z</updated>
    <pubDate>2026-01-25T11:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/meta-data-and-github-actions-video" />
    <id>https://perlmaven.com/meta-data-and-github-actions-video</id>
    <content type="html"><![CDATA[<p>See <a href="https://osdc.code-maven.com/perl">OSDC Perl</a></p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Y1La0sfcvbI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<ul>
<li>
<p>00:00 Working with Peter Nilsson</p>
</li>
<li>
<p>00:01 Find a module to add GitHub Action to. go to <a href="https://cpan-digger.perlmaven.com/recent">CPAN::Digger recent</a></p>
</li>
<li>
<p>00:10 Found <a href="https://metacpan.org/dist/Tree-STR">Tree-STR</a></p>
</li>
<li>
<p>01:20 Bug in CPAN Digger that shows a GitHub link even if it is broken.</p>
</li>
<li>
<p>01:30 Search for the module name on GitHub.</p>
</li>
<li>
<p>02:25 Verify that the name of the module author is the owner of the GitHub repository.</p>
</li>
<li>
<p>03:25 Edit the Makefile.PL.</p>
</li>
<li>
<p>04:05 Edit the file, fork the repository.</p>
</li>
<li>
<p>05:40 Send the Pull-Request.</p>
</li>
<li>
<p>06:30 Back to CPAN Digger recent to find a module without GitHub Actions.</p>
</li>
<li>
<p>07:20 Add file / Fork repository gives us &quot;unexpected error&quot;.</p>
</li>
<li>
<p>07:45 Direct fork works.</p>
</li>
<li>
<p>08:00 Create the <code>.github/workflows/ci.yml</code> file.</p>
</li>
<li>
<p>09:00 Example <a href="https://perlmaven.com/setup-github-actions">CI yaml file</a> copy it and edit it.</p>
</li>
<li>
<p>14:25 Look at a GitLab CI file for a few seconds.</p>
</li>
<li>
<p>14:58 Commit - change the branch and add a description!</p>
</li>
<li>
<p>17:31 Check if the GitHub Action works properly.</p>
</li>
<li>
<p>18:17 There is a warning while the tests are running.</p>
</li>
<li>
<p>21:20 Opening an <a href="https://github.com/ehuelsmann/perl-protocol-sys-virt/issues/1">issue</a>.</p>
</li>
<li>
<p>21:48 Opening the PR (on the wrong repository).</p>
</li>
<li>
<p>22:30 Linking to output of a CI?</p>
</li>
<li>
<p>23:40 Looking at the file to see the source of the warning.</p>
</li>
<li>
<p>25:25 Assigning an issue? In an open source project?</p>
</li>
<li>
<p>27:15 Edit the already created issue.</p>
</li>
<li>
<p>28:30 USe the Preview!</p>
</li>
<li>
<p>29:20 Sending the <a href="https://github.com/ehuelsmann/perl-protocol-sys-virt/pull/2">Pull-Request</a> to the project owner.</p>
</li>
<li>
<p>31:25 Switching to Jonathan</p>
</li>
<li>
<p>33:10 CPAN Digger recent</p>
</li>
<li>
<p>34:00 Net-SSH-Perl of BDFOY - Testing a networking module is hard and Jonathan is using Windows.</p>
</li>
<li>
<p>35:13 Frequency of update of CPAN Digger.</p>
</li>
<li>
<p>36:00 Looking at our notes to find the GitHub account of the module author LNATION.</p>
</li>
<li>
<p>38:10 Look at the modules of <a href="https://metacpan.org/author/LNATION">LNATION on MetaCPAN</a></p>
</li>
<li>
<p>38:47 Found <a href="https://metacpan.org/pod/JSON::Lines">JSON::Lines</a></p>
</li>
<li>
<p>39:42 Install the dependencies, run the tests, generate test coverage.</p>
</li>
<li>
<p>40:32 Cygwin?</p>
</li>
<li>
<p>42:45 Add Github Action copying it from the previous PR.</p>
</li>
<li>
<p>43:54 <code>META.yml</code> should not be committed as it is a generated file.</p>
</li>
<li>
<p>48:25 I am looking for sponsors!</p>
</li>
<li>
<p>48:50 Create a branch that reflects what we do.</p>
</li>
<li>
<p>51:38 commit the changes</p>
</li>
<li>
<p>53:10 Fork the project on GitHub and setup git remote locally.</p>
</li>
<li>
<p>55:05 <code>git push -u fork add-ci</code></p>
</li>
<li>
<p>57:44 Sending the Pull-Request.</p>
</li>
<li>
<p>59:10 The 7 dwarfs and Snowwhite. My hope is to have a 100 people sending these PRs.</p>
</li>
<li>
<p>1:01:30 Feedback.</p>
</li>
<li>
<p>1:02:10 Did you think this was useful?</p>
</li>
<li>
<p>1:02:55 Would you be willing to tell people you know that you did this and you will do it again?</p>
</li>
<li>
<p>1:03:17 You can put this on your resume. It means you know how to do it.</p>
</li>
<li>
<p>1:04:16 ... and Zoom suddenly closed the recording...</p>
</li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

  <entry>
    <title>Open source contribution - Perl - MIME::Lite - GitHub Actions, test coverage and adding a test</title>
    <summary type="html"><![CDATA[]]></summary>
    <updated>2026-01-25T09:00:02Z</updated>
    <pubDate>2026-01-25T09:00:02Z</pubDate>
    <link rel="alternate" type="text/html" href="https://perlmaven.com/testing-mime-lite-video" />
    <id>https://perlmaven.com/testing-mime-lite-video</id>
    <content type="html"><![CDATA[<p>See <a href="https://osdc.code-maven.com/perl">OSDC Perl</a></p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/XuwHFAyldsA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<ul>
<li>00:00 Introduction and about <a href="https://osdc.code-maven.com/perl">OSDC Perl</a></li>
<li>01:50 <a href="https://metacpan.org/about/sponsors">Sponsors of MetaCPAN</a>, looking at some modules on CPAN.</li>
<li>03:30 The river status</li>
<li>04:10 Picking <a href="https://metacpan.org/dist/MIME-Lite">MIME::Lite</a> and looking at MetaCPAN. Uses RT, has no GitHub Actions.</li>
<li>05:55 Look at the clone of the repository, the 2 remotes and the 3 branches.</li>
<li>06:40 GitHub Actions <a href="https://perlmaven.com/setup-github-actions">Examples</a></li>
<li>08:00 Running the Docker container locally. Install the dependencies.</li>
<li>09:10 Run the tests locally.</li>
<li>09:20 Add the <code>.gitignore</code> file.</li>
<li>10:30 Picking a module from <a href="https://metacpan.org/recent">MetaCPAN recent</a></li>
<li>11:10 <a href="https://cpan-digger.perlmaven.com/recent">CPAN Digger recent</a></li>
<li>12:20 Explaining about pair-programming and workshop.</li>
<li>13:25 CPAN Digger statistics</li>
<li>14:15 Generate test coverage report using <a href="https://metacpan.org/pod/Devel::Cover">Devel::Cover</a>.</li>
<li>17:15 The <code>fold</code> function that is not tested and not even used.</li>
<li>18:39 Wanted to open an issue about <code>fold</code>, but I'll probbaly don't do it on RT.</li>
<li>20:00 Updating the OSDC Perl document with the TODO items.</li>
<li>21:13 Split the packages into files?</li>
<li>22:27 The culture of Open Source contributions.</li>
<li>24:20 Why is the BEGIN line red when the content of the block is green?</li>
<li>27:40 Switching to the <code>long-header</code> branch.</li>
<li>30:40 Finding <code>header_as_string</code> in the documentation.</li>
<li>32:15 Going over the test with the long subject line.</li>
<li>33:54 Let's compare the result to an empty string.</li>
<li>36:15 Switching to <a href="https://metacpan.org/pod/Test::LongString">Test::Longstring</a> to see the difference.</li>
<li>37:35 <a href="https://metacpan.org/pod/Test::Differences">Test::Differences</a> was also suggested.</li>
<li>39:40 Push out the branch and send the Pull-request.</li>
<li>40:35 Did this really increase the test coverage? Let's see it.</li>
<li>43:50 Messing up the explanation about codition coverage.</li>
<li>45:35 The repeated use of the magic number 72.</li>
<li>47:00 Is the output actually correct? Is it according to the standard?</li>
<li>51:45 Discussion about /usr/bin/perl on the first line.</li>
<li>52:45 No version is specified.</li>
<li>55:15 The sentence should be &quot;conforms to the standard&quot;</li>
</ul>
]]></content>
    <author>
      <name></name>
    </author>
  </entry>

</feed>

