Run the readme.md example Error: TypeError: 'granian._granian.RSGIHeaders' object is not subscriptable
RuixiangS opened this issue · comments
It seems like a granian bug, and it works when I use the emmett develop --interface asgi
command that works out.
system: Windows 10 Pro 22H2 19045.3086
my_package version list:
absl-py 1.3.0
anyio 3.7.0
Appium-Python-Client 2.9.0
argcomplete 2.1.2
certifi 2023.5.7
charset-normalizer 3.1.0
click 8.1.3
colorama 0.4.6
colorlog 6.7.0
distlib 0.3.6
emmett 2.5.3
emmett-crypto 0.3.0
emmett-rest 1.5.1
emmett-sentry 0.4.1
exceptiongroup 1.1.1
func-timeout 4.3.5
granian 0.4.2
h11 0.14.0
idna 3.4
pendulum 2.1.2
pip 23.0.1
poium 1.3.2
polars 0.18.2
psycopg2-binary 2.9.6
pyDAL 17.3
pydantic 1.10.8
python-dateutil 2.8.2
python-rapidjson 1.10
pytzdata 2020.1
PyYAML 6.0
renoir 1.6.1
requests 2.31.0
sentry-sdk 1.25.0
setuptools 67.8.0
severus 1.2.1
six 1.16.0
sniffio 1.3.0
typer 0.9.0
typing_extensions 4.6.3
urllib3 2.0.2
uvicorn 0.19.0
watchfiles 0.19.0
websockets 10.4
wheel 0.38.4
example
from emmett import App, request, response
from emmett.orm import Database, Field, Model
from emmett.tools import requires, service
class Task(Model):
name = Field.string()
is_completed = Field.bool(default=False)
app = App(__name__)
app.config.db.uri = "postgres://username:password@localhost/foo"
db = Database(app)
db.define_models(Task)
app.pipeline = [db.pipe]
def is_authenticated():
print(request.headers)
return request.headers["Api-Key"] == "foobar"
def not_authorized():
response.status = 401
return {"error": "not authorized"}
@app.route(methods="get")
@service.json
@requires(is_authenticated, otherwise=not_authorized)
async def todo():
page = request.query_params.page or 1
tasks = Task.where(lambda t: t.is_completed == False).select(paginate=(page, 20))
return {"tasks": tasks}
My Test
import requests
url = "http://localhost:8000/todo"
headers = {"Api-Key": "foobar"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
tasks = response.json()["tasks"]
print(tasks)
else:
print("Error:", response.status_code, response.json())
Case: Add an additional question when I use emmett develop --interface asgi
I generate a new request whose headers["Api-key"]="not_foobar", otherwise condition will not work properly.
Expected: otherwise return {"error": "not authorized"}
Traceback (most recent call last):
File "D:\Anaconda\envs\emmett-frame\lib\asyncio\events.py", line 81, in _run
self._context.run(self._callback, *self._args)
File "D:\Anaconda\envs\emmett-frame\lib\site-packages\emmett\asgi\handlers.py", line 194, in __call__
await asyncio.wait_for(
File "D:\Anaconda\envs\emmett-frame\lib\asyncio\tasks.py", line 455, in wait_for
return await fut
File "D:\Anaconda\envs\emmett-frame\lib\site-packages\emmett\http.py", line 112, in asgi
await self._send_body(send)
File "D:\Anaconda\envs\emmett-frame\lib\site-packages\emmett\http.py", line 165, in _send_body
'body': self.encoded_body,
File "D:\Anaconda\envs\emmett-frame\lib\site-packages\emmett\http.py", line 160, in encoded_body
return self.body.encode('utf-8')
AttributeError: 'dict' object has no attribute 'encode'
Test
import requests
url = "http://localhost:8000/todo"
headers = {"Api-Key": "not_foobar"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
tasks = response.json()["tasks"]
print(tasks)
else:
print("Error:", response.status_code, response.json())
My bad I didn't check the README example was still valid with 2.5
You can find the updated code in master