Skip to content

NimTechnology

Trình bày các công nghệ CLOUD một cách dễ hiểu.

  • Kubernetes & Container
    • Docker
    • Kubernetes
      • Ingress
      • Pod
    • Helm Chart
    • OAuth2 Proxy
    • Isito-EnvoyFilter
    • Apache Kafka
      • Kafka
      • Kafka Connect
      • Lenses
    • Vault
    • Longhorn – Storage
    • VictoriaMetrics
    • MetalLB
    • Kong Gateway
  • CI/CD
    • ArgoCD
    • ArgoWorkflows
    • Argo Events
    • Spinnaker
    • Jenkins
    • Harbor
    • TeamCity
    • Git
      • Bitbucket
  • Coding
    • DevSecOps
    • Terraform
      • GCP – Google Cloud
      • AWS – Amazon Web Service
      • Azure Cloud
    • Golang
    • Laravel
    • Python
    • Jquery & JavaScript
    • Selenium
  • Log, Monitor & Tracing
    • DataDog
    • Prometheus
    • Grafana
    • ELK
      • Kibana
      • Logstash
  • BareMetal
    • NextCloud
  • Toggle search form

[Python] Look into FastAPI to contribute backend by Python

Posted on September 3, 2023September 3, 2023 By nim No Comments on [Python] Look into FastAPI to contribute backend by Python

Contents

Toggle
  • 1) Define Function in Python.
  • 2) Validate data type in python via Pydantic library.
  • 3) Design backend for restful API on Python.
    • 3.1) Get method with Path URL.
    • 3.2) Get method with query URL.
    • 3.3) Design Post method.
  • 4) Decrease values when responding.

1) Define Function in Python.

Sau đây chúng ta define 1 function trong python.

def my_func(my_var : str | None = None):
    return my_var

var_1 = 10
var_2 = "10"

print(my_func())

Trong đoạn mã Python trên, hàm my_func có một đối số có tên là my_var có kiểu dữ liệu được ghi là str | None. Đây là kiểu gợi ý cho Python biết đối số my_var có thể là một chuỗi (str) hoặc là None. Kiểu gợi ý này không buộc người lập trình phải truyền một chuỗi hay None, nhưng nó giúp làm rõ mục tiêu của hàm và có thể hỗ trợ trong việc kiểm tra kiểu.

None = None có nghĩa là giá trị mặc định của my_var là None. Khi bạn gọi my_func() mà không truyền bất kỳ đối số nào, my_var sẽ tự động được gán là None.

Đoạn mã sau:
print(my_func())

sẽ in ra None, vì bạn đã gọi hàm mà không truyền giá trị cho my_var, nên giá trị mặc định None sẽ được sử dụng.

Các biến var_1 và var_2 không được sử dụng trong đoạn mã trên, nhưng bạn có thể sử dụng chúng bằng cách truyền vào hàm my_func nếu muốn. Tuy nhiên, hãy chú ý rằng var_1 có kiểu dữ liệu là int, nên nó sẽ không phù hợp với kiểu gợi ý của đối số my_var.

2) Validate data type in python via Pydantic library.

from pydantic import BaseModel
from datetime import datetime

class Vietnamese(BaseModel):
    id: int
    name: str
    birthday: datetime

vietname_1_data = {"name": "Tran Tuan Dung", "id": 100, "birthday": "2009-12-25 00:00" }

vietnam_1 = Vietnamese(**vietname_1_data)

print(vietnam_1)

Đoạn mã Python trên sử dụng thư viện Pydantic để định nghĩa một mô hình dữ liệu có tên là Vietnamese. Pydantic giúp bạn định rõ kiểu dữ liệu và hệ thống sẽ tự động kiểm tra (validate) dữ liệu đầu vào để đảm bảo rằng nó phù hợp với kiểu dữ liệu đã định.

Cụ thể trong trường hợp này, mô hình Vietnamese có ba trường:

  1. id: kiểu int – số nguyên, là ID của người.
  2. name: kiểu str – chuỗi, là tên của người.
  3. birthday: kiểu datetime – thời gian, là ngày sinh của người.

Khi bạn tạo một đối tượng mới bằng cách sử dụng Vietnamese(**vietname_1_data), Pydantic sẽ tự động kiểm tra xem liệu dữ liệu trong từ điển vietname_1_data có phù hợp với kiểu dữ liệu đã định trong Vietnamese hay không.

Trong trường hợp này:

  • id: 100 là một số nguyên (int) nên không có vấn đề.
  • name: “Tran Tuan Dung” là một chuỗi (str), cũng không có vấn đề.
  • birthday: “2009-12-25 00:00” là một chuỗi, nhưng Pydantic sẽ cố gắng tự động chuyển đổi nó thành một đối tượng datetime nếu có thể.

Nếu toàn bộ dữ liệu được kiểm tra (validate) thành công, đối tượng vietnam_1 sẽ được tạo và bạn có thể sử dụng nó như một đối tượng Python thông thường.

Nếu có bất kỳ trường nào không phù hợp với kiểu dữ liệu đã định, Pydantic sẽ ném ra một ngoại lệ để thông báo vấn đề.

3) Design backend for restful API on Python.

3.1) Get method with Path URL.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}/action/{action_id}")
def read_item(item_id: str, action_id: str):
    return {"item" : item_id, "action": action_id}

Ứng dụng này có một điểm đầu (endpoint) được định nghĩa thông qua decorator @app.get.

  1. app = FastAPI(): Khởi tạo một đối tượng FastAPI.
  2. @app.get("/items/{item_id}/action/{action_id}"): Định nghĩa một HTTP GET request tới URL có dạng /items/{item_id}/action/{action_id}. Trong URL này, {item_id} và {action_id} là các tham số động, có nghĩa là giá trị của chúng có thể thay đổi.
  3. def read_item(item_id: str, action_id: str): Định nghĩa hàm read_item với hai tham số item_id và action_id, cả hai đều có kiểu là str.

Khi bạn gửi một GET request đến URL như /items/123/action/abc, FastAPI sẽ tự động trích xuất 123 và abc từ URL, sau đó truyền chúng như là đối số cho hàm read_item. Hàm này sẽ trả lại một từ điển JSON chứa item_id và action_id mà bạn đã cung cấp.

Ví dụ, nếu bạn gửi một GET request đến /items/123/action/abc, ứng dụng sẽ trả lại JSON có dạng:

giờ kiểm tra bằng lệnh curl:

openvscode-server@openvscode-server-c48986987-qz8q4:~/learn-python$ curl localhost:8000/items/123/action/abc
{"item":"123","action":"abc"}

3.2) Get method with query URL.

from fastapi import FastAPI

app = FastAPI()
data = [0, 1, 2, 3, 4, 5]

@app.get("/items")
def get_data(limit: int | None = 3):
    return data[0:limit]

Đoạn mã này sử dụng thư viện FastAPI để tạo một ứng dụng web API đơn giản với một điểm đầu (endpoint) HTTP GET tại URL /items.

  1. app = FastAPI(): Khởi tạo một đối tượng FastAPI.
  2. data = [0, 1, 2, 3, 4, 5]: Định nghĩa một danh sách data chứa các số từ 0 đến 5.
  3. @app.get("/items"): Định nghĩa một HTTP GET request tới URL /items.
  4. def get_data(limit: int | None = 3): Hàm get_data có tham số limit với kiểu dữ liệu là int | None và giá trị mặc định là 3.

Khi bạn gửi một GET request đến /items, FastAPI sẽ gọi hàm get_data và trả lại một phần của danh sách data từ phần tử đầu tiên đến phần tử thứ limit.

Nếu bạn không cung cấp tham số limit khi gọi API (ví dụ, bạn chỉ gửi GET request đến /items), giá trị mặc định của limit là 3, và API sẽ trả lại [0, 1, 2].

Thường bạn sẽ thấy là có dấu chấm hỏi xuất hiện “?”

Nếu bạn cung cấp tham số limit (ví dụ, GET /items?limit=4), thì API sẽ trả lại [0, 1, 2, 3].

from fastapi import FastAPI
from pydantic import BaseModel


app = FastAPI()

class User(BaseModel):
    username: str
    password: str
    fullname: str



@app.post("/users/register")
def user_register(user: User):
    return user

3.3) Design Post method.

openvscode-server@openvscode-server-c48986987-qz8q4:~/learn-python$ curl -X 'POST' \
  'http://127.0.0.1:8000/users/register' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "your_username",
  "password": "your_password",
  "fullname": "Your Full Name"
}'
{"username":"your_username","password":"your_password","fullname":"Your Full Name"}

Trong lệnh này:

  • -X 'POST': Định nghĩa phương thức HTTP là POST.
  • http://127.0.0.1:8000/users/register: Địa chỉ của điểm đầu.
  • -H 'accept: application/json': Đặt header “accept” để chỉ định rằng chúng ta muốn nhận dữ liệu trả về dưới dạng JSON.
  • -H 'Content-Type: application/json': Đặt header “Content-Type” để chỉ định rằng dữ liệu gửi đi là JSON.
  • -d '{...}': Dữ liệu JSON được gửi trong body của request. Bạn cần thay thế your_username, your_password, và Your Full Name bằng các giá trị thực tế bạn muốn sử dụng.

Chú ý: Đảm bảo rằng ứng dụng FastAPI của bạn đang chạy và lắng nghe tại http://127.0.0.1:8000/ trước khi bạn chạy lệnh curl.

4) Decrease values when responding.

Cách đâu tiên là bạn khai báo 1 model trả về và sử dụng model đó cho response

from fastapi import FastAPI, Response, status
from pydantic import BaseModel
from pprint import pprint


app = FastAPI()

class User(BaseModel):
    username: str
    password: str
    fullname: str

class UserLogin(BaseModel):
    username: str
    password: str

class UserOut(BaseModel):
    username: str
    fullname: str

users = {}



@app.post("/users/register", response_model=UserOut)
def user_register(user: User):
    user_dict = user.dict() #convert to dictionary
    users[user_dict["username"]] = user_dict
    return user_dict

@app.get("/users")
async def user_list():
    return users


@app.get("/users/{username}")
async def user_get(username: str):
    try:
        found_user = users[username]
        return found_user
    except KeyError:
        return {"message": "username not found"}

@app.post("/users/login")
async def user_login(credetinal: UserLogin):
    data = credetinal.dict()
    _user_name = data["username"]
    pprint(users)
    pprint(_user_name)
    if _user_name in users:
        if users[_user_name]["password"] == data["password"]:
            return {"message": "Login Success"}
    else:
        return   {"message": "Forbidden"}

Trong ví dụ của bạn, response_model=UserOut chỉ định rằng dữ liệu trả về từ API endpoint /users/register sẽ tuân theo cấu trúc được định nghĩa trong lớp Pydantic UserOut. Model UserOut có các trường username và fullname, nghĩa là, dù trong users dictionary có thêm trường password, nó sẽ không được trả về trong phản hồi HTTP, giúp bảo mật thông tin của người dùng.

Thứ 2 là bạn sài response_model cài model cũ, response_model_exclude được sử dụng để remove các values khi response.

from fastapi import FastAPI, Response, status
from pydantic import BaseModel
from pprint import pprint


app = FastAPI()

class User(BaseModel):
    username: str
    password: str
    fullname: str

class UserLogin(BaseModel):
    username: str
    password: str

class UserOut(BaseModel):
    username: str
    fullname: str

users = {}



@app.post("/users/register", response_model=User, response_model_exclude={"password"})
def user_register(user: User, response: Response):
    user_dict = user.dict() #convert to dictionary
    users[user_dict["username"]] = user_dict
    response.status_code = status.HTTP_201_CREATED ## Hoặc để là 201
    return user_dict

Một điều cần thiết là trả về status code.

Trong FastAPI, bạn có thể sử dụng tham số response: Response để truy cập và chỉnh sửa đối tượng phản hồi HTTP một cách trực tiếp. Đối tượng Response cho phép bạn tùy chỉnh các thuộc tính của phản hồi, bao gồm status code, headers, cookies, và nhiều thuộc tính khác.

  1. response: Response: Trong ví dụ của bạn, response: Response là một tham số của hàm user_register. Tham số này cho phép bạn tương tác với đối tượng phản hồi HTTP một cách trực tiếp.
  2. response.status_code = status.HTTP_201_CREATED: Ở đây, bạn đặt status code của đối tượng phản hồi là 201, tức là “Created”. Status code này là một quy ước trong RESTful APIs để thông báo rằng một nguồn tài nguyên mới đã được tạo thành công trên máy chủ.
    • status.HTTP_201_CREATED là chỉ một cách tiện lợi để đề cập đến số 201, giúp làm cho mã của bạn dễ đọc và hiểu hơn. Bạn cũng có thể đặt response.status_code = 201 nếu bạn muốn.

Khi bạn đặt response.status_code, người dùng gửi yêu cầu đến endpoint này sẽ nhận được phản hồi với status code 201, cho họ biết rằng tài nguyên đã được tạo thành công.

Python

Post navigation

Previous Post: [DevSecOps] Engines for Pentesters
Next Post: How to join labels of 2 different metrics on PromQL

More Related Articles

[Python] The eval() function automatically calculates a string Python
[Python] OOP Python
[Python] Look into “for else” Python
[Python] use Try/Except in python Python
[Python] Python connects MongoDB Python
[Python] what mean if __name__==”__main__”: Python

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tham Gia Group DevOps nhé!
Để Nim có nhiều động lực ra nhiều bài viết.
Để nhận được những thông báo mới nhất.

Recent Posts

  • [AWS/EKS] Cache Docker image to accelerate EKS container deployment. July 10, 2025
  • [Laravel] Laravel Helpful June 26, 2025
  • [VScode] Hướng dẫn điều chỉnh font cho terminal June 20, 2025
  • [WordPress] Hướng dấn gửi mail trên WordPress thông qua gmail. June 15, 2025
  • [Bitbucket] Git Clone/Pull/Push with Bitbucket through API Token. June 12, 2025

Archives

  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • June 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021

Categories

  • BareMetal
    • NextCloud
  • CI/CD
    • Argo Events
    • ArgoCD
    • ArgoWorkflows
    • Git
      • Bitbucket
    • Harbor
    • Jenkins
    • Spinnaker
    • TeamCity
  • Coding
    • DevSecOps
    • Golang
    • Jquery & JavaScript
    • Laravel
    • NextJS 14 & ReactJS & Type Script
    • Python
    • Selenium
    • Terraform
      • AWS – Amazon Web Service
      • Azure Cloud
      • GCP – Google Cloud
  • Kubernetes & Container
    • Apache Kafka
      • Kafka
      • Kafka Connect
      • Lenses
    • Docker
    • Helm Chart
    • Isito-EnvoyFilter
    • Kong Gateway
    • Kubernetes
      • Ingress
      • Pod
    • Longhorn – Storage
    • MetalLB
    • OAuth2 Proxy
    • Vault
    • VictoriaMetrics
  • Log, Monitor & Tracing
    • DataDog
    • ELK
      • Kibana
      • Logstash
    • Fluent
    • Grafana
    • Prometheus
  • Uncategorized
  • Admin

Copyright © 2025 NimTechnology.