Concept #163Mediumpython-for-gen-aiimportant

Explain me detailly about the Folder Structure need to be followed in Python along with the flow diagram?

#python#folder-structure#project-structure#architecture#best-practices#packaging#gen-ai

Answer

Python Folder Structure Best Practices

A well-organised folder structure makes your code maintainable, testable, and scalable. The right structure depends on the project type — script, library, web app, or Gen AI application.


1. Basic Python Project Structure

The standard structure recommended by the Python Packaging Authority (PyPA):

text
my_project/
ā”œā”€ā”€ src/
│   └── my_package/
│       ā”œā”€ā”€ __init__.py        # makes it a Python package
│       ā”œā”€ā”€ main.py            # entry point
│       ā”œā”€ā”€ config.py          # configuration & settings
│       └── utils.py           # shared utility functions
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ __init__.py
│   ā”œā”€ā”€ test_main.py
│   └── test_utils.py
ā”œā”€ā”€ docs/                      # documentation
ā”œā”€ā”€ pyproject.toml             # project metadata & dependencies
ā”œā”€ā”€ README.md
ā”œā”€ā”€ .env                       # environment variables (never commit)
└── .gitignore
python
# pyproject.toml
[project]
name = "my_package"
version = "1.0.0"
requires-python = ">=3.11"
dependencies = [
    "openai>=1.0",
    "langchain>=0.2",
]

[project.optional-dependencies]
dev = ["pytest", "ruff", "mypy"]

2. Gen AI Application Structure

The recommended structure for a production Gen AI app (RAG, agents, LLM APIs):

text
gen_ai_app/
ā”œā”€ā”€ src/
│   └── app/
│       ā”œā”€ā”€ __init__.py
│       ā”œā”€ā”€ api/                       # API layer (FastAPI routes)
│       │   ā”œā”€ā”€ __init__.py
│       │   ā”œā”€ā”€ routes.py              # endpoint definitions
│       │   └── schemas.py             # Pydantic request/response models
│       ā”œā”€ā”€ core/                      # app-wide config & infrastructure
│       │   ā”œā”€ā”€ __init__.py
│       │   ā”œā”€ā”€ config.py              # settings (env vars, constants)
│       │   └── logging.py             # logging setup
│       ā”œā”€ā”€ models/                    # AI model wrappers
│       │   ā”œā”€ā”€ __init__.py
│       │   ā”œā”€ā”€ llm.py                 # LLM client (OpenAI, Anthropic, etc.)
│       │   └── embedder.py            # embedding model client
│       ā”œā”€ā”€ pipelines/                 # end-to-end AI workflows
│       │   ā”œā”€ā”€ __init__.py
│       │   ā”œā”€ā”€ rag.py                 # RAG pipeline
│       │   └── ingestion.py           # document ingestion pipeline
│       ā”œā”€ā”€ services/                  # business logic layer
│       │   ā”œā”€ā”€ __init__.py
│       │   ā”œā”€ā”€ vector_store.py        # vector DB operations
│       │   └── retriever.py           # retrieval logic
│       └── utils/                     # shared helpers
│           ā”œā”€ā”€ __init__.py
│           ā”œā”€ā”€ text.py                # text processing utilities
│           └── validators.py          # input validation
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ unit/
│   │   ā”œā”€ā”€ test_pipelines.py
│   │   └── test_services.py
│   └── integration/
│       └── test_api.py
ā”œā”€ā”€ data/
│   ā”œā”€ā”€ raw/                           # original source documents
│   ā”œā”€ā”€ processed/                     # cleaned, chunked documents
│   └── embeddings/                    # cached embeddings
ā”œā”€ā”€ notebooks/                         # Jupyter notebooks for exploration
│   ā”œā”€ā”€ 01_data_exploration.ipynb
│   └── 02_model_evaluation.ipynb
ā”œā”€ā”€ configs/
│   ā”œā”€ā”€ dev.yaml                       # development config
│   └── prod.yaml                      # production config
ā”œā”€ā”€ scripts/
│   ā”œā”€ā”€ ingest_docs.py                 # one-off ingestion script
│   └── evaluate_pipeline.py           # evaluation script
ā”œā”€ā”€ docker/
│   ā”œā”€ā”€ Dockerfile
│   └── docker-compose.yml
ā”œā”€ā”€ pyproject.toml
ā”œā”€ā”€ .env.example                       # template (commit this)
ā”œā”€ā”€ .env                               # actual secrets (never commit)
ā”œā”€ā”€ README.md
└── .gitignore

3. Key Files Explained

text
core/config.py
— Centralised Settings

python
from pydantic_settings import BaseSettings
from functools import lru_cache

class Settings(BaseSettings):
    # LLM
    openai_api_key: str
    openai_model: str = "gpt-4o"
    temperature: float = 0.7
    max_tokens: int = 2048

    # Vector DB
    chroma_persist_dir: str = "./data/embeddings"
    embedding_model: str = "text-embedding-3-small"

    # App
    app_name: str = "GenAI App"
    debug: bool = False
    log_level: str = "INFO"

    class Config:
        env_file = ".env"

@lru_cache
def get_settings() -> Settings:
    return Settings()

# Usage anywhere in the app
settings = get_settings()
print(settings.openai_model)    # gpt-4o

text
models/llm.py
— LLM Wrapper

python
from openai import OpenAI
from app.core.config import get_settings

settings = get_settings()

class LLMClient:
    def __init__(self):
        self._client = OpenAI(api_key=settings.openai_api_key)
        self._model = settings.openai_model

    def generate(self, prompt: str, system: str = "You are a helpful assistant.") -> str:
        response = self._client.chat.completions.create(
            model=self._model,
            messages=[
                {"role": "system", "content": system},
                {"role": "user", "content": prompt},
            ],
            temperature=settings.temperature,
            max_tokens=settings.max_tokens,
        )
        return response.choices[0].message.content

text
pipelines/rag.py
— RAG Pipeline

python
from app.models.llm import LLMClient
from app.models.embedder import EmbedderClient
from app.services.retriever import Retriever

class RAGPipeline:
    def __init__(self):
        self.llm = LLMClient()
        self.embedder = EmbedderClient()
        self.retriever = Retriever()

    def run(self, query: str) -> str:
        # 1. Embed the query
        query_vector = self.embedder.embed(query)
        # 2. Retrieve relevant docs
        docs = self.retriever.search(query_vector, k=5)
        # 3. Build augmented prompt
        context = "\n\n".join(docs)
        prompt = f"Answer using this context:\n{context}\n\nQuestion: {query}"
        # 4. Generate response
        return self.llm.generate(prompt)

text
api/routes.py
— FastAPI Routes

python
from fastapi import APIRouter, Depends
from app.api.schemas import QueryRequest, QueryResponse
from app.pipelines.rag import RAGPipeline

router = APIRouter(prefix="/api/v1")

def get_pipeline() -> RAGPipeline:
    return RAGPipeline()

@router.post("/query", response_model=QueryResponse)
async def query(request: QueryRequest, pipeline: RAGPipeline = Depends(get_pipeline)):
    answer = pipeline.run(request.question)
    return QueryResponse(answer=answer)

4. Request Flow Diagram


5. LangChain / Agent Project Structure

For more complex multi-agent Gen AI systems:

text
agent_project/
ā”œā”€ā”€ src/
│   └── app/
│       ā”œā”€ā”€ agents/
│       │   ā”œā”€ā”€ researcher.py      # research agent
│       │   ā”œā”€ā”€ writer.py          # content writer agent
│       │   └── reviewer.py        # review/critique agent
│       ā”œā”€ā”€ tools/
│       │   ā”œā”€ā”€ web_search.py      # Tavily / SerpAPI tool
│       │   ā”œā”€ā”€ code_executor.py   # Python REPL tool
│       │   └── file_reader.py     # document reading tool
│       ā”œā”€ā”€ memory/
│       │   ā”œā”€ā”€ conversation.py    # conversation buffer memory
│       │   └── vector_memory.py   # long-term vector memory
│       └── chains/
│           ā”œā”€ā”€ summarise.py       # summarisation chain
│           └── qa_chain.py        # Q&A chain

6.
text
.gitignore
for Python Gen AI Projects

text
# Python
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/
.venv/
venv/

# Environment & secrets
.env
*.key
*.pem

# Data & models
data/raw/
data/processed/
*.pkl
*.bin
*.safetensors
chroma_db/

# Notebooks
.ipynb_checkpoints/

# IDE
.vscode/
.idea/

# OS
.DS_Store
Thumbs.db

7. Folder Structure Rules

RuleWhy
One
text
__init__.py
per package
Makes directory a Python package
Keep
text
config.py
in
text
core/
Single source of truth for all settings
Separate
text
pipelines/
from
text
services/
Pipelines orchestrate; services execute
Put secrets in
text
.env
, never in code
Security — never commit API keys
Use
text
src/
layout
Prevents accidental imports of non-installed package
Separate
text
unit/
and
text
integration/
tests
Different speed and setup requirements
Keep
text
notebooks/
out of
text
src/
Exploration only, not production code
Use
text
scripts/
for one-off tasks
Keeps
text
src/
clean and importable

Quick Reference

Pro tip: Start with the Gen AI app structure even for small projects. Adding layers later is painful — removing them is easy. A good folder structure is the first step to a production-ready Gen AI system.

Learn more at Python Packaging Guide and Cookiecutter Data Science.