config.py — sozlamalar
Birinchi Python faylimiz. Nega aynan config?
Chunki qolgan hamma fayl shuni o'qiydi. Baza manzili, model nomi, chunk o'lchami — hammasi shu yerda. Agar sozlamalarni kod ichiga yozsangiz, keyin ularni o'zgartirish uchun 10 ta faylni ochishga to'g'ri keladi.
Qoida: parol kodda bo'lmaydi
# YOMON — parol kodda DB_PASSWORD = "mening_parolim" # YAXSHI — parol .env faylida DB_PASSWORD = os.getenv("DB_PASSWORD")
Birinchisi git'ga tushadi va butun dunyo ko'radi. Bu nazariy xavf emas — GitHub'da har kuni minglab parol shu tarzda oshkor bo'ladi.
.env fayli
DB_HOST=localhost DB_PORT=5432 DB_NAME=rag_demo DB_USER=postgres DB_PASSWORD=parolingiz RAG_MODE=local OLLAMA_BASE_URL=http://localhost:11434 OLLAMA_EMBED_MODEL=bge-m3 OLLAMA_MODEL=qwen2.5:7b RAG_TOP_K=10 RAG_RERANK_TOP=5 RAG_SIMILARITY_THRESHOLD=0.3 CHUNK_SIZE=500 CHUNK_OVERLAP=100
Va .env.example — bir xil, lekin parolsiz. Bu git'ga tushadi, shunda
boshqa dasturchi qaysi sozlamalar kerakligini biladi.
config.py
from pydantic_settings import BaseSettings from pydantic import Field class Settings(BaseSettings): db_host: str = Field(default="localhost") db_port: int = Field(default=5432) db_name: str = Field(default="rag_demo") db_user: str = Field(default="postgres") db_password: str = Field(default="") rag_mode: str = Field(default="local") ollama_base_url: str = Field(default="http://localhost:11434") ollama_embed_model: str = Field(default="bge-m3") ollama_model: str = Field(default="qwen2.5:7b") rag_top_k: int = Field(default=10) rag_rerank_top: int = Field(default=5) rag_similarity_threshold: float = Field(default=0.3) chunk_size: int = Field(default=500) chunk_overlap: int = Field(default=100) class Config: env_file = ".env" @property def database_url(self) -> str: return (f"postgresql://{self.db_user}:{self.db_password}" f"@{self.db_host}:{self.db_port}/{self.db_name}") @property def is_local(self) -> bool: return self.rag_mode == "local" settings = Settings()
Qator-qator
BaseSettings — pydantic'ning maxsus klassi. U .env faylini
avtomatik o'qiydi va qiymatlarni to'g'ri turga aylantiradi.
DB_PORT=5432 matn edi — int bo'lib keladi.
Field(default=...) — agar .env da yo'q bo'lsa, shu qiymat.
Shuning uchun loyiha .env siz ham ishga tushadi (bazadan tashqari).
@property database_url — parchalarni bitta manzilga yig'adi.
Bu SQLAlchemy kutadigan format:
postgresql://foydalanuvchi:parol@host:port/baza_nomi
is_local — lokal (Ollama) yoki bulut (OpenAI) rejimini
ajratadi. Kodning boshqa joylarida if settings.is_local: deb
yozamiz — matn solishtirishni takrorlamaslik uchun.
settings = Settings() — eng muhim qator. Bu bitta nusxa.
Boshqa fayllar from app.config import settings deb oladi va hammasi
shu bitta obyektni ishlatadi.
Tekshirish
python -c "from app.config import settings; print(settings.database_url)"
Parol ko'rinadi — bu normal, chunki bu sizning kompyuteringiz. Lekin uni hech qachon log'ga yozmang.
Nega pydantic, oddiy os.getenv emas?
os.getenv hamma narsani matn qaytaradi:
top_k = os.getenv("RAG_TOP_K") # "10" — bu MATN chunks[:top_k] # XATO: matn bilan kesib bo'lmaydi
Pydantic buni oldini oladi: int deb e'lon qilsangiz — int keladi.
Agar .env da RAG_TOP_K=abc yozilgan bo'lsa, dastur darhol
xato beradi, uch soatdan keyin qidiruv paytida emas.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.