Is anyone here running Supertokens using Python? I...
# support-questions-legacy
d
Is anyone here running Supertokens using Python? I'm trying to follow/use the example, but am not sure how to hook it up to the frontend. No routes are added to the FastAPI (e.g.
session/refresh
) https://github.com/supertokens/supertokens-python/blob/master/examples/with-fastapi/with-thirdpartyemailpassword/main.py
r
hey @da.fant
the routes are added by the supertokens middleware
if you query your API as per this doc: https://app.swaggerhub.com/apis/supertokens/FDI, you will see that the APis exist
d
Ok, might be working now. I'm getting 400s now. Maybe because all client ids etc from env vars are still not configured?
Copy code
2023-05-23 13:56:54 MacBook-Pro-141.lan com.supertokens[94025] DEBUG {"t": "2023-05-23T12:56:54.654Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: emailverification", "file": "supertokens.py:495"}
com.supertokens {"t": "2023-05-23T12:56:54.655Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: thirdpartyemailpassword", "file": "supertokens.py:495"}

2023-05-23 13:56:54 MacBook-Pro-141.lan com.supertokens[94025] DEBUG {"t": "2023-05-23T12:56:54.655Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: thirdpartyemailpassword", "file": "supertokens.py:495"}
com.supertokens {"t": "2023-05-23T12:56:54.655Z", "sdkVer": "0.14.0", "message": "middleware: Not handling because no recipe matched", "file": "supertokens.py:508"}

2023-05-23 13:56:54 MacBook-Pro-141.lan com.supertokens[94025] DEBUG {"t": "2023-05-23T12:56:54.655Z", "sdkVer": "0.14.0", "message": "middleware: Not handling because no recipe matched", "file": "supertokens.py:508"}
INFO:     127.0.0.1:51648 - "OPTIONS /auth/authorisationurl?thirdPartyId=google HTTP/1.1" 400 Bad Request
Is there somewhere in the docs where I can see how to setup google/github auth and get client ids? I've searched but not found it
r
you can start by using the credentials in our docs (see the backend section in quick setup)
also, it seems that the OTIONS API is giving back a 400. We don't really handle the OPTIONS APIs, so maybe check the cors liv you use?
d
yup, cors issue that's now fixed /session/refresh now returns 401 as expected pre-auth Backend init looks like this where env is setup w your test tokens. Any ideas?
Copy code
init(
    supertokens_config=SupertokensConfig(connection_uri="https://try.supertokens.io"),
    # supertokens_config=SupertokensConfig(connection_uri=os.getenv('SUPERTOKENS_API_URL')),
    app_info=InputAppInfo(
      app_name="Godmode",
      api_domain=os.getenv("API_URL"),
      website_domain=os.getenv("APP_URL"),
      # api_gateway_path="",
    ),
    framework="fastapi",
    recipe_list=[
      session.init(),
      dashboard.init(),
      emailverification.init("REQUIRED"),
      thirdpartyemailpassword.init(
        providers=[
          Google(
            is_default=True,
            client_id=os.environ.get("GOOGLE_CLIENT_ID"),  # type: ignore
            client_secret=os.environ.get("GOOGLE_CLIENT_SECRET"),  # type: ignore
          ),
          Google(
            client_id=os.environ.get("GOOGLE_CLIENT_ID_MOBILE"),  # type: ignore
            client_secret=os.environ.get("GOOGLE_CLIENT_SECRET"),  # type: ignore
          ),
          Github(
            is_default=True,
            client_id=os.environ.get("GITHUB_CLIENT_ID"),  # type: ignore
            client_secret=os.environ.get("GITHUB_CLIENT_SECRET"),  # type: ignore
          ),
          Github(
            client_id=os.environ.get("GITHUB_CLIENT_ID_MOBILE"),  # type: ignore
            client_secret=os.environ.get("GITHUB_CLIENT_SECRET_MOBILE"),  # type: ignore
          ),
          GoogleWorkspaces(
            is_default=True,
            client_id=os.environ.get("GOOGLE_WORKSPACES_CLIENT_ID"),  # type: ignore
            client_secret=os.environ.get("GOOGLE_WORKSPACES_CLIENT_SECRET"),  # type: ignore
          ),
        ]
      ),
    ],
    telemetry=False,
)
now getting this. any ideas?
Copy code
2023-05-23 14:08:09 MacBook-Pro-141.lan com.supertokens[94756] DEBUG {"t": "2023-05-23T13:08:09.893Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: emailverification", "file": "supertokens.py:482"}
com.supertokens {"t": "2023-05-23T13:08:09.893Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: thirdpartyemailpassword", "file": "supertokens.py:482"}

2023-05-23 14:08:09 MacBook-Pro-141.lan com.supertokens[94756] DEBUG {"t": "2023-05-23T13:08:09.893Z", "sdkVer": "0.14.0", "message": "middleware: Checking recipe ID for match: thirdpartyemailpassword", "file": "supertokens.py:482"}
com.supertokens {"t": "2023-05-23T13:08:09.894Z", "sdkVer": "0.14.0", "message": "middleware: Not handling because no recipe matched", "file": "supertokens.py:508"}

2023-05-23 14:08:09 MacBook-Pro-141.lan com.supertokens[94756] DEBUG {"t": "2023-05-23T13:08:09.894Z", "sdkVer": "0.14.0", "message": "middleware: Not handling because no recipe matched", "file": "supertokens.py:508"}
INFO:     127.0.0.1:54556 - "GET /auth/authorisationurl?thirdPartyId=google HTTP/1.1" 404 Not Found
r
whats the recipeList that's initialised on the frontend?
d
Copy code
ts
export const config = (): SuperTokensConfig => {
  return {
    appInfo,
    enableDebugLogs: true,
    recipeList: [
      ThirdPartyReact.init({
        signInAndUpFeature: {
          providers: [
            ThirdPartyReact.Google.init(),
            ThirdPartyReact.Github.init(),
          ],
        },
      }),
      SessionReact.init(),
    ],
    windowHandler: (oI: any) => {
      return {
        ...oI,
        location: {
          ...oI.location,
          setHref: (href: string) => {
            Router.push(href)
          },
        },
      }
    },
  }
}
r
right. So you need to use thirdpartyemailpassword on the frontend as well
instead of just thirdparty
d
got it! CORS issue resolved for the session api req, but not for the authorizationurl one. I've tried both the CORS config in fastapi's docs and yours https://fastapi.tiangolo.com/tutorial/cors/ e.g.
Copy code
python
app.add_middleware(
  CORSMiddleware,
  # allow_origins=["*"],
  allow_origins=[os.getenv('APP_URL')],
  # allow_methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"],
  allow_methods=["*"],
  allow_headers=["*"],
  allow_credentials=True,
  # allow_headers=["Content-Type"] + get_all_cors_headers(),
)
req goes through, but browser holds it due to cors:
cess to fetch at 'http://localhost:8000/auth/authorisationurl?thirdPartyId=google' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The rest of my API (unauthed though) works perfectly w CORS. Anything you recognize?
ahh, works when I ordered the middlewares correctly
r
yup!
d
sweet, works now
are there docs for how to set up my own thirdparty clients?
r
we don't have docs for those unfortunately. But it's very easy to find them via google
d
are there best practices for e.g. how to manage something like: * in our DB there's a concept of organizations * a user tries to fetch /api/organization/{org_id}/admin-stuff * make sure the user has role "admin" in the org your current RBAC docs seem to be mostly a flat structure (e.g. global admin). would I do something like
{org_id}:admin
etc and then have basically 1000s of roles?
really appreciate the help!
r
> would I do something like {org_id}:admin etc and then have basically 1000s of roles? Yea. At the moment, this would be the way of doing it. But you can always skip using our roles recipe and use something else for authorization if you want.
d
you mean as in me mapping whatever user id I get from you to roles I manage in my db?
r
yea. if you want to make your own roles system. Else with our roles system, you will need to create {org_id}:admin roles.
d
btw made some tweaks to the default UI to IMO make it look quite a bit better. feel free to steal. I also changed the translation to what I wanted the header to be
Copy code
css
          * {
            font-family: system-ui;
          }

          [data-supertokens~="providerButtonLeft"] {
            margin: 0;
          }

          [data-supertokens~="headerTitle"] {
            letter-spacing: unset;
            font-weight: 500;
            font-size: var(--font-size-2);
          }

          [data-supertokens~="headerTitle"]::before {
            content: " ";
            display: block;
            width: 100%;
            height: 80px;
            background-image: url(/logo.png);
            background-size: contain;
            background-repeat:no-repeat;
            background-position: center center;
            margin-bottom: 16px;
          }

          [data-supertokens~="button"] {
            height: unset;
            font-size: var(--font-size-2);
            padding: 8px;
            display: flex;
            justify-content: center;
          }

https://cdn.discordapp.com/attachments/1110546820809117767/1110570958932164628/image.png

r
Thanks!
d
@rp_st btw I've gotten my qs answered for now, so can cancel the call we have scheduled for today!
r
Cool!
d
another issue cropped up:
"Failed to create init process: failed to load /usr/local/bin/docker-entrypoint.sh: exec format error"
I tried deploying
registry.supertokens.io/supertokens/supertokens-postgresql:5.0
to GCP Cloud Run env:
Copy code
API_KEYS=...
POSTGRESQL_CONNECTION_URI=postgresql://...
SUPERTOKENS_PORT=8080
any ideas on what might go wrong?
r
hmm. this is a new issue
im not sure at the moment. How are you running the core?
d
Copy code
bash
PROJECT_ID="..."
DEPLOYMENT_NAME="..."
IMAGE_NAME="gcr.io/$PROJECT_ID/api"
REGION="us-central1"

gcloud config set project $PROJECT_ID

SUPERTOKENS_IMAGE_NAME="registry.supertokens.io/supertokens/supertokens-postgresql:5.0"
docker pull $SUPERTOKENS_IMAGE_NAME
docker tag $SUPERTOKENS_IMAGE_NAME $IMAGE_NAME
docker push $IMAGE_NAME

ENV_VARS=$(grep -v '^#' .env.demo.supertokens | xargs echo | tr ' ' ',')
gcloud run deploy $DEPLOYMENT_NAME  \
  --image $IMAGE_NAME               \
  --region $REGION                  \
  --platform managed                \
  --allow-unauthenticated           \
  --update-env-vars $ENV_VARS
r
@kakashi_44 can maybe try and help.
k
Hello @da.fant , just to check, are you using the M1 Macbook?
Or any other ARM based machine to execute the above steps?
d
Yes, M2
since I'm just pulling/pushing, should i pull some other image?
I need to pull/push bc GCP doesn't allow docker containers that are hosted in non gcr registries
woo, that did the trick
docker pull --platform linux/amd64 $SUPERTOKENS_IMAGE_NAME
k
Yup, exactly 🙂
GCP requires linux/amd64 image
d
what's the best way to verify "does user X have permission Y" from the DB? atm it seems like I need to do:
Copy code
/recipe/user/roles
for each role:
  /recipe/role/permissions
and check if the perm is in the list
I have a concept of organizations in my app and am currently creating roles and perms like
{organization_id}:admin
has perms
{organization_id}:task.write
. in the endpoint to write a task, I'd want to check if the current user has that permission
r
This is a good way of doing it.
8 Views