问题描述

产生冲突的原因是因为 uvicorn 启动时候会解析命令行参数,而 argparse 也会解析命令行参数,导致冲突。
具体表现为,当使用 uvicorn 启动时候,argparse 获取不到参数。

即在代码中如果在启动了的 uvicorn 程序中调用了sys.argv[1:], 则会报错
在 argparse 中的参数列表初始化中有这么一段代码,也是导致报错的原因

1
2
3
4
5
6
7
def parse_known_args(self, args=None, namespace=None):
if args is None:
# args default to the system args
args = _sys.argv[1:]
else:
# make sure that args are mutable
args = list(args)

解决方案

在初始化 argparse 时候,传入参数 [] 即可解决问题

1
2
parser = argparse.ArgumentParser(add_help=add_help)
args = parser.parse_args([])

附上实际报错栈弹出日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
ERROR:uvicorn.error:Exception in ASGI application
Traceback (most recent call last):
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py", line 366, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
return await self.app(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/fastapi/applications.py", line 211, in __call__
await super().__call__(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/routing.py", line 656, in __call__
await route.handle(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/routing.py", line 259, in handle
await self.app(scope, receive, send)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/routing.py", line 61, in app
response = await func(request)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/fastapi/routing.py", line 227, in app
dependant=dependant, values=values, is_coroutine=is_coroutine
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/starlette/concurrency.py", line 39, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/anyio/to_thread.py", line 34, in run_sync
func, *args, cancellable=cancellable, limiter=limiter
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/anyio/_backends/_asyncio.py", line 877, in run_sync_in_worker_thread
return await future
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/site-packages/anyio/_backends/_asyncio.py", line 807, in run
result = context.run(func, *args)
File "./app/api/v1/face.py", line 14, in init_face_index
return crud.init_face_index(index_name)
File "./app/sql_app/crud.py", line 15, in init_face_index
face_ = FaceRecognition(index_name=index_name, operate="index")
File "./app/face_recognition.py", line 26, in __init__
self.args = parser.parse_args()
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/argparse.py", line 1758, in parse_args
self.error(msg % ' '.join(argv))
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/argparse.py", line 2508, in error
self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
File "/Users/asus/miniconda3/envs/testtest37/lib/python3.7/argparse.py", line 2495, in exit
_sys.exit(status)
SystemExit: 2