Python 使用 FastAPI 和 PostgreSQL 构建简单 API

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 最近一年公司也在卷 LLM 的应用项目,所以我们也从 goper => Pythoner。 这一年使用最多的就是 Python 的 FastAPI 框架。下面一个简易项目让你快速玩转 Python API Web。API代表应用程序编程接口,是软件开发中最重要的概念之一。它允许程序通过发送和接收数据与其他服务进行交互。API Web 通信最广泛使用的标准之一是 REST,它依赖于JSON 格式或键值对,类似于 Python 的字典。如果想用 Python 构建一个,那么可以从几个框架中选择。Flask -RESTful、Django Rest Framework 和 FastAPI 是最受

最近一年公司也在卷 LLM 的应用项目,所以我们也从 goper => Pythoner。 这一年使用最多的就是 Python 的 FastAPI 框架。下面一个简易项目让你快速玩转 Python API Web。


API代表应用程序编程接口,是软件开发中最重要的概念之一。它允许程序通过发送和接收数据与其他服务进行交互。API Web 通信最广泛使用的标准之一是 REST,它依赖于JSON 格式或键值对,类似于 Python 的字典。


如果想用 Python 构建一个,那么可以从几个框架中选择。Flask -RESTful、Django Rest Framework 和 FastAPI 是最受欢迎的。


然而,FastAPI 专为快速 API 应用程序设计。

  • 自动文档:FastAPI 根据 OpenAPI 标准自动生成全面的文档,节省时间和精力。
  • 快捷、简便:专为高性能、高效执行而设计。
  • 数据验证FastAPI建立在 Pydantic 之上,提供了一批有用的功能,如数据验证和异步支持。


虽然Django Rest Framework在许多公司中也很常用,但让从FastAPI开始,了解它的好处。话虽如此,在简短的理论介绍之后,让我们继续编写 FastAPI 代码的第一步。

总体简介

端点

如前所述,API是不同服务和应用程序之间的一种通信方式。这种通信通常由服务器端基础设施和 API 的后端实现来促进。此后端的目的可能是提供对数据的访问,而无需直接连接到数据库,从而最大限度地减少对数据库的请求数量。

在 API 通信中,我们通常有一个指定的 URL,该端点可能在网站URL显示为/api/item/5。这种方法非常有利,因为它允许我们利用同一个URL从各种设备请求数据并接收相同的响应。

HTTP 方法

尽管我不想深入讨论理论概念,但了解使用 API 时不同方法之间的区别非常重要。让我们快速回顾一下最常用的方法:

  • GET — 用于检索数据
  • POST — 写入新数据
  • DELETE— 删除数据
  • PUT — 更新现有数据


虽然还有其他选项,但这些是我们应该从中入门的基本选项。POST 和 PUT 之间的区别很重要。两者都可用于添加数据,但 POST 用于写入新项目,而 PUT 用于使用较新的值更新现有数据。

构建你的第一个 API

运行第一个 FastAPI 服务器

首先,我们需要安装所有依赖项。至少需要将fastapi包与uvicorn服务器和一起安装pydantic。第一行应该安装所有列出的库。

pip install fastapi[all]
 pip install uvicorn
 pip install pydantic

现在,让我们使用带有必要方法和端点的装饰器创建一个基本的FastAPI应用程序。在此示例中,我们将使用 GET 方法检索数据。在本文中,我们不会讨论装饰器,因为它超出了 API 主题的范围。


在该函数之前,可能会看到下面一行代码,它负责将所有FastAPI进程添加到我们的方法中。

from fastapi import FastAPI
 
 app = FastAPI()
 
 @app.get('/') 
 def first_response():
     return {"response": "first"}

要查看响应,可以使用 uvicorn 运行服务器。默认情况下,服务器在端口 8000 上,并可通过 http://127.0.0.1:8000 访问。在开发过程中,可以使用 --reload 选项确保服务器对代码所做的任何更改都会自动重启。

uvicorn main:app
 uvicorn main:app --reload

通常我们可以使用 terminal 可以使用curl测试一下响应。

curl 127.0.0.1:8000
 #{"response": "first"}
 
 curl 127.0.0.1:8000 -X POST
 #{"detail":"Method Not Allowed"}

最后,我们可以使用 requests 库来访问我们的端点,并在 Python 中打印响应。

import requests
 
 print(requests.get('http://127.0.0.1:8000').json())
 #{'response': 'first'}

使用JSON文件中的数据

让我们继续下一步,开始处理一些实际数据。为了简化目前的情况,我们可以创建一个带有一些输入内容的 JSON 文件。


我们随便找一段 json 数据:

{
     "stocks": [
         {
             "symbol": "TSLA",
             "stockname": "Tesla Inc. Common Stock",
             "lastsale": "$235.45",
             "country": "United States",
             "ipoyear": 2010
         },
         {
             "symbol": "NVDA",
             "stockname": "NVIDIA Corporation Common Stock",
             "lastsale": "$477.76",
             "country": "United States",
             "ipoyear": 1999
         },
         {
             "symbol": "AMZN",
             "stockname": "Amazon.com Inc. Common Stock",
             "lastsale": "$146.74",
             "country": "United States",
             "ipoyear": 1997
         }
     ]
 }

现在我们可以修改我们的代码,不再检索所有项目,而是仅检索包含我们想要的特定符号的项目。也就是在后端执行过滤操作。为了实现这一点,我们执行以下操作:

  • 导入 pydantic 的模块。
  • 读取 JSON 文件并将其内容存储在字典中。
  • 使用过滤器,仅从该字典中检索所需项目。 如果未找到则引发带有 404 状态码(Not Found)的异常。


看起来很简单,但这是每个 FastAPI 应用程序的基础部分 — 模式、数据和方法。

from fastapi import FastAPI, HTTPException, Query
 from pydantic import BaseModel
 from typing import Optional
 import json
 
 app = FastAPI()
 
 class Stock(BaseModel):
     symbol: str
     stockname: str
     lastsale: str
     country: str
     ipoyear: Optional[int] = None
     
 with open('stocks.json', 'r') as f:
     stocks = json.load(f)['stocks']
 
 @app.get('/stock/{stock_symbol}', status_code=200)
 def get_stock(stock_symbol: str) -> Stock:
     stock = [stock for stock in stocks if stock['symbol'] == stock_symbol]
     if len(stock) == 0:
         raise HTTPException(
             status_code=404, detail=f"No stock {stock_symbol} found."
          )
 
     return stock[0]

当然,现在我们需要更改获数据请求的 url。

import requests
 
 print(requests.get('http://127.0.0.1:8000/stock/AMZN').json())

如上面所述,我们的文档现在应该是可用的。可以通过在浏览器的地址栏中输入http://127.0.0.1:8000/docs 来访问它。


FastAPI 内置了 OpenAPI 的文档系统,可基于我们的代码生成标准 API 文档。


随着我们继续添加更多方法,可以轻松地导航到同一位置找到它们所有。这份文档对刚开始使用 API 的人尤其有帮助。

在我们的代码中确定了 Pydantic 模型之后,现在我们可以确定输出响应的模式。这也是更好地理解各种 API 方法及其返回内容的一个更好的方式。

链接 Postgres 数据库

过去,我们只使用本地文件。然而,在大多数情况下将需要在后端使用数据库。为了实现这一点,我们将连接PostgreSQL数据库,并尝试在我们的GET方法中使用它。这是一个简单的SELECT语句。但是我们需要正确识别所有内容以供FastAPI使用。


这个过程涉及到 SQLAlchem 库,它是 Python 中最流行的用于对象关系映射(ORM)操作的包之一。


为了将数据存储在单独的文件中,创建一个名为config.py的文件,并添加以下代码。下面是示例代码:

from pydantic_settings import BaseSettings
class Settings(BaseSettings):
    sqlalchemy_string: str = "postgresql://user:passwordp@host/db"
    
settings = Settings()

让我们通过将这部分内容结构化到 database.py 文件中来创建引擎并为 FastAPI 会话准备数据库。我们使用 config.py 文件中的设置。

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from config import settings
engine = create_engine(
    settings.sqlalchemy_string, connect_args={'sslmode':'require'}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

接下来,我们需要将模型与数据库中相关的表格进行关联。我们具体处理数据的表格,并且将为其使用一个简单的模型。我们会使用基本模型。

from sqlalchemy import Column, Integer, String, Float, BigInteger
from database import Base
class Stock(Base):
    __tablename__ = "nasdaq_stocks"
    
    symbol = Column(String, primary_key=True)
    stockname = Column(String)
    lastsale = Column(String)
    netchange = Column(Float)
    percentchange = Column(String)
    marketcap = Column(BigInteger)
    country = Column(String, nullable=True)
    ipoyear = Column(Integer, nullable=True)
    volume = Column(Integer)
    sector = Column(String, nullable=True)
    industry = Column(String, nullable=True)

我们将 Pydantic 模型存储在单独的文件中。让我们将文件命名为 schemas.py,并在其中添加相关模型。正确配置 orm_mode,因为我们正在使用 SQLAlchemy 数据库。

from pydantic import BaseModel
from typing import Optional
class StockBase(BaseModel):
    symbol: str
    stockname: str
    lastsale: str
    country: str
    ipoyear: Optional[int] = None
    volume: int
    
class StockCreate(StockBase):
    pass
class Stock(StockBase):
    
    class Config:
        orm_mode = True

我们必须在数据库指定 CRUD(Create, Read, Update, Delete) 操作的代码。以后在主脚本中仅使用 FastAPI 应用程序中的函数会更方便。 对于我们基本的 GET 方法,仅需要通过符号进行简单的过滤查询即可, 下面是一个最基础的 crud.py 文件示例。

from sqlalchemy.orm import Session
import models, schemas
def get_stock(db: Session, symbol: str):
    return db.query(models.Stock).filter(models.Stock.symbol == symbol).first()

我们已经完成了实现 API 所需的所有准备工作。由于正在操作数据库,需要在脚本中包含一些额外的细节。


get_db 函数负责与数据库建立连接,并已将其包含在 Depends FastAPI 类中。下面是可运行代码的最终示例。

from fastapi import FastAPI, HTTPException, Query, Depends
from sqlalchemy.orm import Session
import crud, models, schemas
from database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI(
    title="NASDAQ stocks",
    description="Start using FastAPI in development",
    version="0.1"
)
# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close() 
@app.get('/stock/{symbol}', response_model=schemas.Stock, status_code=200)
def get_stock(symbol: str, db: Session = Depends(get_db)) -> models.Stock:
    db_stock = crud.get_stock(db, symbol=symbol)
    if db_stock is None:
        raise HTTPException(
            status_code=404, detail=f"No stock {symbol} found."
        )
    return db_stock

虽然没有明显变化,但我们现在可以搜索整个数据库,而不仅仅是来自 JSON 文件中的数据。修改输出也很简单,因为我们可以在 Pydantic 模型中添加或删除字段。

import requests
print(requests.get('http://127.0.0.1:8000/stock/AAL').json())

ORM 与市场上提供的各种数据库选项无缝配合,实现高效集成不需要进行任何修改。可以参考关于如何在 FastAPI 中使用 SQL 数据库的相关文档。

总结

在本文中,我们描述了 FastAPI 及其简化 REST API 实现的能力。 与其他有用的 Python 依赖项一起,FastAPI 提供许多必要的功能:

  • Pydantic 使用Pydantic 对数据进行验证。
  • SQLAlchemy 使用SQLAlchemy ORM 对数据进行数据库操作。


FastAPI 不仅局限于使用 GET 方法返回数据作为响应。它提供了完整的 REST API 功能,包括POST、PUT 和 DELETE 等其他有价值的方法。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
1天前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
15 3
|
6天前
|
JSON API 数据库
使用Python和Flask构建简单的RESTful API
使用Python和Flask构建简单的RESTful API
13 6
|
6天前
|
Python
使用Python和Flask构建简单的Web应用
使用Python和Flask构建简单的Web应用
18 6
|
6天前
|
数据可视化 数据处理 开发者
构建高效的数据流图:Python与PyGraphviz的实践
【9月更文挑战第13天】在本文中,我们将探索如何利用Python和PyGraphviz库来创建和操作数据流图。我们将通过一个具体示例,展示如何从零开始构建一张数据流图,并讨论如何优化图表以提高可读性。文章旨在为初学者提供一个清晰的入门指南,同时为有经验的开发者提供一些高级技巧。
|
8天前
|
消息中间件 Kafka 数据安全/隐私保护
Python IPC实战指南:构建高效稳定的进程间通信桥梁
【9月更文挑战第11天】在软件开发中,随着应用复杂度的提升,进程间通信(IPC)成为构建高效系统的关键。本文通过一个分布式日志处理系统的案例,介绍如何使用Python和套接字实现可靠的IPC。案例涉及定义通信协议、实现日志发送与接收,并提供示例代码。通过本教程,你将学会构建高效的IPC桥梁,并了解如何根据需求选择合适的IPC机制,确保系统的稳定性和安全性。
24 5
|
11天前
|
JSON 安全 数据安全/隐私保护
实战指南:Python中OAuth与JWT的完美结合,构建安全认证防线
【9月更文挑战第9天】当今互联网应用的安全性至关重要,尤其在处理用户数据和个人隐私时。OAuth 和 JWT 是两种广泛使用的认证机制,各具优势。本文探讨如何在 Python 中结合 OAuth 和 JSON Web Tokens (JWT) 构建安全可靠的认证系统。OAuth 允许第三方应用获取有限访问权限而不暴露用户密码;JWT 则是一种轻量级数据交换格式,用于安全传输信息。结合使用这两种技术,可以在确保安全性的同时简化认证流程。
11 4
|
8天前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【9月更文挑战第11天】在数字时代,数据安全至关重要。AES与RSA加密技术相结合,构成了一道坚固防线。AES以其高效性保障数据加密,而RSA则确保密钥安全传输,二者相辅相成,提供双重保护。本文通过Python代码示例展示了这一加密方案的魅力,强调了其在实际应用中的重要性和安全性。使用HTTPS等安全协议传输加密密钥和密文,确保数据在数字世界中自由流通而无忧。
19 1
|
10天前
|
数据采集 JavaScript 前端开发
构建你的首个Python网络爬虫
【9月更文挑战第8天】本文将引导你从零开始,一步步构建属于自己的Python网络爬虫。我们将通过实际的代码示例和详细的步骤解释,让你理解网络爬虫的工作原理,并学会如何使用Python编写简单的网络爬虫。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开网络数据获取的新世界。
|
14天前
|
算法 程序员 Linux
Python编程入门:构建你的第一个程序
【9月更文挑战第4天】编程是现代技术发展的基石,而Python作为一门简洁、易学且功能强大的编程语言,已成为众多初学者的首选。本文将引导你通过一个简单的Python程序,探索编程世界的奥秘,并了解如何利用Python实现基本的算法逻辑。无论你是完全的新手还是希望巩固基础的开发者,这篇文章都将为你提供一个清晰的学习路径。从安装Python环境开始,到编写第一个程序,我们将一步步揭开编程的神秘面纱。
|
19天前
|
数据采集 JavaScript 前端开发
构建简易Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字信息的时代,数据抓取成为获取网络资源的重要手段。本文将引导你通过Python编写一个简单的网页爬虫,从零基础到实现数据抓取的全过程。我们将一起探索如何利用Python的requests库进行网络请求,使用BeautifulSoup库解析HTML文档,并最终提取出有价值的数据。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开数据抓取的大门。