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

Unlimited number of subscribers per channel A few years ago, you had to use a special bot to run a poll on Telegram. Now you can easily do that yourself in two clicks. Hit the Menu icon and select “Create Poll.” Write your question and add up to 10 options. Running polls is a powerful strategy for getting feedback from your audience. If you’re considering the possibility of modifying your channel in any way, be sure to ask your subscribers’ opinions first. Telegram Channels requirements & features A Telegram channel is used for various purposes, from sharing helpful content to implementing a business strategy. In addition, you can use your channel to build and improve your company image, boost your sales, make profits, enhance customer loyalty, and more. The public channel had more than 109,000 subscribers, Judge Hui said. Ng had the power to remove or amend the messages in the channel, but he “allowed them to exist.”
from us


Telegram Python Hints
FROM American