我正在尝试使用 asgi 而不是 wsgi 来运行我的 django 项目。我已经设置了我的 routing.py 和 asgi.py 如下:
路由.py
from django.conf.urls import url
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator,
OriginValidator
from channels.auth import AuthMiddlewareStack
from some.consumers import SomeConsumer
application = ProtocolTypeRouter({
'websocket': AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
url(r'^some_url/$', SomeConsumer),
]
)
)
)
})
Run Code Online (Sandbox Code Playgroud)
asgi.py
import os
from channels.routing import get_default_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
application = get_default_application()
Run Code Online (Sandbox Code Playgroud)
现在,正如您所看到的,它是标准设置,并且在默认 django 服务器上运行良好,但是当我尝试与其他一些(daphne 或 uvicorn)一起运行时,它抛出了这个异常。
这是我的 INSTALLED_APPS
INSTALLED_APPS = [
'channels',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_jenkins', …Run Code Online (Sandbox Code Playgroud) 我试图理解 uvicorn 的“backlog”标志和“limit-concurrency”标志之间的相互作用。来自文档(https://www.uvicorn.org/settings/)
积压:积压中保留的最大连接数。与大量传入流量相关。默认值:2048
limit-concurrency:在发出 HTTP 503 响应之前允许的最大并发连接或任务数。即使在资源过剩的负载下,也有助于确保已知的内存使用模式。
这两种描述似乎都独立有意义,具体取决于您如何解释“积压”一词。但我对他们如何相互作用感到困惑。
限制并发明确表示,如果超过打开连接的数量,那么它将抛出 503 错误,但默认为 2048 的积压似乎意味着 uvicorn 将保留 2048 个请求等待其他请求完成,这意味着它不会是503ing。
任何人都可以阐明这些设置吗?
django-channels是我将在新的一年里学习的第一个材料清单。但是 Django 3 也有 ASGI 功能,没有任何文档。那么我怀疑django-channels用例 VS Django 3 ASGI之间有什么不同?
当我在 Windows 10 专业版上使用 Apache2.4.41 + Python 3.8.1 + Django 3.0.2 + MySQL 8.0.19 运行我的 Django Web 应用程序时,它会在 / 处抛出值错误。set_wakeup_fd 仅适用于主线程。
此问题是 Python 3.8 中回归的结果,并于 11 月在 Python 的后续版本中修复。有关更多详细信息 - https://bugs.python.org/issue38563。
错误的堆栈跟踪如下 -
Environment:
Request Method: GET
Request URL: http://127.0.0.1/
Django Version: 3.0.2
Python Version: 3.8.1
Installed Applications:
['Analysis.apps.AnalysisConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "c:\python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request) …Run Code Online (Sandbox Code Playgroud) Listen 3600
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:3600>
WSGIDaemonProcess project_name display-name=project_name
WSGIScriptAlias / /data/project_name/config/wsgi.py process-group=api application-group=api
ServerName project_name
<Directory /data/project_name/config>
Order allow,deny
Allow from all
Require all granted
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
Exception ignored in: <function Local.__del__ at 0x7fd675a70a60>
Traceback (most recent call last):
File "/data/venv/api/lib/python3.8/site-packages/asgiref/local.py", line 96, in __del__
NameError: name 'TypeError' is not defined
Run Code Online (Sandbox Code Playgroud)
上面的错误日志一遍遍的出来。
不知道为什么不使用asgi时会出现asgi相关的错误。
我已经使用 fastapi 开发了一个 api,它将充当接收短信请求并调用短信 api 发送所述短信的包装器,现在我已准备好部署它。这是代码:
import logging
import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastapi.middleware.trustedhost import TrustedHostMiddleware
import verifier
logging.basicConfig(
format='%(asctime)s - %(funcName)s - %(levelname)s - %(message)s',
level=logging.INFO
)
# get logger
logger = logging.getLogger(__name__)
bot_verifier = None
class DataForBot(BaseModel):
number: str
msg_txt: str
def get_application():
app = FastAPI(title='bot_wrapper', version="1.0.0")
return app
app = get_application()
@app.on_event("startup")
async def startup_event():
global bot_verifier
try:
bot_verifier = await verifier.Verifier.create()
except Exception as e:
logger.error(f"exception occured during bot …Run Code Online (Sandbox Code Playgroud) 最近我一直在开发一个名为(DBSF - 不要成为一个糟糕的朋友)的应用程序,它的功能有点像facebook,但它会提醒你偶尔与你的朋友互动。我遇到了一个长期无法修复的错误。
该应用程序在我的本地计算机上运行良好,但当我尝试将应用程序部署到 heroku 时遇到一个错误。
该问题与使用 Websockets 和 Django 通道的用户之间的聊天功能有关。这是由 heroku 需要 https 引起的,因此 websocket 也必须是安全的(wss:// 而不是 ws://)。
所以我这样做了,我创建了一个安全的 webSocket,其 url 以 wss:// 开头
这就是错误发生的地方:由于某种原因,asgi.py 文件永远无法建立连接,或者routing.py 文件无法将 websocket 连接到consumer.py 中的正确消费者
以下是我尝试修复该错误的方法:
这些都没有改变错误,甚至错误消息。
错误消息总是抱怨套接字仍在连接或已经关闭或处于关闭状态
这是一些代码
在浏览器上(为了在本地计算机上重新创建错误,我只是硬编码“wss”):
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
const chatSocket = new WebSocket(
ws_scheme
+ '://'
+ window.location.host
+ '/ws/chat/'
+ …Run Code Online (Sandbox Code Playgroud) 我想统计特定 URL 路径中的请求数。
app = FastAPI()
counter = 0
@app.get("/do_something")
async def do_something():
global counter
counter += 1
return {"message": "Hello World"}
Run Code Online (Sandbox Code Playgroud)
这段代码可以吗?计数器应该是线程安全的?阿辛西奥安全吗?这是计算请求的正确方法(没有数据库)吗?在这种情况下,“do_something”函数中的“async”有含义吗?以及如何让它与多个工人一起工作?
我们目前正在维护用多个 HTTP 框架(Flask、aiohttp 和 FastAPI)编写的代码。重写它们以便它们都使用相同的框架目前是不可行的。我想在这些应用程序之间共享一些代码,这些代码非常适合中间件(日志记录配置、监控、身份验证等)。
最初的实现是通过子类化 Flask 来完成的,并且在所有基于 Flask 的应用程序中运行得非常好。但它在 aiohttp 或 FastAPI 中无法使用。
创建一个与框架无关的实现是可行的(理论上),今天早上我采用了一个更简单的案例,并成功地将其转换为 WSGI 中间件,并且能够将其集成到 Flask 应用程序中。
但 ASGI 给我带来了一些麻烦,因为没有太多关于纯 ASGI中间件的文档。所有示例都展示了如何为其框架编写中间件。
ASGI 官方文档在该主题上也非常“精简”。据我所知,它应该看起来像这样(附带问题:“传递给构造函数的第二个参数是什么?”):
class MyMiddleware:
def __init__(self, app, something) -> None:
self.app = app
self.something = something # <- what is this second argument?
async def __call__(self, scope, receive, send):
print("Hello from the Middleware")
await self.app(scope, receive, send)
Run Code Online (Sandbox Code Playgroud)
我以Starlette TimingMiddleware作为灵感,但我无法将它与aiohttp. 可能是因为他们的实现略有不同。
考虑到 ASGI 规范中有一个中间件部分,并且两者都aiohttp实现Starlette了该规范,难道不应该有一种方法来编写一个可以在两者中工作的中间件吗?
如果是的话,我错过了什么?
我有一个无法解决的问题。我有一个使用 FastAPI 构建的 API 服务,当我尝试从本地计算机上的另一个 Python 脚本调用任何端点时,响应需要 2 秒以上的时间。当我通过 cURL 或内置 Swagger 文档发送相同的请求时,响应几乎是即时的。
整个服务器脚本是这样的:
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
if __name__ == '__main__':
uvicorn.run(app, host='0.0.0.0', port=8000)
Run Code Online (Sandbox Code Playgroud)
然后我使用 HTTPX 从测试脚本中调用它。我也尝试了 requests 包,结果是一样的。
import httpx
r = httpx.get('http://localhost:8000/')
print(r.elapsed)
Run Code Online (Sandbox Code Playgroud)
这会打印如下内容:0:00:02.069705
然后我使用 cURL 做同样的事情:
curl -w "@curl-format.txt" -o /dev/null -X 'GET' 'http://localhost:8000/'
Run Code Online (Sandbox Code Playgroud)
这打印:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left …Run Code Online (Sandbox Code Playgroud)