پروژههای جنگو من را ناامید میکرد، زیرا فاقد روشی قوی و مقیاسپذیر برای افزودن محیطهای جدید بودم. با گرد هم آوردن نکات Pydantic و Python، پایه قدرتمندی را که لازم داشتم ساختم.
همانطور که در PEP 484، نکات تایپ از تحلیل استاتیک پشتیبانی می کنند، اما همین حاشیه نویسی ها در زمان اجرا نیز در دسترس هستند. بستههای شخص ثالث مانند pydantic بررسی نوع زمان اجرا را ارائه میدهند که از این ابرداده اضافی استفاده میکند. Pydantic از نکات نوع Python برای کمک به مدیریت فراداده تنظیمات و انجام اعتبارسنجی داده های زمان اجرا استفاده می کند.
این آموزش pydantic اثرات مثبت و گسترده استفاده از مدیریت تنظیمات pydantic با جنگو را نشان می دهد.
پیکربندی ما به بهترین شیوه های شرح داده شده در آن پایبند است اپلیکیشن دوازده عاملی سایت اینترنتی:
- تنظیمات غیر ثابت و مخفی را به صورت تعریف کنید متغیرهای محیطی.
- در محیط های توسعه، متغیرهای محیطی را در a تعریف کنید
.env
فایل و اضافه کنید.env
به.gitignore
. - از مکانیسمهای ارائهدهنده ابر برای تعریف متغیرهای محیطی (مخفی) برای محیطهای QA، مرحلهبندی و تولید استفاده کنید.
- از یک تک استفاده کنید
settings.py
فایلی که خود را از روی متغیرهای محیطی پیکربندی می کند. - از pydantic برای خواندن، بررسی، اعتبارسنجی و تایپکست متغیرهای محیطی بر روی متغیرهای Python که پیکربندیهای جنگو را تعریف میکنند، استفاده کنید.
از طرف دیگر، برخی از توسعه دهندگان چندین فایل تنظیمات ایجاد می کنند، مانند settings_dev.py
و settings_prod.py
. متأسفانه، این رویکرد مقیاس خوبی ندارد. این منجر به تکرار کد، سردرگمی، اشکالات سخت و تلاش برای تعمیر و نگهداری می شود.
با استفاده از بهترین روش های ذکر شده، افزودن هر تعداد محیط آسان، به خوبی تعریف شده و ضد خطا است. اگرچه میتوانیم پیکربندی محیط پیچیدهتری را بررسی کنیم، برای وضوح روی دو تمرکز میکنیم: توسعه و تولید.
این در عمل چگونه به نظر می رسد؟
مدیریت تنظیمات Pydantic و متغیرهای محیطی
ما اکنون روی یک مثال در توسعه و تولید تمرکز می کنیم. ما نشان میدهیم که چگونه هر محیط تنظیمات خود را بهطور متفاوتی پیکربندی میکند و چگونه pydantic از هر یک پشتیبانی میکند.
برنامه مثال ما به a نیاز دارد پایگاه داده با پشتیبانی جنگو، بنابراین باید رشته اتصال پایگاه داده را ذخیره کنیم. ما اطلاعات پیکربندی اتصال پایگاه داده را به یک متغیر محیطی منتقل می کنیم، DATABASE_URL
، با استفاده از بسته پایتون dj-base-url. لطفا توجه داشته باشید که این متغیر از نوع خود است str
و به صورت زیر فرمت شده است:
postgres://{user}:{password}@{hostname}:{port}/{database-name}
mysql://{user}:{password}@{hostname}:{port}/{database-name}
oracle://{user}:{password}@{hostname}:{port}/{database-name}
sqlite:///PATH
در محیط توسعه خود، ما می توانیم از یک نمونه PostgreSQL حاوی Docker برای سهولت استفاده استفاده کنیم، در حالی که در محیط تولید خود، به یک سرویس پایگاه داده ارائه شده اشاره خواهیم کرد.
متغیر دیگری که می خواهیم تعریف کنیم یک بولی است، DEBUG
. را اشکال زدایی پرچم در جنگو هرگز نباید در استقرار تولید روشن شود. برای دریافت بازخورد اضافی در طول توسعه در نظر گرفته شده است. به عنوان مثال، در حالت اشکال زدایی، جنگو صفحات خطای دقیق را در صورت بروز یک استثنا نمایش می دهد.
مقادیر مختلف برای توسعه و تولید را می توان به صورت زیر تعریف کرد:
نام متغیر | توسعه | تولید |
---|---|---|
DATABASE_URL |
postgres://postgres:mypw@localhost:5432/mydb |
postgres://foo1:foo2@foo3:5432/foo4 |
DEBUG |
True |
False |
ما استفاده می کنیم مدیریت تنظیمات pydantic ماژول برای مدیریت این مجموعه های مختلف از مقادیر متغیر محیطی بسته به محیط.
مراحل مقدماتی
برای عملی کردن این موضوع، ما شروع به پیکربندی محیط توسعه خود با ایجاد تک آهنگ خود می کنیم .env
فایل با این محتوا:
DATABASE_URL=postgres://postgres:mypw@localhost:5432/mydb
DEBUG=True
بعد، ما اضافه می کنیم .env
فایل به پروژه .gitignore
فایل. را .gitignore
فایل از ذخیره اطلاعات بالقوه حساس در کنترل منبع جلوگیری می کند.
در حالی که این رویکرد در محیط توسعه ما به خوبی کار می کند، مشخصات محیط تولید ما از مکانیزم متفاوتی استفاده می کند. بهترین شیوه های ما حکم می کند که متغیرهای محیط تولید از اسرار محیط استفاده کنند. به عنوان مثال، در Heroku، این رازها Config Vars نامیده می شوند و از طریق داشبورد Heroku پیکربندی می شوند. آنها به عنوان متغیرهای محیطی در دسترس برنامه مستقر هستند:
پس از آن، باید پیکربندی برنامه را طوری تنظیم کنیم که این مقادیر را از هر محیط به طور خودکار بخواند.
پیکربندی جنگو settings.py
بیایید با یک پروژه جنگو جدید شروع کنیم تا ساختار ضروری را برای مثال خود ارائه کنیم. ما یک پروژه جنگو جدید را با دستور ترمینال زیر داربست می کنیم:
$ django-admin startproject mysite
ما در حال حاضر یک ساختار پروژه اساسی برای mysite
پروژه ساختار فایل پروژه به شرح زیر است:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
را settings.py
فایل حاوی کد دیگ بخار است که به ما امکان می دهد پیکربندی برنامه را مدیریت کنیم. تنظیمات پیش فرض از پیش تعریف شده زیادی دارد که باید آنها را با محیط مربوطه تنظیم کنیم.
برای مدیریت این تنظیمات برنامه با استفاده از متغیرهای محیطی و pydantic، این کد را به بالای صفحه اضافه کنید settings.py
فایل:
import os
from pathlib import Path
from pydantic import (
BaseSettings,
PostgresDsn,
EmailStr,
HttpUrl,
)
import dj_database_url
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
class SettingsFromEnvironment(BaseSettings):
"""Defines environment variables with their types and optional defaults"""
DATABASE_URL: PostgresDsn
DEBUG: bool = False
class Config:
"""Defines configuration for pydantic environment loading"""
env_file = str(BASE_DIR / ".env")
case_sensitive = True
config = SettingsFromEnvironment()
os.environ["DATABASE_URL"] = config.DATABASE_URL
DATABASES = {
"default": dj_database_url.config(conn_max_age=600, ssl_require=True)
}
DEBUG = config.DEBUG
این کد کارهای زیر را انجام می دهد:
- کلاس را تعریف می کند
SettingsFromEnvironment
، از pydantic به ارث می بردBaseSettings
کلاس - تعریف می کند
DATABASE_URL
وDEBUG
، تنظیم نوع و پیش فرض اختیاری آنها با استفاده از نکات نوع پایتون. - کلاس را تعریف می کند
Config
به pydantic گفتن به دنبال متغیرهای a.env
فایل در صورتی که در متغیرهای محیطی سیستم وجود نداشته باشد. - را نمونه می کند
Config
کلاس به شیconfig
; متغیرهای مورد نظر در دسترس قرار می گیرندconfig.DATABASE_URL
وconfig.DEBUG
. - متغیرهای معمولی جنگو را تعریف می کند
DATABASES
وDEBUG
از اینهاconfig
اعضا.
کد یکسان در همه محیط ها اجرا می شود و pydantic موارد زیر را انجام می دهد:
- به دنبال متغیرهای محیط می گردد
DATABASE_URL
وDEBUG
.- اگر به عنوان متغیرهای محیطی تعریف شود، مانند تولید، از آنها استفاده خواهد کرد.
- در غیر این صورت، آن مقادیر را از
.env
فایل. - اگر مقداری را پیدا نکرد، کارهای زیر را انجام می دهد:
- برای
DATABASE_URL
، خطا می دهد. - برای
DEBUG
، یک مقدار پیش فرض را اختصاص می دهدFalse
.
- برای
- اگر یک متغیر محیطی پیدا کند، بررسی می کند انواع میدان و اگر هر یک از آنها اشتباه است خطا بدهید:
- برای
DATABASE_URL
، تأیید می کند که نوع فیلد آن a استPostgresDsn
URL -style. - برای
DEBUG
، تأیید می کند که نوع میدان آن یک پیدانتیک معتبر و غیر دقیق است بولی.
- برای
لطفاً به تنظیم صریح متغیر محیطی سیستم عامل از مقدار پیکربندی برای توجه کنید DATABASE_URL
. ممکن است تنظیم آن اضافی به نظر برسد os.environ["DATABASE_URL"] = config.DATABASE_URL
زیرا DATABASE_URL
قبلاً به عنوان یک متغیر محیط خارجی تعریف شده است. با این حال، این به pydantic اجازه می دهد تا این متغیر را تجزیه، بررسی و اعتبار سنجی کند. اگر متغیر محیطی DATABASE_URL
گم شده یا به اشتباه فرمت شده است، pydantic یک پیغام خطای واضح می دهد. وقتی برنامه از توسعه به محیطهای بعدی میرود، این بررسیهای خطا بسیار ارزشمند هستند.
اگر متغیری تعریف نشده باشد، یا یک پیشفرض تعیین میشود یا یک خطا از تعریف آن درخواست میکند. هر درخواست ایجاد شده نیز نوع متغیر مورد نظر را به تفصیل شرح می دهد. یک مزیت جانبی این بررسی ها این است که اعضای تیم جدید و مهندسان DevOps راحت تر متوجه می شوند که کدام متغیرها باید تعریف شوند. با این کار از مشکلاتی که به سختی پیدا میشوند، زمانی که برنامه بدون همه متغیرهای تعریف شده اجرا میشود، ایجاد میشود.
خودشه. این برنامه اکنون دارای یک پیاده سازی قابل نگهداری و مدیریت تنظیمات با استفاده از یک نسخه واحد است settings.py
. زیبایی این رویکرد این است که به ما امکان می دهد متغیرهای محیطی صحیح را در a مشخص کنیم .env
فایل یا هر وسیله دلخواه دیگری که از طریق محیط میزبانی ما در دسترس است.
مسیر مقیاس پذیر
من از مدیریت تنظیمات جنگو با تایپ زمان اجرا pydantic در تمام پروژه های جنگو استفاده کرده ام. من متوجه شده ام که به پایگاه های کد کوچکتر و قابل نگهداری تر منجر می شود. همچنین یک رویکرد خوب ساختار یافته، مستندسازی و مقیاس پذیر برای افزودن محیط های جدید ارائه می دهد.
مقاله بعدی این مجموعه آموزش گام به گام ساخت اپلیکیشن جنگو از ابتدا با مدیریت تنظیمات pydantic و استقرار آن در Heroku است.
وبلاگ مهندسی Toptal از استفان دیویدسون برای بررسی نمونه کدهای ارائه شده در این مقاله تشکر می کند.
نسخه قبلی این مقاله بر انتشار اختصاصی پایتون تاکید داشت. از آنجایی که پایتون چندین سال است که از نکات نوع پشتیبانی میکند، با حذف این مرجع نسخه، متن مقدماتی را تعمیم دادهایم.