<?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: Anal Jyoti Goswami</title>
    <description>The latest articles on DEV Community by Anal Jyoti Goswami (@analjyotigoswami).</description>
    <link>https://dev.to/analjyotigoswami</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3940175%2F02f8c3ef-e6dc-47b0-9b02-9392bc496702.jpg</url>
      <title>DEV Community: Anal Jyoti Goswami</title>
      <link>https://dev.to/analjyotigoswami</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/analjyotigoswami"/>
    <language>en</language>
    <item>
      <title>The Dirty Secret of Senior Engineers: They Just Got Better at Hiding It</title>
      <dc:creator>Anal Jyoti Goswami</dc:creator>
      <pubDate>Wed, 20 May 2026 19:30:53 +0000</pubDate>
      <link>https://dev.to/analjyotigoswami/the-dirty-secret-of-senior-engineers-they-just-got-better-at-hiding-it-389b</link>
      <guid>https://dev.to/analjyotigoswami/the-dirty-secret-of-senior-engineers-they-just-got-better-at-hiding-it-389b</guid>
      <description>&lt;p&gt;When I was a junior developer, I had a theory about senior engineers.&lt;/p&gt;

&lt;p&gt;I thought they were a different species.&lt;/p&gt;

&lt;p&gt;Not smarter exactly — just wired differently. Like their brain had some extra module installed that mine was still waiting on. They walked into meetings and casually said things like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We should probably use a lazy-loaded module federation setup with a shared Angular state layer.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…with the same energy I use to say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’ll grab coffee.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No hesitation. No visible effort. Just answers appearing fully formed.&lt;/p&gt;

&lt;p&gt;I spent years waiting for my brain to install that module.&lt;/p&gt;

&lt;p&gt;It never did.&lt;/p&gt;

&lt;p&gt;What I eventually realized was much more uncomfortable:&lt;/p&gt;

&lt;p&gt;The module doesn’t exist.&lt;/p&gt;

&lt;p&gt;What I was watching wasn’t certainty. It was a performance of certainty — polished over years until it became indistinguishable from the real thing. And like most junior engineers, I was sitting in the audience learning completely wrong lessons about what competence was supposed to feel like internally.&lt;/p&gt;




&lt;h2&gt;
  
  
  I Didn’t Start as a Developer
&lt;/h2&gt;

&lt;p&gt;My first role wasn’t software engineering.&lt;/p&gt;

&lt;p&gt;It was end-to-end business process testing for SAP systems. Procure-to-pay. Order-to-cash. Walking through workflows and figuring out where systems broke, where configurations failed, or where reality diverged from what people thought the software was doing.&lt;/p&gt;

&lt;p&gt;It was not glamorous work.&lt;/p&gt;

&lt;p&gt;But looking back, it quietly shaped the way I think about systems more than almost anything else in my career.&lt;/p&gt;

&lt;p&gt;Because you cannot test what you do not understand.&lt;/p&gt;

&lt;p&gt;You have to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the process flow&lt;/li&gt;
&lt;li&gt;the data&lt;/li&gt;
&lt;li&gt;the edge cases&lt;/li&gt;
&lt;li&gt;the integrations&lt;/li&gt;
&lt;li&gt;the user behavior&lt;/li&gt;
&lt;li&gt;the failure modes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…all at the same time.&lt;/p&gt;

&lt;p&gt;Otherwise you miss things.&lt;/p&gt;

&lt;p&gt;I never formally became “techno-functional,” but that experience gave me something incredibly valuable early on:&lt;/p&gt;

&lt;p&gt;A testing mindset.&lt;/p&gt;

&lt;p&gt;The habit of thinking about downstream effects, weird user behavior, integration gaps, and all the places reality quietly diverges from architecture diagrams, requirement documents, and happy-path user flows.&lt;/p&gt;

&lt;p&gt;I think that’s part of why I feel technically confident today.&lt;/p&gt;

&lt;p&gt;Not because I always know the answer.&lt;/p&gt;

&lt;p&gt;But because I learned early that systems only really make sense once you understand how they fail.&lt;/p&gt;

&lt;p&gt;At the time though?&lt;/p&gt;

&lt;p&gt;Watching senior developers and architects in meetings, I just felt behind.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Senior Engineering Actually Feels Like
&lt;/h2&gt;

&lt;p&gt;Ten years later, I’m the one in the architecture meetings.&lt;/p&gt;

&lt;p&gt;Lead engineer. Fullstack. AI systems. Cloud infrastructure. Distributed systems. DevOps. Product architecture.&lt;/p&gt;

&lt;p&gt;And I can tell you honestly:&lt;/p&gt;

&lt;p&gt;The performance is still happening.&lt;/p&gt;

&lt;p&gt;I just understand it better now.&lt;/p&gt;

&lt;p&gt;Picture a typical Tuesday.&lt;/p&gt;

&lt;p&gt;We’re designing a platform architecture that will affect deployment decisions, release pipelines, scaling behavior, and operational workflows across multiple teams.&lt;/p&gt;

&lt;p&gt;Someone draws boxes and arrows on a whiteboard.&lt;/p&gt;

&lt;p&gt;Someone says “event streaming.”&lt;/p&gt;

&lt;p&gt;I nod slowly — partly because I’m thinking, partly because I’m buying time.&lt;/p&gt;

&lt;p&gt;Inside my head:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay, the backend itself is fine. But the event routing for this service mesh is going to become a nightmare:&lt;/p&gt;

&lt;p&gt;dead-letter queues,&lt;br&gt;
retry handling,&lt;br&gt;
multiple queues feeding the same service,&lt;br&gt;
eventual consistency issues…&lt;/p&gt;

&lt;p&gt;and I haven’t actually implemented this exact combination before.&lt;/p&gt;

&lt;p&gt;I really hope nobody asks me about the x-requirement implementation right now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not a crisis.&lt;/p&gt;

&lt;p&gt;This is Tuesday.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Part of Code Reviews
&lt;/h2&gt;

&lt;p&gt;Then comes the code review.&lt;/p&gt;

&lt;p&gt;I open a pull request from a junior developer and see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStatus&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UserDTO&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I leave a clean, confident review comment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Maybe use &lt;code&gt;Collectors.toUnmodifiableList()&lt;/code&gt; here to avoid accidental downstream mutation.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Professional. Concise. Senior-engineer-like.&lt;/p&gt;

&lt;p&gt;What the comment does &lt;em&gt;not&lt;/em&gt; show is the actual process that produced it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// What actually happened:

1. Read the code twice
2. Mentally simulated execution flow
3. Opened documentation again
4. Remembered a production issue from years ago
5. Asked AI whether I was overthinking mutability
6. Still not entirely certain this belongs in the service layer
7. Left comment anyway because it feels directionally correct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The feedback improves the code.&lt;/p&gt;

&lt;p&gt;But the process stays invisible.&lt;/p&gt;

&lt;p&gt;And that invisibility does damage.&lt;/p&gt;

&lt;p&gt;Because someone with two years of experience is reading that review and thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Senior engineers already know the answers.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They do not see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the uncertainty&lt;/li&gt;
&lt;li&gt;the memory recall&lt;/li&gt;
&lt;li&gt;the docs tabs&lt;/li&gt;
&lt;li&gt;the debugging history&lt;/li&gt;
&lt;li&gt;the pattern matching&lt;/li&gt;
&lt;li&gt;the verification process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They only see confidence.&lt;/p&gt;

&lt;p&gt;That creates a very different story.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lie Junior Engineers Accidentally Learn
&lt;/h2&gt;

&lt;p&gt;I know this because I was that person.&lt;/p&gt;

&lt;p&gt;Fresh out of testing, moving into fullstack development, watching senior engineers move effortlessly between Angular frontends, backend classes, HANA procedures, internal tables, BSP deployments, and debugging sessions like the entire stack was just sitting neatly inside their heads.&lt;/p&gt;

&lt;p&gt;Every confident review comment.&lt;/p&gt;

&lt;p&gt;Every architecture decision.&lt;/p&gt;

&lt;p&gt;Every:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We should split this into a separate service.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…felt like evidence that I was behind.&lt;/p&gt;

&lt;p&gt;The cross-functional meetings were the worst.&lt;/p&gt;

&lt;p&gt;You’re sitting in rooms where half the people speak business and half speak technology, and somehow the senior engineer appears fluent in both.&lt;/p&gt;

&lt;p&gt;What you don’t see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the preparation beforehand&lt;/li&gt;
&lt;li&gt;the requirement documents they read the night before&lt;/li&gt;
&lt;li&gt;the conversations with product owners&lt;/li&gt;
&lt;li&gt;the internal confusion they resolved privately before the meeting started&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You only see the final polished version.&lt;/p&gt;

&lt;p&gt;There’s actually a name for this phenomenon:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pluralistic ignorance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everyone privately feels uncertain while publicly assuming everyone else is fine.&lt;/p&gt;

&lt;p&gt;Engineering culture accidentally amplifies this.&lt;/p&gt;

&lt;p&gt;Junior engineers stay quiet because senior engineers seem certain.&lt;/p&gt;

&lt;p&gt;Senior engineers stay quiet because they learned that uncertainty should be hidden.&lt;/p&gt;

&lt;p&gt;And eventually the silence itself gets mistaken for competence.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Part Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;The cruelest part is how this gets passed down.&lt;/p&gt;

&lt;p&gt;It’s 2021.&lt;/p&gt;

&lt;p&gt;A mid-level engineer is staring at a brutal production issue.&lt;/p&gt;

&lt;p&gt;A service keeps failing under load for reasons that don’t fully make sense. Memory usage looks normal until suddenly it isn’t. Requests timeout inconsistently. Thread pools behave strangely. Logs are noisy but somehow useless.&lt;/p&gt;

&lt;p&gt;This is still pre-AI.&lt;/p&gt;

&lt;p&gt;Stack Overflow is basically a religious institution at this point.&lt;/p&gt;

&lt;p&gt;So it becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;two days of reading logs&lt;/li&gt;
&lt;li&gt;reproducing failures in sandbox environments&lt;/li&gt;
&lt;li&gt;digging through obscure Stack Overflow posts from 2014&lt;/li&gt;
&lt;li&gt;testing theories nobody else can see&lt;/li&gt;
&lt;li&gt;slowly narrowing uncertainty until something finally clicks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the issue gets fixed.&lt;/p&gt;

&lt;p&gt;The sprint moves on.&lt;/p&gt;

&lt;p&gt;Nobody talks about the confusion beforehand.&lt;/p&gt;

&lt;p&gt;Nobody talks about the dead ends.&lt;/p&gt;

&lt;p&gt;Nobody talks about the panic.&lt;/p&gt;

&lt;p&gt;That part quietly disappears from the story.&lt;/p&gt;

&lt;p&gt;What survives instead is the mythology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Senior engineers see answers faster&lt;/li&gt;
&lt;li&gt;Senior engineers feel less lost&lt;/li&gt;
&lt;li&gt;Senior engineers are naturally confident&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five years later, that same engineer becomes the lead.&lt;/p&gt;

&lt;p&gt;A junior developer looks at them during another production issue, waiting for some signal that confusion is normal.&lt;/p&gt;

&lt;p&gt;But by then the performance has become automatic.&lt;/p&gt;

&lt;p&gt;Not because anyone is malicious.&lt;/p&gt;

&lt;p&gt;Because nobody ever modeled uncertainty honestly for them either.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Actually Helps
&lt;/h2&gt;

&lt;p&gt;The funny thing is that fixing this culture does not require massive organizational change.&lt;/p&gt;

&lt;p&gt;It requires tiny moments of honesty.&lt;/p&gt;

&lt;p&gt;A lead engineer saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m not fully convinced this integration approach will scale the way we think it will. Let’s validate it first.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An architect casually admitting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I had to re-read the event routing docs this morning because I forgot how this edge case behaves.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A code review comment saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Works correctly.&lt;/span&gt;
&lt;span class="c1"&gt;// I'm not entirely convinced this belongs in the service layer though.&lt;/span&gt;
&lt;span class="c1"&gt;// Would like a second opinion.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tiny things.&lt;/p&gt;

&lt;p&gt;But those tiny things change entire team cultures.&lt;/p&gt;

&lt;p&gt;Because the biggest thing junior engineers almost never get to see is this:&lt;/p&gt;

&lt;p&gt;Senior engineers are not people who stopped feeling lost.&lt;/p&gt;

&lt;p&gt;They are people who got better at functioning while lost.&lt;/p&gt;

&lt;p&gt;Better at narrowing uncertainty.&lt;/p&gt;

&lt;p&gt;Better at pattern recognition.&lt;/p&gt;

&lt;p&gt;Better at asking targeted questions.&lt;/p&gt;

&lt;p&gt;Better at surviving the moments where they have absolutely no idea what they’re doing.&lt;/p&gt;

&lt;p&gt;The confidence was never the skill.&lt;/p&gt;

&lt;p&gt;The skill was learning not to panic inside uncertainty.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tags
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;#softwareengineering&lt;/code&gt; &lt;code&gt;#programming&lt;/code&gt; &lt;code&gt;#career&lt;/code&gt; &lt;code&gt;#devops&lt;/code&gt; &lt;code&gt;#webdev&lt;/code&gt; &lt;code&gt;#java&lt;/code&gt; &lt;code&gt;#cloud&lt;/code&gt; &lt;code&gt;#ai&lt;/code&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>career</category>
      <category>computerscience</category>
      <category>developer</category>
    </item>
    <item>
      <title>How the Internet Actually Works: Understanding Client-Server Architecture with Real Code</title>
      <dc:creator>Anal Jyoti Goswami</dc:creator>
      <pubDate>Tue, 19 May 2026 19:27:34 +0000</pubDate>
      <link>https://dev.to/analjyotigoswami/how-the-internet-actually-works-understanding-client-server-architecture-with-real-code-fd1</link>
      <guid>https://dev.to/analjyotigoswami/how-the-internet-actually-works-understanding-client-server-architecture-with-real-code-fd1</guid>
      <description>&lt;h1&gt;
  
  
  How the Internet Actually Works: Understanding Client-Server Architecture with Real Code
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Big Picture: What Happens When You Visit a Website?
&lt;/h2&gt;

&lt;p&gt;Every time you type a URL into your browser and hit Enter, a surprisingly complex chain of events kicks off in the background. Most people never think about it, but understanding this process is the foundation of everything we'll cover in this guide.&lt;/p&gt;

&lt;p&gt;Let's walk through what actually happens when you visit something like &lt;code&gt;https://www.example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Your browser looks up the address&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your computer doesn't understand domain names like &lt;code&gt;www.example.com&lt;/code&gt;. It needs an IP address, which is basically a numerical home address for a server somewhere in the world. To get it, your browser contacts a &lt;strong&gt;DNS (Domain Name System) server&lt;/strong&gt;, which works like a giant phone book for the internet. It translates the human-friendly name into something like &lt;code&gt;93.184.216.34&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Your browser opens a connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that your browser knows the IP address, it reaches out to that server and says "hey, I'd like to talk." This happens using a protocol called &lt;strong&gt;TCP (Transmission Control Protocol)&lt;/strong&gt;, which sets up a reliable back-and-forth channel between your machine and the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Your browser sends an HTTP request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the connection is open, your browser sends a message to the server. That message looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.example.com&lt;/span&gt;
&lt;span class="na"&gt;User-Agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Mozilla/5.0&lt;/span&gt;
&lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a raw &lt;strong&gt;HTTP request&lt;/strong&gt;. It's just text, following a specific format. The &lt;code&gt;GET&lt;/code&gt; part means "please give me this resource." The &lt;code&gt;/&lt;/code&gt; refers to the homepage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: The server sends back a response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The server receives your request, figures out what you want, and sends back a response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello, World!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;200 OK&lt;/code&gt; means everything went fine. The server then sends the actual HTML content your browser will display.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Your browser renders the page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your browser reads the HTML, fetches any additional files it needs (like CSS, images, or JavaScript), and paints the final page on your screen.&lt;/p&gt;

&lt;p&gt;The whole process typically takes under a second, but it involves your computer, at least one DNS server, and a web server potentially located on the other side of the planet.&lt;/p&gt;

&lt;p&gt;This request-and-response cycle is the heartbeat of the web. Everything else we cover in this tutorial builds directly on top of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clients vs. Servers: Who Does What?
&lt;/h2&gt;

&lt;p&gt;Before we write any code, let's get one thing straight: a &lt;strong&gt;client&lt;/strong&gt; and a &lt;strong&gt;server&lt;/strong&gt; are just two computers (or programs) having a conversation. That's it. No magic involved.&lt;/p&gt;

&lt;p&gt;Here's the simple breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The client&lt;/strong&gt; is the one asking questions. Your web browser is a client. When you type a URL and hit enter, your browser is saying &lt;em&gt;"Hey, can I have that webpage?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The server&lt;/strong&gt; is the one answering. It sits around waiting for requests, and when one arrives, it figures out what to send back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like ordering food at a restaurant. You're the client, you make a request ("I'll have the burger"), and the kitchen is the server, preparing and sending back exactly what you asked for.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Client Sends Requests
&lt;/h3&gt;

&lt;p&gt;A request has a few key pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A method&lt;/strong&gt; (like &lt;code&gt;GET&lt;/code&gt; or &lt;code&gt;POST&lt;/code&gt;) that says &lt;em&gt;what kind&lt;/em&gt; of action you want&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A URL&lt;/strong&gt; that says &lt;em&gt;where&lt;/em&gt; you want to do it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers&lt;/strong&gt; that carry extra info (like what kind of data you can accept)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A body&lt;/strong&gt; (optional) that carries data you're sending along&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what a dead-simple client looks like in Python using the &lt;code&gt;requests&lt;/code&gt; library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://jsonplaceholder.typicode.com/posts/1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 200 means success
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;       &lt;span class="c1"&gt;# The actual data sent back
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that and you'll see a dictionary of data come back. Your script just acted as a client.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Server Listens and Responds
&lt;/h3&gt;

&lt;p&gt;The server's job is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Listen&lt;/strong&gt; on a specific port for incoming connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read&lt;/strong&gt; the incoming request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process&lt;/strong&gt; it (look up data, run some logic, whatever)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send back&lt;/strong&gt; a response with a status code and some data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A status code is just a number that tells the client how things went. You've probably seen &lt;code&gt;404&lt;/code&gt; before, which means "I couldn't find what you asked for." A &lt;code&gt;200&lt;/code&gt; means everything went fine.&lt;/p&gt;

&lt;p&gt;Here's a quick cheat sheet of the most common ones:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;OK, here's your stuff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;Created successfully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;Bad request (you messed up)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Not found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;Server error (they messed up)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither side can do the other's job. The client can't serve data, and the server doesn't go out looking for things to do — the client always starts the conversation, and the server always responds. That boundary is also why you can swap out a Spring Boot backend for FastAPI without touching the Angular frontend, as long as the contract — the API — stays the same.&lt;/p&gt;

&lt;p&gt;Next up, we'll actually build one of these servers from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Basic HTTP Server in Python from Zero
&lt;/h2&gt;

&lt;p&gt;Alright, let's get our hands dirty and actually build something. The good news is that Python comes with a built-in HTTP server module, so you don't need to install anything extra to get started.&lt;/p&gt;

&lt;p&gt;Open up your terminal and try this one-liner first, just to see the magic happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point your browser to &lt;code&gt;http://localhost:8080&lt;/code&gt; and you'll see a file listing for whatever directory you ran that command in. Cool, right? But that's cheating a little. Let's build one ourselves so you actually understand what's going on.&lt;/p&gt;

&lt;p&gt;Create a new file called &lt;code&gt;server.py&lt;/code&gt; and paste in this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;http.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HTTPServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Send a 200 OK response
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Write the response body
&lt;/span&gt;        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Hello from my server!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Start the server on port 8080
&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HTTPServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;MyHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Server running on http://localhost:8080&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serve_forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with &lt;code&gt;python3 server.py&lt;/code&gt;, then visit &lt;code&gt;http://localhost:8080&lt;/code&gt; in your browser. You should see a big "Hello from my server!" heading. You just wrote a web server.&lt;/p&gt;

&lt;p&gt;Let's break down what each part does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BaseHTTPRequestHandler&lt;/code&gt;&lt;/strong&gt; is the class we inherit from. It handles the low-level networking stuff so we don't have to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;do_GET&lt;/code&gt;&lt;/strong&gt; is a method that gets called automatically whenever someone sends a GET request to your server. The name matters here, so don't rename it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;send_response(200)&lt;/code&gt;&lt;/strong&gt; tells the client "everything went fine." That 200 is an HTTP status code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;send_header&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;end_headers&lt;/code&gt;&lt;/strong&gt; package up the metadata about your response before the actual content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;self.wfile.write()&lt;/code&gt;&lt;/strong&gt; is where you actually send the content back. It needs bytes, which is why we call &lt;code&gt;.encode("utf-8")&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to serve different content based on the URL? You can check &lt;code&gt;self.path&lt;/code&gt; to see what the user requested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/about&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;About Page&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;h1&amp;gt;Home Page&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now visiting &lt;code&gt;/about&lt;/code&gt; gives a different response than visiting &lt;code&gt;/&lt;/code&gt;. That right there is the core concept behind routing — something every web framework like Flask or Django builds on top of. Worth noting: this raw &lt;code&gt;http.server&lt;/code&gt; approach is useful for learning, but in production you'd reach for FastAPI or Spring Boot, where routing, validation, and serialization are handled for you. For now, though, knowing what happens underneath those abstractions is exactly the point.&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;Ctrl+C&lt;/code&gt; in your terminal to stop the server when you're done experimenting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Your First API Request: Sending and Receiving Data
&lt;/h2&gt;

&lt;p&gt;Now that you have a server running, let's actually talk to it. This is where things get fun.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;API request&lt;/strong&gt; is just your code asking another computer for data. Think of it like ordering food at a restaurant: you (the client) tell the waiter (the HTTP request) what you want, and the kitchen (the server) sends it back.&lt;/p&gt;

&lt;p&gt;We'll use Python's &lt;code&gt;requests&lt;/code&gt; library to do this. If you don't have it yet, install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fetching Data with a GET Request
&lt;/h3&gt;

&lt;p&gt;A GET request means "give me some data." Here's the simplest possible example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://jsonplaceholder.typicode.com/posts/1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Should print 200
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;        &lt;span class="c1"&gt;# Prints the actual data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that and you'll see a real JSON response come back. The &lt;code&gt;status_code&lt;/code&gt; of &lt;code&gt;200&lt;/code&gt; means everything went fine. You'll also notice &lt;code&gt;response.json()&lt;/code&gt; automatically converts the raw text into a Python dictionary you can work with right away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending Data with a POST Request
&lt;/h3&gt;

&lt;p&gt;A POST request means "here's some data, do something with it." This is how login forms, sign-up pages, and chat apps send information to a server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;new_post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My First Post&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, internet!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;userId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://jsonplaceholder.typicode.com/posts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_post&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Should print 201 (Created)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the status code here is &lt;code&gt;201&lt;/code&gt; instead of &lt;code&gt;200&lt;/code&gt;. Servers use different codes to tell you what happened:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;OK, here's your data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;Created successfully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Resource not found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;Server had a problem&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Reading the Response
&lt;/h3&gt;

&lt;p&gt;Every response has two important parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Headers&lt;/strong&gt;: metadata about the response (content type, server info, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body&lt;/strong&gt;: the actual data you requested
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# Tells you the data format
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                     &lt;span class="c1"&gt;# Raw response as a string
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;                   &lt;span class="c1"&gt;# Parsed as a Python dict
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One quick tip: always check the status code before trusting the data. A simple habit is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Something went wrong: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's genuinely all there is to making API requests. You're sending a message over the internet and reading the reply. Everything else is just details built on top of this foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Stateless vs. Stateful Communication
&lt;/h2&gt;

&lt;p&gt;Here's one of those concepts that trips up a lot of beginners, but once it clicks, everything starts to make more sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP is stateless by default.&lt;/strong&gt; That means every single request your browser sends to a server is treated as a brand new conversation. The server has no memory of you from one request to the next. It's like calling a customer service line where the agent forgets you the moment you hang up, and you have to re-introduce yourself every single time you call back.&lt;/p&gt;

&lt;p&gt;Let's make this concrete. Imagine you log into a website. On request #1, you send your username and password. The server checks them and says "yep, that's valid." Now on request #2, you ask to see your profile page. The server has absolutely no idea who you are anymore. Stateless. Clean slate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Every request arrives with no memory of previous requests
# The server just sees raw data each time
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;http.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPServer&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StatelessHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# The server has zero context about who called before
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Who are you? I have no idea!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how do websites actually remember you're logged in? They fake statefulness by passing identity information along with every request. The two most common tricks are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cookies&lt;/strong&gt; - The server sends a small token to your browser after you log in. Your browser then automatically attaches that token to every future request, like wearing a name badge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tokens (like JWTs)&lt;/strong&gt; - Similar idea, but the token itself contains encoded information about who you are, so the server can verify it without even checking a database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Simulating stateful behavior by reading a token from headers
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TokenHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseHTTPRequestHandler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer secret-token-123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome back! I recognize your token.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Access denied. Who are you?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what happened there. The server itself still has no memory. But because the client sent a token, the server could figure out who was asking. The state lives in the token, not in the server.&lt;/p&gt;

&lt;p&gt;This is actually a really smart design. If the server held everyone's session in memory, it would get overwhelmed fast and become nearly impossible to scale. By keeping things stateless and pushing identity into tokens or cookies, you can run dozens of servers and any one of them can handle any request. In practice, this is exactly the pattern you see in Kubernetes-based deployments — pods can be added, removed, or replaced without any of them needing to share session memory, because the client carries its own identity on every call.&lt;/p&gt;

&lt;p&gt;The takeaway: stateless does not mean insecure or forgetful from the user's perspective. It just means the client is responsible for proving who they are on every single request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls Beginners Make and How to Avoid Them
&lt;/h2&gt;

&lt;p&gt;You've made it this far, which means you're ready to start building real things. But before you do, let's talk about the mistakes that trip up almost every beginner. Learning these now will save you hours of frustration later.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Pitfall #1: Forgetting to Handle Errors in Your Requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lot of beginners write code that assumes everything will work perfectly. Spoiler: it won't. Networks fail, servers go down, and URLs get mistyped. Always wrap your requests in error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Raises an error for 4xx and 5xx status codes
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The request timed out. Try again later.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP error occurred: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Could not connect. Check your internet or the URL.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;timeout=5&lt;/code&gt; parameter too. Without it, your program could hang forever waiting for a response that never comes.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Pitfall #2: Hardcoding Sensitive Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never put API keys, passwords, or tokens directly in your code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# BAD - don't do this!
&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_super_secret_key_12345&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you push this to GitHub, the whole world can see it. Instead, use environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set the variable in your terminal before running your script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"my_super_secret_key_12345"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Pitfall #3: Ignoring Status Codes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A request can "succeed" in the sense that it got a response, but that response might be a &lt;code&gt;404 Not Found&lt;/code&gt; or a &lt;code&gt;500 Internal Server Error&lt;/code&gt;. Beginners often skip checking the status code and then wonder why their data looks weird.&lt;/p&gt;

&lt;p&gt;Always check &lt;code&gt;response.status_code&lt;/code&gt; or use &lt;code&gt;raise_for_status()&lt;/code&gt; as shown above.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Pitfall #4: Not Closing Your Server Properly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you run a local Python server during testing, always stop it with &lt;code&gt;Ctrl + C&lt;/code&gt; when you're done. If you just close the terminal window, the port can stay occupied. Then the next time you try to start the server, you'll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OSError: [Errno 98] Address already in use
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find and kill the process using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :8080   &lt;span class="c"&gt;# Find what's using port 8080&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;   &lt;span class="c"&gt;# Replace &amp;lt;PID&amp;gt; with the process ID shown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Pitfall #5: Assuming JSON is Always the Answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSON is super common, but not every API returns it. Some return XML, plain text, or even HTML. Always check the &lt;code&gt;Content-Type&lt;/code&gt; header in the response before blindly calling &lt;code&gt;.json()&lt;/code&gt;, or you'll get a confusing parse error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoiding these five mistakes puts you way ahead of where most beginners start. Keep them in your back pocket and your debugging sessions will be a lot shorter.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>webfundamentals</category>
      <category>http</category>
      <category>backenddevelopment</category>
    </item>
  </channel>
</rss>
