Miserlou / Zappa

Serverless Python
https://blog.zappa.io/
MIT License
11.89k stars 1.2k forks source link

Sanic Support #798

Open fifthecho opened 7 years ago

fifthecho commented 7 years ago

Now that Lambda and Zappa support Python 3.6, it's time to go fast!

Context

Using Python 3.6.1 build a simple Sanic app:

from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
    return json({"ping": "pong"})

Deploy using zappa deploy

Expected Behavior

When calling the deployed app, you should get a JSON response of {"ping": "pong"}

Actual Behavior

[1492803091188] [DEBUG] 2017-04-21T19:31:31.188Z 1e86ec3b-26c9-11e7-8d39-675d00368992 Zappa Event: {'resource': '/', 'path': '/', 'httpMethod': 'POST', 'headers': {'Accept': '*/*', 'Accept-Encoding': 'deflate, gzip', 'CloudFront-Forwarded-Proto': 'https', 'CloudFront-Is-Desktop-Viewer': 'true', 'CloudFront-Is-Mobile-Viewer': 'false', 'CloudFront-Is-SmartTV-Viewer': 'false', 'CloudFront-Is-Tablet-Viewer': 'false', 'CloudFront-Viewer-Country': 'US', 'Content-Type': 'multipart/form-data; boundary=------------------------7c00f57f3885d2a5', 'Host': 'oyn744qikj.execute-api.us-east-1.amazonaws.com', 'User-Agent': 'insomnia/5.0.3', 'Via': '1.1 a1bc06b7f7932216e8d406a348288eac.cloudfront.net (CloudFront)', 'X-Amz-Cf-Id': '4p7JV4jmjNtB5KshFDuYnmYe3V_4txKeSbVNzZIp_MznJV3lORfwXQ==', 'X-Amzn-Trace-Id': 'Root=1-58fa5e11-52449eba1dbcb40e121bb50b', 'X-Forwarded-For': '108.29.95.21, 54.240.159.105', 'X-Forwarded-Port': '443', 'X-Forwarded-Proto': 'https'}, 'queryStringParameters': None, 'pathParameters': None, 'stageVariables': None, 'requestContext': {'accountId': '074567182610', 'resourceId': 'zf1pblv31c', 'stage': 'staging', 'requestId': '1e7e8722-26c9-11e7-93ac-45c462b16c20', 'identity': {'cognitoIdentityPoolId': None, 'accountId': None, 'cognitoIdentityId': None, 'caller': None, 'apiKey': None, 'sourceIp': '108.29.95.21', 'accessKey': None, 'cognitoAuthenticationType': None, 'cognitoAuthenticationProvider': None, 'userArn': None, 'userAgent': 'insomnia/5.0.3', 'user': None}, 'resourcePath': '/', 'httpMethod': 'POST', 'apiId': 'oyn744qikj'}, 'body': 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03YzAwZjU3ZjM4ODVkMmE1DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9InVybCINCg0KaHR0cDovL3d3dy56eXBlLmNvbS9kZW1vLw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS03YzAwZjU3ZjM4ODVkMmE1LS0NCg==', 'isBase64Encoded': True}
[1492803091205] __call__() takes 1 positional argument but 3 were given

Your Environment

fifthecho commented 7 years ago

It's worth mentioning that this is my first Sanic application, but it returns properly on localhost.

bjinwright commented 7 years ago

The tricky part I would imagine is how to handle the event loop. That is the same reason it was tricky to get Tornado working.

r0fls commented 7 years ago

I'm working on this but having some basic difficulties as this is my first zappa deployment. The dependencies aren't being packaged, though I can't tell why. Is there a way to get more debug info regarding what is being packaged in the zip? It works to import the needed requirements in my virtual environment.

r0fls commented 7 years ago

Furthermore the dependencies do exist in the correct location:

>>> import httptools
>>> httptools.__file__
'/Users/r0fls/Documents/code/foss/zappa/sanic-test/36/lib/python3.6/site-packages/httptools/__init__.py'

However I don't see any open issues about dependency packaging. Does it have to be an egg or wheel? 🤔 I see https://github.com/Miserlou/Zappa/issues/185#issuecomment-246439291 but it looks like @fifthecho has gotten farther than me...

r0fls commented 7 years ago

@fifthecho would you be willing to post your entire code into a repo or upload, including the virtual environment, packages, etc...? I couldn't even seem to get to the point you're at.

fifthecho commented 7 years ago

https://github.com/fifthecho/zappa-sanic is a super basic app but exhibits the behaviors I've logged when I deploy it.

Miserlou commented 7 years ago

I think that Sanic isn't WSGI?

You may need this: https://github.com/ashleysommer/sanic-dispatcher

Miserlou commented 7 years ago

So

app = Sanic(__name__)
dispatcher = SanicDispatcherMiddlewareController(app)

Then myapp.dispatcher as the app_function in Zappa settings.

Miserlou commented 7 years ago

(Just a theory)

fifthecho commented 7 years ago

A viable theory. It may be a few days before I can test myself, but if others want to give it a shot and report back, please do.

ubergarm commented 7 years ago

So unfortunately, sanic_dispatcher goes "the wrong way". https://github.com/ashleysommer/sanic-dispatcher/issues/4

Gotta check out this gunicorn worker business... https://github.com/channelcat/sanic/blob/master/docs/sanic/deploying.md#running-via-gunicorn

ubergarm commented 7 years ago

Also some talk over on the Sanic side that seems relevant about Werkzeug and ...a WSGI adapter, that'd allow you to eg. deploy to zappa.

https://github.com/channelcat/sanic/issues/761#issuecomment-313146637