<?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: Yagnesh</title>
    <description>The latest articles on DEV Community by Yagnesh (@yagnesh97).</description>
    <link>https://dev.to/yagnesh97</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%2F1208856%2F08d2cba1-9d3b-4417-8aa1-38b3be8a02ad.png</url>
      <title>DEV Community: Yagnesh</title>
      <link>https://dev.to/yagnesh97</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yagnesh97"/>
    <language>en</language>
    <item>
      <title>Building Document Intelligence: A Document Q&amp;A API with FastAPI, Qdrant, and RAG</title>
      <dc:creator>Yagnesh</dc:creator>
      <pubDate>Fri, 23 Oct 2026 09:24:05 +0000</pubDate>
      <link>https://dev.to/yagnesh97/building-document-intelligence-a-document-qa-api-with-fastapi-qdrant-and-rag-3p7o</link>
      <guid>https://dev.to/yagnesh97/building-document-intelligence-a-document-qa-api-with-fastapi-qdrant-and-rag-3p7o</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine having multiple financial documents—PDFs, spreadsheets, scanned receipts, and reports—and needing to answer a specific question about their contents.&lt;/p&gt;

&lt;p&gt;You could manually open each file, search for relevant information, extract the necessary figures, and organize the results.&lt;/p&gt;

&lt;p&gt;But what if you could upload these documents, index their contents, and ask questions directly?&lt;/p&gt;

&lt;p&gt;That is the problem I wanted to explore with &lt;strong&gt;Document Intelligence&lt;/strong&gt;, an AI-powered document-question-answering API built with Python.&lt;/p&gt;

&lt;p&gt;The project combines document parsing, OCR, embeddings, hybrid retrieval, and retrieval-augmented generation (RAG) into a single backend workflow.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/yagnesh97/document-intelligence" rel="noopener noreferrer"&gt;https://github.com/yagnesh97/document-intelligence&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What Problem Does It Solve?
&lt;/h2&gt;

&lt;p&gt;Financial information is often distributed across different document formats.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;A financial report may be available as a PDF.&lt;/li&gt;
&lt;li&gt;A spreadsheet may contain revenue and expense information.&lt;/li&gt;
&lt;li&gt;A scanned document may contain information that cannot be extracted using normal text extraction.&lt;/li&gt;
&lt;li&gt;A presentation may contain financial summaries across multiple slides.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finding relevant information across these documents can require manually opening files and searching through their contents.&lt;/p&gt;

&lt;p&gt;Document Intelligence provides a workflow to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload documents.&lt;/li&gt;
&lt;li&gt;Extract their text and metadata.&lt;/li&gt;
&lt;li&gt;Split the extracted content into smaller chunks.&lt;/li&gt;
&lt;li&gt;Generate embeddings and index the chunks.&lt;/li&gt;
&lt;li&gt;Retrieve relevant document content using a question.&lt;/li&gt;
&lt;li&gt;Generate an answer using the retrieved context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The objective is to make uploaded financial material searchable and enable question answering grounded in the retrieved document content.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Can It Process?
&lt;/h2&gt;

&lt;p&gt;Document Intelligence supports the following formats:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Supported formats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.txt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.csv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.xls&lt;/code&gt;, &lt;code&gt;.xlsx&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.pdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Word&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.docx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PowerPoint&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.pptx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.png&lt;/code&gt;, &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.jpeg&lt;/code&gt;, &lt;code&gt;.tif&lt;/code&gt;, &lt;code&gt;.tiff&lt;/code&gt;, &lt;code&gt;.bmp&lt;/code&gt;, &lt;code&gt;.webp&lt;/code&gt;, &lt;code&gt;.gif&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Different document formats require different extraction strategies.&lt;/p&gt;

&lt;p&gt;For example, extracting text from an Excel spreadsheet is different from extracting text from a scanned PDF.&lt;/p&gt;

&lt;p&gt;The project uses format-specific parsers and dedicated PDF analysis and OCR paths to handle these differences.&lt;/p&gt;
&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The application is built around a FastAPI API, a Celery ingestion worker, document storage, MongoDB, and Qdrant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj3ptjuspipjlcwdai0q.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj3ptjuspipjlcwdai0q.jpg" alt="Architecture diagram" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main components are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FastAPI&lt;/td&gt;
&lt;td&gt;HTTP API and request handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Celery&lt;/td&gt;
&lt;td&gt;Asynchronous document ingestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redis&lt;/td&gt;
&lt;td&gt;Task queue and Celery backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MongoDB&lt;/td&gt;
&lt;td&gt;Document records, extracted content, metadata, and chunks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MinIO AIStor / S3&lt;/td&gt;
&lt;td&gt;Original document storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qdrant&lt;/td&gt;
&lt;td&gt;Dense and sparse vector storage and hybrid retrieval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sentence Transformers&lt;/td&gt;
&lt;td&gt;Dense embedding generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FastEmbed&lt;/td&gt;
&lt;td&gt;Sparse embedding generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI / Gemini&lt;/td&gt;
&lt;td&gt;Question answering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PyMuPDF / OCRmyPDF / Tesseract&lt;/td&gt;
&lt;td&gt;PDF extraction and OCR&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The architecture separates document ingestion from question answering.&lt;/p&gt;

&lt;p&gt;Document processing happens asynchronously through Celery, while search and chat requests are handled synchronously by the API.&lt;/p&gt;
&lt;h2&gt;
  
  
  Document Processing Workflow
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Uploading documents
&lt;/h3&gt;

&lt;p&gt;The API exposes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST /files&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The endpoint accepts multipart file uploads.&lt;/p&gt;

&lt;p&gt;Before processing, it validates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of uploaded files&lt;/li&gt;
&lt;li&gt;Individual file size&lt;/li&gt;
&lt;li&gt;Total request size&lt;/li&gt;
&lt;li&gt;Supported file extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After validation, the API creates a document record in MongoDB.&lt;/p&gt;

&lt;p&gt;The original file is stored in S3-compatible object storage, and the document ID is submitted to Celery for background processing.&lt;/p&gt;

&lt;p&gt;The upload response includes the document ID and task ID.&lt;/p&gt;

&lt;p&gt;This allows the client to track the document without waiting for the entire ingestion process to finish.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Extracting document content
&lt;/h3&gt;

&lt;p&gt;Once the Celery worker receives the document ID, it retrieves the original file and selects a parser based on the filename extension.&lt;/p&gt;

&lt;p&gt;For common office documents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text files are processed using text extraction.&lt;/li&gt;
&lt;li&gt;CSV files are parsed for their content.&lt;/li&gt;
&lt;li&gt;Excel files include worksheet text.&lt;/li&gt;
&lt;li&gt;Word documents include document and table content.&lt;/li&gt;
&lt;li&gt;PowerPoint files include slide content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PDF processing requires additional analysis.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Handling different types of PDFs
&lt;/h3&gt;

&lt;p&gt;One of the interesting parts of the project is its PDF processing strategy.&lt;/p&gt;

&lt;p&gt;Not every PDF contains extractable text.&lt;/p&gt;

&lt;p&gt;Some PDFs contain native text, some contain scanned images, and others combine both.&lt;/p&gt;

&lt;p&gt;Document Intelligence analyzes PDFs and classifies them into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native-text PDFs&lt;/li&gt;
&lt;li&gt;Image-based PDFs&lt;/li&gt;
&lt;li&gt;Hybrid PDFs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Native-text PDFs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are processed using PyMuPDF text extraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image-based PDFs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are processed using OCRmyPDF, followed by text extraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid PDFs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are analyzed page by page.&lt;/p&gt;

&lt;p&gt;Pages that require OCR are processed using PyMuPDF OCR, while pages with usable native text can continue through normal extraction.&lt;/p&gt;

&lt;p&gt;This avoids treating every PDF as an image or assuming that every PDF contains extractable text.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. OCR for scanned documents
&lt;/h3&gt;

&lt;p&gt;Scanned documents require OCR because their contents are stored as images rather than selectable text.&lt;/p&gt;

&lt;p&gt;The project uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tesseract for standalone image OCR&lt;/li&gt;
&lt;li&gt;OCRmyPDF for image-based PDF processing&lt;/li&gt;
&lt;li&gt;PyMuPDF for PDF analysis and extraction&lt;/li&gt;
&lt;li&gt;OpenCV and Pillow for image processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For standalone images, the OCR pipeline applies grayscale conversion and enlargement before extracting text.&lt;/p&gt;

&lt;p&gt;OCR details are also retained in document metadata.&lt;/p&gt;

&lt;p&gt;The goal is to make scanned financial documents available to the same downstream indexing and retrieval workflow as other supported documents.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Chunking extracted content
&lt;/h3&gt;

&lt;p&gt;After extraction, the document content is split into paragraph-sized chunks.&lt;/p&gt;

&lt;p&gt;The current implementation uses blank-line paragraph boundaries.&lt;/p&gt;

&lt;p&gt;Each chunk is stored in MongoDB with its document association and chunk information.&lt;/p&gt;

&lt;p&gt;This makes it possible to retrieve relevant portions of a document instead of passing an entire document to the language model.&lt;/p&gt;

&lt;p&gt;One current limitation is that chunking does not yet support configurable chunk sizes or overlap.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the Retrieval Pipeline
&lt;/h2&gt;

&lt;p&gt;Extracting text is only the first part of the workflow.&lt;/p&gt;

&lt;p&gt;The next challenge is finding the relevant information when a user asks a question.&lt;/p&gt;

&lt;p&gt;Document Intelligence uses dense and sparse embeddings.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dense embeddings
&lt;/h3&gt;

&lt;p&gt;The project uses:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BAAI/bge-m3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Dense embeddings represent the semantic meaning of document chunks.&lt;/p&gt;

&lt;p&gt;This helps retrieve content that is conceptually related to a query, even when the exact wording differs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Sparse embeddings
&lt;/h3&gt;

&lt;p&gt;The project uses:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Qdrant/bm25&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sparse retrieval helps identify content based on important terms and keyword relationships.&lt;/p&gt;

&lt;p&gt;This is particularly useful when questions contain specific financial terminology, names, or figures.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hybrid retrieval
&lt;/h3&gt;

&lt;p&gt;The project combines dense and sparse retrieval using Qdrant reciprocal-rank fusion.&lt;/p&gt;

&lt;p&gt;The retrieval workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Embed the user query in both dense and sparse spaces.&lt;/li&gt;
&lt;li&gt;Retrieve candidate document chunks.&lt;/li&gt;
&lt;li&gt;Combine the results using reciprocal-rank fusion.&lt;/li&gt;
&lt;li&gt;Optionally rerank the retrieved candidates using a CrossEncoder.&lt;/li&gt;
&lt;li&gt;Return the most relevant chunks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The optional reranker uses:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;BAAI/bge-reranker-v2-m3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This additional step helps refine the candidate results before they are used for question answering.&lt;/p&gt;
&lt;h2&gt;
  
  
  Retrieval-Augmented Question Answering
&lt;/h2&gt;

&lt;p&gt;The final stage is answering questions using retrieved document context.&lt;/p&gt;

&lt;p&gt;Document Intelligence supports configured OpenAI and Gemini models through LangChain provider integrations.&lt;/p&gt;

&lt;p&gt;The chat workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive a question.&lt;/li&gt;
&lt;li&gt;Retrieve relevant document chunks.&lt;/li&gt;
&lt;li&gt;Use the retrieved chunks as context.&lt;/li&gt;
&lt;li&gt;Generate an answer using the configured language model.&lt;/li&gt;
&lt;li&gt;Return the answer and source chunks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The application prompt instructs the model to use the supplied context and avoid presenting financial advice as fact.&lt;/p&gt;

&lt;p&gt;The non-streaming chat endpoint returns the answer along with the retrieved sources.&lt;/p&gt;

&lt;p&gt;This allows users to inspect the document content used to generate the response.&lt;/p&gt;

&lt;p&gt;The project also supports streaming responses through server-sent events.&lt;/p&gt;
&lt;h2&gt;
  
  
  API Endpoints
&lt;/h2&gt;

&lt;p&gt;The API currently exposes the following endpoints:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Check API and MongoDB availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /files&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upload documents and queue ingestion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /files&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /files/{document_id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect document status, content, and metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DELETE /files/{document_id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete document records, chunks, vectors, and original files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retrieve relevant document chunks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /chat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ask questions using retrieved document context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /chat/stream&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stream generated answers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Document processing tracks the following states:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;QUEUED → PROCESSING → COMPLETED&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If processing fails, the document is marked:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FAILED&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The worker records the error and retries processing up to three times with backoff.&lt;/p&gt;
&lt;h2&gt;
  
  
  Running the Project Locally
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.14 or later&lt;/li&gt;
&lt;li&gt;uv&lt;/li&gt;
&lt;li&gt;Docker Engine and Docker Compose&lt;/li&gt;
&lt;li&gt;Tesseract&lt;/li&gt;
&lt;li&gt;OCRmyPDF and its system dependencies&lt;/li&gt;
&lt;li&gt;An API key for OpenAI or Gemini if you want to use chat&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Clone the repository
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/yagnesh97/document-intelligence.git
&lt;span class="nb"&gt;cd &lt;/span&gt;document-intelligence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Install dependencies
&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;cp&lt;/span&gt; .env.example .env
uv &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--all-groups&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Configure the required environment variables in &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At minimum, the settings class requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MONGODB_URI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S3_ACCESS_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S3_SECRET_KEY&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure the object-storage endpoint and create the bucket specified by &lt;code&gt;S3_BUCKET&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Start infrastructure
&lt;/h3&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;p&gt;The Compose configuration starts the local infrastructure, including Redis, MongoDB, MinIO AIStor, Qdrant, and Flower.&lt;/p&gt;
&lt;h3&gt;
  
  
  Start the API
&lt;/h3&gt;


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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Start the Celery worker
&lt;/h3&gt;

&lt;p&gt;In another terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run celery &lt;span class="nt"&gt;-A&lt;/span&gt; app.worker.celery:celery worker &lt;span class="nt"&gt;--loglevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nt"&gt;--pool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;solo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify the API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:8000/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive API documentation is available at:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://127.0.0.1:8000/docs" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Uploading a Document
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:8000/files &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s1"&gt;'files=@./statement.pdf;type=application/pdf'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response contains a document ID.&lt;/p&gt;

&lt;p&gt;Use that ID to inspect processing status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:8000/files/&amp;lt;document-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait until the document reaches &lt;code&gt;COMPLETED&lt;/code&gt; before searching its content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Searching Document Content
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--get&lt;/span&gt; &lt;span class="s1"&gt;'http://127.0.0.1:8000/search'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'q=What was the operating income?'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-urlencode&lt;/span&gt; &lt;span class="s1"&gt;'limit=5'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The search response contains retrieved chunks, their scores, document identifiers, and metadata.&lt;/p&gt;

&lt;p&gt;Search can also be scoped to a specific document using &lt;code&gt;document_id&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Asking Questions
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:8000/chat &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "question": "Summarize the reported revenue.",
    "model_id": "&amp;lt;llm-model-object-id&amp;gt;",
    "document_id": "&amp;lt;document-id&amp;gt;",
    "limit": 5
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generated answer&lt;/li&gt;
&lt;li&gt;Retrieved source chunks&lt;/li&gt;
&lt;li&gt;Document identifiers&lt;/li&gt;
&lt;li&gt;Chunk identifiers&lt;/li&gt;
&lt;li&gt;Retrieval scores&lt;/li&gt;
&lt;li&gt;Source metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;model_id&lt;/code&gt; must be the MongoDB ObjectId of an enabled LLM model configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;The project uses pytest.&lt;/p&gt;

&lt;p&gt;Run the test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./cmd.sh &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run pytest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run specific tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run pytest tests/api/test_files.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run pytest tests/services/parsers/pdf/test_analyzer.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run code checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./cmd.sh check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Format the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./cmd.sh format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integration tests require the relevant external services and must be selected explicitly.&lt;/p&gt;

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

&lt;p&gt;Building Document Intelligence brought several backend and AI engineering concepts together.&lt;/p&gt;

&lt;p&gt;Some of the key areas explored include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing asynchronous document ingestion with FastAPI and Celery&lt;/li&gt;
&lt;li&gt;Handling multiple document formats through parser-specific workflows&lt;/li&gt;
&lt;li&gt;Understanding the differences between native-text and scanned PDFs&lt;/li&gt;
&lt;li&gt;Integrating OCR into document processing&lt;/li&gt;
&lt;li&gt;Generating dense and sparse embeddings&lt;/li&gt;
&lt;li&gt;Implementing hybrid retrieval with reciprocal-rank fusion&lt;/li&gt;
&lt;li&gt;Connecting retrieved document context to language models&lt;/li&gt;
&lt;li&gt;Managing document records, original files, chunks, and vectors across different storage systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also highlighted how important the document-processing stage is to the overall quality of a RAG application.&lt;/p&gt;

&lt;p&gt;Retrieval quality depends on the content extracted from the original document, how that content is chunked, and how relevant chunks are selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Limitations
&lt;/h2&gt;

&lt;p&gt;The project is still evolving.&lt;/p&gt;

&lt;p&gt;Some current limitations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paragraph-based chunking without configurable size or overlap&lt;/li&gt;
&lt;li&gt;Hard-coded local Redis configuration for Celery&lt;/li&gt;
&lt;li&gt;No API endpoint for listing or managing LLM model configurations&lt;/li&gt;
&lt;li&gt;Manual creation of the configured object-storage bucket&lt;/li&gt;
&lt;li&gt;Parser selection based on supported filename extensions&lt;/li&gt;
&lt;li&gt;No application-level authentication or authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The service should be placed behind appropriate access controls before being exposed beyond a local development environment.&lt;/p&gt;

&lt;p&gt;Financial documents may contain sensitive information, so storage and infrastructure access must also be configured carefully.&lt;/p&gt;

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

&lt;p&gt;There are several areas where the project could be improved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More flexible chunking strategies&lt;/li&gt;
&lt;li&gt;Configurable chunk size and overlap&lt;/li&gt;
&lt;li&gt;Improved document extraction and OCR accuracy&lt;/li&gt;
&lt;li&gt;More configurable ingestion infrastructure&lt;/li&gt;
&lt;li&gt;Better model configuration management&lt;/li&gt;
&lt;li&gt;Additional document-processing workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are potential improvements rather than features currently implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore the Project
&lt;/h2&gt;

&lt;p&gt;Document Intelligence is an open-source project for developers interested in document processing, OCR, hybrid search, and retrieval-augmented generation.&lt;/p&gt;

&lt;p&gt;You can explore the architecture, run the application locally, experiment with different documents, and adapt the implementation to your own use cases.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;GitHub Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/yagnesh97/document-intelligence" rel="noopener noreferrer"&gt;https://github.com/yagnesh97/document-intelligence&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're building document-processing or RAG applications, feel free to explore the code, share feedback, or contribute improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What would you add to a document-question-answering pipeline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd be interested to hear your thoughts.&lt;/p&gt;




&lt;h1&gt;
  
  
  Python #FastAPI #RAG #DocumentProcessing #OCR #Qdrant #ArtificialIntelligence #OpenSource #BackendDevelopment
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🧩 I Built a Privacy-First Chrome Extension to Collect Public Emails from LinkedIn</title>
      <dc:creator>Yagnesh</dc:creator>
      <pubDate>Sat, 17 Jan 2026 11:37:54 +0000</pubDate>
      <link>https://dev.to/yagnesh97/i-built-a-privacy-first-chrome-extension-to-collect-public-emails-from-linkedin-3mjg</link>
      <guid>https://dev.to/yagnesh97/i-built-a-privacy-first-chrome-extension-to-collect-public-emails-from-linkedin-3mjg</guid>
      <description>&lt;p&gt;While job hunting and doing outreach, I kept running into the same problem:&lt;/p&gt;

&lt;p&gt;A lot of LinkedIn posts and profiles already have email addresses in plain sight, but finding them is slow and repetitive. You scroll, click “see more”, copy one email, scroll again… repeat.&lt;/p&gt;

&lt;p&gt;I tried a few tools that claimed to solve this, but most of them had at least one of these issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They sent data to external servers&lt;/li&gt;
&lt;li&gt;Required accounts or logins&lt;/li&gt;
&lt;li&gt;Over-automated things in a way that felt risky&lt;/li&gt;
&lt;li&gt;Or clearly wouldn’t pass Chrome Web Store review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I decided to build a small tool myself.&lt;/p&gt;

&lt;p&gt;That’s how &lt;strong&gt;ReachIn&lt;/strong&gt; was born.&lt;/p&gt;

&lt;p&gt;👉 Repo: &lt;a href="https://github.com/yagnesh97/reach-in" rel="noopener noreferrer"&gt;https://github.com/yagnesh97/reach-in&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What ReachIn Is (and What It Isn’t)
&lt;/h2&gt;

&lt;p&gt;ReachIn is a Chrome extension that helps collect &lt;strong&gt;publicly visible email addresses&lt;/strong&gt; from LinkedIn search result pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Works only when you explicitly click a button&lt;/li&gt;
&lt;li&gt;Scrolls through LinkedIn search results&lt;/li&gt;
&lt;li&gt;Expands visible content&lt;/li&gt;
&lt;li&gt;Extracts email addresses already shown on the page&lt;/li&gt;
&lt;li&gt;Stores everything locally in your browser&lt;/li&gt;
&lt;li&gt;Lets you copy results or view past collections&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What it &lt;em&gt;does not&lt;/em&gt; do
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No background scraping&lt;/li&gt;
&lt;li&gt;No credential access&lt;/li&gt;
&lt;li&gt;No analytics or tracking&lt;/li&gt;
&lt;li&gt;No servers&lt;/li&gt;
&lt;li&gt;No remote APIs&lt;/li&gt;
&lt;li&gt;No automation running on its own&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Privacy From Day One
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chrome reviewers care far more about intent and data handling than fancy features.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I set a few non-negotiable rules early:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Everything runs locally&lt;/li&gt;
&lt;li&gt;No network requests&lt;/li&gt;
&lt;li&gt;User action triggers everything&lt;/li&gt;
&lt;li&gt;The behavior must be easy to explain in plain English&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Under the Hood (High Level)
&lt;/h2&gt;

&lt;p&gt;ReachIn is a plain &lt;strong&gt;Manifest V3 Chrome extension&lt;/strong&gt;. No frameworks, no build step.&lt;/p&gt;

&lt;p&gt;Structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── assets/
│   ├── css/
│   │   └── popup.css
│   ├── js/
│   │   ├── background.js
│   │   ├── content.js
│   │   └── popup.js
│   ├── icons/
│   │   ├── icon-16.png
│   │   ├── icon-32.png
│   │   ├── icon-48.png
│   │   └── icon-128.png
│
├── popup.html
├── manifest.json
│
├── README.md
├── PRIVACY.md
├── LICENSE
└── .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;The popup controls everything&lt;/li&gt;
&lt;li&gt;The content script runs only on &lt;code&gt;linkedin.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Scripts are injected only after user action&lt;/li&gt;
&lt;li&gt;Data is stored with &lt;code&gt;chrome.storage.local&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Content Script
&lt;/h2&gt;

&lt;p&gt;The content script does three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scrolls the page&lt;/li&gt;
&lt;li&gt;Clicks “see more” where needed&lt;/li&gt;
&lt;li&gt;Extracts emails from visible text and &lt;code&gt;mailto:&lt;/code&gt; links&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No DOM mutation beyond expanding content.&lt;/li&gt;
&lt;li&gt;No hidden scraping.&lt;/li&gt;
&lt;li&gt;No background execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was critical for staying within Chrome Web Store policies.&lt;/p&gt;




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

&lt;p&gt;I’m keeping the roadmap intentionally conservative:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minor UX improvements&lt;/li&gt;
&lt;li&gt;Performance tweaks&lt;/li&gt;
&lt;li&gt;Optional export formats&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you’re curious, feel free to check out the repo:&lt;br&gt;
👉 &lt;a href="https://github.com/yagnesh97/reach-in" rel="noopener noreferrer"&gt;https://github.com/yagnesh97/reach-in&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy building.&lt;/p&gt;

</description>
      <category>chromeextension</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building a Modern Web App: FastAPI + React TypeScript Template</title>
      <dc:creator>Yagnesh</dc:creator>
      <pubDate>Tue, 21 Jan 2025 22:32:59 +0000</pubDate>
      <link>https://dev.to/yagnesh97/building-a-modern-web-app-fastapi-react-typescript-template-5d88</link>
      <guid>https://dev.to/yagnesh97/building-a-modern-web-app-fastapi-react-typescript-template-5d88</guid>
      <description>&lt;p&gt;Hey developers! 👋 I'm excited to share a template I've created that combines FastAPI and React with TypeScript, aimed at helping you kickstart your full-stack projects faster. Whether you're building a new web application or looking to modernize your stack, this template provides a solid foundation with best practices baked in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Stack? 🤔
&lt;/h2&gt;

&lt;p&gt;The combination of FastAPI and React offers several compelling advantages:&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend (FastAPI)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lightning-fast performance with async support&lt;/li&gt;
&lt;li&gt;Automatic OpenAPI documentation&lt;/li&gt;
&lt;li&gt;Type hints and validation with Pydantic&lt;/li&gt;
&lt;li&gt;Easy to learn and highly productive&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend (React + TypeScript)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Type safety and better developer experience&lt;/li&gt;
&lt;li&gt;Modern React features and hooks&lt;/li&gt;
&lt;li&gt;Scalable component architecture&lt;/li&gt;
&lt;li&gt;Reduced runtime errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MongoDB for flexible document storage&lt;/li&gt;
&lt;li&gt;Redis for high-performance caching&lt;/li&gt;
&lt;li&gt;Docker for consistent environments&lt;/li&gt;
&lt;li&gt;Poetry and Yarn for dependency management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Template Features 🚀
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Containerized Development&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run everything in Docker or use a hybrid approach&lt;/li&gt;
&lt;li&gt;Consistent development environment across team members&lt;/li&gt;
&lt;li&gt;Production-ready Docker configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Development Tools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code formatting utilities&lt;/li&gt;
&lt;li&gt;Development scripts for common tasks&lt;/li&gt;
&lt;li&gt;Environment configuration templates&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Modern Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.11 with Poetry management&lt;/li&gt;
&lt;li&gt;Latest React 18 with TypeScript&lt;/li&gt;
&lt;li&gt;MongoDB and Redis integration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started 🌟
&lt;/h2&gt;

&lt;p&gt;The template is designed to be easy to use. Here's how you can get started:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/yagnesh97/fastapi-react-template
&lt;span class="nb"&gt;cd &lt;/span&gt;fastapi-react-template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set up your environment files:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backend environment&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;backend
&lt;span class="nb"&gt;cp&lt;/span&gt; .env-example .env

&lt;span class="c"&gt;# Database environment&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ../database
&lt;span class="nb"&gt;cp&lt;/span&gt; .env-example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Choose your development mode:&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Option 1: Full Docker Setup
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2: Hybrid Setup (Local Development with Dockerized Database)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start MongoDB and Redis&lt;/span&gt;
docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml up mongo redis &lt;span class="nt"&gt;--build&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# Start Backend&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;backend
poetry &lt;span class="nb"&gt;install&lt;/span&gt;
./cmd.sh start

&lt;span class="c"&gt;# Start Frontend&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
yarn &lt;span class="nb"&gt;install
&lt;/span&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── backend/          # FastAPI application
├── frontend/         # React TypeScript application
├── database/         # Database configuration
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Development Workflow 💻
&lt;/h2&gt;

&lt;p&gt;The template supports a flexible development workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Local Development&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hot-reloading for both frontend and backend&lt;/li&gt;
&lt;li&gt;Local dependency management&lt;/li&gt;
&lt;li&gt;Easy debugging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Docker Development&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent environment across team&lt;/li&gt;
&lt;li&gt;Easy service orchestration&lt;/li&gt;
&lt;li&gt;Production-like setup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimized Docker builds&lt;/li&gt;
&lt;li&gt;Environment-specific configurations&lt;/li&gt;
&lt;li&gt;Ready for CI/CD integration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Future improvements planned for the template:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication boilerplate&lt;/li&gt;
&lt;li&gt;Testing setup and examples&lt;/li&gt;
&lt;li&gt;CI/CD pipeline templates&lt;/li&gt;
&lt;li&gt;More development utilities&lt;/li&gt;
&lt;li&gt;Performance optimization examples&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Acknowledgments 🙏
&lt;/h2&gt;

&lt;p&gt;This template was inspired by and builds upon the excellent work of &lt;a href="https://dev.to/dpills"&gt;@dpills&lt;/a&gt; in his article &lt;a href="https://dev.to/dpills/fastapi-production-setup-guide-1hhh"&gt;FastAPI Production Setup Guide&lt;/a&gt;. His guide provided valuable insights into structuring a production-ready FastAPI application, which I've extended by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding React with TypeScript for the frontend&lt;/li&gt;
&lt;li&gt;Integrating MongoDB and Redis&lt;/li&gt;
&lt;li&gt;Security enhancements to the Docker&lt;/li&gt;
&lt;li&gt;Including additional development utilities&lt;/li&gt;
&lt;li&gt;Providing multiple deployment options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I highly recommend checking out his original article for in-depth insights into FastAPI production setups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute 🤝
&lt;/h2&gt;

&lt;p&gt;This template is open source and contributions are welcome! Whether it's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bug fixes&lt;/li&gt;
&lt;li&gt;New features&lt;/li&gt;
&lt;li&gt;Documentation improvements&lt;/li&gt;
&lt;li&gt;Best practices suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fork the repository&lt;/li&gt;
&lt;li&gt;Create your feature branch&lt;/li&gt;
&lt;li&gt;Submit a pull request&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Get Started Now 🚀
&lt;/h2&gt;

&lt;p&gt;Check out the template on GitHub: &lt;a href="https://github.com/yagnesh97/fastapi-react-template" rel="noopener noreferrer"&gt;fastapi-react-template&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, don't forget to give it a star ⭐️&lt;/p&gt;

&lt;p&gt;Have questions or suggestions? Feel free to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open an issue&lt;/li&gt;
&lt;li&gt;Submit a pull request&lt;/li&gt;
&lt;li&gt;Comment below&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's build something amazing together! 💪&lt;/p&gt;

&lt;h4&gt;
  
  
  #webdev #python #react #typescript #docker
&lt;/h4&gt;

</description>
    </item>
  </channel>
</rss>
