PYHINTS Telegram 460
Python Hints
توی پست قبلی زیر sample.env خروجی دستور tree رو هم گذاشتم (نباید اینجا باشه) فقط گفتم شاید توی مثال‌های بعدی لازم شد. اما مهمترین فایل این مثال config.py هست. راجب lru_cache قبلا صحبت کردیم؛ اما بطور خلاصه بخوام یادآوری کنم. اگر یک تابع در طول پروژه مقدار…
خط ۱۴ تا ۱۹:
همیشه اسمش رو Global بهش میدم تا همه بچه‌های تیم بدونند تحت هر ENV_STATE ایی که باشه این تنظیمات برای پروژه واجب هست.
و بعد از این برای هر ENV_STATE یک کلاس جداگونه تعریف میشه؛ بعضی‌ موارد ممکنه مقدار default داشته باشند مثل MONGO_DBNAME توی کلاس DevConfig (دوباره برمیگردم سراغش). اما توی خط بعدی
SettingsConfigDict(env_prefix="DEV_")
چیزی که خیلی مهم هست env_prefix هست که میگه اسم‌های هرکدوم از تنظیمات لازم که توی Global تعریف شده اگر اولش DEV_ داشت توسط این کلاس هندل میشه؛ زیاده روی هست ؟ شاید باشه ولی اینطوری مطمئن میشم طرف بیشتر حواسش جمع هست موقع ساخت .env همین کار رو برای موارد دیگه هم انجام میدم. من case_sensitive رو True نمیذارم هیچوقت (شاید یکی حال نمی‌کنه از کاراکترهای uppercase استفاده کنه توی .env )

خط ۳۶ تا ۴۷:
همونطور که گفتم من هرجا تابعی دارم که return value ثابتی رو خواهد داشت یا حتی input argument های محدودی داره که همیشه return value خاص خودشون رو تولید می‌کنند از lru_cache استفاده می‌کنم که سربار کمتری روی سیستم و پردازش داشته باشه (بیشتر نمیگم چون قبلا راجبش صحبت‌ کردم؛ مثالش توی نجات پروژه رو هم زدم)
توی این تابع بر اساس مقداری که BaseConfig از .env برای ENV_STATE خواهد گرفت class معادلش رو صدا میزنم.
اما برای اینکه مطمئن بشم مقدار ENV_STATE برای مثلا DEV در صورت وجود DEV_ENV_STATE خونده نمی‌شه موقع ساخت instance اینکارو کردم :
return DevConfig(ENV_STATE="development")
که یعنی مهم نیست یوزر چی خواسته یا اینکه اصن تعریف کرده یا نه باید development باشه ENV_STATE ایی که از DevConfig میاد.

حواستون باشه ENV_STATE , DEV_ENV_STATE تنظیمات متفاوتی هست از نظر کدهای بالا بخاطر env_prefix هرچیزی که env_prefix درست رو نداشته باشه بی‌اهمیت میشه توی اون کلاس.

print(settings.model_dump())
وظیفه model_dump بازگردان خروجی بصورت dictionary هست همون کار
settings.dict()
رو می‌کنه که اتوی آپدیت‌های بعدی قرار هست deprecate بشه.

شمارو نمی‌دونم ولی من این تنظیم رو به شکوندن فایل‌ها به ۱۲ تا فایل بیس و بعدم monkey patch برای هر environment ترجیح میدم.

اما اگر تنظیمات بسیار زیادی داشتید؛ می‌تونید ازین حالت هم استفاده کنید :
├── config
│ ├── base.py
│ ├── dev.py
│ ├── __init__.py
│ ├── prod.py
│ └── test.py


و توی init تابع get_config , settings رو داشته باشید :
from functools import lru_cache

from config.base import BaseConfig, BaseSettings
from config.dev import DevConfig
from config.prod import ProdConfig
from config.test import TestConfig


@lru_cache()
def get_config(env_state: str | None) -> GlobalConfig:
try:
match env_state.casefold(): # type: ignore
case "production" | "prod":
return ProdConfig(ENV_STATE="production") # type: ignore
case "test":
return TestConfig(ENV_STATE="test") # type: ignore
case _:
return DevConfig(ENV_STATE="development") # type: ignore
except AttributeError:
return DevConfig(ENV_STATE="development") # type: ignore


settings = get_config(BaseConfig().ENV_STATE)


موقع استفاده هم یوزر راحت هست :
from myproject.config import settings


بنظرم این مورد هم حتی تمیزتر هست.‍‍‍
👍18❤‍🔥41



tgoop.com/pyHints/460
Create:
Last Update:

خط ۱۴ تا ۱۹:
همیشه اسمش رو Global بهش میدم تا همه بچه‌های تیم بدونند تحت هر ENV_STATE ایی که باشه این تنظیمات برای پروژه واجب هست.
و بعد از این برای هر ENV_STATE یک کلاس جداگونه تعریف میشه؛ بعضی‌ موارد ممکنه مقدار default داشته باشند مثل MONGO_DBNAME توی کلاس DevConfig (دوباره برمیگردم سراغش). اما توی خط بعدی
SettingsConfigDict(env_prefix="DEV_")
چیزی که خیلی مهم هست env_prefix هست که میگه اسم‌های هرکدوم از تنظیمات لازم که توی Global تعریف شده اگر اولش DEV_ داشت توسط این کلاس هندل میشه؛ زیاده روی هست ؟ شاید باشه ولی اینطوری مطمئن میشم طرف بیشتر حواسش جمع هست موقع ساخت .env همین کار رو برای موارد دیگه هم انجام میدم. من case_sensitive رو True نمیذارم هیچوقت (شاید یکی حال نمی‌کنه از کاراکترهای uppercase استفاده کنه توی .env )

خط ۳۶ تا ۴۷:
همونطور که گفتم من هرجا تابعی دارم که return value ثابتی رو خواهد داشت یا حتی input argument های محدودی داره که همیشه return value خاص خودشون رو تولید می‌کنند از lru_cache استفاده می‌کنم که سربار کمتری روی سیستم و پردازش داشته باشه (بیشتر نمیگم چون قبلا راجبش صحبت‌ کردم؛ مثالش توی نجات پروژه رو هم زدم)
توی این تابع بر اساس مقداری که BaseConfig از .env برای ENV_STATE خواهد گرفت class معادلش رو صدا میزنم.
اما برای اینکه مطمئن بشم مقدار ENV_STATE برای مثلا DEV در صورت وجود DEV_ENV_STATE خونده نمی‌شه موقع ساخت instance اینکارو کردم :
return DevConfig(ENV_STATE="development")
که یعنی مهم نیست یوزر چی خواسته یا اینکه اصن تعریف کرده یا نه باید development باشه ENV_STATE ایی که از DevConfig میاد.

حواستون باشه ENV_STATE , DEV_ENV_STATE تنظیمات متفاوتی هست از نظر کدهای بالا بخاطر env_prefix هرچیزی که env_prefix درست رو نداشته باشه بی‌اهمیت میشه توی اون کلاس.

print(settings.model_dump())
وظیفه model_dump بازگردان خروجی بصورت dictionary هست همون کار
settings.dict()
رو می‌کنه که اتوی آپدیت‌های بعدی قرار هست deprecate بشه.

شمارو نمی‌دونم ولی من این تنظیم رو به شکوندن فایل‌ها به ۱۲ تا فایل بیس و بعدم monkey patch برای هر environment ترجیح میدم.

اما اگر تنظیمات بسیار زیادی داشتید؛ می‌تونید ازین حالت هم استفاده کنید :
├── config
│ ├── base.py
│ ├── dev.py
│ ├── __init__.py
│ ├── prod.py
│ └── test.py


و توی init تابع get_config , settings رو داشته باشید :

from functools import lru_cache

from config.base import BaseConfig, BaseSettings
from config.dev import DevConfig
from config.prod import ProdConfig
from config.test import TestConfig


@lru_cache()
def get_config(env_state: str | None) -> GlobalConfig:
try:
match env_state.casefold(): # type: ignore
case "production" | "prod":
return ProdConfig(ENV_STATE="production") # type: ignore
case "test":
return TestConfig(ENV_STATE="test") # type: ignore
case _:
return DevConfig(ENV_STATE="development") # type: ignore
except AttributeError:
return DevConfig(ENV_STATE="development") # type: ignore


settings = get_config(BaseConfig().ENV_STATE)


موقع استفاده هم یوزر راحت هست :
from myproject.config import settings


بنظرم این مورد هم حتی تمیزتر هست.‍‍‍

BY Python Hints




Share with your friend now:
tgoop.com/pyHints/460

View MORE
Open in Telegram


Telegram News

Date: |

Add the logo from your device. Adjust the visible area of your image. Congratulations! Now your Telegram channel has a face Click “Save”.! While the character limit is 255, try to fit into 200 characters. This way, users will be able to take in your text fast and efficiently. Reveal the essence of your channel and provide contact information. For example, you can add a bot name, link to your pricing plans, etc. Other crimes that the SUCK Channel incited under Ng’s watch included using corrosive chemicals to make explosives and causing grievous bodily harm with intent. The court also found Ng responsible for calling on people to assist protesters who clashed violently with police at several universities in November 2019. With the administration mulling over limiting access to doxxing groups, a prominent Telegram doxxing group apparently went on a "revenge spree." To view your bio, click the Menu icon and select “View channel info.”
from us


Telegram Python Hints
FROM American