Гузариш ба мундариҷа
Мавзӯи 2 аз 6

Масирҳо ва ҷавобҳо

Чаро масирҳо лозиманд

Flask веб-фреймворк аст: китобхонае, ки дархости HTTP-ро қабул мекунад, рамзи Python-и шуморо иҷро карда, ҷавоб месозад. Саҳифаҳои портфолио, феҳристҳо ва қисми серверии барномаҳои мобилӣ ҳамин тавр кор мекунанд. Дар ин курс тадриҷан сайти шахсӣ бо форма ва API месозед.

Браузер ба нишонӣ, масалан /help, муроҷиат мекунад. Танҳо номи функсияи Python саҳифа намесозад. Масир (route) қоидаест, ки роҳро ба функсия мепайвандад. Фаҳмидани ин қоида ва рамзҳои ҳолат имкон медиҳад, ки нишонии нодурустро аз хатои ҳисоб фарқ кунед.

1. Барнома, масир ва намоиш

Flask(__name__) барномаро месозад; __name__ ба Flask дар ёфтани захираҳо ёрӣ медиҳад. Ороишгари @app.route(...) қоидаро сабт мекунад. Функсияи зераш намоиш (view) аст: он барои ҳар дархости мувофиқ аз нав иҷро шуда, муҳтавои ҷавобро бармегардонад.

Аввал аз мизоҷи санҷишӣ истифода мебарем. Ин объект дархостро бевосита ба барнома мефиристад, бе сервери шабакавӣ. .get() дархости GET месозад, .status_code рамзи ҳолатро мехонад ва .get_data(as_text=True) тани ҷавобро ба сатр табдил медиҳад. Ҳар мисоли ин лексияро алоҳида иҷро кунед.

from flask import Flask

app = Flask(__name__)

@app.route("/help")
def help_page():
    return "Роҳнамо"

client = app.test_client()
r = client.get("/help")
print(r.status_code)
print(r.get_data(as_text=True))

Натиҷа:

200
Роҳнамо

Бе рамзи ошкор сатри баргардонда ба ҷавоби 200 OK табдил меёбад. Дар ин ҷо мизоҷ ҷавоб гирифт, вале сервери алоҳида оғоз нашуд. Барои кор дар браузер дар охири файл if __name__ == "__main__": ва зери он бо фосила app.run(debug=True) илова мекунанд. Сайт дар http://127.0.0.1:5000/help дастрас мешавад. debug=True азнавоғозкунӣ пас аз тағйир ва debugger-ро фаъол мекунад; онро танҳо дар компютери худ истифода кунед. Қатъ кардан бо Ctrl+C аст.

2. Қисми тағйирёбандаи роҳ

Қисми дар қавсҳои кунҷӣ буда ба намоиш ҳамчун аргумент дода мешавад. Табдилдиҳанда (converter) шакли иҷозатдодаи қисмро муайян карда, қиматро табдил медиҳад. <int:code> адади бутуни ғайриманфиро қабул мекунад: функсия фавран int мегирад. Бе табдилдиҳанда Flask сатри бе / медиҳад. Номи параметри функсия бояд бо номи қоида яксон бошад.

from flask import Flask

app = Flask(__name__)

@app.route("/book/<int:code>")
def book(code):
    return f"{code + 100}"

client = app.test_client()
for path in ("/book/8", "/book/text", "/book/-8"):
    r = client.get(path)
    print(path, r.status_code)
print(client.get("/book/8").get_data(as_text=True))

Натиҷа:

/book/8 200
/book/text 404
/book/-8 404
108

Барои нишонии номувофиқ функсия умуман иҷро намешавад: 404 ҳангоми ҷустуҷӯи масир пайдо мешавад. <float:value> барои ададҳои дорои нуқтаи даҳӣ аст; <path:part> метавонад / дошта бошад, масалан дар роҳи ҳуҷҷат. Табдилдиҳанда шакли нишониро месанҷад, вале мавҷудияти китоб бо ин рақамро худатон месанҷед.

3. Тан ва рамзи ҷавоб

Ҷавоби HTTP тан (муҳтавои намоишёбанда) ва ҳолат (натиҷаи дархост) дорад. Барои додани ҳар ду кортежи (тан, рамз) баргардонед. Барои қимати нодурусти параметр рамзи 400 мувофиқ аст. abort(code) коркардро фавран қатъ карда, саҳифаи стандартии хато месозад; return-и баъдӣ дигар иҷро намешавад.

from flask import Flask, abort

app = Flask(__name__)

@app.route("/stock/<int:count>")
def stock(count):
    if count > 50:
        return "Дастнорас", 400
    if count == 0:
        abort(404)
    return f"Боқӣ монд: {count}"

client = app.test_client()
for count in (4, 70, 0):
    r = client.get(f"/stock/{count}")
    print(r.status_code)
    if r.status_code != 404:
        print(r.get_data(as_text=True))

Натиҷа:

200
Боқӣ монд: 4
400
Дастнорас
404

Сабабҳоро ҷудо кунед: 200 — муваффақият, 302 — равонасозӣ, 400 — додаҳои нодуруст, 404 — нишонӣ ё захира нест, 405 — усул иҷозат надорад, 500 — хатои коркарднашудаи сервер. Матни «Хато» бе унсури дуюми кортеж боз ҳам бо рамзи 200 меравад. Истиснои ZeroDivisionError худ аз худ ба хатои фаҳмои корбар табдил намеёбад.

4. Санҷиши чанд дархости мустақил

Як мизоҷи санҷиширо чанд бор истифода бурдан мумкин аст. Ҳар ҷавоб объекти алоҳида аст: ҳар кадомро санҷед. Дар мисоли зерин як роҳ матн ва дигаре адад қабул мекунад; ҳеҷ дархост барномаро тағйир намедиҳад.

from flask import Flask
from markupsafe import escape

app = Flask(__name__)

@app.route("/label/<name>")
def label(name):
    return f"<p>{escape(name)}</p>"

@app.route("/double/<int:value>")
def double(value):
    return str(value * 2)

client = app.test_client()
for path in ("/label/Flask", "/double/6", "/missing"):
    r = client.get(path)
    print(r.status_code)
    if r.status_code == 200:
        print(r.get_data(as_text=True))

Натиҷа:

200
<p>Flask</p>
200
12
404

escape аз markupsafe аломатҳои махсуси меҳмонро ба матни бехатари HTML табдил медиҳад. Ин барои додаҳои нишонӣ низ лозим аст. Гурезонидани худкорро дар мавзӯи қолибҳо муфассал меомӯзем.

Дархост дар дохил чӣ тавр мегузарад

Хадамоти маълумотро тасаввур кунед: аввал шуъбаро аз рӯйи нишонӣ меёбанд, баъд параметрҳоро ба он медиҳанд ва охир ҷавобро омода мекунанд. Flask роҳ ва усули HTTP-ро бо ҷадвали масирҳо муқоиса мекунад, табдилдиҳандаҳоро истифода мебарад, view-ро иҷро карда, сатру кортежро ба объекти ҷавоб табдил медиҳад. Агар қоида набошад, намоиши шумо иҷро намешавад. Мизоҷи санҷишӣ ҳамин раванди коркардро бе пайвасти шабакавӣ мегузарад.

Хатоҳои маъмул ва ислоҳи онҳо

  1. return 12: адади бутун ҷавоби дурусти view нест ва хатои сервер медиҳад. Ислоҳ: return str(12).
  2. Қоида <int:code> дорад, вале функсия number қабул мекунад: Flask аргументи ношиноси code медиҳад ва хато мешавад. Ислоҳ: номҳо дар қоида ва функсия яксон бошанд.
  3. return "Дастнорас" барои додаҳои нодуруст рамзи 200 медиҳад. Ислоҳ: , 400 илова кунед.
  4. app.run() пеш аз санҷишҳо барномаро то қатъи сервер ба хизматрасонӣ машғул мекунад. Ислоҳ: оғози интерактивиро бо if __name__ == "__main__": ҷудо кунед; санҷишҳо test_client-ро бе app.run истифода мебаранд.

Ёддошт

Вазифа Восита
Сохтани барнома Flask(__name__)
Пайвастани роҳ ба view @app.route("/help")
Қабули адади бутуни ғайриманфӣ <int:code>
Баргардондани матн ва ҳолат return text, 400
Қатъи фаврии дархост abort(404)
Санҷиши ҷавоб client.get(path), r.status_code, r.get_data(as_text=True)

Пеш аз ҳалли масъалаҳо қиматҳои иҷозатдода, ҳудудҳо ва матни хаторо алоҳида фикр кунед. Масир шакли нишониро муайян мекунад, қоидаҳои соҳаи масъала дар намоиш мемонанд.