-
Notifications
You must be signed in to change notification settings - Fork 39
Notes about the python SDK
- Python SDK is designed to be async-first for performance but we expose sync variants of those functions using our
sync
function (Actually, it also uses an event loop but makes async functions compatible with sync frameworks/workers)from supertokens_python.async_to_sync_wrapper import sync import asyncio sync(asyncio.sleep(1)) # Note how you didn't have to use `await` here print("Slept for 1 sec")
Publically exposed syncio
and asyncio
functions have separate directories/modules. Please make sure that they are always consistent with each other.
- To run tests in CI without dev tag, you can create a branch
test-cicd/*
and circleci will pick it up.
git checkout -b test-cicd/my-feature
git push --set-upstream origin test-cicd/my-feature
-
It's very likely that you'll face cyclic dependency error. You'll generally have 2 kinds of solutions:
- Often, you are mostly just using the import for typing, so in that case, just use:
from typing import TYPE_CHECKING if TYPE_CHECKING: from foo import Bar def bar(b: Bar) -> None: pass
- And sometimes, you might have to slightly change the design (most of the times just the import structure). Watch this video to understand more https://www.youtube.com/watch?v=UnKa_t-M_kM
-
You might also be have to use a type before defining it, in such cases, try this:
from __future__ import annotations
-
You'd often face pylint/pyright errors. In that case, you can either find a fix or add comment
# pylint: disable=rule-name
. Here rule name can be found by quickly doing a search. Some examples areno-self-use
,redefined-builtin
,too-many-public-methods
, etc. But please disable them as the last resort. Try always to find a cleaner approach because we have added pylint to ensure best practices. -
In python SDK, we had to introduce a response mutators to attach session to the response object. They are nothing but list of functions that are given a response object and the functions run in sequence (to alter headers, cookies, etc) just before sending the response to the end user.
-
Mappings for equivalent files in Node vs. Python SDK:
error.ts => exceptions.py
index.ts => __init__.py
types.ts => interfaces.py
- We often use
ABC
to implement abstract base classes
from abc import ABC
from typing import Literal
class ContactConfig(ABC):
STATIC_VARIABLE: str = "value"
@staticmethod
def my_static_method(): # Note that self isn't passed
return "foo"
@property
def prop(self):
return "bar"
def __init__(self, contact_method: Literal["PHONE", "EMAIL", "EMAIL_OR_PHONE"]):
self.contact_method = contact_method
@abc.abstractmethod
async def method_to_implement_in_child():
pass
Try to follow Google's python style guide. As a devtools company, it's important that our SDKs feel native and smooth for our users (developers)
- To work across multiple versions of python (and python libraries), use
virtualenvwrapper
. It's a create utility that helps you seamlessly create and enter python virtual environments. - Try using PyCharm for editing code. It's refactor feature and speed are unparalleled.
- Setup alias likes:
alias mc="make check-lint"
alias mf="make format"
alias mfc="mf && mc"
- We should try to better document python functions using doc strings (and possibly provide examples for using the function)
def foo():
"""one line description
lengthy description and notes (if any)
Args:
param1: ...
param2: ...
Returns:
Lengthy description with example (if possible)
Raises:
IOError: ...
"""
- We should setup code coverage reports so it's easier to identify lines that are untouched by tests.