Skip to content

Commit

Permalink
refactor: splits async_to_sync_wrapper into a module
Browse files Browse the repository at this point in the history
- Separates logical groups of utils into modules
- Disables pylint cyclic checks on supertokens lazy import
  • Loading branch information
namsnath committed Nov 23, 2024
1 parent 295128b commit 409e664
Show file tree
Hide file tree
Showing 32 changed files with 211 additions and 66 deletions.
4 changes: 2 additions & 2 deletions supertokens_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from typing_extensions import Literal

from supertokens_python import async_to_sync_wrapper
from supertokens_python.async_to_sync.handler import ConcreteAsyncHandler
from supertokens_python.framework.request import BaseRequest
from supertokens_python.types import RecipeUserId

Expand All @@ -37,7 +37,7 @@ def init(
mode: Optional[Literal["asgi", "wsgi"]] = None,
telemetry: Optional[bool] = None,
debug: Optional[bool] = None,
async_handler: Optional[async_to_sync_wrapper.ConcreteAsyncHandler] = None,
async_handler: Optional[ConcreteAsyncHandler] = None,
):
return Supertokens.init(
app_info=app_info,
Expand Down
Empty file.
26 changes: 26 additions & 0 deletions supertokens_python/async_to_sync/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from typing import Any, Coroutine, TypeVar

_T = TypeVar("_T")


def sync(co: Coroutine[Any, Any, _T]) -> _T:
from supertokens_python import supertokens # pylint: disable=cyclic-import

st = supertokens.Supertokens.get_instance()
handler = st.async_handler

return handler.run_as_sync(co)
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,11 @@
from enum import Enum
from threading import Thread
from typing import Any, Coroutine, Optional, TypeVar, Union
from os import getenv
from supertokens_python.async_to_sync.utils import create_or_get_event_loop

_T = TypeVar("_T")


def nest_asyncio_enabled():
return getenv("SUPERTOKENS_NEST_ASYNCIO", "") == "1"


def create_or_get_event_loop() -> asyncio.AbstractEventLoop:
try:
return asyncio.get_event_loop()
except Exception as ex:
if "There is no current event loop in thread" in str(ex):
loop = asyncio.new_event_loop()

if nest_asyncio_enabled():
import nest_asyncio # type: ignore

nest_asyncio.apply(loop) # type: ignore

asyncio.set_event_loop(loop)
return loop
raise ex


class AsyncType(Enum):
asyncio = "asyncio"
gevent = "gevent"
Expand Down Expand Up @@ -187,15 +166,6 @@ def run_as_sync(self, coroutine: Coroutine[Any, Any, _T]) -> _T:
return future.result()


def sync(co: Coroutine[Any, Any, _T]) -> _T:
from supertokens_python import supertokens

st = supertokens.Supertokens.get_instance()
handler = st.async_handler

return handler.run_as_sync(co)


ConcreteAsyncHandler = Union[
DefaultHandler, AsyncioHandler, GeventHandler, EventletHandler
]
37 changes: 37 additions & 0 deletions supertokens_python/async_to_sync/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
#
# This software is licensed under the Apache License, Version 2.0 (the
# "License") as published by the Apache Software Foundation.
#
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import asyncio
from os import getenv


def nest_asyncio_enabled():
return getenv("SUPERTOKENS_NEST_ASYNCIO", "") == "1"


def create_or_get_event_loop() -> asyncio.AbstractEventLoop:
try:
return asyncio.get_event_loop()
except Exception as ex:
if "There is no current event loop in thread" in str(ex):
loop = asyncio.new_event_loop()

if nest_asyncio_enabled():
import nest_asyncio # type: ignore

nest_asyncio.apply(loop) # type: ignore

asyncio.set_event_loop(loop)
return loop
raise ex
16 changes: 12 additions & 4 deletions supertokens_python/framework/flask/flask_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import json
from typing import TYPE_CHECKING, Union

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.framework import BaseResponse

if TYPE_CHECKING:
Expand Down Expand Up @@ -54,13 +54,14 @@ def _():
user_context = default_user_context(request_)

result: Union[BaseResponse, None] = sync(
st.middleware(request_, response_, user_context)
st.middleware(request_, response_, user_context),
)
# result = await st.middleware(request_, response_, user_context)

if result is not None:
if isinstance(result, FlaskResponse):
return result.response
raise Exception("Should never come here")
raise Exception(f"Should never come here, {type(result)=}")
return None

@app.after_request
Expand Down Expand Up @@ -109,8 +110,15 @@ def _(error: Exception):
error,
FlaskResponse(response),
user_context,
)
),
)
# result: BaseResponse = await st.handle_supertokens_error(
# base_request,
# error,
# FlaskResponse(response),
# user_context,
# )

if isinstance(result, FlaskResponse):
return result.response
raise Exception("Should never come here")
2 changes: 1 addition & 1 deletion supertokens_python/querier.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from .process_state import PROCESS_STATE, ProcessState
from .utils import find_max_version, is_4xx_error, is_5xx_error
from sniffio import AsyncLibraryNotFoundError
from supertokens_python.async_to_sync_wrapper import create_or_get_event_loop
from supertokens_python.async_to_sync.utils import create_or_get_event_loop
from supertokens_python.utils import get_timestamp_ms


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# under the License.
from typing import Any, Dict, Optional

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync

from ..types import AccountInfoWithRecipeId
from supertokens_python.types import RecipeUserId
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/emailpassword/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Any, Dict, Union, Optional
from typing_extensions import Literal

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.emailpassword.interfaces import (
SignUpOkResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from typing import Any, Dict, Optional, Union

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.emailverification.types import EmailTemplateVars
from supertokens_python.types import RecipeUserId

Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/jwt/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# under the License.
from typing import Any, Dict, Union, Optional

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.jwt import asyncio
from supertokens_python.recipe.jwt.interfaces import (
CreateJwtOkResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from typing import Any, Dict, Optional, List

from supertokens_python.recipe.session import SessionContainer
from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync


def assert_allowed_to_setup_factor_else_throw_invalid_claim_error(
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/multitenancy/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from __future__ import annotations
from typing import Any, Dict, Optional, TYPE_CHECKING

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.multitenancy.interfaces import TenantConfigCreateOrUpdate
from supertokens_python.types import RecipeUserId

Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/openid/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# under the License.
from typing import Any, Dict, Union, Optional

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.openid import asyncio
from supertokens_python.recipe.openid.interfaces import (
GetOpenIdDiscoveryConfigurationResult,
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/passwordless/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from typing import Any, Dict, List, Optional, Union
from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.auth_utils import LinkingToSessionUserFailedError
from supertokens_python.recipe.passwordless import asyncio
from supertokens_python.recipe.session import SessionContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import Any, Callable, Dict, TypeVar, Union, cast, List, Optional

from supertokens_python import Supertokens
from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.exceptions import SuperTokensError
from supertokens_python.framework.django.django_request import DjangoRequest
from supertokens_python.framework.django.django_response import DjangoResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import Any, Callable, Dict, TypeVar, Union, cast, List, Optional

from supertokens_python import Supertokens
from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.framework.flask.flask_request import FlaskRequest
from supertokens_python.framework.flask.flask_response import FlaskResponse
from supertokens_python.recipe.session import SessionRecipe, SessionContainer
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/session/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
)
from typing_extensions import TypedDict

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.types import (
APIResponse,
GeneralErrorResponse,
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/session/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from __future__ import annotations
from typing import Any, Dict, List, Union, Callable, Optional, TypeVar

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.openid.interfaces import (
GetOpenIdDiscoveryConfigurationResult,
)
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/thirdparty/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# under the License.
from typing import Any, Dict, Optional, Union

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.auth_utils import LinkingToSessionUserFailedError
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.thirdparty.interfaces import (
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/totp/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from typing import Any, Dict, Union, Optional

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync

from supertokens_python.recipe.totp.types import (
CreateDeviceOkResult,
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/usermetadata/syncio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, Dict, Union

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync


def get_user_metadata(user_id: str, user_context: Union[Dict[str, Any], None] = None):
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/recipe/userroles/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from typing import Any, Dict, List, Union

from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.recipe.userroles.interfaces import (
AddRoleToUserOkResult,
CreateNewRoleOrAddPermissionsOkResult,
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/supertokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from typing_extensions import Literal

from supertokens_python.async_to_sync_wrapper import (
from supertokens_python.async_to_sync.handler import (
ConcreteAsyncHandler,
DefaultHandler,
)
Expand Down
2 changes: 1 addition & 1 deletion supertokens_python/syncio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Dict, List, Optional, Union, Any

from supertokens_python import Supertokens
from supertokens_python.async_to_sync_wrapper import sync
from supertokens_python.async_to_sync.base import sync
from supertokens_python.interfaces import (
CreateUserIdMappingOkResult,
DeleteUserIdMappingOkResult,
Expand Down
Loading

0 comments on commit 409e664

Please sign in to comment.