Hi there! Here's the issue I'm facing. I'm at the step where I've deployed FastAPI to an AWS Lambda...
a
Hi there! Here's the issue I'm facing. I'm at the step where I've deployed FastAPI to an AWS Lambda function via Mangum, with Supertokens successfully running (returns hello from /hello), the Lambda function accessing the API database, and the frontend accessing the API. All of these are tested. Unfortunately, I get a cryptic error in the post-signup handler:
Copy code
response = await api_implementation.sign_up_post(
  File \"/var/task/app/users/utils.py\", line 93, in sign_up_post
    response = await original_sign_up_post(form_fields, api_options, user_context)
  File \"/var/lang/lib/python3.9/site-packages/supertokens_python/recipe/emailpassword/api/implementation.py\", line 199, in sign_up_post
    result = await api_options.recipe_implementation.sign_up(
  File \"/var/lang/lib/python3.9/site-packages/supertokens_python/recipe/emailpassword/recipe_implementation.py\", line 123, in sign_up
    response = await self.querier.send_post_request(
  File \"/var/lang/lib/python3.9/site-packages/supertokens_python/querier.py\", line 167, in send_post_request
    return await self.__send_request_helper(path, \"POST\", f, len(self.__hosts))
  File \"/var/lang/lib/python3.9/site-packages/supertokens_python/querier.py\", line 246, in __send_request_helper
    raise_general_exception(e)
  File \"/var/lang/lib/python3.9/site-packages/supertokens_python/exceptions.py\", line 25, in raise_general_exception
    raise GeneralError(msg) from None
supertokens_python.exceptions.GeneralError
Now, I've tried running the same FastAPI locally (sans Lambda), passing the same Supertokens instance and same API database in production (just the API running locally in uvicorn). I was able to successfully create a new user! Then, I was able to successfully sign in as that user via the frontend hitting the Lambda API 🀯 This tells me that the Lambda function does have access to the Supertokens deployment for signin functions, but mysteriously fails for signup.
A few more details that may be relevant: - I keep seeing the following warning in the Lambda function logs:
Copy code
supertokens_python/utils.py:174: RuntimeWarning: Inconsistent mode detected, check if you are using the right asgi / wsgi mode
I was unable to run the Lambda function for a long while, until I used https://github.com/erdewit/nest_asyncio to get around
RuntimeError: no running event loop
issues - the Lambda function is not in a VPC and does have general Internet access
I'm guessing that
GeneralError
means the POST request to Supertokens failed for some reason (ooh, I could check the Supertokens logs, BRB)
r
Hey! @KShivendu can help here (sometime tomorrow since it’s 11 pm here)
a
Nothing useful:
Copy code
20 Sep 2022 17:22:58:758 +0000 | INFO | pid: e91bbb61-5c6a-4188-877a-d95d648640f6 | [http-nio-0.0.0.0-3567-exec-2] thread | io.supertokens.webserver.WebserverAPI.service(WebserverAPI.java:184) | API ended: /recipe/signup. Method: POST
r
Thanks for raising this! Will will get back asap
Hey @adyus3380 we will update the aws lambda docs sometime next week to also include the python SDK. Stay tuned please. That’s the easiest way to help you here
a
That means I'm not doing something right πŸ˜… Looking forward to the new docs! I'll deploy via a Docker container and uvicorn for now
k
Hey @adyus3380, I tried replicated the setup and was able to get everything to work (siginup, siginin, signout, session refresh, protected apis, etc)
Here's what I used:
Copy code
python
from fastapi import FastAPI, Depends
from starlette.middleware.cors import CORSMiddleware
from mangum import Mangum


import nest_asyncio

nest_asyncio.apply()


from supertokens_python import init, SupertokensConfig, InputAppInfo
from supertokens_python.framework.fastapi import get_middleware
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.fastapi import verify_session
from supertokens_python.recipe import session, emailpassword

init(
    supertokens_config=SupertokensConfig(
        connection_uri="XXX",
        api_key="YYY",
    ),
    app_info=InputAppInfo(
        app_name="SuperTokens Demo",
        api_domain="http://localhost:8000",
        website_domain="http://localhost:3000",
        api_base_path="/auth",
    ),
    framework="fastapi",
    recipe_list=[
        session.init(),
        emailpassword.init(),
    ],
    telemetry=False,
    mode="wsgi",
)


app = FastAPI(title="MyAwesomeApp")
app.add_middleware(get_middleware())

@app.get("/hello")
def hello_world():
    return {"message": "Hello World"}


@app.get("/secure")
def secure_api(s: SessionContainer = Depends(verify_session())):
    user_id = s.user_id
    return {"session": user_id}


handler = Mangum(app)

# To run locally: uvicorn lambda_function:app
can you please try this and see if it works? ^
meanwhile, if you share your version of the config, I might be able to find and fix the the GeneralResponseError? πŸ˜„
a
Hi there, it turns out I might not have been deleting an existing user completely (via manual DB intervention), which is why signup (and only signup) was failing on Lambda. I've since switched to running in a Docker container via uvicorn (and had to remove
nest_asyncio
to make it work). However, if/when I return to a Lambda deployment, is the
nest_asyncio
still required, or will there be a fix for that, to make it work out-of-the-box on both uvicorn/other ASGI and Lambda?
Copy code
mode="wsgi"
Oh, I see what you did there. Is this required for Lambda use?
And I can also understand why we wouldn't want telemetry on every Lambda invocation 😁
k
nope.
a
But there's still that warning about
Inconsistent mode detected, check if you are using the right asgi / wsgi mode
So the upcoming docs will clarify that we do need the default
asgi
mode that comes with the FastAPI middleware, plus
nest_asyncio
to make it work with Mangum on Lambda
k
ohh yes. you're right. this warning won't come up if it's running with uvicorn (which supports asyncio). but since it's not the case with AWS Lambda (Mangum), the warning appears.
I could be possible to run it with asyncio in lambda too, but there will be more steps for that. So yeah, for now, please use
mode="wsgi"
πŸ˜„
a
I guess I'll have to test, but would
mode="wsgi"
remove the need for
nest_asyncio
at the top of the file? Would `await`s continue to work with Supertokens functions?
k
Let me confirm that with experiments.
Okay so here's the final thing: - nest_asyncio.apply() is critically important for supertokens-python to work in AWS Lambda. Without that, it cannot work. Even non-supertokens APIs will break if supertokens_python is getting used without
nest_asyncio.apply()
- async route handlers aren't supported in the AWS Lambda environment (probably because Mangum can't handle them). But, async overrides for supertokens will work fine. - Since AWS Lambda (magnum), doesn't support async route handlers, you should import from
from supertokens_python.recipe.X.syncio
(not
asyncio
) - Supertokens-python is smart about wsgi/asgi part. But keep it
wsgi
for AWS Lambda env.
a
Awesome, thank you for doing the legwork! I'm guessing this will go into the upcoming guides as well.
Thanks again and keep up the awesome work you all are doing!
k
thanks πŸ˜„
let me know if I can help you with something else.
a
All set for now, thanks! (well, any estimates on multitenancy? weeks/months/years away? πŸ˜…)
k
@rp_st can answer that πŸ˜„
a
No need, was just curious.
r
months
thanks @KShivendu