<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Huzaifa Fareed</title>
    <description>The latest articles on DEV Community by Huzaifa Fareed (@zaifnatra).</description>
    <link>https://dev.to/zaifnatra</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4050251%2F6277050c-56dd-4a1f-b7a8-98edcb62b9ce.jpg</url>
      <title>DEV Community: Huzaifa Fareed</title>
      <link>https://dev.to/zaifnatra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zaifnatra"/>
    <language>en</language>
    <item>
      <title>PE Fellowship - Mid Program Blog</title>
      <dc:creator>Huzaifa Fareed</dc:creator>
      <pubDate>Wed, 29 Jul 2026 02:05:38 +0000</pubDate>
      <link>https://dev.to/zaifnatra/pe-fellowship-mid-program-blog-i50</link>
      <guid>https://dev.to/zaifnatra/pe-fellowship-mid-program-blog-i50</guid>
      <description>&lt;p&gt;I have been part of the Meta x MLH Fellowship for almost 7 weeks now, and it has&lt;br&gt;
been nothing but fun. Meeting people across different regions, time zones, and&lt;br&gt;
backgrounds has been the best part. Alongside building a project to learn&lt;br&gt;
Production Engineering fundamentals, I have picked up a lot of what it means to&lt;br&gt;
think like an SRE: debugging, diagnosing, and reasoning carefully about systems&lt;br&gt;
under failure.&lt;/p&gt;

&lt;p&gt;The project is a Flask portfolio, and it is now a live, HTTPS-secured site&lt;br&gt;
running on my own VPS.&lt;/p&gt;

&lt;p&gt;Live site: &lt;a href="https://huzaifa-pe-portfolio.duckdns.org" rel="noopener noreferrer"&gt;huzaifa-pe-portfolio.duckdns.org&lt;/a&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/zaifnatra/pe-portfolio" rel="noopener noreferrer"&gt;zaifnatra/pe-portfolio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not just a static page: everything renders from Python lists through Jinja&lt;br&gt;
templates, so adding an entry means adding one dictionary instead of a block of&lt;br&gt;
HTML. The nav bar builds itself from the Flask URL map, so a new page shows up in&lt;br&gt;
the menu automatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbu3ja3mvrwwhp3pl9gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbu3ja3mvrwwhp3pl9gt.png" alt="Portfolio homepage showing About Me, Education, Work Experience, and a map of countries visited" width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1z547uaczonxaj744pn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1z547uaczonxaj744pn8.png" alt="Hobbies page showing fishing and hiking photos with captions" width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is also a timeline with a working API, so anyone can leave a post. It is&lt;br&gt;
backed by MariaDB through Peewee, with server-side validation so bad input&lt;br&gt;
returns a 400 instead of a row in the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrh3ryfhl5iwjsq9ji6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrh3ryfhl5iwjsq9ji6a.png" alt="Timeline page with a post form and existing posts showing Gravatar avatars" width="800" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wrote unit tests covering the database model and integration tests that hit the&lt;br&gt;
Flask routes, running against an in-memory SQLite database so the suite never&lt;br&gt;
touches real data. The whole thing is containerized with Docker Compose (Flask +&lt;br&gt;
MariaDB + nginx), with TLS through certbot and rate limiting on the timeline&lt;br&gt;
endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that taught me the most
&lt;/h2&gt;

&lt;p&gt;I rate limited POSTs to the timeline to 1 per minute per IP so nobody could flood&lt;br&gt;
it. Then the timeline page itself started returning 503s.&lt;/p&gt;

&lt;p&gt;The limit was keyed on client IP for every request, not just POSTs, so simply&lt;br&gt;
loading the page burned the quota. The fix was an nginx &lt;code&gt;map&lt;/code&gt; that only sets the&lt;br&gt;
limit key for POST requests and leaves it empty otherwise, since nginx does not&lt;br&gt;
account requests with an empty key:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;map $request_method $timeline_post_key {
    POST    $binary_remote_addr;
    default "";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Small change, but it was the first time I had to reason about a config from the&lt;br&gt;
perspective of "what is this actually counting?" rather than "what did I intend&lt;br&gt;
it to count?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Some of my contributions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/zaifnatra/pe-portfolio/pull/16" rel="noopener noreferrer"&gt;#16 - Database and Flask integration tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zaifnatra/pe-portfolio/pull/14" rel="noopener noreferrer"&gt;#14 - Dynamic menu bar and separate hobbies page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zaifnatra/pe-portfolio/pull/13" rel="noopener noreferrer"&gt;#13 - Refactor static HTML into Jinja templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stack: Flask, Jinja2, Peewee, MariaDB, Docker, nginx.&lt;/p&gt;

&lt;p&gt;Have a look and leave something on&lt;br&gt;
&lt;a href="https://huzaifa-pe-portfolio.duckdns.org/timeline" rel="noopener noreferrer"&gt;the timeline&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mlhfellowship</category>
      <category>productionengineer</category>
      <category>mlh</category>
      <category>meta</category>
    </item>
  </channel>
</rss>
