Skip to main content

FastAPI launcher for GraiaCommunity.

Project description

GraiaX FastAPI

:sparkles: Easy FastAPI Access for GraiaCommunity :sparkles:

codecov Code style: black Imports: isort License pdm-managed PyPI

你可以方便地使用 GraiaX FastAPI 配合 graia.amnesia.builtins.asgi.UvicornASGIService 轻松地在启动使用了 Graia Amnesia 的项目(如:Ariadne、Avilla)的同时启动一个 Uvicorn 服务器并在 Saya 模块中便捷地注册 FastAPI 的路由,且在 Launart 退出的时候自动关闭 Uvicorn。

安装

pdm add graiax-fastapipoetry add graiax-fastapi

我们强烈建议使用包管理器或虚拟环境

开始使用

以 Avilla 为例。

[!IMPORTANT]
自 v0.4.0 版本开始, GraiaX FastAPI 抛弃了旧版 Launart(<0.7.0)和旧版 Amnesia(<0.8.0)的支持,因此在 Ariadne 支持新的 Launart 以及 Amnesia 之前,请使用 graiax-fastapi==0.3.0

配合 Launart 使用

机器人入口文件

如果你有使用 Graia Saya 作为模块管理工具,那么你可以使用 FastAPIBehaviour 以在 Saya 模块中更方便地使用 FastAPI。

FastAPI 本身并 不自带 ASGI 服务器,因此你需要额外添加一个 UvicornASGIService

import pkgutil

from avilla.console.protocol import ConsoleProtocol
from avilla.core import Avilla
from creart import create
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from graia.amnesia.builtins.asgi import UvicornASGIService
from graia.broadcast import Broadcast
from graia.saya import Saya
from launart import Launart

broadcast = create(Broadcast)
saya = create(Saya)
launart = create(Launart)
avilla = Avilla(broadcast=broadcast, launch_manager=launart, message_cache_size=0)
fastapi = FastAPI()

avilla.apply_protocols(ConsoleProtocol())
saya.install_behaviours(FastAPIBehaviour(fastapi))
fastapi.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
launart.add_component(FastAPIService(fastapi))
launart.add_component(UvicornASGIService("127.0.0.1", 9000, {"": fastapi}))  # type:ignore
# 上面这条命令会占据 Uvicorn 的所有入口点,详见下方的 Warning

with saya.module_context():
    for module in pkgutil.iter_modules(["modules"]):
        if module.name[0] in ("#", ".", "_"):
            continue
        saya.require(f"modules.{module.name}")

launart.launch_blocking()

[!WARNING]
需要留意的是,在把我们的 FastAPI 实例添加到 UvicornASGIService 中间件时,我们通过 {"": fastapi} 指定了一个入口点(entrypoint)"",这代表着我们此时传进去的 FastAPI 实例将占据 http://127.0.0.1:9000/ 下所有入口(例如我们可以通过 http://127.0.0.1:9000/docs 访问我们的 FastAPI 实例的 OpenAPI 文档),这样用起来很方便,但可能会影响其他也使用 UvicornASGIService 中间件的功能(例如 Avilla 的 ob11 协议)。

假如我们使用 {"/api": fastapi} 指定 /api 为入口点,那么我们就需要通过 http://127.0.0.1:9000/api/docs 而不是 http://127.0.0.1:9000/docs 来访问我们的 FastAPI 实例的 OpenAPI 文档。

Saya 模块中

from graia.saya import Channel
from pydantic import BaseModel

from graiax.fastapi import RouteSchema, route

channel = Channel.current()


class ResponseModel(BaseModel):
    code: int
    message: str


# 方式一:像 FastAPI 那样直接使用装饰器
@route.get("/", response_model=ResponseModel)
async def root():
    return {"code": 200, "message": "Hello World!"}


# 方式二:当你先需要同一个路径有多种请求方式时你可以这样做
@route.route(["GET"], "/xxxxx")
async def xxxxx():
    return "xxxx"


# 方式三:上面那种方式实际上也可以这么写
@channel.use(RouteSchema("/xxx", methods=["GET", "POST"]))
async def xxx():
    return "xxx"


# Websocket
from fastapi import WebSocket
from starlette.websockets import WebSocketDisconnect
from websockets.exceptions import ConnectionClosedOK


@route.ws("/ws")
# 等价于 @channel.use(WebsocketRouteSchema("/ws"))
async def ws(websocket: WebSocket):
    await websocket.accept()
    while True:
        try:
            print(await websocket.receive_text())
        except (WebSocketDisconnect, ConnectionClosedOK, RuntimeError):
            break

其他方式

假如你不想在 Saya 模块中为 FastAPI 添加路由,那么你可以选择以下几种方式:

在机器人入口文件中直接添加
...
fastapi = FastAPI()
...
fastapi.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@fastapi.get("/main")
async def main():
    return "main"

...
launart.add_component(FastAPIService(fastapi))
launart.add_component(UvicornASGIService("127.0.0.1", 9000, {"": fastapi}))  # type:ignore
...
在 Avilla 启动成功后添加
from fastapi.responses import PlainTextResponse
from avilla.standard.core.application.event import ApplicationReady
from graiax.fastapi.interface import FastAPIProvider

async def interface_test():
    return PlainTextResponse("I'm from interface!")


@listen(ApplicationReady)
async def function():
    launart = Launart.current()
    fastapi = launart.get_interface(FastAPIProvider)
    fastapi.add_api_route("/interface", fastapi.get("/interface")(interface_test))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

graiax_fastapi-0.4.1.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graiax_fastapi-0.4.1-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

Details for the file graiax_fastapi-0.4.1.tar.gz.

File metadata

  • Download URL: graiax_fastapi-0.4.1.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for graiax_fastapi-0.4.1.tar.gz
Algorithm Hash digest
SHA256 1def38cce7a0ff4d76a16a51b156c8f0ce47a365331e7e7eb8a560db24fee592
MD5 612f9c89394181061437720e6c55ec62
BLAKE2b-256 3cd8cd1eb1d6b17b686b418df49fae916bf1fd8c418f10d74ed8811edbbd877d

See more details on using hashes here.

File details

Details for the file graiax_fastapi-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: graiax_fastapi-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 9.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for graiax_fastapi-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d6aad009ea4819ee09dfbd9d46ed8f3d5e2b56b8fd5cec15b99ccb8e8695981f
MD5 c2b8932b2f7705a1e0c35662997d83b9
BLAKE2b-256 371131f97ee5a7eedba764fa963d3a635301ab10adcad17f5bde2f58068e6750

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page