From 68a6462dba9c68d4c8cb65178865593d5cee5a0f Mon Sep 17 00:00:00 2001 From: orenzhang Date: Wed, 8 Jan 2025 17:49:45 +0800 Subject: [PATCH] feat(asgi): replace async to sync --- .cruft.json | 2 +- Makefile | 3 ++ apps/account/serializers.py | 32 +++++---------- apps/account/views.py | 71 ++++++++++++++++----------------- apps/application/serializers.py | 2 +- apps/application/views.py | 4 +- apps/cel/tasks/notice.py | 3 +- apps/home/models.py | 2 - apps/home/serializers.py | 5 +-- apps/home/views.py | 12 ++++-- apps/notice/serializers.py | 11 +++-- apps/notice/utils/base.py | 16 ++++---- apps/notice/utils/mail.py | 4 +- apps/notice/utils/msg.py | 2 +- apps/notice/utils/robot.py | 11 ++--- apps/notice/views.py | 21 +++++----- apps/tcloud/serializers.py | 3 +- apps/tcloud/views.py | 5 +-- bin/run.sh | 4 +- core/auth.py | 5 +-- entry/settings.py | 1 - requirements.txt | 4 +- scripts/messages.sh | 7 ++++ 23 files changed, 108 insertions(+), 122 deletions(-) create mode 100755 scripts/messages.sh diff --git a/.cruft.json b/.cruft.json index 9043b40..5931bdd 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/OVINC-CN/DevTemplateDjango.git", - "commit": "1e0028fba6cb111a2ef69038ca07ac74fc95a219", + "commit": "c57436b9cfec6091334edb5b2115ea498911d51c", "checkout": "main", "context": { "cookiecutter": { diff --git a/Makefile b/Makefile index 89c561b..6b0a957 100644 --- a/Makefile +++ b/Makefile @@ -5,3 +5,6 @@ pre-commit: scripts/pre-commit.sh lint: pre-commit pylint + +messages: + scripts/messages.sh diff --git a/apps/account/serializers.py b/apps/account/serializers.py index bc896f7..1c20301 100644 --- a/apps/account/serializers.py +++ b/apps/account/serializers.py @@ -1,9 +1,7 @@ import re -from adrf.serializers import ModelSerializer, Serializer from django.contrib.auth import get_user_model from django.utils.translation import gettext, gettext_lazy -from ovinc_client.core.async_tools import SyncRunner from ovinc_client.tcaptcha.exceptions import TCaptchaInvalid from ovinc_client.tcaptcha.utils import TCaptchaVerify from rest_framework import serializers @@ -21,7 +19,7 @@ USER_MODEL: User = get_user_model() -class UserInfoSerializer(ModelSerializer): +class UserInfoSerializer(serializers.ModelSerializer): """ User Info """ @@ -31,7 +29,7 @@ class Meta: fields = ["username", "nick_name", "last_login", "user_type"] -class SignInSerializer(Serializer): +class SignInSerializer(serializers.Serializer): """ Sign in """ @@ -44,14 +42,12 @@ class SignInSerializer(Serializer): def validate(self, attrs: dict) -> dict: data = super().validate(attrs) - if not SyncRunner().run( - TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify() - ): + if not TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify(): raise TCaptchaInvalid() return data -class UserRegistrySerializer(ModelSerializer): +class UserRegistrySerializer(serializers.ModelSerializer): """ User Registry """ @@ -84,9 +80,7 @@ class Meta: def validate(self, attrs: dict) -> dict: data = super().validate(attrs) - if not SyncRunner().run( - TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify() - ): + if not TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify(): raise TCaptchaInvalid() if not USER_MODEL.check_phone_verify_code( area=data["phone_area"], phone_number=data["phone_number"], code=data["phone_verify"] @@ -108,7 +102,7 @@ def validate_phone_number(self, phone_number: str) -> str: return phone_number -class VerifyCodeRequestSerializer(Serializer): +class VerifyCodeRequestSerializer(serializers.Serializer): """ Verify Code """ @@ -116,7 +110,7 @@ class VerifyCodeRequestSerializer(Serializer): code = serializers.CharField(label=gettext_lazy("Code")) -class WeChatLoginReqSerializer(Serializer): +class WeChatLoginReqSerializer(serializers.Serializer): """ WeChat Login """ @@ -126,7 +120,7 @@ class WeChatLoginReqSerializer(Serializer): is_oauth = serializers.BooleanField(label=gettext_lazy("Is OAuth"), default=False) -class ResetPasswordRequestSerializer(Serializer): +class ResetPasswordRequestSerializer(serializers.Serializer): """ Reset Password """ @@ -144,9 +138,7 @@ class ResetPasswordRequestSerializer(Serializer): def validate(self, attrs: dict) -> dict: data = super().validate(attrs) - if not SyncRunner().run( - TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify() - ): + if not TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify(): raise TCaptchaInvalid() if not USER_MODEL.check_phone_verify_code( area=data["phone_area"], phone_number=data["phone_number"], code=data["phone_verify"] @@ -155,7 +147,7 @@ def validate(self, attrs: dict) -> dict: return data -class SendVerifyCodeRequestSerializer(Serializer): +class SendVerifyCodeRequestSerializer(serializers.Serializer): """ Verify Code """ @@ -166,8 +158,6 @@ class SendVerifyCodeRequestSerializer(Serializer): def validate(self, attrs: dict) -> dict: data = super().validate(attrs) - if not SyncRunner().run( - TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify() - ): + if not TCaptchaVerify(user_ip=self.context.get("user_ip", ""), **data.get("tcaptcha", {})).verify(): raise TCaptchaInvalid() return data diff --git a/apps/account/views.py b/apps/account/views.py index fff7af4..9419d1d 100644 --- a/apps/account/views.py +++ b/apps/account/views.py @@ -3,7 +3,6 @@ from json import JSONDecodeError import httpx -from channels.db import database_sync_to_async from django.conf import settings from django.contrib import auth from django.contrib.auth import get_user_model @@ -53,13 +52,13 @@ class UserInfoViewSet(MainViewSet): queryset = USER_MODEL.get_queryset() serializer_class = UserInfoSerializer - async def list(self, request, *args, **kwargs): + def list(self, request, *args, **kwargs): """ Get User Info """ serializer = self.serializer_class(instance=request.user) - return Response(await serializer.adata) + return Response(serializer.data) class UserSignViewSet(MainViewSet): @@ -70,7 +69,7 @@ class UserSignViewSet(MainViewSet): queryset = USER_MODEL.get_queryset() @action(methods=["POST"], detail=False, authentication_classes=[SessionAuthenticate]) - async def sign_in(self, request, *args, **kwargs): + def sign_in(self, request, *args, **kwargs): """ Sign in """ @@ -81,16 +80,16 @@ async def sign_in(self, request, *args, **kwargs): request_data = request_serializer.validated_data # login - user: User = await database_sync_to_async(auth.authenticate)(request, **request_data) + user: User = auth.authenticate(request, **request_data) if not user: raise WrongSignInParam() # bind wechat if request_data.get("wechat_code"): - await self.update_user_by_wechat(user, request_data["wechat_code"]) + self.update_user_by_wechat(user, request_data["wechat_code"]) # auth session - await database_sync_to_async(auth.login)(request, user) + auth.login(request, user) # oauth if request_data["is_oauth"]: @@ -99,27 +98,27 @@ async def sign_in(self, request, *args, **kwargs): return Response() @action(methods=["GET"], detail=False) - async def sign_out(self, request, *args, **kwargs): + def sign_out(self, request, *args, **kwargs): """ Sign out """ - await database_sync_to_async(auth.logout)(request) + auth.logout(request) return Response() @action(methods=["POST"], detail=False, authentication_classes=[SessionAuthenticate]) - async def sign_up(self, request, *args, **kwargs): + def sign_up(self, request, *args, **kwargs): """ sign up """ # validate request request_serializer = UserRegistrySerializer(data=request.data, context={"user_ip": get_ip(request)}) - await database_sync_to_async(request_serializer.is_valid)(raise_exception=True) + request_serializer.is_valid(raise_exception=True) request_data = request_serializer.validated_data # save - user = await database_sync_to_async(USER_MODEL.objects.create_user)( + user = USER_MODEL.objects.create_user( last_login=datetime.datetime.now(), username=request_data["username"], password=request_data["password"], @@ -129,10 +128,10 @@ async def sign_up(self, request, *args, **kwargs): # bind wechat if request_data.get("wechat_code"): - await self.update_user_by_wechat(user, request_data["wechat_code"]) + self.update_user_by_wechat(user, request_data["wechat_code"]) # login session - await database_sync_to_async(auth.login)(request, user) + auth.login(request, user) # oauth if request_data["is_oauth"]: @@ -147,7 +146,7 @@ async def sign_up(self, request, *args, **kwargs): authentication_classes=[SessionAuthenticate], throttle_classes=[SMSRateThrottle, IPRateThrottle], ) - async def phone_verify_code(self, request, *args, **kwargs): + def phone_verify_code(self, request, *args, **kwargs): """ send verify code """ @@ -164,7 +163,7 @@ async def phone_verify_code(self, request, *args, **kwargs): return Response() @action(methods=["GET"], detail=False) - async def oauth_code(self, request, *args, **kwargs): + def oauth_code(self, request, *args, **kwargs): """ oauth code """ @@ -172,7 +171,7 @@ async def oauth_code(self, request, *args, **kwargs): return Response({"code": request.user.generate_oauth_code()}) @action(methods=["POST"], detail=False, authentication_classes=[ApplicationAuthenticate]) - async def verify_code(self, request, *args, **kwargs): + def verify_code(self, request, *args, **kwargs): """ verify oauth code """ @@ -183,13 +182,13 @@ async def verify_code(self, request, *args, **kwargs): request_data = request_serializer.validated_data # load user - is_success, user = await database_sync_to_async(USER_MODEL.check_oauth_code)(request_data["code"]) + is_success, user = USER_MODEL.check_oauth_code(request_data["code"]) if is_success: - return Response(await UserInfoSerializer(instance=user).adata) + return Response(UserInfoSerializer(instance=user).data) raise WrongToken() @action(methods=["GET"], detail=False, authentication_classes=[SessionAuthenticate]) - async def wechat_config(self, request, *args, **kwargs): + def wechat_config(self, request, *args, **kwargs): """ WeChat Config """ @@ -209,7 +208,7 @@ async def wechat_config(self, request, *args, **kwargs): # pylint: disable=R0914 @action(methods=["POST"], detail=False, authentication_classes=[SessionAuthenticate]) - async def wechat_login(self, request, *args, **kwargs): + def wechat_login(self, request, *args, **kwargs): """ WeChat Login """ @@ -241,15 +240,15 @@ async def wechat_login(self, request, *args, **kwargs): f"&code={request_data['code']}" f"&grant_type={WeChatAuthType.CODE}" ) - client = httpx.AsyncClient() + client = httpx.Client() try: - resp = await client.get(url) + resp = client.get(url) access_info = resp.json() except Exception as err: logger.exception("[CallWeChatAPIFailed] %s %s", url, err) raise WeChatLoginFailed() from err finally: - await client.aclose() + client.close() if "openid" not in access_info: logger.error("[WeChatLoginFailed] %s", access_info) @@ -259,31 +258,31 @@ async def wechat_login(self, request, *args, **kwargs): url = ( f"{settings.WECHAT_USER_INFO_API}?access_token={access_info['access_token']}&openid={access_info['openid']}" ) - client = httpx.AsyncClient() + client = httpx.Client() try: - resp = await client.get(url) + resp = client.get(url) user_info = resp.json() except Exception as err: logger.exception("[CallWeChatAPIFailed] %s", url, err) raise WeChatLoginFailed() from err finally: - await client.aclose() + client.close() code = uniq_id() cache_key = WECHAT_USER_INFO_KEY.format(code=code) cache.set(cache_key, json.dumps(user_info, ensure_ascii=False), timeout=settings.WECHAT_SCOPE_TIMEOUT) # load user - user: User = await database_sync_to_async(USER_MODEL.load_user_by_union_id)(union_id=user_info["unionid"]) + user: User = USER_MODEL.load_user_by_union_id(union_id=user_info["unionid"]) if user: - await self.update_user_by_wechat(user, code) - await database_sync_to_async(auth.login)(request, user) + self.update_user_by_wechat(user, code) + auth.login(request, user) return Response({"code": user.generate_oauth_code() if request_data["is_oauth"] else ""}) # need registry return Response({"wechat_code": code}) - async def update_user_by_wechat(self, user: User, wechat_code: str) -> None: + def update_user_by_wechat(self, user: User, wechat_code: str) -> None: """ Update User Info By WeChat """ @@ -299,10 +298,10 @@ async def update_user_by_wechat(self, user: User, wechat_code: str) -> None: user.wechat_union_id = user_info["unionid"] user.wechat_open_id = user_info["openid"] user.avatar = user_info["headimgurl"] - await database_sync_to_async(user.save)(update_fields=["wechat_union_id", "wechat_open_id", "avatar"]) + user.save(update_fields=["wechat_union_id", "wechat_open_id", "avatar"]) @action(methods=["POST"], detail=False, authentication_classes=[SessionAuthenticate]) - async def reset_password(self, request, *args, **kwargs) -> Response: + def reset_password(self, request, *args, **kwargs) -> Response: """ Reset Password """ @@ -314,19 +313,19 @@ async def reset_password(self, request, *args, **kwargs) -> Response: # load user try: - user: User = await database_sync_to_async(USER_MODEL.objects.get)( + user: User = USER_MODEL.objects.get( username=request_data["username"], phone_number=request_data["phone_number"] ) except USER_MODEL.DoesNotExist as err: raise UserNotExist() from err # set new password - await database_sync_to_async(user.reset_password)(request_data["password"]) + user.reset_password(request_data["password"]) return Response() @action(methods=["GET"], detail=False, authentication_classes=[SessionAuthenticate]) - async def phone_areas(self, request, *args, **kwargs) -> Response: + def phone_areas(self, request, *args, **kwargs) -> Response: """ Phone Number Areas """ diff --git a/apps/application/serializers.py b/apps/application/serializers.py index 4fa17f3..cd25c49 100644 --- a/apps/application/serializers.py +++ b/apps/application/serializers.py @@ -1,5 +1,5 @@ -from adrf.serializers import ModelSerializer from django.contrib.auth import get_user_model +from rest_framework.serializers import ModelSerializer from apps.account.models import User from apps.application.models import Application diff --git a/apps/application/views.py b/apps/application/views.py index 42d3804..e0fcc13 100644 --- a/apps/application/views.py +++ b/apps/application/views.py @@ -23,7 +23,7 @@ class ApplicationViewSet(MainViewSet): serializer_class = ApplicationSerializer @action(methods=["GET"], detail=False, authentication_classes=[SessionAuthenticate]) - async def all(self, request, *args, **kwargs): + def all(self, request, *args, **kwargs): """ list all applications """ @@ -33,4 +33,4 @@ async def all(self, request, *args, **kwargs): # response serializer = ApplicationListSerializer(queryset, many=True) - return Response(await serializer.adata) + return Response(serializer.data) diff --git a/apps/cel/tasks/notice.py b/apps/cel/tasks/notice.py index bc7ec03..454ed06 100644 --- a/apps/cel/tasks/notice.py +++ b/apps/cel/tasks/notice.py @@ -1,4 +1,3 @@ -from asgiref.sync import async_to_sync from ovinc_client.core.logger import celery_logger from apps.cel import app @@ -10,5 +9,5 @@ def send_notice(self, notice_type: str, **kwargs): from apps.notice.utils import NoticeBase celery_logger.info(f"[SendNotice] Start {self.request.id}") - async_to_sync(NoticeBase.get_instance(notice_type, **kwargs).send)() + NoticeBase.get_instance(notice_type, **kwargs).send() celery_logger.info(f"[SendNotice] End {self.request.id}") diff --git a/apps/home/models.py b/apps/home/models.py index 7b86029..60ac1a7 100644 --- a/apps/home/models.py +++ b/apps/home/models.py @@ -1,6 +1,5 @@ from typing import Dict -from channels.db import database_sync_to_async from django.db import models from django.db.models import Q from django.utils.translation import gettext_lazy @@ -26,6 +25,5 @@ def __str__(self): return str(self.key) @classmethod - @database_sync_to_async def as_map(cls, condition: Q) -> Dict[str, str]: return {config.key: config.val for config in cls.objects.filter(condition)} diff --git a/apps/home/serializers.py b/apps/home/serializers.py index b12ec66..a068346 100644 --- a/apps/home/serializers.py +++ b/apps/home/serializers.py @@ -1,11 +1,10 @@ -from adrf.serializers import Serializer from django.utils.translation import check_for_language, gettext_lazy from rest_framework import serializers from apps.home.exceptions import LanguageCodeInvalid -class I18nRequestSerializer(Serializer): +class I18nRequestSerializer(serializers.Serializer): """ I18n """ @@ -18,7 +17,7 @@ def validate_language(self, language: str) -> str: raise LanguageCodeInvalid() -class MetaConfigQuerySerializer(Serializer): +class MetaConfigQuerySerializer(serializers.Serializer): """ MetaConfig """ diff --git a/apps/home/views.py b/apps/home/views.py index 7c7f356..9f786d0 100644 --- a/apps/home/views.py +++ b/apps/home/views.py @@ -21,7 +21,7 @@ class HomeView(MainViewSet): queryset = USER_MODEL.get_queryset() authentication_classes = [SessionAuthenticate] - async def list(self, request, *args, **kwargs): + def list(self, request, *args, **kwargs): msg = f"[{request.method}] Connect Success" return Response( { @@ -38,7 +38,7 @@ class I18nViewSet(MainViewSet): authentication_classes = [SessionAuthenticate] - async def create(self, request, *args, **kwargs): + def create(self, request, *args, **kwargs): """ Change Language """ @@ -56,6 +56,10 @@ async def create(self, request, *args, **kwargs): lang_code, max_age=settings.SESSION_COOKIE_AGE, domain=settings.SESSION_COOKIE_DOMAIN, + path=settings.SESSION_COOKIE_PATH, + secure=settings.SESSION_COOKIE_SECURE or None, + httponly=settings.SESSION_COOKIE_HTTPONLY or None, + samesite=settings.SESSION_COOKIE_SAMESITE, ) return response @@ -68,7 +72,7 @@ class MetaConfigViewSet(MainViewSet): queryset = MetaConfig.get_queryset() authentication_classes = [SessionAuthenticate] - async def list(self, request, *args, **kwargs): + def list(self, request, *args, **kwargs): """ Meta Config """ @@ -81,4 +85,4 @@ async def list(self, request, *args, **kwargs): if request_data: condition &= Q(**request_data) - return Response(await MetaConfig.as_map(condition)) + return Response(MetaConfig.as_map(condition)) diff --git a/apps/notice/serializers.py b/apps/notice/serializers.py index 013b4b9..191ecc6 100644 --- a/apps/notice/serializers.py +++ b/apps/notice/serializers.py @@ -1,4 +1,3 @@ -from adrf.serializers import ModelSerializer, Serializer from django.conf import settings from django.utils.translation import gettext_lazy from rest_framework import serializers @@ -6,7 +5,7 @@ from apps.notice.models import Robot -class NoticeRequestSerializer(Serializer): +class NoticeRequestSerializer(serializers.Serializer): """ Notice Base """ @@ -17,7 +16,7 @@ class NoticeRequestSerializer(Serializer): content = serializers.JSONField(label=gettext_lazy("Content")) -class MailContentSerializer(Serializer): +class MailContentSerializer(serializers.Serializer): """ Mail Content """ @@ -34,7 +33,7 @@ class MailRequestSerialzier(NoticeRequestSerializer): content = MailContentSerializer(label=gettext_lazy("Content")) -class SmsContentSerializer(Serializer): +class SmsContentSerializer(serializers.Serializer): """ SMS Content """ @@ -51,7 +50,7 @@ class SmsRequestSerializer(NoticeRequestSerializer): content = SmsContentSerializer(label=gettext_lazy("Content")) -class RegistryRobotSerializer(ModelSerializer): +class RegistryRobotSerializer(serializers.ModelSerializer): """ registry robot """ @@ -61,7 +60,7 @@ class Meta: fields = "__all__" -class RobotRequestSerializer(Serializer): +class RobotRequestSerializer(serializers.Serializer): """ Robot """ diff --git a/apps/notice/utils/base.py b/apps/notice/utils/base.py index 59b31fc..828421a 100644 --- a/apps/notice/utils/base.py +++ b/apps/notice/utils/base.py @@ -2,8 +2,6 @@ import traceback from typing import List, Union -from asgiref.sync import async_to_sync -from channels.db import database_sync_to_async from django.contrib.auth import get_user_model from django.utils.module_loading import import_string from django.utils.translation import gettext @@ -22,8 +20,9 @@ class NoticeBase: Notice Base """ + # pylint: disable=R1710 @classmethod - async def send_notice(cls, notice_type: str, is_async: bool = True, **kwargs) -> None: + def send_notice(cls, notice_type: str, is_async: bool = True, **kwargs) -> None: if is_async: send_notice.delay(notice_type, **kwargs) return None @@ -40,7 +39,7 @@ def get_instance(cls, notice_type: str, **kwargs) -> "NoticeBase": def __init__(self, usernames: List[str], content: Union[dict, str], **kwargs) -> None: self.kwargs = kwargs - self.receivers = async_to_sync(self._load_receivers)(usernames) + self.receivers = self._load_receivers(usernames) self.content = self._build_content(content) @property @@ -48,33 +47,32 @@ def __init__(self, usernames: List[str], content: Union[dict, str], **kwargs) -> def property_key(self) -> str: raise NotImplementedError - async def send(self) -> None: + def send(self) -> None: """ send notice """ logger.info("[%s SendNotice] Content => %s", self.__class__.__name__, self.content) try: - result = await self._send() + result = self._send() logger.info("[%s SendNoticeSuccess] Result => %s", self.__class__.__name__, result) except Exception as err: # pylint: disable=W0718 msg = traceback.format_exc() logger.error("[%s SendNoticeFailed] Err => %s; Detail => %s", self.__class__.__name__, err, msg) result = {"err": str(err)} - await database_sync_to_async(NoticeLog.objects.create)( + NoticeLog.objects.create( receivers=self.receivers, content=self.content, extra_params=self.kwargs, result=str(result) ) return result @abc.abstractmethod - async def _send(self) -> None: + def _send(self) -> None: """ send notice """ raise NotImplementedError - @database_sync_to_async def _load_receivers(self, usernames: List[str]) -> List[str]: """ trans username to receiver diff --git a/apps/notice/utils/mail.py b/apps/notice/utils/mail.py index 979b2d2..05abb13 100644 --- a/apps/notice/utils/mail.py +++ b/apps/notice/utils/mail.py @@ -23,11 +23,11 @@ def __init__(self, usernames: List[str], content: Union[dict, str], **kwargs) -> def property_key(self) -> str: return "email_address" - async def _send(self) -> None: + def _send(self) -> None: connection = EmailBackend( host=self.host, port=self.port, username=self.username, password=self.password, use_ssl=True ) - return send_mail( + send_mail( subject=self.content["title"], message=self.content["content"], from_email=self.username, diff --git a/apps/notice/utils/msg.py b/apps/notice/utils/msg.py index b36a731..465aad7 100644 --- a/apps/notice/utils/msg.py +++ b/apps/notice/utils/msg.py @@ -21,7 +21,7 @@ def __init__(self, usernames: List[str], content: Union[dict, str], **kwargs): def property_key(self): return "phone_number" - async def _send(self) -> None: + def _send(self) -> None: req = models.SendSmsRequest() req.SmsSdkAppId = settings.NOTICE_MSG_TCLOUD_APP req.SignName = settings.NOTICE_MSG_TCLOUD_SIGN diff --git a/apps/notice/utils/robot.py b/apps/notice/utils/robot.py index 4476203..9be49b0 100644 --- a/apps/notice/utils/robot.py +++ b/apps/notice/utils/robot.py @@ -1,7 +1,6 @@ from typing import List, Union import httpx -from channels.db import database_sync_to_async from ovinc_client.core.logger import logger from apps.notice.models import Robot @@ -19,19 +18,15 @@ class RobotHandler(NoticeBase): def __init__(self, robots: List[str], content: Union[dict, str], **kwargs) -> None: super().__init__(robots, content, **kwargs) - async def _send(self) -> list: + def _send(self) -> list: result = [] - client = httpx.AsyncClient() - try: + with httpx.Client() as client: for robot in self.receivers: - resp = await client.post(robot, json=self.content) + resp = client.post(robot, json=self.content) result.append(resp.json()) - finally: - await client.aclose() return result # pylint: disable=W0237 - @database_sync_to_async def _load_receivers(self, robot_ids: List[str]) -> List[str]: """ robot id diff --git a/apps/notice/views.py b/apps/notice/views.py index d655328..5990a11 100644 --- a/apps/notice/views.py +++ b/apps/notice/views.py @@ -1,4 +1,3 @@ -from channels.db import database_sync_to_async from django.shortcuts import get_object_or_404 from ovinc_client.core.viewsets import MainViewSet from rest_framework.decorators import action @@ -27,7 +26,7 @@ class NoticeViewSet(MainViewSet): throttle_classes = [AppRateThrottle] @action(methods=["POST"], detail=False) - async def mail(self, request, *args, **kwargs): + def mail(self, request, *args, **kwargs): """ mail """ @@ -38,11 +37,11 @@ async def mail(self, request, *args, **kwargs): request_data = request_serializer.validated_data # send - await NoticeBase.send_notice(NoticeWayChoices.MAIL, **request_data) + NoticeBase.send_notice(NoticeWayChoices.MAIL, **request_data) return Response() @action(methods=["POST"], detail=False) - async def sms(self, request, *args, **kwargs): + def sms(self, request, *args, **kwargs): """ sms """ @@ -53,11 +52,11 @@ async def sms(self, request, *args, **kwargs): request_data = request_serializer.validated_data # send - await NoticeBase.send_notice(NoticeWayChoices.MSG, **request_data) + NoticeBase.send_notice(NoticeWayChoices.MSG, **request_data) return Response() @action(methods=["POST"], detail=False) - async def robot(self, request, *args, **kwargs): + def robot(self, request, *args, **kwargs): """ robot of Wecom or Feishu """ @@ -68,11 +67,11 @@ async def robot(self, request, *args, **kwargs): request_data = request_serializer.validated_data # send - await NoticeBase.send_notice(NoticeWayChoices.ROBOT, **request_data) + NoticeBase.send_notice(NoticeWayChoices.ROBOT, **request_data) return Response() @action(methods=["POST"], detail=False) - async def registry_robot(self, request, *args, **kwargs): + def registry_robot(self, request, *args, **kwargs): """ registry robot """ @@ -80,13 +79,13 @@ async def registry_robot(self, request, *args, **kwargs): # get instance instance = None if request.data.get("id"): - instance = await database_sync_to_async(get_object_or_404)(Robot, pk=request.data.pop("id")) + instance = get_object_or_404(Robot, pk=request.data.pop("id")) # validate request request_serializer = RegistryRobotSerializer(instance=instance, data=request.data, partial=bool(instance)) request_serializer.is_valid(raise_exception=True) # save - await request_serializer.asave() + request_serializer.save() - return Response(await request_serializer.adata) + return Response(request_serializer.data) diff --git a/apps/tcloud/serializers.py b/apps/tcloud/serializers.py index d9e4df4..f85614b 100644 --- a/apps/tcloud/serializers.py +++ b/apps/tcloud/serializers.py @@ -1,9 +1,8 @@ -from adrf.serializers import Serializer from rest_framework import serializers from apps.tcloud.constants import CICallbackEventName -class TCICallbackSerializer(Serializer): +class TCICallbackSerializer(serializers.Serializer): EventName = serializers.ChoiceField(choices=CICallbackEventName.choices) JobsDetail = serializers.JSONField() diff --git a/apps/tcloud/views.py b/apps/tcloud/views.py index a10fddd..693a166 100644 --- a/apps/tcloud/views.py +++ b/apps/tcloud/views.py @@ -1,4 +1,3 @@ -from channels.db import database_sync_to_async from django.conf import settings from django.utils.translation import gettext from ovinc_client.core.auth import SessionAuthenticate @@ -19,7 +18,7 @@ class AuditCallbackViewSet(MainViewSet): authentication_classes = [SessionAuthenticate] - async def create(self, request: Request, *args, **kwargs) -> Response: + def create(self, request: Request, *args, **kwargs) -> Response: """ callback """ @@ -27,7 +26,7 @@ async def create(self, request: Request, *args, **kwargs) -> Response: req_slz = TCICallbackSerializer(data=request.data) req_slz.is_valid(raise_exception=True) # save - callback = await database_sync_to_async(AuditCallback.add_callback)(req_slz.validated_data) + callback = AuditCallback.add_callback(req_slz.validated_data) if callback.is_sensitive: send_notice.delay( notice_type=NoticeWayChoices.ROBOT, diff --git a/bin/run.sh b/bin/run.sh index f9758e4..0080b8d 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -2,6 +2,6 @@ python manage.py collectstatic --noinput python manage.py migrate --noinput -nohup python manage.py celery worker -c 4 -l INFO >/dev/stdout 2>&1 & +nohup python manage.py celery worker -c ${WORKER_COUNT:-1} -l INFO >/dev/stdout 2>&1 & nohup python manage.py celery beat -l INFO >/dev/stdout 2>&1 & -gunicorn --bind "[::]:8020" -w $WEB_PROCESSES --threads $WEB_THREADS -k uvicorn_worker.UvicornWorker --proxy-protocol --proxy-allow-from "*" --forwarded-allow-ips "*" entry.asgi:application +gunicorn --bind "[::]:8020" -w ${WEB_PROCESSES:-1} --threads ${WEB_THREADS:-10} -k uvicorn_worker.UvicornWorker --proxy-protocol --proxy-allow-from "*" --forwarded-allow-ips "*" entry.asgi:application diff --git a/core/auth.py b/core/auth.py index 4058bb5..d793a2d 100644 --- a/core/auth.py +++ b/core/auth.py @@ -1,4 +1,3 @@ -from channels.db import database_sync_to_async from django.contrib.auth import get_user_model from django.utils.translation import gettext from rest_framework.authentication import BaseAuthentication @@ -22,7 +21,7 @@ class ApplicationAuthenticate(BaseAuthentication): """ # pylint: disable=W0236 - async def authenticate(self, request: Request) -> (Application, None): + def authenticate(self, request: Request) -> (Application, None): # load params app_code = request.headers.get(APP_AUTH_HEADER_APPID_KEY) signature = request.headers.get(APP_AUTH_HEADER_APPID_SIGN) @@ -32,7 +31,7 @@ async def authenticate(self, request: Request) -> (Application, None): raise AppAuthFailed(gettext("App Auth Headers Not Exist")) # varify app try: - app = await database_sync_to_async(Application.objects.get)(pk=app_code) + app = Application.objects.get(pk=app_code) except Application.DoesNotExist as err: # pylint: disable=E1101 raise AppAuthFailed(gettext("App Not Exist")) from err # verify secret diff --git a/entry/settings.py b/entry/settings.py index 13fcb71..65e1870 100644 --- a/entry/settings.py +++ b/entry/settings.py @@ -43,7 +43,6 @@ "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", - "adrf", "sslserver", "apps.account", "apps.application", diff --git a/requirements.txt b/requirements.txt index f672b1a..100c0d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ # ovinc -ovinc-client==0.3.16 +ovinc-client==0.4.0b5 # Celery celery==5.4.0 -# Async +# ASGI asgiref==3.8.1 channels[daphne]==4.2.0 channels_redis==4.2.1 diff --git a/scripts/messages.sh b/scripts/messages.sh new file mode 100755 index 0000000..e9c425e --- /dev/null +++ b/scripts/messages.sh @@ -0,0 +1,7 @@ +export PACKAGE_PATH=`python -c "import site; print(site.getsitepackages()[0])"` + +ln -s "$PACKAGE_PATH/ovinc_client" ovinc_client + +python manage.py makemessages -l zh_Hans --no-wrap --no-location -s + +rm ovinc_client