Run FastAPI as a real background HTTP service inside Google Colab, then call it from later notebook cells with requests.
เหมือน Exercise 1: ให้ FastAPI ทำงานอยู่ใน background thread แล้วใช้ Colab cell ถัดไปเป็น API Client โดยตรง
http://127.0.0.1:8000 ได้โดยตรงRun once at the beginning of the notebook.
pyngrok เพราะ Client อยู่ใน runtime เดียวกับ Server!pip -q install fastapi uvicorn requests
print("Packages ready ✓")app และข้อมูลจำลอง แต่ยังไม่ได้เปิด HTTP Serverfrom fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI(title="KASA Student Service")
students = {
1: {"id": 1, "name": "Mina", "score": 88},
2: {"id": 2, "name": "Narin", "score": 76},
}
class Student(BaseModel):
id: int
name: str
score: int
@app.get("/students")
def list_students():
return list(students.values())
@app.get("/students/{student_id}")
def get_student(student_id: int):
if student_id not in students:
raise HTTPException(status_code=404, detail="Student not found")
return students[student_id]
@app.post("/students", status_code=201)
def create_student(student: Student):
students[student.id] = student.model_dump()
return students[student.id]
@app.delete("/students/{student_id}")
def delete_student(student_id: int):
if student_id not in students:
raise HTTPException(status_code=404, detail="Student not found")
return students.pop(student_id)
print("FastAPI app ready ✓")Start Uvicorn in a daemon thread so the Colab cell can finish while the API keeps listening.
BASE_URL = http://127.0.0.1:8000 โดยอัตโนมัติ ไม่ต้อง copy URL จากที่อื่นimport threading
import time
import uvicorn
HOST = "127.0.0.1"
PORT = 8000
BASE_URL = f"http://{HOST}:{PORT}"
config = uvicorn.Config(
app,
host=HOST,
port=PORT,
log_level="warning"
)
api_server = uvicorn.Server(config)
server_thread = threading.Thread(
target=api_server.run,
daemon=True
)
server_thread.start()
# Wait briefly for the background server to start
for _ in range(20):
if api_server.started:
break
time.sleep(0.25)
print("FastAPI running ✓")
print("BASE_URL =", BASE_URL)ใช้ requests เรียก API จริงผ่าน HTTP ภายใน Colab runtime เดียวกัน
import requests
print("Using API:", BASE_URL)
# 1) GET all students
r = requests.get(f"{BASE_URL}/students", timeout=10)
print("\nGET /students")
print("Status:", r.status_code)
print("JSON :", r.json())
# 2) GET one student
r = requests.get(f"{BASE_URL}/students/1", timeout=10)
print("\nGET /students/1")
print("Status:", r.status_code)
print("JSON :", r.json())
# 3) POST new student
payload = {
"id": 3,
"name": "Kasa",
"score": 91
}
r = requests.post(
f"{BASE_URL}/students",
json=payload,
timeout=10
)
print("\nPOST /students")
print("Status:", r.status_code)
print("JSON :", r.json())
# 4) Verify student 3 exists
r = requests.get(f"{BASE_URL}/students/3", timeout=10)
print("\nGET /students/3")
print("Status:", r.status_code)
print("JSON :", r.json())
# 5) DELETE student 3
r = requests.delete(f"{BASE_URL}/students/3", timeout=10)
print("\nDELETE /students/3")
print("Status:", r.status_code)
print("JSON :", r.json())import requests
r = requests.get(
f"{BASE_URL}/students/999",
timeout=10
)
print("GET /students/999")
print("Status:", r.status_code)
print("JSON :", r.json())
# Expected:
# Status: 404
# JSON: {'detail': 'Student not found'}เพิ่ม endpoint สำหรับ update student แล้วทดสอบด้วย Client
# Challenge: add an update endpoint to the FastAPI app.
# IMPORTANT:
# After changing routes, stop the server and rerun
# the Build Service + Start Service cells.
@app.put("/students/{student_id}")
def update_student(student_id: int, student: Student):
if student_id not in students:
raise HTTPException(status_code=404, detail="Student not found")
students[student_id] = student.model_dump()
return students[student_id]payload = {
"id": 1,
"name": "Mina",
"score": 95
}
r = requests.put(
f"{BASE_URL}/students/1",
json=payload,
timeout=10
)
print("PUT /students/1")
print("Status:", r.status_code)
print("JSON :", r.json())เมื่อจบ Exercise ให้ปิด background Uvicorn server อย่างถูกต้อง
api_server.should_exit = True
server_thread.join(timeout=5)
print("FastAPI server stopped ✓")