<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kshitij Chaudhary</title>
    <description>The latest articles on DEV Community by Kshitij Chaudhary (@kshitijchaudhary).</description>
    <link>https://dev.to/kshitijchaudhary</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1392966%2Fc4718650-f30c-4597-85af-f0c3843f569c.jpg</url>
      <title>DEV Community: Kshitij Chaudhary</title>
      <link>https://dev.to/kshitijchaudhary</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kshitijchaudhary"/>
    <language>en</language>
    <item>
      <title>Why We Built NepStack Before Building Another App</title>
      <dc:creator>Kshitij Chaudhary</dc:creator>
      <pubDate>Fri, 10 Jul 2026 06:32:51 +0000</pubDate>
      <link>https://dev.to/kshitijchaudhary/why-we-built-nepstack-before-building-another-app-2bjj</link>
      <guid>https://dev.to/kshitijchaudhary/why-we-built-nepstack-before-building-another-app-2bjj</guid>
      <description>&lt;p&gt;A few weeks ago, our team had many product ideas.&lt;/p&gt;

&lt;p&gt;A grocery app.&lt;br&gt;
A property management app.&lt;br&gt;
A workflow SaaS.&lt;/p&gt;

&lt;p&gt;More ideas kept coming.&lt;/p&gt;

&lt;p&gt;But we noticed one problem:&lt;/p&gt;

&lt;p&gt;Every idea needed the same foundation again and again.&lt;/p&gt;

&lt;p&gt;Authentication.&lt;br&gt;
User management.&lt;br&gt;
Dashboard layout.&lt;br&gt;
Settings.&lt;br&gt;
Roles and permissions.&lt;br&gt;
Database patterns.&lt;br&gt;
Deployment.&lt;br&gt;
Documentation.&lt;br&gt;
Team workflow.&lt;/p&gt;

&lt;p&gt;So instead of starting another app immediately, we decided to build the foundation first.&lt;/p&gt;

&lt;p&gt;That decision became &lt;strong&gt;NepStack&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The repeated problem
&lt;/h2&gt;

&lt;p&gt;Most side projects start with excitement.&lt;/p&gt;

&lt;p&gt;But after a few days, the same setup work appears again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New app idea
      ↓
Build login again
      ↓
Build dashboard again
      ↓
Build settings again
      ↓
Set up deployment again
      ↓
Project slows down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where many projects lose momentum.&lt;/p&gt;

&lt;p&gt;Not because the idea is bad.&lt;/p&gt;

&lt;p&gt;But because the foundation is not reusable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we decided to build
&lt;/h2&gt;

&lt;p&gt;NepStack is our reusable SaaS starter kit.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;p&gt;Build the common SaaS foundation once.&lt;br&gt;
Reuse it for future products.&lt;br&gt;
Improve it over time.&lt;/p&gt;

&lt;p&gt;For the first version, we are focusing on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;User management&lt;/li&gt;
&lt;li&gt;Role-based access&lt;/li&gt;
&lt;li&gt;Dashboard shell&lt;/li&gt;
&lt;li&gt;Settings module&lt;/li&gt;
&lt;li&gt;API structure&lt;/li&gt;
&lt;li&gt;Database patterns&lt;/li&gt;
&lt;li&gt;GitHub workflow&lt;/li&gt;
&lt;li&gt;Jira planning&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Deployment foundation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not supposed to be perfect from day one.&lt;/p&gt;

&lt;p&gt;It is supposed to become useful through real usage.&lt;/p&gt;
&lt;h2&gt;
  
  
  Our Engineering OS
&lt;/h2&gt;

&lt;p&gt;We are also trying to build a simple engineering workflow around it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Idea
  ↓
Product note
  ↓
Jira ticket
  ↓
Git branch
  ↓
Pull request
  ↓
Code review
  ↓
Merge to dev
  ↓
Sprint demo
  ↓
Developer Notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps us connect planning, coding, documentation, and reflection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;I used to think progress meant writing code quickly.&lt;/p&gt;

&lt;p&gt;Now I am learning that real progress also means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;making clear decisions&lt;/li&gt;
&lt;li&gt;documenting why we chose something&lt;/li&gt;
&lt;li&gt;creating reusable systems&lt;/li&gt;
&lt;li&gt;reviewing work properly&lt;/li&gt;
&lt;li&gt;reducing repeated setup&lt;/li&gt;
&lt;li&gt;helping the team move in the same direction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good software is not only about writing features.&lt;/p&gt;

&lt;p&gt;It is also about building systems that make future work easier.&lt;/p&gt;

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

&lt;p&gt;Starting with NepStack taught me one important lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before building more apps, build the foundation that helps you build better apps.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is still early.&lt;/p&gt;

&lt;p&gt;We are learning as we go.&lt;/p&gt;

&lt;p&gt;But I think this approach will help us become more disciplined developers and build products with better structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;In the next Developer Note, I’ll share how we are planning our first sprint and organizing work with GitHub, Jira, and documentation.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;— Xitol Mitra&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>saas</category>
      <category>teamwork</category>
    </item>
    <item>
      <title>From Code to Cloud: Mastering the Gemini API with a Seamless CI/CD Pipeline</title>
      <dc:creator>Kshitij Chaudhary</dc:creator>
      <pubDate>Mon, 25 Nov 2024 03:23:49 +0000</pubDate>
      <link>https://dev.to/kshitijchaudhary/from-code-to-cloud-mastering-the-gemini-api-with-a-seamless-cicd-pipeline-1kdh</link>
      <guid>https://dev.to/kshitijchaudhary/from-code-to-cloud-mastering-the-gemini-api-with-a-seamless-cicd-pipeline-1kdh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's dynamic world of software development, APIs(Application Programming Interfaces) serve as the backbone of software development, which acts as bridges between different applications for communicating and sharing data seamlessly. It allows developers to leverage the existing features, functions, and services to accelerate development process with enhancement of application capabilities. Among the tons of APIs available, the Gemini API stands out offering AI capabilities, which allow developers to integrate generative models into the application.&lt;/p&gt;

&lt;p&gt;In this blog, we will explore setting up custom implementation of Gemini API, while focusing on its functionality and features. We will also discuss ensuring reliability through testing and automate the deployment process using the Continuous Integration/Continuous Deployment (CI/CD) Pipeline. By the end of this blog, we will be able to setup, test and deploy project using Gemini API, ensuring efficient workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding the Gemini API
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujnd1naink13sw8bfgsp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujnd1naink13sw8bfgsp.jpg" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
Gemini API is a cutting-edge AI technology that is developed by Google and provides the developers with powerful generative capabilities. It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate human-like text.&lt;/li&gt;
&lt;li&gt;Provide intelligent responses across various domains.&lt;/li&gt;
&lt;li&gt;Process complex queries.&lt;/li&gt;
&lt;li&gt;Create code snippets and analyze multimodal inputs.
This API acts as strong tool for development of the applications which require dynamic, AI-powered features.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why use CI/CD?
&lt;/h3&gt;

&lt;p&gt;Continuous Integration (CI)/Continuous Deployment (CD) is software development methodology from which we can improve code quality and streamline the development process. It reduces the time between writing code and deploying it. It helps in code quality improvement by catching and fixing errors. With CI/CD, we can standardize deployment processes and minimize human error in software releases.&lt;br&gt;
With the CI/CD pipeline along with the Gemini API's AI capabilities, we can create intelligent, scalable, and managed applications.&lt;/p&gt;


&lt;h2&gt;
  
  
  Setting Up the API
&lt;/h2&gt;

&lt;p&gt;The Gemini API allows developers to leverage Google's AI models for various tasks. Here are the few steps to get started.&lt;br&gt;
&lt;strong&gt;- Get API key from Google AI Studio&lt;/strong&gt;&lt;br&gt;
Here is the example of how to obtain the API key from Google AI Studio Interface. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4um0yov2h28w81tihfu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4um0yov2h28w81tihfu.jpg" alt="Getting API Keys from Google AI Studio" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Install the Gemini API SDK&lt;/strong&gt;&lt;br&gt;
Let's use Python package manager and install the Gemini API SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;generativeai&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Set up authentication and Usage.&lt;/strong&gt; &lt;br&gt;
Let's setup authentication for Gemini API, for creating model instance and generate content.&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;google.generativeai&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Load API key from the .env file
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_gemini_api&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Configure the Gemini API.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&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="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GenerativeModel&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;gemini-1.5-flash&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="n"&gt;model&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate content using the Gemini API.&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="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage
&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;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setup_gemini_api&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="nf"&gt;generate_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is CI/CD?&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;Here, we can remove the "YOUR_API_KEY" with the actual API key that we generated from Google AI Studio.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;How it worked?&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We imported the Google generative AI library which provided the necessary tools to interact with API.&lt;/li&gt;
&lt;li&gt;The prompt is created, which we will send to the API for processing.&lt;/li&gt;
&lt;li&gt;The initialized model processes the input and leverages Google's AI to generate the response.&lt;/li&gt;
&lt;li&gt;The API returns the generated content which we can access and use in our application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;em&gt;Key Points&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; We need to implement error handling to minimize potential issues during API requests.&lt;br&gt;
&lt;strong&gt;Environment Variables:&lt;/strong&gt; We need to store API key securely using environment variables to avoid hardcoding of sensitive information.&lt;/p&gt;


&lt;h2&gt;
  
  
  Integrating the Gemini API with Flask
&lt;/h2&gt;

&lt;p&gt;Let's use Flask as the framework  and create API endpoint and integrate essential features for handling prompts and custom instructions. We can see the key functionality implemented in the &lt;code&gt;generate_content&lt;/code&gt; function.&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;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;gemini_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;gemini_model&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="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;/chat&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;chat&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Endpoint to handle user prompts and generate AI responses.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;gemini_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&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;response&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;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;u&gt;Features&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This code accepts POST requests containing prompts and optional instructions.&lt;/li&gt;
&lt;li&gt;The function generates a response using Gemini API.&lt;/li&gt;
&lt;li&gt;It returns the output as JSON, making easy to integrate with frontend applications.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Testing the API
&lt;/h2&gt;

&lt;p&gt;We need to perform testing to ensure that our integration with the Gemini API functions correctly and efficiently. In detail, testing involves proper verification of the application and its interaction with the API endpoints, handling of responses, and management of errors.&lt;br&gt;
We perform two types of tests detailed below.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Unit Testing
&lt;/h3&gt;

&lt;p&gt;Let's use Python &lt;code&gt;unittest&lt;/code&gt; framework to validate individual components. Here is the example:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestGeminiAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&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;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&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;test_client&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;test_chat_endpoint&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&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;Test prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Test prompt&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="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&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;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This unit test stimulates client request to the /generate endpoint. It assets that the response contains the expected format and content.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Integration Testing
&lt;/h3&gt;

&lt;p&gt;For testing API endpoints, let's use  &lt;code&gt;requests&lt;/code&gt; library to stimulate HTTP requests.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_gemini_endpoint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5000/chat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;payload&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;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Gemini!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Gemini!&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test ensures that Gemini API integration functions correctly and handles various scenarios appropriately. &lt;/p&gt;




&lt;h2&gt;
  
  
  Automating Up CI/CD with Github Actions
&lt;/h2&gt;

&lt;p&gt;To automate testing and deployment, Let's use Github Actions. The CI/CD pipeline automates the build, test and deployment stages/ Let's make a workflow configuration. &lt;code&gt;.github/workflows/main.yml&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;name: CI/CD Pipeline for Gemini API

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    name: Run Unit Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Run Unit Tests
        run: |
          python -m unittest discover -s tests

  docker-build:
    name: Build and Test Docker Image
    runs-on: ubuntu-latest
    needs: test
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
      - name: Build Docker Image
        run: docker build -t gemini-api:latest -f Dockerfile .
      - name: Test Docker Container
        run: docker run --rm gemini-api:latest

  deploy:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: docker-build
    steps:
      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Push Docker Image
        run: |
          docker tag gemini-api:latest ${{ secrets.DOCKER_USERNAME }}/gemini-api:latest
          docker push ${{ secrets.DOCKER_USERNAME }}/gemini-api:latest
      - name: Deploy to Server
        run: |
          ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} &amp;lt;&amp;lt; 'EOF'
          docker pull ${{ secrets.DOCKER_USERNAME }}/gemini-api:latest
          docker stop gemini-api || true
          docker rm gemini-api || true
          docker run -d --name gemini-api -p 5000:5000 -e API_KEY=${{ secrets.API_KEY }} ${{ secrets.DOCKER_USERNAME }}/gemini-api:latest
          EOF

&lt;/pre&gt;

&lt;p&gt;With this configuration, we can automate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;the pipeline ensures all dependencies and configurations are prepared. With the use of &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;DockerfileTest&lt;/code&gt; , we can replicate the environment anywhere.&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;test_job&lt;/code&gt; stage validates the application by running predefined tests in controlled Docker environment. These tests ensure that the API works as expected.&lt;/li&gt;
&lt;li&gt;Once changes are integrated to &lt;code&gt;main&lt;/code&gt; branch, the CI/CD pipeline triggers automatically. It ensures there is no manual tasks needed for updating application.&lt;/li&gt;
&lt;li&gt;In final stage, it pulls the docker image and deploys to production environment. The application is deployed at port &lt;code&gt;5000&lt;/code&gt;, and sensitive credentials are passed with Github Secrets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Deployment Considerations&lt;/strong&gt;&lt;br&gt;
For smooth deployment, we consider the following.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;We use github secrets to store sensitive environment variables like &lt;code&gt;MONGODB_USERNAME&lt;/code&gt;, &lt;code&gt;MONGODB_PASSWORD&lt;/code&gt;, and &lt;code&gt;DOCKERHUB_PASSWORD&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;List all the dependencies in &lt;code&gt;requirements.txt&lt;/code&gt; file. It makes easier to replicate the development environment anywhere using the command.
&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adding the logging mechanisms help tracking application behaviour and we can debug issues promptly. For Flask app, we can use the Python's built-in logging module.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&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;logging&lt;/span&gt;  

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&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="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Application started successfully!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Challenges and Solution
&lt;/h2&gt;

&lt;p&gt;While doing every project, we come with unique challenges, and integration of Gemini API into CI/CD Pipeline was no exception. Here are some key challenges which I faced during this project along with the solutions which I implemented to overcome them.&lt;br&gt;
&lt;u&gt;&lt;strong&gt;1. Debugging Tests&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
I faced issues with failing the tests due to incorrect configurations and missing environment variables. This was really frustation and slowed down the development progress.&lt;br&gt;
&lt;u&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/u&gt; I implemented detailed logging in the test cases to capture the variable states and API responses, where i identified the failure points. I also used mock objects to stimulate API responses, which allowed me to isolate issues without depending on live calls.&lt;br&gt;
&lt;u&gt;&lt;strong&gt;2. Managing Secrets&lt;/strong&gt;&lt;/u&gt;&lt;br&gt;
It is challenge to manage the sensitive information like API keys, as hardcoding the values posess the security risks.&lt;br&gt;
&lt;u&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/u&gt; I used Github Secrets to store the sensitive information securely, allowing access in CI/CD Pipeline without exposing it on codebase. For local development, I have created a &lt;code&gt;.env&lt;/code&gt; file which was excluded on Git.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  .env file example
&lt;/h1&gt;

&lt;pre&gt;GEMINI_API_KEY=your_actual_api_key
MONGO_URI=your_mongo_uri
&lt;/pre&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;In this blog posts, we explored:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;How to set up the Gemini API&lt;/li&gt;
&lt;li&gt;Testing methodologies for API endpoints&lt;/li&gt;
&lt;li&gt;Automating deployment using CI/CD with Github Actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Testing:&lt;/strong&gt; Ensures reliabilty and scability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipeline:&lt;/strong&gt; Streamline development with automated process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Secrets:&lt;/strong&gt; Always protect sensitive information.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;With this practice, we can create intelligent, scalable and production-ready applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzce6ygyjv8ysfn1nh3x0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzce6ygyjv8ysfn1nh3x0.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
Looking ahead in coming days, I plan to expand the tests,  enhance the monitoring solution using AWS CloudWatch or Prometheus for performance tracking and explore further intgerations with other APIs to enhance the functionality.&lt;br&gt;
With more exploration in coming days, I aim to create the application which leverages advanced AI capabilities ensuring reliablitiy through development.&lt;/p&gt;




</description>
      <category>cicd</category>
      <category>githubactions</category>
      <category>geminiapi</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
