Asosiy qismga o'tish

config.py — sozlamalar

2-bob 6 kod bloki 579 so'z

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

python5 qator
# 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

python16 qator
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

python36 qator
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:

matn1 qator
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

bash1 qator
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:

python2 qator
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.

Telegramda yozish Narxlar