标签: uvicorn

有没有办法使用Python后端服务器检索客户端IP地址

有问题的设置如下所示:

我的网络应用程序使用和工作类fastapi实现和部署,位于具有IP地址的同一主机上的代理后面(以及其他远程设备后面,例如VPN集中器等)gunicornuvicornnginx172.31.x.x

nginx配置如下:

location / {
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    set_real_ip_from 172.31.x.x/32;  # well-known vpn concentrator

    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect off;
    proxy_pass http://172.31.x.x:5045;
Run Code Online (Sandbox Code Playgroud)

gunicorn配置如下:

OPTIONS="--bind 127.0.0.1:5045 --bind 172.31.x.x:5045 --forwarded-allow-ips=127.0.0.1,172.31.x.x --workers 1 --worker-class uvicorn.workers.Uv
icornWorker --log-config config/logging.conf"
Run Code Online (Sandbox Code Playgroud)

fastapi使用starlette.requests.Request对象(名为request)时,request.client.host打印托管 Web 应用程序的服务器的接口 IP 地址(即172.31.x.x

request.headers["x-real-ip"], request.headers["x-forwarded-for"]两者都打印我的代理之前设备的 IP 地址,这是我公司中众所周知的防火墙设备。

我想问的是:

  1. 是否可以打印整个X-Forwarded-ForHTTP 标头来查看中间代理服务?
  2. 如何检索最终用户的真实客户端 IP 地址(基本上覆盖众所周知的白名单 IP 地址)?

python-3.x gunicorn starlette fastapi uvicorn

5
推荐指数
0
解决办法
3162
查看次数

在 python-fastApi 中间件中引发异常

我正在尝试在 fastapi 中间件中验证令牌,但这似乎是不可能的。因为我认为中间件需要进行下一次调用,尽管它不是必需的。我无法在这个 python-fastapi 后端找到任何好的解决方案来一次性处理令牌。任何帮助表示赞赏。

@app.middleware("http")
async def add_middleware_here(request: Request, call_next):
    token = request.headers["Authorization"]
    try:
        verification_of_token = verify_token(token)
        if verification_of_token:
            response = await call_next(request)
            return response
    except InvalidSignatureError as er:
        raise HTTPException(status_code=401)
Run Code Online (Sandbox Code Playgroud)

python starlette fastapi uvicorn

5
推荐指数
2
解决办法
2663
查看次数

错误:为 FastAPI docker 设置“开发实时重新加载”时出现意外的额外参数 (/start-reload.sh)

按照uvicorn-gunicorn-fastapi-docker中的文档,我应该通过运行以下命令来运行我的图像:

docker run -d -p 80:80 -v $(pwd):/app myimage /start-reload.sh
Run Code Online (Sandbox Code Playgroud)

但我得到:

Usage: uvicorn [OPTIONS] 
Try 'uvicorn --help' for help.

Error: Got unexpected extra argument (/start-reload.sh)
Run Code Online (Sandbox Code Playgroud)

我成功地使用我在这里找到的调试模式挂载了一个卷?但我认为它不够优雅,每次进行更改时我都必须运行它(至少我不必构建图像)

docker run --name ${containerName} \
--env GUNICORN_CMD_ARGS="--reload" \
-p 5000:5000 \
-v $(pwd)/app:/app \
${imageName}:${versionTag} 
Run Code Online (Sandbox Code Playgroud)

我的 Dockerfile 只是:

FROM tiangolo/uvicorn-gunicorn-fastapi:latest

EXPOSE 5000

COPY ./app /app

ENTRYPOINT ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "5000"]
Run Code Online (Sandbox Code Playgroud)

它按预期工作。

当我更改代码时可以重新加载吗?

python gunicorn docker fastapi uvicorn

5
推荐指数
1
解决办法
2966
查看次数

Uvicorn Detect --reload 主线程

我有一个简单的Uvicorn应用程序(使用FastAPI构建)。开发中,uvicorn server:app --reload。该--reload参数表示将启动两个线程,一个用于服务器,一个用于监视文件更改\xe2\x80\x94当检测到文件更改时,将重新启动服务器线程。

\n

到目前为止没有什么特别的。这在 Flask、Django 和其他开发服务器中也很常见。问题是,我想pyngrok在启动开发服务器时使用打开一个隧道,并且我希望该隧道与这两个线程的父线程一样长寿。也就是说,当检测到文件更改并重新启动开发服务器时,我不希望重新启动隧道(因为ngrok这会导致生成新的公共 URL 并中断现有连接)。

\n

使用 Flask 和 Django,这相对容易完成。例如,对于 Flask,我只是这样做os.environ.get("WERKZEUG_RUN_MAIN") != "true",对于 Django,我类似地评估RUN_MAIN环境变量,并且在任何一种情况下,我仅在将这些设置为 时才实例化隧道true。我找不到与 Uvicorn 一起使用的类似变量。有人可以帮忙吗?

\n

fastapi uvicorn pyngrok

5
推荐指数
1
解决办法
2172
查看次数

如何让 Django 3、channels 和 uvicorn 协同工作

我一直在尝试从 daphne 切换到 uvicorn 进行使用 django 3 和通道的项目的生产。我在加载频道的经典 asgi 文件时遇到错误。由于同步调用 django.setup 或 get_application,我无法使用它。我尝试使用sync_to_async 调用调整此文件,但没有成功。有人设法让它发挥作用吗?

原始asgi.py

代码

import os
import django
from channels.routing import get_default_application


os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

django.setup()
application = get_default_application()
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪

Traceback (most recent call last):                                                                                                                                              
File "/usr/local/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap                                                                                           
  self.run()                                                                                                                                                                  
File "/usr/local/lib/python3.8/multiprocessing/process.py", line 108, in run                                                                                                  
  self._target(*self._args, **self._kwargs)                                                                                                                                   
File "/var/www/.cache/pypoetry/virtualenvs/project-4ffvdAoS-py3.8/lib/python3.8/site-packages/uvicorn/subprocess.py", line 61, in subprocess_started                           
  target(sockets=sockets)                                                                                                                                                     
File "/var/www/.cache/pypoetry/virtualenvs/project-4ffvdAoS-py3.8/lib/python3.8/site-packages/uvicorn/main.py", line 407, in run                                               
  loop.run_until_complete(self.serve(sockets=sockets))                                                                                                                        
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete                                                                                       
  return future.result()                                                                                                                                                      
File "/var/www/.cache/pypoetry/virtualenvs/project-4ffvdAoS-py3.8/lib/python3.8/site-packages/uvicorn/main.py", line 414, in serve                                             
  config.load() …
Run Code Online (Sandbox Code Playgroud)

django django-channels django-3.0 uvicorn

5
推荐指数
1
解决办法
4998
查看次数

FastAPI文件上传

我正在尝试使用请求将 JSON 数据+文件(二进制)上传到 FastAPI“POST”端点。

这是服务器代码:

@app.post("/files/")
async def create_file(
    file: bytes = File(...), fileb: UploadFile = File(...), timestamp: str = Form(...)
):
    return {
        "file_size": len(file),
        "timestamp": timestamp,
        "fileb_content_type": fileb.content_type,
    }
Run Code Online (Sandbox Code Playgroud)

这是客户端代码:

session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=0)
session.mount('http://', adapter)

jpg_image = open(IMG_PATH, 'rb').read()

timestamp_str = datetime.datetime.now().isoformat()
files = {
    'timestamp': (None, timestamp_str),
    'file': ('image.jpg', jpg_image),
}
request = requests.Request('POST',
                           FILE_UPLOAD_ENDPOINT,
                           files=files)
prepared_request = request.prepare()
response = session.send(prepared_request)
Run Code Online (Sandbox Code Playgroud)

服务器失败并显示

“POST /files/ HTTP/1.1” 422 无法处理的实体

python-requests http-status-code-422 fastapi uvicorn

5
推荐指数
1
解决办法
9966
查看次数

如何触发 FastAPI/Uvicorn 的干净关闭

我正在使用 uvicorn 和 python 的 subprocess.Popen 运行多个 FastAPI 实例。我有一个用 PySimpleGUI 制作的小型 GUI,我希望能够随意关闭服务器并重新启动它们。

我遇到的第一个问题是,至少在 Windows 中,启动 uvicorn 服务器似乎创建的不是一个,而是两个新进程,并且调用Popen.terminate()仅关闭其中一个进程,这不会释放与服务器关联的端口。我使用 psutil 包修复了此问题,以检查实例化 Popen 对象后创建了哪些新进程,并使用 psutil 跟踪和终止第二个进程。

还有一个主要问题是,调用psutil.terminate()进程并没有调用.net下的FastAPI函数@app.on_event("shutdown")。过去,我们在单独的终端窗口中运行所有服务器,并发现这些终端窗口上的 ctrl-c 将调用关闭事件,但我没有找到其他方法来执行此操作。我界面上的 ctrl-c 显然会关闭界面和所有服务器,并且在命中所有服务器的关闭事件方面有些不可靠。我的另一个想法是 use psutil.send_signal(signal.CTRL_C_EVENT),但这与在终端中调用 ctrl-c 具有相同的效果。

所以我很茫然。我看到很多帖子说这是 uvicorn 的普遍缺点,但没有看到任何直接证实我自己的经验或提供解决方案的内容。我还知道 FastAPI 中的“关闭”和“启动”事件是从 Starlette 移植的,并且在这两个包中都没有很好的记录。我看到过使用 guvicorn 的建议,但我的简短调查证实它与 Windows 不兼容。有什么建议么?

python windows subprocess fastapi uvicorn

5
推荐指数
1
解决办法
2627
查看次数

当我使用 fastapi 运行 aiogram 时,FSM 不起作用

我在使用aiogramFastapi时遇到fsm问题。我运行了aiogram_fsm_example中的代码,但将长轮询更改为 Fastapi 实现。这是我得到的代码:

import logging
from fastapi import FastAPI, Request
import aiogram.utils.markdown as md
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode
from aiogram.utils import executor

logging.basicConfig(level=logging.INFO)

API_TOKEN = "here's the bot token"


bot = Bot(token=API_TOKEN)

# For example use simple MemoryStorage for Dispatcher.
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)


# States
class …
Run Code Online (Sandbox Code Playgroud)

ubuntu python-3.x fastapi uvicorn aiogram

5
推荐指数
1
解决办法
3696
查看次数

带有 nginx 的 FastAPI 不提供 HTTPS 中的静态文件

我有一个小型的测试 FastAPI Web 应用程序,它提供一个简单的 HTML 页面,该页面需要位于静态文件夹中的 css 样式表。它安装在 Linode 服务器(Ubuntu 20.04 LTS)、nginx、gunicorn、uvicorn 工作人员和supervisorctl 上。我已经使用 certbot 添加了证书。

该应用程序在 http 中工作正常,但无法访问 https 中的静态文件。当通过 http 访问时,所有基于静态的功能都可以工作,但是当通过 https 访问时,它缺少 css 样式表中的所有样式。我需要让它工作,这样我就可以加载一个需要 css 和其他静态文件夹存储功能的更复杂的应用程序。

文件结构为:

/home/<user_name>/application
- main.py
- static
   |_ css
   |_ bootstrap
- templates
   |_ index.html
Run Code Online (Sandbox Code Playgroud)

主要.py:

import fastapi
import uvicorn
from fastapi import Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates


api = fastapi.FastAPI()

api.mount('/static', StaticFiles(directory='static'), name='static')
templates = Jinja2Templates(directory="templates")


@api.get('/')
@api.get('/index', response_class=HTMLResponse)
def index(request: Request):
    message …
Run Code Online (Sandbox Code Playgroud)

https nginx fastapi uvicorn

5
推荐指数
1
解决办法
4291
查看次数

如何在 FastApi-SwaggerUI 中输入名称中带有连字符的变量?

如果我向此 API 发送请求:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Response(BaseModel):
    var_name: str

@app.put("/", response_model=Response)
def simple_server(a: str):
    response = Response(var_name=a)
    return response
Run Code Online (Sandbox Code Playgroud)

我收到此 json 文件的响应{"var_name1": "a"}。此外,我还得到了一个非常漂亮的 Swagger UI,它说明了响应字段。

我的问题是,如何{"var-name1": "a"}在 Swagger 文档中使用同样好的输入方式获取这个 json 文件(这是用连字符而不是下划线)?

显然,我无法命名响应数据类中的var_name属性var-name

python swagger pydantic fastapi uvicorn

5
推荐指数
1
解决办法
1768
查看次数