如何在python starlette(fastapi)响应中传递西里尔文自定义头?

2024-10-03 06:18:44 发布

您现在位置:Python中文网/ 问答频道 /正文

只是像在DRF中一样尝试——响应(data=data,status=status,headers={'X-API-Code':anydata})——就是这样

from fastapi import Response
@app.get('/customCyrillicHeader')
def test(resp: Response):
    resp.headers['X-API-Code'] = "Это киррилица, бро"
    return 'ok'

然后是错误堆栈

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 369, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 59, in __call__
    return await self.app(scope, receive, send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\fastapi\applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
    raise exc from None
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\exceptions.py", line 82, in __call__
    raise exc from None
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\routing.py", line 241, in handle
    await self.app(scope, receive, send)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\routing.py", line 52, in app
    response = await func(request)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\fastapi\routing.py", line 220, in app
    dependant=dependant, values=values, is_coroutine=is_coroutine
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\fastapi\routing.py", line 154, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\concurrency.py", line 40, in run_in_threadpool
    return await loop.run_in_executor(None, func, *args)
  File "C:\Python37\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "D:\Projects\RecalcAPIfast\app\main.py", line 18, in test
    resp.headers['X-API-Code'] = "Это киррилица, бро"
  File "D:\Projects\RecalcAPIfast\venv\lib\site-packages\starlette\datastructures.py", line 585, in __setitem__
    set_value = value.encode("latin-1")
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-2: ordinal not in range(256)

starlette\datastructures.py硬编码为拉丁语-1

class MutableHeaders(Headers):
    def __setitem__(self, key: str, value: str) -> None:
        """
        Set the header `key` to `value`, removing any duplicate entries.
        Retains insertion order.
        """
        set_key = key.lower().encode("latin-1")
        set_value = value.encode("latin-1")

        found_indexes = []
        for idx, (item_key, item_value) in enumerate(self._list):
            if item_key == set_key:
                found_indexes.append(idx)

        for idx in reversed(found_indexes[1:]):
            del self._list[idx]

        if found_indexes:
            idx = found_indexes[0]
            self._list[idx] = (set_key, set_value)
        else:
            self._list.append((set_key, set_value))

正如我所知,可以传递http头键的base64值(就像在DRF中的简单方式一样),但我在FastAPI中看不到它。 请帮忙


Tags: inpyselfappvenvlibpackagesline