Giter VIP home page Giter VIP logo

msgpack-asgi's People

Contributors

faresbakhit avatar florimondmanca avatar roedoejet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

msgpack-asgi's Issues

Support for large requests (more_body=True)

This library seemed to hit the spot for drop-in support for msgpack with FastAPI. I am using the following to enable the msgpack interface:
app.add_middleware(MessagePackMiddleware)

Unfortunately, large client requests are failing. Running uvicorn with --log-level trace I see that the request is being chunked:

TRACE:    127.0.0.1:42088 - Connection made
TRACE:    10.60.1.118:0 - ASGI [4] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.0', 'server': ('127.0.0.1', 8901), 'client': ('10.60.1.118', 0), 'scheme': 'https', 'method': 'POST', 'root_path': '/app/<redacted>', 'path': '<redacted> 'raw_path': b'/<redacted>', 'query_string': b'', 'headers': '<...>'}
TRACE:    10.60.1.118:0 - ASGI [4] Receive {'type': 'http.request', 'body': '<65150 bytes>', 'more_body': True}
TRACE:    10.60.1.118:0 - ASGI [4] Receive {'type': 'http.request', 'body': '<65482 bytes>', 'more_body': True}
TRACE:    10.60.1.118:0 - ASGI [4] Send {'type': 'http.response.start', 'status': 400, 'headers': '<...>'}
INFO:     10.60.1.118:0 - "POST<redacted> HTTP/1.0" 400 Bad Request
TRACE:    10.60.1.118:0 - ASGI [4] Send {'type': 'http.response.body', 'body': '<45 bytes>'}
TRACE:    10.60.1.118:0 - ASGI [4] Completed
TRACE:    127.0.0.1:42088 - Connection lost

Requests under 64k work fine. JSON requests of any size are also fine.
The request is being sent from the client as a regular POST.

I assume this is related the comments about more_body not being implemented in the source code.

I am still getting up to speed with ASGI. Is this something that should be fixed with this middleware, or should I look at figuring out how to increase the buffer size elsewhere?

Supporting alternative msgpack implementations

ormsgpack is a faster alternative to python-msgpack and since speed is critical/required in Web/ASGI application I think it would be nice to have support for using ormsgpack!

My current idea is to provide ormsgpack as an extra/optional dependency to msgpack-asgi (installed like pip install msgpack-asgi[ormsgpack]?) and provide two more classes to the public API ORMessagePackMiddleware and ORMessagePackResponse if ormsgpack can be imported.

I will happily create a PR and start working on this feature if this is something can be added to the project! ๐Ÿ˜„

Support for Content-Type: application/msgpack header

As evidenced by msgpack/msgpack#194, there still is no clear answer on the "proper" MIME type for msgpack. Fluent-bit's HTTP output plugin uses application/msgpack for the content-type instead of aapplication/x-msgpack, so the msgpack-asgi middleware doesn't attempt to unpack requests from fluent-bit POST's

Always getting 442 Unprocessable entity

I cannot get msgpack-asgi running with FastAPI. Any request with msgpack-bytes is returned with a "422 Unprocessable Entity" error. The following minimal example will show the problem:

from pathlib import Path
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
from msgpack_asgi import MessagePackMiddleware


class Foo(BaseModel):
    bar: int


app = FastAPI()
app.add_middleware(MessagePackMiddleware)


@app.post("/")
def index(thing: Foo):
    return thing


if __name__ == "__main__":
    uvicorn.run(f"{Path(__file__).stem}:app", host="0.0.0.0", port=5001, log_level="debug", reload=True)

The data is sent with the following snippet:

import requests
import msgpack

url = "http://127.0.0.1:5001/"
headers = {"content-type": "application/x-msgpack"}
data_raw = {"bar": 23}
data_packed = msgpack.packb(data_raw)

response_json = requests.post(url, json=data_raw)
response_msgpack = requests.post(url, data=data_packed, headers=headers)

Resulting in:

INFO:     127.0.0.1:54682 - "POST / HTTP/1.1" 200 OK
INFO:     127.0.0.1:54684 - "POST / HTTP/1.1" 422 Unprocessable Entity

So the data is accepted as json but refused as msgpack-bytes. May there be an incompatibility with newser versions of FastAPI or pydantic? Or am I just using this completely wrong?

HTTPS support

  1. Why it does not support HTTPS?
  2. How to make it working with HTTPS?
class MessagePackMiddleware:
    def __init__(self, app: ASGIApp) -> None:
        self.app = app

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        if scope["type"] == "http":
            responder = _MessagePackResponder(self.app)
            await responder(scope, receive, send)
            return
        await self.app(scope, receive, send)

Implementation flaw of the middleware prevents concurrent requests

I think the current vesion of the msgpack middleware has a serious implementaion flaw that will cause errors when parallel requests are processed.

During each request, some request scoped variables, like receive, send, should_decode_from_msgpack_to_json, initial_message etc, are stored on the middleware instance itself:

        self.should_decode_from_msgpack_to_json = (
            "application/x-msgpack" in headers.get("content-type", "")
        )
        # Take an initial guess, although we eventually may not
        # be able to do the conversion.
        self.should_encode_from_json_to_msgpack = (
            "application/x-msgpack" in headers.getlist("accept")
        )
        self.receive = receive
        self.send = send

The problem is that there is only one instance of the middleware, but multiple parallel requests are normally in progress, so these variables will get mixed up between the requests. When for example receive_with_msgpack is called to process a request, self.receive could already have been overwritten by a subsequent request.

The proper way to pass request scoped values between the various instance methods would be to use request or function scoped storage, like scope, wrapped function or partial function.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.