from fastapi import FastAPI
from a2wsgi import ASGIMiddleware
app = FastAPI()
# IIS 需要转换将ASGI转为Wsgi
wsgi_app = ASGIMiddleware(app)
使用IIS部署Fastapi简直是造孽,asgi变wsgi,异步变同步,拉跨,万恶的上帝,万恶的windows
基本操作参考:IIS 部署 django+react_庞各庄学霸的博客-CSDN博客
# 我的 web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="D:\acknowledge\code\knowledge\env\Scripts\python.exe|D:\acknowledge\code\knowledge\acknowledge\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<security>
<requestFiltering allowDoubleEscaping="true"></requestFiltering>
</security>
<tracing>
<traceFailedRequests>
<add path="*">
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,WebSocket,RequestRouting,Rewrite" verbosity="Verbose" />
</traceAreas>
<failureDefinitions timeTaken="00:00:00" statusCodes="500" />
</add>
</traceFailedRequests>
</tracing>
<httpErrors errorMode="Detailed" />
</system.webServer>
<appSettings>
<!-- Required settings -->
<add key="WSGI_HANDLER" value="server.wsgi_app" />
<add key="PYTHONPATH" value="D:\project\server.py" />
<add key="WSGI_LOG" value="D:\project\error.log" />
</appSettings>
</configuration>
注意:如果你在程序中使用了__file__变量,IIS或得到相对路径而不是绝对路径,这可能会导致你的程序python命令启动运行正常,但在IIS中却出现莫名其妙的错误
如果只是为了测试,建议使用nssm快速启动服务:
nssm install 服务名称 xx/python.exe xx/server.py
注意:python路径和py脚本路径不用加引号,可以修改描述sc description 服务名称 "xxx服务 "
错误1:FastAPILimiter 在IIS中无法使用,服务报错500
原因是IIS启动fastapi时on_startup不会执行,是的不会执行,所以你在on_startup,on_shutdown的调用并不会执行。由于我在on_startup执行了FastAPILimiter.init,所以IIS启动导致FastAPILimiter并未初执行始化
我的解决办法:
尝试在启动服务时调用FastAPILimiter.init,或完成相同的功能,由于我不知道如何在同步方法中调用异步函数,所以我尝试使用同步完成相同的功能:
FastAPILimiter.redis = cache
FastAPILimiter.prefix = "fastapi-limiter"
FastAPILimiter.identifier = default_identifier
FastAPILimiter.callback = default_callback
FastAPILimiter.lua_sha = 'a3f9e982197e9e887f6b5dcb7ec273863bb83aad' (先用uvicorn启动获取FastAPILimiter.init方法中返回的lua_sha 值)
错误2:win32com 打开ppt,在IIS中运行报错
首先选择对应的进程池,高级设置--允许win32设置为True
原因1:未初始化
解决:
pythoncom.CoInitialize() powerpoint = win32com.client.dynamic.Dispatch('PowerPoint.Application')
原因2:没有文件的操作权限
解决:通过属性修改文件或文件夹权限
原因3:IIS用户没有操作Dcom权限
解决:运行dcomcnfg命令,打开组件服务设置,标识--选择交互用户(也有很多网友在设置安全里-自定义设置,增加IIS用户也得到解决)
IIS的排错:权限->权限->权限!!
配置为交互用户后,发现服务器本机可以允许,局域网用户无法使用。
解决:通过选择“下列用户”,使用一个特定的用户(管理员)
使用https 启动服务:
第一步安装openssl:Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions
pip install pyOpenSSL
openssl req -new -x509 -nodes -out secret.pem -keyout secret.key
openssl req -new -x509 -key secret.key -out secret.cer
if __name__ == '__main__':uvicorn.run("server:app", ssl_keyfile='secret.key', ssl_certfile='secret.cer', )
IIS文件上传默认大小为30M,通过修改服务的配置编辑器,取消大小限制,无需重启IIS服务
修改applicationHost.config
注意:上传大文件,前端也要适当修改下超时时间
尝试另外一种部署:
使用IIS HttpPlatformHandler 模块,让IIS仅充当代理功能,app以uvicorn 或 hypercorn启动,服务就是asgi,异步就可以生效了
使用web平台安装或者手动下载安装。
手动下载连接:HttpPlatformHandler v1.2 : The Official Microsoft IIS Site
we.config配置文件
<configuration>
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" scriptProcessor="D:/xxx/python.exe" resourceType="Unspecified" requireAccess="Script" />
</handlers>
<httpPlatform requestTimeout="00:05:00" startupTimeLimit="120" startupRetryCount="3" stdoutLogEnabled="true" stdoutLogFile="D:/xxx/logs/log" processPath="D:/xxx/python.exe" arguments="-m uvicorn server:app --host 0.0.0.0 --port %HTTP_PLATFORM_PORT% ">
</httpPlatform>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="300000000" />
</requestFiltering>
</security>
</system.webServer>
<system.web>
<httpRuntime executionTimeout="300" />
</system.web>
</configuration>
说明:
web.config位于项目根路径下,修改红色字体内容即可
1. 因为put请求问题,故移除 WebDAV
2. maxAllowedContentLength IIS默认上传文件大小不能超过30M,这里改为300M
3. server:app : app 实例位于server.py内
4. D:/xxx/logs/log :日志文件位于logs文件夹下,前缀为log
5. windows下uvicorn的workers不能大于1,不过可以再稍后修改IIS进程池的进程数达到多进程的目的。
配置生效:
如果修改了配置,需要再执行一次
大功告成,如果启动失败,请查看日志排错
续集:
上线两天,总时挂掉,无奈回到wsgi
异常如下:
Accept failed on a socket
socket: <asyncio.TransportSocket fd=1836, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('0.0.0.0', 23463)>
Traceback (most recent call last):
File "C:\acknowledge\software\python\lib\asyncio\proactor_events.py", line 818, in loop
conn, addr = f.result()
File "C:\acknowledge\software\python\lib\asyncio\windows_events.py", line 566, in accept_coro
await future
File "C:\acknowledge\software\python\lib\asyncio\windows_events.py", line 812, in _poll
value = callback(transferred, key, ov)
File "C:\acknowledge\software\python\lib\asyncio\windows_events.py", line 555, in finish_accept
ov.getresult()
OSError: [WinError 64] 指定的网络名不再可用。