Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demonstration of ASGI support. #181

Closed
wants to merge 3 commits into from
Closed

Demonstration of ASGI support. #181

wants to merge 3 commits into from

Conversation

tomchristie
Copy link

@tomchristie tomchristie commented Apr 5, 2018

This pull request is intended as a demonstration of the scope of changes needed to add ASGI support to WhiteNoise.

Refs #179.

Some notes:

  • Uses async and await syntax. The codebase won't be 2.7 compatible.
  • Requires the aiofiles package for non-blocking file open and read.
  • Does not implement sendfile support. There's not yet any provision for that in the ASGI spec, so there'd need to be some discussion around the right API for adding that as an extension.
  • Doesn't currently update the test cases to include tests for ASGI.

An example...

example.py

from whitenoise import ASGIWhiteNoise

class MyASGIApp():
    def __init__(self, scope):
        self.scope = scope

    async def __call__(self, receive, send):
        await send({
            'type': 'http.response.start',
            'status': 200,
            'headers': [
                [b'content-type', b'text/plain'],
                [b'content-length', b'13'],
            ],
        })
        await send({
            'type': 'http.response.body',
            'body': b'Hello, world!',
        })


app = ASGIWhiteNoise(MyASGIApp, root='static', prefix='static')

Run using daphne...

$ daphne -b 127.0.0.1 -p 8001 example:app

@tomchristie tomchristie mentioned this pull request Apr 5, 2018
@jordaneremieff
Copy link

jordaneremieff commented Apr 5, 2018

Tested this with an example using uvicorn as well: https://github.com/erm/uvicorn-examples/tree/master/whitenoise

@evansd
Copy link
Owner

evansd commented Apr 6, 2018

Thanks Tom, this is really helpful.

I reckon we can get around the compatibility issue reasonably easily. If we change the responder API to return a file path and a seek offset rather than the file handle then the caller can handle that using sync or async code as it wishes.

At least, that's the first thing that occurs to me; I haven't thought all the implications yet, or whether there are better alternatives. But I'm pretty confident it's solvable in any case.

@tomchristie
Copy link
Author

If we change the responder API to return a file path and a seek offset rather than the file handle then the caller can handle that using sync or async code as it wishes.

That's a really nice idea, yup. Then it only ends up being __init__ and serve that need to be adapted for the ASGI case.

I guess that until you want to drop Python 2, it might make sense for any ASGI variant to be a separate package, that's just the small extra shim on top?

@ebsaral
Copy link

ebsaral commented Sep 20, 2018

@tomchristie I was trying this on my local but at this line https://github.com/evansd/whitenoise/pull/181/files#diff-ffc8dfee817831216f12835223bcad04R252 I am getting 'AsgiRequest' object is not subscriptable error. scope parameter is an AsgiRequest. I am trying to test this with Uvicorn as well. Am I doing something wrong?

@evansd evansd force-pushed the master branch 2 times, most recently from fcaf91a to 4d8a3ab Compare December 24, 2018 15:34
range_header = request_headers.get('HTTP_RANGE')
if range_header:
try:
return await self.get_range_response(range_header, headers, file_handle)
Copy link

@charettes charettes Feb 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be get_range_response_async

Suggested change
return await self.get_range_response(range_header, headers, file_handle)
return await self.get_range_response_async(range_header, headers, file_handle)

@tomchristie
Copy link
Author

I'm going to close this off, since I'm not particularly planning on progressing it myself.
Any other contributors are welcome to use it as the basis for a new pull request taking this on.

@evansd
Copy link
Owner

evansd commented Jul 16, 2019

Fair enough! Thanks for the work you've put into this and sorry I didn't end up able to progress it either. Whitenoise is obviously going to have to go async at some point, but it's just a question of finding the time 😃

@tomchristie
Copy link
Author

Yeah, s'all good.
Figured I'd rather keep things tidy by closing off inactive stuff.

@Palisand
Copy link

I am having trouble understanding what this solves. Is it to allow ASGI apps to serve compressed files? WhiteNoise appears to work just fine with daphne + ASGI as long as the middleware is added; wrapping the ASGI app is seemingly unnecessary. However, I am using whitenoise.storage.CompressedManifestStaticFilesStorage and cannot tell if compressed assets are being served.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants