Ачааллж байна...
Бүлэг 15 эхэлж байна. Энэ бол сүүлчийн бүлэг.
Курсийн хамгийн эхний хичээлд (Бүлэг 1.1) би танд амлалт өгсөн. Тэр амлалтыг эргэн санацгаая:
"Энэ сургалтын зорилгыг би нэг өгүүлбэрээр хэлье: сургалтын төгсгөлд та FastAPI гэх мэт орчин үеийн framework-ийн албан ёсны documentation-ыг нээгээд, уншаад, ойлгодог болно."
Мөн би тэр үед нэг зүйлийг хойшлуулсан:
"Framework гэдэг үгийг би энэ сургалтын турш олон удаа хэрэглэх болно, тиймээс одооноос жаахан таниулъя. Гэхдээ бүрэн, зөв тодорхойлолтыг нь Бүлэг 15-д, та бүх шаардлагатай мэдлэгээ цуглуулсны дараа өгнө — учир нь одоо өгвөл тэр тодорхойлолт зүгээр л үг болж үлдэнэ, ойлголт болохгүй."
Одоо тэр цаг ирлээ.
Энэ хичээлд бид:
Framework ба library-ийн ялгааг бүрэн тайлбарлана
"Framework-д бэлэн" гэдэг нь ЯГ ЮУ гэсэн үг болохыг тодруулна
Та энэ курсийн турш юуг эзэмшсэнийг нэг дор харна
Ганц ч мөр шинэ код байхгүй. Зөвхөн ойлголт ба дүгнэлт.
Дараагийн хичээл (15.2) нь CAPSTONE — та өөрийн FastAPI программ бичнэ.
Framework ба library-ийн ялгаа нь ГАНЦХАН асуултад оршдог:
ХЭН ХЭНИЙГ ДУУДДАГ ВЭ?
LIBRARY (сан):
ТА түүнийг дууддаг.
Та программаа бичнэ. Хэрэгтэй үедээ сангийн функцийг дуудна. Хяналт ТАНД байна.
python
import requests # LIBRARY
hariult = requests.get(url) # ТА дуудаж байна
uguudul = hariult.json() # ТА дуудаж байна
print(uguudul) # ТА шийдэж байнаТаны программ нь ЭХЛЭЭД, ТӨГСГӨЛТЭЙ. Тэр нь дээрээс доош урсана. Та хаана, хэзээ юу дуудахыг шийднэ.
FRAMEWORK:
ТЭР таныг дууддаг.
Та кодоо бичээд БҮРТГҮҮЛНЭ. Дараа нь ХҮЛЭЭНЭ. Framework нь түүнийг хэзээ дуудахаа өөрөө шийднэ.
python
from fastapi import FastAPI # FRAMEWORK
app = FastAPI()
@app.get("/nomnuud") # БҮРТГҮҮЛЖ байна
def nomnuud_jagsaakh():
return nomnuud
# Энэ функц ХЭЗЭЭ дуудагдах вэ?
# Хэн нэгэн /nomnuud хаяг руу хандахад.
# ТА түүнийг мэдэхгүй. ТЭР шийднэ.Таны код нь эхлэл, төгсгөлгүй. Тэр нь зөвхөн ХАРИУЛТУУД — асуулт ирэхэд бэлэн.
Программистууд түүнийг "Inversion of Control" (хяналтын эргэлт) гэж нэрлэдэг. Хяналт нь таны гараас framework -ийн гарт шилжсэн.
Ялгааг ойлгуулах зүйрлэл.
LIBRARY бол ХЭРЭГСЭЛ.
Танд алх байна. Та хэзээ, хаана, яаж цохихыг ӨӨРӨӨ шийднэ. Алх нь таны гарт байна. Тэр нь та юу барихыг мэдэхгүй.
FRAMEWORK бол БАЙШИНГИЙН ХҮРЭЭ.
Хэн нэгэн суурь, багана, дээврийг аль хэдийн барьсан. Танд ТОДОРХОЙ ГАЗАР үлдээсэн: "энд цонх тавь, энд хаалга тавь, энд ханыг будаж өг."
Та тэр газруудыг дүүргэнэ. Гэхдээ БҮТЭЦ нь аль хэдийн тогтсон.
Та байшинг сүйрүүлж, өөрөөр барьж чадахгүй. Хэрэв та тэгэхийг хүсвэл — өөр framework сонго.
Тэр нь СУЛ ТАЛ уу?
ҮГҮЙ. Тэр бол ХЭЛЭЛЦЭЭР:
Та ЭРХ ЧӨЛӨӨГ өгнө
Тэр танд ХУРД, БЭЛЭН БҮТЭЦ, ЗӨВ ШИЙДЛҮҮД өгнө
FastAPI нь HTTP, JSON, validation, documentation, сервер — БҮГДИЙГ хийж өгнө. Та зөвхөн ЛОГИКОО бичнэ.
Ялгааг ТОД харуулъя.
LIBRARY -тэй программ (requests):
python
import requests
# ТА бүх зүйлийг зохион байгуулж байна
def main():
ner = input("Хотын нэр: ") # 1. Та асууж байна
hariult = requests.get(url, params=...) # 2. Та дуудаж байна
uguudul = hariult.json() # 3. Та задалж байна
print(uguudul) # 4. Та харуулж байна
main() # 5. Та эхлүүлж байнаУрсгал нь ТОД: дээрээс доош. Та мөр бүр хэзээ ажиллахыг мэднэ.
FRAMEWORK -тэй программ (FastAPI):
python
from fastapi import FastAPI
app = FastAPI()
@app.get("/nomnuud")
def nomnuud_jagsaakh():
return nomnuud # ХЭЗЭЭ ажиллах вэ? Мэдэхгүй.
@app.post("/nomnuud")
def nom_nemekh(nom: Nom):
nomnuud.append(nom)
return nom # ХЭЗЭЭ ажиллах вэ? Мэдэхгүй.
# main() БАЙХГҮЙ!
# Та ЮУ Ч эхлүүлэхгүй!Урсгал нь ТАНД ХАРАГДАХГҮЙ.
Та зөвхөн ХАРИУЛТУУД бичсэн. Асуулт хэзээ ирэхийг та мэдэхгүй.
uvicorn (сервер) нь программыг ажиллуулна. Хүсэлт ирэхэд — FastAPI нь ТАНЫ функцийг дуудна.
Та ХҮЛЭЭЖ БАЙНА. ТЭР ДУУДДАГ.
Бүлэг 10.4-т бид өөрсдийн жижиг framework бичсэн:
python
ZAMUUD: dict[tuple[str, str], Callable] = {}
def get(khayag: str):
def decorator(func):
ZAMUUD[("GET", khayag)] = func # БҮРТГЭНЭ
return func
return decorator
@get("/nomnuud")
def nomnuud_jagsaakh() -> str:
return "Номнуудын жагсаалт"
def khuselt_boloviruulakh(method: str, khayag: str) -> str:
func = ZAMUUD.get((method, khayag))
if func is None:
return "404"
return func() # ТЭР ДУУДАЖ БАЙНАТэр бол ЖИНХЭНЭ framework — жижиг, гэхдээ бүх зарчим нь тэнд байна:
Decorator нь функцийг БҮРТГЭНЭ (ZAMUUD[...] = func)
Бүртгэл нь ФАЙЛ АЧААЛАГДАХ үед болно — функц дуудагдах үед биш
Framework нь хэзээ дуудахаа ӨӨРӨӨ шийднэ
FastAPI нь ЯГ ЭНЭ ЗҮЙЛИЙГ хийдэг — зөвхөн хамаагүй илүү нарийн.
Тиймээс @app.get("/") нь илбэ БИШ. Та түүнийг өөрөө бичсэн.
Одоо энэ курсийн гол асуултад хариулъя.
Бүлэг 1.1-т би ингэж хэлсэн:
"Орчин үеийн Python-ы documentation бүхэн уншигч нь тодорхой зүйлсийг аль хэдийн мэддэг гэж таамагладаг."
Тэдгээр "тодорхой зүйлс" нь ЯГ ЮУ байсан бэ?
Одоо би тэдгээрийг ЖАГСААНА. Мөн та тус бүрийг нь ЭЗЭМШСЭН гэдгээ харна.
Дараах код бол FastAPI-гийн documentation -оос авсан ердийн жишээ:
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class Nom(BaseModel):
garchig: str
zokhiolch: str
on: int
khuudas: int = 0
tailbar: str | None = None
nomnuud: dict[int, Nom] = {}
daraagiin_id = 1
@app.get("/nomnuud")
def nomnuud_jagsaakh(zokhiolch: str | None = None) -> list[Nom]:
if zokhiolch is None:
return list(nomnuud.values())
return [n for n in nomnuud.values() if n.zokhiolch == zokhiolch]
@app.get("/nomnuud/{nom_id}")
def nom_avakh(nom_id: int) -> Nom:
nom = nomnuud.get(nom_id)
if nom is None:
raise HTTPException(status_code=404, detail="Ном олдсонгүй")
return nom
@app.post("/nomnuud", status_code=201)
def nom_nemekh(nom: Nom) -> Nom:
global daraagiin_id
nomnuud[daraagiin_id] = nom
daraagiin_id += 1
return nomОдоо энэ кодыг МӨР МӨРӨӨР нь задалъя. Мөр бүрд — "энэ нь ЯМАР бүлгээс ирсэн бэ?"
from fastapi import FastAPI, HTTPException
→ Бүлэг 12.1: import, модуль
from pydantic import BaseModel
→ Бүлэг 12.1: from ... import
class Nom(BaseModel):
→ Бүлэг 7.1: INHERITANCE. Nom нь BaseModel -ээс өвлөж байна.
garchig: str
→ Бүлэг 4.2: TYPE HINT.
khuudas: int = 0
→ Бүлэг 3.1: DEFAULT УТГА. Бүлэг 4.4: hint + default.
tailbar: str | None = None
→ Бүлэг 4.3: UNION (| None). "Байж ч болно, байхгүй ч байж болно."
Тэр class бүхэлдээ → Бүлэг 9.2: "dataclass + type hint + default утга = ЯГ ТЭР бүтэц, Pydantic ашигладаг."
nomnuud: dict[int, Nom] = {}
→ Бүлэг 4.2: цуглуулгын hint. Бүлэг 5.4: "ID -гаар индексжүүлсэн олон зүйл → dict[int, ...]"
@app.get("/nomnuud")
→ Бүлэг 10.2, 10.4: DECORATOR. Функцийг БҮРТГЭЖ байна.
def nomnuud_jagsaakh(zokhiolch: str | None = None) -> list[Nom]:
→ Бүлэг 4.4: бүрэн hint. Бүлэг 3.1: default утга. Бүлэг 11.2: query parameter — ?zokhiolch=Ринчен
return [n for n in nomnuud.values() if n.zokhiolch == zokhiolch]
→ Бүлэг 2.1: COMPREHENSION + шүүлт.
@app.get("/nomnuud/{nom_id}")
→ Бүлэг 11.2: path parameter. /nomnuud/123
def nom_avakh(nom_id: int) -> Nom:
→ FastAPI нь {nom_id} -ыг УНШИЖ, int болгож хувиргаж, функцэд дамжуулна. Type hint -ээс.
nom = nomnuud.get(nom_id)
→ Бүлэг 4.3: .get() — key байхгүй бол None.
if nom is None:
→ Бүлэг 4.3: is None (== None биш).
raise HTTPException(status_code=404, detail="Ном олдсонгүй")
→ Бүлэг 13.2: raise! Бүлэг 11.1: 404 = Not Found.
@app.post("/nomnuud", status_code=201)
→ Бүлэг 11.1: POST = үүсгэх. 201 = Created.
def nom_nemekh(nom: Nom) -> Nom:
→ Хамгийн гайхалтай мөр. FastAPI нь интернэтээс ирсэн JSON -ыг АВТОМАТААР Nom объект болгож хувиргана (Бүлэг 6, 9.3). Хэрэв өгөгдөл буруу бол — АВТОМАТААР 400 буцаана.
Бүлэг 9.3-т бид түүнийг ГАРААР хийсэн:
python
try:
zarlaguud.append(Zarlaga(**d))
except (TypeError, ValueError) as alda:
print(f"Бичлэг {i} алгаслаа: {alda}")FastAPI нь тэр КОДЫГ таны өмнөөс бичдэг.
nomnuud.append(nom)
→ Курс 1: list.
ЭНЭ КОДОД ТАНД ОЙЛГОМЖГҮЙ ЗҮЙЛ БАЙНА УУ?
Магадгүй HTTPException -ийн нарийвчлал. Магадгүй BaseModel -ийн дотоод механизм.
Гэвч КОДЫН БҮТЭЦ нь БҮХЭЛДЭЭ ТАНИЛ.
Тэр бол "framework-д бэлэн" гэдэг нь ЯГ ЭНЭ.
Одоо бүх зүйлийг НЭГ ХҮСНЭГТ болгоё.
Framework-ийн documentation нь таныг ЭДГЭЭРИЙГ мэднэ гэж таамагладаг:
Ойлголт | Хаанаас | Framework -д яагаад хэрэгтэй вэ |
|---|---|---|
Virtual environment, pip | Бүлэг 1 |
|
Comprehension | Бүлэг 2 | Өгөгдөл шүүх, хувиргах |
Default утга | Бүлэг 3.1 | Сонголттой параметр |
Keyword argument | Бүлэг 3.2 |
|
| Бүлэг 3.3 | Decorator -ын дотор |
Функц бол утга | Бүлэг 3.5 | Decorator -ын суурь |
TYPE HINT | Бүлэг 4 | FastAPI-гийн ЗҮРХ |
**` | None` (union)** | Бүлэг 4.3 |
Dictionary, list, set | Бүлэг 5 | Өгөгдлийн бүтэц |
Үүрлэсэн бүтэц | Бүлэг 5.3 | JSON-ы хэлбэр |
JSON | Бүлэг 6 | API-гийн ХЭЛ |
Inheritance | Бүлэг 7 |
|
Special methods | Бүлэг 8 | Python-ы протоколууд |
DATACLASS | Бүлэг 9 | Pydantic -ийн бүтэц |
DECORATOR | Бүлэг 10 |
|
HTTP, status code | Бүлэг 11 | 404, 400, 201 |
Package, модуль | Бүлэг 12 | Төслийн бүтэц |
| Бүлэг 13.2 |
|
| Бүлэг 14 | Уншиж таних |
ХОРИН ойлголт. Та БҮГДИЙГ эзэмшсэн.
Тэдгээрийн ЯМАР Ч НЭГИЙГ мэдэхгүй бол — FastAPI-гийн эхний хуудас нь ойлгомжгүй байх байсан.
Одоо тэр нь ТАНИЛ.
Одоо би энэ курсийн хамгийн гүн санааг дахин хэлье.
Бүлэг 4.1-т би ингэж хэлсэн:
"Python нь type hint-ийг ШАЛГАДАГГҮЙ. Тэр тэднийг бүрэн үл тоомсорлодог. Тэдгээр нь ХҮМҮҮС ба ХЭРЭГСЛҮҮДЭД зориулагдсан."
Мөн би нэг зүйлийг нэмсэн:
"Мөн дөрөв дэх нь: зарим framework нь hint-ийг УНШИЖ, ажиллуулдаг."
Одоо тэр нь БҮРЭН тодорхой боллоо.
Бүлэг 9.1-д @dataclass нь hint-ийг уншиж, __init__ үүсгэсэн:
"Type hint нь эцэст нь ЖИНХЭНЭ АЖИЛ хийж эхэллээ."
Одоо FastAPI нь ижил hint-ээс ХАМААГҮЙ ИЛҮҮ зүйл үүсгэнэ:
python
def nom_nemekh(nom: Nom) -> Nom:Тэр НЭГ мөрөөс FastAPI нь:
JSON -ыг АВТОМАТААР задална (Бүлэг 6.2-ын json.loads())
Nom объект болгож ХУВИРГАНА (Бүлэг 9.3-ын Nom(**d))
Талбар бүрийг ШАЛГАНА (Бүлэг 9.2-ын __post_init__)
Буруу бол 400 буцаана (Бүлэг 13.2-ын raise)
Хариуг JSON болгож хувиргана (Бүлэг 9.3-ын asdict())
БАРИМТ БИЧИГ ҮҮСГЭНЭ ← дараагийн хичээлийн шагнал
Та тэдгээр БҮГДИЙГ ГАРААР хийж үзсэн.
Одоо FastAPI нь тэднийг таны өмнөөс хийнэ.
ТЭР Л ШАЛТГААНААР ЭНЭ КУРС ЯГ ИЙМ ДАРААЛЛААР БАРИГДСАН.
Хэрэв би шууд FastAPI -г заасан бол — тэр нь ИЛБЭ мэт санагдах байсан.
Одоо тэр нь илбэ БИШ. Тэр нь таны бичих байсан кодыг АВТОМАТААР бичдэг хэрэгсэл юм.
Эцэст нь нэг практик зүйл.
Framework ба library нь эсрэг тэсрэг БИШ. Тэдгээр нь ХАМТДАА ажилладаг.
Ердийн FastAPI төсөл нь:
python
from fastapi import FastAPI # FRAMEWORK — тэр таныг дууддаг
from pydantic import BaseModel # LIBRARY — та түүнийг дууддаг
import httpx # LIBRARY — та түүнийг дууддаг
import json # LIBRARY — та түүнийг дууддаг
app = FastAPI()
@app.get("/tsag-agaar") # FRAMEWORK нь ЭНЭ функцийг дуудна
def tsag_agaar():
hariult = httpx.get(url) # ГЭХДЭЭ дотор нь ТА library дуудна
return hariult.json()Framework нь ГАДНА БҮТЭЦ, library нь ДОТООД ХЭРЭГСЭЛ.
Байшингийн хүрээ (framework) + алх, хөрөө (library).
Хэрэв сонирхвол: FastAPI-гийн албан ёсны documentation -г нээгээд (fastapi.tiangolo.com), эхний хуудсыг уншаарай.
Тэнд байгаа кодыг харж, өөрөөсөө асуугаарай: "Ойлгомжгүй зүйл байна уу?"
Магадгүй хэдэн нарийвчлал. Гэхдээ БҮТЭЦ нь танил байх ёстой.
Тэр мөч — та FastAPI-гийн кодыг ойлгож байгаагаа мэдрэх мөч — бол энэ курсийн эхний шагнал юм.
Хоёр дахь шагнал нь дараагийн хичээлд.
Framework ба library-ийн ялгаа нь ГАНЦХАН асуултад оршдог: ХЭН ХЭНИЙГ ДУУДДАГ вэ?
LIBRARY → ТА түүнийг дууддаг. Хяналт ТАНД. (requests, json)
FRAMEWORK → ТЭР таныг дууддаг. Та БҮРТГҮҮЛЖ, ХҮЛЭЭНЭ. (FastAPI)
Программистууд түүнийг "Inversion of Control" гэж нэрлэдэг.
Зүйрлэл: library бол ХЭРЭГСЭЛ (алх), framework бол БАЙШИНГИЙН ХҮРЭЭ (тодорхой газруудыг дүүргэнэ).
Хэлэлцээр: та ЭРХ ЧӨЛӨӨГ өгнө, тэр танд ХУРД, БЭЛЭН БҮТЭЦ, ЗӨВ ШИЙДЛҮҮД өгнө.
Бүлэг 10.4-т та ӨӨРӨӨ жижиг framework бичсэн — decorator нь функцийг БҮРТГЭНЭ, бүртгэл нь ФАЙЛ АЧААЛАГДАХ үед болно, framework нь хэзээ дуудахаа өөрөө шийднэ. FastAPI нь ЯГ ЭНЭ.
"FRAMEWORK-Д БЭЛЭН" гэдэг нь: FastAPI-гийн кодын БҮХ бүрэлдэхүүн хэсэг танил байх.
class Nom(BaseModel) → inheritance (Б7) + dataclass бүтэц (Б9)
garchig: str, khuudas: int = 0 → type hint (Б4) + default (Б3.1)
tailbar: str | None = None → union (Б4.3)
@app.get("/nomnuud") → decorator (Б10)
?zokhiolch=..., /{nom_id} → query/path parameter (Б11.2)
raise HTTPException(status_code=404) → raise (Б13.2) + status code (Б11.1)
[n for n in ... if ...] → comprehension (Б2.1)
nomnuud.get(id), is None → .get() (Б4.3)
ХОРИН ойлголт. Та БҮГДИЙГ эзэмшсэн.
ХАМГИЙН ГҮН САНАА: TYPE HINT нь БҮХ ЗҮЙЛИЙГ УДИРДДАГ.
def nom_nemekh(nom: Nom) -> Nom: гэсэн НЭГ мөрөөс FastAPI нь: JSON задлах, объект болгох, шалгах, алдаа буцаах, JSON болгох, БАРИМТ БИЧИГ ҮҮСГЭХ — БҮГДИЙГ хийнэ.
Та тэдгээр БҮГДИЙГ ГАРААР хийж үзсэн (Б6, Б9.3, Б9.2, Б13.2).
Тэр л шалтгаанаар энэ курс ЯГ ИЙМ ДАРААЛЛААР баригдсан. Одоо FastAPI нь илбэ БИШ.
Framework ба library нь ХАМТДАА ажилладаг. Framework нь ГАДНА БҮТЭЦ, library нь ДОТООД ХЭРЭГСЭЛ.
ДАРААГИЙН ХИЧЭЭЛ — CAPSTONE.
Та шинэ venv үүсгэж, pip install fastapi uvicorn гэж бичиж, өөрийн FastAPI программ бичнэ.
Дараа нь uvicorn -оор ажиллуулж, browser-ээр нээнэ.
Тэгээд /docs хуудсыг нээнэ.
Тэнд та өөрийн бичсэн TYPE HINT-үүдээс АВТОМАТААР үүссэн, БҮРЭН ИНТЕРАКТИВ баримт бичгийг харна. Товчлуур дарж, өөрийн API-г ТЭР ДОР НЬ туршиж болно.
Тэр мөч бол энэ бүх курсийн ШАГНАЛ юм. Бид түүнийг зохих ёсоор нь тэмдэглэнэ.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.