Fastapi testclient middleware problam

היי לכולם!
אני עובד על הפאנל פיצרים ומה שמצאתי שאני רוצה לעשות לתפוס את כל הבקשות HTTP ואם הבקשה מובילה לפיצר מכובה disabled הוא לא יתן להריץ אותו.
(אם אני לא עושה את זה אני כנראה אצור פונקציה שמי שיש לו פיצר יצתרך כנראה לתמוך בה…)

אז עושה את זה בעזרת Middleware של http שזה בעצם עושה את מה שתיארתי, וזה עובד נפלא.

הבעיה מתחילה כאשר מריצים את הטסטים הקיימים…
כל פעם שעושים בקשת http בעזרת testclient של fastapi זה זורק AssertionError

הנה הפלט.
Screen Shot 2021-02-06 at 16.09.52

כמו בתמונה כמובן שחיפשתי באינטרנט איך לטפל בזה ומצאתי בשביל שאוכל להשתמש בmiddleware צריך להשתמש בasync asgi testclient

והנה הבעיה בגיטאב עם דוגמא של השגיאה כאן ובמקרה זה גם המקור שסיפק את התשובה.

כמובן שהחלפתי את הtestclient כדי לנסות לראות שהבעיה נפתרה ואכן השגיאה שספציפית הזאת כן.
אבל שאר הטסטים לא מעודכנים לסוג הזה של testclient ופקודות כמו response.ok לא עובדות.

אשמח להצעות נוספות :blush: או האם זה אפשרי שנעדכן את הtestclient שלנו ואת הטסטים שלנו.

היי,
האם הבעיה היא ספציפית שאין את .ok?
אם כן, בדקת האם יש תחליפים בקוד של המודול? :slight_smile:

יש תחליפים פחות ספציפים.

הנה כמה דוגמאות מהדוקומנטציה.

resp = await client.get("/")
assert resp.status_code == 200
assert resp.text == "plain response"

resp = await client.get("/json")
assert resp.status_code == 200
assert resp.json() == {"hello": "world"}

הם למעשה יותר ספציפיים, כי הם לא מקבלים 302 או 303 כוולידיים. יש משהו פחות ספציפי?(:

לייק 1

לא מצאתי משהו נוסף…

איך ממשיכים?

הלינק ששלחת ל־issue הוא בעיה שהייתה קיימת לפני שנתיים. אתה בטוח שזו הבעיה?

רפרנס נוסף: AssertionError with middleware and TemplateResponse · Issue #472 · encode/starlette · GitHub

כן זה אותה בעיה.
וכבר ראיתי את הלינק ששלחת, זה כמו הissue ששלחתי…

כיצד ממשיכים?

יש פתרונות בטיקט ששלחתי. ניסית אותם?

לייק 1

ניסיתי שם הכל ולא עבד לי.

חלק מהפתרונות עושים שגיאות יותר גדולות.

לצערי לא יהיה לי זמן להתפנות להיכנס לקוד בקרוב. נסה למצוא פתרונות בעצמך או להיעזר בקהילה

מצאתי פתרון את זה async asgi testclient כפי שציינתי בפוסט.
ולא רצית כי אין .ok ויש במקום .status_code
אז אם זאת הבעיה למה לא לבדוק אם .status_code בין 200 ל299 ?
הראי כל קוד בין 200 ל299 הוא אומר שהבקשה עברה בהצלחה כפי שצויין כאן HTTP response status codes - HTTP | MDN.

רגע, למה המודול ההוא עובד? מה ממומש בו שונה?
נכנסתי ל¯async asgi test client, זה מודול שמתוחזק חצי כוח

אני לא יודע למה הוא עובד אחרת…
אני רק יודע שזה עובד וזה מה שאומרים לעשות למי שיש את הבעיה.
אתה יכול לראות את ההסבר למה זה עובד כאן. זה מתוך הissue שפתחו בfastapi.

אני יודע מניסיון שfastapi testclient מחזיר type לא מתאים של הבקשה גם מצולם בתמונה למעלה.

אי אפשר לפתור באגים בלי להבין למה fix שהכנסת לפרויקט עובד, ולמה הדבר הקודם לא.
לא הייתי מכניס לבית שלי תיקונאי שאומר “אין לי מושג למה זה עובד, אבל הנה תראה זה עובד” :slight_smile:

הסכנות הן:

  1. הכנסת פתרונות לא מתאימים שיגרמו באגים במקומות אחרים.
  2. יצירת באגים עתידיים עבור אנשים שירצו להוסיף קוד לפרויקט.
  3. פתרון לא מיטבי שלא מתחשב בכל מקרי הקצה, ועלול להוסיף טכנולוגיות לא נכונות או מזיקות לקוד.

אני אשמח אם תוכל לחקור קצת מה ההבדל ולמה אחד עובד והשני לא,
או שתצליח למממש פתרון כזה בעצמך.

לייק 1

אז בדקתי על ההבדלים כמו שביקשת.

הfastapi משתמש ב-starlette middleware הוא אפילו לא משנה אותו.
וכאשר משתמשים בmiddleware עם jinja2 templates
הוא מחזיר message["type"] שונה.

לדוגמא {'type': 'http.response.template'}

וכאשר הקוד רץ הmessage["type"] עובר וולידציה והוא חייב להיות תואם ל-
{'type': 'http.response.start'} ככה הקוד שלהם כתוב.

ומצאו שהפתרון הוא להשתמש בasync-asgi-testclient כי הוא מחזיר את הmessage["type"] הנכון.

לפי מה שמצאתי זה הפתרון הרשמי שסגר את הissues של הבעיה הזאת.

בדקתי גם על הסכנות והסכנות האלה לא קיימות פה, fastapi testclient הוא בעצם starlette testclient והוא מבוסס על HTTPX וגם async-asgi-testclient מבוסס על HTTPX, הם בגדול עובדים באותה צורה וההבדל זה הmessage["type"] שונה זה מה שמצאתי על הבדלים.

וגם לfastapi יש פונקציות כמו .ok כמו שאמרנו אבל אפשר לפתור את זה כשבודקים אם ה.status_code
בין 200 ל299 כפי שאומרים כאן HTTP response status codes - HTTP | MDN.

לא הצלחתי לפתור את הבעיה הזאת בעצמי כי הדברים שם הם read only ולא נותן לי לשנות אותם.

מה אתה אומר אפשר להחליף את הtestclient שלנו כדי שאוכל להשתמש בmiddleware?

ותודה רבה על העזרה :raised_hands:

2 לייקים

מגניב, אחלה תגובה וכל הכבוד על המחקר העצמאי :slight_smile:

קראתי את הקישורים שהבאת ונראה שזו באמת הבעיה, ואני לא רואה פתרון טוב יותר כרגע.
נשמע אחלה, לך על זה!

לפני שאתה מתחיל שים לב שב־requests שבודקים האם משהו הוא ok, רואים האם הוא בין 200 ל־400 (לא כולל 400) – משום שגם 301/302 ושאר החברים נחשבים כעמוד תקין.
אם אתה בכלל רוצה לצאת מלך – תעשה PR ל־async-asgi-testclient ותוסיף שם .ok :wink:

2 לייקים

תודה ענקית !!
אנסה להוסיף .ok נשמע מעניין.
חחחחח

ואולי אפשר להחליף מעכשיו את הtest client שכולם יכולו לעדכן את הטסטים שלהם?

ברגע שתחליף ואקבל את הקומיט שלך לכולם לא תהיה ברירה :wink:
(כן, כדאי להחליף עכשיו)

לייק 1

אבל זה לא יעבור את הטסטים בגיטאב, אתה תקבל את הקומיט בכל זאת?

זה יעבור אם תדאג שזה יעבור :slight_smile:

2 לייקים