<?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>Forem: Chandrani Mukherjee</title>
    <description>The latest articles on Forem by Chandrani Mukherjee (@moni121189).</description>
    <link>https://forem.com/moni121189</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3324456%2Fbd5d4f89-441b-483d-91d6-fa7260065254.png</url>
      <title>Forem: Chandrani Mukherjee</title>
      <link>https://forem.com/moni121189</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/moni121189"/>
    <language>en</language>
    <item>
      <title># Deploying Twilio Apps on the Cloud (Python + Flask/FastAPI)</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Wed, 03 Dec 2025 17:30:42 +0000</pubDate>
      <link>https://forem.com/moni121189/-deploying-twilio-apps-on-the-cloud-python-flaskfastapi-25bi</link>
      <guid>https://forem.com/moni121189/-deploying-twilio-apps-on-the-cloud-python-flaskfastapi-25bi</guid>
      <description>&lt;p&gt;Twilio applications need public HTTPS webhook URLs for SMS, WhatsApp, and Voice interactions. This guide explains how to deploy your Twilio-powered Python applications on Cloud Run, AWS Lambda, Azure, Railway, Render, and Docker-based platforms.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Google Cloud Run (Fast, Serverless, Recommended)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11-slim&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["gunicorn", "-b", ":8080", "app:app"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud builds submit &lt;span class="nt"&gt;--tag&lt;/span&gt; gcr.io/PROJECT_ID/twilio-ai-agent
gcloud run deploy twilio-ai-agent     &lt;span class="nt"&gt;--image&lt;/span&gt; gcr.io/PROJECT_ID/twilio-ai-agent     &lt;span class="nt"&gt;--platform&lt;/span&gt; managed     &lt;span class="nt"&gt;--region&lt;/span&gt; us-central1     &lt;span class="nt"&gt;--allow-unauthenticated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the Cloud Run URL in Twilio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-service.run.app/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. AWS Lambda + API Gateway (Low Cost)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Convert FastAPI to Lambda
&lt;/h3&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;mangum&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Mangum&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;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Mangum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy with AWS SAM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sam build
sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Webhook example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://abc123.execute-api.us-east-1.amazonaws.com/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Azure App Service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az webapp up &lt;span class="nt"&gt;--name&lt;/span&gt; twilio-ai-app &lt;span class="nt"&gt;--runtime&lt;/span&gt; &lt;span class="s2"&gt;"PYTHON:3.10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Twilio webhook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://twilio-ai-app.azurewebsites.net/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Railway Deployment (Easiest)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Connect GitHub repo
&lt;/li&gt;
&lt;li&gt;Add environment variables
&lt;/li&gt;
&lt;li&gt;Railway assigns URL like:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://twilio-agent-production.up.railway.app/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Render Deployment
&lt;/h2&gt;

&lt;p&gt;Start command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gunicorn app:app --bind 0.0.0.0:$PORT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Render URL becomes your webhook endpoint.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Docker Deployments (Fly.io, EC2, DigitalOcean)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fly.io Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fly launch
fly deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://twilio-bot.fly.dev/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Local Ngrok Testing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Webhook example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://1234abcd.ngrok-free.app/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Production Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Store Twilio credentials in environment variables
&lt;/li&gt;
&lt;li&gt;Use request validation
&lt;/li&gt;
&lt;li&gt;Rotate API keys
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use Gunicorn workers
&lt;/li&gt;
&lt;li&gt;Prefer serverless platforms for scaling
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reliability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Twilio automatically retries failed webhook calls
&lt;/li&gt;
&lt;li&gt;Add logging and monitoring
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Twilio apps deploy easily across modern cloud platforms. Choose Cloud Run for scalability, Lambda for low cost, Railway for speed, or Docker for flexibility.&lt;/p&gt;

</description>
      <category>python</category>
      <category>aws</category>
      <category>twilio</category>
      <category>ai</category>
    </item>
    <item>
      <title>Build AI Agents with Twilio: SMS, Voice &amp; WhatsApp Automation</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Wed, 03 Dec 2025 17:27:56 +0000</pubDate>
      <link>https://forem.com/moni121189/build-ai-agents-with-twilio-sms-voice-whatsapp-automation-ack</link>
      <guid>https://forem.com/moni121189/build-ai-agents-with-twilio-sms-voice-whatsapp-automation-ack</guid>
      <description>&lt;p&gt;AI agents are reshaping how applications interact with the world—performing tasks, scheduling actions, retrieving information, and responding intelligently to users. Pairing AI agents with &lt;strong&gt;Twilio&lt;/strong&gt; unlocks real-time communication capabilities across SMS, Voice, and WhatsApp. In this article, we’ll build a Twilio-powered Python AI agent that can reason, plan, and act.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI Agents + Twilio?
&lt;/h2&gt;

&lt;p&gt;An AI agent becomes far more useful when it can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receive instructions from users by SMS/WhatsApp
&lt;/li&gt;
&lt;li&gt;Take actions (search, fetch data, schedule reminders)
&lt;/li&gt;
&lt;li&gt;Trigger workflows or APIs
&lt;/li&gt;
&lt;li&gt;Provide reasoning back to the user
&lt;/li&gt;
&lt;li&gt;Handle voice calls and respond dynamically
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Twilio acts as the communication gateway, while the AI model provides intelligence and decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;Twilio account + SMS-enabled phone number&lt;/li&gt;
&lt;li&gt;AI model API (OpenAI, Groq, Anthropic, or local LLM)&lt;/li&gt;
&lt;li&gt;Libraries:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install twilio flask openai requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ol&gt;
&lt;li&gt;User sends SMS/WhatsApp → Twilio Webhook
&lt;/li&gt;
&lt;li&gt;Flask endpoint receives message
&lt;/li&gt;
&lt;li&gt;Python AI Agent interprets task
&lt;/li&gt;
&lt;li&gt;Agent executes tools (APIs, searches, actions)
&lt;/li&gt;
&lt;li&gt;Sends response back via Twilio
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Example: Python AI Agent
&lt;/h2&gt;

&lt;p&gt;Below is a minimal agent that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search the web
&lt;/li&gt;
&lt;li&gt;Look up weather
&lt;/li&gt;
&lt;li&gt;Set reminders
&lt;/li&gt;
&lt;li&gt;Respond conversationally
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;agent.py&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AIAgent&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;search_web&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Dummy search
&lt;/span&gt;        &lt;span class="k"&gt;return&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;Search results for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&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;The weather in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is sunny and 72°F.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&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="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search_web&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="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather&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="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;remind&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reminder set! (demo version)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I can help with search, weather, reminders, or questions!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Twilio + Flask AI Agent Endpoint
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;app.py&lt;/code&gt;
&lt;/h3&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;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;twilio.twiml.messaging_response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MessagingResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIAgent&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;Flask&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;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AIAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/sms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&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;POST&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;sms_reply&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;user_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Body&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;result&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;plan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&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;__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;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&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;h2&gt;
  
  
  Connecting Twilio Webhook
&lt;/h2&gt;

&lt;p&gt;In Twilio Console → Phone Numbers → Messaging&lt;/p&gt;

&lt;p&gt;Set the webhook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-server.ngrok.io/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your number behaves like an AI agent!&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending the Agent
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Calendar and task automation
&lt;/li&gt;
&lt;li&gt;Database lookups
&lt;/li&gt;
&lt;li&gt;Document RAG
&lt;/li&gt;
&lt;li&gt;LLM-based reasoning
&lt;/li&gt;
&lt;li&gt;Multi-step planning &amp;amp; tool execution
&lt;/li&gt;
&lt;li&gt;WhatsApp support
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Twilio gives AI agents the ability to interact with users in real time across SMS, Voice, and WhatsApp. With just a few lines of Python, you can build intelligent assistants that perform tasks, answer questions, and automate workflows—all from a phone.&lt;/p&gt;

</description>
      <category>python</category>
      <category>aws</category>
      <category>twilio</category>
    </item>
    <item>
      <title>Build AI-Powered SMS &amp; Voice Apps with Twilio and Python</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Wed, 03 Dec 2025 17:22:01 +0000</pubDate>
      <link>https://forem.com/moni121189/build-ai-powered-sms-voice-apps-with-twilio-and-python-gb1</link>
      <guid>https://forem.com/moni121189/build-ai-powered-sms-voice-apps-with-twilio-and-python-gb1</guid>
      <description>&lt;p&gt;Artificial intelligence is transforming how applications interact with users—but without seamless communication channels, even the smartest models fall short. Twilio bridges that gap by giving your AI apps the ability to send messages, respond to users, handle voice, and automate conversations. In this article, we’ll build a simple—but powerful—AI-driven SMS assistant using Twilio + Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Twilio + AI + Python?
&lt;/h2&gt;

&lt;p&gt;Python is the go-to language for AI because of its rich ecosystem (OpenAI, LangChain, HuggingFace, FastAPI, etc.). Twilio adds real-time reachability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send AI-generated responses via SMS
&lt;/li&gt;
&lt;li&gt;Build voice apps powered by LLM reasoning
&lt;/li&gt;
&lt;li&gt;Connect AI chatbots to WhatsApp
&lt;/li&gt;
&lt;li&gt;Trigger LLM workflows from inbound user messages
&lt;/li&gt;
&lt;li&gt;Integrate with retrieval (RAG), analytics, workflows, or IoT events
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9+&lt;/li&gt;
&lt;li&gt;Twilio account + phone number enabled for SMS&lt;/li&gt;
&lt;li&gt;An AI model/API (OpenAI, Groq, Anthropic)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install twilio flask&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install openai&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build an AI SMS Assistant (Flask + Twilio + OpenAI)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TWILIO_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_token"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TWILIO_SID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_sid"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. app.py
&lt;/h3&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;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;twilio.twiml.messaging_response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MessagingResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&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;Flask&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&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="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&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.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/sms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&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;POST&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;sms_reply&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;user_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&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;messages&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;system&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;You are a helpful AI assistant.&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;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="n"&gt;user_text&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;ai_reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&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;message&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="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ai_reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&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;__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;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&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;h3&gt;
  
  
  3. Configure Twilio Webhook
&lt;/h3&gt;

&lt;p&gt;Twilio Console → Phone Numbers → Messaging → Webhook URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-server.ngrok.io/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI Voice Bonus
&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;twilio.twiml.voice_response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VoiceResponse&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/voice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&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;POST&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;voice&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;VoiceResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello! Ask me anything.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;alice&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record&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;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/process_voice&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What You Can Build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI customer support
&lt;/li&gt;
&lt;li&gt;WhatsApp travel planner
&lt;/li&gt;
&lt;li&gt;Voice LLM receptionist
&lt;/li&gt;
&lt;li&gt;Real-time IoT → SMS AI alerts
&lt;/li&gt;
&lt;li&gt;RAG chatbot via SMS
&lt;/li&gt;
&lt;li&gt;Study tutor bot
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker + Gunicorn
&lt;/li&gt;
&lt;li&gt;AWS Lambda
&lt;/li&gt;
&lt;li&gt;GCP Cloud Run
&lt;/li&gt;
&lt;li&gt;Fly.io
&lt;/li&gt;
&lt;li&gt;Railway
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Twilio transforms AI models from passive generators into interactive, real-time communication agents. With a few lines of Python, you can build SMS/voice/WhatsApp AI assistants and deploy them anywhere.&lt;/p&gt;

</description>
      <category>python</category>
      <category>aws</category>
      <category>twilio</category>
      <category>docker</category>
    </item>
    <item>
      <title>Build AI-Powered SMS &amp; Voice Apps with Twilio and Python</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Wed, 03 Dec 2025 17:22:01 +0000</pubDate>
      <link>https://forem.com/moni121189/build-ai-powered-sms-voice-apps-with-twilio-and-python-1ka6</link>
      <guid>https://forem.com/moni121189/build-ai-powered-sms-voice-apps-with-twilio-and-python-1ka6</guid>
      <description>&lt;p&gt;Artificial intelligence is transforming how applications interact with users—but without seamless communication channels, even the smartest models fall short. Twilio bridges that gap by giving your AI apps the ability to send messages, respond to users, handle voice, and automate conversations. In this article, we’ll build a simple—but powerful—AI-driven SMS assistant using Twilio + Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Twilio + AI + Python?
&lt;/h2&gt;

&lt;p&gt;Python is the go-to language for AI because of its rich ecosystem (OpenAI, LangChain, HuggingFace, FastAPI, etc.). Twilio adds real-time reachability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send AI-generated responses via SMS
&lt;/li&gt;
&lt;li&gt;Build voice apps powered by LLM reasoning
&lt;/li&gt;
&lt;li&gt;Connect AI chatbots to WhatsApp
&lt;/li&gt;
&lt;li&gt;Trigger LLM workflows from inbound user messages
&lt;/li&gt;
&lt;li&gt;Integrate with retrieval (RAG), analytics, workflows, or IoT events
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9+&lt;/li&gt;
&lt;li&gt;Twilio account + phone number enabled for SMS&lt;/li&gt;
&lt;li&gt;An AI model/API (OpenAI, Groq, Anthropic)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install twilio flask&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install openai&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build an AI SMS Assistant (Flask + Twilio + OpenAI)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TWILIO_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_token"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TWILIO_SID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_sid"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. app.py
&lt;/h3&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;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;twilio.twiml.messaging_response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MessagingResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&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;Flask&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&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="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&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.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/sms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&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;POST&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;sms_reply&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;user_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&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;messages&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;system&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;You are a helpful AI assistant.&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;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="n"&gt;user_text&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;ai_reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&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;message&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="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ai_reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&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;__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;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&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;h3&gt;
  
  
  3. Configure Twilio Webhook
&lt;/h3&gt;

&lt;p&gt;Twilio Console → Phone Numbers → Messaging → Webhook URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-server.ngrok.io/sms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  AI Voice Bonus
&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;twilio.twiml.voice_response&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VoiceResponse&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/voice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&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;POST&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;voice&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;VoiceResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello! Ask me anything.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;alice&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record&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;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/process_voice&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What You Can Build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AI customer support
&lt;/li&gt;
&lt;li&gt;WhatsApp travel planner
&lt;/li&gt;
&lt;li&gt;Voice LLM receptionist
&lt;/li&gt;
&lt;li&gt;Real-time IoT → SMS AI alerts
&lt;/li&gt;
&lt;li&gt;RAG chatbot via SMS
&lt;/li&gt;
&lt;li&gt;Study tutor bot
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker + Gunicorn
&lt;/li&gt;
&lt;li&gt;AWS Lambda
&lt;/li&gt;
&lt;li&gt;GCP Cloud Run
&lt;/li&gt;
&lt;li&gt;Fly.io
&lt;/li&gt;
&lt;li&gt;Railway
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Twilio transforms AI models from passive generators into interactive, real-time communication agents. With a few lines of Python, you can build SMS/voice/WhatsApp AI assistants and deploy them anywhere.&lt;/p&gt;

</description>
      <category>python</category>
      <category>aws</category>
      <category>twilio</category>
      <category>docker</category>
    </item>
    <item>
      <title>Teach your RAG to learn from its mistakes — the smart way</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Mon, 03 Nov 2025 05:42:50 +0000</pubDate>
      <link>https://forem.com/moni121189/teach-your-rag-to-learn-from-its-mistakes-the-smart-way-32lp</link>
      <guid>https://forem.com/moni121189/teach-your-rag-to-learn-from-its-mistakes-the-smart-way-32lp</guid>
      <description>&lt;h1&gt;
  
  
  🔁 Building a Feedback Loop for RAG with LangChain and Docker
&lt;/h1&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG) is great — until your LLM starts hallucinating or retrieving outdated context. That’s where a &lt;strong&gt;feedback loop&lt;/strong&gt; comes in.  &lt;/p&gt;

&lt;p&gt;In this post, we’ll build a simple RAG pipeline with &lt;strong&gt;LangChain&lt;/strong&gt;, containerize it using &lt;strong&gt;Docker&lt;/strong&gt;, and add a &lt;strong&gt;feedback mechanism&lt;/strong&gt; to make it smarter over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why Feedback Matters in RAG
&lt;/h2&gt;

&lt;p&gt;A RAG system has two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Retriever&lt;/strong&gt; — fetches relevant documents from a vector store.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generator&lt;/strong&gt; — produces an answer using the retrieved context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without feedback, your model never learns from mistakes.&lt;br&gt;&lt;br&gt;
A feedback loop lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-rank documents that users find more useful.
&lt;/li&gt;
&lt;li&gt;Fine-tune retrievers based on query–document relevance.
&lt;/li&gt;
&lt;li&gt;Measure response quality (faithfulness, groundedness, etc.).
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚙️ Step 1: Build a Minimal RAG Pipeline
&lt;/h2&gt;

&lt;p&gt;Let’s start with a simple LangChain setup:&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.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.embeddings&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIEmbeddings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.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.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.document_loaders&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TextLoader&lt;/span&gt;

&lt;span class="c1"&gt;# Load documents
&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TextLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/policies.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Create embeddings and vector store
&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="n"&gt;db&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_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&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="n"&gt;retriever&lt;/span&gt; &lt;span class="o"&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;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_kwargs&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;k&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="c1"&gt;# Define RAG pipeline
&lt;/span&gt;&lt;span class="n"&gt;qa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_chain_type&lt;/span&gt;&lt;span class="p"&gt;(&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_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;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;retriever&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;return_source_documents&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;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 the latest leave policy?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;qa&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&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;
  
  
  💬 Step 2: Add a Feedback Collector
&lt;/h2&gt;

&lt;p&gt;After displaying the result, log user feedback (thumbs up/down) into a simple JSON or database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_feedback&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;entry&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;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&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;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&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="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;feedback.json&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;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&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;You can later parse this feedback file to improve your retriever — e.g., re-weighting embeddings or filtering irrelevant sources.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 Step 3: Close the Feedback Loop
&lt;/h2&gt;

&lt;p&gt;Use libraries like &lt;strong&gt;TruLens&lt;/strong&gt; or &lt;strong&gt;Ragas&lt;/strong&gt; to automatically evaluate and fine-tune based on feedback:&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;trulens_eval&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Feedback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TruChain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Select&lt;/span&gt;

&lt;span class="n"&gt;tru_qa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TruChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;qa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rag-feedback-demo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;feedback_quality&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Feedback&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;helpfulness&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tru_qa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_feedback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feedback_quality&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tru_qa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&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="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&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;
  
  
  🐳 Step 4: Containerize with Docker
&lt;/h2&gt;

&lt;p&gt;Create a simple &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.10-slim&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain openai faiss-cpu trulens-eval
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; OPENAI_API_KEY=your_api_key&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "rag_feedback.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then build and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; rag-feedback &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$OPENAI_API_KEY&lt;/span&gt; rag-feedback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Step 5: Scale &amp;amp; Iterate
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploy your RAG system as a microservice behind an API.
&lt;/li&gt;
&lt;li&gt;Stream feedback data to a shared database (Postgres, MongoDB).
&lt;/li&gt;
&lt;li&gt;Periodically retrain or re-index your vector store based on positive/negative signals.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Summary
&lt;/h2&gt;

&lt;p&gt;By integrating &lt;strong&gt;LangChain&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;, and a &lt;strong&gt;feedback loop&lt;/strong&gt;, you get a self-improving RAG system that learns what “good” looks like from real usage.  &lt;/p&gt;

&lt;p&gt;This loop not only boosts retrieval precision but also reduces hallucination and improves trust in your AI answers.&lt;/p&gt;




&lt;h3&gt;
  
  
  💡 Next Steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add automated evaluation with &lt;a href="https://github.com/explodinggradients/ragas" rel="noopener noreferrer"&gt;Ragas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Serve your feedback endpoint via FastAPI
&lt;/li&gt;
&lt;li&gt;Store embeddings and feedback in a persistent vector DB like Weaviate or Pinecone
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>docker</category>
      <category>devops</category>
      <category>pinecone</category>
    </item>
    <item>
      <title>Securing LangChain APIs with AWS SSO and Active Directory</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Thu, 09 Oct 2025 05:21:11 +0000</pubDate>
      <link>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-3lhj</link>
      <guid>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-3lhj</guid>
      <description>&lt;h1&gt;
  
  
  🔐 Using AWS Active Directory SSO to Secure AI Models and Protect LangChain APIs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Chandrani Mukherjee&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tags:&lt;/strong&gt; #AWS #ActiveDirectory #SSO #LangChain #Security #AI #Python  &lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Overview
&lt;/h2&gt;

&lt;p&gt;When building &lt;strong&gt;AI-powered platforms&lt;/strong&gt; with &lt;strong&gt;LangChain&lt;/strong&gt;, &lt;strong&gt;RAG&lt;/strong&gt;, or &lt;strong&gt;LLMs&lt;/strong&gt;, one of the most overlooked aspects is &lt;strong&gt;access security&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Unsecured APIs can expose sensitive data, allow unauthorized model invocation, or lead to prompt injection attacks.&lt;/p&gt;

&lt;p&gt;By integrating &lt;strong&gt;AWS Active Directory (AD)&lt;/strong&gt; through &lt;strong&gt;AWS IAM Identity Center (formerly AWS SSO)&lt;/strong&gt;, we can bring &lt;strong&gt;enterprise-grade identity, access control, and auditing&lt;/strong&gt; into AI model deployment pipelines.&lt;/p&gt;

&lt;p&gt;This guide walks through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enabling &lt;strong&gt;SSO authentication with AWS AD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Applying &lt;strong&gt;fine-grained IAM access policies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Securing &lt;strong&gt;LangChain APIs&lt;/strong&gt; behind AWS gateways&lt;/li&gt;
&lt;li&gt;Enforcing &lt;strong&gt;responsible AI access controls&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[Corporate User] 
   ↓  (AD Credentials)
[ AWS SSO / IAM Identity Center integrated with AWS Managed Microsoft AD ]
   ↓  (SSO token / SAML assertion)
[ API Gateway / ALB w/ JWT Authorizer + WAF ]
   ↓
[ Auth Proxy Service (Python/Flask or FastAPI) ]
   ↓
[ LangChain Server / AI Model Backend ]
   ↓
[ AWS Services: S3 | DynamoDB | Bedrock | SageMaker | KMS ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Security Layers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; Authentication handled via &lt;strong&gt;AWS AD SSO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Control:&lt;/strong&gt; Short-lived credentials through &lt;strong&gt;IAM roles and permissions boundaries&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Security:&lt;/strong&gt; Private subnets, &lt;strong&gt;VPC endpoints&lt;/strong&gt;, and &lt;strong&gt;AWS WAF&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Security:&lt;/strong&gt; Input/output sanitization, tool whitelisting, prompt validation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; CloudWatch + GuardDuty + centralized logs
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Enable SSO with AWS Active Directory
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up AWS Managed Microsoft AD&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the AWS Directory Service console, create or connect your corporate AD.
&lt;/li&gt;
&lt;li&gt;Sync identities using &lt;strong&gt;AWS IAM Identity Center&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integrate with IAM Identity Center (AWS SSO)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect AWS AD to &lt;strong&gt;IAM Identity Center&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Map user groups (e.g., &lt;code&gt;AI_Architects&lt;/code&gt;, &lt;code&gt;Data_Scientists&lt;/code&gt;) to &lt;strong&gt;permission sets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assign access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grant your AI services access only through designated AD groups.&lt;/li&gt;
&lt;li&gt;Example:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AI_Admins&lt;/code&gt;: Can deploy and fine-tune models
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI_Users&lt;/code&gt;: Read-only inference access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This creates a unified login experience — users authenticate with their &lt;strong&gt;corporate AD credentials&lt;/strong&gt; to access AI APIs or consoles.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 Step 2: Protect LangChain APIs with AWS Auth Layers
&lt;/h2&gt;

&lt;p&gt;LangChain services often expose REST endpoints — these must sit &lt;strong&gt;behind a secured API Gateway or ALB&lt;/strong&gt; with JWT validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 — API Gateway + JWT Authorizer
&lt;/h3&gt;



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

aws apigatewayv2 create-authorizer   --api-id &amp;lt;api_id&amp;gt;   --authorizer-type JWT   --identity-source '$request.header.Authorization'   --name LangChainAuth   --jwt-configuration Audience=&amp;lt;app_client_id&amp;gt;,Issuer=&amp;lt;sso_issuer_url&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Issuer&lt;/strong&gt; points to the &lt;strong&gt;AWS AD / Identity Center&lt;/strong&gt; OIDC endpoint.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Audience&lt;/strong&gt; matches your app's client ID.
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;AWS WAF&lt;/strong&gt; rules to protect from abuse and injection attempts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Option 2 — ALB + OIDC Authentication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use an &lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt; to authenticate directly via OIDC before routing to your backend.&lt;/li&gt;
&lt;li&gt;Add group-based routing:
&lt;/li&gt;
&lt;/ul&gt;

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

  condition:
    Field: path-pattern
    Values: /admin/*
    Authenticate: groups = AI_Admins

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 Step 3: Build an Auth Proxy for LangChain
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Flask/FastAPI proxy&lt;/strong&gt; ensures your AI backend remains isolated and safe.&lt;br&gt;&lt;br&gt;
This layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifies AD-based JWT tokens
&lt;/li&gt;
&lt;li&gt;Performs &lt;strong&gt;rate limiting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sanitizes &lt;strong&gt;user prompts&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Logs usage metadata for auditing
&lt;/li&gt;
&lt;/ul&gt;

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

from flask import Flask, request, jsonify
import jwt, requests

app = Flask(__name__)
ISSUER = "https://YOUR_SSO_DOMAIN.awsapps.com/start"
AUDIENCE = "LangChainApp"

def verify_token(token):
    # Validate token with AWS OIDC public keys (jwks)
    return jwt.decode(token, options={"verify_aud": True, "verify_iss": True}, audience=AUDIENCE, issuer=ISSUER)

@app.route("/api/query", methods=["POST"])
def handle_query():
    auth_header = request.headers.get("Authorization", "")
    if not auth_header:
        return jsonify({"error": "Missing Authorization"}), 401

    token = auth_header.split(" ")[1]
    claims = verify_token(token)
    user = claims.get("email")

    # Simple prompt validation
    prompt = request.json.get("prompt", "")
    if "DROP TABLE" in prompt.upper():
        return jsonify({"error": "Invalid input detected"}), 400

    # Forward safely to LangChain backend
    resp = requests.post("http://langchain-service/internal-query", json={"prompt": prompt, "user": user})
    return jsonify(resp.json()), resp.status_code

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧰 Step 4: Secure AWS Resources via IAM &amp;amp; KMS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;IAM Roles for Service Accounts (IRSA)&lt;/strong&gt; if deploying LangChain on &lt;strong&gt;EKS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store model keys, vector DB credentials, and LLM API tokens in &lt;strong&gt;AWS Secrets Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Encrypt all sensitive data and embeddings with &lt;strong&gt;AWS KMS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Step 5: Enforce Responsible AI Practices
&lt;/h2&gt;

&lt;p&gt;Security isn't just about access — it's about usage integrity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Log all model invocations with user identity (but mask sensitive input)&lt;/li&gt;
&lt;li&gt;✅ Detect abnormal query patterns with &lt;strong&gt;CloudWatch metrics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ Quarantine or sandbox untrusted user prompts&lt;/li&gt;
&lt;li&gt;✅ Integrate &lt;strong&gt;GuardDuty + Security Hub&lt;/strong&gt; for continuous compliance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Step 6: Continuous Monitoring &amp;amp; Auditing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;AWS CloudTrail&lt;/strong&gt; for every API and role assumption.
&lt;/li&gt;
&lt;li&gt;Store all model interaction logs in &lt;strong&gt;S3 with object-level encryption&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Automate review dashboards using &lt;strong&gt;QuickSight&lt;/strong&gt; or &lt;strong&gt;Grafana on CloudWatch logs&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Summary Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control Area&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSO Identity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrated AWS AD with IAM Identity Center&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API Gateway / ALB JWT authorizer enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secrets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stored in Secrets Manager + KMS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IRSA-enabled pods with least-privilege IAM roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Input sanitization, rate-limiting, and proxy layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GuardDuty, CloudTrail, and CloudWatch integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;By combining &lt;strong&gt;AWS Active Directory SSO&lt;/strong&gt;, &lt;strong&gt;IAM&lt;/strong&gt;, and &lt;strong&gt;LangChain architectural hardening&lt;/strong&gt;, you achieve a &lt;strong&gt;zero-trust AI deployment&lt;/strong&gt; — where &lt;strong&gt;authentication, authorization, encryption, and accountability&lt;/strong&gt; are baked into every step of model access.&lt;/p&gt;

&lt;p&gt;This design keeps your AI APIs secure, your credentials protected, and your compliance auditors happy.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://www.linkedin.com/in/chandrani-mukherjee-usa-nj/" rel="noopener noreferrer"&gt;Chandrani Mukherjee&lt;/a&gt;,&lt;br&gt;&lt;br&gt;
Senior Solution Enterprise Architect | AI/ML Specialist&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>langchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Securing LangChain APIs with AWS SSO and Active Directory</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Thu, 09 Oct 2025 05:21:11 +0000</pubDate>
      <link>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-39pg</link>
      <guid>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-39pg</guid>
      <description>&lt;h1&gt;
  
  
  🔐 Using AWS Active Directory SSO to Secure AI Models and Protect LangChain APIs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Chandrani Mukherjee&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tags:&lt;/strong&gt; #AWS #ActiveDirectory #SSO #LangChain #Security #AI #Python  &lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Overview
&lt;/h2&gt;

&lt;p&gt;When building &lt;strong&gt;AI-powered platforms&lt;/strong&gt; with &lt;strong&gt;LangChain&lt;/strong&gt;, &lt;strong&gt;RAG&lt;/strong&gt;, or &lt;strong&gt;LLMs&lt;/strong&gt;, one of the most overlooked aspects is &lt;strong&gt;access security&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Unsecured APIs can expose sensitive data, allow unauthorized model invocation, or lead to prompt injection attacks.&lt;/p&gt;

&lt;p&gt;By integrating &lt;strong&gt;AWS Active Directory (AD)&lt;/strong&gt; through &lt;strong&gt;AWS IAM Identity Center (formerly AWS SSO)&lt;/strong&gt;, we can bring &lt;strong&gt;enterprise-grade identity, access control, and auditing&lt;/strong&gt; into AI model deployment pipelines.&lt;/p&gt;

&lt;p&gt;This guide walks through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enabling &lt;strong&gt;SSO authentication with AWS AD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Applying &lt;strong&gt;fine-grained IAM access policies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Securing &lt;strong&gt;LangChain APIs&lt;/strong&gt; behind AWS gateways&lt;/li&gt;
&lt;li&gt;Enforcing &lt;strong&gt;responsible AI access controls&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[Corporate User] 
   ↓  (AD Credentials)
[ AWS SSO / IAM Identity Center integrated with AWS Managed Microsoft AD ]
   ↓  (SSO token / SAML assertion)
[ API Gateway / ALB w/ JWT Authorizer + WAF ]
   ↓
[ Auth Proxy Service (Python/Flask or FastAPI) ]
   ↓
[ LangChain Server / AI Model Backend ]
   ↓
[ AWS Services: S3 | DynamoDB | Bedrock | SageMaker | KMS ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Security Layers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; Authentication handled via &lt;strong&gt;AWS AD SSO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Control:&lt;/strong&gt; Short-lived credentials through &lt;strong&gt;IAM roles and permissions boundaries&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Security:&lt;/strong&gt; Private subnets, &lt;strong&gt;VPC endpoints&lt;/strong&gt;, and &lt;strong&gt;AWS WAF&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Security:&lt;/strong&gt; Input/output sanitization, tool whitelisting, prompt validation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; CloudWatch + GuardDuty + centralized logs
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Enable SSO with AWS Active Directory
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up AWS Managed Microsoft AD&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the AWS Directory Service console, create or connect your corporate AD.
&lt;/li&gt;
&lt;li&gt;Sync identities using &lt;strong&gt;AWS IAM Identity Center&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integrate with IAM Identity Center (AWS SSO)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect AWS AD to &lt;strong&gt;IAM Identity Center&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Map user groups (e.g., &lt;code&gt;AI_Architects&lt;/code&gt;, &lt;code&gt;Data_Scientists&lt;/code&gt;) to &lt;strong&gt;permission sets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assign access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grant your AI services access only through designated AD groups.&lt;/li&gt;
&lt;li&gt;Example:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AI_Admins&lt;/code&gt;: Can deploy and fine-tune models
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI_Users&lt;/code&gt;: Read-only inference access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This creates a unified login experience — users authenticate with their &lt;strong&gt;corporate AD credentials&lt;/strong&gt; to access AI APIs or consoles.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 Step 2: Protect LangChain APIs with AWS Auth Layers
&lt;/h2&gt;

&lt;p&gt;LangChain services often expose REST endpoints — these must sit &lt;strong&gt;behind a secured API Gateway or ALB&lt;/strong&gt; with JWT validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 — API Gateway + JWT Authorizer
&lt;/h3&gt;



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

aws apigatewayv2 create-authorizer   --api-id &amp;lt;api_id&amp;gt;   --authorizer-type JWT   --identity-source '$request.header.Authorization'   --name LangChainAuth   --jwt-configuration Audience=&amp;lt;app_client_id&amp;gt;,Issuer=&amp;lt;sso_issuer_url&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Issuer&lt;/strong&gt; points to the &lt;strong&gt;AWS AD / Identity Center&lt;/strong&gt; OIDC endpoint.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Audience&lt;/strong&gt; matches your app's client ID.
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;AWS WAF&lt;/strong&gt; rules to protect from abuse and injection attempts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Option 2 — ALB + OIDC Authentication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use an &lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt; to authenticate directly via OIDC before routing to your backend.&lt;/li&gt;
&lt;li&gt;Add group-based routing:
&lt;/li&gt;
&lt;/ul&gt;

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

  condition:
    Field: path-pattern
    Values: /admin/*
    Authenticate: groups = AI_Admins

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 Step 3: Build an Auth Proxy for LangChain
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Flask/FastAPI proxy&lt;/strong&gt; ensures your AI backend remains isolated and safe.&lt;br&gt;&lt;br&gt;
This layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifies AD-based JWT tokens
&lt;/li&gt;
&lt;li&gt;Performs &lt;strong&gt;rate limiting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sanitizes &lt;strong&gt;user prompts&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Logs usage metadata for auditing
&lt;/li&gt;
&lt;/ul&gt;

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

from flask import Flask, request, jsonify
import jwt, requests

app = Flask(__name__)
ISSUER = "https://YOUR_SSO_DOMAIN.awsapps.com/start"
AUDIENCE = "LangChainApp"

def verify_token(token):
    # Validate token with AWS OIDC public keys (jwks)
    return jwt.decode(token, options={"verify_aud": True, "verify_iss": True}, audience=AUDIENCE, issuer=ISSUER)

@app.route("/api/query", methods=["POST"])
def handle_query():
    auth_header = request.headers.get("Authorization", "")
    if not auth_header:
        return jsonify({"error": "Missing Authorization"}), 401

    token = auth_header.split(" ")[1]
    claims = verify_token(token)
    user = claims.get("email")

    # Simple prompt validation
    prompt = request.json.get("prompt", "")
    if "DROP TABLE" in prompt.upper():
        return jsonify({"error": "Invalid input detected"}), 400

    # Forward safely to LangChain backend
    resp = requests.post("http://langchain-service/internal-query", json={"prompt": prompt, "user": user})
    return jsonify(resp.json()), resp.status_code

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧰 Step 4: Secure AWS Resources via IAM &amp;amp; KMS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;IAM Roles for Service Accounts (IRSA)&lt;/strong&gt; if deploying LangChain on &lt;strong&gt;EKS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store model keys, vector DB credentials, and LLM API tokens in &lt;strong&gt;AWS Secrets Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Encrypt all sensitive data and embeddings with &lt;strong&gt;AWS KMS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Step 5: Enforce Responsible AI Practices
&lt;/h2&gt;

&lt;p&gt;Security isn't just about access — it's about usage integrity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Log all model invocations with user identity (but mask sensitive input)&lt;/li&gt;
&lt;li&gt;✅ Detect abnormal query patterns with &lt;strong&gt;CloudWatch metrics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ Quarantine or sandbox untrusted user prompts&lt;/li&gt;
&lt;li&gt;✅ Integrate &lt;strong&gt;GuardDuty + Security Hub&lt;/strong&gt; for continuous compliance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Step 6: Continuous Monitoring &amp;amp; Auditing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;AWS CloudTrail&lt;/strong&gt; for every API and role assumption.
&lt;/li&gt;
&lt;li&gt;Store all model interaction logs in &lt;strong&gt;S3 with object-level encryption&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Automate review dashboards using &lt;strong&gt;QuickSight&lt;/strong&gt; or &lt;strong&gt;Grafana on CloudWatch logs&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Summary Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control Area&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSO Identity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrated AWS AD with IAM Identity Center&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API Gateway / ALB JWT authorizer enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secrets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stored in Secrets Manager + KMS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IRSA-enabled pods with least-privilege IAM roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Input sanitization, rate-limiting, and proxy layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GuardDuty, CloudTrail, and CloudWatch integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;By combining &lt;strong&gt;AWS Active Directory SSO&lt;/strong&gt;, &lt;strong&gt;IAM&lt;/strong&gt;, and &lt;strong&gt;LangChain architectural hardening&lt;/strong&gt;, you achieve a &lt;strong&gt;zero-trust AI deployment&lt;/strong&gt; — where &lt;strong&gt;authentication, authorization, encryption, and accountability&lt;/strong&gt; are baked into every step of model access.&lt;/p&gt;

&lt;p&gt;This design keeps your AI APIs secure, your credentials protected, and your compliance auditors happy.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://www.linkedin.com/in/chandrani-mukherjee-usa-nj/" rel="noopener noreferrer"&gt;Chandrani Mukherjee&lt;/a&gt;,&lt;br&gt;&lt;br&gt;
Senior Solution Enterprise Architect | AI/ML Specialist&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>langchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Securing LangChain APIs with AWS SSO and Active Directory</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Thu, 09 Oct 2025 05:21:11 +0000</pubDate>
      <link>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-2245</link>
      <guid>https://forem.com/moni121189/securing-langchain-apis-with-aws-sso-and-active-directory-2245</guid>
      <description>&lt;h1&gt;
  
  
  🔐 Using AWS Active Directory SSO to Secure AI Models and Protect LangChain APIs
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Chandrani Mukherjee&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tags:&lt;/strong&gt; #AWS #ActiveDirectory #SSO #LangChain #Security #AI #Python  &lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Overview
&lt;/h2&gt;

&lt;p&gt;When building &lt;strong&gt;AI-powered platforms&lt;/strong&gt; with &lt;strong&gt;LangChain&lt;/strong&gt;, &lt;strong&gt;RAG&lt;/strong&gt;, or &lt;strong&gt;LLMs&lt;/strong&gt;, one of the most overlooked aspects is &lt;strong&gt;access security&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Unsecured APIs can expose sensitive data, allow unauthorized model invocation, or lead to prompt injection attacks.&lt;/p&gt;

&lt;p&gt;By integrating &lt;strong&gt;AWS Active Directory (AD)&lt;/strong&gt; through &lt;strong&gt;AWS IAM Identity Center (formerly AWS SSO)&lt;/strong&gt;, we can bring &lt;strong&gt;enterprise-grade identity, access control, and auditing&lt;/strong&gt; into AI model deployment pipelines.&lt;/p&gt;

&lt;p&gt;This guide walks through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enabling &lt;strong&gt;SSO authentication with AWS AD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Applying &lt;strong&gt;fine-grained IAM access policies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Securing &lt;strong&gt;LangChain APIs&lt;/strong&gt; behind AWS gateways&lt;/li&gt;
&lt;li&gt;Enforcing &lt;strong&gt;responsible AI access controls&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[Corporate User] 
   ↓  (AD Credentials)
[ AWS SSO / IAM Identity Center integrated with AWS Managed Microsoft AD ]
   ↓  (SSO token / SAML assertion)
[ API Gateway / ALB w/ JWT Authorizer + WAF ]
   ↓
[ Auth Proxy Service (Python/Flask or FastAPI) ]
   ↓
[ LangChain Server / AI Model Backend ]
   ↓
[ AWS Services: S3 | DynamoDB | Bedrock | SageMaker | KMS ]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Security Layers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; Authentication handled via &lt;strong&gt;AWS AD SSO&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Control:&lt;/strong&gt; Short-lived credentials through &lt;strong&gt;IAM roles and permissions boundaries&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Security:&lt;/strong&gt; Private subnets, &lt;strong&gt;VPC endpoints&lt;/strong&gt;, and &lt;strong&gt;AWS WAF&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Security:&lt;/strong&gt; Input/output sanitization, tool whitelisting, prompt validation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; CloudWatch + GuardDuty + centralized logs
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚙️ Step 1: Enable SSO with AWS Active Directory
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set up AWS Managed Microsoft AD&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the AWS Directory Service console, create or connect your corporate AD.
&lt;/li&gt;
&lt;li&gt;Sync identities using &lt;strong&gt;AWS IAM Identity Center&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integrate with IAM Identity Center (AWS SSO)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect AWS AD to &lt;strong&gt;IAM Identity Center&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Map user groups (e.g., &lt;code&gt;AI_Architects&lt;/code&gt;, &lt;code&gt;Data_Scientists&lt;/code&gt;) to &lt;strong&gt;permission sets&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Assign access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grant your AI services access only through designated AD groups.&lt;/li&gt;
&lt;li&gt;Example:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AI_Admins&lt;/code&gt;: Can deploy and fine-tune models
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI_Users&lt;/code&gt;: Read-only inference access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This creates a unified login experience — users authenticate with their &lt;strong&gt;corporate AD credentials&lt;/strong&gt; to access AI APIs or consoles.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 Step 2: Protect LangChain APIs with AWS Auth Layers
&lt;/h2&gt;

&lt;p&gt;LangChain services often expose REST endpoints — these must sit &lt;strong&gt;behind a secured API Gateway or ALB&lt;/strong&gt; with JWT validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 — API Gateway + JWT Authorizer
&lt;/h3&gt;



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

aws apigatewayv2 create-authorizer   --api-id &amp;lt;api_id&amp;gt;   --authorizer-type JWT   --identity-source '$request.header.Authorization'   --name LangChainAuth   --jwt-configuration Audience=&amp;lt;app_client_id&amp;gt;,Issuer=&amp;lt;sso_issuer_url&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Issuer&lt;/strong&gt; points to the &lt;strong&gt;AWS AD / Identity Center&lt;/strong&gt; OIDC endpoint.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Audience&lt;/strong&gt; matches your app's client ID.
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;AWS WAF&lt;/strong&gt; rules to protect from abuse and injection attempts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Option 2 — ALB + OIDC Authentication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use an &lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt; to authenticate directly via OIDC before routing to your backend.&lt;/li&gt;
&lt;li&gt;Add group-based routing:
&lt;/li&gt;
&lt;/ul&gt;

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

  condition:
    Field: path-pattern
    Values: /admin/*
    Authenticate: groups = AI_Admins

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 Step 3: Build an Auth Proxy for LangChain
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Flask/FastAPI proxy&lt;/strong&gt; ensures your AI backend remains isolated and safe.&lt;br&gt;&lt;br&gt;
This layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifies AD-based JWT tokens
&lt;/li&gt;
&lt;li&gt;Performs &lt;strong&gt;rate limiting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sanitizes &lt;strong&gt;user prompts&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Logs usage metadata for auditing
&lt;/li&gt;
&lt;/ul&gt;

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

from flask import Flask, request, jsonify
import jwt, requests

app = Flask(__name__)
ISSUER = "https://YOUR_SSO_DOMAIN.awsapps.com/start"
AUDIENCE = "LangChainApp"

def verify_token(token):
    # Validate token with AWS OIDC public keys (jwks)
    return jwt.decode(token, options={"verify_aud": True, "verify_iss": True}, audience=AUDIENCE, issuer=ISSUER)

@app.route("/api/query", methods=["POST"])
def handle_query():
    auth_header = request.headers.get("Authorization", "")
    if not auth_header:
        return jsonify({"error": "Missing Authorization"}), 401

    token = auth_header.split(" ")[1]
    claims = verify_token(token)
    user = claims.get("email")

    # Simple prompt validation
    prompt = request.json.get("prompt", "")
    if "DROP TABLE" in prompt.upper():
        return jsonify({"error": "Invalid input detected"}), 400

    # Forward safely to LangChain backend
    resp = requests.post("http://langchain-service/internal-query", json={"prompt": prompt, "user": user})
    return jsonify(resp.json()), resp.status_code

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧰 Step 4: Secure AWS Resources via IAM &amp;amp; KMS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;IAM Roles for Service Accounts (IRSA)&lt;/strong&gt; if deploying LangChain on &lt;strong&gt;EKS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store model keys, vector DB credentials, and LLM API tokens in &lt;strong&gt;AWS Secrets Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Encrypt all sensitive data and embeddings with &lt;strong&gt;AWS KMS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Step 5: Enforce Responsible AI Practices
&lt;/h2&gt;

&lt;p&gt;Security isn't just about access — it's about usage integrity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Log all model invocations with user identity (but mask sensitive input)&lt;/li&gt;
&lt;li&gt;✅ Detect abnormal query patterns with &lt;strong&gt;CloudWatch metrics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ Quarantine or sandbox untrusted user prompts&lt;/li&gt;
&lt;li&gt;✅ Integrate &lt;strong&gt;GuardDuty + Security Hub&lt;/strong&gt; for continuous compliance&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Step 6: Continuous Monitoring &amp;amp; Auditing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;strong&gt;AWS CloudTrail&lt;/strong&gt; for every API and role assumption.
&lt;/li&gt;
&lt;li&gt;Store all model interaction logs in &lt;strong&gt;S3 with object-level encryption&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Automate review dashboards using &lt;strong&gt;QuickSight&lt;/strong&gt; or &lt;strong&gt;Grafana on CloudWatch logs&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Summary Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control Area&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SSO Identity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrated AWS AD with IAM Identity Center&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API Gateway / ALB JWT authorizer enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secrets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stored in Secrets Manager + KMS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;IRSA-enabled pods with least-privilege IAM roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Input sanitization, rate-limiting, and proxy layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GuardDuty, CloudTrail, and CloudWatch integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;By combining &lt;strong&gt;AWS Active Directory SSO&lt;/strong&gt;, &lt;strong&gt;IAM&lt;/strong&gt;, and &lt;strong&gt;LangChain architectural hardening&lt;/strong&gt;, you achieve a &lt;strong&gt;zero-trust AI deployment&lt;/strong&gt; — where &lt;strong&gt;authentication, authorization, encryption, and accountability&lt;/strong&gt; are baked into every step of model access.&lt;/p&gt;

&lt;p&gt;This design keeps your AI APIs secure, your credentials protected, and your compliance auditors happy.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://www.linkedin.com/in/chandrani-mukherjee-usa-nj/" rel="noopener noreferrer"&gt;Chandrani Mukherjee&lt;/a&gt;,&lt;br&gt;&lt;br&gt;
Senior Solution Enterprise Architect | AI/ML Specialist&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>langchain</category>
      <category>python</category>
    </item>
    <item>
      <title>Streamlining Qwen: Containerized AI with Docker &amp; Kubernetes</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Tue, 23 Sep 2025 04:23:15 +0000</pubDate>
      <link>https://forem.com/moni121189/streamlining-qwen-containerized-ai-with-docker-kubernetes-41e1</link>
      <guid>https://forem.com/moni121189/streamlining-qwen-containerized-ai-with-docker-kubernetes-41e1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Deploying large language models like &lt;strong&gt;Qwen&lt;/strong&gt; can be resource-intensive and environment-dependent. By using &lt;strong&gt;Docker&lt;/strong&gt;, we can containerize the Qwen model for consistent, reproducible, and scalable deployments across different systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Dockerize Qwen?
&lt;/h2&gt;

&lt;p&gt;Docker provides several advantages when running AI models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility&lt;/strong&gt;: Ensures the same environment everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability&lt;/strong&gt;: Deploy on any system with Docker installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Easier integration with orchestration tools like Kubernetes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: Keeps dependencies separated from the host system.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Steps to Dockerize Qwen
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Dockerfile
&lt;/h3&gt;

&lt;p&gt;A sample Dockerfile for Qwen might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use an official PyTorch image as a base&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; pytorch/pytorch:2.1.0-cuda11.8-cudnn8-runtime&lt;/span&gt;

&lt;span class="c"&gt;# Set working directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Install system dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git

&lt;span class="c"&gt;# Copy project files&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Install Python dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;     pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Expose the API port&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;

&lt;span class="c"&gt;# Start the model service&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "serve_qwen.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Build the Docker Image
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; qwen-model:latest &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Run the Container
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 qwen-model:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the Qwen model server inside a container, accessible on port 8000.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Using Docker Compose (Optional)
&lt;/h3&gt;

&lt;p&gt;For more complex setups, you can use &lt;strong&gt;docker-compose.yml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;qwen&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/app/data&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;GPU-enabled Docker images&lt;/strong&gt; for better performance.&lt;/li&gt;
&lt;li&gt;Keep model weights in &lt;strong&gt;mounted volumes&lt;/strong&gt; for easier updates.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;healthcheck&lt;/strong&gt; in Docker to monitor container status.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;environment variables&lt;/strong&gt; for configuration.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;By dockerizing the &lt;strong&gt;Qwen model&lt;/strong&gt;, you can simplify deployment, ensure reproducibility, and scale more effectively across cloud or on-premise environments. This approach makes it easier for teams to share, deploy, and manage AI workloads.&lt;/p&gt;

</description>
      <category>python</category>
      <category>docker</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>From Chaos to Clarity: Leveraging Pydantic for Smarter AI</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Tue, 23 Sep 2025 04:18:39 +0000</pubDate>
      <link>https://forem.com/moni121189/from-chaos-to-clarity-leveraging-pydantic-for-smarter-ai-5aan</link>
      <guid>https://forem.com/moni121189/from-chaos-to-clarity-leveraging-pydantic-for-smarter-ai-5aan</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In modern AI applications, data validation, serialization, and consistency play a crucial role. &lt;strong&gt;Pydantic&lt;/strong&gt;, a Python library for data validation using Python type annotations, offers powerful tools that can be leveraged alongside AI systems to ensure reliability and scalability.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Pydantic?
&lt;/h2&gt;

&lt;p&gt;AI workflows often deal with unstructured, noisy, or inconsistent data. Pydantic provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data validation&lt;/strong&gt;: Ensures input data conforms to expected formats before being processed by AI models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type enforcement&lt;/strong&gt;: Minimizes runtime errors by enforcing strict data typing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serialization&lt;/strong&gt;: Facilitates seamless conversion between JSON, dictionaries, and objects for API integration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Potential Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Input Validation for AI Models
&lt;/h3&gt;

&lt;p&gt;AI models expect structured input. Using Pydantic, developers can define schemas for model inputs, ensuring only valid and sanitized data reaches the inference pipeline.&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;TextInput&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;text&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;language&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guarantees that every input to an NLP model contains a text field and a language specification.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Standardizing Data for Training Pipelines
&lt;/h3&gt;

&lt;p&gt;Training datasets can have missing values or inconsistent formats. Pydantic models help enforce schema constraints during preprocessing, ensuring cleaner and more reliable training data.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Integration with APIs
&lt;/h3&gt;

&lt;p&gt;Many AI systems expose APIs for inference or data collection. Pydantic can be used to validate requests and responses, reducing errors in API communication.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Explainability and Logging
&lt;/h3&gt;

&lt;p&gt;With Pydantic, validated inputs and outputs can be logged in a consistent format. This structured logging aids in &lt;strong&gt;explainable AI (XAI)&lt;/strong&gt; by making it easier to trace how inputs lead to outputs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benefits in AI Systems
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt;: Prevents malformed data from breaking pipelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Standardized schemas make it easier to scale AI applications across teams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt;: Improves debugging and auditability of AI decisions.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Pydantic bridges the gap between raw, messy real-world data and the structured requirements of AI systems. By combining strong data validation with modern AI pipelines, developers can build &lt;strong&gt;robust, explainable, and production-ready AI applications&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>fastapi</category>
      <category>webdev</category>
    </item>
    <item>
      <title>DaemonSet vs Deployment in Kubernetes: Key Differences Explained with Docker</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Thu, 04 Sep 2025 03:01:41 +0000</pubDate>
      <link>https://forem.com/moni121189/daemonset-vs-deployment-in-kubernetes-key-differences-explained-with-docker-57n7</link>
      <guid>https://forem.com/moni121189/daemonset-vs-deployment-in-kubernetes-key-differences-explained-with-docker-57n7</guid>
      <description>&lt;p&gt;Kubernetes DaemonSet vs Deployment: Key Differences&lt;/p&gt;

&lt;p&gt;Kubernetes provides multiple ways to run workloads on clusters, with &lt;strong&gt;DaemonSet&lt;/strong&gt; and &lt;strong&gt;Deployment&lt;/strong&gt; being two commonly used controllers. While they may seem similar, they serve different purposes and are optimized for distinct use cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Deployment?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Deployment&lt;/strong&gt; in Kubernetes is used to manage a set of identical &lt;strong&gt;Pods&lt;/strong&gt; that can be scaled, updated, and rolled back. Deployments are ideal for &lt;strong&gt;stateless applications&lt;/strong&gt; like web servers, APIs, or backend services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of Deployment:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensures a specified number of Pod replicas are running at any time.&lt;/li&gt;
&lt;li&gt;Provides rolling updates and rollbacks.&lt;/li&gt;
&lt;li&gt;Pods can be scheduled on &lt;strong&gt;any available node&lt;/strong&gt; in the cluster.&lt;/li&gt;
&lt;li&gt;Great for horizontally scalable workloads (scale up/down easily).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running a web application backend.&lt;/li&gt;
&lt;li&gt;Hosting a stateless API service.&lt;/li&gt;
&lt;li&gt;Running multiple replicas of a machine learning inference service.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is a DaemonSet?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;DaemonSet&lt;/strong&gt; ensures that a copy of a Pod runs on &lt;strong&gt;every node&lt;/strong&gt; (or specific nodes) in the cluster. DaemonSets are generally used for workloads that need to run &lt;strong&gt;cluster-wide&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of DaemonSet:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensures &lt;strong&gt;one Pod per node&lt;/strong&gt; (or per selected nodes using selectors/taints).&lt;/li&gt;
&lt;li&gt;Automatically adds Pods when new nodes are added to the cluster.&lt;/li&gt;
&lt;li&gt;Removes Pods when nodes are removed.&lt;/li&gt;
&lt;li&gt;Used for &lt;strong&gt;node-level agents&lt;/strong&gt; or monitoring/logging solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running a &lt;strong&gt;logging agent&lt;/strong&gt; (e.g., Fluentd, Logstash) on each node.&lt;/li&gt;
&lt;li&gt;Running a &lt;strong&gt;metrics collector&lt;/strong&gt; (e.g., Prometheus Node Exporter).&lt;/li&gt;
&lt;li&gt;Running a &lt;strong&gt;CNI plugin&lt;/strong&gt; for networking.&lt;/li&gt;
&lt;li&gt;Running a &lt;strong&gt;storage daemon&lt;/strong&gt; on each node.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  DaemonSet vs Deployment: Side-by-Side
&lt;/h2&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;Deployment&lt;/th&gt;
&lt;th&gt;DaemonSet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pod Placement&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs Pods on any nodes as scheduled&lt;/td&gt;
&lt;td&gt;Runs one Pod per node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scales horizontally with replicas&lt;/td&gt;
&lt;td&gt;Automatically matches cluster nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Updates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supports rolling updates &amp;amp; rollbacks&lt;/td&gt;
&lt;td&gt;Supports rolling updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stateless apps, scalable workloads&lt;/td&gt;
&lt;td&gt;Node-level daemons, monitoring, logging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node Awareness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not tied to node count&lt;/td&gt;
&lt;td&gt;Strongly tied to cluster node count&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How is this Related to Docker?
&lt;/h2&gt;

&lt;p&gt;Both &lt;strong&gt;DaemonSets&lt;/strong&gt; and &lt;strong&gt;Deployments&lt;/strong&gt; ultimately run &lt;strong&gt;containers&lt;/strong&gt;, and most commonly these containers are built from &lt;strong&gt;Docker images&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pods in Kubernetes&lt;/strong&gt; are wrappers around containers. The container runtime (historically Docker, now often containerd or CRI-O) actually runs the container.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Deployment&lt;/strong&gt; ensures that multiple replicas of your Docker container (e.g., &lt;code&gt;nginx:latest&lt;/code&gt;) are distributed across the cluster.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;DaemonSet&lt;/strong&gt; ensures that one instance of your Docker container (e.g., a log shipper or monitoring agent) runs on every node.&lt;/li&gt;
&lt;li&gt;When you &lt;code&gt;kubectl apply&lt;/code&gt; a Deployment or DaemonSet, Kubernetes pulls the specified Docker image and runs it inside Pods according to the controller's rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker (or another container runtime) provides the &lt;strong&gt;container packaging and execution&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Kubernetes controllers like &lt;strong&gt;Deployment&lt;/strong&gt; and &lt;strong&gt;DaemonSet&lt;/strong&gt; decide &lt;strong&gt;how, where, and how many times&lt;/strong&gt; those containers should run across the cluster.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;Use a &lt;strong&gt;Deployment&lt;/strong&gt; when you need &lt;strong&gt;scalable, stateless applications&lt;/strong&gt; that can run on any node.&lt;/li&gt;
&lt;li&gt;Use a &lt;strong&gt;DaemonSet&lt;/strong&gt; when you need a &lt;strong&gt;per-node agent or service&lt;/strong&gt; (like logging, monitoring, networking, or storage).&lt;/li&gt;
&lt;li&gt;Both are built on top of &lt;strong&gt;Docker images&lt;/strong&gt; (or OCI-compatible images) that package the application and dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;`# Save updated file&lt;br&gt;
output_path = "/mnt/data/daemonset_vs_deployment_with_docker.md"&lt;br&gt;
with open(output_path, "w") as f:&lt;br&gt;
    f.write(markdown_content)&lt;/p&gt;

&lt;p&gt;output_path`&lt;/p&gt;

</description>
      <category>aws</category>
      <category>docker</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>From Scanned PDFs to Smart Docs: OCR with LangChain, Docker &amp; AWS</title>
      <dc:creator>Chandrani Mukherjee</dc:creator>
      <pubDate>Mon, 25 Aug 2025 04:48:49 +0000</pubDate>
      <link>https://forem.com/moni121189/from-scanned-pdfs-to-smart-docs-ocr-with-langchain-docker-aws-3jlm</link>
      <guid>https://forem.com/moni121189/from-scanned-pdfs-to-smart-docs-ocr-with-langchain-docker-aws-3jlm</guid>
      <description>&lt;h1&gt;
  
  
  🧠 OCR Any PDF with LangChain, Docker, and AWS Using OCRmyPDF
&lt;/h1&gt;

&lt;p&gt;Many PDFs are just images — scanned contracts, invoices, or reports. They're unreadable by machines and non-searchable by humans.&lt;/p&gt;

&lt;p&gt;What if you could automate &lt;strong&gt;adding a searchable text layer&lt;/strong&gt; and then run a language model like GPT to &lt;strong&gt;summarize&lt;/strong&gt;, &lt;strong&gt;extract data&lt;/strong&gt;, or &lt;strong&gt;answer questions&lt;/strong&gt; from them?&lt;/p&gt;

&lt;p&gt;Welcome to a powerful workflow using:&lt;/p&gt;

&lt;p&gt;✅ &lt;a href="https://github.com/ocrmypdf/OCRmyPDF" rel="noopener noreferrer"&gt;OCRmyPDF&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✅ LangChain&lt;br&gt;&lt;br&gt;
✅ Docker&lt;br&gt;&lt;br&gt;
✅ AWS (S3, Lambda/ECS)&lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 What Is OCRmyPDF?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ocrmypdf&lt;/code&gt; is a command-line tool that adds an &lt;strong&gt;OCR layer&lt;/strong&gt; (invisible searchable text) to scanned PDFs using &lt;a href="https://github.com/tesseract-ocr/tesseract" rel="noopener noreferrer"&gt;Tesseract&lt;/a&gt;. It keeps the original visual layout intact while making the text machine-readable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ocrmypdf input.pdf output.pdf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use multiple languages:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ocrmypdf -l eng+fra input.pdf output.pdf&lt;/code&gt;&lt;br&gt;
🧱 Architecture Overview&lt;/p&gt;

&lt;p&gt;User Uploads PDF → S3 Bucket → Docker OCR Service → &lt;br&gt;
→ LangChain Processor → Response (Extracted Data / Summary / Q&amp;amp;A)&lt;br&gt;
🐳 Dockerizing the OCR Service&lt;br&gt;
Here's how to containerize the OCR layer:&lt;/p&gt;

&lt;p&gt;🧾 Dockerfile&lt;/p&gt;

&lt;p&gt;dockerfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.11-slim

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
    tesseract-ocr \
    ghostscript \
    libtesseract-dev \
    tesseract-ocr-eng \
    tesseract-ocr-fra \
    &amp;amp;&amp;amp; pip install ocrmypdf

WORKDIR /app
COPY ocr_service.py .

ENTRYPOINT ["python", "ocr_service.py"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧾 ocr_service.py&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ocrmypdf
import sys

input_path = sys.argv[1]
output_path = sys.argv[2]

ocrmypdf.ocr(input_path, output_path, language='eng+fra', skip_text=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and run locally:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t ocr-service .
docker run -v $(pwd):/data ocr-service /data/input.pdf /data/output.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Using LangChain for Text Analysis&lt;br&gt;
After OCR is done, you can feed the PDF into LangChain and perform QA, summarization, or structured data extraction.&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from langchain.document_loaders import PyPDFLoader
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI

loader = PyPDFLoader("output.pdf")
pages = loader.load()

chain = load_qa_chain(OpenAI(), chain_type="stuff")
response = chain.run(input_documents=pages, question="What is the document about?")

print(response)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangChain lets you chain OCR → LLM → Output via APIs or a UI.&lt;/p&gt;

&lt;p&gt;☁️ Deploying on AWS&lt;br&gt;
Option 1: ECS Fargate&lt;br&gt;
Push Docker image to ECR.&lt;/p&gt;

&lt;p&gt;Use Lambda to trigger Fargate task on new S3 uploads.&lt;/p&gt;

&lt;p&gt;OCR result uploaded back to S3.&lt;/p&gt;

&lt;p&gt;Option 2: Lambda + S3&lt;br&gt;
Use Lambda for lightweight OCR jobs (under 15 minutes runtime).&lt;/p&gt;

&lt;p&gt;Sample Lambda Code:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import boto3
import subprocess

def handler(event, context):
    s3 = boto3.client("s3")
    bucket = event["Records"][0]["s3"]["bucket"]["name"]
    key = event["Records"][0]["s3"]["object"]["key"]

    input_path = f"/tmp/{key}"
    output_path = f"/tmp/ocr_{key}"

    s3.download_file(bucket, key, input_path)
    subprocess.run(["ocrmypdf", "-l", "eng+fra", input_path, output_path])
    s3.upload_file(output_path, "ocr-output-bucket", f"ocr_{key}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔐 Security &amp;amp; 💰 Cost Tips&lt;br&gt;
Use IAM roles with least privilege.&lt;/p&gt;

&lt;p&gt;Set lifecycle rules on S3 buckets to auto-delete temp files.&lt;/p&gt;

&lt;p&gt;Use Lambda for lightweight OCR, ECS for heavier tasks.&lt;/p&gt;

&lt;p&gt;Monitor LangChain + LLM token usage if using OpenAI.&lt;/p&gt;

&lt;p&gt;✅ Final Thoughts&lt;br&gt;
You now have a production-ready OCR pipeline powered by:&lt;/p&gt;

&lt;p&gt;🧠 ocrmypdf for PDF text layers&lt;/p&gt;

&lt;p&gt;⚙️ Docker for repeatable environments&lt;/p&gt;

&lt;p&gt;🤖 LangChain for LLM magic&lt;/p&gt;

&lt;p&gt;☁️ AWS for scale&lt;/p&gt;

&lt;p&gt;This setup lets you convert unsearchable PDFs into structured insights. Automate document workflows, extract legal data, read scanned invoices — the possibilities are huge.&lt;/p&gt;

</description>
      <category>langchain</category>
      <category>docker</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
