<?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: Ananya S</title>
    <description>The latest articles on DEV Community by Ananya S (@zeroshotanu).</description>
    <link>https://dev.to/zeroshotanu</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%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg</url>
      <title>DEV Community: Ananya S</title>
      <link>https://dev.to/zeroshotanu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zeroshotanu"/>
    <language>en</language>
    <item>
      <title>FastAPI for AI Engineers - Part 6: JWT Authentication in FastAPI</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Mon, 15 Jun 2026 17:22:40 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-6-jwt-authentication-in-fastapi-5fpk</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-6-jwt-authentication-in-fastapi-5fpk</guid>
      <description>&lt;p&gt;In the previous article, we explored the concepts of Authentication and Authorization.&lt;/p&gt;

&lt;p&gt;We learned that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication answers &lt;strong&gt;"Who are you?"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Authorization answers &lt;strong&gt;"What are you allowed to do?"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding the concepts is important, but real-world applications require actual implementation.&lt;/p&gt;

&lt;p&gt;If you've ever used Gmail, LinkedIn, GitHub, or ChatGPT, you've already used authentication systems countless times.&lt;/p&gt;

&lt;p&gt;You enter your username and password, the application verifies your identity, and you gain access to protected resources.&lt;/p&gt;

&lt;p&gt;But how does this actually work behind the scenes?&lt;/p&gt;

&lt;p&gt;In this article, we'll build a complete JWT Authentication system using FastAPI.&lt;/p&gt;

&lt;p&gt;If you haven't read the previous article, check it out first:&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma" class="crayons-story__hidden-navigation-link"&gt;FastAPI for AI Engineers - Part 5: Authentication vs Authorization (And Why Most Beginners Confuse Them)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/zeroshotanu" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" alt="zeroshotanu profile" class="crayons-avatar__image" width="799" height="436"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/zeroshotanu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ananya S
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ananya S
                
              
              &lt;div id="story-author-preview-content-3876313" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/zeroshotanu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" class="crayons-avatar__image" alt="" width="799" height="436"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ananya S&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 12&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma" id="article-link-3876313"&gt;
          FastAPI for AI Engineers - Part 5: Authentication vs Authorization (And Why Most Beginners Confuse Them)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/fastapi"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;fastapi&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Why Do We Need Authentication?
&lt;/h2&gt;

&lt;p&gt;Imagine building an AI-powered learning platform.&lt;/p&gt;

&lt;p&gt;Without authentication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anyone could access any user's profile&lt;/li&gt;
&lt;li&gt;Anyone could view another student's progress&lt;/li&gt;
&lt;li&gt;Anyone could modify data belonging to other users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clearly, this is a security problem.&lt;/p&gt;

&lt;p&gt;Applications need a way to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify user identity&lt;/li&gt;
&lt;li&gt;Protect sensitive resources&lt;/li&gt;
&lt;li&gt;Allow users to stay logged in&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where JWT Authentication comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is JWT?
&lt;/h2&gt;

&lt;p&gt;JWT stands for &lt;strong&gt;JSON Web Token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A JWT is a secure token that contains information about a user.&lt;/p&gt;

&lt;p&gt;Instead of sending a username and password with every request, the user sends a token.&lt;/p&gt;

&lt;p&gt;Typical flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Register User
      ↓
   Login
      ↓
Verify Credentials
      ↓
Generate JWT Token
      ↓
Access Protected Routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Installing Required Packages
&lt;/h2&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;python-jose passlib[bcrypt]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;passlib&lt;/code&gt; for password hashing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;python-jose&lt;/code&gt; for JWT token generation and verification&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Step 1: Hashing Passwords
&lt;/h1&gt;

&lt;p&gt;Storing passwords in plain text is extremely dangerous.&lt;/p&gt;

&lt;p&gt;Never do 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="n"&gt;users&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;rahul&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;password123&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;If the database is compromised, every user's password becomes visible.&lt;/p&gt;

&lt;p&gt;Instead, we store a hashed version.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a Password Hasher
&lt;/h2&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;passlib.context&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CryptContext&lt;/span&gt;

&lt;span class="n"&gt;pwd_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CryptContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;schemes&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;bcrypt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;deprecated&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&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;h3&gt;
  
  
  What is CryptContext?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CryptContext&lt;/code&gt; manages password hashing algorithms.&lt;/p&gt;

&lt;p&gt;In this 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="n"&gt;schemes&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;bcrypt&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;we tell FastAPI to use the bcrypt hashing algorithm.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hashing a Password
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;hashed_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password123&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;hashed_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$2b$12$.....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the original password is no longer visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verifying Passwords
&lt;/h2&gt;

&lt;p&gt;When the user logs in:&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="n"&gt;pwd_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;password123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hashed_password&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;returns:&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="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to verify passwords without storing them in plain text.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2: User Registration
&lt;/h1&gt;

&lt;p&gt;Let's create a simple registration endpoint.&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/register&lt;/span&gt;&lt;span class="sh"&gt;"&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;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;hashed_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hashed_password&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;User registered successfully&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;h3&gt;
  
  
  What happens here?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;User submits username and password&lt;/li&gt;
&lt;li&gt;Password is hashed&lt;/li&gt;
&lt;li&gt;Hash is stored instead of the original password&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  Step 3: User Login
&lt;/h1&gt;

&lt;p&gt;Now let's verify credentials.&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="nd"&gt;@app.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;/login&lt;/span&gt;&lt;span class="sh"&gt;"&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;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;stored_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&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="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;stored_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;User not found&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="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stored_password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Invalid credentials&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Login successful&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;At this point, users can log in successfully.&lt;/p&gt;

&lt;p&gt;However, they still need to send their username and password with every request.&lt;/p&gt;

&lt;p&gt;JWT solves this problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 4: Creating a JWT Token
&lt;/h1&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;jose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;

&lt;span class="n"&gt;SECRET_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;mysecretkey&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;ALGORITHM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HS256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why do we need a secret key?
&lt;/h3&gt;

&lt;p&gt;The secret key is used to sign tokens.&lt;/p&gt;

&lt;p&gt;If someone modifies the token, the signature becomes invalid.&lt;/p&gt;




&lt;h2&gt;
  
  
  Generate Token Function
&lt;/h2&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;create_access_token&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="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;to_encode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;expire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;to_encode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expire&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;encoded_jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&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="n"&gt;to_encode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ALGORITHM&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;encoded_jwt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What does this function do?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Copies user data&lt;/li&gt;
&lt;li&gt;Adds an expiry time&lt;/li&gt;
&lt;li&gt;Creates a signed JWT token&lt;/li&gt;
&lt;li&gt;Returns the token&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  Step 5: Generate Token During Login
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.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;/login&lt;/span&gt;&lt;span class="sh"&gt;"&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;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;stored_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&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="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;stored_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;User not found&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="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stored_password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Invalid credentials&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;create_access_token&lt;/span&gt;&lt;span class="p"&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;sub&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token_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;bearer&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;Successful login now returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"access_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJIUzI1NiIs..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bearer"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 6: Protected Route
&lt;/h1&gt;

&lt;p&gt;Now we can protect routes.&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="nd"&gt;@app.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;/profile&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_profile&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Protected profile data&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;Currently anyone can access it.&lt;/p&gt;

&lt;p&gt;In production applications, FastAPI verifies the JWT token before allowing access.&lt;/p&gt;

&lt;p&gt;We'll implement complete route protection in the next article.&lt;/p&gt;

&lt;p&gt;For now, focus on understanding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Registration&lt;/li&gt;
&lt;li&gt;Password Hashing&lt;/li&gt;
&lt;li&gt;Password Verification&lt;/li&gt;
&lt;li&gt;JWT Generation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These form the foundation of every authentication system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Authentication Flow Recap
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Register User
      ↓
Hash Password
      ↓
Store Hash
      ↓
   Login
      ↓
Verify Password
      ↓
Generate JWT
      ↓
Access Protected Routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Today we built the core components of JWT Authentication:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Registration&lt;/li&gt;
&lt;li&gt;Password Hashing&lt;/li&gt;
&lt;li&gt;Password Verification&lt;/li&gt;
&lt;li&gt;JWT Token Generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A user can now register, log in, and receive a signed JWT token.&lt;/p&gt;

&lt;p&gt;However, generating a token is only half the story.&lt;/p&gt;

&lt;p&gt;The next step is learning how to validate tokens and protect routes using FastAPI dependencies.&lt;/p&gt;

&lt;p&gt;In the next article, we'll implement JWT-based route protection and begin exploring Role-Based Access Control (RBAC).&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>fastapi</category>
      <category>backend</category>
    </item>
    <item>
      <title>FastAPI for AI Engineers - Part 5: Authentication vs Authorization (And Why Most Beginners Confuse Them)</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Fri, 12 Jun 2026 17:23:27 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-5-authentication-vs-authorization-and-why-most-beginners-confuse-42ma</guid>
      <description>&lt;p&gt;In the previous article, we explored how Pydantic validates data before it enters our application.&lt;/p&gt;

&lt;p&gt;For example, if an API expects a temperature value, sending text such as "Sunny" instead of a numeric value should be rejected.&lt;/p&gt;

&lt;p&gt;Just as applications validate data before processing it, they must also validate users before granting access.&lt;/p&gt;

&lt;p&gt;Not everyone should be able to access every endpoint or perform every action.&lt;/p&gt;

&lt;p&gt;This brings us to two important concepts in backend development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although these terms are often used together, they solve different problems.&lt;/p&gt;

&lt;p&gt;If you haven't read it already, check out the previous post to maintain continuity in the series and improve your understanding on FastAPI: &lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35" class="crayons-story__hidden-navigation-link"&gt;FastAPI for AI Engineers - Part 4: Stop Bad Data Before It Breaks Your API (Pydantic and Data Validation)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/zeroshotanu" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" alt="zeroshotanu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/zeroshotanu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ananya S
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ananya S
                
              
              &lt;div id="story-author-preview-content-3849809" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/zeroshotanu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ananya S&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35" id="article-link-3849809"&gt;
          FastAPI for AI Engineers - Part 4: Stop Bad Data Before It Breaks Your API (Pydantic and Data Validation)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/fastapi"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;fastapi&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              4&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;Imagine entering an airport.&lt;/p&gt;

&lt;p&gt;At the entrance, security checks your passport or government-issued ID to verify who you are.&lt;/p&gt;

&lt;p&gt;This process is Authentication.&lt;/p&gt;

&lt;p&gt;Once inside, not everyone can access every area.&lt;/p&gt;

&lt;p&gt;Passengers can access waiting lounges, restaurants, and boarding gates.&lt;/p&gt;

&lt;p&gt;Pilots, security personnel, and airport staff can access restricted areas that ordinary passengers cannot.&lt;/p&gt;

&lt;p&gt;This process is Authorization.&lt;/p&gt;

&lt;p&gt;The difference becomes clearer when we compare them side by side:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Authentication&lt;/th&gt;
&lt;th&gt;Authorization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Verifies identity&lt;/td&gt;
&lt;td&gt;Determines permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Answers "Who are you?"&lt;/td&gt;
&lt;td&gt;Answers "What can you do?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Happens first&lt;/td&gt;
&lt;td&gt;Happens after authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Login credentials, tokens&lt;/td&gt;
&lt;td&gt;Roles and permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Example: Logging into an app&lt;/td&gt;
&lt;td&gt;Example: Accessing the admin dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The following endpoint can be accessed by anyone:&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/profile/&lt;/span&gt;&lt;span class="sh"&gt;'&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;get_profile&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;message&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;Your profile is here&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;There is no mechanism to verify who is making the request.&lt;/p&gt;

&lt;p&gt;Whether the user is logged in or not, the endpoint remains accessible.&lt;/p&gt;

&lt;p&gt;Authentication is the process of verifying a user's identity.&lt;/p&gt;

&lt;p&gt;A typical authentication flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login
  ↓
Username + Password
  ↓
Verify User
  ↓
Generate Token
  ↓
Access Protected Routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="n"&gt;users&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;suman&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;password123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/login&lt;/span&gt;&lt;span class="sh"&gt;"&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;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&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;users&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="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Login successful&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Invalid credentials&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;&lt;em&gt;This is a simplified example used only to demonstrate the concept.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In real-world applications, passwords should never be stored in plain text and authentication is usually implemented using JWT tokens, OAuth, or other secure mechanisms.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Authentication confirms the identity of a user.&lt;/p&gt;

&lt;p&gt;However, simply knowing who a user is does not determine what they are allowed to do.&lt;/p&gt;

&lt;p&gt;This is where Authorization comes into play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;users&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;suman&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;role&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;admin&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;rahul&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;role&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;student&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;delete_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&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;current_user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;admin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Access denied&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&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;Student &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; deleted&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;h3&gt;
  
  
  To summarize:
&lt;/h3&gt;

&lt;p&gt;Authentication -&amp;gt; Who are you?&lt;/p&gt;

&lt;p&gt;Authorization -&amp;gt; What are you allowed to do?&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication and Authorization in AI Applications
&lt;/h2&gt;

&lt;p&gt;Suppose you're building an AI-powered learning platform.&lt;/p&gt;

&lt;p&gt;Authentication determines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which user is sending the request&lt;/li&gt;
&lt;li&gt;Whether the user is logged in&lt;/li&gt;
&lt;li&gt;Whether the access token is valid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Authorization determines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the user can access premium AI models&lt;/li&gt;
&lt;li&gt;Whether the user can upload training datasets&lt;/li&gt;
&lt;li&gt;Whether the user can view analytics dashboards&lt;/li&gt;
&lt;li&gt;Whether the user can manage other users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if two users are authenticated, they may not have the same permissions.&lt;/p&gt;

&lt;p&gt;This is why authentication and authorization are both essential in production AI systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
      │
      ▼
Authentication
(Who are you?)
      │
      ▼
Authorization
(What can you do?)
      │
      ▼
Protected Resource
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Authentication and Authorization are often mentioned together, but they solve different problems.&lt;/p&gt;

&lt;p&gt;Authentication verifies identity.&lt;/p&gt;

&lt;p&gt;Authorization determines permissions.&lt;/p&gt;

&lt;p&gt;A user must first prove who they are before the system can decide what they are allowed to do.&lt;/p&gt;

&lt;p&gt;In this article, we focused on understanding the concepts behind Authentication and Authorization.&lt;br&gt;
JWT (JSON Web Tokens) is one of the most common approaches used to authenticate users in modern APIs.&lt;/p&gt;

&lt;p&gt;In the next article, we'll move beyond theory and implement JWT-based Authentication in FastAPI step-by-step, allowing us to generate access tokens, protect routes, and identify users securely.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>fastapi</category>
      <category>backend</category>
    </item>
    <item>
      <title>FastAPI for AI Engineers - Part 4: Stop Bad Data Before It Breaks Your API (Pydantic and Data Validation)</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Tue, 09 Jun 2026 03:05:00 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-4-stop-bad-data-before-it-breaks-your-api-pydantic-and-data-1l35</guid>
      <description>&lt;p&gt;In the previous article, we connected our FastAPI application to a database using SQLite and SQLAlchemy.&lt;/p&gt;

&lt;p&gt;We also used classes like:&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;class&lt;/span&gt; &lt;span class="nc"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;without fully understanding what was happening behind the scenes.&lt;/p&gt;

&lt;p&gt;Today, we'll fix that.&lt;/p&gt;
&lt;h3&gt;
  
  
  If you haven't read it check it out: &lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca" class="crayons-story__hidden-navigation-link"&gt;FastAPI for AI Engineers - Part 3: Connecting to a database&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/zeroshotanu" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" alt="zeroshotanu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/zeroshotanu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ananya S
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ananya S
                
              
              &lt;div id="story-author-preview-content-3827796" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/zeroshotanu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ananya S&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 6&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca" id="article-link-3827796"&gt;
          FastAPI for AI Engineers - Part 3: Connecting to a database
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/fastapi"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;fastapi&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;/div&gt;

&lt;/h3&gt;





&lt;h2&gt;
  
  
  Why Do We Need Data Validation?
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a weather application.&lt;/p&gt;

&lt;p&gt;A user asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the temperature in Chennai?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A valid response might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;35
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;35°C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if the API returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sunny
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is clearly wrong.&lt;/p&gt;

&lt;p&gt;Temperature should be represented as a number.&lt;/p&gt;

&lt;p&gt;Even if the value itself is inaccurate, we still know that temperature must be numeric.&lt;/p&gt;

&lt;p&gt;This is where validation becomes important.&lt;/p&gt;

&lt;p&gt;Validation allows us to define rules about what data is acceptable before it enters our application.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Temperature should be numeric&lt;/li&gt;
&lt;li&gt;Age cannot be negative&lt;/li&gt;
&lt;li&gt;CGPA should be between 0 and 10&lt;/li&gt;
&lt;li&gt;Email addresses should follow a valid format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without validation, applications can receive invalid data and behave unexpectedly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Without Validation
&lt;/h2&gt;

&lt;p&gt;Consider a student registration API.&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="nd"&gt;@app.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;/student&lt;/span&gt;&lt;span class="sh"&gt;"&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;create_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A user could send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Excellent"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API would accept it.&lt;/p&gt;

&lt;p&gt;But a CGPA should be a number, not text.&lt;/p&gt;

&lt;p&gt;As applications grow, manually checking every field becomes difficult.&lt;/p&gt;

&lt;p&gt;We need a better solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter Pydantic
&lt;/h2&gt;

&lt;p&gt;Pydantic is a Python library used for data validation.&lt;/p&gt;

&lt;p&gt;FastAPI uses Pydantic extensively behind the scenes.&lt;/p&gt;

&lt;p&gt;Instead of manually validating data, we define a schema.&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now FastAPI knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; must be a string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cgpa&lt;/code&gt; must be a floating-point number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whenever data arrives, FastAPI automatically validates it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your First Pydantic Model
&lt;/h2&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of this model as a blueprint.&lt;/p&gt;

&lt;p&gt;Any incoming request must follow this structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Valid Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Invalid Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Excellent"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastAPI will reject the request automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using Pydantic with FastAPI
&lt;/h2&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/student&lt;/span&gt;&lt;span class="sh"&gt;"&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;create_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice this line:&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="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastAPI now expects the incoming request body to match the &lt;code&gt;Student&lt;/code&gt; schema.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding Validation Errors
&lt;/h2&gt;

&lt;p&gt;Suppose we send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Excellent"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastAPI returns a validation error before the request reaches our route.&lt;/p&gt;

&lt;p&gt;You'll see an error similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"float_parsing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Input should be a valid number"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of failing silently, FastAPI clearly tells us what went wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  Adding Constraints with Field()
&lt;/h2&gt;

&lt;p&gt;Validating types is useful.&lt;/p&gt;

&lt;p&gt;But sometimes we need stricter rules.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CGPA should be between 0 and 10&lt;/li&gt;
&lt;li&gt;Name should have a minimum length&lt;/li&gt;
&lt;li&gt;Age should always be positive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pydantic provides &lt;code&gt;Field()&lt;/code&gt; for this purpose.&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;min_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Understanding the Constraints
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CGPA &amp;gt; 0
CGPA &amp;lt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Valid Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Invalid Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastAPI immediately rejects the request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Optional Fields
&lt;/h2&gt;

&lt;p&gt;Sometimes fields are not mandatory.&lt;/p&gt;

&lt;p&gt;For example, a student may not have a department assigned yet.&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;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the department field becomes optional.&lt;/p&gt;

&lt;h3&gt;
  
  
  Valid Request
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Also Valid
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Request Models vs Database Models
&lt;/h2&gt;

&lt;p&gt;One question many beginners ask is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do we need both &lt;code&gt;schemas.py&lt;/code&gt; and &lt;code&gt;models.py&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's understand the difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  SQLAlchemy Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;students&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This defines how data is stored in the database.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pydantic Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This defines how data enters our API.&lt;/p&gt;




&lt;p&gt;Think of it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database Structure
        ≠
API Structure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They may look similar, but they serve different purposes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Response Models
&lt;/h2&gt;

&lt;p&gt;Pydantic can also control what data is returned from an API.&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;class&lt;/span&gt; &lt;span class="nc"&gt;StudentResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.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;/student/{id}&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_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;StudentResponse&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;get_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the response always follows a consistent structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Pydantic Matters for AI Applications
&lt;/h2&gt;

&lt;p&gt;Suppose you're building an LLM API.&lt;/p&gt;

&lt;p&gt;Expected request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explain FastAPI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"temperature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without validation, a user could send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explain FastAPI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"temperature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"very creative"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a lot"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and your application would have to deal with invalid data.&lt;/p&gt;

&lt;p&gt;Pydantic prevents invalid requests from ever reaching your business logic.&lt;/p&gt;

&lt;p&gt;This becomes especially important when building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI chatbots&lt;/li&gt;
&lt;li&gt;RAG applications&lt;/li&gt;
&lt;li&gt;Agentic systems&lt;/li&gt;
&lt;li&gt;Model inference APIs&lt;/li&gt;
&lt;li&gt;Multi-agent workflows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Validation Fits into the Request Lifecycle
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client Request
      │
      ▼
Pydantic Validation
      │
      ▼
FastAPI Route
      │
      ▼
Business Logic
      │
      ▼
Database / LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pydantic acts as the first line of defense.&lt;/p&gt;

&lt;p&gt;Only valid data reaches the rest of the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Pydantic is one of the reasons FastAPI has become so popular. It allows us to build APIs that are safer, more predictable, and easier to maintain.&lt;/p&gt;

&lt;p&gt;In the next article, we'll move into Authentication and Authorization and learn how to protect our APIs from unauthorized access.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>fastapi</category>
      <category>backend</category>
      <category>python</category>
    </item>
    <item>
      <title>FastAPI for AI Engineers - Part 3: Connecting to a database</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Sat, 06 Jun 2026 06:27:51 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-3-connecting-to-a-database-30ca</guid>
      <description>&lt;p&gt;In the previous article, we explored how to build our first CRUD API using FastAPI. While our API worked correctly, there was one major problem.&lt;/p&gt;

&lt;p&gt;We were storing data inside Python lists, which exist only in memory.&lt;/p&gt;

&lt;p&gt;If you've ever wondered how applications like Instagram, LinkedIn, or ChatGPT remember information even after a server restart, the answer is simple: databases.&lt;/p&gt;

&lt;p&gt;In this article, we'll solve the problem of in-memory storage by connecting our FastAPI application to SQLite using SQLAlchemy.&lt;br&gt;
If you haven't read the previous post, check it out: &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl" class="crayons-story__hidden-navigation-link"&gt;FastAPI for AI Engineers - Part 2: Building Your First CRUD API&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/zeroshotanu" class="crayons-avatar  crayons-avatar--l  "&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" alt="zeroshotanu profile" class="crayons-avatar__image" width="799" height="436"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/zeroshotanu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ananya S
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ananya S
                
              
              &lt;div id="story-author-preview-content-3793398" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/zeroshotanu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3559285%2Fc3ef331f-5380-4103-9520-7e34720fd7dc.jpeg" class="crayons-avatar__image" alt="" width="799" height="436"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ananya S&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 1&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl" id="article-link-3793398"&gt;
          FastAPI for AI Engineers - Part 2: Building Your First CRUD API
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/fastapi"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;fastapi&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;By the end of this article, you'll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why in-memory storage is a problem&lt;/li&gt;
&lt;li&gt;What SQLite is&lt;/li&gt;
&lt;li&gt;What SQLAlchemy is&lt;/li&gt;
&lt;li&gt;How ORM works&lt;/li&gt;
&lt;li&gt;How to create database tables using Python classes&lt;/li&gt;
&lt;li&gt;How to perform CRUD operations using a real database&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem with In-Memory Storage
&lt;/h2&gt;

&lt;p&gt;Previously, our application stored students inside a Python list.&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="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;id&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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;Ananya&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;department&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;CSE&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;cgpa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.9&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked for learning CRUD operations.&lt;/p&gt;

&lt;p&gt;However, consider what happens when the server restarts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FastAPI Server Stops
        ↓
Python Memory Cleared
        ↓
All Student Data Lost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is unacceptable in real-world applications.&lt;/p&gt;

&lt;p&gt;We need a place where data can survive application restarts.&lt;/p&gt;

&lt;p&gt;This is where databases come in.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is SQLite?
&lt;/h2&gt;

&lt;p&gt;SQLite is a lightweight relational database.&lt;/p&gt;

&lt;p&gt;Unlike MySQL or PostgreSQL, SQLite doesn't require a separate database server.&lt;/p&gt;

&lt;p&gt;Instead, everything is stored inside a single file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;students.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Advantages of SQLite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No installation required&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;Easy to learn&lt;/li&gt;
&lt;li&gt;Perfect for local development&lt;/li&gt;
&lt;li&gt;Great for small projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this article, we'll use SQLite.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is SQLAlchemy?
&lt;/h2&gt;

&lt;p&gt;Before SQLAlchemy, developers often wrote raw SQL queries.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While SQL is powerful, writing queries everywhere quickly becomes difficult to maintain.&lt;/p&gt;

&lt;p&gt;SQLAlchemy solves this problem using an ORM.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is an ORM?
&lt;/h2&gt;

&lt;p&gt;ORM stands for Object Relational Mapper.&lt;/p&gt;

&lt;p&gt;It allows us to interact with database tables using Python classes.&lt;/p&gt;

&lt;p&gt;Think of it like a translator.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Database&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table&lt;/td&gt;
&lt;td&gt;Class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Row&lt;/td&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column&lt;/td&gt;
&lt;td&gt;Attribute&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Database table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;students

id     name     department     cgpa
1      Ananya   CSE            8.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes:&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;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing SQL manually, we work with Python objects.&lt;/p&gt;

&lt;p&gt;SQLAlchemy generates SQL behind the scenes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Create the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project/
│
├── database.py
├── models.py
├── schemas.py
├── main.py
└── students.db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file has a specific responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  database.py
&lt;/h3&gt;

&lt;p&gt;Responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database connection&lt;/li&gt;
&lt;li&gt;Session creation&lt;/li&gt;
&lt;li&gt;Base class creation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  models.py
&lt;/h3&gt;

&lt;p&gt;Responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database tables&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  schemas.py
&lt;/h3&gt;

&lt;p&gt;Responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request validation&lt;/li&gt;
&lt;li&gt;Response structure&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  main.py
&lt;/h3&gt;

&lt;p&gt;Responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API routes&lt;/li&gt;
&lt;li&gt;Business logic&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Installing Dependencies
&lt;/h2&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;sqlalchemy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you haven't installed FastAPI yet:&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;fastapi uvicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Creating database.py
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;database.py&lt;/code&gt;&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;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;declarative_base&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sessionmaker&lt;/span&gt;

&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sqlite:///./students.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;connect_args&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;check_same_thread&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;#allows the same connection to be used across threads
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SessionLocal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sessionmaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;autocommit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;autoflush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;declarative_base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, SQLAlchemy uses transactional mode:&lt;br&gt;
You make changes → they are staged in the session → you call commit() to persist them.&lt;br&gt;
If autocommit is enabled, each statement is committed immediately (like SQLite’s default).&lt;br&gt;
When autoflush=True (default), SQLAlchemy automatically flushes pending changes to the database before executing a query.&lt;br&gt;
Flush means:&lt;br&gt;
Synchronize in-memory changes with the database inside the current transaction.&lt;br&gt;
Does not commit — changes are still rollback-able until you call commit().&lt;/p&gt;


&lt;h2&gt;
  
  
  Understanding create_engine()
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQLAlchemy needs a way to communicate with the database.&lt;/p&gt;

&lt;p&gt;The Engine object acts as the bridge between FastAPI and SQLite.&lt;/p&gt;

&lt;p&gt;Whenever we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;insert data&lt;/li&gt;
&lt;li&gt;retrieve data&lt;/li&gt;
&lt;li&gt;update data&lt;/li&gt;
&lt;li&gt;delete data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SQLAlchemy uses the engine to talk to the database.&lt;/p&gt;


&lt;h2&gt;
  
  
  Understanding SessionLocal
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;SessionLocal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sessionmaker&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A session represents a conversation with the database.&lt;/p&gt;

&lt;p&gt;Imagine visiting a bank:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start conversation&lt;/li&gt;
&lt;li&gt;Perform transactions&lt;/li&gt;
&lt;li&gt;End conversation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A database session works similarly.&lt;/p&gt;

&lt;p&gt;Every database operation happens through a session.&lt;/p&gt;


&lt;h2&gt;
  
  
  Understanding Base
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;declarative_base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Every database model we create will inherit from Base.&lt;/p&gt;

&lt;p&gt;SQLAlchemy uses Base to keep track of all models and create tables automatically.&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating Database Sessions
&lt;/h2&gt;

&lt;p&gt;Add this function below the previous 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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SessionLocal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;

    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Do We Need get_db()?
&lt;/h2&gt;

&lt;p&gt;Without this function, every route would need to create and close sessions manually.&lt;/p&gt;

&lt;p&gt;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="nd"&gt;@app.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;/students&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_students&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SessionLocal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Database operations
&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes repetitive.&lt;/p&gt;

&lt;p&gt;Instead, FastAPI can automatically create and close sessions for us.&lt;/p&gt;

&lt;p&gt;Later we'll use:&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="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastAPI will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a session&lt;/li&gt;
&lt;li&gt;Give it to the route&lt;/li&gt;
&lt;li&gt;Close it automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is called Dependency Injection.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Creating models.py
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;models.py&lt;/code&gt;&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;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Float&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;students&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Understanding the Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;students&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a table named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;students
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;








&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates the primary key.&lt;/p&gt;

&lt;p&gt;Every student must have a unique ID.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates a text column.&lt;/p&gt;

&lt;p&gt;The same applies to department.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cgpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates a floating-point column.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Creating schemas.py
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;code&gt;schemas.py&lt;/code&gt;&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;from_attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Do We Need Schemas?
&lt;/h2&gt;

&lt;p&gt;Schemas define what data our API expects.&lt;/p&gt;

&lt;p&gt;For now, think of schemas as blueprints.&lt;/p&gt;

&lt;p&gt;We're using Pydantic behind the scenes.&lt;/p&gt;

&lt;p&gt;We'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Optional fields&lt;/li&gt;
&lt;li&gt;Custom validators&lt;/li&gt;
&lt;li&gt;Response models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in a dedicated article later in this series.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Creating main.py
&lt;/h2&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Creating Tables Automatically
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When FastAPI starts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQLAlchemy checks all models.&lt;/li&gt;
&lt;li&gt;Looks for missing tables.&lt;/li&gt;
&lt;li&gt;Creates them automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our Student table is now created inside SQLite.&lt;/p&gt;




&lt;h2&gt;
  
  
  CREATE Operation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.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;/student&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_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StudentResponse&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;create_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;new_student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgpa&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;new_student&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Happens Here?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adds the object to the session.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permanently saves data to the database.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reloads the object from the database.&lt;/p&gt;

&lt;p&gt;This is useful because the database automatically generates the ID.&lt;/p&gt;




&lt;h2&gt;
  
  
  READ Operation
&lt;/h2&gt;

&lt;p&gt;Get all students.&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="nd"&gt;@app.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;/students&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_students&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Get a student by ID.&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="nd"&gt;@app.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;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  UPDATE Operation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;update_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StudentCreate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;
    &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgpa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgpa&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  DELETE Operation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;delete_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student deleted successfully&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;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Swagger UI to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create students&lt;/li&gt;
&lt;li&gt;Retrieve students&lt;/li&gt;
&lt;li&gt;Update students&lt;/li&gt;
&lt;li&gt;Delete students&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  SQLite vs MySQL
&lt;/h2&gt;

&lt;p&gt;The good news is that SQLAlchemy makes switching databases extremely easy.&lt;/p&gt;

&lt;p&gt;Current SQLite connection:&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="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sqlite:///./students.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MySQL connection:&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="n"&gt;MYSQL_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DB_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123456&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# use your MySQL login password
&lt;/span&gt;&lt;span class="n"&gt;MYSQL_HOST&lt;/span&gt; &lt;span class="o"&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="n"&gt;MYSQL_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3306&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;MYSQL_DATABASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fastapi_db&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;


&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&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;mysql+pymysql://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;@&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MYSQL_HOST&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MYSQL_PORT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the MySQL driver:&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;pymysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else remains almost identical. Ensure you have MySQL in your desktop, open MySQL WorkBench and connect to database to see the database and tables in it. Ensure the database with the name 'fastapi_db' is already present in MySQL WorkBench.&lt;/p&gt;

&lt;p&gt;This is one of the biggest advantages of using an ORM.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Everything Works Together
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client Request
      │
      ▼
FastAPI Route
      │
      ▼
Pydantic Schema
      │
      ▼
Database Session
      │
      ▼
SQLAlchemy Model
      │
      ▼
SQLite / MySQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a user creates a student:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;FastAPI receives the request&lt;/li&gt;
&lt;li&gt;Pydantic validates the incoming data&lt;/li&gt;
&lt;li&gt;A database session is created&lt;/li&gt;
&lt;li&gt;SQLAlchemy converts the Python object into SQL&lt;/li&gt;
&lt;li&gt;SQLite stores the data permanently&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We've now moved beyond in-memory storage and built our first database-backed FastAPI application.&lt;br&gt;
Most production AI applications use the same architecture, whether they're storing chat histories, user profiles, agent memory, evaluation results, or feedback data.&lt;/p&gt;

&lt;p&gt;In the next article, we'll take a deeper look at Pydantic and understand how FastAPI validates incoming data automatically.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>fastapi</category>
      <category>python</category>
      <category>backend</category>
    </item>
    <item>
      <title>FastAPI for AI Engineers - Part 2: Building Your First CRUD API</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Mon, 01 Jun 2026 17:06:06 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl</guid>
      <description>&lt;p&gt;In the previous article, we explored why FastAPI has become one of the most popular backend frameworks for modern AI applications.&lt;/p&gt;

&lt;p&gt;If you haven't read the previous post, check it out: &lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-1-why-every-ai-backend-is-moving-toward-fastapi-45fg"&gt;https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-1-why-every-ai-backend-is-moving-toward-fastapi-45fg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it's time to build something practical.&lt;/p&gt;

&lt;p&gt;Most backend applications revolve around four basic operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;li&gt;Read&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Delete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these operations are known as &lt;strong&gt;CRUD&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whether you're building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a social media application,&lt;/li&gt;
&lt;li&gt;an e-commerce platform,&lt;/li&gt;
&lt;li&gt;a chatbot,&lt;/li&gt;
&lt;li&gt;or an AI agent,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CRUD operations are the foundation of backend development.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a simple Student Management API while learning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Path Parameters&lt;/li&gt;
&lt;li&gt;Query Parameters&lt;/li&gt;
&lt;li&gt;GET Requests&lt;/li&gt;
&lt;li&gt;POST Requests&lt;/li&gt;
&lt;li&gt;PUT Requests&lt;/li&gt;
&lt;li&gt;DELETE Requests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Creating Sample Data
&lt;/h2&gt;

&lt;p&gt;Let's start with a small dataset.&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&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;id&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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;Ananya&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;department&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;CSE&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;cgpa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.9&lt;/span&gt;
    &lt;span class="p"&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;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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;Rahul&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;department&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;ECE&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;cgpa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.4&lt;/span&gt;
    &lt;span class="p"&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;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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;Priya&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;department&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;IT&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;cgpa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;9.1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Swagger UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Path Parameters
&lt;/h2&gt;

&lt;p&gt;A path parameter is part of the URL itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/student/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;2&lt;/code&gt; is the path parameter.&lt;br&gt;
Think of path parameters as:&lt;/p&gt;

&lt;p&gt;"I know exactly which resource I want."&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/users/10
/products/25
/orders/1001
/student/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's fetch a specific student using their ID.&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="nd"&gt;@app.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;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_student_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;students&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;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student not found&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;Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/student/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rahul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ECE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Query Parameters
&lt;/h2&gt;

&lt;p&gt;A query parameter appears after the &lt;code&gt;?&lt;/code&gt; in a URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/student?department="CSE"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filtering&lt;/li&gt;
&lt;li&gt;searching&lt;/li&gt;
&lt;li&gt;sorting&lt;/li&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement the same endpoint using a query parameter.&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="nd"&gt;@app.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;/students&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_students&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;filtered_students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;students&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;student&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;department&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;filtered_students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filtered_students&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/student?department="CSE"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.9&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All students in CSE department would be filtered.&lt;br&gt;
Query parameters are often optional and are used to modify, filter, or search results.&lt;/p&gt;
&lt;h3&gt;
  
  
  Path vs Query Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path Parameter&lt;/th&gt;
&lt;th&gt;Query Parameter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Part of URL path&lt;/td&gt;
&lt;td&gt;Appears after ?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identifies a resource&lt;/td&gt;
&lt;td&gt;Filters or searches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/student/1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/student?id=1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  GET Request
&lt;/h2&gt;

&lt;p&gt;GET requests are used to retrieve data.&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="nd"&gt;@app.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;/students&lt;/span&gt;&lt;span class="sh"&gt;"&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;get_all_students&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ananya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.9&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rahul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ECE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.4&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Priya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Request Bodies with Pydantic
&lt;/h2&gt;

&lt;p&gt;When users send data to our API, FastAPI needs a way to validate that the incoming data has the correct structure.&lt;/p&gt;

&lt;p&gt;This is where Pydantic comes in.&lt;/p&gt;

&lt;p&gt;Pydantic allows us to define the expected shape of incoming data using Python classes.&lt;/p&gt;

&lt;p&gt;For example, every student should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an ID&lt;/li&gt;
&lt;li&gt;a name&lt;/li&gt;
&lt;li&gt;a department&lt;/li&gt;
&lt;li&gt;a CGPA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can define this structure using a Pydantic model.&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now FastAPI automatically validates incoming requests.&lt;/p&gt;

&lt;p&gt;For example, this request is valid:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
    "id": 4,&lt;br&gt;
    "name": "Karthik",&lt;br&gt;
    "department": "AI",&lt;br&gt;
    "cgpa": 8.8&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;But if someone sends:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
    "id": "four",&lt;br&gt;
    "name": "Karthik"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;FastAPI will automatically return a validation error because:&lt;/p&gt;

&lt;p&gt;id should be an integer&lt;br&gt;
required fields are missing&lt;/p&gt;

&lt;p&gt;This saves us from writing validation code manually.&lt;br&gt;
We'll explore Pydantic, validation, optional fields, custom validators, and advanced request handling in a dedicated article later in this series.&lt;/p&gt;
&lt;h2&gt;
  
  
  POST Request
&lt;/h2&gt;

&lt;p&gt;POST requests are used to create new resources.&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cgpa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.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;/student&lt;/span&gt;&lt;span class="sh"&gt;"&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;add_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student added successfully&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;student&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request Body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Karthik"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cgpa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PUT Request
&lt;/h2&gt;

&lt;p&gt;PUT requests are used to update existing resources.&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="nd"&gt;@app.put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;update_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;students&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;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student updated successfully&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;student&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;updated_student&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student not found&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;Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PUT /student/2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  DELETE Request
&lt;/h2&gt;

&lt;p&gt;DELETE requests are used to remove resources.&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="nd"&gt;@app.delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/student/{id}&lt;/span&gt;&lt;span class="sh"&gt;"&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;delete_student&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;students&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;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="n"&gt;deleted_student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student deleted successfully&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;student&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;deleted_student&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Student not found&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;Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELETE /student/3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  CRUD Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;HTTP Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;PUT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;DELETE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CRUD operations form the foundation of almost every backend application you'll build.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Right now, our data exists only in memory.&lt;/p&gt;

&lt;p&gt;If the server restarts, everything disappears.&lt;/p&gt;

&lt;p&gt;In the next article, we'll connect FastAPI with SQLite and MySQL so our application can store data permanently, just like real-world production systems.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>fastapi</category>
      <category>python</category>
    </item>
    <item>
      <title>FastAPI for AI Engineers — Part 1: Why Every AI Backend Is Moving Toward FastAPI</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Fri, 29 May 2026 17:57:34 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-1-why-every-ai-backend-is-moving-toward-fastapi-45fg</link>
      <guid>https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-1-why-every-ai-backend-is-moving-toward-fastapi-45fg</guid>
      <description>&lt;p&gt;You open ChatGPT.&lt;/p&gt;

&lt;p&gt;You type a prompt.&lt;/p&gt;

&lt;p&gt;Within seconds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your request reaches a backend server,&lt;/li&gt;
&lt;li&gt;the backend communicates with an LLM,&lt;/li&gt;
&lt;li&gt;retrieves memory,&lt;/li&gt;
&lt;li&gt;queries vector databases,&lt;/li&gt;
&lt;li&gt;processes context,&lt;/li&gt;
&lt;li&gt;and streams responses back to you in real time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern AI applications are no longer just “apps.”&lt;/p&gt;

&lt;p&gt;They are systems made up of multiple services constantly communicating with each other through APIs.&lt;/p&gt;

&lt;p&gt;And one framework has quietly become the default choice for building these modern AI backends:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FastAPI.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we’ll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why APIs are essential,&lt;/li&gt;
&lt;li&gt;why modern AI systems depend heavily on them,&lt;/li&gt;
&lt;li&gt;what FastAPI actually is,&lt;/li&gt;
&lt;li&gt;and why it became the preferred backend framework for AI engineers.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Modern Applications Are API Systems
&lt;/h2&gt;

&lt;p&gt;Most applications today are distributed systems.&lt;/p&gt;

&lt;p&gt;Your frontend, backend, database, authentication service, payment gateway, and AI models continuously exchange data with one another.&lt;/p&gt;

&lt;p&gt;When you order food online:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend → Backend API → Database → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use an AI chatbot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → FastAPI Backend → LLM → Vector DB → Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;frontend applications would directly access databases,&lt;/li&gt;
&lt;li&gt;systems would become tightly coupled,&lt;/li&gt;
&lt;li&gt;security would become difficult,&lt;/li&gt;
&lt;li&gt;scaling would become messy,&lt;/li&gt;
&lt;li&gt;and AI applications would be extremely difficult to maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;APIs act as communication bridges between systems.&lt;/p&gt;

&lt;p&gt;They define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how requests are sent,&lt;/li&gt;
&lt;li&gt;what data is expected,&lt;/li&gt;
&lt;li&gt;and what responses should be returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern software runs on APIs.&lt;/p&gt;

&lt;p&gt;Modern AI systems depend on them even more.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Exactly Is an API?
&lt;/h2&gt;

&lt;p&gt;API stands for &lt;strong&gt;Application Programming Interface&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An API allows two software systems to communicate with each other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a frontend sends a request,&lt;/li&gt;
&lt;li&gt;the backend processes it,&lt;/li&gt;
&lt;li&gt;and returns a response (usually JSON).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello World"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every major application you use today relies heavily on APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instagram&lt;/li&gt;
&lt;li&gt;Netflix&lt;/li&gt;
&lt;li&gt;Uber&lt;/li&gt;
&lt;li&gt;Spotify&lt;/li&gt;
&lt;li&gt;ChatGPT&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;recommendation systems&lt;/li&gt;
&lt;li&gt;RAG applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;APIs are the foundation of modern backend engineering.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AI Applications Changed Backend Development
&lt;/h2&gt;

&lt;p&gt;Traditional web applications were already API-heavy.&lt;/p&gt;

&lt;p&gt;But AI applications introduced entirely new backend challenges.&lt;/p&gt;

&lt;p&gt;Modern AI systems constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;communicate with LLM APIs,&lt;/li&gt;
&lt;li&gt;query vector databases,&lt;/li&gt;
&lt;li&gt;retrieve embeddings,&lt;/li&gt;
&lt;li&gt;stream responses,&lt;/li&gt;
&lt;li&gt;interact with external tools,&lt;/li&gt;
&lt;li&gt;and handle concurrent requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This created a need for backend frameworks that were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lightweight,&lt;/li&gt;
&lt;li&gt;fast,&lt;/li&gt;
&lt;li&gt;asynchronous,&lt;/li&gt;
&lt;li&gt;scalable,&lt;/li&gt;
&lt;li&gt;and developer-friendly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where FastAPI entered.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is FastAPI?
&lt;/h2&gt;

&lt;p&gt;FastAPI is a modern Python framework designed specifically for building APIs.&lt;/p&gt;

&lt;p&gt;It became popular because it combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;high performance,&lt;/li&gt;
&lt;li&gt;async support,&lt;/li&gt;
&lt;li&gt;automatic validation,&lt;/li&gt;
&lt;li&gt;clean developer experience,&lt;/li&gt;
&lt;li&gt;and excellent scalability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FastAPI is built on top of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Starlette&lt;/strong&gt; → provides ASGI and async capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pydantic&lt;/strong&gt; → handles data validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uvicorn&lt;/strong&gt; → runs FastAPI applications efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, this stack became perfect for modern AI systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
        Client Request
               │
               ▼
         ┌─────────┐
         │ FastAPI │
         └────┬────┘
              │
     ┌────────┼────────┐
     ▼                 ▼
 Starlette         Pydantic
 (ASGI/Async)     (Validation)
              │
              ▼
           Uvicorn
        (ASGI Server)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why FastAPI Became the Standard for AI Backends
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. Async Support
&lt;/h2&gt;

&lt;p&gt;This is one of the biggest reasons FastAPI exploded in popularity.&lt;/p&gt;

&lt;p&gt;AI applications constantly wait for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLM responses,&lt;/li&gt;
&lt;li&gt;vector database retrieval,&lt;/li&gt;
&lt;li&gt;external APIs,&lt;/li&gt;
&lt;li&gt;embeddings,&lt;/li&gt;
&lt;li&gt;cloud services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FastAPI supports asynchronous programming using Python’s &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;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="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_response&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Async response&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;Instead of blocking the server while waiting for responses, FastAPI can efficiently handle multiple requests concurrently.&lt;/p&gt;

&lt;p&gt;For AI systems, this matters a lot.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Built on Starlette
&lt;/h2&gt;

&lt;p&gt;FastAPI uses Starlette underneath.&lt;/p&gt;

&lt;p&gt;Starlette provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASGI support,&lt;/li&gt;
&lt;li&gt;middleware,&lt;/li&gt;
&lt;li&gt;WebSockets,&lt;/li&gt;
&lt;li&gt;background tasks,&lt;/li&gt;
&lt;li&gt;async request handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes FastAPI much better suited for modern real-time AI applications compared to older synchronous architectures.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Powered by Uvicorn
&lt;/h2&gt;

&lt;p&gt;FastAPI applications are commonly run using Uvicorn.&lt;/p&gt;

&lt;p&gt;Start a FastAPI server using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; → filename&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt; → FastAPI instance&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--reload&lt;/code&gt; → automatically reloads during development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uvicorn is an ASGI server optimized for high-performance asynchronous applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Automatic Swagger UI Documentation
&lt;/h2&gt;

&lt;p&gt;One of FastAPI’s most loved features is automatic API documentation.&lt;/p&gt;

&lt;p&gt;The moment you create routes, FastAPI automatically generates interactive API documentation for you.&lt;/p&gt;

&lt;p&gt;Visit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test endpoints,&lt;/li&gt;
&lt;li&gt;send requests,&lt;/li&gt;
&lt;li&gt;inspect responses,&lt;/li&gt;
&lt;li&gt;and debug APIs directly from the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This becomes incredibly useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working with frontend developers,&lt;/li&gt;
&lt;li&gt;building AI APIs,&lt;/li&gt;
&lt;li&gt;or testing backend systems quickly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Automatic Data Validation Using Pydantic
&lt;/h2&gt;

&lt;p&gt;FastAPI uses Python type hints for validation.&lt;/p&gt;

&lt;p&gt;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;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If invalid data is sent, FastAPI automatically validates and rejects it.&lt;/p&gt;

&lt;p&gt;This removes a huge amount of manual validation code developers previously had to write themselves.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing FastAPI
&lt;/h2&gt;

&lt;p&gt;Install FastAPI and Uvicorn:&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;fastapi uvicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Your First FastAPI Application
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;main.py&lt;/code&gt;&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;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/&lt;/span&gt;&lt;span class="sh"&gt;"&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;home&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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;Welcome to Dev.io&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;&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.amazonaws.com%2Fuploads%2Farticles%2Ffroaj5gsyore8nbdjufr.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.amazonaws.com%2Fuploads%2Farticles%2Ffroaj5gsyore8nbdjufr.png" alt="Sample example of home function" width="438" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.amazonaws.com%2Fuploads%2Farticles%2Fo6rrj2igftkg7gpiim6k.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.amazonaws.com%2Fuploads%2Farticles%2Fo6rrj2igftkg7gpiim6k.png" alt="Sample example of Swagger UI docs" width="800" height="313"&gt;&lt;/a&gt;&lt;br&gt;
And you’ll see FastAPI’s automatically generated Swagger UI.&lt;/p&gt;

&lt;p&gt;At this point, you already have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a running backend server,&lt;/li&gt;
&lt;li&gt;a working API,&lt;/li&gt;
&lt;li&gt;and interactive API documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With surprisingly little code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why FastAPI Matters for AI Engineers
&lt;/h2&gt;

&lt;p&gt;FastAPI became extremely popular because modern AI applications are fundamentally API systems.&lt;/p&gt;

&lt;p&gt;It is heavily used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAG pipelines,&lt;/li&gt;
&lt;li&gt;AI agents,&lt;/li&gt;
&lt;li&gt;chatbot backends,&lt;/li&gt;
&lt;li&gt;LangChain applications,&lt;/li&gt;
&lt;li&gt;vector database APIs,&lt;/li&gt;
&lt;li&gt;recommendation systems,&lt;/li&gt;
&lt;li&gt;and model-serving APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern AI engineering is not just about building models anymore.&lt;/p&gt;

&lt;p&gt;It’s also about building scalable systems around those models.&lt;/p&gt;

&lt;p&gt;And FastAPI fits perfectly into that ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;FastAPI didn’t become popular accidentally.&lt;/p&gt;

&lt;p&gt;It became the framework of choice for AI engineers because modern AI systems are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;asynchronous,&lt;/li&gt;
&lt;li&gt;API-driven,&lt;/li&gt;
&lt;li&gt;performance-sensitive,&lt;/li&gt;
&lt;li&gt;and highly modular.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents,&lt;/li&gt;
&lt;li&gt;chat systems,&lt;/li&gt;
&lt;li&gt;RAG applications,&lt;/li&gt;
&lt;li&gt;or production AI platforms,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FastAPI provides the exact architecture modern AI applications need.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;Right now, our API returns data, but it doesn’t actually store anything permanently.&lt;/p&gt;

&lt;p&gt;In the next article, we’ll build real CRUD APIs using FastAPI and understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET requests,&lt;/li&gt;
&lt;li&gt;POST requests,&lt;/li&gt;
&lt;li&gt;PUT requests,&lt;/li&gt;
&lt;li&gt;DELETE requests,&lt;/li&gt;
&lt;li&gt;and how backend applications manage data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we’ll move toward integrating databases like SQLite and MySQL in the following parts of this series.&lt;/p&gt;

&lt;p&gt;Check out the next post here:&lt;br&gt;
&lt;a href="https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl"&gt;https://dev.to/zeroshotanu/fastapi-for-ai-engineers-part-2-building-your-first-crud-api-lpl&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>api</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>How I Built an AI-Powered Incident RCA Platform with LangGraph and RAG</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Tue, 26 May 2026 03:23:00 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/how-i-built-an-ai-powered-incident-rca-platform-with-langgraph-and-rag-423j</link>
      <guid>https://dev.to/zeroshotanu/how-i-built-an-ai-powered-incident-rca-platform-with-langgraph-and-rag-423j</guid>
      <description>&lt;p&gt;It’s 2:13 AM.&lt;/p&gt;

&lt;p&gt;A payment API suddenly starts failing in production.&lt;/p&gt;

&lt;p&gt;Customers can’t complete transactions. Alerts begin firing everywhere. Dashboards turn red. Kubernetes pods restart unexpectedly. Database connections start timing out.&lt;/p&gt;

&lt;p&gt;And somewhere, an exhausted engineer opens Datadog and starts scrolling through thousands of logs trying to answer a single question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What actually broke?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern systems generate enormous amounts of telemetry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;alerts&lt;/li&gt;
&lt;li&gt;traces&lt;/li&gt;
&lt;li&gt;metrics&lt;/li&gt;
&lt;li&gt;infrastructure events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem isn’t the lack of monitoring anymore.&lt;/p&gt;

&lt;p&gt;The problem is:&lt;/p&gt;

&lt;h2&gt;
  
  
  making sense of the chaos quickly enough during an outage.
&lt;/h2&gt;

&lt;p&gt;That idea became the starting point for &lt;strong&gt;OpsMind AI&lt;/strong&gt; — an AI-powered incident root cause analysis platform inspired by real-world DevOps and Site Reliability Engineering workflows.&lt;/p&gt;

&lt;p&gt;The goal was ambitious but simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Upload observability logs → identify probable root cause → generate remediation recommendations automatically.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Core Problem
&lt;/h2&gt;

&lt;p&gt;In modern distributed systems, a single failure rarely stays isolated.&lt;/p&gt;

&lt;p&gt;A database lock might cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API latency spikes&lt;/li&gt;
&lt;li&gt;gateway timeouts&lt;/li&gt;
&lt;li&gt;downstream service crashes&lt;/li&gt;
&lt;li&gt;Kubernetes restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During incidents, engineers manually jump between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grafana dashboards&lt;/li&gt;
&lt;li&gt;Datadog alerts&lt;/li&gt;
&lt;li&gt;New Relic traces&lt;/li&gt;
&lt;li&gt;raw log streams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;trying to correlate failures across services.&lt;/p&gt;

&lt;p&gt;This process is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;time-consuming&lt;/li&gt;
&lt;li&gt;mentally exhausting&lt;/li&gt;
&lt;li&gt;highly dependent on experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to explore whether multi-agent AI systems could assist in this process.&lt;/p&gt;

&lt;p&gt;Not just summarizing logs.&lt;/p&gt;

&lt;p&gt;But actually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieving similar historical incidents&lt;/li&gt;
&lt;li&gt;classifying incident severity&lt;/li&gt;
&lt;li&gt;reconstructing event timelines&lt;/li&gt;
&lt;li&gt;identifying affected services&lt;/li&gt;
&lt;li&gt;generating RCA explanations&lt;/li&gt;
&lt;li&gt;suggesting remediation steps&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Enter OpsMind AI
&lt;/h2&gt;

&lt;p&gt;OpsMind AI simulates an AI-driven observability assistant for SRE and DevOps teams.&lt;/p&gt;

&lt;p&gt;The platform processes observability logs through a &lt;strong&gt;LangGraph-based multi-agent workflow&lt;/strong&gt; that orchestrates specialized agents for different operational tasks.&lt;/p&gt;

&lt;p&gt;Instead of relying on a single monolithic LLM prompt, the system breaks incident investigation into multiple coordinated reasoning stages.&lt;/p&gt;




&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The workflow begins by ingesting logs from simulated monitoring platforms such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Datadog&lt;/li&gt;
&lt;li&gt;Grafana&lt;/li&gt;
&lt;li&gt;New Relic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logs are normalized and passed into a multi-agent orchestration pipeline.&lt;/p&gt;

&lt;p&gt;The architecture consists of:&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieval Agent
&lt;/h3&gt;

&lt;p&gt;Searches historical incidents using FAISS vector similarity search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incident Classification Agent
&lt;/h3&gt;

&lt;p&gt;Identifies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;incident type&lt;/li&gt;
&lt;li&gt;severity level&lt;/li&gt;
&lt;li&gt;monitoring source&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RCA Agent
&lt;/h3&gt;

&lt;p&gt;Performs root cause analysis and generates remediation recommendations using LLM reasoning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timeline &amp;amp; Impact Analysis
&lt;/h3&gt;

&lt;p&gt;Reconstructs operational event sequences and identifies affected downstream services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation Layer
&lt;/h3&gt;

&lt;p&gt;Measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;retrieval accuracy&lt;/li&gt;
&lt;li&gt;RCA quality&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;incident correlation confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend dashboard was built using Streamlit to simulate an operational observability console.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why RAG Was Important Here
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of the project was integrating retrieval-augmented generation.&lt;/p&gt;

&lt;p&gt;Production incidents often repeat patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;database pool exhaustion&lt;/li&gt;
&lt;li&gt;API rate limiting&lt;/li&gt;
&lt;li&gt;Kubernetes OOM crashes&lt;/li&gt;
&lt;li&gt;retry storms&lt;/li&gt;
&lt;li&gt;deadlocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of asking the LLM to reason from scratch every time, OpsMind AI retrieves semantically similar historical incidents from a FAISS vector database and uses them as contextual memory during RCA generation.&lt;/p&gt;

&lt;p&gt;This significantly improved the consistency of generated analyses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the Multi-Agent Workflow
&lt;/h2&gt;

&lt;p&gt;The orchestration layer uses LangGraph to model incident analysis as a graph of specialized AI agents.&lt;/p&gt;

&lt;p&gt;This made the workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modular&lt;/li&gt;
&lt;li&gt;explainable&lt;/li&gt;
&lt;li&gt;easier to visualize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing I particularly enjoyed was building the animated agent execution dashboard where each agent executes sequentially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieval Agent&lt;/li&gt;
&lt;li&gt;Classification Agent&lt;/li&gt;
&lt;li&gt;RCA Agent&lt;/li&gt;
&lt;li&gt;Timeline Agent&lt;/li&gt;
&lt;li&gt;Impact Analysis Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Watching the workflow execute in real time made the system feel much closer to an actual operational AI assistant rather than just another chatbot interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Simulating Real Production Incidents
&lt;/h2&gt;

&lt;p&gt;Since real enterprise observability data isn’t publicly available, I generated synthetic production-style incident logs for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes CrashLoopBackOff failures&lt;/li&gt;
&lt;li&gt;database connection exhaustion&lt;/li&gt;
&lt;li&gt;API rate limiting failures&lt;/li&gt;
&lt;li&gt;downstream gateway crashes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture was intentionally designed so that simulated connectors can later be replaced with real monitoring APIs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Evaluation Was Surprisingly Hard
&lt;/h2&gt;

&lt;p&gt;One unexpected realization during development:&lt;/p&gt;

&lt;p&gt;Building the RCA pipeline was easier than evaluating it.&lt;/p&gt;

&lt;p&gt;It’s very easy to generate convincing AI explanations.&lt;/p&gt;

&lt;p&gt;It’s much harder to measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether the RCA is actually correct&lt;/li&gt;
&lt;li&gt;whether retrieval is meaningful&lt;/li&gt;
&lt;li&gt;whether severity classification is reliable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why I added an evaluation layer measuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieval Accuracy&lt;/li&gt;
&lt;li&gt;RCA Match Accuracy&lt;/li&gt;
&lt;li&gt;Severity Accuracy&lt;/li&gt;
&lt;li&gt;Average Latency&lt;/li&gt;
&lt;li&gt;Correlation Confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding evaluation made the project feel significantly more engineering-focused rather than simply prompt-driven.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Streamlit&lt;/li&gt;
&lt;li&gt;LangGraph&lt;/li&gt;
&lt;li&gt;FAISS&lt;/li&gt;
&lt;li&gt;SentenceTransformers&lt;/li&gt;
&lt;li&gt;Groq LLM API&lt;/li&gt;
&lt;li&gt;Pandas&lt;/li&gt;
&lt;/ul&gt;







&lt;h2&gt;
  
  
  Building Under Hackathon Constraints
&lt;/h2&gt;

&lt;p&gt;OpsMind AI was originally built during a short-duration engineering hackathon focused on AI agents and developer infrastructure workflows.&lt;/p&gt;

&lt;p&gt;One interesting challenge was balancing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ambitious system design ideas&lt;/li&gt;
&lt;li&gt;realistic implementation scope&lt;/li&gt;
&lt;li&gt;evaluation reliability&lt;/li&gt;
&lt;li&gt;UI polish&lt;/li&gt;
&lt;li&gt;deployment constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted the project to feel less like a simple LLM wrapper and more like an actual operational intelligence platform, which is why I focused heavily on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multi-agent orchestration&lt;/li&gt;
&lt;li&gt;retrieval systems&lt;/li&gt;
&lt;li&gt;evaluation metrics&lt;/li&gt;
&lt;li&gt;workflow visualization&lt;/li&gt;
&lt;li&gt;observability-inspired architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even within a constrained timeline, building the system end-to-end — from synthetic telemetry generation to agent orchestration and evaluation — was an incredibly valuable learning experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This project taught me a lot about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observability systems&lt;/li&gt;
&lt;li&gt;multi-agent orchestration&lt;/li&gt;
&lt;li&gt;RAG pipelines&lt;/li&gt;
&lt;li&gt;AI evaluation strategies&lt;/li&gt;
&lt;li&gt;operational intelligence workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, it changed how I think about AI systems.&lt;/p&gt;

&lt;p&gt;The interesting challenge wasn’t generating text.&lt;/p&gt;

&lt;p&gt;It was designing systems that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reason through operational data&lt;/li&gt;
&lt;li&gt;coordinate specialized agents&lt;/li&gt;
&lt;li&gt;retrieve contextual memory&lt;/li&gt;
&lt;li&gt;produce actionable outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That feels much closer to how real-world AI systems will evolve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo &amp;amp; Repository
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Repository
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Anucool419/OpsMind-AI" rel="noopener noreferrer"&gt;https://github.com/Anucool419/OpsMind-AI&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo Video
&lt;/h3&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/OTj5cE5ortQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;p&gt;Some things I’d love to explore next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;real-time telemetry ingestion&lt;/li&gt;
&lt;li&gt;live Datadog/New Relic integrations&lt;/li&gt;
&lt;li&gt;Slack incident alerting&lt;/li&gt;
&lt;li&gt;autonomous remediation workflows&lt;/li&gt;
&lt;li&gt;distributed tracing support&lt;/li&gt;
&lt;li&gt;long-term incident memory systems&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;What started as a simple idea — “Can AI help investigate production incidents faster?” — turned into a much deeper exploration of how intelligent systems can assist engineering operations.&lt;/p&gt;

&lt;p&gt;The most interesting part of building OpsMind AI wasn’t the UI or even the LLM integration.&lt;/p&gt;

&lt;p&gt;It was understanding how modern operational systems actually behave:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cascading failures&lt;/li&gt;
&lt;li&gt;noisy telemetry&lt;/li&gt;
&lt;li&gt;infrastructure dependencies&lt;/li&gt;
&lt;li&gt;repeated incident patterns&lt;/li&gt;
&lt;li&gt;operational uncertainty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project made me realize that the future of AI in engineering is not just about chat interfaces.&lt;/p&gt;

&lt;p&gt;It’s about building systems that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reason over complex environments&lt;/li&gt;
&lt;li&gt;retrieve operational memory&lt;/li&gt;
&lt;li&gt;coordinate specialized agents&lt;/li&gt;
&lt;li&gt;assist humans during high-pressure decision making&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpsMind AI is still a prototype, but building it gave me a much deeper appreciation for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observability engineering&lt;/li&gt;
&lt;li&gt;SRE workflows&lt;/li&gt;
&lt;li&gt;AI orchestration systems&lt;/li&gt;
&lt;li&gt;evaluation-driven AI development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And honestly, that combination of AI + systems engineering is one of the most exciting areas to explore right now. Do suggest any improvements you think I should make or share your experiences.&lt;/p&gt;




&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langgraph</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🚀 This AI Tells You What to Study for Exams</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Mon, 04 May 2026 17:45:51 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/this-ai-tells-you-what-to-study-for-exams-35ji</link>
      <guid>https://dev.to/zeroshotanu/this-ai-tells-you-what-to-study-for-exams-35ji</guid>
      <description>&lt;p&gt;Consider this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s 3 days before your exam.&lt;br&gt;
You have 5 units. 2 are huge. 1 is confusing.&lt;br&gt;
And you’re thinking:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What do I actually study?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you open past papers.&lt;/p&gt;

&lt;p&gt;You start spotting patterns… maybe.&lt;/p&gt;

&lt;p&gt;But it’s slow. Inconsistent. And honestly — a bit of guessing.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What if that entire process was automated?
&lt;/h2&gt;

&lt;p&gt;What if you could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload past papers 📄&lt;/li&gt;
&lt;li&gt;Instantly see &lt;strong&gt;what matters most&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Identify &lt;strong&gt;high-weightage topics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Know what’s &lt;strong&gt;missing from your prep&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Get a &lt;strong&gt;day-wise study plan&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's the solution I built and prototyped in 6 hours during a GenAI hackathon&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Introducing: AI Exam Strategist
&lt;/h2&gt;

&lt;p&gt;A system that analyzes past question papers and turns them into &lt;strong&gt;actionable study strategy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not just summaries. Not just answers.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Actual decision-making support for exams.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What It Does
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📂 Multi-Paper Analysis
&lt;/h3&gt;

&lt;p&gt;Upload multiple past papers → the system processes them together and extracts meaningful patterns.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔍 Pattern Detection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Finds &lt;strong&gt;frequently asked topics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Classifies &lt;strong&gt;difficulty levels&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Identifies &lt;strong&gt;year-wise trends&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Helps you focus on topics with the &lt;strong&gt;highest exam impact&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Syllabus Mapping
&lt;/h3&gt;

&lt;p&gt;Upload your syllabus → instantly see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Topics already appearing in exams&lt;/li&gt;
&lt;li&gt;❌ Topics not covered (potential blind spots)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📊 Visual Insights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Topic frequency charts&lt;/li&gt;
&lt;li&gt;Difficulty distribution&lt;/li&gt;
&lt;li&gt;Topic vs difficulty breakdown&lt;/li&gt;
&lt;li&gt;Year-wise trends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Patterns become &lt;strong&gt;obvious at a glance&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Smart Study Planner
&lt;/h3&gt;

&lt;p&gt;Generates a &lt;strong&gt;day-wise plan&lt;/strong&gt; based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;available time&lt;/li&gt;
&lt;li&gt;topic importance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Designed for &lt;strong&gt;maximum ROI under time constraints&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  📝 Practice Question Generator
&lt;/h3&gt;

&lt;p&gt;Select a topic → generate relevant practice questions instantly.&lt;/p&gt;




&lt;h3&gt;
  
  
  💬 AI Assistant
&lt;/h3&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What should I prioritize?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Get answers grounded in your own analyzed data.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; → backend APIs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit&lt;/strong&gt; → interactive UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groq API (LLM)&lt;/strong&gt; → classification &amp;amp; generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; → structured workflow orchestration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pandas&lt;/strong&gt; → data processing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ How It Works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upload Papers → Extract Questions → Classify (Topic + Difficulty)
→ Analyze Patterns → Map with Syllabus → Generate Insights
→ Create Study Plan → Practice + AI Chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🤔 Did I Use RAG?
&lt;/h2&gt;

&lt;p&gt;Not in this version.&lt;/p&gt;

&lt;p&gt;Since the dataset is relatively small, I used:&lt;br&gt;
👉 &lt;strong&gt;context injection (passing structured analysis directly to the LLM)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This keeps the system fast and simple.&lt;/p&gt;

&lt;p&gt;For larger-scale usage, this can evolve into a &lt;strong&gt;RAG-based system with vector search&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  📏 Evaluation (Keeping It Real)
&lt;/h2&gt;

&lt;p&gt;I added a basic evaluation layer to understand how the system behaves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used a &lt;strong&gt;small, manually created dataset&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Measured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Topic classification&lt;/li&gt;
&lt;li&gt;Difficulty classification&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;⚠️ Important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accuracy may appear low if you try it yourself&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dataset is small&lt;/li&gt;
&lt;li&gt;matching is strict (semantic matches may be marked wrong)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 The goal wasn’t perfect scoring —&lt;br&gt;
but to &lt;strong&gt;validate the system’s reasoning and consistency&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Building GenAI systems is more about &lt;strong&gt;pipelines than prompts&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;LLM outputs are messy — &lt;strong&gt;normalization is critical&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Evaluation in AI is not straightforward&lt;/li&gt;
&lt;li&gt;Simple approaches (like context injection) can outperform complex ones for MVPs&lt;/li&gt;
&lt;li&gt;Speed + clarity &amp;gt; overengineering&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔮 Future Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OCR for scanned PDFs&lt;/li&gt;
&lt;li&gt;Semantic topic matching using embeddings&lt;/li&gt;
&lt;li&gt;Persistent memory across sessions&lt;/li&gt;
&lt;li&gt;Scalable deployment&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎥 Demo &amp;amp; Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 GitHub: &lt;em&gt;&lt;a href="https://github.com/Anucool419/AI-Exam_Strategist" rel="noopener noreferrer"&gt;https://github.com/Anucool419/AI-Exam_Strategist&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;🎥 Demo Video: &lt;em&gt;&lt;a href="https://www.loom.com/share/04005565701e45d1855d1fa13bcee73a" rel="noopener noreferrer"&gt;https://www.loom.com/share/04005565701e45d1855d1fa13bcee73a&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;🌐 Live App: &lt;em&gt;&lt;a href="https://ai-examstrategist-ryjarq6usrfbsd85gipexy.streamlit.app/" rel="noopener noreferrer"&gt;https://ai-examstrategist-ryjarq6usrfbsd85gipexy.streamlit.app/&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚠️ Note: The live demo UI is deployed, but the backend runs locally. Full functionality is shown in the demo video.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Exams aren’t just about how much you study.&lt;/p&gt;

&lt;p&gt;They’re about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what you choose to study&lt;/li&gt;
&lt;li&gt;how you prioritize&lt;/li&gt;
&lt;li&gt;how well you use limited time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And right now, students are expected to figure that out manually.&lt;/p&gt;

&lt;p&gt;This project explores a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if AI could guide those decisions?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not replace studying.&lt;br&gt;
Not shortcut learning.&lt;/p&gt;

&lt;p&gt;But make preparation &lt;strong&gt;more focused, more intentional, and more efficient&lt;/strong&gt;.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Because sometimes, the smartest move…&lt;br&gt;
is knowing what &lt;em&gt;not&lt;/em&gt; to study.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In &lt;em&gt;~6 hours&lt;/em&gt;, this went from an idea to a working system.&lt;/p&gt;

&lt;p&gt;It’s not perfect — but it solves a real problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Maximizing study ROI when time is limited
&lt;/h3&gt;
&lt;/blockquote&gt;




&lt;p&gt;Would love your thoughts 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>genai</category>
      <category>productivity</category>
      <category>python</category>
    </item>
    <item>
      <title>🚀 I Built an AI-Powered Fest Assistant with Agents, RAG &amp; Planning (Pragyan @ NITT)</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Tue, 14 Apr 2026 17:57:01 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/i-built-an-ai-powered-fest-assistant-with-agents-rag-planning-pragyan-nitt-44e9</link>
      <guid>https://dev.to/zeroshotanu/i-built-an-ai-powered-fest-assistant-with-agents-rag-planning-pragyan-nitt-44e9</guid>
      <description>&lt;p&gt;I deleted Instagram more than a year ago, and honestly, it saved me from a lot of distractions.&lt;/p&gt;

&lt;p&gt;But there was an unexpected downside.&lt;/p&gt;

&lt;p&gt;A lot of informal, real-time information — especially during college events — still lives there.&lt;/p&gt;

&lt;p&gt;During our college fest, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event schedules&lt;/li&gt;
&lt;li&gt;Last-minute updates&lt;/li&gt;
&lt;li&gt;Food stall announcements&lt;/li&gt;
&lt;li&gt;Informal activities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…everything gets posted on Instagram.&lt;/p&gt;

&lt;p&gt;At the same time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fest details and significance are on the official website&lt;/li&gt;
&lt;li&gt;Food stall info is on a separate app&lt;/li&gt;
&lt;li&gt;The entire 3-day schedule is compressed into a few posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s no single place to get a clear, structured view of everything.&lt;/p&gt;

&lt;p&gt;And that’s when it hit me:&lt;/p&gt;

&lt;p&gt;Most college fests have websites.&lt;br&gt;
Some even have apps.&lt;/p&gt;

&lt;p&gt;But none of them actually &lt;strong&gt;help you navigate the fest intelligently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They give information.&lt;br&gt;
They don’t give guidance.&lt;/p&gt;

&lt;p&gt;But I wanted to build something smarter —&lt;br&gt;
an &lt;strong&gt;AI assistant that actually understands queries, plans your day, and even helps you find teammates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, I built &lt;strong&gt;Pragyan Mentor Assistant&lt;/strong&gt; — an AI-powered system for navigating a techno-managerial fest.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Problem
&lt;/h2&gt;

&lt;p&gt;During college fests like Pragyan (NIT Trichy):&lt;br&gt;
There are &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are &lt;strong&gt;dozens of events, workshops, and shows&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Information is scattered across PDFs, sites, and posters&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users don’t know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what to attend&lt;/li&gt;
&lt;li&gt;what matches their interests&lt;/li&gt;
&lt;li&gt;how to plan their time&lt;/li&gt;
&lt;li&gt;who to team up with&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 Traditional apps = static information&lt;br&gt;
👉 I wanted &lt;strong&gt;intelligent interaction&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Solution
&lt;/h2&gt;

&lt;p&gt;I built a &lt;strong&gt;multi-tool AI assistant&lt;/strong&gt; that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎉 Answer questions about events, workshops, proshows&lt;/li&gt;
&lt;li&gt;🍔 Show food stalls &amp;amp; mess menu&lt;/li&gt;
&lt;li&gt;🧠 Recommend activities based on user intent&lt;/li&gt;
&lt;li&gt;📅 Plan your schedule&lt;/li&gt;
&lt;li&gt;🤝 Match you with like-minded participants/Suggest potential teammates (prototype)&lt;/li&gt;
&lt;li&gt;📚 Answer fest-related questions using RAG&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 System Design
&lt;/h2&gt;

&lt;p&gt;Instead of a simple chatbot, I designed it as a &lt;strong&gt;tool-using agent system&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fetch_events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fetch_workshops&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fetch_food_stall&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fetch_mess_menu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pragyan_bot&lt;/code&gt; (RAG-based)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;smart_recommender&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;planner&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buddy_matcher&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔹 Agent Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;User query&lt;/li&gt;
&lt;li&gt;LLM decides:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Which tool to call

&lt;ol&gt;
&lt;li&gt;Tool executes&lt;/li&gt;
&lt;li&gt;Response is generated in natural language&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📚 Retrieval Approach
&lt;/h3&gt;

&lt;p&gt;This system uses a hybrid retrieval strategy at the system level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Structured retrieval (keyword-based)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Direct tool calls for events/workshops&lt;/li&gt;
&lt;li&gt;Fast and deterministic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Semantic retrieval (RAG)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vector search over fest documents&lt;/li&gt;
&lt;li&gt;Handles open-ended queries&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;👉 This combination allows both precision and flexibility&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 RAG (Retrieval Augmented Generation)
&lt;/h2&gt;

&lt;p&gt;To handle fest knowledge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text files (events, shows, lectures, FAQs)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FAISS vector store&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Retrieval:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic search on query&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context-aware answers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Memory
&lt;/h2&gt;

&lt;p&gt;Using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;InMemorySaver()&lt;/code&gt; (LangGraph)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;remembering user preferences&lt;/li&gt;
&lt;li&gt;better recommendations&lt;/li&gt;
&lt;li&gt;conversational continuity&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤖 Smart Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎯 Recommendations
&lt;/h3&gt;

&lt;p&gt;Understands intent like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What should I attend if I like tech and fun?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  📅 Planner Agent
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Plan my next 3 hours"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Generates a structured schedule based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;time&lt;/li&gt;
&lt;li&gt;interests&lt;/li&gt;
&lt;li&gt;available events&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🤝 Buddy Matching (Prototype)
&lt;/h3&gt;

&lt;p&gt;Matches based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interests&lt;/li&gt;
&lt;li&gt;level&lt;/li&gt;
&lt;li&gt;context (e.g. case study competitions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uses a small dataset to demonstrate logic&lt;/p&gt;




&lt;h2&gt;
  
  
  🖥️ UI
&lt;/h2&gt;

&lt;p&gt;Built with &lt;strong&gt;Streamlit&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chat-based interface&lt;/li&gt;
&lt;li&gt;Quick action buttons&lt;/li&gt;
&lt;li&gt;Structured responses&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Deployment
&lt;/h2&gt;

&lt;p&gt;Deployed on Render (free tier)&lt;br&gt;
Environment variables for API security&lt;/p&gt;




&lt;p&gt;&lt;a href="" class="article-body-image-wrapper"&gt;&lt;img width="100%"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎥 Demo
&lt;/h2&gt;

&lt;p&gt;👉 &lt;a href="https://www.loom.com/share/13f87025a9154a55b80fc240bfc91ba2" rel="noopener noreferrer"&gt;https://www.loom.com/share/13f87025a9154a55b80fc240bfc91ba2&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;LangChain&lt;/li&gt;
&lt;li&gt;OpenAI API&lt;/li&gt;
&lt;li&gt;FAISS&lt;/li&gt;
&lt;li&gt;Streamlit&lt;/li&gt;
&lt;li&gt;Render&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Challenges Faced
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RAG retrieval quality (chunking + parsing issues)&lt;/li&gt;
&lt;li&gt;Tool selection accuracy&lt;/li&gt;
&lt;li&gt;Structuring multi-agent workflow&lt;/li&gt;
&lt;li&gt;Deployment + API key handling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔄 Ongoing Improvements
&lt;/h2&gt;

&lt;p&gt;Some features I’m actively working on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding database-backed user profiles for real buddy matching&lt;/li&gt;
&lt;li&gt;Improving RAG with better retrieval and evaluation&lt;/li&gt;
&lt;li&gt;Expanding dataset coverage for more complete fest information&lt;/li&gt;
&lt;li&gt;Exploring true hybrid retrieval + reranking&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📈 What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Building &lt;strong&gt;agents &amp;gt; building chatbots&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;RAG needs &lt;strong&gt;data structuring, not just embeddings&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;UI matters a lot for perceived intelligence&lt;/li&gt;
&lt;li&gt;Deployment and debugging are part of the real challenge&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔒 Live demo available on request&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💭 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project made me realize:&lt;/p&gt;

&lt;p&gt;👉 The future isn’t just about LLMs&lt;br&gt;
👉 It’s about &lt;strong&gt;systems built around them&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;If you have suggestions or ideas to improve this, I’d love to hear them!&lt;/p&gt;




</description>
      <category>ai</category>
      <category>python</category>
      <category>langchain</category>
      <category>rag</category>
    </item>
    <item>
      <title>Stop Calling FAISS a Database: The VectorStore vs. VectorDB Showdown🧠⚡</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Tue, 17 Mar 2026 16:40:58 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/stop-calling-faiss-a-database-the-vectorstore-vs-vectordb-showdown-4g94</link>
      <guid>https://dev.to/zeroshotanu/stop-calling-faiss-a-database-the-vectorstore-vs-vectordb-showdown-4g94</guid>
      <description>&lt;p&gt;If you’ve been building with LangChain, you’ve probably used Chroma or FAISS and called them "databases." But in a production environment, that distinction could be the difference between a smooth app and a total system crash.&lt;/p&gt;

&lt;p&gt;As AI Engineers, we need to know when to use a lightweight VectorStore and when to upgrade to a full Vector Database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a VectorStore? (The Engine)
&lt;/h2&gt;

&lt;p&gt;A VectorStore is a specialized data structure or a local library. Its primary job is simple: Calculate the distance between vectors as fast as possible.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Best for&lt;/em&gt;: Prototypes, local research, and small datasets.&lt;br&gt;
&lt;em&gt;Pros&lt;/em&gt;: Zero latency (runs in-process), easy to set up, free.&lt;br&gt;
&lt;em&gt;Cons&lt;/em&gt;: If your app restarts, your data might vanish (if not saved to disk). It doesn't scale across multiple servers easily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Popular Choice&lt;/em&gt;: FAISS (by Meta). It's incredibly fast but lacks "database" features like user authentication or real-time updates.&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;langchain_community.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Initialize Embeddings
&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Create the VectorStore (In-memory)
&lt;/span&gt;&lt;span class="n"&gt;texts&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;AI is transforming civil engineering&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;LangChain is a framework for LLMs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;vector_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_texts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Search (Fast, but only local)
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is LangChain?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Persistence (Manual step required)
&lt;/span&gt;&lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save_local&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_faiss_index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;# To use it later, you must load_local() manually
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is a Vector Database? (The Full System)
&lt;/h2&gt;

&lt;p&gt;A Vector Database is a production-ready management system. It uses a vector store under the hood but wraps it in the features we expect from enterprise software.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Best for:&lt;/em&gt; Production apps, multi-user systems, and massive datasets (millions of vectors).&lt;/p&gt;

&lt;p&gt;The "Extras" you get:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Persistence&lt;/em&gt;: Your data lives on a server, not just in your RAM.&lt;br&gt;
&lt;em&gt;Metadata Filtering&lt;/em&gt;: The ability to say "Find similar vectors, but only for documents created in 2024."&lt;br&gt;
&lt;em&gt;Scalability&lt;/em&gt;: It can handle billions of vectors by spreading them across different "pods" or nodes.&lt;/p&gt;

&lt;p&gt;Popular Choice: Pinecone or Weaviate.&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;langchain_pinecone&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PineconeVectorStore&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pinecone&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pinecone&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Initialize Cloud Client
&lt;/span&gt;&lt;span class="n"&gt;pc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pinecone&lt;/span&gt;&lt;span class="p"&gt;(&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;YOUR_PINECONE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;index_name&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-production-index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Connect to the Index (Data lives on Pinecone's servers)
&lt;/span&gt;&lt;span class="n"&gt;vector_db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PineconeVectorStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_texts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;texts&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;B.Tech students at NITT are building AI agents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;OpenAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;index_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;index_name&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Search (API Call to the cloud)
# Anyone with the API key can now query this from any device
&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Who is building agents?&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;&lt;strong&gt;Key Observation&lt;/strong&gt;: There is no "save" step. The moment you run from_texts, the data is permanently stored in the cloud. You can delete your local code, and the data remains accessible.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;VectorStore (e.g., FAISS, Chroma)&lt;/th&gt;
&lt;th&gt;Vector Database (e.g., Pinecone, Milvus)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A library that runs &lt;strong&gt;inside&lt;/strong&gt; your application code.&lt;/td&gt;
&lt;td&gt;A standalone &lt;strong&gt;distributed system&lt;/strong&gt; running on a server.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Persistence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mostly &lt;strong&gt;In-Memory&lt;/strong&gt;. Data is lost when the script ends.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Persistent by default&lt;/strong&gt;. Data is stored on cloud/disk.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited by your machine's &lt;strong&gt;RAM/Disk&lt;/strong&gt;. Hard to scale.&lt;/td&gt;
&lt;td&gt;Built for &lt;strong&gt;Horizontal Scaling&lt;/strong&gt;. Handles billions of vectors.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-tenancy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No built-in support for isolated users.&lt;/td&gt;
&lt;td&gt;High. Supports multiple users and &lt;strong&gt;isolated indexes&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CRUD Operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hard to update specific vectors without rebuilding.&lt;/td&gt;
&lt;td&gt;Full &lt;strong&gt;Create, Read, Update, Delete&lt;/strong&gt; support via API.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metadata&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic filtering capabilities.&lt;/td&gt;
&lt;td&gt;Advanced &lt;strong&gt;Metadata Filtering&lt;/strong&gt; (e.g., Filter by date).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Free&lt;/strong&gt; (Uses your local resources).&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Tiered&lt;/strong&gt;. Free tiers available, then paid.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Let's Discuss!&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Are you currently using a local store like Chroma or have you made the jump to a cloud database? What's the biggest challenge you've faced with vector scaling? Drop a comment below! 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>vectordatabase</category>
      <category>python</category>
    </item>
    <item>
      <title>Decoding Embedding Models: Why Your RAG Is Only as Good as Your Vectors 🚀</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Mon, 09 Mar 2026 17:36:43 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/decoding-embedding-models-why-your-rag-is-only-as-good-as-your-vectors-4k0n</link>
      <guid>https://dev.to/zeroshotanu/decoding-embedding-models-why-your-rag-is-only-as-good-as-your-vectors-4k0n</guid>
      <description>&lt;p&gt;As an AI Engineer, the first major decision you make in a RAG (Retrieval-Augmented Generation) pipeline isn't which LLM to use—it's which Embedding Model will represent your data. If your vectors are low-quality, your retrieval will fail, and even a top-tier LLM can't save a response based on the wrong context.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ What exactly is an Embedding?
&lt;/h2&gt;

&lt;p&gt;Embedding models take text tokens and map them into a multi-dimensional coordinate system (vectors).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Dimensions&lt;/em&gt;&lt;/strong&gt;: These represent the "features" the model understands. Different models represent words in vectors of different dimensions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Semantic Proximity&lt;/em&gt;&lt;/strong&gt;: In a good model, the vector for "King" and "Queen" will be mathematically closer than "King" and "Keyboard."&lt;/p&gt;

&lt;h2&gt;
  
  
  🌟 Popular Embedding Models: Hugging Face
&lt;/h2&gt;

&lt;p&gt;Hugging Face models are the go-to for privacy, local deployment, and cost-efficiency. Here are the top picks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1. all-MiniLM-L6-v2&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 384&lt;br&gt;
Description: Fast, efficient, and good quality.&lt;br&gt;
Use Case: General purpose; ideal for real-time applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. all-mpnet-base-v2&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 768&lt;br&gt;
Description: The best quality in the MiniLM family, though slower than L6. More dimensions lead to an improvement in accuracy.&lt;br&gt;
Use Case: When quality matters more than speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. all-MiniLM-L12-v2&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 384&lt;br&gt;
Description: Slightly better than L6 but a bit slower.&lt;br&gt;
Use Case: A solid balance of speed and quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;4. multi-qa-MiniLM-L6-cos-v1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 384&lt;br&gt;
Description: Optimized specifically for question-answering.&lt;br&gt;
Use Case: Q&amp;amp;A systems and semantic search.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;5. paraphrase-multilingual-MiniLM-L12-v2&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 384&lt;br&gt;
Description: Supports 50+ languages.&lt;br&gt;
Use Case: Global and multilingual applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  💰 The OpenAI Standard
&lt;/h2&gt;

&lt;p&gt;If you need massive scale and the highest "reasoning" in your vectors without managing infrastructure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;text-embedding-3-small&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Dimensions: 1536&lt;br&gt;
Cost: ~$0.02 per 1M tokens.&lt;br&gt;
Description: Highly cost-effective with improved accuracy over older models. It also supports Matryoshka Representation Learning, allowing you to trim dimensions (e.g., to 512) to save storage costs without losing much performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. text-embedding-3-large&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 3072&lt;br&gt;
Cost: ~$0.13 per 1M tokens.&lt;br&gt;
Description: The most powerful model available. It captures incredibly fine-grained nuances in text.&lt;br&gt;
Feature: Like the "small" version, it supports Matryoshka Representation Learning, which means you can shorten the vector to 256 or 1024 dimensions to save database space while keeping most of the accuracy.&lt;br&gt;
Use Case: Enterprise-level research, legal document analysis, or complex medical data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. text-embedding-ada-002&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dimensions: 1536&lt;br&gt;
Cost: ~$0.10 per 1M tokens.&lt;br&gt;
Description: The previous industry standard. While still reliable, it is now considered legacy compared to the "v3" family.&lt;br&gt;
Use Case: Mostly seen in older "legacy" AI systems. For any new project in 2026, you should skip this and go straight to text-embedding-3-small.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚖️ How to Choose?
&lt;/h2&gt;

&lt;p&gt;Strict Privacy/On-Prem? ➔ Hugging Face (Local).&lt;/p&gt;

&lt;p&gt;Real-time/Low Latency? ➔ all-MiniLM-L6-v2.&lt;/p&gt;

&lt;p&gt;Multilingual Data? ➔ paraphrase-multilingual-MiniLM-L12-v2.&lt;/p&gt;

&lt;p&gt;Enterprise Scale &amp;amp; Accuracy? ➔ text-embedding-3-small.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Conclusion
&lt;/h2&gt;

&lt;p&gt;In 2026, picking the right embedding model is about balancing latency, cost, and accuracy. Don't just pick the one with the most dimensions—pick the one that fits your specific data and hardware.&lt;/p&gt;

&lt;p&gt;What's your go-to embedding model for production? Let's discuss in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vectordatabase</category>
      <category>python</category>
      <category>langchain</category>
    </item>
    <item>
      <title>🧠 Your LLM Isn’t an Agent — Until It Has Tools, Memory, and Structure (LangChain Deep Dive)</title>
      <dc:creator>Ananya S</dc:creator>
      <pubDate>Mon, 02 Mar 2026 17:09:48 +0000</pubDate>
      <link>https://dev.to/zeroshotanu/your-llm-isnt-an-agent-until-it-has-tools-memory-and-structure-langchain-deep-dive-18d8</link>
      <guid>https://dev.to/zeroshotanu/your-llm-isnt-an-agent-until-it-has-tools-memory-and-structure-langchain-deep-dive-18d8</guid>
      <description>&lt;p&gt;Most “AI apps” today are just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prompt → LLM → Text Response&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s not an agent.&lt;/p&gt;

&lt;p&gt;That’s autocomplete with branding.&lt;/p&gt;

&lt;p&gt;A real AI agent can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛠 Use tools&lt;/li&gt;
&lt;li&gt;🧠 Remember context&lt;/li&gt;
&lt;li&gt;📦 Return structured outputs&lt;/li&gt;
&lt;li&gt;🔁 Reason across multiple steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With modern LangChain, building this is surprisingly clean.&lt;/p&gt;

&lt;p&gt;Let’s build one properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Architecture of a Real Agent
&lt;/h2&gt;

&lt;p&gt;A production-ready AI agent has four core components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; – the brain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; – capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured outputs&lt;/strong&gt; – reliability and formatting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt; – continuity&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re missing one of these, you’re not building a system — you’re running a demo.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ The Brain: Modern Agent Setup
&lt;/h2&gt;

&lt;p&gt;We start with &lt;code&gt;create_agent()&lt;/code&gt; — the current way to build agents in LangChain.&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;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Low temperature = more deterministic reasoning.&lt;/p&gt;

&lt;p&gt;Now let’s give it capabilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Tools: Giving the Agent Superpowers
&lt;/h2&gt;

&lt;p&gt;Tools are just Python functions with clear docstrings.&lt;br&gt;
The docstring matters — it’s how the model decides when to use the tool.&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;langchain.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_revenue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Calculate total revenue given price per unit and quantity sold.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;


&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_exchange_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Get the USD exchange rate for a given currency code.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;rates&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;EUR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GBP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rates&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="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we assemble the agent:&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="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;calculate_revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_exchange_rate&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a financial analysis assistant.&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 it.&lt;/p&gt;

&lt;p&gt;The agent now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decides when math is needed&lt;/li&gt;
&lt;li&gt;Calls tools autonomously&lt;/li&gt;
&lt;li&gt;Observes results&lt;/li&gt;
&lt;li&gt;Produces a final answer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No manual routing logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Structured Outputs: Stop Parsing Strings
&lt;/h2&gt;

&lt;p&gt;If you're still doing regex on LLM responses, stop.&lt;/p&gt;

&lt;p&gt;Modern agents can return structured data using schemas.&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;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FinancialReport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;usd_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we enforce structure:&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="n"&gt;structured_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;calculate_revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_exchange_rate&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;response_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;FinancialReport&lt;/span&gt;&lt;span class="p"&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 when you invoke:&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;structured_agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&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;role&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;user&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;content&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;I sold 120 units at 50 EUR each. Convert to USD.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don’t get text.&lt;/p&gt;

&lt;p&gt;You get validated data.&lt;br&gt;
Using Pydantic structured output parsers ensures the datatype of the fields is based on how we defined it.&lt;/p&gt;


&lt;h2&gt;
  
  
  4️⃣ Memory: Making the Agent Stateful
&lt;/h2&gt;

&lt;p&gt;Without memory, every request is a new message.&lt;/p&gt;

&lt;p&gt;With memory, your agent becomes a collaborator.&lt;/p&gt;

&lt;p&gt;In LangChain, memory can be plugged in via message history.&lt;/p&gt;

&lt;p&gt;Example pattern:&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="n"&gt;chat_history&lt;/span&gt; &lt;span class="o"&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="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chat_history&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&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;role&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;user&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;content&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 product costs 20 USD.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;chat_history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&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="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;chat_history&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&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;role&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;user&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;content&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;Now calculate revenue for 300 units.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&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 the agent remembers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product price&lt;/li&gt;
&lt;li&gt;Prior discussion&lt;/li&gt;
&lt;li&gt;Contextual decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memory transforms isolated responses into evolving workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What’s Actually Happening Internally?
&lt;/h2&gt;

&lt;p&gt;When you call:&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="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads conversation + system prompt&lt;/li&gt;
&lt;li&gt;Plans next action&lt;/li&gt;
&lt;li&gt;Chooses a tool (if needed)&lt;/li&gt;
&lt;li&gt;Executes tool&lt;/li&gt;
&lt;li&gt;Feeds result back into reasoning&lt;/li&gt;
&lt;li&gt;Produces structured final output&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This loop is grounded in tool-calling rather than fragile prompt tricks.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Common Mistakes
&lt;/h2&gt;

&lt;p&gt;Things beginner devs get wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Adding too many tools&lt;/li&gt;
&lt;li&gt;❌ Writing vague tool descriptions&lt;/li&gt;
&lt;li&gt;❌ Not enforcing structured outputs&lt;/li&gt;
&lt;li&gt;❌ Forgetting observability/logging&lt;/li&gt;
&lt;li&gt;❌ Letting the agent free-run without constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents are probabilistic planners — not deterministic scripts.&lt;/p&gt;

&lt;p&gt;Design them intentionally.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗 The Big Shift in How We Build Software
&lt;/h2&gt;

&lt;p&gt;Before agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs returned static responses&lt;/li&gt;
&lt;li&gt;Business logic was deterministic&lt;/li&gt;
&lt;li&gt;LLMs were “smart text generators”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLMs orchestrate execution&lt;/li&gt;
&lt;li&gt;Tools become capabilities&lt;/li&gt;
&lt;li&gt;Structure guarantees reliability&lt;/li&gt;
&lt;li&gt;Memory enables continuity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're no longer building chat interfaces.&lt;/p&gt;

&lt;p&gt;You're building &lt;strong&gt;goal-driven systems&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Take
&lt;/h2&gt;

&lt;p&gt;If your AI system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t use tools&lt;/li&gt;
&lt;li&gt;Doesn’t enforce structure&lt;/li&gt;
&lt;li&gt;Doesn’t maintain memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not an agent.&lt;/p&gt;

&lt;p&gt;It’s autocomplete with better marketing.&lt;/p&gt;

&lt;p&gt;With modern LangChain, the barrier to real agents is gone.&lt;/p&gt;

&lt;p&gt;The question isn’t &lt;em&gt;“Can we build agents?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What workflows are we ready to automate?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Do comment how you build agents and regarding any interesting types of agents you've built!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>langchain</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
