-
Learning python & Backend Engineering, with Mani! Youtube: https://www.youtube.com/@GitOverHere Github: https://github.com/ManiMozaffar Linkedin: https://www.linkedin.com/in/manimozaffar Admin: @Mani_nikou لینک گروه: https://t.me/PythonFellow
یکی از دوستانی امروز یادم انداخت به یه لایبری قدیمی که نوشته بودم. این لایبری یه HTTP client هست که میتونه سایتهایی که زیر پوشش Cloudflare هستن و سیستم رباتیابشون فعاله رو کراول کنه. تاحالا در موردش صحبت نکرده بودم، ولی گفتم اینجا یه توضیحی بدم.
لینک گیتهابش اینجاست با httpx کاملاً سازگاره، یعنی اگه از httpx استفاده میکردید، با تغییر import میتونید به راحتی ازش استفاده کنید.
مشکل چی بود؟ سایتهایی که از Cloudflare به عنوان reverse proxy استفاده میکنن، معمولاً از یه مکانیزم تشخیص ربات استفاده میکنن که به TLS Fingerprint متکیه. حالا TLS Fingerprint چیه؟ وقتی شما به یه سایت وصل میشید، اولین چیزی که رد و بدل میشه، یه پیام به اسم Client Hello هست. این پیام اطلاعات اولیهای رو درباره کلاینت شما به سرور میده، مثل نسخه TLS که پشتیبانی میکنید و یه لیست به اسم cipher suite.
توضیح Cipher suite: در واقع مجموعهای از الگوریتمهای رمزنگاری هست که کلاینت و سرور میتونن برای برقراری یه ارتباط امن استفاده کنن. هر مرورگر یا کلاینت یه لیست مشخص از cipher suite داره که ترتیبش هم خاص همون کلاینت هست. مثلاً مرورگر کروم یه لیست مشخص داره، مرورگر فایرفاکس یه لیست دیگه، و مثلاً requests پایتون هم یه لیست کاملاً متفاوت.
کلادفلیر چطور متوجه میشه شما مرورگر نیستید؟ اون میاد این TLS Fingerprint، یعنی ترکیب نسخه TLS و ترتیب cipher suiteها، رو با user-agent شما مقایسه میکنه. اگه این دو تا با هم نخونن، مثلاً user-agent شما میگه مرورگر کروم هستید ولی cipher suiteها میگن یه اسکریپت پایتونید، Cloudflare متوجه میشه که شما مرورگر نیستید و درخواست رو بلاک میکنه.
کله سناریویی که گفتم اینجا داره اتفاق میفته تو لایبری من که کلا ۱۰ خط کده.
@PyBackendHub
این پارگراف هم باز کنم و برم بخوابم :))
اینکه میگم فرهنگه منظورم اینه که من باید بدونم که نباید aws secret key شرکتو رو slack بفرستم برای همکارم. این قسمت فرهنگشه. که باید آکاه باشم دیتایی که بره تو نت دیگه خدا میدونه چه بلایی سرش میاد.
اینکه قفل و زنجیر بزنی به اپلیکیشنت باعث امنیت بیشتر نمیشه. اپلیکیشنت اگه آسیب پذیری نداشته باشه مشکلی نداره. طبیعتا همه اپلیکیشن ها ضعف امنیتی دارن و اشکالیم نداره. یک ترید آفه اون.
بخشیش هم به قانون گذاری برمیگرده که گفتم. الان از ۱۰ تا سایت معتبر ایرانی واقعا ۳-۴ تاشون term of service دارن. سایت دیدم نماد الکترونیکی داره ولی term of service نداره. یعنی یک بازرس اومده سایتو دیده ولی اینو چک نکرده؟! اگه ربات تلگرام ناشناسی که شما استفاده میکردی term of use داشت و میگفت دیتاتون تو سرور من همیشه ذخیره میمونه, اون موقع هیچ مشکل قانونی نداشت. اگه هم اینکارو میکرد قطعا ۹۹درصد مردم نمیخوندنش. و هیچ یوزری انتظار نداره که دیتاشو پاک کنه. من تو هیچ اپی ندیدم وقتی ایران زندگی میکردم که این آپشن دیلیت کردن دیتا رو داشته باشه. پس بخشیش هم برمیگرده به فرهنگ و فقط قانون گذاری نیست. توقع کاربر کمه. تو آلمان دیدم مردم خیلی به این موارد اهمیت میدن.
و در نهایت اینکه دیتا لو رفته چیه؟ اگه دو تا عکس و فیلم باشه, نباید فرهنگمون اجازه بده که کسیو مسخره کنیم یا بذاریم زندگیش تموم شه بخاطر همچین چیزی. دیگه نسل جدید نباید اینقدر پوسیده فکر کنه. زندگی خصوصی آدما به خودشون مربوطه. متاسفانه مثال خلافش تو جامعه ما میشه یوتیوبری به اسم مدگل که کامنت های خیلی بدی میبنیم راجبش همه جا 🤦♂️
@PyBackendHub
چند نکته که اشتباه برداشت نکنید.
نکته اول من نمیگم که شما تحقیق نکنید راجب شرکتی که میرین مصاحبه میدین. من دارم دید خودمو میگم به عنوان کسی که مصاحبه میکنید چطوری میتونید یک شرکت رو کالچرش رو از بیرون قضاوت کنید. اینکه شما بری تو مصاحبه و نشون بدی تحقیق کردی و الکی یک دلیلی بیاری بگی چرا دوست داری تو اون شرکت کار کنی خیلی کمک میکنه به فرایند مصاحبه و شانس قبول شدنت. ولی من دارم راجب قضاوت کالچر صحبت میکنم نه راجب قبولی مصاحبه. همینطور که شرکت شما رو انتخاب میکنه, شما هم شرکت رو انتخاب میکنی. این پروسه interview یک چیزه دو طرفست. شرکت redflag نشون بده که با خواسته شما و مدل کاری شما یکی نیست سریع پا پس میکشید حتی اگه آفر بدن.
نکته دوم اشاره کردن ممکنه تو هیچ مرحله ای با کسی از تیم آیندتون مصاحبه نکنید. خب این خودش بزرگترین رد فلگه تو دید من. اینطوری نیست شما برین تو مصاحبه بشینید و مصاحبه گر رد فلگ های شرکت رو لیست کنه براتون. شما باید زرنگ باشین سوال خوب بپرسین و کشف کنید رد فلگ هارو اول کار. اینکه یک نفر رو دارن استخدام میکنن تو یک تیمی ولی هیچ کدوم از اعضای تیم یک بارم اون نفری که داره استخدام میشه رو نمیبینه, این موضوع برای من رد فلگه و بوی سلسله مراتب سنگین رو میده تو شرکت.
و در نهایت بحث گلس دور هم شد, ببینید جامعه آماری گلس دور نرمال نیست. اینطوری نیست گوگل میت تموم شه بگن بهتون ۱ تا ۱۰ نمره بدید. باید برین تو یک سایت ثبت نام کنید احراز هویت کنید و یک مراحلی رو طی کنید که یک review بذارین. هیچکسی اینکارو معمولا نمیکنه. مگه یا اینکه مجبورش کرده باشن. یا اینکه اینقدر عصبی شده که رفته گلس دور انتقام بگیره. جامعه آماری نرمال نیست تو گلس دور. من مصاحبه رفتم ریت شرکت بد بوده تو گلس دور ولی فرهنگش تو مصاحبه خیلی خوب بنظر میرسیده. و کاملا برعکس.
@PyBackendHub
یک tip آخر دیگه در مورد ارتباط typing با maintainability
استفاده درست از تایپ never باعث میشه شما همیشه سیسمتون خیلی راحت extendable باشه.
مثالش اینجا تو سورس کد واقعیه. من یک enum دارم برای PaymentType. و نیاز دارم که بتونم query کنم payment هایی که خودکار هستن رو.
اگه من این مقدار رو هارد کد میکردم فردا اگه یک مدل payment جدید اضافه میکردم اون موقع یادم میرفت اینجا اضافه کنم تو query آورده نمیشد.
ولی الان اون assert never منو وادار میکنه اگه تایپ جدیدی اضافه کردم و سیستم رو بزرگ تر کردم حالا بیام اینجا هندلش کنم که آيا payment خودکار هست یا نه. پس هرجایی تو سیستمم دپندسی خاصی دارم سعی میکنم یک جوری کد بنویسم که وقتی سیستم رو بزرگ تر میکنم مجبور شم هندلش کنم. کمی باعث میشه بیشتر کد بزنم و بیشتر وقت بذارم ولی از طرفی اصلا رو دیباگ اون کد وقت نمیذارم و پروداکتم خیلی stable تره.
تو تایپ اسکریپت و بعضی زبونای دیگه این ایده رو میشه بدون runtime cost اجرا کرد. تو پایتون ولی یک وقتا (مثل اینجا)یک کوچولو ران تایم کاست داره.
@PyBackendHub
نمونش هم تو تایپ اسکریپت اینطوری میشه:
@PyBackendHub
این ویدیو راجب ماکروسرویسه، و اینکه چطوری service هاتونو abstract کنید👌
توصیه میکنم حتما ببینید ، عالیه این ویدیو
@PyBackendHub
ولی ادیتور امیربهادر >>>> 😂😂👌 باید تو نتفلیکس کار کنه :))
تیراژش از تیراژ فیلم های هالیوودی جذاب تره 😂
@PyBackendHub
یک پست خیلی خوب از بنیامین تو گروه👌
یه مقاله ای دیدم
https://dev.to/stripe/common-design-patterns-at-stripe-1hb4
که نویسندش توسعه دهنده توی استرایپه
4 بخشه و نکاتی رو در مورد توسعه API میگه که به نظرم خوندنش خالی از لطف نیست. بخش مهم ترش به نظرم بخش آخره.
یه قسمتش یه حرفی رو میزنه:
Prefer enums over booleans
و میگه وقتی شما یه چیزی رو میخواید با مقدار bool بذارید مثلا:
Subscription.canceled={true, false}Subscription.canceled={true, false}
Subscription.paused={true, false}Subscription.status={"active", "canceled"}Subscription.status={"active", "canceled", "paused"}post.published = true, false
post.status = PUBLISHED, NOT_PUBLISHED
product.in_stock = true, false
product.availability = IN_STOCK, OUT_OF_STOCK
ولی یک فکتی رو هم در نظر بگیرین, که شیب خروجی با حقوقتون ۱ نیست. یعنی چی؟
یعنی بیاین تصور کنیم که من ساعتی n دلار میگیرم.و در روز ۴ ساعت کار میکنم. و بیایم تصور کنیم من هر ساعت بیشتر کار کنم به همون میزان خروجیم هم بیشتره (تو بهترین حالت ممکن).
بنابراین درآمد من در روز باید 4n باشه اگه ۴ ساعت کار کنم.
و 8n باشه اگه ۸ ساعت کار کنم.
و 10n باشه اگه ۱۰ ساعت کار کنم.
ولی تو واقعیت اینطوری نیست. وقتی شما خروجی بیشتری دارین,اونوقت پروموشن میگیرید. این پروموشن رو کل حقوقتون تاثیر میذاره. بعد اینطوری تو ۱۰ ساعت به جای 10n حقوقه من میشه 16n.
یک نکته دیگه هم بنظرم خیلی مهمه تو پروموشن گرفتن و این حالت.
اینکه شما اگه یک وظیفه رو به بهترین حالت ممکن انجام بدید, پروموشن نمیگیرین. (یا خیلی نمیگیرین). چون صرفا دارین کارتونو انجام میدید. ولی اگه چند وظیفه که حتی خارج از وظایف خودتونه انجام بدید و ownership اشو دستتون بگیرین خیلی پروموشن بیشتری میگیرین. چون دارین چند تا کار انجام میدین. و جا به جا کردن شما با یک نفر دیگه تقریبا خیلی سخت و پر هزینه میشه. و نیازی هم ندارین اون وظایف رو پرفکت انجام بدید. به حد کافی (و در حد انتظار) خوب انجام بدید کافیه.
@PyBackendHub
دلیل ناکافی بودن unit test به تنهایی:
@PyBackendHub
توییت آخر امروز 😁
قبلا فکر میکردم مصاحبه هایی هست که میرم توش و مشکل شرکت رو میذارن جلوم و صرفا هدفشون <حل کردن مشکله>. ولی الان که فکر میکنم بهش امکان نداره همچین چیزی. صرفا یک مشکل خیلی ساده بود که خودشون قطعا حل کرده بودن. یا خیلی ساده حلش میکردن خودشون.
چون فکر کنید بهش: شما یک مشکلی دارین. یک نفر از بیرون میاد و تو ۲۰ دقیقه بهش توضیح میدین و میخواین تو ۱-۲ ساعت براتون حل کنه. بدون اینکه هیچ context ای از نرم افزار شما داشته باشه. سولوشنی که طرف میده هم پرفکت سولوشنه و تمام مشکلاتشونو حل میکنه.
اگه واقعا همچین سناریویی رخ بده خب اون مشکل خیلی احمقانست 😅 یا اینکه یک سری دوره هم جمع شدن که هیچ کدومشون اصلا نمیدونن چیکار دارن میکنن. که ۹۹ درصد مواقع بنظرم این نیست. صرفا سوء برداشت شماست.
@PyBackendHub
ادامه پست دیروز
من یک سری فکت های خیلی ترسناک امروز راجب sqlalchemy پیدا کردم....
ببینید ما یک آبجکت session داریم که session maker میاد. (یا session factory). که درواقع کانکشن پول این آبجکت رو میسازه و به ما میده. این Session نسبت به همه آبجکت هایی که از query میاد آگاهه. و آبجکت هارو به صورت خیلی implicit داره mutate میکنه.
مثلا مثال زیر رو در نظر بگیرین. من یک کانکشن باز کردم به دیتابیس. یک یوزر گرفتم. name رو گذاشتم مانی. بعد یک transaction زدم. به session این transaction گفتم که user رو track کن. همون یوزر, اسمش رو تغییر دادم به عباس.
حالا اگه transaction رو من بیام rollback کنم sqlalchemy به صورت خودکار میاد اون تغییری که من دادم رو تو سطح memory میاد revert میکنه. یعنی الان پراپرتی name یوزر مانیه!
async with session_maker() as session:
query = sa.select(User).where(User.id == 1).limit(1)
user = await session.scalar(query)
user.name = "Mani"
async with session.begin() as transaction:
transaction.add(user)
user.name = "Abbas"
await transaction.rollback()
print(user.name) # This is mani! not abbas 🙂
یک کامنت و PR Review خیلی معمول 😂😂😂
@PyBackendHub
برای اینکه بهتر متوجه شید این عکس از repsonse همون api ای هست که تیم یاسر زده.
الان با وجود sender_public_key میشه گفت واقعا ناشناسه؟
@PyBackendHub
شاید نظریه نامحبوب باشه، ولی من چیزا رو قبول ندارم:
۱. اینکه تو مصاحبه اول بگی آره من خیلی علاقه دارم تو شرکت شما کار کنم. اینکه به یک پروداکت علاقه داشته باشین، طبیعتا عادیه. ولی چطوری به شرکتی علاقه دارین که هنوز نوش نرفتین و هیچی نمیدونید راجبش؟
۲. من حتی گلس دور هم قبول ندارم. چون کسایی که رفتن گلس دور همه bias هستن. یا نظره خیلی منفی داشتن رفتن نظر بدن. یا شرکت هلشون داده که نظره خوب بنویسن. یعنی جامعه اماری که تو گلس دوره اصلا قابل اعتماد نیست برای نتیجه گیری
۳. اینکه از یک کارمند و غریبه داخل شرکت تو لینکدین بپرسید که شرکت چطوریه؟ احتمال اینکه دقیقا بشینه براتون تعریف کنه چه حس و حالیه تو شرکت، خیلی کمه.
چطوری بفهمیم؟ از روند مصاحبه. روند مصاحبه کالچر شرکت رو تا حد زیادی لیک میکنه. سوالایی که میتونید بپرسید، و نحوه ای که کلا جلو میره.
بازم خیلی شاید قاطع نباشه، ولی بهترین چیزیه که میتونید بگیرید.
@PyBackendHub
من احتمال ۹۰ درصد میدم که فرانت اند کاره سامانه سجاد از .env استفاده کرده و فکر کرده ship نمیشه سمت کلاینت.
همینجاست که دانش عمیق بهتون کمک میکنه. باید متوجه شین چه اتفاقی داره میفته و چه بلایی سره کدتون میاد.
@PyBackendHub
اگه کلمه story point رو شنیدین، فرار کنید 😂🏃
@PyBackendHub
چیزی که من متعجب شدم اکثرا میگن این <خیلی پیچیدست>. ولی حقیقتا اصلا پیچیده نیست. کامیونیتی پایتون خیلی گارد زیادی نسبت به تایپینگ داره که تو دراز مدت قطعا ضربه میخورین چون پایتون الان هر نسخه ریلیز میده ۸۰ درصدش تایپینگ improvement هست و شما اگه الان typing بلد نباشین عملا از خیلی از لایبری های جدید نمیتونید استفاده کنید.
تو این مثال حتی یک خط نشده. و شما اینکار رو برای آیدی ها انجام میدی. تو یک سرویس پرحجم که شما ۲۰۰ تیبل داری نهایتا میشه ۲۰۰ خط NewType. و باعث میشه signature همه کد های شما قابل خوانا باشه.
این tip به درد شما میخوره اگه کد میزنی. لزوما به بک اند هیچ ربطی نداره. الان شما یک تابع بنویسید که یک سریآیدی موزیک و آیدی یوزر بگیره و بعد بگه برای هر موزیک هر یوزر پیش بینی کنه از صفر تا صد چقدر ممکنه دوست داشته باشه
این ۳ مثال رو ببینید, مثال اول تایپینگ خوبی داره. مثال دوم تایپینگ داره ولی به درد بخور نیست خیلی. و مثال سوم تایپینگ نداره.
# WITH GOOD TYPING
Percentage: TypeAlias = int # from 0 to 100.
def calculate_music_populatiry(person_ids: list[PersonId], music_ids: list[MusicId]) -> dict[PersonId, list[tuple[MusicId, Percentage]]
# WITH BAD TYPING
def calculate_music_populatiry(person_ids: list[UUID], music_ids: list[UUID]) -> dict[UUID, list[tuple[UUID, int]]
# WITHOUT TYPING
def calculate_music_populatiry(person_ids, music_ids)
ممنون میشم دلیل دیس لایک هم بنویسید, ممکنه تایپ اسکریپت یک چیزی built in داشته باشه برای اینکار ولی من پیدا نکردم. البته اینم بگم این مثال اصلا منطقی نیست. چون مثال کوچیکه.
فکر کنید تو دنیای واقعی ORM دارین. یا API. اون موقع تو ورودی دیتا به اپلیکیشنتون این تایپ رو میدین. اون موقع منطقیه. یعنی اون تیکه as UserId رو نمینویسین جایی.
یکی از چیزایی که باعث به شدت maintainable شدن کدم شده این مقاله هست و نکاتی که توشه.
Writing python like rust
توصیه میکنم حتما بخونید اگه تا الان نخوندین. اکثر چیزایی که تو مقاله گفته تو همه زبونا قابل پیاده سازیه یعنی اصلا ربطی به پایتون و راست و ... نداره.
یکی ازچیزایی که دوست دارم NewType هست. بهتون یک تایپ جدید برمیگردونه. خوبیش اینه که signature توابعتون و دیتا استراکچر رو خیلی پرمفهوم میکنه و جلوی خطا رو میگیره.
مثالش تو عکس گذاشتم.
@PyBackendHub
پنل گفت و گو - کد قابل نگهداری
@BenDevelop
https://youtu.be/Pf1uk3IjTJc
من تازه فهمیدم که میشه تو sqlalchemy با انجین هم transaction باز کرد. و حتی یک سری متود هایی که Session داره رو نداره. مثل add. همه متود هایی که رفتار عجیب غریب و ORM طور اضافه میکردن به sqlalchemy
حالا کنجکاو شدم بدونم ایا انجین sqlalchemy اون رفتار های implicit سشن رو داره یا نه؟ با توجه به اینترفیسش بنظر نمیاد داشته باشه. ولی هیچی بعید نیست از sqlalchemy 😅
@PyBackendHub
Unpopular opinion
خیلی دیدم جامعه رو <سخت کار کردن> مانور رفته. سخت کار کن. موفق میشی. و ...
ولی حقیقتا اصلا مهم نیست چقدر سخت کار میکنید. مهم خروجیه. ممکنه من ۷ صبح کار کنم تا ۷ شب. ولی خروجیم کمتر از کسی باشه که ۱۱ صبح کار میکنه تا ۴.
پس مهم نیست چقدر سخت کار میکنی. مهم اینه که کارآمد و بهینه کار میکنی.
@PyBackendHub
Monad چیه؟
اگه گوگل کنید خیلی چیزا میاد راجبش. تو دوره دیزاین پترن هم جزو سرفصلام بود. ولی درواقع یک استراکچر داخل جبره، که بهش میگن category theory
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
یک مقاله قشنگ که تو پایتون این پترن رو پیاده کرده
https://dev.to/hamzzak/mastering-monad-design-patterns-simplify-your-python-code-and-boost-efficiency-kal
@PyBackendHub
نمیدونم چرا ولی روند توسعه یک فیچر ۹۹درصد مواقع اینطوریه که شما اول under engineer میکنی. همه یوزکیس هارو کاور نمیکنی. بعدش اورانجینر میکنی. یک سیستم پیچیده تحویل میدی، که maintain اش یکم سخت تره. و باره سوم، درست انجامش میدی 😁
احساس میکنم دلیلش میتونه مشخص نبودن اون خطی باشه که باید تا اون حد انجینرینگ کنی.
@PyBackendHub
این شاید مهم ترین پست sqlalchemy بود که تا امروز گذاشتم (و خواهم گذاشت). 👆
Читать полностью…