Python小酷庫系列:pyNest,把FastAPI程序寫出Spring的味道

pyNest,把FastAPI程序寫出Spring的風格

    • 快速入門
      • 1、安裝pyNest
      • 2、創建項目
      • 3、編寫app_module.py
      • 4、編寫app_service.py
      • 5、編寫app_controller.py
      • 6、編寫main.py
      • 7、啟動程序
    • 核心概念
      • 1、Modules
      • 2、Controllers
      • 3、Providers
      • 4、ORM Provider

NestJS是風靡于Node.js圈的web框架,它深度借鑒了Spring Boot的設計思路,但又比Spring Boot小巧靈活。
對于轉戰于python圈的小伙伴來說,如果可以把Spring Boot搬運到python,那將是一件非常有價值的事情,于是就有了pyNest這個“小酷庫”——它站在FastAPI的基礎,在python中實現了NestJS風格,讓你的代碼有了Spring的味道。本文我們就一起來試試pyNest這個“小酷庫”。

快速入門

1、安裝pyNest

pip install pynest-api

2、創建項目

my_pynest_project/
├── src/
│   ├── __init__.py
│   ├── app_module.py
│   ├── app_controller.py
│   ├── app_service.py
├── main.py
├── requirements.txt
└── README.md

3、編寫app_module.py

from nest.core import Module, PyNestFactory
from .app_controller import AppController
from .app_service import AppService@Module(controllers=[AppController],providers=[AppService],
)
class AppModule:passapp = PyNestFactory.create(AppModule,description="This is my PyNest app",title="My App",version="1.0.0",debug=True,
)http_server = app.get_server()

4、編寫app_service.py

from nest.core import Injectable@Injectable
class AppService:def __init__(self):self.app_name = "MyApp"self.app_version = "1.0.0"def get_app_info(self):return {"app_name": self.app_name, "app_version": self.app_version}

5、編寫app_controller.py

from nest.core import Controller, Get
from .app_service import AppService@Controller("/")
class AppController:def __init__(self, service: AppService):self.service = service@Get("/")def get_app_info(self):return self.service.get_app_info()

6、編寫main.py

import uvicorn
from src.app_module import http_serverif __name__ == "__main__":uvicorn.run(http_server, host="0.0.0.0", port=8000, reload=True)

7、啟動程序

python main.py

核心概念

PyNest 主要包括Modules、Controllers、Providers三個核心概念,其中:

  • Module負責組織和管理 ControllerProvider
  • Controller 負責接收請求,調用注入的 Provider 來完成業務邏輯
  • Provider服務/工具,也可以互相注入組合;
  • 模塊之間通過 imports/exports 連接起來,實現模塊解耦和共享。

它們的關系如下圖:

Product
Order
User
Exports
Imports
Exports
Imports
ProductController
ProductModule
ProductService
OrderController
OrderModule
OrderService
AuthController
UserModule
UserController
UserService
AuthService
HTTP Request
FastAPI APP

1、Modules

模塊(Modules)是一個帶有@Module()裝飾器注解的類。@Module()裝飾器提供 PyNest 用于組織應用程序結構的元數據。
在pyNest中,每個應用程序至少有一個模塊,即根模塊。根模塊是 PyNest 構建應用程序圖的起點,而應用程序圖是 PyNest 用于解析模塊和提供程序關系及依賴關系的內部數據結構。雖然非常小的應用程序理論上可能只有一個根模塊,但這并不是典型情況。強烈建議使用模塊作為組織組件的有效方法。
模塊定義了以下元數據:

  • controllers:控制器列表
  • providers:服務提供者(通常是業務邏輯)
  • imports:導入其他模塊
  • exports:暴露自己的部分 provider 給其他模塊使用

2、Controllers

控制器(Controllers )是一個帶有@Controller() 裝飾器注解的類。該類負責處理傳入的請求并向客戶端返回響應。控制器在應用程序中注冊路由并管理請求和響應對象,有效地充當客戶端與應用程序交互的網關。
pyNest 支持 5 種 http 方法——Get、Post、Put、Delete、Patch。由于 Pynest 是 FastAPI 的抽象,因此我們可以像在 FastAPI 中一樣使用這些方法。
以下為一個完整的 CRUD 示例:

from nest.core import Controller, Get, Post, Put, Delete
from .book_service import BookService
from .book_models import Book@Controller('/books')
class BooksController:def __init__(self, book_service: BookService):self.book_service = book_service@Get('/')def get_books(self):return self.book_service.get_books()@Get('/:book_id')def get_book(self, book_id: int):return self.book_service.get_book(book_id)@Post('/')def add_book(self, book: Book):return self.book_service.add_book(book)@Put('/:book_id')def update_book(self, book_id: int , book: Book):return self.book_service.update_book(book_id, book)@Delete('/:book_id')def delete_book(self, book_id: int):return self.book_service.delete_book(book_id)

3、Providers

服務(Providers),是一個帶有@Injectable裝飾器注解的類,是 PyNest 應用程序的基礎。它們處理業務邏輯和其他功能,充當可注入到其他組件(例如控制器)的依賴項。本指南通過各種示例講解了什么是提供程序、如何使用它們、如何在模塊中導入和導出它們,以及如何將它們注入到控制器和其他服務中。
定義Provider

from nest.core import Injectable@Injectable
class LoggerService:def log(self, message: str):print(f"LOG: {message}")

在例子中,LoggerService使用@Injectable裝飾器將類定義為提供程序。現在可以將此類注入到同一模塊內的其他類中,或將其導出以供其他模塊使用。

在模塊中注冊Provider

from nest.core import Module
from .s3_service import S3Service
from src.providers.logger.logger_service import LoggerService
from src.providers.logger.logger_module import LoggerModule@Module(providers=[S3Service, LoggerService],exports=[S3Service],imports=[LoggerModule],
)
class S3Module:pass

在例子中:S3Module 定義了一個提供 S3Service 的模塊,并將其導出以供其他模塊使用。它還導入了 LoggerModule 以使用 LoggerService。

將Provider注入Controller

from nest.core import Controller, Post
from .s3_service import S3Service@Controller('/s3')
class S3Controller:def __init__(self, s3_service: S3Service):self.s3_service = s3_service@Post('/upload')def upload_file(self, file_name: str):self.s3_service.upload_file(file_name)return {"message": "File uploaded successfully!"}

在這個例子中,S3Service通過構造函數注入到了S3Controller中。

將Provider注入其他Provider

from nest.core import Injectable
from src.providers.logger.logger_service import LoggerService@Injectable
class S3Service:def __init__(self, logger_service: LoggerService):self.logger_service = logger_servicedef upload_file(self, file_name: str):print(f"Uploading {file_name}")self.logger_service.log(f"Uploaded file: {file_name}")

4、ORM Provider

pyNest內置了基于SQLAlchemy的數據庫連接組件,它包括了OrmProvider( 同步)、AsyncOrmProvider( 異步)兩個服務。
以下是AsyncOrmProvider的使用示例:
config.py

from nest.core.database.orm_provider import AsyncOrmProvider
import os
from dotenv import load_dotenvload_dotenv()config = AsyncOrmProvider(db_type="postgresql",config_params=dict(host=os.getenv("POSTGRESQL_HOST", "localhost"),db_name=os.getenv("POSTGRESQL_DB_NAME", "default_nest_db"),user=os.getenv("POSTGRESQL_USER", "postgres"),password=os.getenv("POSTGRESQL_PASSWORD", "postgres"),port=int(os.getenv("POSTGRESQL_PORT", 5432)),)
)

app_schema.py

from src.config import config
from sqlalchemy import Integer, String
from sqlalchemy.orm import Mapped, mapped_columnclass Example(config.Base):__tablename__ = "example"id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)name: Mapped[str] = mapped_column(String, unique=True)

app_service.py

from .examples_model import Examples
from .examples_entity import Examples as ExamplesEntity
from src.config import config
from nest.core.decorators.database import async_db_request_handler
from nest.core import Injectable
from sqlalchemy import select@Injectable
class ExamplesService:def __init__(self):self.orm_config = configself.session = self.orm_config.get_session@async_db_request_handlerasync def add_examples(self, examples: Examples):examples_entity = ExamplesEntity(**examples.dict())async with self.session() as session:session.add(examples_entity)await session.commit()return examples_entity.id@async_db_request_handlerasync def get_examples(self):query = select(ExamplesEntity)async with self.session() as session:result = await session.execute(query)return result.scalars().all()

app_controller.py

from nest.core import Controller, Get, Postfrom .examples_service import ExamplesService
from .examples_model import Examples@Controller("examples")
class ExamplesController:def __init__(self, service: ExamplesService):self.service = service@Get("/")async def get_examples(self):return await self.service.get_examples()@Post("/")async def add_examples(self, examples: Examples):return await self.service.add_examples(examples)

app_module.py

from .config import config
from .example.example_module import ExampleModulefrom .app_controller import AppController
from .app_service import AppServicefrom nest.core import Module, PyNestFactory@Module(imports=[ExampleModule],controllers=[AppController],providers=[AppService],
)
class AppModule:passapp = PyNestFactory.create(AppModule, description="This is my FastAPI app drive by Async ORM Engine", title="My App",version="1.0.0", debug=True)http_server = app.get_server()@http_server.on_event("startup")
async def startup():await config.create_all()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77660.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77660.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77660.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML 詳解:從基礎結構到語義標簽

目錄 一、HTML 是什么&#xff1f;二、HTML 的基本結構? 簡要說明&#xff1a; 三、常見 HTML 標簽講解3.1 標題標簽 <h1> ~ <h6>3.2 段落和換行3.3 超鏈接3.4 圖像插入3.5 列表無序列表&#xff1a;有序列表&#xff1a; 3.6 表格結構 四、HTML 語義化標簽詳解五…

用Python做有趣的AI項目 6:AI音樂生成器(LSTM Melody Generator)

&#x1f3b5; 項目名稱&#xff1a;AI音樂生成器&#xff08;LSTM Melody Generator&#xff09; &#x1f9e0; 項目簡介 這個項目的目標是&#xff1a;用 AI 來自動生成簡單的旋律&#xff08;MIDI格式&#xff09;&#xff0c;類似于基礎的鋼琴曲、背景音樂片段。 我們使…

【運維】利用任務計劃程序定時重啟 nssm 服務 | Windows 服務每日定時維護實踐

&#x1f680; 利用任務計劃程序定時重啟 nssm 服務 | Windows 服務每日定時維護實踐 一、前言 在 Windows 系統中&#xff0c;nssm&#xff08;Non-Sucking Service Manager&#xff09; 是一個非常好用的工具&#xff0c;可以將任意可執行程序注冊為系統服務。很多運維場景…

MATLAB小試牛刀系列(1)

問題描述 某機床廠生產甲、乙兩種機床&#xff0c;每臺機床銷售后的利潤分別為 4 千元與 3 千元。生產甲機床需用 A、B 機器加工&#xff0c;加工時間分別為每臺 2h 和每臺 1h&#xff1b;生產乙機床需用 A、B、C 三種機器加工&#xff0c;加工時間均為每臺 1h。若每天可用于加…

云原生周刊:Kubernetes v1.33 正式發布

開源項目推薦 Robusta Robusta 是一個開源的 K8s 可觀測性與自動化平臺&#xff0c;旨在增強 Prometheus 告警的智能化處理能力。它通過規則和 AI 技術對告警進行豐富化處理&#xff0c;自動附加相關的 Pod 日志、圖表和可能的修復建議&#xff0c;支持智能分組、自動修復和高…

React速通筆記

相關視頻&#xff1a; 黑馬程序員前端React18入門到實戰視頻教程&#xff0c;從reacthooks核心基礎到企業級項目開發實戰&#xff08;B站評論、極客園項目等&#xff09;及大廠面試全通關_嗶哩嗶哩_bilibili 一、React介紹 React由Meta公司開發&#xff0c;是一個用于 構建W…

人工智能與機器學習:Python從零實現K-Means 算法

&#x1f9e0; 向所有學習者致敬&#xff01; “學習不是裝滿一桶水&#xff0c;而是點燃一把火。” —— 葉芝 我的博客主頁&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 歡迎點擊加入AI人工智能社區&#xff01; &#x1f680; 讓我們一起努力&#xff0c;共創…

【神經網絡與深度學習】訓練集與驗證集的功能解析與差異探究

引言 在深度學習模型的訓練過程中&#xff0c;訓練集和驗證集是兩個關鍵組成部分&#xff0c;它們在模型性能的提升和評估中扮演著不可替代的角色。通過分析這兩者的區別和作用&#xff0c;可以幫助我們深入理解模型的學習過程和泛化能力&#xff0c;同時為防止過擬合及優化超…

Macos m系列芯片環境下python3安裝mysqlclient系列問題

最近學習python3&#xff0c;在安裝mysqlclient的時候遇到了一些問題&#xff0c;直接使用哦pip install mysqlclient 直接報錯了&#xff0c;記錄一下解決方案。 環境信息 設備&#xff1a;Macbook Pro m1 系統&#xff1a;macos Sequoia 15.3.2 最終成功的python版本&#xf…

微信小程序-van-uploader的preview-size

preview-size支持數組格式 修改前修改后1、升級微信小程序里面的van版本:2、 重新構建npm3、重啟微信開發工具 修改前 引用van組件的上傳文件&#xff0c;設置預覽圖尺寸&#xff0c;剛開始設置的是preview-size“140”&#xff0c;出來的效果就是一個正方形。 修改后 1、升級…

2. 第一個網頁:前端基礎入門

第一個網頁&#xff1a;前端基礎入門 一、網頁文件基礎認知 1. 文件擴展名 .htm 或 .html 均為網頁文件后綴&#xff0c;二者功能完全一致擴展名隱藏方法 系統設置 → 文件夾選項 → 查看 → 取消勾選「隱藏已知文件類型的擴展名」 二、前端發展簡史 1. 瀏覽器戰爭與標準混…

云原生--核心組件-容器篇-7-Docker私有鏡像倉庫--Harbor

1、Harbor的定義與核心作用 定義&#xff1a; Harbor是由VMware開源的企業級容器鏡像倉庫系統&#xff0c;后捐贈給 CNCF (Cloud Native Computing Foundation)。它基于Docker Registry擴展了企業級功能&#xff0c;用于存儲、分發和管理容器鏡像&#xff08;如Docker、OCI標準…

Java項目與技術棧場景題深度解析

Java項目與技術棧場景題深度解析 在互聯網大廠Java求職者的面試中&#xff0c;經常會被問到關于Java項目或技術棧的場景題。本文通過一個故事場景來展示這些問題的實際解決方案。 第一輪提問 面試官&#xff1a;馬架構&#xff0c;歡迎來到我們公司的面試現場。請問您對Java…

SpringMVC 靜態資源處理 mvc:default-servlet-handler

我們先來看看效果,當我把這一行注釋掉的時候&#xff1a; 我們來看看頁面&#xff1a; 現在我把注釋去掉&#xff1a; 、 可以看到的是&#xff0c;這個時候又可以訪問了 那么我們就可以想&#xff0c;這個 <mvc:default-servlet-handler />它控制著我們頁面的訪問…

【leetcode】最長公共子路徑問題

滾動hash 滾動哈希&#xff08;rolling hash&#xff09;也叫 Rabin-Karp 字符串哈希算法&#xff0c;它是將某個字符串看成某個進制下的整數&#xff0c;并將其對應的十進制整數作為hash值。 滾動hash算法的推導 假設有一個長度為n的數組a[0],a[1],a[2],…a[n-1]&#xff0…

【Linux網絡】:套接字之UDP

一、UDP和TCP協議 TCP &#xff08;Transmission Control Protocol 傳輸控制協議&#xff09;的特點&#xff1a; 傳輸層協議有連接&#xff08;在正式通信前要先建立連接&#xff09;可靠傳輸&#xff08;在內部幫我們做可靠傳輸工作&#xff09;面向字節流 UDP &#xff08;U…

React19 useOptimistic 用法

用法 樂觀更新 發起異步請求時&#xff0c;先假設請求會成功立即更新 UI 給用戶反饋若請求最終失敗&#xff0c;再將 UI 恢復到之前的狀態 const [optimisticState, addOptimistic] useOptimistic(state, updateFn) 參數 state&#xff1a;實際值&#xff0c;可以是 useSta…

Deepseek-v3+cline+vscode java自動化編程

1、Deepseek DeepSeek 充值后&#xff0c;創建apikey 2、vscode Visual Studio Code - Code Editing. Redefined 3、下載插件cline 4、配置deepeseek-v3 的密鑰到cline 5、不可用 在開始的幾次調用能正常使用起來&#xff0c;用了幾次后&#xff0c;不能使用了&#xff0c;請求…

數據分析案例:環境數據分析

目錄 數據分析案例&#xff1a;環境數據分析1. 項目背景2. 數據加載與預處理2.1 數據說明2.2 讀取與清洗 3. 探索性數據分析&#xff08;EDA&#xff09;3.1 時序趨勢3.2 日內變化3.3 氣象與污染物相關性 4. 特征工程4.1 時間特征4.2 滯后與滾動統計4.3 目標變量 5. 模型構建與…

網絡原理 - 8

目錄 補充 網絡層 IP 協議 基本概念&#xff1a; 協議頭格式 地址管理 如何解決 IP 地址不夠用呢&#xff1f;&#xff1f;&#xff1f; 1. 動態分配 IP 地址&#xff1a; 2. NAT 機制&#xff08;網絡地址映射&#xff09; 3. IPv6 網段劃分 一些特殊的 IP 地址 …