Python__模块(代码-辅助)__contextlib / pprint

本文介绍了Python的contextlib模块如何实现自动文件管理和线程操作,以及contextmanager装饰器的使用示例。同时,对pprint模块的PrettyPrinter类及其参数进行了详细说明,展示了美化打印内容的方法。

contextlib(简介)

上下文管理器。

实现自动的文件打开关闭以及线程操作。


contextlib(参考代码)

contextlib / with 区别

# 例子:with
class echo:
    def __enter__(self):
        print("enter")

    def __exit__(self, *args):
        print("exit")
        print("________________")

with echo() as e:
    print("test")
""" >>>
enter
test
exit
________________
"""

# 例子:contextlib
from contextlib import contextmanager

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

with tag("ul"):
    print("<li>line1</li>")
    print("<li>line2</li>")
""" >>>
<ul>
<li>line1</li>
<li>line2</li>
</ul>
"""
# 代码的执行顺序:
"""   
with语句首先执行yield之前的语句,因此打印出<h1>
yield调用会执行with语句内部的所有语句,因此打印出hello和world
最后执行yield之后的语句,打印出</h1>
"""

pprint(简介)

美化打印内容。


pprint(参数列表)

【语法】

pprint.PrettyPrinter(width,indent,compact,sort_dicts)

pprint.pprint(对象,流=无,缩进=1,宽度=80,深度=无,*, 紧凑=假,sort_dicts=真,underscore_numbers=假)

【参数】

width

(默认值80) 指定输出中每行所需的最大字符数。

indent

缩进 紧凑会影响长序列(列表、元组、集合等)的格式设置方式。

compact

行格式化

compact  为false(默认值)

则序列的每个项目都将在单独的行上进行格式化

如果紧凑为真,则每个输出行将设置宽度范围内适合的任意数量的项目。

sort_dicts

键排序

sort_dicts为True(默认值),则字典的格式将按键排序。

否则将按广告插入顺序显示。


pprint(参考代码)

简单例子

import pprint

# 简化版
obj = {"word": {"test": "测试"}, "fruit": {"apple": "苹果"}}
pprint.pprint(obj)
# 样式版
words = {
    "apple": "苹果",
    "banana": "香蕉",
    "watermelon": "西瓜",
    "grape": "葡萄",
    "orange": "橙子",
}
pprint.pprint(words)
p = pprint.PrettyPrinter(width=1, indent=1, compact=True, sort_dicts=False)
p.pprint(words)

2025-07-23 16:48:26 2025-07-23 16:48:26.051 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.18.0.1:0 - "POST /api/v1/images/image/config/update HTTP/1.1" 500 - {} 2025-07-23 16:48:26 Exception in ASGI application 2025-07-23 16:48:26 + Exception Group Traceback (most recent call last): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 76, in collapse_excgroups 2025-07-23 16:48:26 | yield 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 178, in __call__ 2025-07-23 16:48:26 | async with anyio.create_task_group() as task_group: 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__ 2025-07-23 16:48:26 | raise BaseExceptionGroup( 2025-07-23 16:48:26 | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception) 2025-07-23 16:48:26 +-+---------------- 1 ---------------- 2025-07-23 16:48:26 | Traceback (most recent call last): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi 2025-07-23 16:48:26 | result = await app( # type: ignore[func-returns-value] 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ 2025-07-23 16:48:26 | return await self.app(scope, receive, send) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ 2025-07-23 16:48:26 | await super().__call__(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ 2025-07-23 16:48:26 | await self.middleware_stack(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ 2025-07-23 16:48:26 | await self.app(scope, receive, _send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in __call__ 2025-07-23 16:48:26 | await self.app(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 | with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 | self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 | response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/main.py", line 1117, in inspect_websocket 2025-07-23 16:48:26 | return await call_next(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 | raise app_exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 | await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 | with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 | self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 | response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/main.py", line 1096, in check_url 2025-07-23 16:48:26 | response = await call_next(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 | raise app_exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 | await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 | with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 | self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 | response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/main.py", line 1082, in commit_session_after_request 2025-07-23 16:48:26 | response = await call_next(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 | raise app_exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 | await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 | with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 | self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 | response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/utils/security_headers.py", line 11, in dispatch 2025-07-23 16:48:26 | response = await call_next(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 | raise app_exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 | await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 | with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 | self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 | response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/main.py", line 1070, in dispatch 2025-07-23 16:48:26 | response = await call_next(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 | raise app_exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 | await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette_compress/__init__.py", line 94, in __call__ 2025-07-23 16:48:26 | return await self._brotli(scope, receive, send) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette_compress/_brotli.py", line 106, in __call__ 2025-07-23 16:48:26 | await self.app(scope, receive, wrapper) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 62, in __call__ 2025-07-23 16:48:26 | await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2025-07-23 16:48:26 | await app(scope, receive, sender) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 715, in __call__ 2025-07-23 16:48:26 | await self.middleware_stack(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 735, in app 2025-07-23 16:48:26 | await route.handle(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 288, in handle 2025-07-23 16:48:26 | await self.app(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 76, in app 2025-07-23 16:48:26 | await wrap_app_handling_exceptions(app, request)(scope, receive, send) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2025-07-23 16:48:26 | raise exc 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2025-07-23 16:48:26 | await app(scope, receive, sender) 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 73, in app 2025-07-23 16:48:26 | response = await f(request) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 301, in app 2025-07-23 16:48:26 | raw_response = await run_endpoint_function( 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 212, in run_endpoint_function 2025-07-23 16:48:26 | return await dependant.call(**values) 2025-07-23 16:48:26 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | File "/app/backend/open_webui/routers/images.py", line 303, in update_image_config 2025-07-23 16:48:26 | set_image_model(request, form_data.MODEL) 2025-07-23 16:48:26 | File "/app/backend/open_webui/routers/images.py", line 239, in set_image_model 2025-07-23 16:48:26 | if model != options["sd_model_checkpoint"]: 2025-07-23 16:48:26 | ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 | KeyError: 'sd_model_checkpoint' 2025-07-23 16:48:26 +------------------------------------ 2025-07-23 16:48:26 2025-07-23 16:48:26 During handling of the above exception, another exception occurred: 2025-07-23 16:48:26 2025-07-23 16:48:26 Traceback (most recent call last): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi 2025-07-23 16:48:26 result = await app( # type: ignore[func-returns-value] 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ 2025-07-23 16:48:26 return await self.app(scope, receive, send) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/fastapi/applications.py", line 1054, in __call__ 2025-07-23 16:48:26 await super().__call__(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/applications.py", line 112, in __call__ 2025-07-23 16:48:26 await self.middleware_stack(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 187, in __call__ 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 165, in __call__ 2025-07-23 16:48:26 await self.app(scope, receive, _send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/cors.py", line 85, in __call__ 2025-07-23 16:48:26 await self.app(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/main.py", line 1117, in inspect_websocket 2025-07-23 16:48:26 return await call_next(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 raise app_exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/main.py", line 1096, in check_url 2025-07-23 16:48:26 response = await call_next(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 raise app_exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/main.py", line 1082, in commit_session_after_request 2025-07-23 16:48:26 response = await call_next(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 raise app_exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/utils/security_headers.py", line 11, in dispatch 2025-07-23 16:48:26 response = await call_next(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 raise app_exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 177, in __call__ 2025-07-23 16:48:26 with recv_stream, send_stream, collapse_excgroups(): 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__ 2025-07-23 16:48:26 self.gen.throw(typ, value, traceback) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_utils.py", line 82, in collapse_excgroups 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 179, in __call__ 2025-07-23 16:48:26 response = await self.dispatch_func(request, call_next) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/main.py", line 1070, in dispatch 2025-07-23 16:48:26 response = await call_next(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 154, in call_next 2025-07-23 16:48:26 raise app_exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/base.py", line 141, in coro 2025-07-23 16:48:26 await self.app(scope, receive_or_disconnect, send_no_error) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette_compress/__init__.py", line 94, in __call__ 2025-07-23 16:48:26 return await self._brotli(scope, receive, send) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette_compress/_brotli.py", line 106, in __call__ 2025-07-23 16:48:26 await self.app(scope, receive, wrapper) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 62, in __call__ 2025-07-23 16:48:26 await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2025-07-23 16:48:26 await app(scope, receive, sender) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 715, in __call__ 2025-07-23 16:48:26 await self.middleware_stack(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 735, in app 2025-07-23 16:48:26 await route.handle(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 288, in handle 2025-07-23 16:48:26 await self.app(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 76, in app 2025-07-23 16:48:26 await wrap_app_handling_exceptions(app, request)(scope, receive, send) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app 2025-07-23 16:48:26 raise exc 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app 2025-07-23 16:48:26 await app(scope, receive, sender) 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 73, in app 2025-07-23 16:48:26 response = await f(request) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 301, in app 2025-07-23 16:48:26 raw_response = await run_endpoint_function( 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 212, in run_endpoint_function 2025-07-23 16:48:26 return await dependant.call(**values) 2025-07-23 16:48:26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 File "/app/backend/open_webui/routers/images.py", line 303, in update_image_config 2025-07-23 16:48:26 set_image_model(request, form_data.MODEL) 2025-07-23 16:48:26 File "/app/backend/open_webui/routers/images.py", line 239, in set_image_model 2025-07-23 16:48:26 if model != options["sd_model_checkpoint"]: 2025-07-23 16:48:26 ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ 2025-07-23 16:48:26 KeyError: 'sd_model_checkpoint'
07-24
<think>我们遇到的是一个KeyError: 'sd_model_checkpoint'错误。这个错误发生在尝试访问一个字典中不存在的键时。具体来说,在文件`/app/backend/open_webui/routers/images.py`的第239行,尝试从`options`字典中获取键`'sd_model_checkpoint'`的值,但是该键不存在。 错误堆栈如下: ``` File "/app/backend/open_webui/routers/images.py", line 239, in set_image_model if model != options["sd_model_checkpoint"]: KeyError: 'sd_model_checkpoint' ``` 解决方案: 1. 首先,我们需要确保在访问字典的键之前,该键确实存在。我们可以使用`in`关键字检查键是否存在,或者使用`get`方法提供默认值。 2. 根据上下文,这里可能是期望`options`字典中有这个键,但实际上没有。我们需要考虑为什么没有这个键,以及在没有这个键的情况下应该如何处理。 具体到代码,我们可以修改`set_image_model`函数中的这一行,使用`get`方法并提供一个默认值,或者先检查键是否存在。 原始代码行: ```python if model != options["sd_model_checkpoint"]: ``` 修改建议: 方法1:使用get方法,如果键不存在则返回None(或其他合适的默认值),然后进行比较。 ```python if model != options.get("sd_model_checkpoint"): # 注意:如果键不存在,get返回None,那么这里就会变成 model != None,这可能是我们期望的?或者 # 如果键不存在,我们也可以认为当前模型不是我们想要的,从而执行后续操作? ``` 方法2:先检查键是否存在,如果不存在,我们可以选择跳过或者执行其他操作。 ```python if "sd_model_checkpoint" in options and model != options["sd_model_checkpoint"]: ``` 但是,根据错误堆栈,这个函数是在更新图像配置时调用的,所以可能我们需要确保这个键存在。如果这个键在正常情况下应该存在,那么可能是其他地方没有正确初始化`options`字典。因此,我们还需要考虑在程序初始化时确保`options`字典包含这个键。 然而,由于我们无法直接修改整个程序的初始化过程,因此更安全的做法是在访问前检查。 考虑到这个错误是发生在生产环境中,我们应尽快修复。这里我们采用方法1或方法2都可以,但更推荐方法2,因为它明确检查了键的存在性。 但是,我们注意到在同一个文件的第239行附近,还有对`options`字典的其他操作。我们可能需要更全面地检查这个函数,确保对字典的访问都是安全的。 另外,我们也可以考虑在设置`options`字典时,确保它包含所有必要的键,并设置初始值。但根据错误发生的位置,我们目前只看到这一处访问。 因此,我们修改代码: 原函数(假设): ```python def set_image_model(request: Request, model: str): # ... 其他代码 options = get_sd_options() # 假设这是获取options的函数,实际可能不同 if model != options["sd_model_checkpoint"]: # 更新模型 # ... 后续操作 ``` 修改后: ```python def set_image_model(request: Request, model: str): # ... 其他代码 options = get_sd_options() # 假设这是获取options的函数 # 检查键是否存在 if "sd_model_checkpoint" in options: current_model = options["sd_model_checkpoint"] else: current_model = None # 或者一个默认的模型字符串,根据实际情况 if model != current_model: # 更新模型 # ... 后续操作 ``` 或者更简洁的写法: ```python current_model = options.get("sd_model_checkpoint") if model != current_model: # ... ``` 这两种写法都可以避免KeyError。 但是,我们还需要注意:在后续的代码中,可能还有对`options`字典其他键的访问。因此,最好对整个函数中的类似访问都进行保护。 由于我们只看到这一处错误,所以先修复这一处。 另外,我们还需要考虑这个错误是否会导致整个请求失败。从堆栈来看,这个异常没有被捕获,导致返回500错误。因此,修复后应该能避免这个500错误。 但是,我们还需要思考:为什么`options`字典中没有`'sd_model_checkpoint'`这个键?可能是配置加载不完整,或者版本升级导致配置项变化。因此,除了修复这个错误,我们还需要确保配置的完整性。 由于时间关系,我们先修复这个KeyError,确保程序不会崩溃。然后,我们应该在程序初始化或配置加载的地方检查是否包含了所有必要的键。 由于我们无法看到整个项目的代码,所以只能针对这个错误进行修复。 修改后的代码(针对这一行): ```python # 原始代码:if model != options["sd_model_checkpoint"]: # 改为: current_model = options.get("sd_model_checkpoint") if model != current_model: ``` 这样,即使`sd_model_checkpoint`不在`options`中,`current_model`会是`None`,然后比较`model != None`,如果`model`是一个非None的字符串,条件就会成立,从而执行更新操作。这可能是符合逻辑的,因为如果当前配置中没有这个模型,那么我们就需要设置它。 但是,我们也要注意,如果`current_model`为None,可能意味着配置中没有这个项,那么更新操作是否应该执行?这取决于业务逻辑。如果这个键是必须存在的,那么它不存在时,我们可能需要进行初始化设置,所以执行更新操作也是合理的。 因此,这个修改在逻辑上是合理的。 由于我们无法直接修改原文件,我们只能建议在代码库中修改这一行。 另外,在同一个文件中,可能还有其他地方访问`options`字典,我们应当检查并做同样的修改,避免类似错误。 总结:这个错误是由于访问字典中不存在的键导致的,修复方法是使用`get`方法或检查键的存在性。 下面,我们给出修改代码的示例(仅针对该行):</think>根据提供的错误日志,问题发生在处理图像配置更新请求时,具体是`KeyError: 'sd_model_checkpoint'`错误。这表明代码尝试访问字典中不存在的键。以下是详细分析和解决方案: ### 问题分析 1. **错误位置**: ```python File "/app/backend/open_webui/routers/images.py", line 239, in set_image_model if model != options["sd_model_checkpoint"]: KeyError: 'sd_model_checkpoint' ``` 2. **根本原因**: - `options`字典中缺少`sd_model_checkpoint`键 - 可能原因: - 后端服务未正确初始化配置 - 配置加载失败 - 键名拼写错误或不一致 ### 解决方案 修改`/app/backend/open_webui/routers/images.py`中的`set_image_model`函数,使用安全的字典访问方法: ```python def set_image_model(request: Request, model: str): # ... 其他代码 ... options = get_sd_options() # 假设这是获取配置的函数 # 安全访问字典键 current_model = options.get("sd_model_checkpoint") # 使用get方法避免KeyError if model != current_model: # 更新模型配置 options["sd_model_checkpoint"] = model set_sd_options(options) # 假设这是更新配置的函数 request.app.state.SD.set_options(options) # 添加额外日志便于调试 logger.info(f"Updated model to: {model}") else: logger.info(f"Model unchanged: {model}") ``` ### 关键修改说明 1. **使用`.get()`方法**: - 当键不存在时返回`None`而非抛出异常 - 语法:`dict.get(key, default=None)` 2. **添加防御性日志**: - 记录配置变更情况 - 帮助追踪未初始化的配置 3. **完整错误处理建议**: 在路由处理函数中添加异常捕获: ```python # 在 /app/backend/open_webui/routers/images.py 的 update_image_config 函数中 async def update_image_config(request: Request, form_data: ImageConfigForm): try: set_image_model(request, form_data.MODEL) return JSONResponse({"status": "success"}) except Exception as e: logger.error(f"Config update failed: {str(e)}") return JSONResponse( {"status": "error", "detail": str(e)}, status_code=500 ) ``` ### 预防措施 1. **配置初始化检查**: 在服务启动时验证必要配置项是否存在: ```python def validate_config(options: dict): required_keys = ["sd_model_checkpoint", "sd_api_url"] for key in required_keys: if key not in options: logger.warning(f"Missing config key: {key}") # 设置默认值 options[key] = None ``` 2. **配置热重载监控**: ```python import threading import time def config_watcher(app): while True: time.sleep(60) current_config = app.state.config if "sd_model_checkpoint" not in current_config: app.state.config = load_config() # 重新加载配置 ``` ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vip飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值