| کانال توسعه‌دهندگان |
1.75K subscribers
55 photos
1 video
30 links
⭕️ کانال توسعه‌دهندگان دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
FastAPI — فریم‌ورک وب سریع برای Python

FastAPI برای ساخت APIهای سریع، تایپ‌ایمن و قابل مقیاس طراحی شده. مشکل ولیدیشن دستی، مستندسازی و کار با async را با Pydantic و طراحی مبتنی بر نوع حل می‌کند.

ویژگی‌ها:
- پشتیبانی async/await
- اعتبارسنجی و تبدیل داده با Pydantic
- مستندات خودکار OpenAPI/Swagger
- عملکرد بالا و کم‌کد

نمونه نصب و استفاده:
pip install fastapi uvicorn

# main.py
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
async def read_root():
return {"hello": "world"}

# اجرا: uvicorn main:app --reload


موارد کاربرد: میکروسرویس‌ها، APIهای REST، پروتوتایپ سریع و بک‌اند سرویس‌های تحت ترافیک بالا. مستندات و سورس:
Docs — GitHub

نظرتون و تجربه‌هاتون با FastAPI رو بنویسید؛ استقبال می‌کنیم.

🔖 #Programming #برنامه_نویسی #python #fastapi #api #web #pydantic

👤 Developix

💎 Channel: @DevelopixChannel
👍6
استفاده از print برای دیباگ ساده و وسوسه‌برانگیز است، اما در پروژه‌های واقعی مشکلات متعددی ایجاد می‌کند: خروجی‌های نامنظم، فقدان سطح‌بندی (info/debug/error)، و مشکل در خاموش/روشن کردن لاگها. استفاده از ماژول استاندارد logging در پایتون یک تغییر کوچک ولی بسیار اثربخش است. ✅

توضیح کوتاه و کاربردی:
- در هر ماژول یک logger با نام ماژول بسازید و لاگینگ را در نقطه ورود برنامه (مثلاً main) پیکربندی کنید.
- از logger.debug/info/warning/error/exception استفاده کنید تا سطح و فرمت را کنترل کنید.

نمونهٔ کوچک و عملی:
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(levelname)s [%(name)s] %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

def divide(a, b):
try:
return a / b
except Exception:
logger.exception("error dividing %s by %s", a, b)
return None

if __name__ == "__main__":
logger.info("start")
print(divide(10, 0))


چرا مفید است و نکات عملی:
- می‌توانید سطح لاگ (DEBUG/INFO/ERROR) را بدون تغییر کد تغییر دهید. ⚙️
- لاگ‌ها قابل هدایت به فایل، کنسول یا سرویس‌های خارجی هستند. 📁
- در except از logger.exception() استفاده کنید تا استک‌تریس ثبت شود. 🧾
- اجتناب از فراخوانی basicConfig در کتابخانه‌ها؛ فقط در برنامهٔ اصلی پیکربندی کنید.

پایانی کوتاه: این تغییر ساده کیفیت دیباگ و نگهداری کد را سریعاً بالا می‌برد — چند دقیقه وقت بذارید و لاگینگ را در پروژه‌هایتان جایگزین print کنید. 🔧

منبع معتبر: Python logging — official docs

#python #logging #دیباگ

🔖 #Programming #برنامه_نویسی #python #logging #debug #دیباگ #best_practices

👤 Developix

💎 Channel: @DevelopixChannel
👍4🔥1
Pydantic یکی از کتابخانه‌های جدی و پراستفاده در Python برای کار با data models و validation است؛ مخصوصاً وقتی از FastAPI، اسکریپت‌های ETL یا سرویس‌های داخلی استفاده می‌شود.

ایده‌اش ساده است: به‌جای if—elseهای تکراری برای چک کردن ورودی‌ها، یک مدل تعریف می‌کنی و Pydantic خودش نوع‌ها را تبدیل و داده را اعتبارسنجی می‌کند ✅

ویژگی‌های مهم:
• تایپ‌محور بر اساس type hints پایتون
• تبدیل خودکار انواع (مثلاً str به int در صورت امکان)
• پیام خطای قابل‌خواندن برای API و لاگ‌ها
• ادغام عالی با FastAPI و ابزارهای async

نمونه استفاده ساده:
from pydantic import BaseModel, ValidationError

class User(BaseModel):
id: int
name: str
is_active: bool = True

try:
user = User(id="1", name="Sara")
print(user.id, type(user.id)) # 1 <class 'int'>
except ValidationError as e:
print(e.json())


برای پروژه‌هایی که ورودی‌شان از API، فرم، Message Queue یا فایل JSON می‌آید، Pydantic کمک می‌کند باگ‌های مربوط به داده را خیلی زودتر شکار کنی 🧪

Docs رسمی:
docs.pydantic.dev
GitHub:
github.com/pydantic/pydantic

امتحانش کن روی یکی از سرویس‌های داخلی‌ات و ببین چقدر validation تمیزتر و قابل‌اعتمادتر می‌شود 🚀

🔖 #Programming #برنامه_نویسی #Python #Pydantic #Validation #FastAPI #Data_Modeling

👤 Developix

💎 Channel: @DevelopixChannel
👍4
اصل Single Responsibility: هر کلاس فقط یک دلیل برای تغییر 💡

یکی از مهم‌ترین اصول SOLID که واقعاً در پروژهٔ روزمره جواب می‌دهد، Single Responsibility Principle (SRP) است:

هر ماژول، کلاس یا فانکشن باید فقط یک مسئولیت داشته باشد.

یعنی چه؟ یعنی اگر فردا قرار باشد این کلاس تغییر کند، فقط یک «دلیل منطقی» برای آن وجود داشته باشد، نه چند دلیل مختلف و نامربوط.

مثال ساده ⬇️

class OrderService:
def create_order(self, data):
# 1) اعتبارسنجی دیتا
# 2) ذخیره در دیتابیس
# 3) ارسال ایمیل تایید
pass


این کلاس ۳ مسئولیت دارد:

• منطق بیزینسی سفارش 🧠
• دسترسی به دیتابیس 💾
• ارسال ایمیل 📧

هر بار که قوانین ایمیل عوض شود، این کلاس باید عوض شود.
هر بار که ساختار دیتابیس عوض شود، باز هم همین کلاس.
این دقیقاً خلاف SRP است و در طول زمان به کد شکننده و پر باگ تبدیل می‌شود.

ری‌فکتور با SRP ✅

class OrderRepository:
def save(self, order):
pass

class EmailService:
def send_order_confirmation(self, order):
pass

class OrderService:
def __init__(self, repo, email_service):
self.repo = repo
self.email_service = email_service

def create_order(self, data):
# منطق سفارش
order = self._build_order(data)
self.repo.save(order)
self.email_service.send_order_confirmation(order)


حالا:

• تغییر دیتابیس فقط OrderRepository را درگیر می‌کند.
• تغییر متن/قوانین ایمیل فقط در EmailService انجام می‌شود.
• خود OrderService روی منطق سفارش تمرکز می‌کند.

چرا این کار در عمل ارزش دارد؟

• تست کردن راحت‌تر می‌شود؛ چون می‌توان EmailService و OrderRepository را mock کرد و فقط منطق سفارش را تست گرفت ✅
• تغییرات بیزینسی، UI یا زیرساخت، بخش‌های جداگانه را لمس می‌کند، نه کل سیستم را 🔧
• خوانایی بالاتر: هر کلاس را که باز می‌کنی، تقریباً می‌توانی با خواندن نامش حدس بزنی چه کاری انجام می‌دهد 👀

نشانه‌های نقض SRP (Code Smell) 🚨

• کلاس‌هایی با نام‌های مبهم مثل Manager، Helper، Util که همه کار می‌کنند.
• فانکشن‌هایی که ۱۰۰+ خط کد دارند و هم validate می‌کنند، هم log، هم call به API.
• هر بار که فیچر جدیدی می‌آید، مجبور می‌شوی همان فایل‌های قدیمی «همه‌فن‌حریف» را باز کنی.

لینک‌های مفید برای مطالعهٔ بیشتر:
Refactoring.Guru - Single Responsibility Principle
Martin Fowler - Single Responsibility Principle

قدم‌های کوچک ری‌فکتور بر اساس SRP، در طول زمان کیفیت کد را به‌طرز عجیبی بالا می‌برد. از فانکشن‌های طولانی و کلاس‌های همه‌کاره شروع و به تدریج مسئولیت‌ها را جدا کنید 🌱

🔖 #Programming #برنامه_نویسی #Clean_Code #SOLID #SRP #Software_Architecture #Refactoring #Python

👤 Developix

💎 Channel: @DevelopixChannel
❤4🔥2
اصل Single Responsibility در عمل 🧩

یکی از مهم‌ترین اصول SOLID که عملاً هر روز سر و کار داریم، Single Responsibility Principle (SRP) است:

«هر کلاس یا ماژول باید فقط یک دلیل برای تغییر داشته باشد.»

این یعنی:

• هر قطعه کد روی یک کار مشخص تمرکز کند.
• وقتی نیاز به تغییر یک رفتار داریم، فقط به یک جای مشخص سر بزنیم.

چرا مهم است؟

• کد قابل فهم‌تر می‌شود.
• Bugها کمتر در جاهای نامربوط نشت می‌کنند.
• تست‌ها ساده‌تر و Refactor کردن کم‌ریسک‌تر می‌شود. ✅

نمونه کد بدون رعایت SRP 😵

این تابع هم ورودی را می‌خواند، هم پردازش می‌کند، هم لاگ می‌گیرد و هم نتیجه را ذخیره می‌کند:

def process_order(request):
# 1) validate input
if not request.get("user_id"):
print("[ERROR] missing user_id")
return

# 2) calculate price
total = 0
for item in request["items"]:
total += item["price"] * item["qty"]

# 3) log result
print(f"[INFO] user={request['user_id']} total={total}")

# 4) save to db (fake)
db["orders"].append({"user": request["user_id"], "total": total})


این تابع حداقل چهار مسئولیت دارد؛ هر تغییر کوچکی (مثلاً فرمت لاگ یا ساختار دیتابیس) باعث تغییر در همین تابع می‌شود.

تقسیم به مسئولیت‌های جدا ✂️

با SRP، مسئولیت‌ها را جدا می‌کنیم:

def validate_request(request):
if not request.get("user_id"):
raise ValueError("missing user_id")


def calculate_total(items):
return sum(i["price"] * i["qty"] for i in items)


def log_order(user_id, total, logger):
logger.info(f"user={user_id} total={total}")


def save_order(user_id, total, repo):
repo.save({"user": user_id, "total": total})


def process_order(request, logger, repo):
validate_request(request)
total = calculate_total(request["items"])
log_order(request["user_id"], total, logger)
save_order(request["user_id"], total, repo)


حالا:

• منطق محاسبه قیمت جداست؛ اگر تخفیف یا Tax اضافه شود، فقط همان بخش را تغییر می‌دهیم.
• تغییر سیستم لاگ یا دیتابیس، منطق دامنه را دست‌کاری نمی‌کند.
• تست کردن calculate_total و validate_request به‌صورت واحد بسیار ساده است. 🧪

نکتهٔ مهم

SRP را افراطی تفسیر نکنید؛ منظور این نیست برای هر خط یک تابع بسازیم. معیار خوب این است:

• وقتی می‌گویید «این کلاس/تابع کارش چیه؟»، بتوانید با یک جملهٔ کوتاه جواب بدهید.

برای مطالعهٔ بیشتر:

• کتاب Clean Code – Robert C. Martin
• توضیح SRP در Refactoring.Guru: refactoring.guru/design-patterns/solid

این اصل به‌ظاهر ساده، اگر واقعاً در هر Pull Request به آن فکر شود، کیفیت بلندمدت کدبیس را عوض می‌کند. 🌱

🔖 #Programming #برنامه_نویسی #SRP #SOLID #clean_code #refactoring #architecture #Python

👤 Developix

💎 Channel: @DevelopixChannel
🔥4
کتابخونهٔ معروف Requests توی Python عملاً استانداردِ کار با HTTP شده؛ به‌جای درگیر شدن با urllib و جزئیات خسته‌کننده، با چند خط کد می‌شه API صدا زد و JSON گرفت و فرستاد. 😉

Requests مشکل «کد شلوغ و پر از boilerplate برای request ساده» رو حل می‌کنه و خوندن/دیباگ‌کردن کدهای مرتبط با شبکه رو خیلی راحت‌تر می‌کنه.

ویژگی‌های مهم:
• سینتکس خیلی خوانا و نزدیک به زبان طبیعی 🧠
• پشتیبانی راحت از headers، query params، timeout، session و cookie
• هندل سادهٔ JSON و status code ها
• مناسب برای کار با REST API، اسکریپت‌های اتوماسیون و crawlerهای سبک

pip install requests

import requests

resp = requests.get("https://api.github.com/repos/psf/requests")
if resp.status_code == 200:
data = resp.json()
print(data["full_name"], data["stargazers_count"])


برای پروژه‌هایی مثل مانیتورینگ سرویس‌ها، نوشتن bot، یا اتصال سریع به سرویس‌های third-party، Requests انتخاب امن و پرکاربردیه. 🤝

Docs رسمی:
requests.readthedocs.io
GitHub:
github.com/psf/requests

امتحانش کن و کم‌کم هر جا اسم HTTP تو Python بیاد، یاد Requests می‌افتی. 🚀

🔖 #Programming #برنامه_نویسی #Python #HTTP #Requests #Web #API

👤 Developix

💎 Channel: @DevelopixChannel
اصل Single Responsibility (SRP) از اصول معروف SOLID می‌گوید:

«هر ماژول، کلاس یا تابع باید فقط یک دلیل برای تغییر داشته باشد.» ✅

یعنی چی؟ یعنی یک کلاس نباید هم منطق کسب‌وکار را انجام دهد، هم لاگ بنویسد، هم با دیتابیس صحبت کند، هم ایمیل بفرستد. این دقیقاً همان جایی است که کد شروع به بو دادن می‌کند (Code Smell) 😅

نمونه‌ی بد: کلاس همه‌کاره
class UserService:
def register(self, user_data):
# validate
if not user_data["email"]:
raise Exception("email required")

# save to db
db.save(user_data)

# send welcome email
email_client.send(user_data["email"], "welcome")

# log
logger.info("user registered")


اینجا UserService چند مسئولیت دارد:

• validation ✅
• ذخیره در دیتابیس 🗄️
• ارسال ایمیل 📧
• logging 📜

تست کردنش سخت می‌شود، تغییر هر بخش روی بقیه اثر می‌گذارد، و هر تغییری ریسک Bug را بالا می‌برد.

بازطراحی با SRP
class UserValidator:
def validate(self, user_data):
if not user_data["email"]:
raise Exception("email required")

class UserRepository:
def save(self, user_data):
db.save(user_data)

class EmailNotifier:
def send_welcome(self, email):
email_client.send(email, "welcome")

class UserService:
def __init__(self, validator, repo, notifier, logger):
self.validator = validator
self.repo = repo
self.notifier = notifier
self.logger = logger

def register(self, user_data):
self.validator.validate(user_data)
self.repo.save(user_data)
self.notifier.send_welcome(user_data["email"])
self.logger.info("user registered")


حالا:

• هر کلاس یک مسئولیت واضح دارد ✔️
• تست واحد برای هر بخش ساده‌تر است ✔️
• تغییر ایمیل یا دیتابیس، UserService را نمی‌شکند ✔️

چند نکته‌ی کاربردی 🔍

• اگر در توضیح یک کلاس مجبورید از «و» زیاد استفاده کنید (این کلاس X و Y و Z انجام می‌دهد)، احتمالاً SRP نقض شده.
• متدهایی که بیش از حد طولانی‌اند و کارهای ناهمگن انجام می‌دهند، نامزد جدی Refactor هستند.
• SRP کمک می‌کند معماری تمیزتر داشته باشید و Design Patternها (مثل Strategy، Repository) را راحت‌تر پیاده کنید.

برای مطالعه‌ی بیشتر می‌توان به Refactoring.Guru - SRP یا فصل‌های ابتدایی کتاب Clean Code سر زد.

اجرای مستمر SRP روی کدهای روزمره، در بلندمدت پروژه‌ را قابل‌تغییرتر، تست‌پذیرتر و کم‌استرس‌تر می‌کند. از همین الان روی یکی از فایل‌های شلوغ پروژه شروع شود و مسئولیت‌ها را جدا کنید ✨

🔖 #Programming #برنامه_نویسی #Clean_Code #SOLID #SRP #Refactoring #Architecture #Design_Principles #Python

👤 Developix

💎 Channel: @DevelopixChannel
🚀 ساخت یک REST API ساده با FastAPI (ولی حرفه‌ای!)

FastAPI این‌قدر سریع و تمیزه که برای ساخت REST APIهای کوچک تا سرویس‌های جدی تولید (Production) عالی جواب می‌ده. توی این پست، بر اساس داک رسمی FastAPI (https://fastapi.tiangolo.com)، یک API واقعی و قابل استفاده برای مدیریت "تسک‌ها" می‌سازیم؛ چیزی شبیه todo-service کوچیک، ولی تمیز و قابل توسعه. 😎

ایده اینه:

• یک API می‌سازیم که لیست تسک‌ها رو بده، تسک جدید بگیره و وضعیتش رو عوض کنه.
• از Pydantic models برای اعتبارسنجی ورودی استفاده می‌کنیم.
• خروجی JSON تمیز و قابل مصرف برای Front-end یا mobile app داریم.

اول با نصب شروع کن:
pip install "fastapi[all]" uvicorn


حالا یک فایل به اسم main.py بساز و این کد رو بذار داخلش:

from typing import List, Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI(title="Tasks API")

class Task(BaseModel):
id: int
title: str
done: bool = False
description: Optional[str] = None

# دیتابیس موقتی در حافظه
TASKS_DB: List[Task] = []

@app.get("/tasks", response_model=List[Task])
async def list_tasks():
return TASKS_DB

@app.post("/tasks", response_model=Task, status_code=201)
async def create_task(task: Task):
for t in TASKS_DB:
if t.id == task.id:
raise HTTPException(status_code=400, detail="Task id already exists")
TASKS_DB.append(task)
return task

@app.patch("/tasks/{task_id}", response_model=Task)
async def mark_done(task_id: int):
for t in TASKS_DB:
if t.id == task_id:
t.done = True
return t
raise HTTPException(status_code=404, detail="Task not found")


اجرا روی لوکال:
uvicorn main:app --reload


بعد از اجرا، دو چیز خیلی کاربردی داری:

1️⃣ خود API روی:
http://127.0.0.1:8000/tasks


2️⃣ داکیومنت خودکار با Swagger UI روی:
http://127.0.0.1:8000/docs


همون‌جا می‌تونی POST /tasks رو تست کنی، JSON بفرستی و خروجی رو ببینی. این همون چیزی‌یه که تو سرویس‌های واقعی برای Front-end، موبایل یا حتی microserviceهای دیگه فرستاده می‌شه.

نکته‌های ریز ولی مهم:

• استفاده از response_model باعث می‌شه خروجی همیشه شکل مشخصی داشته باشه و Pydantic اون رو validate کنه.
• با HTTPException خطاها رو استاندارد و قابل پیش‌بینی برمی‌گردونی.
• چون TASKS_DB فقط تو حافظه‌ست، برای محیط واقعی باید به یک دیتابیس واقعی مثل PostgreSQL وصلش کنی (مثلاً با SQLModel یا SQLAlchemy).

این اسکلت ساده، پایه خیلی از APIهای واقعی‌ه: فقط کافیه endpointها و مدل‌هات رو گسترش بدی. 👨‍💻👩‍💻

امتحانش کن، یک mini todo-service برای خودت بساز و روی پروژه‌های شخصی یا تمرینی‌ات سوارش کن. اگر مفید بود برای بقیه دولوپرها هم بفرست تا از FastAPI لذت ببرن. 😄

🔖 #Programming #برنامه_نویسی #FastAPI #Python #REST_API #Backend #Web

👤 Developix

💎 Channel: @DevelopixChannel
👍3❤1
🧪 استفاده از assert برای گرفتن باگ‌ها، قبل از دیر شدن

خیلی وقت‌ها یک فرض توی کد داریم که "مطمئنیم" همیشه برقرار است؛ مثلا این‌که ورودی خالی نیست یا مقدار نال نمی‌آید. این‌جور جاها assert دوست خوب ماست 😄

با assert می‌شود این فرض‌ها را به شکل چکِ خودکار داخل کد ثبت کرد تا اگر جایی نقض شد، همان‌جا و همان لحظه سرِ اجرا بترکد، نه دو روز بعد توی لاگ‌های مشتری.

یک مثال ساده در Python:
def average(nums: list[float]) -> float:
assert len(nums) > 0, "nums must not be empty"
return sum(nums) / len(nums)

print(average([1, 2, 3])) # 2.0
print(average([])) # AssertionError


نکته مهم 👇
- در Python اگر با فلگ -O اجرا شود، assertها حذف می‌شوند. پس برای validation ورودی کاربر از assert استفاده نمی‌شود؛ فقط برای چک‌کردن منطق داخلی و فرضیات برنامه‌نویس مناسب است.

امروز یکی از فرض‌های مهم کدت را با یک assert ساده محکم‌تر کن و نتیجه‌اش را در باگ‌های آینده ببین 🤝

📚 مرجع: Python Docs - assert statement

🔖 #Programming #برنامه_نویسی #assert #debugging #python #clean_code #defensive_programming

👤 Developix

💎 Channel: @DevelopixChannel
👍3🔥1
گاهی وسط دیباگ سریع، کلی print می‌ریزیم تو کد و بعداً یادمان می‌رود پاکشان کنیم 😅 بهتر است از اول سراغ لاگ ساخت‌یافته (Structured Logging) برویم.

با لاگ، هم سطح اهمیت داریم (info, warning, error)، هم می‌توانیم به‌راحتی فیلتر و جستجو کنیم و هم در محیط‌های Production به‌درد می‌خورد.

مثال ساده در Python 👇
import logging

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s - %(message)s",
)

logger = logging.getLogger("payment-service")

user_id = 42
amount = 199_000

logger.info("starting payment", extra={"user_id": user_id, "amount": amount})

try:
1 / 0
except ZeroDivisionError:
logger.exception("payment failed")


✅ مزیت‌ها:
• لاگ‌ها قابل فیلتر بر اساس سطح هستند و می‌شود فقط warning/error دید.
• در سرویس‌های Microservice و ابزارهایی مثل ELK یا Grafana Loki خیلی تمیزتر تحلیل می‌شوند.

برای پروژه بعدی، از همان روز اول یک Logger درست و حسابی تنظیم شود تا Debug و Monitoring آینده خیلی راحت‌تر پیش برود 🚀

مرجع: Python logging (Official Docs)

🔖 #Programming #برنامه_نویسی #logging #debugging #best_practices #python #structured_logging

👤 Developix

💎 Channel: @DevelopixChannel
👍2❤1