diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fee236562..e226e7be7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,10 @@ name: "CodeQL" on: push: - branches: [ master ] + branches: [ master, develop ] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [ master, develop ] schedule: - cron: '22 11 * * 4' @@ -39,11 +39,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -54,7 +54,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -68,4 +68,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml deleted file mode 100644 index 7d7741a5d..000000000 --- a/.github/workflows/eslint.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: ESLint - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install modules - run: | - cd src/pages - npm i - - name: Run ESLint - run: | - cd src/pages - npx eslint --ext .js,.vue src/ diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml new file mode 100644 index 000000000..7023b0652 --- /dev/null +++ b/.github/workflows/eslint.yml @@ -0,0 +1,26 @@ +name: ESLint + +on: + push: + branches: [ master, develop, pre_*, ft_* ] + pull_request: + branches: [ master, develop, pre_*, ft_* ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'npm' + cache-dependency-path: 'src/pages/yarn.lock' + - name: Install modules + run: | + cd src/pages + npm i + - name: Run ESLint + run: | + cd src/pages + npx eslint --ext .js,.vue src/ diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index b38f5460c..bee830c47 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -2,9 +2,9 @@ name: Python CI Check on: push: - branches: [ master, develop ] + branches: [ master, develop, pre_*, ft_* ] pull_request: - branches: [ master, develop ] + branches: [ master, develop, pre_*, ft_* ] jobs: build: @@ -14,23 +14,24 @@ jobs: matrix: python-version: [3.6.14] poetry-version: [1.1.7] - os: [ubuntu-18.04] + os: [ubuntu-20.04] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Install poetry + run: pipx install poetry==${{ matrix.poetry-version }} + - name: Export requirements.txt + run: poetry export -f requirements.txt --dev --without-hashes -o requirements.txt --no-ansi - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Set up Poetry - uses: abatilo/actions-poetry@v2.1.0 - with: - poetry-version: ${{ matrix.poetry-version }} + cache: 'pip' + cache-dependency-path: 'requirements.txt' - name: Install dependencies - run: poetry config virtualenvs.create false && poetry install + run: pip install -r requirements.txt -i https://pypi.org/simple/ - name: Lint with flake8 run: pflake8 src/ --config=pyproject.toml - name: Lint with mypy run: mypy src/ --config-file=pyproject.toml - diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index d9f73e751..1ac76a0d6 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -2,9 +2,9 @@ name: Unittest on: push: - branches: [ master, develop ] + branches: [ master, develop, pre_*, ft_* ] pull_request: - branches: [ master, develop ] + branches: [ master, develop, pre_*, ft_* ] jobs: build: @@ -13,7 +13,7 @@ jobs: matrix: python-version: [3.6.14] poetry-version: [1.1.7] - os: [ubuntu-18.04] + os: [ubuntu-20.04] runs-on: ${{ matrix.os }} env: @@ -23,7 +23,7 @@ jobs: DB_PORT: 3306 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: samin/mysql-action@v1.3 with: mysql version: '5.7' @@ -31,18 +31,22 @@ jobs: mysql root password: ${{ env.DB_PASSWORD }} mysql user: ${{ env.DB_USER }} mysql password: ${{ env.DB_PASSWORD }} + - name: Install poetry + run: pipx install poetry==${{ matrix.poetry-version }} + - name: Export requirements.txt + run: | + cd src/api/ + bash bin/export_requirements_txt.sh - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Set up Poetry - uses: abatilo/actions-poetry@v2.1.0 - with: - poetry-version: ${{ matrix.poetry-version }} + cache: 'pip' + cache-dependency-path: 'src/api/requirements.txt' - name: Install dependencies run: | cd src/api/ - poetry config virtualenvs.create false && bash bin/install_ci_dependencies.sh + pip install -r requirements.txt -i https://pypi.org/simple/ - name: Run api unittest env: DJANGO_SETTINGS_MODULE: "bkuser_core.config.overlays.unittest" diff --git a/Makefile b/Makefile index 44b8ef5c3..5dc8f77a3 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ generate-release-md: mv src/saas/release.md docs/ test: - cd src/api && source ./test_env.sh && poetry run pytest bkuser_core/tests --disable-pytest-warnings + cd src/api && export DJANGO_SETTINGS_MODULE="bkuser_core.config.overlays.unittest" && poetry run pytest bkuser_core/tests --disable-pytest-warnings link: rm src/api/bkuser_global || true diff --git a/pyproject.toml b/pyproject.toml index 4a4e93c46..5e5f8f0f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,10 +2,10 @@ name = "蓝鲸用户管理" version = "2.3.3" description = "project description file for ci" -authors = ["IMBlues "] +authors = ["TencentBlueKing "] [tool.poetry.dependencies] -python = "3.6.14" +python = "^3.8" apigw-manager = "^1.0.3" [tool.poetry.dev-dependencies] @@ -14,8 +14,8 @@ black = "^22.3.0" # isort isort = "^5.9.2" # flake8 -pyproject-flake8 = "^0.0.1-alpha.2" -flake8-comprehensions = "^3.5.0" +pyproject-flake8 = "0.0.1-alpha.2" +flake8-comprehensions = "3.5.0" # pytest pytest = "^6.2.4" pytest-django = "^3.9.0" @@ -39,6 +39,7 @@ exclude = ''' | .+/migrations | .+/sdk | .+/node_modules + | .+/build )/ ''' @@ -59,7 +60,7 @@ format = "pylint" show_source = "true" statistics = "true" count = "true" -exclude = "*migrations*,*.pyc,.git,__pycache__,*/node_modules/*,*/templates_module*,*/bin/*,*/config/*,*sdk*" +exclude = "*migrations*,*.pyc,.git,__pycache__,*/node_modules/*,*/templates_module*,*/bin/*,*/config/*,*sdk*,*build*" [tool.mypy] ignore_missing_imports = true @@ -70,6 +71,7 @@ pretty=true exclude = '''(?x)( instrumentor\.py$ | otel\.py$ + | src/build/.*\.py$ )''' [[tool.mypy.overrides]] @@ -78,5 +80,6 @@ module = [ "*.config.*", "bkuser_sdk.*", "*.bkuser_sdk.*", + "*.build.*", ] ignore_errors = true diff --git a/src/api/bin/install_ci_dependencies.sh b/src/api/bin/export_requirements_txt.sh similarity index 81% rename from src/api/bin/install_ci_dependencies.sh rename to src/api/bin/export_requirements_txt.sh index 894de6074..92bffd496 100644 --- a/src/api/bin/install_ci_dependencies.sh +++ b/src/api/bin/export_requirements_txt.sh @@ -6,5 +6,3 @@ sed -i '/^--extra-index-url*/d' requirements.txt sed -i '/gevent/d' requirements.txt sed -i '/greenlet/d' requirements.txt sed -i '/gunicorn/d' requirements.txt - -pip install -r requirements.txt -i https://pypi.org/simple/ diff --git a/src/api/bkuser_core/api/login/serializers.py b/src/api/bkuser_core/api/login/serializers.py index 662318406..ace11971f 100644 --- a/src/api/bkuser_core/api/login/serializers.py +++ b/src/api/bkuser_core/api/login/serializers.py @@ -85,6 +85,8 @@ class Meta: "status", "time_zone", "language", + "domain", + "category_id", # NOTE: 这里缩减登陆成功之后的展示字段 # "position", # "logo_url", => to logo? diff --git a/src/api/bkuser_core/api/login/views.py b/src/api/bkuser_core/api/login/views.py index b4d2526b5..98a64288d 100644 --- a/src/api/bkuser_core/api/login/views.py +++ b/src/api/bkuser_core/api/login/views.py @@ -102,8 +102,8 @@ def login(self, request): time_aware_now = now() config_loader = ConfigProvider(category_id=category.id) - # Admin 用户只需直接判断 密码是否正确 (只有本地目录有密码配置) - if not profile.is_superuser and category.type in [CategoryType.LOCAL.value]: + # 由于安全检测等原因,取消原先对admin用户的检查豁免 + if category.type in [CategoryType.LOCAL.value]: # 判断账户状态 if profile.status in [ diff --git a/src/api/bkuser_core/api/web/audit/serializers.py b/src/api/bkuser_core/api/web/audit/serializers.py index 77c95305b..1e4a6570e 100644 --- a/src/api/bkuser_core/api/web/audit/serializers.py +++ b/src/api/bkuser_core/api/web/audit/serializers.py @@ -11,10 +11,12 @@ import datetime from typing import Optional +from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from .constants import LOGIN_FAILED_REASON_MAP, OPERATION_ABOUT_PASSWORD, OPERATION_NAME_MAP, OPERATION_OBJ_NAME_MAP +from bkuser_core.profiles.models import Profile PLACE_HOLDER = "--" @@ -35,6 +37,7 @@ class GeneralLogListInputSLZ(LogListInputSLZ): class GeneralLogOutputSLZ(serializers.Serializer): id = serializers.IntegerField(help_text=_("ID")) extra_value = serializers.JSONField(help_text=_("额外信息")) + display_name = serializers.CharField(help_text=_("用户全名"), read_only=True) operator = serializers.CharField(help_text=_("操作者")) create_time = serializers.DateTimeField(help_text=_("创建时间")) status = serializers.CharField(help_text=_("状态")) @@ -57,12 +60,15 @@ def to_representation(self, obj): category_id = extra_value.get("category_id") category_display_name = category_name_map.get(category_id, PLACE_HOLDER) + operator_profile = Profile.objects.filter(username=obj.operator).first() + display_name = operator_profile.display_name if operator_profile else "" return { "datetime": datetime.datetime.strptime(instance["create_time"], "%Y-%m-%dT%H:%M:%S.%fZ"), "operator": instance["operator"], "target_obj": instance["target_obj"], "category_display_name": category_display_name, + "display_name": display_name, "operation": instance["operation"], "client_ip": extra_value.get("client_ip", PLACE_HOLDER), } @@ -79,14 +85,16 @@ class LoginLogOutputSLZ(serializers.Serializer): # datetime = serializers.CharField(source="create_time", help_text=_("登录时间"), required=False) is_success = serializers.BooleanField(help_text=_("是否登录成功"), required=False) username = serializers.CharField(help_text=_("登录用户"), source="profile.username") - + display_name = serializers.CharField(help_text=_("用户全名"), source="profile.display_name") datetime = serializers.SerializerMethodField(help_text=_("登录时间"), required=False) category_display_name = serializers.SerializerMethodField(help_text=_("所属目录"), required=False) client_ip = serializers.SerializerMethodField(help_text=_("客户端 IP"), required=False) reason = serializers.SerializerMethodField(help_text=_("失败原因"), required=False) def get_datetime(self, obj): - return obj.create_time + # 转换成本地时间 + local_time = timezone.localtime(obj.create_time) + return local_time.strftime("%Y-%m-%d %H:%M:%S") def get_reason(self, obj) -> Optional[str]: """get reason display name""" @@ -132,7 +140,8 @@ def get_reason(self, obj) -> Optional[str]: """get reason display name""" if obj.is_success: return None - return LOGIN_FAILED_REASON_MAP.get(obj.reason, _("未知失败原因")) + # bugfix: ugettext_lazy + return str(LOGIN_FAILED_REASON_MAP.get(obj.reason, _("未知失败原因"))) def get_datetime(self, obj): return obj.create_time.strftime("%Y-%m-%dT%H:%M:%S.%fZ") diff --git a/src/api/bkuser_core/api/web/category/serializers.py b/src/api/bkuser_core/api/web/category/serializers.py index ed7978a44..97d037d06 100644 --- a/src/api/bkuser_core/api/web/category/serializers.py +++ b/src/api/bkuser_core/api/web/category/serializers.py @@ -192,6 +192,10 @@ class CategoryFileImportInputSLZ(serializers.Serializer): file = serializers.FileField(required=False) +class CategoryFileImportQuerySLZ(serializers.Serializer): + is_overwrite = serializers.BooleanField(required=False, default=False) + + class CategorySyncResponseOutputSLZ(serializers.Serializer): task_id = serializers.CharField(help_text="task_id for the sync job.") diff --git a/src/api/bkuser_core/api/web/category/views.py b/src/api/bkuser_core/api/web/category/views.py index 0750866ed..368128d6f 100644 --- a/src/api/bkuser_core/api/web/category/views.py +++ b/src/api/bkuser_core/api/web/category/views.py @@ -25,6 +25,7 @@ CategoryExportInputSLZ, CategoryExportProfileOutputSLZ, CategoryFileImportInputSLZ, + CategoryFileImportQuerySLZ, CategoryMetaOutputSLZ, CategoryNamespaceSettingUpdateInputSLZ, CategoryProfileListInputSLZ, @@ -116,7 +117,6 @@ def get_queryset(self): category = get_category(category_id) namespace = self.kwargs["namespace"] metas = list_setting_metas(category.type, None, namespace) - return Setting.objects.filter(meta__in=metas, category_id=category_id) def post(self, request, *args, **kwargs): @@ -454,6 +454,9 @@ def post(self, request, *args, **kwargs): def _local_category_do_import(self, request, instance): """向本地目录导入数据文件""" + query_slz = CategoryFileImportQuerySLZ(data=request.query_params) + query_slz.is_valid(raise_exception=True) + slz = CategoryFileImportInputSLZ(data=request.data) slz.is_valid(raise_exception=True) @@ -465,7 +468,10 @@ def _local_category_do_import(self, request, instance): raise error_codes.CREATE_SYNC_TASK_FAILED.f(str(e)) instance_id = instance.id - params = {"raw_data_file": slz.validated_data["file"]} + params = { + "raw_data_file": slz.validated_data["file"], + "is_overwrite": query_slz.validated_data["is_overwrite"], + } try: # TODO: FileField 可能不能反序列化, 所以可能不能传到 celery 执行 adapter_sync(instance_id, operator=request.operator, task_id=task_id, **params) diff --git a/src/api/bkuser_core/api/web/constants.py b/src/api/bkuser_core/api/web/constants.py new file mode 100644 index 000000000..940bdf6fd --- /dev/null +++ b/src/api/bkuser_core/api/web/constants.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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. +""" + +EXCLUDE_SETTINGS_META_KEYS = ["password_rsa_private_key"] + +EXCLUDE_SETTINGS_META_IN_META_LISTVIEW = [ + "enable_password_rsa_encrypted", + "password_rsa_public_key", + "password_rsa_private_key", +] diff --git a/src/api/bkuser_core/api/web/password/serializers.py b/src/api/bkuser_core/api/web/password/serializers.py index 377565602..2a6bafaae 100644 --- a/src/api/bkuser_core/api/web/password/serializers.py +++ b/src/api/bkuser_core/api/web/password/serializers.py @@ -12,17 +12,47 @@ from rest_framework import serializers from bkuser_core.api.web.serializers import Base64OrPlainField +from bkuser_core.api.web.utils import get_raw_password, get_token_handler class PasswordResetSendEmailInputSLZ(serializers.Serializer): email = serializers.EmailField(required=True, max_length=254) +class PasswordResetSendSMSInputSLZ(serializers.Serializer): + telephone = serializers.CharField(required=True, max_length=32) + + +class PasswordResetSendSMSOutputSLZ(serializers.Serializer): + verification_code_token = serializers.CharField(required=True, max_length=254) + telephone = serializers.CharField(required=True, max_length=16) + + +class PasswordVerifyVerificationCodeInputSLZ(serializers.Serializer): + verification_code_token = serializers.CharField(required=True, max_length=254) + verification_code = serializers.CharField(required=True) + + +class PasswordVerifyVerificationCodeOutputSLZ(serializers.Serializer): + token = serializers.CharField(required=True, max_length=254) + + class PasswordResetByTokenInputSLZ(serializers.Serializer): token = serializers.CharField(required=True, max_length=254) password = Base64OrPlainField(required=True, max_length=254) + def validate(self, attrs): + token_holder = get_token_handler(token=attrs["token"]) + profile = token_holder.profile + # 对于密码输入可能是明文也可能是密文,根据配置自动判断解析出明文(密文只是与前端加密传递,与后续逻辑无关) + attrs["password"] = get_raw_password(profile.category_id, attrs["password"]) + return attrs + class PasswordModifyInputSLZ(serializers.Serializer): old_password = Base64OrPlainField(required=True, max_length=254) new_password = Base64OrPlainField(required=True, max_length=254) + + +class PasswordListSettingsByTokenInputSLZ(serializers.Serializer): + token = serializers.CharField(required=True, max_length=254) diff --git a/src/api/bkuser_core/api/web/password/tasks.py b/src/api/bkuser_core/api/web/password/tasks.py new file mode 100644 index 000000000..5c24c0f2b --- /dev/null +++ b/src/api/bkuser_core/api/web/password/tasks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 logging + +from bkuser_core.celery import app +from bkuser_core.common.notifier import send_sms + +logger = logging.getLogger(__name__) + + +@app.task +def send_reset_password_verification_code_sms(profile_id: str, send_config: dict): + try: + logger.info( + "going to send verification_code of Profile(%s) via telephone(%s)", + profile_id, + send_config["receivers"], + ) + send_sms(**send_config) + except Exception: + logger.exception( + "Failed to send verification_code of Profile(%s) via telephone(%s): %s", + profile_id, + send_config["receivers"], + ) diff --git a/src/api/bkuser_core/api/web/password/urls.py b/src/api/bkuser_core/api/web/password/urls.py index 92538a731..803990995 100644 --- a/src/api/bkuser_core/api/web/password/urls.py +++ b/src/api/bkuser_core/api/web/password/urls.py @@ -19,6 +19,16 @@ views.PasswordResetSendEmailApi.as_view(), name="password.reset.sent_email", ), + path( + "reset/verification_code/send_sms/", + views.PasswordResetSendVerificationCodeApi.as_view(), + name="password.reset.sent_verification_code_sms", + ), + path( + "reset/verification_code/verify/", + views.PasswordVerifyVerificationCodeApi.as_view(), + name="password.reset.verify_verification_code", + ), path( "reset/by_token/", views.PasswordResetByTokenApi.as_view(), @@ -29,4 +39,9 @@ views.PasswordModifyApi.as_view(), name="password.modify", ), + path( + "settings/by_token/", + views.PasswordListSettingsByTokenApi.as_view(), + name="password.get_settings.by_token", + ), ] diff --git a/src/api/bkuser_core/api/web/password/verification_code_handler.py b/src/api/bkuser_core/api/web/password/verification_code_handler.py new file mode 100644 index 000000000..2d439aaac --- /dev/null +++ b/src/api/bkuser_core/api/web/password/verification_code_handler.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 datetime +import hashlib +import json +import logging +import random +import string +from typing import Any + +from django.core.cache import caches +from django.utils.timezone import now + +from bkuser_core.api.web.password.tasks import send_reset_password_verification_code_sms +from bkuser_core.common.error_codes import error_codes +from bkuser_core.profiles.models import Profile, ProfileTokenHolder +from bkuser_core.user_settings.loader import ConfigProvider + +logger = logging.getLogger(__name__) + + +class ResetPasswordVerificationCodeHandler: + def __init__(self): + self.profile = None + self.config_loader = None + self.cache = caches["verification_code"] + + def _set_into_cache(self, key: str, data: Any, timeout: int, prefix: str = None): + if prefix: + key = f"{prefix}_{key}" + self.cache.set(key=key, timeout=timeout, value=data) + + def _get_from_cache(self, key: str, prefix: str = None): + if prefix: + key = f"{prefix}_{key}" + data = self.cache.get(key=key) + return data + + def _delete_from_cache(self, key: str, prefix: str = None): + if prefix: + key = f"{prefix}_{key}" + self.cache.delete(key=key) + + def _set_reset_password_send_count(self, telephone: str, count: int): + # 当天23:59:59失效 + current_datetime = now() + today_last_time = datetime.datetime( + year=current_datetime.year, + month=current_datetime.month, + day=current_datetime.day, + hour=23, + minute=59, + second=59, + tzinfo=current_datetime.tzinfo, + ) + # 再次发送的情况下 ++ 1 会重置时间; 计算当前时间距离凌晨时间 + expired_second = today_last_time.timestamp() - current_datetime.timestamp() + return self._set_into_cache(telephone, count, timeout=expired_second, prefix="reset_password_send_count") + + def _check_repeat_send_require(self, token: str): + # 校验是否重复发送 + verification_code_data = self._get_from_cache(token, prefix="reset_password") + if verification_code_data: + effective_minutes = self.config_loader.get("verification_code_expire_seconds") + raise error_codes.VERIFICATION_CODE_REPEAT_SENDING_REQUIRE.f(effective_minutes=effective_minutes // 60) + + def _check_send_count_exceeded_limit(self): + # 是否在发送的当日次数中 + limit_send_count = self.config_loader.get("reset_sms_send_max_limit") + send_count_in_cache = self._get_from_cache(key=self.profile.telephone, prefix="reset_password_send_count") + send_count = send_count_in_cache if send_count_in_cache else 0 + if send_count > limit_send_count: + raise error_codes.VERIFICATION_CODE_SEND_REACH_LIMIT + + def generate_reset_password_token(self, profile_id) -> str: + self.profile = Profile.objects.get(id=profile_id) + self.config_loader = ConfigProvider(category_id=self.profile.category_id) + + # token 生成 + hashed_value = f"{self.profile.username}@{self.profile.domain}|{self.profile.telephone}" + md = hashlib.md5() + md.update(hashed_value.encode("utf-8")) + token = md.hexdigest() + + # 是否已经发送,是否超过当日发送次数 + self._check_repeat_send_require(token) + self._check_send_count_exceeded_limit() + + expire_seconds = self.config_loader.get("verification_code_expire_seconds") + verification_code_length = self.config_loader.get("verification_code_length") + + # 生成验证码 + verification_code = "".join(random.sample(string.digits, verification_code_length)) + expired_at = now() + datetime.timedelta(seconds=expire_seconds) + verification_code_data = { + "profile_id": self.profile.id, + "verification_code": verification_code, + "error_count": 0, + # 设置过期点的时间戳,正常情况下会自动过期,但是输入错误的情况下 error_count ++ 1 会重置时间 + "expired_at_timestamp": expired_at.timestamp(), + } + + logger.info( + "Set the verification_code_data in redis. profile<%s-%s> token: %s", + self.profile.id, + f"{self.profile.username}@{self.profile.domain}", + token, + ) + # redis 缓存验证码 + self._set_into_cache(token, json.dumps(verification_code_data), expire_seconds, prefix="reset_password") + + # 增加当日发送次数 + send_count_in_cache = self._get_from_cache(key=self.profile.telephone, prefix="reset_password_send_count") + send_count = send_count_in_cache + 1 if send_count_in_cache else 1 + self._set_reset_password_send_count(self.profile.telephone, send_count) + + reset_password_sms_config = self.config_loader.get("reset_password_sms_config") + + sms_message_send_config = { + "sender": reset_password_sms_config["sender"], + "message": reset_password_sms_config["content"].format(verification_code=verification_code), + "receivers": [self.profile.telephone], + } + + send_reset_password_verification_code_sms.delay( + profile_id=self.profile.id, send_config=sms_message_send_config + ) + + return token + + def verify_verification_code(self, verification_code_token: str, verification_code: str) -> int: + verification_code_data_bytes = self._get_from_cache(verification_code_token, prefix="reset_password") + + # token 校验 + if not verification_code_data_bytes: + logger.info( + "verify verification_code, verification_code_data is invalid. Posted token is %s", + verification_code_token, + ) + raise error_codes.VERIFICATION_CODE_INVALID + + verification_code_data = json.loads(verification_code_data_bytes) + logger.info( + "verify verification_code. Posted token is %s, verification_code=%s", + verification_code_token, + verification_code, + ) + + profile = Profile.objects.get(id=verification_code_data["profile_id"]) + config_loader = ConfigProvider(profile.category_id) + + # 验证码校验 + if verification_code_data["verification_code"] != verification_code: + verification_code_data["error_count"] += 1 + expired_second = verification_code_data["expired_at_timestamp"] - now().timestamp() + # 输入错误,刚好临近过期 + if expired_second < 0: + raise error_codes.VERIFICATION_CODE_INVALID + + self._set_into_cache( + verification_code_token, json.dumps(verification_code_data), expired_second, prefix="reset_password" + ) + error_count_limit = config_loader.get("failed_verification_max_limit") + + # 验证码试错次数 + if verification_code_data["error_count"] > error_count_limit: + raise error_codes.VERIFICATION_CODE_WRONG_REACH_LIMIT + + # 验证码错误 + raise error_codes.VERIFICATION_CODE_WRONG + + # 验证通过删除缓存 + self._delete_from_cache(verification_code_token, prefix="reset_password") + return profile.id + + def generate_profile_token(self, profile_id) -> ProfileTokenHolder: + profile = Profile.objects.get(id=profile_id) + token_holder = ProfileTokenHolder.objects.create(profile=profile) + return token_holder diff --git a/src/api/bkuser_core/api/web/password/views.py b/src/api/bkuser_core/api/web/password/views.py index 6fde3084d..4449bae28 100644 --- a/src/api/bkuser_core/api/web/password/views.py +++ b/src/api/bkuser_core/api/web/password/views.py @@ -16,8 +16,27 @@ from rest_framework import generics, status from rest_framework.response import Response -from .serializers import PasswordModifyInputSLZ, PasswordResetByTokenInputSLZ, PasswordResetSendEmailInputSLZ -from bkuser_core.api.web.utils import get_operator, validate_password +from bkuser_core.api.web.category.serializers import CategorySettingOutputSLZ +from bkuser_core.api.web.password.serializers import ( + PasswordListSettingsByTokenInputSLZ, + PasswordModifyInputSLZ, + PasswordResetByTokenInputSLZ, + PasswordResetSendEmailInputSLZ, + PasswordResetSendSMSInputSLZ, + PasswordResetSendSMSOutputSLZ, + PasswordVerifyVerificationCodeInputSLZ, + PasswordVerifyVerificationCodeOutputSLZ, +) +from bkuser_core.api.web.password.verification_code_handler import ResetPasswordVerificationCodeHandler +from bkuser_core.api.web.utils import ( + get_category, + get_operator, + get_profile_by_telephone, + get_profile_by_username, + get_token_handler, + list_setting_metas, + validate_password, +) from bkuser_core.audit.constants import OperationType from bkuser_core.audit.utils import create_general_log from bkuser_core.categories.models import ProfileCategory @@ -27,6 +46,8 @@ from bkuser_core.profiles.signals import post_profile_update from bkuser_core.profiles.tasks import send_password_by_email from bkuser_core.profiles.utils import parse_username_domain +from bkuser_core.user_settings.constants import SettingsEnableNamespaces +from bkuser_core.user_settings.models import Setting logger = logging.getLogger(__name__) @@ -72,16 +93,9 @@ def post(self, request, *args, **kwargs): token = data["token"] pending_password = data["password"] - try: - token_holder = ProfileTokenHolder.objects.get(token=token, enabled=True) - except ProfileTokenHolder.DoesNotExist: - logger.info("token<%s> not exist in db", token) - raise error_codes.CANNOT_GET_TOKEN_HOLDER - - if token_holder.expired: - raise error_codes.PROFILE_TOKEN_EXPIRED - + token_holder = get_token_handler(token) profile = token_holder.profile + validate_password(profile, pending_password) profile.password = make_password(pending_password) profile.password_update_time = now() @@ -143,3 +157,91 @@ def post(self, request, *args, **kwargs): extra_values=modify_summary, ) return Response(status=status.HTTP_200_OK) + + +class PasswordListSettingsByTokenApi(generics.ListAPIView): + serializer_class = CategorySettingOutputSLZ + + def get(self, request, *args, **kwargs): + slz = PasswordListSettingsByTokenInputSLZ(data=request.query_params) + slz.is_valid(raise_exception=True) + + data = slz.validated_data + token = data["token"] + + token_holder = get_token_handler(token) + profile = token_holder.profile + + category = get_category(profile.category_id) + namespace = SettingsEnableNamespaces.PASSWORD.value + metas = list_setting_metas(category.type, None, namespace) + settings = Setting.objects.filter(meta__in=metas, category_id=profile.category_id) + return Response(self.serializer_class(settings, many=True).data) + + +class PasswordResetSendVerificationCodeApi(generics.CreateAPIView): + def post(self, request, *args, **kwargs): + slz = PasswordResetSendSMSInputSLZ(data=request.data) + slz.is_valid(raise_exception=True) + + data = slz.validated_data + + input_telephone = data["telephone"] + + # 根据交互设计,和登录一样:只能猜测这里传输的username,还是telephone + # 存在着username=telephone的情况 + try: + # 优先过滤username + username, domain = parse_username_domain(input_telephone) + if not domain: + domain = ProfileCategory.objects.get_default().domain + # filter过滤,判断是否存在,存在则仅有一个 + profile = get_profile_by_username(username, domain) + + # 不存在则才是telephone + if not profile: + profile = get_profile_by_telephone(input_telephone) + + except Profile.DoesNotExist: + logger.exception( + "failed to get profile by telephone<%s> or username<%s>", input_telephone, input_telephone + ) + raise error_codes.USER_DOES_NOT_EXIST + + except Profile.MultipleObjectsReturned: + logger.exception("this telephone had bound to multi profiles", input_telephone, input_telephone) + raise error_codes.TELEPHONE_BOUND_TO_MULTI_PROFILE + + # 生成verification_code_token + verification_code_token = ResetPasswordVerificationCodeHandler().generate_reset_password_token(profile.id) + raw_telephone = profile.telephone + + # 用户未绑定手机号,即使用户名就是手机号码 + if not raw_telephone: + raise error_codes.TELEPHONE_NOT_PROVIDED + + response_data = { + "verification_code_token": verification_code_token, + # 加密返回手机号 + "telephone": raw_telephone.replace(raw_telephone[3:7], '****'), + } + + return Response(PasswordResetSendSMSOutputSLZ(response_data).data) + + +class PasswordVerifyVerificationCodeApi(generics.CreateAPIView): + def post(self, request, *args, **kwargs): + slz = PasswordVerifyVerificationCodeInputSLZ(data=request.data) + slz.is_valid(raise_exception=True) + + data = slz.validated_data + + verification_code_handler = ResetPasswordVerificationCodeHandler() + + profile_id = verification_code_handler.verify_verification_code( + data["verification_code_token"], data["verification_code"] + ) + profile_token = verification_code_handler.generate_profile_token(profile_id) + # 前端拿到token,作为query_params,拼接重置页面路由 + response_data = {"token": profile_token.token} + return Response(PasswordVerifyVerificationCodeOutputSLZ(response_data).data) diff --git a/src/api/bkuser_core/api/web/profile/serializers.py b/src/api/bkuser_core/api/web/profile/serializers.py index 08cbde9ef..407152a88 100644 --- a/src/api/bkuser_core/api/web/profile/serializers.py +++ b/src/api/bkuser_core/api/web/profile/serializers.py @@ -8,12 +8,19 @@ 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 Dict from django.conf import settings from rest_framework import serializers from bkuser_core.api.web.serializers import StringArrayField -from bkuser_core.api.web.utils import get_default_category_id +from bkuser_core.api.web.utils import ( + escape_value, + expand_extra_fields, + get_default_category_id, + get_extras_with_default_values, + get_raw_password, +) from bkuser_core.profiles.models import Profile from bkuser_core.profiles.validators import validate_username @@ -78,18 +85,19 @@ class ProfileSearchOutputSLZ(serializers.Serializer): # A: 需要, 搜索结果点击后直接渲染表单进行展示/更新 id = serializers.CharField(required=False, help_text="用户ID") username = serializers.CharField(required=False, help_text="用户名") + display_name = serializers.CharField(required=False, help_text="中文名") + qq = serializers.CharField(required=False, help_text="QQ") email = serializers.CharField(required=False, help_text="邮箱") telephone = serializers.CharField(required=False, help_text="电话") wx_userid = serializers.CharField(required=False, help_text="微信用户id") domain = serializers.CharField(required=False, help_text="域") - display_name = serializers.CharField(required=False, help_text="中文名") status = serializers.CharField(required=False, help_text="账户状态") staff_status = serializers.CharField(required=False, help_text="在职状态") position = serializers.CharField(required=False, help_text="职位") enabled = serializers.BooleanField(required=False, help_text="是否启用", default=True) - extras = serializers.JSONField(required=False, help_text="扩展字段") password_valid_days = serializers.IntegerField(required=False, help_text="密码有效期") + account_expiration_date = serializers.CharField(required=False) country_code = serializers.CharField(required=False, help_text="国家码") iso_code = serializers.CharField(required=False, help_text="国家码") time_zone = serializers.CharField(required=False, help_text="时区") @@ -101,16 +109,39 @@ class ProfileSearchOutputSLZ(serializers.Serializer): departments = ProfileSearchResultDepartmentSerializer(many=True, required=False, help_text="部门列表") leaders = ProfileSearchResultLeaderSerializer(many=True, required=False, help_text="上级列表", source="leader") + # extras = serializers.JSONField(required=False, help_text="扩展字段") + extras = serializers.SerializerMethodField(required=False, read_only=True) + + def get_extras(self, obj: "Profile") -> Dict: + """尝试从 context 中获取默认字段值""" + return get_extras_with_default_values(obj.extras) + + def to_representation(self, instance): + data = super().to_representation(instance) + return expand_extra_fields(data) + class ProfileUpdateInputSLZ(serializers.ModelSerializer): leader = serializers.ListField(child=serializers.IntegerField(), required=False) departments = serializers.ListField(child=serializers.IntegerField(), required=False) + password = serializers.CharField(required=False, write_only=True) + display_name = serializers.CharField(required=False) + old_password = serializers.CharField(required=False, write_only=True) # 只有admin用户重置密码时才需要传递该字段 class Meta: model = Profile # NOTE: 相对原来的api区别, 不支持extras/create_time/update_time更新 exclude = ["category_id", "username", "domain", "extras", "create_time", "update_time"] + def validate_password(self, password): + return get_raw_password(self.instance.category_id, password) + + def validate_display_name(self, display_name): + return escape_value(display_name) + + def validate_old_password(self, old_password): + return get_raw_password(self.instance.category_id, old_password) + class ProfileCreateInputSLZ(serializers.ModelSerializer): category_id = serializers.IntegerField(required=False) @@ -165,6 +196,9 @@ class Meta: # exclude = ["password"] validators: list = [] + def validate_display_name(self, display_name): + return escape_value(display_name) + class ProfileBatchDeleteInputSLZ(serializers.Serializer): id = serializers.IntegerField() diff --git a/src/api/bkuser_core/api/web/profile/views.py b/src/api/bkuser_core/api/web/profile/views.py index 3b7d13569..3f71ca5d3 100644 --- a/src/api/bkuser_core/api/web/profile/views.py +++ b/src/api/bkuser_core/api/web/profile/views.py @@ -40,7 +40,13 @@ from bkuser_core.profiles.exceptions import CountryISOCodeNotMatch from bkuser_core.profiles.models import DynamicFieldInfo, Profile from bkuser_core.profiles.signals import post_profile_create, post_profile_update -from bkuser_core.profiles.utils import align_country_iso_code, make_password_by_config, parse_username_domain +from bkuser_core.profiles.utils import ( + align_country_iso_code, + check_old_password, + make_password_by_config, + parse_username_domain, + should_check_old_password, +) from bkuser_core.user_settings.constants import SettingsEnableNamespaces from bkuser_core.user_settings.models import Setting, SettingMeta @@ -114,7 +120,6 @@ def _update(self, request, partial): slz = ProfileUpdateInputSLZ(instance, data=request.data, partial=partial) slz.is_valid(raise_exception=True) operate_type = OperationType.UPDATE.value - validated_data = slz.validated_data # 前端是把extras字段打平提交的 @@ -158,6 +163,10 @@ def _update(self, request, partial): update_summary = {"request": request} # 密码修改加密 if validated_data.get("password"): + # 如果重置的是admin账号的密码,需要对原始密码进行校验 + if should_check_old_password(username=instance.username): + check_old_password(instance=instance, old_password=validated_data["old_password"], request=request) + operate_type = ( OperationType.FORGET_PASSWORD.value if request.headers.get("User-From-Token") @@ -292,7 +301,12 @@ def create(self, request, *args, **kwargs): meta = SettingMeta.objects.filter( key="expired_after_days", namespace=SettingsEnableNamespaces.ACCOUNT.value ).first() - expired_after_days = Setting.objects.filter(category_id=category_id, meta=meta).first().value + + # NOTE: maybe None here if the meta is not set + expired_after_days = -1 + expired_after_days_setting = Setting.objects.filter(category_id=category_id, meta=meta).first() + if expired_after_days_setting: + expired_after_days = expired_after_days_setting.value # 账户有效期,不传,默认设置为目录设置项 if expired_after_days == -1: diff --git a/src/api/bkuser_core/api/web/search/serializers.py b/src/api/bkuser_core/api/web/search/serializers.py index 3da634ddd..66a885337 100644 --- a/src/api/bkuser_core/api/web/search/serializers.py +++ b/src/api/bkuser_core/api/web/search/serializers.py @@ -66,6 +66,7 @@ class SearchResultProfileOutputSLZ(serializers.Serializer): country_code = serializers.CharField(required=False, help_text="国家码") iso_code = serializers.CharField(required=False, help_text="国家码") time_zone = serializers.CharField(required=False, help_text="时区") + last_login_time = serializers.DateTimeField(required=False, help_text="最后登录时间") create_time = serializers.DateTimeField(required=False, help_text="创建时间") update_time = serializers.DateTimeField(required=False, help_text="更新时间") diff --git a/src/api/bkuser_core/api/web/setting/views.py b/src/api/bkuser_core/api/web/setting/views.py index 4b37d76db..0fdfd576d 100644 --- a/src/api/bkuser_core/api/web/setting/views.py +++ b/src/api/bkuser_core/api/web/setting/views.py @@ -12,6 +12,7 @@ from rest_framework import generics from .serializers import SettingMetaOutputSLZ, SettingMetasListInputSLZ +from bkuser_core.api.web.constants import EXCLUDE_SETTINGS_META_IN_META_LISTVIEW from bkuser_core.user_settings.models import SettingMeta # from bkuser_core.bkiam.permissions import ManageFieldPermission @@ -31,7 +32,9 @@ def get_queryset(self): category_type = data["category_type"] namespace = data["namespace"] - queryset = SettingMeta.objects.filter(category_type=category_type) + queryset = SettingMeta.objects.filter(category_type=category_type).exclude( + key__in=EXCLUDE_SETTINGS_META_IN_META_LISTVIEW + ) if namespace: queryset = queryset.filter(namespace=namespace) return queryset diff --git a/src/api/bkuser_core/api/web/utils.py b/src/api/bkuser_core/api/web/utils.py index 6a3ca18c2..1dbff28b7 100644 --- a/src/api/bkuser_core/api/web/utils.py +++ b/src/api/bkuser_core/api/web/utils.py @@ -8,21 +8,24 @@ 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 base64 import logging from typing import Dict, Union from django.conf import settings +from bkuser_core.api.web.constants import EXCLUDE_SETTINGS_META_KEYS from bkuser_core.categories.models import ProfileCategory from bkuser_core.common.error_codes import error_codes from bkuser_core.departments.models import Department from bkuser_core.profiles.cache import get_extras_default_from_local_cache -from bkuser_core.profiles.models import DynamicFieldInfo, Profile +from bkuser_core.profiles.models import DynamicFieldInfo, Profile, ProfileTokenHolder from bkuser_core.profiles.password import PasswordValidator from bkuser_core.profiles.utils import check_former_passwords from bkuser_core.user_settings.exceptions import SettingHasBeenDisabledError from bkuser_core.user_settings.loader import ConfigProvider from bkuser_core.user_settings.models import SettingMeta +from bkuser_global.crypt import rsa_decrypt_password logger = logging.getLogger(__name__) @@ -82,7 +85,7 @@ def list_setting_metas(category_type: str, region: str, namespace: str) -> list: """ List setting metas. """ - queryset = SettingMeta.objects.filter(category_type=category_type) + queryset = SettingMeta.objects.filter(category_type=category_type).exclude(key__in=EXCLUDE_SETTINGS_META_KEYS) if region: queryset = queryset.filter(region=region) if namespace: @@ -152,3 +155,51 @@ def get_extras_with_default_values(extras_from_db: Union[dict, list]) -> dict: extras.update(formatted_extras) return extras + + +def get_raw_password(category_id: int, encrypted_password: str) -> str: + config_loader = ConfigProvider(category_id=category_id) + enable_rsa_encrypted = config_loader.get("enable_password_rsa_encrypted") + # 未开启,或者未配置rsa + if not enable_rsa_encrypted: + return encrypted_password + rsa_private_key = base64.b64decode(config_loader["password_rsa_private_key"]).decode() + return rsa_decrypt_password(encrypted_password, rsa_private_key) + + +def get_token_handler(token: str) -> ProfileTokenHolder: + try: + token_holder = ProfileTokenHolder.objects.get(token=token, enabled=True) + except ProfileTokenHolder.DoesNotExist: + logger.info("token<%s> not exist in db", token) + raise error_codes.CANNOT_GET_TOKEN_HOLDER + + if token_holder.expired: + raise error_codes.PROFILE_TOKEN_EXPIRED + + return token_holder + + +def get_profile_by_username(username: str, domain: str): + profile = Profile.objects.filter(username=username, domain=domain) + if not profile.exists(): + return None + return profile.first() + + +def get_profile_by_telephone(telephone: str): + return Profile.objects.get(telephone=telephone) + + +def escape_value(input_value: str) -> str: + """Replace special characters "&", "<" and ">" to HTML-safe sequences. + If the optional flag quote is true, the quotation mark character (") + is also translated. + rewrite the cgi method + """ + escaped_value = input_value.replace("&", "") # Must be done first! + escaped_value = escaped_value.replace("<", "") + escaped_value = escaped_value.replace(">", "") + escaped_value = escaped_value.replace('"', "") + escaped_value = escaped_value.replace("'", "") + return escaped_value diff --git a/src/api/bkuser_core/audit/constants.py b/src/api/bkuser_core/audit/constants.py index 272c2dfe7..d9f40ecad 100644 --- a/src/api/bkuser_core/audit/constants.py +++ b/src/api/bkuser_core/audit/constants.py @@ -35,6 +35,12 @@ class LogInFailReason(AutoLowerEnum): ) +class ResetPasswordFailReason(AutoLowerEnum): + BAD_OLD_PASSWORD = auto() + + _choices_labels = ((BAD_OLD_PASSWORD, "原密码校验错误"),) + + class OperationType(AutoLowerEnum): CREATE = auto() UPDATE = auto() diff --git a/src/api/bkuser_core/audit/handlers.py b/src/api/bkuser_core/audit/handlers.py index 0792bcefb..5cdbb0c76 100644 --- a/src/api/bkuser_core/audit/handlers.py +++ b/src/api/bkuser_core/audit/handlers.py @@ -42,6 +42,17 @@ def create_reset_password_log(sender, instance: "Profile", operator: str, extra_ except Exception: # pylint: disable=broad-except logger.exception("failed to create reset password log") + if "failed_reason" in extra_values: + try: + create_profile_log( + instance, + "ResetPassword", + {"is_success": False, "reason": extra_values["failed_reason"]}, + extra_values["request"], + ) + except Exception: # pylint: disable=broad-except + logger.exception("failed to create reset password log") + @receiver([post_profile_create, post_department_create, post_category_create, post_field_create, post_setting_create]) def create_audit_log(sender, instance: "Profile", operator: str, extra_values: dict, **kwargs): diff --git a/src/api/bkuser_core/audit/managers.py b/src/api/bkuser_core/audit/managers.py index d12ee78fd..3852b47ac 100644 --- a/src/api/bkuser_core/audit/managers.py +++ b/src/api/bkuser_core/audit/managers.py @@ -16,12 +16,28 @@ from django.db import models from django.utils.timezone import now -from .constants import LogInFailReason +from .constants import LogInFailReason, ResetPasswordFailReason class ResetPasswordManager(models.Manager): """重置密码DB管理器""" + def latest_check_old_password_failed_count(self): + """最近一段时间重置密码失败的次数,其中最近一段时间指从上一次成功重置密码后到现在""" + # 查找最近一次成功的时间 + try: + latest_time = self.filter(is_success=True).latest().create_time + except ObjectDoesNotExist: + # 当没有任何成功记录时,防止存在大量失败记录时进行统计导致可能的慢查询,只计算默认配置的统计时间 + # 这里取配置里默认设置的统计时间 + latest_time = now() - datetime.timedelta(seconds=settings.RESET_PASSWORD_RECORD_COUNT_SECONDS) + + return self.filter( + is_success=False, + reason=ResetPasswordFailReason.BAD_OLD_PASSWORD.value, + create_time__gte=latest_time, + ).count() + class LogInManager(models.Manager): def latest_failed_count(self) -> int: diff --git a/src/api/bkuser_core/audit/migrations/0007_auto_20221212_1131.py b/src/api/bkuser_core/audit/migrations/0007_auto_20221212_1131.py new file mode 100644 index 000000000..c12529ad8 --- /dev/null +++ b/src/api/bkuser_core/audit/migrations/0007_auto_20221212_1131.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2.13 on 2022-12-12 03:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('audit', '0006_alter_login_index_together'), + ] + + operations = [ + migrations.AlterModelOptions( + name='resetpassword', + options={'get_latest_by': 'create_time', 'ordering': ['-create_time']}, + ), + migrations.AddField( + model_name='resetpassword', + name='reason', + field=models.CharField(blank=True, choices=[('bad_old_password', '原密码校验错误')], max_length=32, null=True, verbose_name='重置密码失败原因'), + ), + ] diff --git a/src/api/bkuser_core/audit/models.py b/src/api/bkuser_core/audit/models.py index c6bdfbd7d..0d8b2a76c 100644 --- a/src/api/bkuser_core/audit/models.py +++ b/src/api/bkuser_core/audit/models.py @@ -15,7 +15,7 @@ from django.db import models from jsonfield import JSONField -from bkuser_core.audit.constants import LogInFailReason, OperationStatus +from bkuser_core.audit.constants import LogInFailReason, OperationStatus, ResetPasswordFailReason from bkuser_core.audit.managers import LogInManager, ResetPasswordManager from bkuser_core.common.fields import EncryptField from bkuser_core.common.models import TimestampedModel @@ -102,6 +102,13 @@ class ResetPassword(ProfileRelatedLog): token = models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, null=True) is_success = models.BooleanField("是否重置成功", default=False) password = EncryptField(default="") + reason = models.CharField( + "重置密码失败原因", + max_length=32, + choices=ResetPasswordFailReason.get_choices(), + null=True, + blank=True, + ) objects = ResetPasswordManager() @@ -110,3 +117,4 @@ def __str__(self): class Meta: ordering = ["-create_time"] + get_latest_by = "create_time" diff --git a/src/api/bkuser_core/bkiam/permissions.py b/src/api/bkuser_core/bkiam/permissions.py index 5d234d38c..e6c789ee9 100644 --- a/src/api/bkuser_core/bkiam/permissions.py +++ b/src/api/bkuser_core/bkiam/permissions.py @@ -41,6 +41,17 @@ def _parse_department_path(data): return field_map[the_last_of_path[0]], int(the_last_of_path[1]) +# NOTE: not used, only in unittest +CATEGORY_KEY_MAPPING = {"category.id": "id"} + +PROFILE_KEY_MAPPING = {"department._bk_iam_path_": _parse_department_path} + +DEPARTMENT_KEY_MAPPING = { + "department.id": "id", + "department._bk_iam_path_": _parse_department_path, +} + + class Permission: """ NOTE: the `operator` should be the username with domain @@ -61,7 +72,9 @@ def make_filter_of_category(self, operator: str, action_id: IAMAction): iam_request = self.helper.make_request_without_resources(username=operator, action_id=action_id) # NOTE: 这里不是给category自己用的, 而是给外检关联表用的, 所以category.id -> category_id fs = Permission().helper.iam.make_filter( - iam_request, converter_class=PathIgnoreDjangoQSConverter, key_mapping={"category.id": "category_id"} + iam_request, + converter_class=PathIgnoreDjangoQSConverter, + key_mapping={"category.id": "category_id"}, ) if not fs: raise IAMPermissionDenied( @@ -79,7 +92,7 @@ def make_filter_of_department(self, operator: str, action_id: IAMAction): fs = Permission().helper.iam.make_filter( iam_request, converter_class=PathIgnoreDjangoQSConverter, - key_mapping={"department._bk_iam_path_": _parse_department_path}, + key_mapping=PROFILE_KEY_MAPPING, ) if not fs: raise IAMPermissionDenied( @@ -96,10 +109,7 @@ def make_department_filter(self, operator: str, action_id: IAMAction): fs = Permission().helper.iam.make_filter( iam_request, converter_class=PathIgnoreDjangoQSConverter, - key_mapping={ - "department.id": "id", - "department._bk_iam_path_": _parse_department_path, - }, + key_mapping=DEPARTMENT_KEY_MAPPING, ) if not fs: raise IAMPermissionDenied( diff --git a/src/api/bkuser_core/categories/management/commands/enable_pwd_rsa_encrypt.py b/src/api/bkuser_core/categories/management/commands/enable_pwd_rsa_encrypt.py new file mode 100644 index 000000000..f107c1821 --- /dev/null +++ b/src/api/bkuser_core/categories/management/commands/enable_pwd_rsa_encrypt.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 base64 +import logging +import traceback + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives.asymmetric import rsa as crypto_rsa +from django.core.management.base import BaseCommand +from django.db import transaction + +from bkuser_core.categories.constants import CategoryType +from bkuser_core.categories.models import ProfileCategory +from bkuser_core.user_settings.models import Setting, SettingMeta + +logger = logging.getLogger(__name__) + + +class Command(BaseCommand): + help = "enable category rsa" + + def add_arguments(self, parser): + parser.add_argument("--category_id", type=str, help="目录ID", required=True) + parser.add_argument("--random_flag", type=bool, default=True, help="是否随机生成") + parser.add_argument("--key_length", type=int, default=1024, help="随机密钥对的长度") + parser.add_argument("--private_key_file", type=str, default="", help="rsa私钥pem文件目录") + parser.add_argument("--public_key_file", type=str, default="", help="rsa公钥pem文件目录") + + def validate_rsa_secret(self, private_key_content: bytes, public_key_content: bytes) -> bool: + testing_msg = "Hello World !!!" + + private_key = serialization.load_pem_private_key(private_key_content, password=None, backend=default_backend()) + public_key = serialization.load_pem_public_key(public_key_content, backend=default_backend()) + + common_condition = padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None + ) + + # 先公钥加密 + encrypt_msg = public_key.encrypt(testing_msg.encode(), common_condition) + + # 解密 + decrypt_msg = private_key.decrypt(encrypt_msg, common_condition) + result_msg = decrypt_msg.decode() + + if result_msg != testing_msg: + return False + return True + + def create_rsa_secret(self, options: dict): + random_flag = options.get("random_flag") + private_key: bytes + public_key: bytes + if not random_flag: + # read the private_key and public key from the file + private_key_file: str = options.get("private_key_file", "") + public_key_file: str = options.get("public_key_file", "") + with open(private_key_file, "rb") as private_file: + private_key = private_file.read() + + with open(public_key_file, "rb") as public_file: + public_key = public_file.read() + + if not self.validate_rsa_secret(private_key, private_key): + self.stdout.write("These pem files do not matching") + raise Exception + else: + self.stdout.write("Private key and public key are creating randomly") + key_length = options.get("key_length") + # 随机生成rsa 秘钥对 + private_key_origin = crypto_rsa.generate_private_key( + public_exponent=65537, key_size=key_length, backend=default_backend() + ) + public_key_origin = private_key_origin.public_key() + + private_key = private_key_origin.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), + ) + + public_key = public_key_origin.public_bytes( + encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.PKCS1 + ) + + # base64加密入库 + public_key_base64: str = base64.b64encode(public_key).decode() + private_key_base64: str = base64.b64encode(private_key).decode() + + return public_key_base64, private_key_base64 + + def handle(self, *args, **options): + category_id = options.get("category_id") + self.stdout.write(f"enable category rsa: category_id={str(category_id)}") + + try: + public_key, private_key = self.create_rsa_secret(options) + category = ProfileCategory.objects.get(id=category_id) + if category.type != CategoryType.LOCAL.value: + self.stdout.write("Rsa setting only support the local category, please check your input") + return + + rsa_settings_filters = { + "enable_password_rsa_encrypted": True, + "password_rsa_private_key": private_key, + "password_rsa_public_key": public_key, + } + + meta_combo = {} + for key, value in rsa_settings_filters.items(): + meta = SettingMeta.objects.get(key=key) + meta_combo[meta] = value + + # 新增或更新该目录的user_setting设置:rsa配置 + with transaction.atomic(): + rsa_settings = [] + for meta, value in meta_combo.items(): + instance, _ = Setting.objects.get_or_create(meta=meta, category_id=category.id) + instance.value = value + rsa_settings.append(instance) + Setting.objects.bulk_update(rsa_settings, ["value"]) + + self.stdout.write(f"Category {category_id} Enable rsa successfully") + + except ProfileCategory.DoesNotExist: + self.stdout.write(f"Category is not exist( category_id={category_id} ), please check your input.") + return + + except Exception as e: + self.stdout.write(traceback.format_exc()) + self.stdout.write(f"Enable rsa failed: {e}") + return diff --git a/src/api/bkuser_core/categories/plugins/local/syncer.py b/src/api/bkuser_core/categories/plugins/local/syncer.py index 2f3e33484..eb345d449 100644 --- a/src/api/bkuser_core/categories/plugins/local/syncer.py +++ b/src/api/bkuser_core/categories/plugins/local/syncer.py @@ -125,13 +125,13 @@ def __post_init__(self): self._default_password_valid_days = int(ConfigProvider(self.category_id).get("password_valid_days")) self.fetcher: ExcelFetcher = self.get_fetcher() - def sync(self, raw_data_file): + def sync(self, raw_data_file, is_overwrite): user_rows, departments = self.fetcher.fetch(raw_data_file) with transaction.atomic(): self._sync_departments(departments) with transaction.atomic(): - self._sync_users(self.fetcher.parser_set, user_rows) + self._sync_users(self.fetcher.parser_set, user_rows, is_overwrite) self._sync_leaders(self.fetcher.parser_set, user_rows) self._notify_init_passwords() @@ -175,7 +175,39 @@ def _judge_data_all_none(raw_data: list) -> bool: """某些状况下会读取 Excel 整个空行""" return all(x is None for x in raw_data) - def _sync_users(self, parser_set: "ParserSet", users: list): + def _department_profile_relation_handle( + self, + is_overwrite: bool, + department_groups: str, + profile_id: int, + should_deleted_department_profile_relation_ids: list, + ): + cell_parser = DepartmentCellParser(self.category_id) + # 已存在的用户-部门关系 + old_department_profile_relations = DepartmentThroughModel.objects.filter(profile_id=profile_id) + # Note: 有新关系可能存在重复数据,所以这里使用不变的old_department_set用于后续判断是否存在的依据, + # 而不使用后面会变更的old_department_relations数据 + old_department_set = {r.department_id for r in old_department_profile_relations} + old_department_relations = {r.department_id: r.id for r in old_department_profile_relations} + + for department in cell_parser.parse_to_db_obj(department_groups): + # 用户-部门关系已存在 + if department.pk in old_department_set: + # Note: 可能本次更新里存在重复数据,dict无法重复移除 + if department.pk in old_department_relations: + del old_department_relations[department.pk] + continue + + # 不存在则添加 + department_attachment = DepartmentThroughModel(department_id=department.pk, profile_id=profile_id) + self.db_sync_manager.magic_add(department_attachment) + + # 已存在的数据从old_department_relations移除后,最后剩下的数据,表示多余的,即本次更新里不存在的用户部门关系 + # 如果是覆盖,则记录需要删除多余数据 + if is_overwrite and len(old_department_relations) > 0: + should_deleted_department_profile_relation_ids.extend(old_department_relations.values()) + + def _sync_users(self, parser_set: "ParserSet", users: list, is_overwrite: bool = False): """在内存中操作&判断数据,bulk 插入""" logger.info("=========== trying to load profiles into memory ===========") @@ -184,6 +216,7 @@ def _sync_users(self, parser_set: "ParserSet", users: list): success_count = 0 total = len(users) + should_deleted_department_profile_relation_ids: list = [] for index, user_raw_info in enumerate(users): if self._judge_data_all_none(user_raw_info): logger.debug("empty line, skipping") @@ -235,8 +268,13 @@ def _sync_users(self, parser_set: "ParserSet", users: list): progress(index, total, f"loading {username}") try: updating_profile = Profile.objects.get(username=username, category_id=self.category_id) - - # 如果已经存在,则更新该 profile + # 已存在的用户:如果未勾选 <进行覆盖更新>(即is_overwrite为false)=》则忽略,反之则更新该 profile + if not is_overwrite: + logger.debug( + "username %s exist, and is_overwrite is false, so will not do update for this user, skip", + username, + ) + continue for name, value in profile_params.items(): if name == "extras": extras = updating_profile.extras or {} @@ -250,6 +288,7 @@ def _sync_users(self, parser_set: "ParserSet", users: list): setattr(updating_profile, name, value) profile_id = updating_profile.id + self.db_sync_manager.magic_add(updating_profile, SyncOperation.UPDATE.value) logger.debug("(%s/%s) username<%s> already exist, trying to update it", username, index + 1, total) @@ -278,15 +317,12 @@ def _sync_users(self, parser_set: "ParserSet", users: list): # 2 获取关联的部门DB实例,创建关联对象 progress(index, total, "adding profile & department relation") department_groups = parser_set.get_cell_data("department_name", user_raw_info) + self._department_profile_relation_handle( + is_overwrite, department_groups, profile_id, should_deleted_department_profile_relation_ids + ) - cell_parser = DepartmentCellParser(self.category_id) - for department in cell_parser.parse_to_db_obj(department_groups): - relation_params = {"department_id": department.pk, "profile_id": profile_id} - try: - DepartmentThroughModel.objects.get(**relation_params) - except DepartmentThroughModel.DoesNotExist: - department_attachment = DepartmentThroughModel(**relation_params) - self.db_sync_manager.magic_add(department_attachment) + if len(should_deleted_department_profile_relation_ids) > 0: + DepartmentThroughModel.objects.filter(id__in=should_deleted_department_profile_relation_ids).delete() # 需要在处理 leader 之前全部插入 DB self.db_sync_manager[Profile].sync_to_db() diff --git a/src/api/bkuser_core/common/error_codes.py b/src/api/bkuser_core/common/error_codes.py index 666f525c1..823d5f7f0 100644 --- a/src/api/bkuser_core/common/error_codes.py +++ b/src/api/bkuser_core/common/error_codes.py @@ -124,6 +124,14 @@ def __getattr__(self, code_name): ErrorCode("USER_ALREADY_EXISTED", _("该目录下此用户名已存在"), status_code=HTTP_409_CONFLICT), ErrorCode("SAVE_USER_INFO_FAILED", _("保存用户信息失败")), ErrorCode("PASSWORD_DUPLICATED", _("新密码不能与最近{max_password_history}次密码相同")), + ErrorCode("TELEPHONE_NOT_PROVIDED", _("该用户没有绑定手机号,发送短信失败")), + ErrorCode("TELEPHONE_BOUND_TO_MULTI_PROFILE", _("该手机号被多个用户绑定,请输入具体的用户名或联系管理员处理")), + ErrorCode("VERIFICATION_CODE_REPEAT_SENDING_REQUIRE", _("验证码已发送,有效时间为{effective_minutes}分钟,请勿重复发送")), + ErrorCode("VERIFICATION_CODE_SEND_REACH_LIMIT", _("该手机号已超过当日重置密码短信发送限制次数")), + ErrorCode("VERIFICATION_CODE_INVALID", _("验证码失效,请重新发送")), + ErrorCode("VERIFICATION_CODE_WRONG", _("你所输入验证码错误,请重新输入")), + ErrorCode("VERIFICATION_CODE_WRONG_REACH_LIMIT", _("你所输入验证码错误,验证次数已达上限,请验证码过期后重试")), + ErrorCode("OLD_PASSWORD_ERROR", _("原密码校验失败")), # 上传文件相关 ErrorCode("FILE_IMPORT_TOO_LARGE", _("上传文件过大")), ErrorCode("FILE_IMPORT_FORMAT_ERROR", _("上传文件格式错误")), diff --git a/src/api/bkuser_core/common/exception_handler.py b/src/api/bkuser_core/common/exception_handler.py index c6a253eb4..06bfc62ac 100644 --- a/src/api/bkuser_core/common/exception_handler.py +++ b/src/api/bkuser_core/common/exception_handler.py @@ -11,11 +11,14 @@ import logging import traceback +from django.conf import settings from django.core.exceptions import PermissionDenied +from django.db import ProgrammingError from django.http import Http404 from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import AuthenticationFailed, ValidationError from rest_framework.response import Response +from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR from rest_framework.views import exception_handler from sentry_sdk import capture_exception @@ -59,11 +62,11 @@ def custom_exception_handler(exc, context): # do nothing if get extra details fail pass - # if bool(context["request"].META.get(settings.FORCE_RAW_RESPONSE_HEADER)): - # return get_raw_exception_response(exc, context, detail) - # else: - # return get_ee_exception_response(exc, context, detail) - return get_ee_exception_response(exc, context, detail) + # NOTE: raw response还有在用, 并且单测基于raw response判断的status_code和异常报错(所以不能去掉) + if bool(context["request"].META.get(settings.FORCE_RAW_RESPONSE_HEADER)): + return get_raw_exception_response(exc, context, detail) + else: + return get_ee_exception_response(exc, context, detail) def get_ee_exception_response(exc, context, detail): @@ -88,7 +91,7 @@ def get_ee_exception_response(exc, context, detail): elif isinstance(exc, ValidationError): data["message"] = f"validation error: {exc}" elif isinstance(exc, AuthenticationFailed): - data["message"] = "403, authentication failed" + data["message"] = f"403, authentication failed: {exc}" else: # log logger.exception("unknown exception while handling the request, detail=%s", detail) @@ -111,3 +114,64 @@ def get_ee_exception_response(exc, context, detail): response = Response(data=data, status=EE_GENERAL_STATUS_CODE) setattr(response, "from_exception", True) return response + + +def one_line_error(detail): + """Extract one line error from error dict""" + try: + # A bare ValidationError will result in a list "detail" field instead of a dict + if isinstance(detail, list): + return detail[0] + else: + key, (first_error, *_) = next(iter(detail.items())) + if key == "non_field_errors": + return first_error + return f"{key}: {first_error}" + except Exception: # pylint: disable=broad-except + return "参数格式错误" + + +def get_raw_exception_response(exc, context, detail): + if isinstance(exc, ValidationError): + data = { + "code": "VALIDATION_ERROR", + "detail": one_line_error(exc.detail), + "fields_detail": exc.detail, + } + return Response(data, status=exc.status_code, headers={}) + elif isinstance(exc, CoreAPIError): + data = { + "code": exc.code.code_name, + "detail": exc.code.message, + } + return Response(data, status=exc.code.status_code, headers={}) + elif isinstance(exc, IAMPermissionDenied): + data = {"code": "PERMISSION_DENIED", "detail": exc.extra_info} + return Response(data, status=exc.status_code, headers={}) + elif isinstance(exc, ProgrammingError): + logger.exception("occur some programming errors") + data = {"code": "PROGRAMMING_ERROR", "detail": UNKNOWN_ERROR_HINT} + return Response(data, status=HTTP_400_BAD_REQUEST, headers={}) + + # log + logger.exception("unknown exception while handling the request, detail=%s", detail) + # report to sentry + capture_exception(exc) + + # Call REST framework's default exception handler to get the standard error response. + response = exception_handler(exc, context) + # Use a default error code + if response is not None: + response.data.update(code="ERROR") + setattr(response, "from_exception", True) + return response + + # NOTE: 不暴露给前端, 只打日志, 所以不放入data.detail + # error detail + if exc is not None: + detail["error"] = traceback.format_exc() + + data = {"result": False, "data": detail, "code": -1, "message": UNKNOWN_ERROR_HINT} + response = Response(data=data, status=HTTP_500_INTERNAL_SERVER_ERROR) + setattr(response, "from_exception", True) + return diff --git a/src/api/bkuser_core/config/common/storage.py b/src/api/bkuser_core/config/common/storage.py index 0cbc67b32..4797a9151 100644 --- a/src/api/bkuser_core/config/common/storage.py +++ b/src/api/bkuser_core/config/common/storage.py @@ -50,6 +50,17 @@ "LOCATION": "memory_cache_0", "KEY_PREFIX": "bk_user", }, + "verification_code": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_URL, + "TIMEOUT": 30 * 60, + "KEY_PREFIX": f"{REDIS_KEY_PREFIX}verification_code", + "VERSION": 1, + "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": REDIS_PASSWORD}, + "SOCKET_CONNECT_TIMEOUT": 5, # socket 建立连接超时设置,单位秒 + "SOCKET_TIMEOUT": 5, # 连接建立后的读写操作超时设置,单位秒 + "IGNORE_EXCEPTIONS": True, # redis 只作为缓存使用, 触发异常不能影响正常逻辑,可能只是稍微慢点而已 + }, } # 全局缓存过期时间,默认为一小时 GLOBAL_CACHES_TIMEOUT = env.int("GLOBAL_CACHES_TIMEOUT", default=60 * 60) diff --git a/src/api/bkuser_core/config/common/system.py b/src/api/bkuser_core/config/common/system.py index df1800271..997633187 100644 --- a/src/api/bkuser_core/config/common/system.py +++ b/src/api/bkuser_core/config/common/system.py @@ -17,6 +17,11 @@ # 密码配置 # ============================================================================== +# 允许原始密码校验错误次数 +RESET_PASSWORD_OLD_PASSWORD_ERROR_MAX_COUNT = 3 +# 重置密码时对原始密码校验超限是否锁定 +ENABLE_RESET_PASSWORD_ERROR_PROFILE_LOCK = env.bool("ENABLE_RESET_PASSWORD_ERROR_PROFILE_LOCK", default=False) + # 最大密码长度(明文) PASSWORD_MAX_LENGTH = 32 # 重复密码最大历史数量 @@ -87,6 +92,9 @@ # 登录次数统计时间周期, 默认为一个月 LOGIN_RECORD_COUNT_SECONDS = env.int("LOGIN_RECORD_COUNT_SECONDS", default=60 * 60 * 24 * 30) +# 重置密码次数统计时间周期, 默认为十分钟 +RESET_PASSWORD_RECORD_COUNT_SECONDS = env.int("RESET_PASSWORD_RECORD_COUNT_SECONDS", default=60 * 10) + # sync, 用户管理本身做业务 HTTP API 数据源, 可以被另一个用户管理同步过去 # 复用 API, 接口参数中存在 SYNC_API_PARAM 时, 以sync的接口协议返回 SYNC_API_PARAM = "for_sync" diff --git a/src/api/bkuser_core/config/overlays/unittest.py b/src/api/bkuser_core/config/overlays/unittest.py index 8980b9746..e21f6eb4f 100644 --- a/src/api/bkuser_core/config/overlays/unittest.py +++ b/src/api/bkuser_core/config/overlays/unittest.py @@ -73,19 +73,6 @@ def get_loggers(package_name: str, log_level: str) -> dict: # patch the unittest logging loggers LOGGING["loggers"] = get_loggers("bkuser_core", LOG_LEVEL) -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(PROJECT_ROOT, "db.sqlite3"), - # "NAME": env(f"{db_prefix}_NAME"), - # "USER": env(f"{db_prefix}_USER"), - # "PASSWORD": env(f"{db_prefix}_PASSWORD"), - # "HOST": env(f"{db_prefix}_HOST"), - # "PORT": env(f"{db_prefix}_PORT"), - # "OPTIONS": {"charset": "utf8mb4"}, - "TEST": {"CHARSET": "utf8mb4", "COLLATION": "utf8mb4_general_ci"}, - } -} # ============================================================================== # Test Ldap diff --git a/src/api/bkuser_core/profiles/models.py b/src/api/bkuser_core/profiles/models.py index a1d2dfad5..36fc64fdc 100644 --- a/src/api/bkuser_core/profiles/models.py +++ b/src/api/bkuser_core/profiles/models.py @@ -180,6 +180,10 @@ def to_audit_info(self): def bad_check_cnt(self) -> int: return self.login_set.latest_failed_count() + @property + def bad_old_password_check_cnt(self): + return self.resetpassword_set.latest_check_old_password_failed_count() + @property def latest_check_time(self): return self.login_set.filter(is_success=False, reason=LogInFailReason.BAD_PASSWORD.value).latest().create_time diff --git a/src/api/bkuser_core/profiles/utils.py b/src/api/bkuser_core/profiles/utils.py index bdffa1f12..f468bf055 100644 --- a/src/api/bkuser_core/profiles/utils.py +++ b/src/api/bkuser_core/profiles/utils.py @@ -16,22 +16,27 @@ from typing import TYPE_CHECKING, Dict, Tuple from django.conf import settings -from django.contrib.auth.hashers import make_password +from django.contrib.auth.hashers import check_password, make_password from phonenumbers.phonenumberutil import UNKNOWN_REGION, country_code_for_region, region_code_for_country_code +from ..audit.constants import OperationStatus, OperationType, ResetPasswordFailReason from ..audit.models import ResetPassword from .exceptions import CountryISOCodeNotMatch, UsernameWithDomainFormatError +from bkuser_core.audit.utils import create_general_log, create_profile_log from bkuser_core.categories.cache import get_default_category_id_from_local_cache +from bkuser_core.common.error_codes import error_codes +from bkuser_core.profiles.constants import ProfileStatus +from bkuser_core.profiles.models import Profile from bkuser_core.profiles.validators import DOMAIN_PART_REGEX, USERNAME_REGEX from bkuser_core.user_settings.constants import InitPasswordMethod from bkuser_core.user_settings.loader import ConfigProvider from bkuser_global.local import local -if TYPE_CHECKING: - from bkuser_core.profiles.models import Profile - logger = logging.getLogger(__name__) +if TYPE_CHECKING: + from rest_framework.request import Request + def gen_password(length): # 必须包含至少一个数字 @@ -245,3 +250,53 @@ def remove_sensitive_fields_for_profile(request, data: Dict) -> Dict: extras.pop(key) return data + + +def check_old_password(instance: "Profile", old_password: str, request: "Request"): + """原密码校验""" + raw_profile = Profile.objects.get(id=instance.id) + + if not check_password(old_password, raw_profile.password): + failed_reason = ResetPasswordFailReason.BAD_OLD_PASSWORD + try: + create_profile_log( + instance, + "ResetPassword", + {"is_success": False, "reason": failed_reason.value}, + request, + ) + except Exception: # pylint: disable=broad-except + logger.exception("failed to create reset password log") + + create_general_log( + operator=request.operator, + operate_type=OperationType.ADMIN_RESET_PASSWORD.value, + operator_obj=instance, + request=request, + status=OperationStatus.FAILED.value, + extra_info={"failed_info": ResetPasswordFailReason.get_choice_label(failed_reason.value)}, + ) + + if ( + instance.bad_old_password_check_cnt >= settings.RESET_PASSWORD_OLD_PASSWORD_ERROR_MAX_COUNT + and settings.ENABLE_RESET_PASSWORD_ERROR_PROFILE_LOCK + ): + # 校验失败次数超过配置次数并且配置锁定则对用户进行锁定 + raw_profile.status = ProfileStatus.LOCKED.value + raw_profile.save() + create_general_log( + operator=request.operator, + operate_type=OperationType.UPDATE.value, + operator_obj=instance, + request=request, + ) + + raise error_codes.OLD_PASSWORD_ERROR + + +def should_check_old_password(username: str) -> bool: + """重置密码时,校验是否为需要检查旧密码的用户""" + formatted_username = username.replace(" ", "").lower() + if not formatted_username == "admin": + return False + return True diff --git a/src/api/bkuser_core/tests/apis/utils.py b/src/api/bkuser_core/tests/apis/utils.py index 711d62893..d7760c6f1 100644 --- a/src/api/bkuser_core/tests/apis/utils.py +++ b/src/api/bkuser_core/tests/apis/utils.py @@ -18,10 +18,11 @@ def get_api_factory(force_params: dict = None): force_params = force_params or {} normal_params = { "HTTP_FORCE_RAW_RESPONSE": True, - "HTTP_RAW_USERNAME": True, "Content-Type": "application/json", - "HTTP_AUTHORIZATION": f"iBearer {list(settings.INTERNAL_AUTH_TOKENS.keys())[0]}", "HTTP_X_BKUSER_OPERATOR": "tester", + # "HTTP_RAW_USERNAME": True, + # should be removed after enhanced_account removed the token auth + "HTTP_AUTHORIZATION": f"iBearer {list(settings.INTERNAL_AUTH_TOKENS.keys())[0]}", } normal_params.update(force_params) diff --git a/src/api/bkuser_core/tests/apis/v2/departments/test_departments.py b/src/api/bkuser_core/tests/apis/v2/departments/test_departments.py index 5f9c4da88..d02b7b659 100644 --- a/src/api/bkuser_core/tests/apis/v2/departments/test_departments.py +++ b/src/api/bkuser_core/tests/apis/v2/departments/test_departments.py @@ -349,23 +349,22 @@ def view(self): return DepartmentViewSet.as_view({"get": "get_profiles", "post": "add_profiles"}) @pytest.mark.parametrize( - "lookup_value, creating_list, raw_username, expected", + "lookup_value, creating_list, expected", [ ( "部门C", ["部门A", "部门B", "部门C"], - False, "@test", ), - ( - "部门C", - ["部门A", "部门B", "部门C"], - True, - "user-0", - ), + # ( + # "部门C", + # ["部门A", "部门B", "部门C"], + # True, + # "user-0", + # ), ], ) - def test_department_get_profiles_1_cate(self, view, lookup_value, creating_list, raw_username, expected): + def test_department_get_profiles_1_cate(self, view, lookup_value, creating_list, expected): """测试从部门获取人员(当只有一个默认目录时)""" parent_id = 1 @@ -386,9 +385,7 @@ def test_department_get_profiles_1_cate(self, view, lookup_value, creating_list, attach_pd_relation(profile=_p, department=target_dep) response = view( - request=get_api_factory({"HTTP_RAW_USERNAME": raw_username}).get( - f"/api/v2/departments/{lookup_value}/profiles/?lookup_field=name" - ), + request=get_api_factory().get(f"/api/v2/departments/{lookup_value}/profiles/?lookup_field=name"), lookup_value=lookup_value, ) assert len(response.data["results"]) == 11 diff --git a/src/api/bkuser_core/tests/apis/v2/profiles/test_login.py b/src/api/bkuser_core/tests/apis/v2/profiles/test_login.py index 82180be0b..6dc9e930c 100644 --- a/src/api/bkuser_core/tests/apis/v2/profiles/test_login.py +++ b/src/api/bkuser_core/tests/apis/v2/profiles/test_login.py @@ -19,7 +19,7 @@ from bkuser_core.categories.constants import CategoryStatus from bkuser_core.profiles.constants import ProfileStatus, RoleCodeEnum from bkuser_core.tests.apis.utils import get_api_factory -from bkuser_core.tests.utils import make_simple_category, make_simple_profile +from bkuser_core.tests.utils import get_one_object, make_simple_category, make_simple_profile from bkuser_core.user_settings.models import Setting pytestmark = pytest.mark.django_db @@ -28,7 +28,8 @@ class TestListCreateApis: @pytest.fixture(scope="class") def factory(self): - return get_api_factory({"HTTP_RAW_USERNAME": False}) + # return get_api_factory({"HTTP_RAW_USERNAME": False}) + return get_api_factory() @pytest.fixture(scope="class") def check_view(self): @@ -47,11 +48,11 @@ def required_return_key(self): return [ "username", "email", - "telephone", - "wx_userid", + # "telephone", + # "wx_userid", "domain", "status", - "staff_status", + # "staff_status", ] def _assert_required_keys_exist(self, response_data: dict): @@ -225,7 +226,7 @@ def test_check_error(self, factory, check_view): response = check_view(request=request) assert response.data["code"] == "PASSWORD_ERROR" - # 超级用户不判断用户状态 + # 超级用户不对用户状态判断做豁免 p.role = RoleCodeEnum.SUPERUSER.value p.save() request = factory.post( @@ -233,8 +234,7 @@ def test_check_error(self, factory, check_view): data={"username": "logintest", "password": "testpwd", "domain": "testdomain"}, ) response = check_view(request=request) - assert response.data - self._assert_required_keys_exist(response.data) + assert response.data["code"] == "PASSWORD_ERROR" p.role = RoleCodeEnum.STAFF.value p.save() @@ -297,6 +297,24 @@ def test_check_auto_lock(self, factory, check_view): self._assert_required_keys_exist(response.data) + # admin用户不做豁免: + admin = get_one_object("profile", username="admin") + admin.set_password("adminpwd") + + request = factory.post("/api/v1/login/check/", data={"username": "admin", "password": "wrongpwd"}) + response = check_view(request=request) + assert response.data["code"] == "PASSWORD_ERROR" + + request = factory.post("/api/v1/login/check/", data={"username": "admin", "password": "wrongpwd"}) + response = check_view(request=request) + assert response.data["code"] == "PASSWORD_ERROR" + + # 确保解锁了 + time.sleep(2) + request = factory.post("/api/v1/login/check/", data={"username": "admin", "password": "adminpwd"}) + response = check_view(request=request) + self._assert_required_keys_exist(response.data) + def test_batch_query(self): """测试批量查询""" # request = self.factory.post('/api/v2/profiles/') diff --git a/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_action.py b/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_action.py index f0b609f45..a15844172 100644 --- a/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_action.py +++ b/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_action.py @@ -81,18 +81,6 @@ def test_profile_retrieve_domain(self, factory, view): response = view(request=request, lookup_value="adminAb@lettest") assert response.data["username"] == "adminAb@lettest" - def test_profile_retrieve_no_domain(self, factory, view): - """测试强制用户名不返回 domain""" - factory = get_api_factory() - make_simple_profile( - username="adminAb", - force_create_params={"domain": "lettest", "category_id": 2}, - ) - request = factory.get("/api/v2/profiles/adminAb@lettest/") - # 测试时需要手动指定 kwargs 参数当作路径参数 - response = view(request=request, lookup_value="adminAb@lettest") - assert response.data["username"] == "adminAb" - # --------------- update --------------- @pytest.mark.parametrize( "former_passwords,new_password,expected", diff --git a/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_list.py b/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_list.py index df1c201f7..1ef143d35 100644 --- a/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_list.py +++ b/src/api/bkuser_core/tests/apis/v2/profiles/test_profiles_list.py @@ -277,7 +277,7 @@ def test_profile_username_with_domain( @pytest.mark.parametrize( "query_string,target_code,results_count,target_username", [ - ("?wildcard_search=lette&wildcard_search_fields=domain", 200, 1, "adminAb"), + ("?wildcard_search=lette&wildcard_search_fields=domain", 200, 1, "adminAb@lettest"), ("?exact_lookups=admin", 200, 1, "admin"), ], ) @@ -300,9 +300,9 @@ def test_profile_username_force_no_domain( "query_string,results_count,target_username", [ ("?ordering=create_time", 2, "admin"), - ("?ordering=-create_time", 2, "adminAb"), + ("?ordering=-create_time", 2, "adminAb@lettest"), ("?ordering=id", 2, "admin"), - ("?ordering=-id", 2, "adminAb"), + ("?ordering=-id", 2, "adminAb@lettest"), ], ) def test_profile_list_ordering(self, factory, view, query_string, results_count, target_username): diff --git a/src/api/bkuser_core/tests/bkiam/test_constants.py b/src/api/bkuser_core/tests/bkiam/test_constants.py index 003db369b..6a11a1f27 100644 --- a/src/api/bkuser_core/tests/bkiam/test_constants.py +++ b/src/api/bkuser_core/tests/bkiam/test_constants.py @@ -18,28 +18,28 @@ class TestResourceTypeEnum: - @pytest.mark.parametrize( - "is_leaf, path, f, v", - [ - (True, "/category,5/department,3440/department,3443/", "parent_id", 3443), - (False, "/category,5/department,3440/department,3443/", "id", 3443), - (True, "/category,5/", "category_id", 5), - (False, "/category,5/", "category_id", 5), - (True, "/department,3440/department,3443/", "parent_id", 3443), - (False, "/department,3440/department,3443/", "id", 3443), - ], - ) - def test_get_key_mapping(self, is_leaf, path, f, v): - key_mapping = ResourceType.get_key_mapping(ResourceType.DEPARTMENT) - path_method = key_mapping["department._bk_iam_path_"] + # @pytest.mark.parametrize( + # "is_leaf, path, f, v", + # [ + # (True, "/category,5/department,3440/department,3443/", "parent_id", 3443), + # (False, "/category,5/department,3440/department,3443/", "id", 3443), + # (True, "/category,5/", "category_id", 5), + # (False, "/category,5/", "category_id", 5), + # (True, "/department,3440/department,3443/", "parent_id", 3443), + # (False, "/department,3440/department,3443/", "id", 3443), + # ], + # ) + # def test_get_key_mapping(self, is_leaf, path, f, v): + # key_mapping = ResourceType.get_key_mapping(ResourceType.DEPARTMENT) + # path_method = key_mapping["department._bk_iam_path_"] - data = {"value": path} - if not is_leaf: - data["node_type"] = "non-leaf" + # data = {"value": path} + # if not is_leaf: + # data["node_type"] = "non-leaf" - f, v = path_method(data) - assert f == f - assert v == v + # f, v = path_method(data) + # assert f == f + # assert v == v @pytest.mark.parametrize( "dep_chain, expected", diff --git a/src/api/bkuser_core/tests/bkiam/test_converter.py b/src/api/bkuser_core/tests/bkiam/test_converter.py index 03d965f11..87750f1e3 100644 --- a/src/api/bkuser_core/tests/bkiam/test_converter.py +++ b/src/api/bkuser_core/tests/bkiam/test_converter.py @@ -10,8 +10,8 @@ """ import pytest -from bkuser_core.bkiam.constants import ResourceType from bkuser_core.bkiam.converters import PathIgnoreDjangoQSConverter +from bkuser_core.bkiam.permissions import CATEGORY_KEY_MAPPING, DEPARTMENT_KEY_MAPPING class TestPathIgnoreDjangoQSConverter: @@ -82,7 +82,8 @@ class TestPathIgnoreDjangoQSConverter: ) def test_converter(self, policies, expected): """测试 filter 转换""" - fs = PathIgnoreDjangoQSConverter(ResourceType.get_key_mapping(ResourceType.DEPARTMENT)).convert(policies) + # fs = PathIgnoreDjangoQSConverter(ResourceType.get_key_mapping(ResourceType.DEPARTMENT)).convert(policies) + fs = PathIgnoreDjangoQSConverter(DEPARTMENT_KEY_MAPPING).convert(policies) assert str(fs) == expected @pytest.mark.parametrize( @@ -96,5 +97,7 @@ def test_converter(self, policies, expected): ) def test_converter_other(self, policies, expected): """测试 filter 转换""" - fs = PathIgnoreDjangoQSConverter(ResourceType.get_key_mapping(ResourceType.CATEGORY)).convert(policies) + + # fs = PathIgnoreDjangoQSConverter(ResourceType.get_key_mapping(ResourceType.CATEGORY)).convert(policies) + fs = PathIgnoreDjangoQSConverter(CATEGORY_KEY_MAPPING).convert(policies) assert str(fs) == expected diff --git a/src/api/bkuser_core/tests/bkiam/test_permissions.py b/src/api/bkuser_core/tests/bkiam/test_permissions.py index e09894944..06aed8f85 100644 --- a/src/api/bkuser_core/tests/bkiam/test_permissions.py +++ b/src/api/bkuser_core/tests/bkiam/test_permissions.py @@ -8,15 +8,12 @@ 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 unittest import mock +# from unittest import mock import pytest -from bkuser_core.bkiam.constants import IAMAction -from bkuser_core.bkiam.permissions import IAMPermissionExtraInfo -from bkuser_core.departments.models import Department from bkuser_core.departments.v2.views import DepartmentViewSet -from bkuser_core.tests.apis.utils import get_api_factory, make_request_operator_aware +from bkuser_core.tests.apis.utils import get_api_factory pytestmark = pytest.mark.django_db @@ -30,50 +27,50 @@ def factory(self): def view(self): return DepartmentViewSet.as_view({"get": "list", "post": "create"}) - def test_from_request(self, factory, view): - """测试从 request 生成 info 对象""" - request = factory.get("/api/v2/departments/") - make_request_operator_aware(request, operator="tester") - info = IAMPermissionExtraInfo.from_request(request) + # def test_from_request(self, factory, view): + # """测试从 request 生成 info 对象""" + # request = factory.get("/api/v2/departments/") + # make_request_operator_aware(request, operator="tester") + # info = IAMPermissionExtraInfo.from_request(request) - assert info.auth_infos - assert info.auth_infos[0].id == "manage_department" - assert info.auth_infos[0].display_name == IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT) + # assert info.auth_infos + # assert info.auth_infos[0].id == "manage_department" + # assert info.auth_infos[0].display_name == IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT) - def test_from_request_obj(self, factory, view): - """测试从 request 和 鉴权对象 生成 info 对象""" - request = factory.patch("/api/v2/departments/1/") - make_request_operator_aware(request, operator="tester") - info = IAMPermissionExtraInfo.from_request(request, obj=Department.objects.get(id=1)) + # def test_from_request_obj(self, factory, view): + # """测试从 request 和 鉴权对象 生成 info 对象""" + # request = factory.patch("/api/v2/departments/1/") + # make_request_operator_aware(request, operator="tester") + # info = IAMPermissionExtraInfo.from_request(request, obj=Department.objects.get(id=1)) - assert info.auth_infos - assert info.auth_infos[0].id == "manage_department" - assert info.auth_infos[0].display_name == IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT) - assert info.auth_infos[0].related_resources[0].name == "总公司" - assert info.auth_infos[0].related_resources[0].id == "1" - assert info.auth_infos[0].related_resources[0].type == "department" + # assert info.auth_infos + # assert info.auth_infos[0].id == "manage_department" + # assert info.auth_infos[0].display_name == IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT) + # assert info.auth_infos[0].related_resources[0].name == "总公司" + # assert info.auth_infos[0].related_resources[0].id == "1" + # assert info.auth_infos[0].related_resources[0].type == "department" - def test_to_dict(self, factory, view): - """测试从对象生成 dict""" - request = factory.get("/api/v2/departments/") - make_request_operator_aware(request, operator="tester") + # def test_to_dict(self, factory, view): + # """测试从对象生成 dict""" + # request = factory.get("/api/v2/departments/") + # make_request_operator_aware(request, operator="tester") - def return_fake_callback_url(*arg, **kwargs): - return "http://test.com" + # def return_fake_callback_url(*arg, **kwargs): + # return "http://test.com" - with mock.patch("bkuser_core.bkiam.helper.IAMHelper.generate_callback_url") as mocked_func: - mocked_func.side_effect = return_fake_callback_url - info = IAMPermissionExtraInfo.from_request(request) + # with mock.patch("bkuser_core.bkiam.helper.IAMHelper.generate_callback_url") as mocked_func: + # mocked_func.side_effect = return_fake_callback_url + # info = IAMPermissionExtraInfo.from_request(request) - raw_info = info.to_dict() + # raw_info = info.to_dict() - assert raw_info == { - "auth_infos": [ - { - "display_name": IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT), - "id": "manage_department", - "related_resources": [], - } - ], - "callback_url": return_fake_callback_url(), - } + # assert raw_info == { + # "auth_infos": [ + # { + # "display_name": IAMAction.get_choice_label(IAMAction.MANAGE_DEPARTMENT), + # "id": "manage_department", + # "related_resources": [], + # } + # ], + # "callback_url": return_fake_callback_url(), + # } diff --git a/src/api/bkuser_core/tests/categories/plugins/local/test_syncer.py b/src/api/bkuser_core/tests/categories/plugins/local/test_syncer.py index d73d0a48d..7d2d7be8b 100644 --- a/src/api/bkuser_core/tests/categories/plugins/local/test_syncer.py +++ b/src/api/bkuser_core/tests/categories/plugins/local/test_syncer.py @@ -105,7 +105,7 @@ def test_sync_users(self, syncer, pre_create_department, users, make_parser_set, ) @pytest.mark.parametrize( - "users,titles,expected", + "users,titles,expected,is_overwrite", [ ( [ @@ -118,10 +118,11 @@ def test_sync_users(self, syncer, pre_create_department, users, make_parser_set, "bbbb": "xxxx@xxxx.xyz", "cccc": "cccc@xxxx.com", }, - ), + True, + ) ], ) - def test_update_existed_users(self, syncer, users, make_parser_set, titles, expected): + def test_update_existed_users(self, syncer, users, make_parser_set, titles, expected, is_overwrite): """测试更新已存在用户""" for u in ["aaaa", "cccc"]: a = make_simple_profile(username=u, force_create_params={"category_id": syncer.category_id}) @@ -130,7 +131,7 @@ def test_update_existed_users(self, syncer, users, make_parser_set, titles, expe # TODO: 当前 id 最大值是在 db_sync_manager 初始化时确定的,实际上并不科学 syncer.db_sync_manager._update_cache() - syncer._sync_users(make_parser_set(titles), users) + syncer._sync_users(make_parser_set(titles), users, is_overwrite=is_overwrite) for k, v in expected.items(): assert Profile.objects.get(category_id=syncer.category_id, username=k).email == v @@ -182,9 +183,12 @@ def test_sync_leaders(self, syncer, users, make_parser_set, titles, expected, le ) def test_sync_wrong_users(self, syncer, users, make_parser_set, titles, expected): """测试异常用户同步""" - syncer._sync_users(make_parser_set(titles), users) + # FIXME: assert exception + with pytest.raises(Exception) as exc_info: + syncer._sync_users(make_parser_set(titles), users) assert ( - set(Profile.objects.filter(category_id=syncer.category_id).values_list("username", flat=True)) == expected + "导入执行完成: 成功 1 条记录, 失败 2 条记录" in exc_info.value.args[0] + or "导入执行完成: 成功 0 条记录, 失败 1 条记录" in exc_info.value.args[0] ) diff --git a/src/api/bkuser_core/tests/conftest.py b/src/api/bkuser_core/tests/conftest.py index 4fc7e07f7..a3a32eab1 100644 --- a/src/api/bkuser_core/tests/conftest.py +++ b/src/api/bkuser_core/tests/conftest.py @@ -25,6 +25,16 @@ pytestmark = pytest.mark.django_db +@pytest.fixture(autouse=True) +def reset_cache(): + yield + + # 必须清缓存, locmem放置了一些数据会导致测试互相影响 + from django.core.cache import caches + + caches["locmem"].clear() + + @pytest.fixture def factory(): return get_api_factory() diff --git a/src/api/bkuser_core/user_settings/migrations/0019_alter_local_password_rsa_config.py b/src/api/bkuser_core/user_settings/migrations/0019_alter_local_password_rsa_config.py new file mode 100644 index 000000000..b52cabcf1 --- /dev/null +++ b/src/api/bkuser_core/user_settings/migrations/0019_alter_local_password_rsa_config.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 __future__ import unicode_literals + +from bkuser_core.categories.constants import CategoryType +from bkuser_core.user_settings.constants import SettingsEnableNamespaces +from django.db import migrations + + +def forwards_func(apps, schema_editor): + """更新默认目录 密码-rsa加密模板配置""" + SettingMeta = apps.get_model("user_settings", "SettingMeta") + + local_password_rsa_settings = [ + dict( + key="enable_password_rsa_encrypted", + default=False, + example=False + ), + dict( + key="password_rsa_private_key", + default="", + example="LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpkZnNkZmRzZgotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=" + ), + dict( + key="password_rsa_public_key", + default="", + example="LS0tLS1CRUdJTiBSU0EgUFVCTElDS0VZLS0tLS0KZXJ0ZXJ0cmV0Ci0tLS0tRU5EIFJTQSBQVUJMSUNLRVktLS0tLQo=" + ) + ] + + for x in local_password_rsa_settings: + + meta, _ = SettingMeta.objects.get_or_create( + namespace=SettingsEnableNamespaces.PASSWORD.value, + category_type=CategoryType.LOCAL.value, + required=False, + **x + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("user_settings", "0018_alter_local_password_mail_config"), + ] + + operations = [migrations.RunPython(forwards_func)] diff --git a/src/api/bkuser_core/user_settings/migrations/0020_add_reset_password_by_phone_confi.py b/src/api/bkuser_core/user_settings/migrations/0020_add_reset_password_by_phone_confi.py new file mode 100644 index 000000000..efd5b71b2 --- /dev/null +++ b/src/api/bkuser_core/user_settings/migrations/0020_add_reset_password_by_phone_confi.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 __future__ import unicode_literals + +from bkuser_core.categories.constants import CategoryType +from bkuser_core.user_settings.constants import SettingsEnableNamespaces +from django.db import migrations + + +def forwards_func(apps, schema_editor): + """更新默认目录 密码-rsa加密模板配置""" + SettingMeta = apps.get_model("user_settings", "SettingMeta") + Setting = apps.get_model("user_settings", "Setting") + ProfileCategory = apps.get_model("categories", "ProfileCategory") + + local_password_reset_by_phone_settings = [ + dict( + key="reset_password_sms_config", + example={ + "sender": "蓝鲸智云", + "content": "【腾讯蓝鲸】验证码:{verification_code}您正在重置密码,如非本人操作,请忽略该短信", + "content_html": "

蓝鲸验证码:{verification_code},您正在重置密码,如非本人操作,请忽略该短信

" + }, + default={ + "sender": "蓝鲸智云", + "content": "【腾讯蓝鲸】验证码:{verification_code},您正在重置密码,如非本人操作,请忽略该短信", + "content_html": "

蓝鲸验证码:{verification_code},您正在重置密码,如非本人操作,请忽略该短信

" + }, + ), + # 最大验证失败次数 + dict( + key="failed_verification_max_limit", + example=3, + default=3, + ), + # 每日最多发送次数 + dict( + key="reset_sms_send_max_limit", + example=5, + default=5, + ), + # 验证码有效时间 + dict( + key="verification_code_expire_seconds", + example=1 * 60, + default=1 * 60, + ), + # 验证码长度 + dict( + key="verification_code_length", + example=6, + default=6, + ) + ] + + for x in local_password_reset_by_phone_settings: + + meta, _ = SettingMeta.objects.get_or_create( + namespace=SettingsEnableNamespaces.ACCOUNT.value, + category_type=CategoryType.LOCAL.value, + required=False, + **x + ) + for category in ProfileCategory.objects.filter(type=CategoryType.LOCAL.value): + Setting.objects.get_or_create(meta=meta, category_id=category.id, value=meta.default) + + +class Migration(migrations.Migration): + dependencies = [ + ("user_settings", "0019_alter_local_password_rsa_config"), + ] + + operations = [migrations.RunPython(forwards_func)] diff --git a/src/api/poetry.lock b/src/api/poetry.lock index 6d4fa9220..ac4e537ae 100644 --- a/src/api/poetry.lock +++ b/src/api/poetry.lock @@ -6,11 +6,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "aiocontextvars" version = "0.2.2" @@ -22,11 +17,6 @@ python-versions = ">=3.5" [package.dependencies] contextvars = {version = "2.4", markers = "python_version < \"3.7\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "amqp" version = "2.6.1" @@ -38,11 +28,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] vine = ">=1.1.3,<5.0.0a1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "apigw-manager" version = "1.1.5" @@ -60,14 +45,9 @@ pyyaml = ">=5.4.1" urllib3 = ">=1.25.3" [package.extras] -django = ["Django (>=1.11.1)", "pyjwt (>=1.6.4)"] -demo = ["Django (>=1.11.1)", "PyMySQL (>=1.0.2,<2.0.0)", "django-environ (>=0.8.1)", "pyjwt (>=1.6.4)"] cryptography = ["cryptography (>=3.1.1)", "pyjwt (>=1.6.4)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +demo = ["Django (>=1.11.1)", "PyMySQL (>=1.0.2,<2.0.0)", "django-environ (>=0.8.1)", "pyjwt (>=1.6.4)"] +django = ["Django (>=1.11.1)", "pyjwt (>=1.6.4)"] [[package]] name = "appnope" @@ -77,11 +57,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "asgiref" version = "3.4.1" @@ -94,44 +69,31 @@ python-versions = ">=3.6" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "atomicwrites" -version = "1.4.0" +version = "1.4.1" description = "Atomic file writes." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "attrs" -version = "21.4.0" +version = "22.2.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs", "zope.interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] +tests_no_zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] [[package]] name = "backcall" @@ -141,11 +103,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "backoff" version = "1.10.0" @@ -154,11 +111,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "billiard" version = "3.6.4.0" @@ -167,11 +119,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "bk-iam" version = "1.1.10" @@ -186,14 +133,9 @@ curlify = "2.2.1" requests = "*" six = ">=1.11.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "bkapi-bk-apigateway" -version = "1.0.6" +version = "1.0.9" description = "蓝鲸API网关" category = "main" optional = false @@ -205,14 +147,9 @@ bkapi-client-core = ">=1.0.2,<2.0.0" [package.extras] django = ["bkapi-client-core[django] (>=1.0.2,<2.0.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "bkapi-client-core" -version = "1.1.5" +version = "1.1.9" description = "" category = "main" optional = false @@ -224,12 +161,8 @@ requests = ">=2.20" typing-extensions = ">=3.7.4" [package.extras] -django = ["bkoauth (>=0.0.10)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +django = ["bkoauth (>=0.0.10)", "prometheus-client (>=0.9.0)"] +monitor = ["prometheus-client (>=0.9.0)"] [[package]] name = "black" @@ -256,11 +189,6 @@ jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "cachetools" version = "3.1.1" @@ -269,11 +197,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "celery" version = "4.4.7" @@ -291,12 +214,12 @@ vine = "1.3.0" [package.extras] arangodb = ["pyArango (>=1.3.2)"] auth = ["cryptography"] -azureblockblob = ["azure-storage (==0.36.0)", "azure-common (==1.1.5)", "azure-storage-common (==1.1.0)"] +azureblockblob = ["azure-common (==1.1.5)", "azure-storage (==0.36.0)", "azure-storage-common (==1.1.0)"] brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] cassandra = ["cassandra-driver (<3.21.0)"] consul = ["python-consul"] cosmosdbsql = ["pydocumentdb (==2.3.2)"] -couchbase = ["couchbase-cffi (<3.0.0)", "couchbase (<3.0.0)"] +couchbase = ["couchbase (<3.0.0)", "couchbase-cffi (<3.0.0)"] couchdb = ["pycouchdb"] django = ["Django (>=1.11)"] dynamodb = ["boto3 (>=1.9.178)"] @@ -322,27 +245,17 @@ yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "certifi" -version = "2021.10.8" +version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false -python-versions = "*" - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +python-versions = ">=3.6" [[package]] name = "cffi" -version = "1.15.0" +version = "1.15.1" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false @@ -351,11 +264,6 @@ python-versions = "*" [package.dependencies] pycparser = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "charset-normalizer" version = "2.0.12" @@ -367,11 +275,6 @@ python-versions = ">=3.5.0" [package.extras] unicode_backport = ["unicodedata2"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "click" version = "8.0.4" @@ -384,24 +287,14 @@ python-versions = ">=3.6" colorama = {version = "*", markers = "platform_system == \"Windows\""} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "contextvars" version = "2.4" @@ -413,11 +306,6 @@ python-versions = "*" [package.dependencies] immutables = ">=0.9" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "coreapi" version = "2.3.3" @@ -432,11 +320,6 @@ itypes = "*" requests = "*" uritemplate = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "coreschema" version = "0.0.4" @@ -448,11 +331,6 @@ python-versions = "*" [package.dependencies] jinja2 = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "coverage" version = "6.2" @@ -464,11 +342,6 @@ python-versions = ">=3.6" [package.extras] toml = ["tomli"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "cryptography" version = "3.4.8" @@ -482,16 +355,11 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] -docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] [[package]] name = "curlify" @@ -504,11 +372,6 @@ python-versions = "*" [package.dependencies] requests = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "dataclasses" version = "0.7" @@ -517,11 +380,6 @@ category = "main" optional = false python-versions = ">=3.6, <3.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "decorator" version = "5.1.1" @@ -530,11 +388,6 @@ category = "dev" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "deprecated" version = "1.2.13" @@ -547,12 +400,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "django" @@ -571,11 +419,6 @@ sqlparse = ">=0.2.2" argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-celery-beat" version = "2.2.0" @@ -590,11 +433,6 @@ Django = ">=2.2,<4.0" django-timezone-field = ">=4.1.0,<5.0" python-crontab = ">=2.3.4" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-celery-results" version = "2.0.1" @@ -606,11 +444,6 @@ python-versions = "*" [package.dependencies] celery = ">=4.4,<6.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-environ" version = "0.4.5" @@ -619,11 +452,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-js-asset" version = "2.0.0" @@ -638,11 +466,6 @@ Django = ">=2.2" [package.extras] tests = ["coverage"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-modeltranslation" version = "0.15.2" @@ -655,11 +478,6 @@ python-versions = "*" Django = ">=2.2" six = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-mptt" version = "0.12.0" @@ -672,11 +490,6 @@ python-versions = ">=3.6" Django = ">=1.11" django-js-asset = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-prometheus" version = "2.2.0" @@ -688,11 +501,6 @@ python-versions = "*" [package.dependencies] prometheus-client = ">=0.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-redis" version = "4.12.1" @@ -705,11 +513,6 @@ python-versions = ">=3.5" Django = ">=2.2" redis = ">=3.0.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-timezone-field" version = "4.2.3" @@ -725,11 +528,6 @@ pytz = "*" [package.extras] rest_framework = ["djangorestframework (>=3.0.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "djangorestframework" version = "3.12.4" @@ -741,11 +539,6 @@ python-versions = ">=3.5" [package.dependencies] django = ">=2.2" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "djangorestframework-jsonp" version = "1.0.2" @@ -754,11 +547,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "drf-yasg" version = "1.20.0" @@ -780,11 +568,6 @@ uritemplate = ">=3.0.0" [package.extras] validation = ["swagger-spec-validator (>=2.1.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "et-xmlfile" version = "1.1.0" @@ -793,11 +576,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "flake8" version = "3.9.2" @@ -812,11 +590,6 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "flake8-comprehensions" version = "3.5.0" @@ -829,11 +602,6 @@ python-versions = ">=3.6" flake8 = ">=3.0,<3.2.0 || >3.2.0,<4" importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "future" version = "0.18.2" @@ -842,11 +610,6 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "gevent" version = "21.1.2" @@ -865,36 +628,26 @@ greenlet = {version = ">=0.4.17,<2.0", markers = "platform_python_implementation dnspython = ["dnspython (>=1.16.0,<2.0)", "idna"] docs = ["repoze.sphinx.autointerface", "sphinxcontrib-programoutput", "zope.schema"] monitor = ["psutil (>=5.7.0)"] -recommended = ["dnspython (>=1.16.0,<2.0)", "idna", "cffi (>=1.12.2)", "selectors2", "backports.socketpair", "psutil (>=5.7.0)"] -test = ["dnspython (>=1.16.0,<2.0)", "idna", "requests", "objgraph", "cffi (>=1.12.2)", "selectors2", "futures", "mock", "backports.socketpair", "contextvars (==2.4)", "coverage (>=5.0)", "coveralls (>=1.7.0)", "psutil (>=5.7.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +recommended = ["backports.socketpair", "cffi (>=1.12.2)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)", "selectors2"] +test = ["backports.socketpair", "cffi (>=1.12.2)", "contextvars (==2.4)", "coverage (>=5.0)", "coveralls (>=1.7.0)", "dnspython (>=1.16.0,<2.0)", "futures", "idna", "mock", "objgraph", "psutil (>=5.7.0)", "requests", "selectors2"] [[package]] name = "googleapis-common-protos" -version = "1.56.2" +version = "1.56.3" description = "Common protobufs used in Google APIs" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -protobuf = ">=3.15.0,<4.0.0dev" +protobuf = ">=3.15.0,<5.0.0dev" [package.extras] grpc = ["grpcio (>=1.0.0,<2.0.0dev)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "greenlet" -version = "1.1.2" +version = "1.1.3.post0" description = "Lightweight in-process concurrent programming" category = "main" optional = false @@ -903,14 +656,9 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] docs = ["sphinx"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "grpcio" -version = "1.46.3" +version = "1.48.2" description = "HTTP/2-based RPC framework" category = "main" optional = false @@ -920,12 +668,7 @@ python-versions = ">=3.6" six = ">=1.5.2" [package.extras] -protobuf = ["grpcio-tools (>=1.46.3)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +protobuf = ["grpcio-tools (>=1.48.2)"] [[package]] name = "gunicorn" @@ -940,27 +683,17 @@ eventlet = ["eventlet (>=0.9.7)"] gevent = ["gevent (>=0.13)"] tornado = ["tornado (>=0.2)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "idna" -version = "3.3" +version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "immutables" -version = "0.18" +version = "0.19" description = "Immutable Collections" category = "main" optional = false @@ -970,12 +703,7 @@ python-versions = ">=3.6" typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [package.extras] -test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (==0.942)", "pytest (>=6.2.4,<6.3.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["flake8 (>=5.0.4,<5.1.0)", "mypy (==0.971)", "pycodestyle (>=2.9.1,<2.10.0)", "pytest (>=6.2.4,<6.3.0)"] [[package]] name = "importlib-metadata" @@ -990,14 +718,9 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-perf (>=0.9.2)"] [[package]] name = "inflection" @@ -1007,11 +730,6 @@ category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "iniconfig" version = "1.1.1" @@ -1020,11 +738,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ipython" version = "7.16.3" @@ -1051,15 +764,10 @@ doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] -notebook = ["notebook", "ipywidgets"] +notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.14)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.14)", "pygments", "requests", "testpath"] [[package]] name = "ipython-genutils" @@ -1069,11 +777,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "isort" version = "5.10.1" @@ -1084,14 +787,9 @@ python-versions = ">=3.6.1,<4.0" [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -requirements_deprecated_finder = ["pip-api", "pipreqs"] pipfile_deprecated_finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +requirements_deprecated_finder = ["pip-api", "pipreqs"] [[package]] name = "itypes" @@ -1101,11 +799,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "jedi" version = "0.17.2" @@ -1121,11 +814,6 @@ parso = ">=0.7.0,<0.8.0" qa = ["flake8 (==3.7.9)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (>=3.9.0,<5.0.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "jinja2" version = "3.0.3" @@ -1140,11 +828,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "jsonfield" version = "3.1.0" @@ -1156,11 +839,6 @@ python-versions = ">=3.6" [package.dependencies] Django = ">=2.2" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "kombu" version = "4.6.11" @@ -1189,11 +867,6 @@ sqs = ["boto3 (>=1.4.4)", "pycurl (==7.43.0.2)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ldap3" version = "2.9.1" @@ -1205,11 +878,6 @@ python-versions = "*" [package.dependencies] pyasn1 = ">=0.4.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "markupsafe" version = "2.0.1" @@ -1218,11 +886,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mccabe" version = "0.6.1" @@ -1231,11 +894,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mypy" version = "0.910" @@ -1254,11 +912,6 @@ typing-extensions = ">=3.7.4" dmypy = ["psutil (>=4.0)"] python2 = ["typed-ast (>=1.4.0,<1.5.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mypy-extensions" version = "0.4.3" @@ -1267,14 +920,9 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "openpyxl" -version = "3.0.9" +version = "3.0.10" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1283,11 +931,6 @@ python-versions = ">=3.6" [package.dependencies] et-xmlfile = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-api" version = "1.7.1" @@ -1300,11 +943,6 @@ python-versions = ">=3.6" aiocontextvars = {version = "*", markers = "python_version < \"3.7\""} Deprecated = ">=1.2.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger" version = "1.7.1" @@ -1317,11 +955,6 @@ python-versions = ">=3.6" opentelemetry-exporter-jaeger-proto-grpc = "1.7.1" opentelemetry-exporter-jaeger-thrift = "1.7.1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger-proto-grpc" version = "1.7.1" @@ -1336,11 +969,6 @@ grpcio = ">=1.0.0,<2.0.0" opentelemetry-api = ">=1.3,<2.0" opentelemetry-sdk = ">=1.3,<2.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger-thrift" version = "1.7.1" @@ -1354,11 +982,6 @@ opentelemetry-api = ">=1.3,<2.0" opentelemetry-sdk = ">=1.3,<2.0" thrift = ">=0.10.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp" version = "1.7.1" @@ -1371,11 +994,6 @@ python-versions = ">=3.6" opentelemetry-exporter-otlp-proto-grpc = "1.7.1" opentelemetry-exporter-otlp-proto-http = "1.7.1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" version = "1.7.1" @@ -1395,11 +1013,6 @@ opentelemetry-sdk = ">=1.3,<2.0" [package.extras] test = ["pytest-grpc"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp-proto-http" version = "1.7.1" @@ -1416,11 +1029,6 @@ opentelemetry-proto = "1.7.1" opentelemetry-sdk = ">=1.3,<2.0" requests = ">=2.7,<3.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation" version = "0.26b1" @@ -1433,11 +1041,6 @@ python-versions = ">=3.6" opentelemetry-api = ">=1.4,<2.0" wrapt = ">=1.0.0,<2.0.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-celery" version = "0.26b1" @@ -1453,12 +1056,7 @@ opentelemetry-semantic-conventions = "0.26b1" [package.extras] instruments = ["celery (>=4.0,<6.0)"] -test = ["pytest", "opentelemetry-test-utils (==0.26b1)", "celery (>=4.0,<6.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["celery (>=4.0,<6.0)", "opentelemetry-test-utils (==0.26b1)", "pytest"] [[package]] name = "opentelemetry-instrumentation-dbapi" @@ -1477,11 +1075,6 @@ wrapt = ">=1.0.0,<2.0.0" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-django" version = "0.26b1" @@ -1500,12 +1093,7 @@ opentelemetry-util-http = "0.26b1" [package.extras] asgi = ["opentelemetry-instrumentation-asgi (==0.26b1)"] instruments = ["django (>=1.10)"] -test = ["opentelemetry-test-utils (==0.26b1)", "django (>=1.10)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["django (>=1.10)", "opentelemetry-test-utils (==0.26b1)"] [[package]] name = "opentelemetry-instrumentation-logging" @@ -1522,11 +1110,6 @@ opentelemetry-instrumentation = "0.26b1" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-redis" version = "0.26b1" @@ -1543,12 +1126,7 @@ wrapt = ">=1.12.1" [package.extras] instruments = ["redis (>=2.6)"] -test = ["opentelemetry-test-utils (==0.26b1)", "opentelemetry-sdk (>=1.3,<2.0)", "redis (>=2.6)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["opentelemetry-sdk (>=1.3,<2.0)", "opentelemetry-test-utils (==0.26b1)", "redis (>=2.6)"] [[package]] name = "opentelemetry-instrumentation-requests" @@ -1566,12 +1144,7 @@ opentelemetry-util-http = "0.26b1" [package.extras] instruments = ["requests (>=2.0,<3.0)"] -test = ["opentelemetry-test-utils (==0.26b1)", "httpretty (>=1.0,<2.0)", "requests (>=2.0,<3.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["httpretty (>=1.0,<2.0)", "opentelemetry-test-utils (==0.26b1)", "requests (>=2.0,<3.0)"] [[package]] name = "opentelemetry-instrumentation-wsgi" @@ -1590,11 +1163,6 @@ opentelemetry-util-http = "0.26b1" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-proto" version = "1.7.1" @@ -1606,11 +1174,6 @@ python-versions = ">=3.6" [package.dependencies] protobuf = ">=3.13.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-sdk" version = "1.7.1" @@ -1623,11 +1186,6 @@ python-versions = ">=3.6" opentelemetry-api = "1.7.1" opentelemetry-semantic-conventions = "0.26b1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-semantic-conventions" version = "0.26b1" @@ -1636,11 +1194,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-util-http" version = "0.26b1" @@ -1649,11 +1202,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "packaging" version = "21.0" @@ -1665,11 +1213,6 @@ python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "parso" version = "0.7.1" @@ -1681,11 +1224,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] testing = ["docopt", "pytest (>=3.0.7)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pathspec" version = "0.9.0" @@ -1694,11 +1232,6 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pexpect" version = "4.8.0" @@ -1710,11 +1243,6 @@ python-versions = "*" [package.dependencies] ptyprocess = ">=0.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "phonenumbers" version = "8.11.0" @@ -1723,11 +1251,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pickleshare" version = "0.7.5" @@ -1736,11 +1259,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "platformdirs" version = "2.4.0" @@ -1753,11 +1271,6 @@ python-versions = ">=3.6" docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pluggy" version = "1.0.0" @@ -1773,14 +1286,9 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "prometheus-client" -version = "0.14.1" +version = "0.15.0" description = "Python client for the Prometheus monitoring system." category = "main" optional = false @@ -1789,14 +1297,9 @@ python-versions = ">=3.6" [package.extras] twisted = ["twisted"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "prompt-toolkit" -version = "3.0.29" +version = "3.0.36" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false @@ -1805,24 +1308,14 @@ python-versions = ">=3.6.2" [package.dependencies] wcwidth = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "protobuf" -version = "3.19.4" +version = "3.19.6" description = "Protocol Buffers" category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ptyprocess" version = "0.7.0" @@ -1831,11 +1324,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "py" version = "1.11.0" @@ -1844,11 +1332,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyasn1" version = "0.4.8" @@ -1857,11 +1340,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pycodestyle" version = "2.7.0" @@ -1870,11 +1348,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pycparser" version = "2.21" @@ -1883,15 +1356,10 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pydantic" -version = "1.9.0" -description = "Data validation and settings management using python 3.6 type hinting" +version = "1.9.2" +description = "Data validation and settings management using python type hints" category = "main" optional = false python-versions = ">=3.6.1" @@ -1904,11 +1372,6 @@ typing-extensions = ">=3.7.4.3" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyflakes" version = "2.3.1" @@ -1917,23 +1380,16 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pygments" -version = "2.12.0" +version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +[package.extras] +plugins = ["importlib-metadata"] [[package]] name = "pyjwt" @@ -1945,14 +1401,9 @@ python-versions = ">=3.6" [package.extras] crypto = ["cryptography (>=3.3.1)"] -dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] [[package]] name = "pymysql" @@ -1966,11 +1417,6 @@ python-versions = ">=3.6" ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyparsing" version = "2.4.7" @@ -1979,28 +1425,18 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyproject-flake8" -version = "0.0.1a4" +version = "0.0.1a5" description = "pyproject-flake8 (`pflake8`), a monkey patching wrapper to connect flake8 with pyproject.toml configuration" category = "dev" optional = false python-versions = "*" [package.dependencies] -flake8 = "*" +flake8 = "<5.0.0" tomli = {version = "*", markers = "python_version < \"3.11\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytest" version = "6.2.5" @@ -2023,11 +1459,6 @@ toml = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytest-cov" version = "2.12.1" @@ -2042,12 +1473,7 @@ pytest = ">=4.6" toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-django" @@ -2064,14 +1490,9 @@ pytest = ">=3.6" docs = ["sphinx", "sphinx-rtd-theme"] testing = ["django", "django-configurations (>=2.0)", "six"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-crontab" -version = "2.6.0" +version = "2.7.1" description = "Python Crontab API" category = "main" optional = false @@ -2084,11 +1505,6 @@ python-dateutil = "*" cron-description = ["cron-descriptor"] cron-schedule = ["croniter"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-dateutil" version = "2.8.2" @@ -2100,11 +1516,6 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] six = ">=1.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-json-logger" version = "0.1.11" @@ -2113,24 +1524,14 @@ category = "main" optional = false python-versions = ">=2.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytz" -version = "2022.1" +version = "2022.7" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyyaml" version = "6.0" @@ -2139,11 +1540,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "redis" version = "3.2.0" @@ -2155,11 +1551,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] hiredis = ["hiredis (>=0.1.3)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "regex" version = "2020.7.14" @@ -2168,11 +1559,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "requests" version = "2.27.1" @@ -2191,10 +1577,16 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +category = "main" +optional = false +python-versions = ">=3.6,<4" + +[package.dependencies] +pyasn1 = ">=0.1.3" [[package]] name = "ruamel.yaml" @@ -2211,24 +1603,14 @@ python-versions = ">=3" docs = ["ryd"] jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ruamel.yaml.clib" -version = "0.2.6" +version = "0.2.7" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "sentry-sdk" version = "1.5.6" @@ -2249,21 +1631,16 @@ celery = ["celery (>=3)"] chalice = ["chalice (>=1.16.0)"] django = ["django (>=1.8)"] falcon = ["falcon (>=1.4)"] -flask = ["flask (>=0.11)", "blinker (>=1.1)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)"] httpx = ["httpx (>=0.16.0)"] -pure_eval = ["pure-eval", "executing", "asttokens"] +pure_eval = ["asttokens", "executing", "pure-eval"] pyspark = ["pyspark (>=2.4.4)"] -quart = ["quart (>=0.16.1)", "blinker (>=1.1)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] rq = ["rq (>=0.6)"] sanic = ["sanic (>=0.8)"] sqlalchemy = ["sqlalchemy (>=1.2)"] tornado = ["tornado (>=5)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "six" version = "1.16.0" @@ -2272,24 +1649,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "sqlparse" -version = "0.4.2" +version = "0.4.3" description = "A non-validating SQL parser." category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "thrift" version = "0.16.0" @@ -2306,11 +1673,6 @@ all = ["tornado (>=4.0)", "twisted"] tornado = ["tornado (>=4.0)"] twisted = ["twisted"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "toml" version = "0.10.2" @@ -2319,11 +1681,6 @@ category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "tomli" version = "1.2.3" @@ -2332,11 +1689,6 @@ category = "dev" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "traitlets" version = "4.3.3" @@ -2351,12 +1703,7 @@ ipython-genutils = "*" six = "*" [package.extras] -test = ["pytest", "mock"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["mock", "pytest"] [[package]] name = "typed-ast" @@ -2366,11 +1713,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-cachetools" version = "4.2.10" @@ -2379,11 +1721,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-dataclasses" version = "0.1.7" @@ -2392,24 +1729,14 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-pymysql" -version = "1.0.19" +version = "1.0.19.1" description = "Typing stubs for PyMySQL" category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-pytz" version = "2021.3.8" @@ -2418,11 +1745,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-pyyaml" version = "5.4.12" @@ -2431,11 +1753,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-redis" version = "3.5.18" @@ -2444,14 +1761,9 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-requests" -version = "2.27.25" +version = "2.28.11.7" description = "Typing stubs for requests" category = "dev" optional = false @@ -2460,11 +1772,6 @@ python-versions = "*" [package.dependencies] types-urllib3 = "<1.27" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-toml" version = "0.1.5" @@ -2473,24 +1780,14 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "types-urllib3" -version = "1.26.14" +version = "1.26.25.4" description = "Typing stubs for urllib3" category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "typing-extensions" version = "4.1.1" @@ -2499,11 +1796,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "uritemplate" version = "4.1.1" @@ -2512,29 +1804,19 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "urllib3" -version = "1.26.9" +version = "1.26.13" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "vine" version = "1.3.0" @@ -2543,11 +1825,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "wcwidth" version = "0.2.5" @@ -2556,11 +1833,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "werkzeug" version = "2.0.3" @@ -2575,11 +1847,6 @@ dataclasses = {version = "*", markers = "python_version < \"3.7\""} [package.extras] watchdog = ["watchdog"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "whitenoise" version = "5.2.0" @@ -2591,11 +1858,6 @@ python-versions = ">=3.5, <4" [package.extras] brotli = ["brotli"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "wrapt" version = "1.14.1" @@ -2604,11 +1866,6 @@ category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "zipp" version = "3.6.0" @@ -2618,17 +1875,12 @@ optional = false python-versions = ">=3.6" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "zope.event" -version = "4.5.0" +version = "4.6" description = "Very basic event publishing system" category = "main" optional = false @@ -2638,33 +1890,23 @@ python-versions = "*" docs = ["sphinx"] test = ["zope.testrunner"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "zope.interface" -version = "5.4.0" +version = "5.5.2" description = "Interfaces for Python" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -docs = ["sphinx", "repoze.sphinx.autointerface"] +docs = ["repoze.sphinx.autointerface", "sphinx"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [metadata] lock-version = "1.1" python-versions = "3.6.14" -content-hash = "a5df43ed5650d6e3aa47d75a0ec94bea78d86ecf964646bb92734b3fa84308e9" +content-hash = "dd7047bc7959257a093eb2baee7c96941b2efe15aa5de6f0c8de93322e907e29" [metadata.files] aenum = [ @@ -2681,7 +1923,7 @@ amqp = [ {file = "amqp-2.6.1.tar.gz", hash = "sha256:70cdb10628468ff14e57ec2f751c7aa9e48e7e3651cfd62d431213c0c4e58f21"}, ] apigw-manager = [ - {file = "apigw_manager-1.1.5-py3-none-any.whl", hash = "md5:cc2df9c0dc88460737b338213b7cc511"}, + {file = "apigw_manager-1.1.5-py3-none-any.whl", hash = "sha256:694ef800ace5344d0b2b5a88dbcd51c143fd3597066cab508b3141cc2f3449d2"}, ] appnope = [ {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, @@ -2692,12 +1934,11 @@ asgiref = [ {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, ] atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, ] backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, @@ -2716,10 +1957,10 @@ bk-iam = [ {file = "bk_iam-1.1.10-py2.py3-none-any.whl", hash = "sha256:83b01016c54e77b39ad474d5265686117bf4b9a70d120397e9c4ae493ce6e8ee"}, ] bkapi-bk-apigateway = [ - {file = "bkapi-bk-apigateway-1.0.6.tar.gz", hash = "md5:a29cfd774a9185c920a394cdec0a9493"}, + {file = "bkapi-bk-apigateway-1.0.9.tar.gz", hash = "sha256:cf11b748cfc671f2fab9b5dc960ab907237b1fff1c319ef6dc4cebb2f8280109"}, ] bkapi-client-core = [ - {file = "bkapi_client_core-1.1.5-py2.py3-none-any.whl", hash = "md5:30099edee4570333fe103e71fe8735f5"}, + {file = "bkapi_client_core-1.1.9-py2.py3-none-any.whl", hash = "sha256:0d0d1210e268f1a93547abfe8cc2701ee77f7c53096ac2a50624a132f726663c"}, ] black = [ {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, @@ -2734,60 +1975,74 @@ celery = [ {file = "celery-4.4.7.tar.gz", hash = "sha256:d220b13a8ed57c78149acf82c006785356071844afe0b27012a4991d44026f9f"}, ] certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, ] cffi = [ - {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, - {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, - {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, - {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, - {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, - {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, - {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, - {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, - {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, - {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, - {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, - {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, - {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, - {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, - {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, - {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, - {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, ] charset-normalizer = [ {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, @@ -2798,8 +2053,8 @@ click = [ {file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] contextvars = [ {file = "contextvars-2.4.tar.gz", hash = "sha256:f38c908aaa59c14335eeea12abea5f443646216c4e29380d7bf34d2018e2c39e"}, @@ -2994,180 +2249,175 @@ gevent = [ {file = "gevent-21.1.2.tar.gz", hash = "sha256:520cc2a029a9eef436e4e56b007af7859315cafa21937d43c1d5269f12f2c981"}, ] googleapis-common-protos = [ - {file = "googleapis-common-protos-1.56.2.tar.gz", hash = "sha256:b09b56f5463070c2153753ef123f07d2e49235e89148e9b2459ec8ed2f68d7d3"}, - {file = "googleapis_common_protos-1.56.2-py2.py3-none-any.whl", hash = "sha256:023eaea9d8c1cceccd9587c6af6c20f33eeeb05d4148670f2b0322dc1511700c"}, + {file = "googleapis-common-protos-1.56.3.tar.gz", hash = "sha256:6f1369b58ed6cf3a4b7054a44ebe8d03b29c309257583a2bbdc064cd1e4a1442"}, + {file = "googleapis_common_protos-1.56.3-py2.py3-none-any.whl", hash = "sha256:87955d7b3a73e6e803f2572a33179de23989ebba725e05ea42f24838b792e461"}, ] greenlet = [ - {file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"}, - {file = "greenlet-1.1.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a"}, - {file = "greenlet-1.1.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d"}, - {file = "greenlet-1.1.2-cp27-cp27m-win32.whl", hash = "sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713"}, - {file = "greenlet-1.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40"}, - {file = "greenlet-1.1.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d"}, - {file = "greenlet-1.1.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8"}, - {file = "greenlet-1.1.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d"}, - {file = "greenlet-1.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497"}, - {file = "greenlet-1.1.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1"}, - {file = "greenlet-1.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58"}, - {file = "greenlet-1.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965"}, - {file = "greenlet-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708"}, - {file = "greenlet-1.1.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23"}, - {file = "greenlet-1.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee"}, - {file = "greenlet-1.1.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c"}, - {file = "greenlet-1.1.2-cp35-cp35m-win32.whl", hash = "sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963"}, - {file = "greenlet-1.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e"}, - {file = "greenlet-1.1.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073"}, - {file = "greenlet-1.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c"}, - {file = "greenlet-1.1.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e"}, - {file = "greenlet-1.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce"}, - {file = "greenlet-1.1.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08"}, - {file = "greenlet-1.1.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168"}, - {file = "greenlet-1.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f"}, - {file = "greenlet-1.1.2-cp36-cp36m-win32.whl", hash = "sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa"}, - {file = "greenlet-1.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d"}, - {file = "greenlet-1.1.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4"}, - {file = "greenlet-1.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"}, - {file = "greenlet-1.1.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c"}, - {file = "greenlet-1.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1"}, - {file = "greenlet-1.1.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28"}, - {file = "greenlet-1.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5"}, - {file = "greenlet-1.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe"}, - {file = "greenlet-1.1.2-cp37-cp37m-win32.whl", hash = "sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc"}, - {file = "greenlet-1.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06"}, - {file = "greenlet-1.1.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0"}, - {file = "greenlet-1.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627"}, - {file = "greenlet-1.1.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478"}, - {file = "greenlet-1.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43"}, - {file = "greenlet-1.1.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711"}, - {file = "greenlet-1.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b"}, - {file = "greenlet-1.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2"}, - {file = "greenlet-1.1.2-cp38-cp38-win32.whl", hash = "sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd"}, - {file = "greenlet-1.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3"}, - {file = "greenlet-1.1.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67"}, - {file = "greenlet-1.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab"}, - {file = "greenlet-1.1.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5"}, - {file = "greenlet-1.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88"}, - {file = "greenlet-1.1.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b"}, - {file = "greenlet-1.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3"}, - {file = "greenlet-1.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3"}, - {file = "greenlet-1.1.2-cp39-cp39-win32.whl", hash = "sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf"}, - {file = "greenlet-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd"}, - {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, + {file = "greenlet-1.1.3.post0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:949c9061b8c6d3e6e439466a9be1e787208dec6246f4ec5fffe9677b4c19fcc3"}, + {file = "greenlet-1.1.3.post0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d7815e1519a8361c5ea2a7a5864945906f8e386fa1bc26797b4d443ab11a4589"}, + {file = "greenlet-1.1.3.post0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9649891ab4153f217f319914455ccf0b86986b55fc0573ce803eb998ad7d6854"}, + {file = "greenlet-1.1.3.post0-cp27-cp27m-win32.whl", hash = "sha256:11fc7692d95cc7a6a8447bb160d98671ab291e0a8ea90572d582d57361360f05"}, + {file = "greenlet-1.1.3.post0-cp27-cp27m-win_amd64.whl", hash = "sha256:05ae7383f968bba4211b1fbfc90158f8e3da86804878442b4fb6c16ccbcaa519"}, + {file = "greenlet-1.1.3.post0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ccbe7129a282ec5797df0451ca1802f11578be018a32979131065565da89b392"}, + {file = "greenlet-1.1.3.post0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a8b58232f5b72973350c2b917ea3df0bebd07c3c82a0a0e34775fc2c1f857e9"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:f6661b58412879a2aa099abb26d3c93e91dedaba55a6394d1fb1512a77e85de9"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c6e942ca9835c0b97814d14f78da453241837419e0d26f7403058e8db3e38f8"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a812df7282a8fc717eafd487fccc5ba40ea83bb5b13eb3c90c446d88dbdfd2be"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83a7a6560df073ec9de2b7cb685b199dfd12519bc0020c62db9d1bb522f989fa"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17a69967561269b691747e7f436d75a4def47e5efcbc3c573180fc828e176d80"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:60839ab4ea7de6139a3be35b77e22e0398c270020050458b3d25db4c7c394df5"}, + {file = "greenlet-1.1.3.post0-cp310-cp310-win_amd64.whl", hash = "sha256:8926a78192b8b73c936f3e87929931455a6a6c6c385448a07b9f7d1072c19ff3"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c6f90234e4438062d6d09f7d667f79edcc7c5e354ba3a145ff98176f974b8132"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:814f26b864ed2230d3a7efe0336f5766ad012f94aad6ba43a7c54ca88dd77cba"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fda1139d87ce5f7bd80e80e54f9f2c6fe2f47983f1a6f128c47bf310197deb6"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0643250dd0756f4960633f5359884f609a234d4066686754e834073d84e9b51"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cb863057bed786f6622982fb8b2c122c68e6e9eddccaa9fa98fd937e45ee6c4f"}, + {file = "greenlet-1.1.3.post0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8c0581077cf2734569f3e500fab09c0ff6a2ab99b1afcacbad09b3c2843ae743"}, + {file = "greenlet-1.1.3.post0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:695d0d8b5ae42c800f1763c9fce9d7b94ae3b878919379150ee5ba458a460d57"}, + {file = "greenlet-1.1.3.post0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:5662492df0588a51d5690f6578f3bbbd803e7f8d99a99f3bf6128a401be9c269"}, + {file = "greenlet-1.1.3.post0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:bffba15cff4802ff493d6edcf20d7f94ab1c2aee7cfc1e1c7627c05f1102eee8"}, + {file = "greenlet-1.1.3.post0-cp35-cp35m-win32.whl", hash = "sha256:7afa706510ab079fd6d039cc6e369d4535a48e202d042c32e2097f030a16450f"}, + {file = "greenlet-1.1.3.post0-cp35-cp35m-win_amd64.whl", hash = "sha256:3a24f3213579dc8459e485e333330a921f579543a5214dbc935bc0763474ece3"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:64e10f303ea354500c927da5b59c3802196a07468332d292aef9ddaca08d03dd"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:eb6ac495dccb1520667cfea50d89e26f9ffb49fa28496dea2b95720d8b45eb54"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:88720794390002b0c8fa29e9602b395093a9a766b229a847e8d88349e418b28a"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39464518a2abe9c505a727af7c0b4efff2cf242aa168be5f0daa47649f4d7ca8"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0914f02fcaa8f84f13b2df4a81645d9e82de21ed95633765dd5cc4d3af9d7403"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96656c5f7c95fc02c36d4f6ef32f4e94bb0b6b36e6a002c21c39785a4eec5f5d"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4f74aa0092602da2069df0bc6553919a15169d77bcdab52a21f8c5242898f519"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3aeac044c324c1a4027dca0cde550bd83a0c0fbff7ef2c98df9e718a5086c194"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-win32.whl", hash = "sha256:fe7c51f8a2ab616cb34bc33d810c887e89117771028e1e3d3b77ca25ddeace04"}, + {file = "greenlet-1.1.3.post0-cp36-cp36m-win_amd64.whl", hash = "sha256:70048d7b2c07c5eadf8393e6398595591df5f59a2f26abc2f81abca09610492f"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:66aa4e9a726b70bcbfcc446b7ba89c8cec40f405e51422c39f42dfa206a96a05"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:025b8de2273d2809f027d347aa2541651d2e15d593bbce0d5f502ca438c54136"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:82a38d7d2077128a017094aff334e67e26194f46bd709f9dcdacbf3835d47ef5"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7d20c3267385236b4ce54575cc8e9f43e7673fc761b069c820097092e318e3b"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8ece5d1a99a2adcb38f69af2f07d96fb615415d32820108cd340361f590d128"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2794eef1b04b5ba8948c72cc606aab62ac4b0c538b14806d9c0d88afd0576d6b"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a8d24eb5cb67996fb84633fdc96dbc04f2d8b12bfcb20ab3222d6be271616b67"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0120a879aa2b1ac5118bce959ea2492ba18783f65ea15821680a256dfad04754"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-win32.whl", hash = "sha256:bef49c07fcb411c942da6ee7d7ea37430f830c482bf6e4b72d92fd506dd3a427"}, + {file = "greenlet-1.1.3.post0-cp37-cp37m-win_amd64.whl", hash = "sha256:62723e7eb85fa52e536e516ee2ac91433c7bb60d51099293671815ff49ed1c21"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d25cdedd72aa2271b984af54294e9527306966ec18963fd032cc851a725ddc1b"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:924df1e7e5db27d19b1359dc7d052a917529c95ba5b8b62f4af611176da7c8ad"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ec615d2912b9ad807afd3be80bf32711c0ff9c2b00aa004a45fd5d5dde7853d9"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0971d37ae0eaf42344e8610d340aa0ad3d06cd2eee381891a10fe771879791f9"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:325f272eb997916b4a3fc1fea7313a8adb760934c2140ce13a2117e1b0a8095d"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75afcbb214d429dacdf75e03a1d6d6c5bd1fa9c35e360df8ea5b6270fb2211c"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5c2d21c2b768d8c86ad935e404cc78c30d53dea009609c3ef3a9d49970c864b5"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:467b73ce5dcd89e381292fb4314aede9b12906c18fab903f995b86034d96d5c8"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-win32.whl", hash = "sha256:8149a6865b14c33be7ae760bcdb73548bb01e8e47ae15e013bf7ef9290ca309a"}, + {file = "greenlet-1.1.3.post0-cp38-cp38-win_amd64.whl", hash = "sha256:104f29dd822be678ef6b16bf0035dcd43206a8a48668a6cae4d2fe9c7a7abdeb"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:c8c9301e3274276d3d20ab6335aa7c5d9e5da2009cccb01127bddb5c951f8870"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:8415239c68b2ec9de10a5adf1130ee9cb0ebd3e19573c55ba160ff0ca809e012"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:3c22998bfef3fcc1b15694818fc9b1b87c6cc8398198b96b6d355a7bcb8c934e"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0aa1845944e62f358d63fcc911ad3b415f585612946b8edc824825929b40e59e"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:890f633dc8cb307761ec566bc0b4e350a93ddd77dc172839be122be12bae3e10"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cf37343e43404699d58808e51f347f57efd3010cc7cee134cdb9141bd1ad9ea"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5edf75e7fcfa9725064ae0d8407c849456553a181ebefedb7606bac19aa1478b"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a954002064ee919b444b19c1185e8cce307a1f20600f47d6f4b6d336972c809"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-win32.whl", hash = "sha256:2ccdc818cc106cc238ff7eba0d71b9c77be868fdca31d6c3b1347a54c9b187b2"}, + {file = "greenlet-1.1.3.post0-cp39-cp39-win_amd64.whl", hash = "sha256:91a84faf718e6f8b888ca63d0b2d6d185c8e2a198d2a7322d75c303e7097c8b7"}, + {file = "greenlet-1.1.3.post0.tar.gz", hash = "sha256:f5e09dc5c6e1796969fd4b775ea1417d70e49a5df29aaa8e5d10675d9e11872c"}, ] grpcio = [ - {file = "grpcio-1.46.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:4c05dbc164c2d3015109292ffeed68292807a6cb1225f9a36699bf2166634908"}, - {file = "grpcio-1.46.3-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:c6a460b6aaf43428d48fececad864cc562458b944df80568e490d985d8576292"}, - {file = "grpcio-1.46.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:707b85fa0cf606a9ab02246bd3142c76e154f1c30f00f7346b2afa3d0b315d5a"}, - {file = "grpcio-1.46.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c63e7c61c0b06f838e8f45ffd3a7c68a520c4c026b2e0e8b1ad29c456d0f859"}, - {file = "grpcio-1.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6fe85e5873d9784ab82cf261d9fc07ed67a4459ba69fbe1187ef8b8e3d9e30e"}, - {file = "grpcio-1.46.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df980c4901a92ca649e18036ff67c7c8cad239b2759c2472694f7ab0f0b4ffb9"}, - {file = "grpcio-1.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7b59982e405159385d5796aa1e0817ec83affb3eb4c2a5b7ca39413d17d7e332"}, - {file = "grpcio-1.46.3-cp310-cp310-win32.whl", hash = "sha256:6d51fa98bd40d4593f819a3fec8a078a192958d24f84c3daf15b5ad7705d4c48"}, - {file = "grpcio-1.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:e9bba429eb743471715e6dadf006a70a77cb6afb065aa4a6eaa9efd76b09e336"}, - {file = "grpcio-1.46.3-cp36-cp36m-linux_armv7l.whl", hash = "sha256:a898b0f13bda2dfe786952cc1ea705762fa6c3ae799b4bb0525d7821605ae968"}, - {file = "grpcio-1.46.3-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:9014aee70e29911008d2f388011cabf2c7fe4fe29918ce5f71513a660494069a"}, - {file = "grpcio-1.46.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9c97106134de70f8323b12738ac0adf0615688b69253002910d0c5d42d202a77"}, - {file = "grpcio-1.46.3-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d41ea8efb87b1ae4e576b13d94f2b470297a1495ae6b2c9d1047952731bf168f"}, - {file = "grpcio-1.46.3-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:ab18e85082003d7883a4d069065436e61cb27c2c2150e7965ce93658f17bc8da"}, - {file = "grpcio-1.46.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:307ff1d6237d5c383196660a12db021c20280227f9f4423d88d6b2ab20c8b1d0"}, - {file = "grpcio-1.46.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c9106ef35239767b3aa9dc1a79856ad499655f853fca9f92f9dd3182d646627"}, - {file = "grpcio-1.46.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e0ae8e8523308bf7ab0b7d6aa686011de59b19fb06abb253f302d0b5da2a5905"}, - {file = "grpcio-1.46.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4fd0aa30a938893060defd5f222604461db55f9a81a028b154479b91deac7074"}, - {file = "grpcio-1.46.3-cp36-cp36m-win32.whl", hash = "sha256:f7637b55662e56a64c07846bc0d2da6232a6e893b22c39790f2e41d03ac1a826"}, - {file = "grpcio-1.46.3-cp36-cp36m-win_amd64.whl", hash = "sha256:97801afa96a819f911d030b490dbea95b246de02433bac69c5acf150081686e4"}, - {file = "grpcio-1.46.3-cp37-cp37m-linux_armv7l.whl", hash = "sha256:3585a6fa3d97fc8f030bbf0e88185b5eb345a340f6732e165d5c22df54de5bc6"}, - {file = "grpcio-1.46.3-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:dc6d15cbcceaebaacf2994280ed1c01d42b5772059b30afd8a76152e9d23daa4"}, - {file = "grpcio-1.46.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e0486485d59d5865149010966ef3df99c5df97ab8b01f10e26f8759d6e10fafc"}, - {file = "grpcio-1.46.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5210ec7a1638daa61da16487fbfafb3dbb7b8cd44382d9262316bbb58a5b1cf7"}, - {file = "grpcio-1.46.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:e278fa30d2b5652f7e43970c86ad34c639146443553678b746909aae204924dc"}, - {file = "grpcio-1.46.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d4148f1f76516b01cccf2273b45bc706847f1560ccb55aa6e29df851e9ca8cc"}, - {file = "grpcio-1.46.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01f3f7a6cdb111cf276ffff9c892fa32624e03999bac809d3f3d8321d98b6855"}, - {file = "grpcio-1.46.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:91aaccbe1c035ad2bcd1b8a25cebd11839070eb70fb6573e9d0197ddbca5d96b"}, - {file = "grpcio-1.46.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:26136c19d96e2138f04412101f3730d66f5f1515dc912ac0d415587c8208d826"}, - {file = "grpcio-1.46.3-cp37-cp37m-win32.whl", hash = "sha256:a8f40dafcdc3e0e378387953528eaf4e35758161f3b10d96199f12b11afbe2c2"}, - {file = "grpcio-1.46.3-cp37-cp37m-win_amd64.whl", hash = "sha256:a6bb52df85a4bd6d3bad16b4e7cc43efe95469b74a856c87a2c5bef496c9147f"}, - {file = "grpcio-1.46.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:2334ceeab4084e80433693451452cba26afc1607a7974133af3b3635fc8aa935"}, - {file = "grpcio-1.46.3-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:2c96a6103caec84985bb2cffac2b261f8cac2641e7a70d4b43b7d08754a6cfe7"}, - {file = "grpcio-1.46.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7a39d39da8855b03be2d7348387986bab6a322031fcc8b04fa5e72355e7b13a1"}, - {file = "grpcio-1.46.3-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4caf87a06de88e3611a4610c57ef55b78801843d1f5a9e5fd6b75e887dad3340"}, - {file = "grpcio-1.46.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:ffbbb228e6fc6f85b34aac428eb76b4fc6591d771e487ce46eb16b4b7e18b91d"}, - {file = "grpcio-1.46.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c89ae010c57333dd3c692e0892199a59df1ddfd467cdfea31f98331d0e8cf87"}, - {file = "grpcio-1.46.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34b206cdf78dd1c14d93e10e7308750c36b4e6754d579895cba74341875e2fb5"}, - {file = "grpcio-1.46.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a19b3ecdb8ddf60e4b034def27636065e49ac1ee3c85854a16353cf52c2afd83"}, - {file = "grpcio-1.46.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aac6e66acae82be5c99a0a40ab8f5733d7df76a04f242cf42ecc34cfb1e947bd"}, - {file = "grpcio-1.46.3-cp38-cp38-win32.whl", hash = "sha256:aff6d961d6bc5e34e12e148383671f8da5d17e47ed606ec15f483def3053b206"}, - {file = "grpcio-1.46.3-cp38-cp38-win_amd64.whl", hash = "sha256:71d46c2f3c0512bac3d658af3193e3d645c96123af56bd07a8416474c69df2cf"}, - {file = "grpcio-1.46.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:5969f63f3cf92538f83f26949d393d9fc59de670f47cf7c2a0e1e0d30b770294"}, - {file = "grpcio-1.46.3-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:5f8134d4a7e76c8c6644bd3ce728b9894933575155d02c09922986d5d8d6e48c"}, - {file = "grpcio-1.46.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:53fff69fd4d315adddda226e7b71804d1f12adf3a4162126dc520725624a483a"}, - {file = "grpcio-1.46.3-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3af2cc4e41f87d3b57f624b1b14321c1d0f030b191da60f9eeeda5448d83240c"}, - {file = "grpcio-1.46.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5fb7779ae01c20c4fad5831e98003b3f036acfe6b77697d6a9baa0f9a7f14daf"}, - {file = "grpcio-1.46.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56636ebf8db63ba50d272dfd73c92538950525120311676246f8f6a81b0aa144"}, - {file = "grpcio-1.46.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a5012ba00cf8b7ce9e6ac2312ace0b0e16fe9502c18340c8c3ecb734a759831"}, - {file = "grpcio-1.46.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:be1679d814a292a701f45df324e25b060435dd13159e9b08a16e2a2396c4391c"}, - {file = "grpcio-1.46.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4faaba7db078a0001a8c1a4370d56dc454c03b4613b6acec01f14b90c8dd03cf"}, - {file = "grpcio-1.46.3-cp39-cp39-win32.whl", hash = "sha256:f5c6393fa645183ae858ebfbf72ab94e7ebafb5cd849dcf4ae8c53a83cce4e24"}, - {file = "grpcio-1.46.3-cp39-cp39-win_amd64.whl", hash = "sha256:158b90d4f1354f40e435f4c866057acc29a4364b214c31049c8b8c903646fbab"}, - {file = "grpcio-1.46.3.tar.gz", hash = "sha256:4b8fd8b1cd553635274b83cd984f0755e6779886eca53c1c71d48215962eb689"}, + {file = "grpcio-1.48.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:665141b3a97b7d22978c8d2ba0c0af7f67bd6d7a56889c5c0aa715d04009b518"}, + {file = "grpcio-1.48.2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:199526758f6f8d35a596c610f33ea76faae65ec175dc109e8481ea3404d8527c"}, + {file = "grpcio-1.48.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:3d3225d477663c27b9051546a32551babd1ccb80192905e08340264deccc975b"}, + {file = "grpcio-1.48.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abee7dd82443b2cd128004e053b263a6d7256d570df80956a974634b8c5bc121"}, + {file = "grpcio-1.48.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dc08baa1b28749e90428aaa16e038e8c389d8ccb843ddc0dc8b95231640b432"}, + {file = "grpcio-1.48.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:110028e0b9c346230ae69b8a6d8b25d4d43bfd37bda61a8ec46486da1e781dcb"}, + {file = "grpcio-1.48.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6affa7e685edbb7421f942296eb618359362e89e641bcf46779c6ec7b944d275"}, + {file = "grpcio-1.48.2-cp310-cp310-win32.whl", hash = "sha256:f6afd1f4b5e0ec320fb2b027a646944fee8b58ba00fb43d081968f77d1a6e925"}, + {file = "grpcio-1.48.2-cp310-cp310-win_amd64.whl", hash = "sha256:b8ec07dcc1cbd77b8c09dfc0ce6274920cb7b09cc04013110971d95d8bcc0bbf"}, + {file = "grpcio-1.48.2-cp36-cp36m-linux_armv7l.whl", hash = "sha256:550b08dfa938e30ffbc1652193cf2877906aa6242d6ba9f61318dc87fcecee63"}, + {file = "grpcio-1.48.2-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:c19d6f337860f382ceaa35c5acab439d84c5ffaa8baba36df1f83ab6b9ac4bd3"}, + {file = "grpcio-1.48.2-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:e69a5907a2a4cf0011ff46205b6bff8f56b8391436acc3c66b70ce8519578d7e"}, + {file = "grpcio-1.48.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:894c5f02c25c83c2320310521a82978b4e252ee18b99a5c4c564d73daeb5c1de"}, + {file = "grpcio-1.48.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47ace91631176efa575c7a34d5004286288f1af1e9de2ff380d1433f241aeed4"}, + {file = "grpcio-1.48.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f1d2cd5b1adecbcffee4ad6613f100e0b583ae2e253d2f8f685e7770ec72d622"}, + {file = "grpcio-1.48.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f5697e4ab90a41a6a1202c1a3ec268a0d69f1cd127a4940d2b2521a0fbc1277b"}, + {file = "grpcio-1.48.2-cp36-cp36m-win32.whl", hash = "sha256:cebeed160466a1e254eb75e7e1bbeeb1359c50b33a1b8f3b2241a8b8dc9bd216"}, + {file = "grpcio-1.48.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0802b080b6b8603a065e505ce83190b6a06229b9a74d0a1681175271ac84fe12"}, + {file = "grpcio-1.48.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:855c125e8cd1c3ab09a239689c940d26c30680edf2edf87c3c1543bd8633cc8f"}, + {file = "grpcio-1.48.2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5571cb828d694b34a7c75484722803e13a2f5e4760e47ae32fb077c83d0c9b2c"}, + {file = "grpcio-1.48.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:2f185b8c5130663c455f6542906ce99f046608e94950c8b354aa22462c202c2d"}, + {file = "grpcio-1.48.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7b1a3a75c34ab39c9df73aa9fecc519dc1035e588a41af19f39b1298a283a57"}, + {file = "grpcio-1.48.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7ec6b04875a5065d04ad86cd2678ca6431dec868c01d731b8233f3de155bfdf"}, + {file = "grpcio-1.48.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e48595440dc86e13245aec7c096238db12b659e5ae6078aecf99d66befb77678"}, + {file = "grpcio-1.48.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ec2dd9f7ab0c809af6b2c65ed31c3cbef2ca9695f7f4d49866ec4707e7836890"}, + {file = "grpcio-1.48.2-cp37-cp37m-win32.whl", hash = "sha256:1fea4cb4368dd0467eb2d208e2d5e3c4f0be28fe33965d45ac9e1d562be67a8c"}, + {file = "grpcio-1.48.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0bfb637344442b273b698ff425d735a5d806ca8715f988875ad669277fb9b1e6"}, + {file = "grpcio-1.48.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:c92b5ef64cd5a0c6aea82dd6862fdb8a1562510d537ea3c356a7fe60db7021af"}, + {file = "grpcio-1.48.2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:2bb1df2920a4968f0c09041b49e591df96f2e6f801f15eed3821c1f16a12f1a8"}, + {file = "grpcio-1.48.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:3f52ef5ba7a8bc334daa87675838d6dafda7d8a116a72b567b8351e561ace498"}, + {file = "grpcio-1.48.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c3b69f8efb214a54f48e8dd1e235a4d8d22fa985f32a9b2844373993c5a605"}, + {file = "grpcio-1.48.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a760ef87fde9a8f2761c7ad8ccf617fc590547ed743a9207fe7e367496164c60"}, + {file = "grpcio-1.48.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1e2dc213fe71566efbf9a5d704c665ff4b1760a88d37f8533b19ca92776070c9"}, + {file = "grpcio-1.48.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3463256399158e9abf115620994e968db8f003224c36bda0d14570eab8a44cfc"}, + {file = "grpcio-1.48.2-cp38-cp38-win32.whl", hash = "sha256:dc00681d546cae66e9d54451f650fe140f9e1aca2dc4f8c9686cfaa4dd5d680b"}, + {file = "grpcio-1.48.2-cp38-cp38-win_amd64.whl", hash = "sha256:b8768daa636e0fa48fec75517bea65ce8fdaca0066dc411fc0a2290d92032f91"}, + {file = "grpcio-1.48.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:104b555e1cb2e0614f05c1def24eb8bb06f1277460058aa0f9c9e6a1018716da"}, + {file = "grpcio-1.48.2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:8d130f666463e4d09a63ff033a6c5cd032867fd51a0db4660c18106aa352be3a"}, + {file = "grpcio-1.48.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5792943481d4270b3e9a4700af0eea86e7183f4d3c250a46e0b357949cc09411"}, + {file = "grpcio-1.48.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26ed6d07f91ce8aeb4697b7e71d930355282ec80acb7a488f4030a3a75c2f7a8"}, + {file = "grpcio-1.48.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c0d0995a0cd8c7198cb49b8ce98b4936c5a70109f9246c58e69c898e4f7329"}, + {file = "grpcio-1.48.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b860e13c112bb9cb44007ef02853a19397d915b31c42dfa18570448bdc0a6245"}, + {file = "grpcio-1.48.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6f693da8ffd2486c354c90ba5a8ca0f4c50bfb8853495501884cadc152551360"}, + {file = "grpcio-1.48.2-cp39-cp39-win32.whl", hash = "sha256:2d99fb56c7e836f165828719c3695d3d27ac70b103ab52226f7a7c237e4a3928"}, + {file = "grpcio-1.48.2-cp39-cp39-win_amd64.whl", hash = "sha256:514392a30a275f4f719c2e05ea969c239e5f03eec4a25965852c7582073d8b94"}, + {file = "grpcio-1.48.2.tar.gz", hash = "sha256:90e5da224c6b9b23658adf6f36de6f435ef7dbcc9c5c12330314d70d6f8de1f7"}, ] gunicorn = [ {file = "gunicorn-19.9.0-py2.py3-none-any.whl", hash = "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471"}, {file = "gunicorn-19.9.0.tar.gz", hash = "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"}, ] idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] immutables = [ - {file = "immutables-0.18-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d841dfa15b932bdad27f5149bce86b32d0dd8a29679ed61405677317b6893447"}, - {file = "immutables-0.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29a5886845cd0ca8263b721337750a895e28feee2f16694a526977a791909db5"}, - {file = "immutables-0.18-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e979a9225507e3cd830ea73ac68b69fe82f495313a891485800daa5b6567e05"}, - {file = "immutables-0.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9949f704b80d0e601587d0a3b1a0cc6ff5d49528f6dfc1c8a1476b2137bb925e"}, - {file = "immutables-0.18-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b6c820c9bb5aac62b76de703384bb8bb706108be90c3def4a7f047f185a92bb"}, - {file = "immutables-0.18-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:03696193b276db3a9b619629685198886ddd7c4098c544bd8d0f87532c74120b"}, - {file = "immutables-0.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:798b4d6c388116effa7523591e4e39865292e4fa74e169b05a0759a16f604ce1"}, - {file = "immutables-0.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b3621256bc8058a7973f736b9e2c940e17133476265a0a83b8df8c0f446ca32f"}, - {file = "immutables-0.18-cp310-cp310-win32.whl", hash = "sha256:98f67bd36532582751dcc9021fdb60e7efc82e5717ae5927b84d0b86ea58fe12"}, - {file = "immutables-0.18-cp310-cp310-win_amd64.whl", hash = "sha256:69352b45a115808219feaf0bb7a551e9aa76c72684db93cd03f11474165f4569"}, - {file = "immutables-0.18-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6ee2d6f8816fce53fa89b6a1ba2d4a96b344bf584d6ed0b10a871b17fff46e49"}, - {file = "immutables-0.18-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13159cedb698fdd243d9f2a7469c1628e075a180fc02f865dd98322b92a14aaf"}, - {file = "immutables-0.18-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d72527fde329e3b566b67c954237be52b07d6e84ff23dcc1e94499755cacff6"}, - {file = "immutables-0.18-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53fccddd28cc3214aa48ca564702311c07eac069190dd890e097802c5d69b33a"}, - {file = "immutables-0.18-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a29e3aa0fe05fb2cc6b31039f448aa6206d7f0cdb660c98aa9be6d12070d6840"}, - {file = "immutables-0.18-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:ffced8535cc673fcfb411d28ba5744689a6978fa596c803725a76f43c1bda911"}, - {file = "immutables-0.18-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9f17407491164beb689d426f7985f79ae9dfa69868653cfbdb95645f6bf05cb0"}, - {file = "immutables-0.18-cp36-cp36m-win32.whl", hash = "sha256:74456c579cfd53f883cdcc0700e3871648a3316767efc1adf8c723ad3d8addec"}, - {file = "immutables-0.18-cp36-cp36m-win_amd64.whl", hash = "sha256:e4c2110173649acf67bd763bbd2a9c3a863a1d20fd7f3db3493ce4e0fb04fae5"}, - {file = "immutables-0.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa5292630b08c874972931bac06ee381cb6fb7382d7be1856234d7bd4a8e676"}, - {file = "immutables-0.18-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc830a689a55e404f0e23d7d69e01c218fa8a0be54a6ca5df45b6fbfeeac648a"}, - {file = "immutables-0.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5caf9c670e6851e7f310716c7dcdf8705236d13056eda1fab3deaad5d7198468"}, - {file = "immutables-0.18-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:853d63f4a07b2ea2131ba0831aeec11f6a6ee5e290e8f175bf56842762d7412e"}, - {file = "immutables-0.18-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9a86dcca4bb406f80e7a18c233aec0e76a7530c456e24aa1e19a708a34f2aac1"}, - {file = "immutables-0.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6baf4dc11ba0e9f41a6cbde7ecaa7af9cb482559b92ba3254e3e37a518b1970e"}, - {file = "immutables-0.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:734ec4467dd15f9135ca5ecccc91e796a67d27c227e81554f9e06b1bb3b28d6d"}, - {file = "immutables-0.18-cp37-cp37m-win32.whl", hash = "sha256:f6edb73619aa0a5fe4a77d97dd9d39bfeef61a5afe71aa5bdceccf59b933999e"}, - {file = "immutables-0.18-cp37-cp37m-win_amd64.whl", hash = "sha256:fade8ccf7afbc1e7ea353159fa90cc04395f2f4f57658160d7a02f6aa60c4e77"}, - {file = "immutables-0.18-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8b650d779a46441dccd02e7ee8326dbd0dec633c6bd75e9fe13373a6b19570dd"}, - {file = "immutables-0.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1acbbc333f1643fd1ed21bcc3e09aad2ef6648478a0cae76a2ca5823764a7d3b"}, - {file = "immutables-0.18-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3bad4d43009fa61ea40d887e6fa89ae7c4e62dff5e4a878d60b76cf245720bb"}, - {file = "immutables-0.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e04b61ddffd4ccb4d7ab823b2e55dbb4ad47c37697e311fae4b98b3c023ab194"}, - {file = "immutables-0.18-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54577e46c5332d7390212040c084335b7d667504847ed2788428d44f20e595ce"}, - {file = "immutables-0.18-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1330f96eb6a3a11f5d02f30b2c6393ef30d01a79f7144d63d2a3e6ff05cb99db"}, - {file = "immutables-0.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1d6821d7718cf9f4a7b1d9e765fc22a9d1ae0fad3fabd8724b4e614d2a6e0b54"}, - {file = "immutables-0.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45bd862a5dfb952eaff4a9c2448712c5a550dd956575e23cbfc512010fb06c74"}, - {file = "immutables-0.18-cp38-cp38-win32.whl", hash = "sha256:989606e440492736112b471dcd80586e3d4a63bc6f8ff4f9d1d612e0f96cb683"}, - {file = "immutables-0.18-cp38-cp38-win_amd64.whl", hash = "sha256:ac9e05f846392e983fb59f74ed2334031b366251d16d24122e4c85f70fb6e2da"}, - {file = "immutables-0.18-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:de1a091ab89b7ba50501a915a0fbdceb52b079c752f4f7c76d2060237774a714"}, - {file = "immutables-0.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d43b16b6adbe1327c6688e14b125cb3b940e748790b305de96c8d55668ac25f"}, - {file = "immutables-0.18-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f32b5933393e4cc204d8f9e7d9f503ec052e30f612090be0de0dd31b1464b35"}, - {file = "immutables-0.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525fe9001b5a96c325eec41677efaeb8c3610776e834ce7f31fbe3d33cc05252"}, - {file = "immutables-0.18-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11da4946e19f3b24a873b2ba2891cc226a89bb398561c62dfb966a9b6501a4a"}, - {file = "immutables-0.18-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:90da9dea0a1c0a907d511f124cd87fe090c0e30a951c3fe68bc9782ae4f2c77f"}, - {file = "immutables-0.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77bdc96dc24e32839557cde3785f8039a369c95529ff9179044b81d0ba4bd02c"}, - {file = "immutables-0.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:210efea163a704597cfdb2d30713d3c0963c30f0d997539c9ab5da40e3d6a886"}, - {file = "immutables-0.18-cp39-cp39-win32.whl", hash = "sha256:535616ad7ca1174a27ade637192c970bfedb0b0e0467e69ce415b40d7cf7ba0c"}, - {file = "immutables-0.18-cp39-cp39-win_amd64.whl", hash = "sha256:1338aad6fd69f11442adcbb3402a028c90f6e945682ddb8aba462a3827f2d427"}, - {file = "immutables-0.18.tar.gz", hash = "sha256:5336c7974084cce62f7e29aaff81a3c3f75e0fd0a23a2faeb986ae0ea08d8cf4"}, + {file = "immutables-0.19-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fef6743f8c3098ae46d9a2a3606b04a91c62e216487d91e90ce5c7419da3f803"}, + {file = "immutables-0.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cfb62119b7302a37cb4a1db44234dab9acda60ba93e3c28489969722e85237b7"}, + {file = "immutables-0.19-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d55b886e92ef5abfc4b066f404d956ca5789a2f8f738d448300fba40930a631"}, + {file = "immutables-0.19-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f1c3ab3ae690a55a2f61039705a110f0e23717d6d8a62a84600fc7cf5934dc"}, + {file = "immutables-0.19-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f3096afb376b9b3651a3b92affd1896b4dcefde209f412572f7e3924f6749a49"}, + {file = "immutables-0.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:85bcb5a7c33100c1b2eeb8c71e5f80acab4c9dde074b2c2ca8e3dfb6830ce813"}, + {file = "immutables-0.19-cp310-cp310-win_amd64.whl", hash = "sha256:620c166e76030ca4772ea64e5190f8347a730a0af85b743820d351f211004397"}, + {file = "immutables-0.19-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c1774f298db9d460e50c40dfc9cfe7dd8a0de22c22f1de9a1f9a468daa1201dc"}, + {file = "immutables-0.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24dbdc28779a2b75e06224609f4fc850ba61b7e1b74e32ec808c6430a535be2d"}, + {file = "immutables-0.19-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b8c0a4264e3ba2f025f4517ce67f0d0869106a625dbda08758cbf4dd6b6dd1f"}, + {file = "immutables-0.19-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28d1ee66424c2db998d27ebe0a331c7e09627e54a402848b2897cb6ef4dc4d7e"}, + {file = "immutables-0.19-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6f857aec0e0455986fd1f41234c867c3daf5a89ff7f54d493d4eb3c233d36d3c"}, + {file = "immutables-0.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:119c60a05cb35add45c1e592e23a5cbb9db03161bb89d1596b920d9341173982"}, + {file = "immutables-0.19-cp311-cp311-win_amd64.whl", hash = "sha256:3fbad255e404b4cbcf3477b384a1e400bd8f28cbbfc2df8d3885abe3bfc7b909"}, + {file = "immutables-0.19-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6660e185354a1cb59ecc130f2b85b50d666d4417be668ce6ba83d4be79f55d34"}, + {file = "immutables-0.19-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37de95c1d79707d95f50d0ab79e067bee52381afc967ff031ac4c822c14f43a8"}, + {file = "immutables-0.19-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed61dbc963251bec7281cdb0c148176bbd70519d21fd05bce4c484632cdc3b2c"}, + {file = "immutables-0.19-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:7da9356a163993e01785a211b47c6a0038b48d1235b68479a0053c2c4c3cf666"}, + {file = "immutables-0.19-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:41d8cae52ea527f9c6dccdf1e1553106c482496acc140523034f91877ccbc103"}, + {file = "immutables-0.19-cp36-cp36m-win_amd64.whl", hash = "sha256:e95f0826f184920adb3cdf830f409f1c1d4e943e4dc50242538c4df9d51eea72"}, + {file = "immutables-0.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:50608784e33c88da8c0e06e75f6725865cf2e345c8f3eeb83cb85111f737e986"}, + {file = "immutables-0.19-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cbd4d9dc531ee24b2387141a5968e923bb6174d13695e730cde0887aadda557"}, + {file = "immutables-0.19-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eed8988dc4ebde8d527dbe4dea68cb9fe6d43bc56df60d6015130dc4abd2ab34"}, + {file = "immutables-0.19-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c830c9afc6fcb4a7d6d74230d6290987e664418026a15488ad00d8a3dc5ec743"}, + {file = "immutables-0.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7c6cce2e87cd5369234b199037631cfed08e43813a1fdd750807d14404de195b"}, + {file = "immutables-0.19-cp37-cp37m-win_amd64.whl", hash = "sha256:10774f73af07b1648fa02f45f6ff88b3391feda65d4f640159e6eeec10540ece"}, + {file = "immutables-0.19-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a208a945ea817b1455b5b0f9c33c097baf6443b50d749a3dc32ff445e41b81d2"}, + {file = "immutables-0.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25a6225efb5e96fc95d84b2d280e35d8a82a1ae72a12857177d48cc289ac1e03"}, + {file = "immutables-0.19-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c0cf0d94b08e58896acf250cbc4682499c8a256fc6d0ee5c63d76a759a6a228"}, + {file = "immutables-0.19-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64c74c5171f3a97b178b880746743a07b08e7d7f6055370bf04a94d50aea0643"}, + {file = "immutables-0.19-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8ababf72ed2a956b28f151d605a7bb1d4e1c59113f53bf2be4a586da3977b319"}, + {file = "immutables-0.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52a91917c65e6b9cfef7a2d2c3b0e00432a153aa8650785b7ee0897d80226278"}, + {file = "immutables-0.19-cp38-cp38-win_amd64.whl", hash = "sha256:bbe65c23779e12e0ecc3dec2c709ad22b7cc8b163895327bc173ae06a8b73425"}, + {file = "immutables-0.19-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:480cc5d62efcac66f9737ae0820acd39d39e516e6fdbcf46cbdc26f11b429fd7"}, + {file = "immutables-0.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2d88ff44e131508def4740964076c3da273baeeb406c1fe139f18373ea4196dd"}, + {file = "immutables-0.19-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa3148393101b0c4571da523929ae90a5b4bfc933c270a11b802a34a921c608"}, + {file = "immutables-0.19-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0575190a90c3fce6862ccdb09be3344741ff97a96e559893541886d372139f1c"}, + {file = "immutables-0.19-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3754b26ef18b5d1009ffdeafc17fbd877a79f0a126e1423069bd8ef51c54302d"}, + {file = "immutables-0.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:648142e16d49f5207ae52ee1b28dfa148206471967b9c9eaa5a9592fd32d5cef"}, + {file = "immutables-0.19-cp39-cp39-win_amd64.whl", hash = "sha256:199db9070ffa1a037e6650ddd63159907a210e4998f932bdf50e70615629db0c"}, + {file = "immutables-0.19.tar.gz", hash = "sha256:df17942d60e8080835fcc5245aa6928ef4c1ed567570ec019185798195048dcf"}, ] importlib-metadata = [ {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, @@ -3214,7 +2464,10 @@ kombu = [ {file = "kombu-4.6.11.tar.gz", hash = "sha256:ca1b45faac8c0b18493d02a8571792f3c40291cf2bcf1f55afed3d8f3aa7ba74"}, ] ldap3 = [ + {file = "ldap3-2.9.1-py2.6.egg", hash = "sha256:5ab7febc00689181375de40c396dcad4f2659cd260fc5e94c508b6d77c17e9d5"}, + {file = "ldap3-2.9.1-py2.7.egg", hash = "sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6"}, {file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"}, + {file = "ldap3-2.9.1-py3.9.egg", hash = "sha256:5630d1383e09ba94839e253e013f1aa1a2cf7a547628ba1265cb7b9a844b5687"}, {file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"}, ] markupsafe = [ @@ -3322,8 +2575,8 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] openpyxl = [ - {file = "openpyxl-3.0.9-py2.py3-none-any.whl", hash = "sha256:8f3b11bd896a95468a4ab162fc4fcd260d46157155d1f8bfaabb99d88cfcf79f"}, - {file = "openpyxl-3.0.9.tar.gz", hash = "sha256:40f568b9829bf9e446acfffce30250ac1fa39035124d55fc024025c41481c90f"}, + {file = "openpyxl-3.0.10-py2.py3-none-any.whl", hash = "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355"}, + {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, ] opentelemetry-api = [ {file = "opentelemetry-api-1.7.1.tar.gz", hash = "sha256:aa4c29150042fd4e9efc30810bc5413a16a442b75fa16bef879651016ca8497e"}, @@ -3434,40 +2687,39 @@ pluggy = [ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] prometheus-client = [ - {file = "prometheus_client-0.14.1-py3-none-any.whl", hash = "sha256:522fded625282822a89e2773452f42df14b5a8e84a86433e3f8a189c1d54dc01"}, - {file = "prometheus_client-0.14.1.tar.gz", hash = "sha256:5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a"}, + {file = "prometheus_client-0.15.0-py3-none-any.whl", hash = "sha256:db7c05cbd13a0f79975592d112320f2605a325969b270a94b71dcabc47b931d2"}, + {file = "prometheus_client-0.15.0.tar.gz", hash = "sha256:be26aa452490cfcf6da953f9436e95a9f2b4d578ca80094b4458930e5f584ab1"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"}, - {file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"}, + {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, + {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, ] protobuf = [ - {file = "protobuf-3.19.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c"}, - {file = "protobuf-3.19.4-cp310-cp310-win32.whl", hash = "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0"}, - {file = "protobuf-3.19.4-cp310-cp310-win_amd64.whl", hash = "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07"}, - {file = "protobuf-3.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4"}, - {file = "protobuf-3.19.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f"}, - {file = "protobuf-3.19.4-cp36-cp36m-win32.whl", hash = "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee"}, - {file = "protobuf-3.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b"}, - {file = "protobuf-3.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909"}, - {file = "protobuf-3.19.4-cp37-cp37m-win32.whl", hash = "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9"}, - {file = "protobuf-3.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f"}, - {file = "protobuf-3.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7"}, - {file = "protobuf-3.19.4-cp38-cp38-win32.whl", hash = "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26"}, - {file = "protobuf-3.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e"}, - {file = "protobuf-3.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e"}, - {file = "protobuf-3.19.4-cp39-cp39-win32.whl", hash = "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a"}, - {file = "protobuf-3.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca"}, - {file = "protobuf-3.19.4-py2.py3-none-any.whl", hash = "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616"}, - {file = "protobuf-3.19.4.tar.gz", hash = "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a"}, + {file = "protobuf-3.19.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:010be24d5a44be7b0613750ab40bc8b8cedc796db468eae6c779b395f50d1fa1"}, + {file = "protobuf-3.19.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11478547958c2dfea921920617eb457bc26867b0d1aa065ab05f35080c5d9eb6"}, + {file = "protobuf-3.19.6-cp310-cp310-win32.whl", hash = "sha256:559670e006e3173308c9254d63facb2c03865818f22204037ab76f7a0ff70b5f"}, + {file = "protobuf-3.19.6-cp310-cp310-win_amd64.whl", hash = "sha256:347b393d4dd06fb93a77620781e11c058b3b0a5289262f094379ada2920a3730"}, + {file = "protobuf-3.19.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a8ce5ae0de28b51dff886fb922012dad885e66176663950cb2344c0439ecb473"}, + {file = "protobuf-3.19.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b0d02163c4e67279ddb6dc25e063db0130fc299aefabb5d481053509fae5c8"}, + {file = "protobuf-3.19.6-cp36-cp36m-win32.whl", hash = "sha256:30f5370d50295b246eaa0296533403961f7e64b03ea12265d6dfce3a391d8992"}, + {file = "protobuf-3.19.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0c0714b025ec057b5a7600cb66ce7c693815f897cfda6d6efb58201c472e3437"}, + {file = "protobuf-3.19.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5057c64052a1f1dd7d4450e9aac25af6bf36cfbfb3a1cd89d16393a036c49157"}, + {file = "protobuf-3.19.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bb6776bd18f01ffe9920e78e03a8676530a5d6c5911934c6a1ac6eb78973ecb6"}, + {file = "protobuf-3.19.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a04134866861b11556a82dd91ea6daf1f4925746b992f277b84013a7cc1229"}, + {file = "protobuf-3.19.6-cp37-cp37m-win32.whl", hash = "sha256:4bc98de3cdccfb5cd769620d5785b92c662b6bfad03a202b83799b6ed3fa1fa7"}, + {file = "protobuf-3.19.6-cp37-cp37m-win_amd64.whl", hash = "sha256:aa3b82ca1f24ab5326dcf4ea00fcbda703e986b22f3d27541654f749564d778b"}, + {file = "protobuf-3.19.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2b2d2913bcda0e0ec9a784d194bc490f5dc3d9d71d322d070b11a0ade32ff6ba"}, + {file = "protobuf-3.19.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d0b635cefebd7a8a0f92020562dead912f81f401af7e71f16bf9506ff3bdbb38"}, + {file = "protobuf-3.19.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a552af4dc34793803f4e735aabe97ffc45962dfd3a237bdde242bff5a3de684"}, + {file = "protobuf-3.19.6-cp38-cp38-win32.whl", hash = "sha256:0469bc66160180165e4e29de7f445e57a34ab68f49357392c5b2f54c656ab25e"}, + {file = "protobuf-3.19.6-cp38-cp38-win_amd64.whl", hash = "sha256:91d5f1e139ff92c37e0ff07f391101df77e55ebb97f46bbc1535298d72019462"}, + {file = "protobuf-3.19.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0ccd3f940fe7f3b35a261b1dd1b4fc850c8fde9f74207015431f174be5976b3"}, + {file = "protobuf-3.19.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:30a15015d86b9c3b8d6bf78d5b8c7749f2512c29f168ca259c9d7727604d0e39"}, + {file = "protobuf-3.19.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:878b4cd080a21ddda6ac6d1e163403ec6eea2e206cf225982ae04567d39be7b0"}, + {file = "protobuf-3.19.6-cp39-cp39-win32.whl", hash = "sha256:5a0d7539a1b1fb7e76bf5faa0b44b30f812758e989e59c40f77a7dab320e79b9"}, + {file = "protobuf-3.19.6-cp39-cp39-win_amd64.whl", hash = "sha256:bbf5cea5048272e1c60d235c7bd12ce1b14b8a16e76917f371c718bd3005f045"}, + {file = "protobuf-3.19.6-py2.py3-none-any.whl", hash = "sha256:14082457dc02be946f60b15aad35e9f5c69e738f80ebbc0900a19bc83734a5a4"}, + {file = "protobuf-3.19.6.tar.gz", hash = "sha256:5f5540d57a43042389e87661c6eaa50f47c19c6176e8cf1c4f287aeefeccb5c4"}, ] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, @@ -3478,7 +2730,18 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pycodestyle = [ @@ -3490,49 +2753,49 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5"}, - {file = "pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4"}, - {file = "pydantic-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab624700dc145aa809e6f3ec93fb8e7d0f99d9023b713f6a953637429b437d37"}, - {file = "pydantic-1.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8d7da6f1c1049eefb718d43d99ad73100c958a5367d30b9321b092771e96c25"}, - {file = "pydantic-1.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3c3b035103bd4e2e4a28da9da7ef2fa47b00ee4a9cf4f1a735214c1bcd05e0f6"}, - {file = "pydantic-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3011b975c973819883842c5ab925a4e4298dffccf7782c55ec3580ed17dc464c"}, - {file = "pydantic-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:086254884d10d3ba16da0588604ffdc5aab3f7f09557b998373e885c690dd398"}, - {file = "pydantic-1.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0fe476769acaa7fcddd17cadd172b156b53546ec3614a4d880e5d29ea5fbce65"}, - {file = "pydantic-1.9.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8e9dcf1ac499679aceedac7e7ca6d8641f0193c591a2d090282aaf8e9445a46"}, - {file = "pydantic-1.9.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1e4c28f30e767fd07f2ddc6f74f41f034d1dd6bc526cd59e63a82fe8bb9ef4c"}, - {file = "pydantic-1.9.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c86229333cabaaa8c51cf971496f10318c4734cf7b641f08af0a6fbf17ca3054"}, - {file = "pydantic-1.9.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:c0727bda6e38144d464daec31dff936a82917f431d9c39c39c60a26567eae3ed"}, - {file = "pydantic-1.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:dee5ef83a76ac31ab0c78c10bd7d5437bfdb6358c95b91f1ba7ff7b76f9996a1"}, - {file = "pydantic-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9c9bdb3af48e242838f9f6e6127de9be7063aad17b32215ccc36a09c5cf1070"}, - {file = "pydantic-1.9.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee7e3209db1e468341ef41fe263eb655f67f5c5a76c924044314e139a1103a2"}, - {file = "pydantic-1.9.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b6037175234850ffd094ca77bf60fb54b08b5b22bc85865331dd3bda7a02fa1"}, - {file = "pydantic-1.9.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b2571db88c636d862b35090ccf92bf24004393f85c8870a37f42d9f23d13e032"}, - {file = "pydantic-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8b5ac0f1c83d31b324e57a273da59197c83d1bb18171e512908fe5dc7278a1d6"}, - {file = "pydantic-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bbbc94d0c94dd80b3340fc4f04fd4d701f4b038ebad72c39693c794fd3bc2d9d"}, - {file = "pydantic-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e0896200b6a40197405af18828da49f067c2fa1f821491bc8f5bde241ef3f7d7"}, - {file = "pydantic-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bdfdadb5994b44bd5579cfa7c9b0e1b0e540c952d56f627eb227851cda9db77"}, - {file = "pydantic-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:574936363cd4b9eed8acdd6b80d0143162f2eb654d96cb3a8ee91d3e64bf4cf9"}, - {file = "pydantic-1.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c556695b699f648c58373b542534308922c46a1cda06ea47bc9ca45ef5b39ae6"}, - {file = "pydantic-1.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f947352c3434e8b937e3aa8f96f47bdfe6d92779e44bb3f41e4c213ba6a32145"}, - {file = "pydantic-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5e48ef4a8b8c066c4a31409d91d7ca372a774d0212da2787c0d32f8045b1e034"}, - {file = "pydantic-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:96f240bce182ca7fe045c76bcebfa0b0534a1bf402ed05914a6f1dadff91877f"}, - {file = "pydantic-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:815ddebb2792efd4bba5488bc8fde09c29e8ca3227d27cf1c6990fc830fd292b"}, - {file = "pydantic-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c5b77947b9e85a54848343928b597b4f74fc364b70926b3c4441ff52620640c"}, - {file = "pydantic-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c68c3bc88dbda2a6805e9a142ce84782d3930f8fdd9655430d8576315ad97ce"}, - {file = "pydantic-1.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a79330f8571faf71bf93667d3ee054609816f10a259a109a0738dac983b23c3"}, - {file = "pydantic-1.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5a64b64ddf4c99fe201ac2724daada8595ada0d102ab96d019c1555c2d6441d"}, - {file = "pydantic-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a733965f1a2b4090a5238d40d983dcd78f3ecea221c7af1497b845a9709c1721"}, - {file = "pydantic-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cc6a4cb8a118ffec2ca5fcb47afbacb4f16d0ab8b7350ddea5e8ef7bcc53a16"}, - {file = "pydantic-1.9.0-py3-none-any.whl", hash = "sha256:085ca1de245782e9b46cefcf99deecc67d418737a1fd3f6a4f511344b613a5b3"}, - {file = "pydantic-1.9.0.tar.gz", hash = "sha256:742645059757a56ecd886faf4ed2441b9c0cd406079c2b4bee51bcc3fbcd510a"}, + {file = "pydantic-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e"}, + {file = "pydantic-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08"}, + {file = "pydantic-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c"}, + {file = "pydantic-1.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131"}, + {file = "pydantic-1.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76"}, + {file = "pydantic-1.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567"}, + {file = "pydantic-1.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044"}, + {file = "pydantic-1.9.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555"}, + {file = "pydantic-1.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84"}, + {file = "pydantic-1.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f"}, + {file = "pydantic-1.9.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb"}, + {file = "pydantic-1.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b"}, + {file = "pydantic-1.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001"}, + {file = "pydantic-1.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56"}, + {file = "pydantic-1.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4"}, + {file = "pydantic-1.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f"}, + {file = "pydantic-1.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979"}, + {file = "pydantic-1.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d"}, + {file = "pydantic-1.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7"}, + {file = "pydantic-1.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3"}, + {file = "pydantic-1.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa"}, + {file = "pydantic-1.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3"}, + {file = "pydantic-1.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0"}, + {file = "pydantic-1.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8"}, + {file = "pydantic-1.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8"}, + {file = "pydantic-1.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326"}, + {file = "pydantic-1.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801"}, + {file = "pydantic-1.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44"}, + {file = "pydantic-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747"}, + {file = "pydantic-1.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453"}, + {file = "pydantic-1.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb"}, + {file = "pydantic-1.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15"}, + {file = "pydantic-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55"}, + {file = "pydantic-1.9.2-py3-none-any.whl", hash = "sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e"}, + {file = "pydantic-1.9.2.tar.gz", hash = "sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d"}, ] pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ - {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, - {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, ] pyjwt = [ {file = "PyJWT-2.4.0-py3-none-any.whl", hash = "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf"}, @@ -3547,8 +2810,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pyproject-flake8 = [ - {file = "pyproject-flake8-0.0.1a4.tar.gz", hash = "sha256:8ed9453f1d984cfe94c998f9840275359e29e7f435b8ddd188ae084e2dc1270c"}, - {file = "pyproject_flake8-0.0.1a4-py2.py3-none-any.whl", hash = "sha256:1a8f94e18d08677ee780625049d9d00a9ee823661c6606caab8a383351037a75"}, + {file = "pyproject-flake8-0.0.1a5.tar.gz", hash = "sha256:22542080ba90d4bd80ee060852db15a24aeea61c9a29ed7c16f5b59b0e47a03a"}, + {file = "pyproject_flake8-0.0.1a5-py2.py3-none-any.whl", hash = "sha256:c843d760c49d7b270e9abda58a57765c031918a9d10da25aa43572f5d77cac43"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -3563,7 +2826,8 @@ pytest-django = [ {file = "pytest_django-3.10.0-py2.py3-none-any.whl", hash = "sha256:c33e3d3da14d8409b125d825d4e74da17bb252191bf6fc3da6856e27a8b73ea4"}, ] python-crontab = [ - {file = "python-crontab-2.6.0.tar.gz", hash = "sha256:1e35ed7a3cdc3100545b43e196d34754e6551e7f95e4caebbe0e1c0ca41c2f1b"}, + {file = "python-crontab-2.7.1.tar.gz", hash = "sha256:b21af4647c7bbb848fef2f020616c6b0289dcb9f94b4f991a55310ff9bec5749"}, + {file = "python_crontab-2.7.1-py3-none-any.whl", hash = "sha256:9c374d1c9d401afdd8dd958f20077f74c158ab3fffb9604296802715e887fe48"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -3573,8 +2837,8 @@ python-json-logger = [ {file = "python-json-logger-0.1.11.tar.gz", hash = "sha256:b7a31162f2a01965a5efb94453ce69230ed208468b0bbc7fdfc56e6d8df2e281"}, ] pytz = [ - {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, - {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, + {file = "pytz-2022.7-py2.py3-none-any.whl", hash = "sha256:93007def75ae22f7cd991c84e02d434876818661f8df9ad5df9e950ff4e52cfd"}, + {file = "pytz-2022.7.tar.gz", hash = "sha256:7ccfae7b4b2c067464a6733c6261673fdb8fd1be905460396b97a073e9fa683a"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -3642,36 +2906,49 @@ requests = [ {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] +rsa = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, +] "ruamel.yaml" = [ {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, ] "ruamel.yaml.clib" = [ - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6e7be2c5bcb297f5b82fee9c665eb2eb7001d1050deaba8471842979293a80b0"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:221eca6f35076c6ae472a531afa1c223b9c29377e62936f61bc8e6e8bdc5f9e7"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win32.whl", hash = "sha256:1070ba9dd7f9370d0513d649420c3b362ac2d687fe78c6e888f5b12bf8bc7bee"}, - {file = "ruamel.yaml.clib-0.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:77df077d32921ad46f34816a9a16e6356d8100374579bc35e15bab5d4e9377de"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"}, - {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"}, - {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"}, - {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"}, - {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"}, - {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"}, - {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, + {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] sentry-sdk = [ {file = "sentry-sdk-1.5.6.tar.gz", hash = "sha256:ac2a50128409d57655279817aedcb7800cace1f76b266f3dd62055d5afd6e098"}, @@ -3682,8 +2959,8 @@ six = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] sqlparse = [ - {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, - {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, + {file = "sqlparse-0.4.3-py3-none-any.whl", hash = "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34"}, + {file = "sqlparse-0.4.3.tar.gz", hash = "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268"}, ] thrift = [ {file = "thrift-0.16.0.tar.gz", hash = "sha256:2b5b6488fcded21f9d312aa23c9ff6a0195d0f6ae26ddbd5ad9e3e25dfc14408"}, @@ -3741,8 +3018,8 @@ types-dataclasses = [ {file = "types_dataclasses-0.1.7-py3-none-any.whl", hash = "sha256:fc372bb68b878ac7a68fd04230d923d4a6303a137ecb0b9700b90630bdfcbfc9"}, ] types-pymysql = [ - {file = "types-PyMySQL-1.0.19.tar.gz", hash = "sha256:f79a1f4d9df4a65db999537f9a47de419be162dfeab3b2c91bcba8bb1a362a65"}, - {file = "types_PyMySQL-1.0.19-py3-none-any.whl", hash = "sha256:fc43dceda3f3fc4ac388db7dd57b157c13d94cb84e30cca4848df590c314bf68"}, + {file = "types-PyMySQL-1.0.19.1.tar.gz", hash = "sha256:c24ce221cd76a24445b4614fff84b13644d7fb4966fc7a07a742e8546da29507"}, + {file = "types_PyMySQL-1.0.19.1-py3-none-any.whl", hash = "sha256:6748b3d830b9fc0299bd85ebf0f4a29de8c51f452a11fee83690ee4b26deede8"}, ] types-pytz = [ {file = "types-pytz-2021.3.8.tar.gz", hash = "sha256:41253a3a2bf028b6a3f17b58749a692d955af0f74e975de94f6f4d2d3cd01dbd"}, @@ -3757,16 +3034,16 @@ types-redis = [ {file = "types_redis-3.5.18-py3-none-any.whl", hash = "sha256:5c55c4b9e8ebdc6d57d4e47900b77d99f19ca0a563264af3f701246ed0926335"}, ] types-requests = [ - {file = "types-requests-2.27.25.tar.gz", hash = "sha256:805ae7e38fd9d157153066dc4381cf585fd34dfa212f2fc1fece248c05aac571"}, - {file = "types_requests-2.27.25-py3-none-any.whl", hash = "sha256:2444905c89731dbcb6bbcd6d873a04252445df7623917c640e463b2b28d2a708"}, + {file = "types-requests-2.28.11.7.tar.gz", hash = "sha256:0ae38633734990d019b80f5463dfa164ebd3581998ac8435f526da6fe4d598c3"}, + {file = "types_requests-2.28.11.7-py3-none-any.whl", hash = "sha256:b6a2fca8109f4fdba33052f11ed86102bddb2338519e1827387137fefc66a98b"}, ] types-toml = [ {file = "types-toml-0.1.5.tar.gz", hash = "sha256:fc5e1df92c245404e4360c63568e9f0e732b0cabea7a220a4788d52b78f5dc59"}, {file = "types_toml-0.1.5-py3-none-any.whl", hash = "sha256:dd00526680595aad0eade682bd8a9e9513e9b4b8932daed159925fe446fc90a9"}, ] types-urllib3 = [ - {file = "types-urllib3-1.26.14.tar.gz", hash = "sha256:2a2578e4b36341ccd240b00fccda9826988ff0589a44ba4a664bbd69ef348d27"}, - {file = "types_urllib3-1.26.14-py3-none-any.whl", hash = "sha256:5d2388aa76395b1e3999ff789ea5b3283677dad8e9bcf3d9117ba19271fd35d9"}, + {file = "types-urllib3-1.26.25.4.tar.gz", hash = "sha256:eec5556428eec862b1ac578fb69aab3877995a99ffec9e5a12cf7fbd0cc9daee"}, + {file = "types_urllib3-1.26.25.4-py3-none-any.whl", hash = "sha256:ed6b9e8a8be488796f72306889a06a3fc3cb1aa99af02ab8afb50144d7317e49"}, ] typing-extensions = [ {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, @@ -3777,8 +3054,8 @@ uritemplate = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] urllib3 = [ - {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, - {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, + {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, + {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, ] vine = [ {file = "vine-1.3.0-py2.py3-none-any.whl", hash = "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"}, @@ -3867,59 +3144,44 @@ zipp = [ {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, ] "zope.event" = [ - {file = "zope.event-4.5.0-py2.py3-none-any.whl", hash = "sha256:2666401939cdaa5f4e0c08cf7f20c9b21423b95e88f4675b1443973bdb080c42"}, - {file = "zope.event-4.5.0.tar.gz", hash = "sha256:5e76517f5b9b119acf37ca8819781db6c16ea433f7e2062c4afc2b6fbedb1330"}, + {file = "zope.event-4.6-py2.py3-none-any.whl", hash = "sha256:73d9e3ef750cca14816a9c322c7250b0d7c9dbc337df5d1b807ff8d3d0b9e97c"}, + {file = "zope.event-4.6.tar.gz", hash = "sha256:81d98813046fc86cc4136e3698fee628a3282f9c320db18658c21749235fce80"}, ] "zope.interface" = [ - {file = "zope.interface-5.4.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7"}, - {file = "zope.interface-5.4.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021"}, - {file = "zope.interface-5.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192"}, - {file = "zope.interface-5.4.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a"}, - {file = "zope.interface-5.4.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531"}, - {file = "zope.interface-5.4.0-cp27-cp27m-win32.whl", hash = "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325"}, - {file = "zope.interface-5.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155"}, - {file = "zope.interface-5.4.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263"}, - {file = "zope.interface-5.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959"}, - {file = "zope.interface-5.4.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e"}, - {file = "zope.interface-5.4.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c"}, - {file = "zope.interface-5.4.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702"}, - {file = "zope.interface-5.4.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f"}, - {file = "zope.interface-5.4.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05"}, - {file = "zope.interface-5.4.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004"}, - {file = "zope.interface-5.4.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117"}, - {file = "zope.interface-5.4.0-cp35-cp35m-win32.whl", hash = "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8"}, - {file = "zope.interface-5.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63"}, - {file = "zope.interface-5.4.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f"}, - {file = "zope.interface-5.4.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920"}, - {file = "zope.interface-5.4.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46"}, - {file = "zope.interface-5.4.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc"}, - {file = "zope.interface-5.4.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9"}, - {file = "zope.interface-5.4.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2"}, - {file = "zope.interface-5.4.0-cp36-cp36m-win32.whl", hash = "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78"}, - {file = "zope.interface-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1"}, - {file = "zope.interface-5.4.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e"}, - {file = "zope.interface-5.4.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b"}, - {file = "zope.interface-5.4.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f"}, - {file = "zope.interface-5.4.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d"}, - {file = "zope.interface-5.4.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8"}, - {file = "zope.interface-5.4.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf"}, - {file = "zope.interface-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7"}, - {file = "zope.interface-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94"}, - {file = "zope.interface-5.4.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3"}, - {file = "zope.interface-5.4.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e"}, - {file = "zope.interface-5.4.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7"}, - {file = "zope.interface-5.4.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120"}, - {file = "zope.interface-5.4.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48"}, - {file = "zope.interface-5.4.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4"}, - {file = "zope.interface-5.4.0-cp38-cp38-win32.whl", hash = "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb"}, - {file = "zope.interface-5.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54"}, - {file = "zope.interface-5.4.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4"}, - {file = "zope.interface-5.4.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d"}, - {file = "zope.interface-5.4.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83"}, - {file = "zope.interface-5.4.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25"}, - {file = "zope.interface-5.4.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1"}, - {file = "zope.interface-5.4.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c"}, - {file = "zope.interface-5.4.0-cp39-cp39-win32.whl", hash = "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e"}, - {file = "zope.interface-5.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09"}, - {file = "zope.interface-5.4.0.tar.gz", hash = "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e"}, + {file = "zope.interface-5.5.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:a2ad597c8c9e038a5912ac3cf166f82926feff2f6e0dabdab956768de0a258f5"}, + {file = "zope.interface-5.5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:65c3c06afee96c654e590e046c4a24559e65b0a87dbff256cd4bd6f77e1a33f9"}, + {file = "zope.interface-5.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d514c269d1f9f5cd05ddfed15298d6c418129f3f064765295659798349c43e6f"}, + {file = "zope.interface-5.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5334e2ef60d3d9439c08baedaf8b84dc9bb9522d0dacbc10572ef5609ef8db6d"}, + {file = "zope.interface-5.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc26c8d44472e035d59d6f1177eb712888447f5799743da9c398b0339ed90b1b"}, + {file = "zope.interface-5.5.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:17ebf6e0b1d07ed009738016abf0d0a0f80388e009d0ac6e0ead26fc162b3b9c"}, + {file = "zope.interface-5.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f98d4bd7bbb15ca701d19b93263cc5edfd480c3475d163f137385f49e5b3a3a7"}, + {file = "zope.interface-5.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:696f3d5493eae7359887da55c2afa05acc3db5fc625c49529e84bd9992313296"}, + {file = "zope.interface-5.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7579960be23d1fddecb53898035a0d112ac858c3554018ce615cefc03024e46d"}, + {file = "zope.interface-5.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:765d703096ca47aa5d93044bf701b00bbce4d903a95b41fff7c3796e747b1f1d"}, + {file = "zope.interface-5.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e945de62917acbf853ab968d8916290548df18dd62c739d862f359ecd25842a6"}, + {file = "zope.interface-5.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:655796a906fa3ca67273011c9805c1e1baa047781fca80feeb710328cdbed87f"}, + {file = "zope.interface-5.5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:0fb497c6b088818e3395e302e426850f8236d8d9f4ef5b2836feae812a8f699c"}, + {file = "zope.interface-5.5.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:008b0b65c05993bb08912f644d140530e775cf1c62a072bf9340c2249e613c32"}, + {file = "zope.interface-5.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:404d1e284eda9e233c90128697c71acffd55e183d70628aa0bbb0e7a3084ed8b"}, + {file = "zope.interface-5.5.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3218ab1a7748327e08ef83cca63eea7cf20ea7e2ebcb2522072896e5e2fceedf"}, + {file = "zope.interface-5.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d169ccd0756c15bbb2f1acc012f5aab279dffc334d733ca0d9362c5beaebe88e"}, + {file = "zope.interface-5.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:e1574980b48c8c74f83578d1e77e701f8439a5d93f36a5a0af31337467c08fcf"}, + {file = "zope.interface-5.5.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:0217a9615531c83aeedb12e126611b1b1a3175013bbafe57c702ce40000eb9a0"}, + {file = "zope.interface-5.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:311196634bb9333aa06f00fc94f59d3a9fddd2305c2c425d86e406ddc6f2260d"}, + {file = "zope.interface-5.5.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6373d7eb813a143cb7795d3e42bd8ed857c82a90571567e681e1b3841a390d16"}, + {file = "zope.interface-5.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:959697ef2757406bff71467a09d940ca364e724c534efbf3786e86eee8591452"}, + {file = "zope.interface-5.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dbaeb9cf0ea0b3bc4b36fae54a016933d64c6d52a94810a63c00f440ecb37dd7"}, + {file = "zope.interface-5.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604cdba8f1983d0ab78edc29aa71c8df0ada06fb147cea436dc37093a0100a4e"}, + {file = "zope.interface-5.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e74a578172525c20d7223eac5f8ad187f10940dac06e40113d62f14f3adb1e8f"}, + {file = "zope.interface-5.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0980d44b8aded808bec5059018d64692f0127f10510eca71f2f0ace8fb11188"}, + {file = "zope.interface-5.5.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6e972493cdfe4ad0411fd9abfab7d4d800a7317a93928217f1a5de2bb0f0d87a"}, + {file = "zope.interface-5.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9d783213fab61832dbb10d385a319cb0e45451088abd45f95b5bb88ed0acca1a"}, + {file = "zope.interface-5.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:a16025df73d24795a0bde05504911d306307c24a64187752685ff6ea23897cb0"}, + {file = "zope.interface-5.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:40f4065745e2c2fa0dff0e7ccd7c166a8ac9748974f960cd39f63d2c19f9231f"}, + {file = "zope.interface-5.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a2ffadefd0e7206adc86e492ccc60395f7edb5680adedf17a7ee4205c530df4"}, + {file = "zope.interface-5.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d692374b578360d36568dd05efb8a5a67ab6d1878c29c582e37ddba80e66c396"}, + {file = "zope.interface-5.5.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4087e253bd3bbbc3e615ecd0b6dd03c4e6a1e46d152d3be6d2ad08fbad742dcc"}, + {file = "zope.interface-5.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb68d212efd057596dee9e6582daded9f8ef776538afdf5feceb3059df2d2e7b"}, + {file = "zope.interface-5.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:7e66f60b0067a10dd289b29dceabd3d0e6d68be1504fc9d0bc209cf07f56d189"}, + {file = "zope.interface-5.5.2.tar.gz", hash = "sha256:bfee1f3ff62143819499e348f5b8a7f3aa0259f9aca5e0ddae7391d059dce671"}, ] diff --git a/src/api/pyproject.toml b/src/api/pyproject.toml index b48791d0b..120974c4b 100644 --- a/src/api/pyproject.toml +++ b/src/api/pyproject.toml @@ -2,7 +2,7 @@ name = "bk-user-api" version = "2.3.3" description = "bk-user Api" -authors = ["IMBlues "] +authors = ["TencentBlueKing "] [tool.poetry.dependencies] python = "3.6.14" @@ -55,6 +55,7 @@ opentelemetry-instrumentation-requests = "0.26b1" opentelemetry-instrumentation-celery = "0.26b1" opentelemetry-instrumentation-logging = "0.26b1" opentelemetry-exporter-jaeger = "1.7.1" +rsa = "^4.9" [tool.poetry.dev-dependencies] ipython = "^7.15.0" @@ -80,10 +81,6 @@ types-redis = "^3.5.4" types-toml = "^0.1.3" types-cachetools = "^4.2.9" -[[tool.poetry.source]] -name = "tencent-mirrors" -url = "https://mirrors.tencent.com/pypi/simple/" - [tool.pytest.ini_options] DJANGO_SETTINGS_MODULE = "bkuser_core.config.overlays.dev" addopts = "--disable-pytest-warnings --reuse-db" diff --git a/src/api/wsgi.py b/src/api/wsgi.py index 2fe6df59c..e8fd974f7 100644 --- a/src/api/wsgi.py +++ b/src/api/wsgi.py @@ -8,10 +8,13 @@ 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 faulthandler import os from django.core.wsgi import get_wsgi_application +faulthandler.enable() + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bkuser_core.config.overlays.prod") application = get_wsgi_application() diff --git a/src/build/README.md b/src/build/README.md new file mode 100644 index 000000000..4bd8957e6 --- /dev/null +++ b/src/build/README.md @@ -0,0 +1 @@ +NOTE: currently this dir is only for build binary packages! not for the container images! diff --git a/src/build/api/VERSION b/src/build/api/VERSION new file mode 100644 index 000000000..4640e9fac --- /dev/null +++ b/src/build/api/VERSION @@ -0,0 +1 @@ +${VERSION} diff --git a/src/build/api/manage.py b/src/build/api/manage.py new file mode 100644 index 000000000..97b91836a --- /dev/null +++ b/src/build/api/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bkuser_core.config.overlays.prod") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django # noqa + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) diff --git a/src/build/api/projects.yaml b/src/build/api/projects.yaml new file mode 100644 index 000000000..9e90e2cb8 --- /dev/null +++ b/src/build/api/projects.yaml @@ -0,0 +1,7 @@ +- name: api + module: usermgr + project_dir: usermgr/api + alias: usermgrapi + language: python/3.6 + version: ${VERSION} + version_type: ee/ce diff --git a/src/build/api/support-files/bkiam/.gitkeeper b/src/build/api/support-files/bkiam/.gitkeeper new file mode 100644 index 000000000..e69de29bb diff --git a/src/build/api/support-files/sql/0002_usermgr_20191128_mysql.sql b/src/build/api/support-files/sql/0002_usermgr_20191128_mysql.sql new file mode 100644 index 000000000..862a4c95b --- /dev/null +++ b/src/build/api/support-files/sql/0002_usermgr_20191128_mysql.sql @@ -0,0 +1 @@ +CREATE DATABASE IF NOT EXISTS `bk_user` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; \ No newline at end of file diff --git a/src/build/api/support-files/templates/#etc#supervisor-usermgr-api.conf b/src/build/api/support-files/templates/#etc#supervisor-usermgr-api.conf new file mode 100644 index 000000000..4e89f32dd --- /dev/null +++ b/src/build/api/support-files/templates/#etc#supervisor-usermgr-api.conf @@ -0,0 +1,56 @@ +[unix_http_server] +file=__BK_HOME__/logs/usermgr/supervisor.sock + +[supervisord] +logfile=__BK_HOME__/logs/usermgr/supervisord.log +logfile_maxbytes=50MB +logfile_backups=10 +loglevel=info +pidfile=__BK_HOME__/logs/usermgr/supervisord.pid +nodaemon=false +minfds=1024 +minprocs=200 + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix://__BK_HOME__/logs/usermgr/supervisor.sock + +[program:usermgrapi] +directory=__BK_HOME__/usermgr/api +environment= + PATH="__BK_HOME__/.envs/usermgr-api/bin/", + DJANGO_SETTINGS_MODULE="bkuser_core.config.overlays.prod", + LOGS_PATH="__BK_HOME__/logs", +command=__BK_HOME__/.envs/usermgr-api/bin/gunicorn wsgi -w 16 --max-requests 1024 --max-requests-jitter 50 --threads 2 --worker-class gevent -b :8009 --access-logfile - --error-logfile - +autostart=true +autorestart=true +redirect_stderr=true +stdout_logfile=__BK_HOME__/logs/usermgr/stdout.log + + +[program:usermgrapi-worker] +directory=__BK_HOME__/usermgr/api +environment= + PATH="__BK_HOME__/.envs/usermgr-api/bin/", + DJANGO_SETTINGS_MODULE="bkuser_core.config.overlays.prod", + LOGS_PATH="__BK_HOME__/logs", +command=__BK_HOME__/.envs/usermgr-api/bin/celery -A bkuser_core worker -l info --concurrency=8 --max-tasks-per-child=1 +autostart=true +autorestart=true +redirect_stderr=true +stdout_logfile=__BK_HOME__/logs/usermgr/worker.log + + +[program:usermgrapi-beat] +directory=__BK_HOME__/usermgr/api +environment= + PATH="__BK_HOME__/.envs/usermgr-api/bin/", + DJANGO_SETTINGS_MODULE="bkuser_core.config.overlays.prod", + LOGS_PATH="__BK_HOME__/logs", +command=__BK_HOME__/.envs/usermgr-api/bin/celery -A bkuser_core beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler +autostart=true +autorestart=true +redirect_stderr=true +stdout_logfile=__BK_HOME__/logs/usermgr/beat.log diff --git a/src/build/api/support-files/templates/api#bkuser_core#config#overlays#prod.py b/src/build/api/support-files/templates/api#bkuser_core#config#overlays#prod.py new file mode 100644 index 000000000..62c8e7900 --- /dev/null +++ b/src/build/api/support-files/templates/api#bkuser_core#config#overlays#prod.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- +""" +正式环境配置 +""" +import urllib.parse + +from bkuser_core.config.common.django_basic import * # noqa +from bkuser_core.config.common.logging import * # noqa +from bkuser_core.config.common.system import * # noqa + +from bkuser_global.logging import LoggingType, get_logging + +DEBUG = False + +# use the static root 'static' in production envs +if not DEBUG: + STATIC_ROOT = "static" + +APP_ID = "__BK_USERMGR_APP_CODE__" +APP_TOKEN = "__BK_USERMGR_APP_SECRET__" + +# 数据库配置信息 +DATABASES = { + "default": { + "ENGINE": "django.db.backends.mysql", # 默认用mysql + "NAME": "bk_user", + "USER": "__BK_USERMGR_MYSQL_USER__", + "PASSWORD": "__BK_USERMGR_MYSQL_PASSWORD__", + "HOST": "__BK_USERMGR_MYSQL_HOST__", + "PORT": "__BK_USERMGR_MYSQL_PORT__", + } +} + +LOGGING_DIR = "__BK_HOME__/logs/usermgr/" +LOGGING = get_logging( + logging_type=LoggingType.FILE, + log_level=LOG_LEVEL, + package_name="bkuser_core", + formatter="verbose", + logging_dir=LOGGING_DIR, + file_name="api", +) + +# 初始化用户名、密码 +SUPERUSER_USERNAME = "__BK_PAAS_ADMIN_USERNAME__" +SUPERUSER_PASSWORD = "__BK_PAAS_ADMIN_PASSWORD__" + +# domain +PAAS_DOMAIN = "__BK_PAAS_PUBLIC_ADDR__" +BK_PAAS_URL = "__BK_PAAS_PUBLIC_URL__" +BK_COMPONENT_API_URL = "__BK_PAAS_PUBLIC_URL__" + +# cookie访问域 +BK_COOKIE_DOMAIN = ".__BK_DOMAIN__" + +SECRET_KEY = "__BK_PAAS_ESB_SECRET_KEY__" + +# ESB Token +ESB_TOKEN = "__BK_PAAS_APP_SECRET__" + +# license +CERTIFICATE_DIR = "__BK_CERT_PATH__" +CERTIFICATE_SERVER_DOMAIN = "__BK_LICENSE_PRIVATE_ADDR__" + +# redis, NOTE: NOT SUPPORT REDIS SENTINEL NOW +REDIS_MODE = "__BK_USERMGR_REDIS_MODE__" +REDIS_HOST = "__BK_USERMGR_REDIS_HOST__" +REDIS_PORT = "__BK_USERMGR_REDIS_PORT__" +REDIS_PASSWORD = "__BK_USERMGR_REDIS_PASSWORD__" +REDIS_DB = 0 +REDIS_KEY_PREFIX = "bk-user-" + +REDIS_URL = f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" + +CACHES = { + "default": { + "BACKEND": "bkuser_core.common.cache.DummyRedisCache", + }, + 'locmem': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'memory_cache_0', + }, + "verification_code": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_URL, + "TIMEOUT": 30 * 60, + "KEY_PREFIX": f"{REDIS_KEY_PREFIX}verification_code", + "VERSION": 1, + "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": REDIS_PASSWORD}, + "SOCKET_CONNECT_TIMEOUT": 5, # socket 建立连接超时设置,单位秒 + "SOCKET_TIMEOUT": 5, # 连接建立后的读写操作超时设置,单位秒 + "IGNORE_EXCEPTIONS": True, # redis 只作为缓存使用, 触发异常不能影响正常逻辑,可能只是稍微慢点而已 + }, +} +# 全局缓存过期时间,默认为一小时 +GLOBAL_CACHES_TIMEOUT = env.int("GLOBAL_CACHES_TIMEOUT", default=60 * 60) + +# 快捷单元测试 dummy cache 标记 +USE_DUMMY_CACHE_FOR_TEST = True + +FORCE_JSONP_HEADER = "HTTP_FORCE_JSONP" +FORCE_NO_CACHE_HEADER = "HTTP_FORCE_NO_CACHE" + +########## +# Celery # +########## +REDIS_URL = "" +REDIS_KEY_PREFIX = env("CACHE_REDIS_KEY_PREFIX", default="bk-user-") +CELERY_BROKER_URL = "amqp://__BK_USERMGR_RABBITMQ_USERNAME__:__BK_USERMGR_RABBITMQ_PASSWORD__@__BK_USERMGR_RABBITMQ_HOST__:__BK_USERMGR_RABBITMQ_PORT__/__BK_USERMGR_RABBITMQ_VHOST__" +CELERY_RESULT_BACKEND = "amqp://__BK_USERMGR_RABBITMQ_USERNAME__:__BK_USERMGR_RABBITMQ_PASSWORD__@__BK_USERMGR_RABBITMQ_HOST__:__BK_USERMGR_RABBITMQ_PORT__/__BK_USERMGR_RABBITMQ_VHOST__" + +# ============================================================================== +# IAM +# ============================================================================== +def get_iam_config(app_id: str, app_token: str) -> dict: + return dict( + api_host="__BK_IAM_PRIVATE_URL__", + system_id=env("BK_IAM_SYSTEM_ID", default="bk_usermgr"), + # iam app 访问 url 用于回调拼接 + iam_app_host=env( + "BK_IAM_SAAS_HOST", + default=f"{BK_PAAS_URL}/o/{env('BK_IAM_V3_APP_CODE', default='bk_iam')}", + ), + apply_path="apply-custom-perm", + # 自己的 app_id & app_token + own_app_id=app_id, + own_app_token=app_token, + ) + + +IAM_CONFIG = get_iam_config(APP_ID, APP_TOKEN) # type: ignore +ENABLE_IAM = True + +# 请求 ESB API 默认版本号 +DEFAULT_BK_API_VER = "v2" + +# 与 SaaS 约定的权限校验头,未传递时跳过权限校验 +NEED_IAM_HEADER = "HTTP_NEED_IAM" +ACTION_ID_HEADER = "HTTP_ACTION_ID" + +# =============================================================================== +# API 访问限制(暂未开启) +# =============================================================================== +INTERNAL_AUTH_TOKENS = {"TCwCnoiuUgPccj8y0Wx187vJBqzqddfLlm": {"username": "iadmin"}} +ACCESS_APP_WHITE_LIST = {"bk-iam": "lLP3gabV8M0C9vbwHQwzSYJX3WumcJsDSdVNQtq6FJVCLqJX6o"} + + +# ============================================================================== +# 登陆相关 +# ============================================================================== +LOGIN_REDIRECT_TO = f"{BK_PAAS_URL}/login/?c_url={SITE_URL}" + +# ============================================================================== +# SaaS 配置 +# ============================================================================== +# SaaS 应用 Code +SAAS_CODE = "bk_user_manage" +# SaaS 请求地址,用于拼接访问地址(默认支持二进制部署) +SAAS_URL = env( + "SAAS_URL", default=urllib.parse.urljoin(BK_PAAS_URL, f"/o/{SAAS_CODE}/") +) + +# SaaS 偏好 client ip 头 +CLIENT_IP_FROM_SAAS_HEADER = "HTTP_CLIENT_IP_FROM_SAAS" + +# 可通过 SaaS 管理的用户目录类型 +CAN_MANUAL_WRITE_LISTS = ["local"] diff --git a/src/build/saas/.env b/src/build/saas/.env new file mode 100644 index 000000000..772a776d4 --- /dev/null +++ b/src/build/saas/.env @@ -0,0 +1,6 @@ +BK_PAAS_URL=$BK_PAAS_HOST +BK_LOGIN_API_URL=http://paas.service.consul:80/login + +BK_APP_CODE=$APP_ID +BK_APP_SECRET=$APP_TOKEN +DB_USER=$DB_USERNAME diff --git a/src/build/saas/bk_user_manage.png b/src/build/saas/bk_user_manage.png new file mode 100644 index 000000000..a66df3b79 Binary files /dev/null and b/src/build/saas/bk_user_manage.png differ diff --git a/src/build/saas/manage.py b/src/build/saas/manage.py new file mode 100644 index 000000000..a25794224 --- /dev/null +++ b/src/build/saas/manage.py @@ -0,0 +1,33 @@ +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-用户管理(Bk-User) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +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 os +import sys + +if __name__ == "__main__": + + # manage.py used to work in dev env + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bkuser_shell.config.overlays.prod") + + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django # noqa + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) diff --git a/src/build/saas/support-files/bk_user_manage.ini b/src/build/saas/support-files/bk_user_manage.ini new file mode 100644 index 000000000..a17e15c22 --- /dev/null +++ b/src/build/saas/support-files/bk_user_manage.ini @@ -0,0 +1,33 @@ +[uwsgi] +socket = /data/app/run/uwsgi.sock +pidfile2 = /data/app/run/uwsgi.pid +logto2 = /data/app/logs/bk_user_manage/uwsgi.log +single-interpreter = True + +logdate = true +log-format = [%(addr)] [%(ctime)] [%(method)] [%(uri)] [%(proto)] [%(status)] [%(msecs)] [%(referer)] [%(uagent)] + +memory-report = true + +master = true +vacuum = true + +chdir = /data/app/code/ +module = wsgi:application + +cheaper = 4 +cheaper-initial = 4 + +workers = 16 + +cheaper-algo = busyness +cheaper-overload = 5 +cheaper-step = 2 +cheaper-busyness-multiplier = 60 + +buffer-size = 8192 +post-buffering = 8192 + +max-requests = 1024 +mount = /o/bk_user_manage=wsgi.py +manage-script-name = true \ No newline at end of file diff --git a/src/build/saas/support-files/supervisord.conf b/src/build/saas/support-files/supervisord.conf new file mode 100644 index 000000000..86d86addc --- /dev/null +++ b/src/build/saas/support-files/supervisord.conf @@ -0,0 +1,21 @@ +[unix_http_server] +file = {{.app_container_path}}run/supervisord.sock + +[supervisorctl] +configuration = {{.app_container_path}}supervisord.conf +serverurl = unix://{{.app_container_path}}/run/supervisord.sock + +[supervisord] +pidfile = {{.app_container_path}}run/supervisord.pid +logfile = {{.app_container_path}}logs/{{.app_code}}/supervisord.log +directory = {{.app_container_path}} + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[program: {{.app_code}}_uwsgi] +command = /cache/.bk/env/bin/uwsgi --ini {{.app_container_path}}code/support-files/{{.app_code}}.ini +stdout_logfile = {{.app_container_path}}logs/{{.app_code}}/uwsgi.log +redirect_stderr = true +autorestart = true +environment = {{.environment}} \ No newline at end of file diff --git a/src/config.json b/src/config.json deleted file mode 100644 index 99ec87d62..000000000 --- a/src/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "packageName":"bkuser_sdk", - "projectName":"bkuser_sdk", - "packageVersion":"1.0.0" -} \ No newline at end of file diff --git a/src/login/poetry.lock b/src/login/poetry.lock index 5ee044626..7f6ad4e4c 100644 --- a/src/login/poetry.lock +++ b/src/login/poetry.lock @@ -9,11 +9,6 @@ python-versions = ">=3.5" [package.dependencies] contextvars = {version = "2.4", markers = "python_version < \"3.7\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "appnope" version = "0.1.3" @@ -22,11 +17,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "asgiref" version = "3.4.1" @@ -39,12 +29,7 @@ python-versions = ">=3.6" typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "atomicwrites" @@ -54,11 +39,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "attrs" version = "21.4.0" @@ -68,15 +48,10 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] [[package]] name = "backcall" @@ -86,11 +61,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "backoff" version = "1.10.0" @@ -99,11 +69,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "black" version = "21.12b0" @@ -129,11 +94,6 @@ jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "blue-krill" version = "1.0.15" @@ -156,11 +116,6 @@ six = "*" toml = "*" watchdog = ">=1.0.2,<2.0.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "cachetools" version = "3.1.1" @@ -169,11 +124,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "certifi" version = "2021.10.8" @@ -182,11 +132,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "cffi" version = "1.15.0" @@ -198,11 +143,6 @@ python-versions = "*" [package.dependencies] pycparser = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "chardet" version = "3.0.4" @@ -211,11 +151,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "click" version = "8.0.4" @@ -228,11 +163,6 @@ python-versions = ">=3.6" colorama = {version = "*", markers = "platform_system == \"Windows\""} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "colorama" version = "0.4.4" @@ -241,11 +171,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "contextvars" version = "2.4" @@ -257,11 +182,6 @@ python-versions = "*" [package.dependencies] immutables = ">=0.9" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "coverage" version = "6.2" @@ -273,11 +193,6 @@ python-versions = ">=3.6" [package.extras] toml = ["tomli"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "cryptography" version = "3.4.8" @@ -291,16 +206,11 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] -docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +docstest = ["doc8", "pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] [[package]] name = "curlify" @@ -313,11 +223,6 @@ python-versions = "*" [package.dependencies] requests = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "dataclasses" version = "0.7" @@ -326,11 +231,6 @@ category = "main" optional = false python-versions = ">=3.6, <3.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "decorator" version = "5.1.1" @@ -339,11 +239,6 @@ category = "dev" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "deprecated" version = "1.2.13" @@ -356,12 +251,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "dj-static" @@ -374,11 +264,6 @@ python-versions = "*" [package.dependencies] static3 = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django" version = "3.2.15" @@ -396,11 +281,6 @@ sqlparse = ">=0.2.2" argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-braces" version = "1.13.0" @@ -409,11 +289,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-environ" version = "0.4.5" @@ -422,11 +297,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "django-prometheus" version = "2.1.0" @@ -438,11 +308,6 @@ python-versions = "*" [package.dependencies] prometheus-client = ">=0.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "flake8" version = "4.0.1" @@ -457,11 +322,6 @@ mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.8.0,<2.9.0" pyflakes = ">=2.4.0,<2.5.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "flake8-comprehensions" version = "3.7.0" @@ -474,11 +334,6 @@ python-versions = ">=3.6" flake8 = ">=3.0,<3.2.0 || >3.2.0,<5" importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "gevent" version = "21.1.2" @@ -497,13 +352,8 @@ greenlet = {version = ">=0.4.17,<2.0", markers = "platform_python_implementation dnspython = ["dnspython (>=1.16.0,<2.0)", "idna"] docs = ["repoze.sphinx.autointerface", "sphinxcontrib-programoutput", "zope.schema"] monitor = ["psutil (>=5.7.0)"] -recommended = ["dnspython (>=1.16.0,<2.0)", "idna", "cffi (>=1.12.2)", "selectors2", "backports.socketpair", "psutil (>=5.7.0)"] -test = ["dnspython (>=1.16.0,<2.0)", "idna", "requests", "objgraph", "cffi (>=1.12.2)", "selectors2", "futures", "mock", "backports.socketpair", "contextvars (==2.4)", "coverage (>=5.0)", "coveralls (>=1.7.0)", "psutil (>=5.7.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +recommended = ["backports.socketpair", "cffi (>=1.12.2)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)", "selectors2"] +test = ["backports.socketpair", "cffi (>=1.12.2)", "contextvars (==2.4)", "coverage (>=5.0)", "coveralls (>=1.7.0)", "dnspython (>=1.16.0,<2.0)", "futures", "idna", "mock", "objgraph", "psutil (>=5.7.0)", "requests", "selectors2"] [[package]] name = "googleapis-common-protos" @@ -519,11 +369,6 @@ protobuf = ">=3.15.0,<5.0.0dev" [package.extras] grpc = ["grpcio (>=1.0.0,<2.0.0dev)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "greenlet" version = "1.1.2" @@ -535,11 +380,6 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] docs = ["sphinx"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "grpcio" version = "1.48.0" @@ -567,11 +407,6 @@ eventlet = ["eventlet (>=0.9.7)"] gevent = ["gevent (>=0.13)"] tornado = ["tornado (>=0.2)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "idna" version = "2.8" @@ -580,11 +415,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "immutables" version = "0.18" @@ -597,12 +427,7 @@ python-versions = ">=3.6" typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [package.extras] -test = ["flake8 (>=3.8.4,<3.9.0)", "pycodestyle (>=2.6.0,<2.7.0)", "mypy (==0.942)", "pytest (>=6.2.4,<6.3.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["flake8 (>=3.8.4,<3.9.0)", "mypy (==0.942)", "pycodestyle (>=2.6.0,<2.7.0)", "pytest (>=6.2.4,<6.3.0)"] [[package]] name = "importlib-metadata" @@ -617,13 +442,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "iniconfig" @@ -633,11 +453,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ipython" version = "7.16.3" @@ -664,15 +479,10 @@ doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] -notebook = ["notebook", "ipywidgets"] +notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.14)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.14)", "pygments", "requests", "testpath"] [[package]] name = "ipython-genutils" @@ -682,11 +492,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "isort" version = "5.10.1" @@ -697,14 +502,9 @@ python-versions = ">=3.6.1,<4.0" [package.extras] colors = ["colorama (>=0.4.3,<0.5.0)"] -requirements_deprecated_finder = ["pip-api", "pipreqs"] pipfile_deprecated_finder = ["pipreqs", "requirementslib"] plugins = ["setuptools"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +requirements_deprecated_finder = ["pip-api", "pipreqs"] [[package]] name = "jedi" @@ -721,11 +521,6 @@ parso = ">=0.7.0,<0.8.0" qa = ["flake8 (==3.7.9)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (>=3.9.0,<5.0.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mccabe" version = "0.6.1" @@ -734,11 +529,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mypy" version = "0.910" @@ -757,11 +547,6 @@ typing-extensions = ">=3.7.4" dmypy = ["psutil (>=4.0)"] python2 = ["typed-ast (>=1.4.0,<1.5.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "mypy-extensions" version = "0.4.3" @@ -770,11 +555,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-api" version = "1.7.1" @@ -787,11 +567,6 @@ python-versions = ">=3.6" aiocontextvars = {version = "*", markers = "python_version < \"3.7\""} Deprecated = ">=1.2.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger" version = "1.7.1" @@ -804,11 +579,6 @@ python-versions = ">=3.6" opentelemetry-exporter-jaeger-proto-grpc = "1.7.1" opentelemetry-exporter-jaeger-thrift = "1.7.1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger-proto-grpc" version = "1.7.1" @@ -823,11 +593,6 @@ grpcio = ">=1.0.0,<2.0.0" opentelemetry-api = ">=1.3,<2.0" opentelemetry-sdk = ">=1.3,<2.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-jaeger-thrift" version = "1.7.1" @@ -841,11 +606,6 @@ opentelemetry-api = ">=1.3,<2.0" opentelemetry-sdk = ">=1.3,<2.0" thrift = ">=0.10.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp" version = "1.7.1" @@ -858,11 +618,6 @@ python-versions = ">=3.6" opentelemetry-exporter-otlp-proto-grpc = "1.7.1" opentelemetry-exporter-otlp-proto-http = "1.7.1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" version = "1.7.1" @@ -882,11 +637,6 @@ opentelemetry-sdk = ">=1.3,<2.0" [package.extras] test = ["pytest-grpc"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-exporter-otlp-proto-http" version = "1.7.1" @@ -903,11 +653,6 @@ opentelemetry-proto = "1.7.1" opentelemetry-sdk = ">=1.3,<2.0" requests = ">=2.7,<3.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation" version = "0.26b1" @@ -920,11 +665,6 @@ python-versions = ">=3.6" opentelemetry-api = ">=1.4,<2.0" wrapt = ">=1.0.0,<2.0.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-celery" version = "0.26b1" @@ -940,12 +680,7 @@ opentelemetry-semantic-conventions = "0.26b1" [package.extras] instruments = ["celery (>=4.0,<6.0)"] -test = ["pytest", "opentelemetry-test-utils (==0.26b1)", "celery (>=4.0,<6.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["celery (>=4.0,<6.0)", "opentelemetry-test-utils (==0.26b1)", "pytest"] [[package]] name = "opentelemetry-instrumentation-dbapi" @@ -964,11 +699,6 @@ wrapt = ">=1.0.0,<2.0.0" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-django" version = "0.26b1" @@ -987,12 +717,7 @@ opentelemetry-util-http = "0.26b1" [package.extras] asgi = ["opentelemetry-instrumentation-asgi (==0.26b1)"] instruments = ["django (>=1.10)"] -test = ["opentelemetry-test-utils (==0.26b1)", "django (>=1.10)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["django (>=1.10)", "opentelemetry-test-utils (==0.26b1)"] [[package]] name = "opentelemetry-instrumentation-logging" @@ -1009,11 +734,6 @@ opentelemetry-instrumentation = "0.26b1" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-instrumentation-redis" version = "0.26b1" @@ -1030,12 +750,7 @@ wrapt = ">=1.12.1" [package.extras] instruments = ["redis (>=2.6)"] -test = ["opentelemetry-test-utils (==0.26b1)", "opentelemetry-sdk (>=1.3,<2.0)", "redis (>=2.6)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["opentelemetry-sdk (>=1.3,<2.0)", "opentelemetry-test-utils (==0.26b1)", "redis (>=2.6)"] [[package]] name = "opentelemetry-instrumentation-requests" @@ -1053,12 +768,7 @@ opentelemetry-util-http = "0.26b1" [package.extras] instruments = ["requests (>=2.0,<3.0)"] -test = ["opentelemetry-test-utils (==0.26b1)", "httpretty (>=1.0,<2.0)", "requests (>=2.0,<3.0)"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["httpretty (>=1.0,<2.0)", "opentelemetry-test-utils (==0.26b1)", "requests (>=2.0,<3.0)"] [[package]] name = "opentelemetry-instrumentation-wsgi" @@ -1077,11 +787,6 @@ opentelemetry-util-http = "0.26b1" [package.extras] test = ["opentelemetry-test-utils (==0.26b1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-proto" version = "1.7.1" @@ -1093,11 +798,6 @@ python-versions = ">=3.6" [package.dependencies] protobuf = ">=3.13.0" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-sdk" version = "1.7.1" @@ -1110,11 +810,6 @@ python-versions = ">=3.6" opentelemetry-api = "1.7.1" opentelemetry-semantic-conventions = "0.26b1" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-semantic-conventions" version = "0.26b1" @@ -1123,11 +818,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "opentelemetry-util-http" version = "0.26b1" @@ -1136,11 +826,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "packaging" version = "21.3" @@ -1152,11 +837,6 @@ python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "parso" version = "0.7.1" @@ -1168,11 +848,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] testing = ["docopt", "pytest (>=3.0.7)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pathspec" version = "0.9.0" @@ -1181,11 +856,6 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pexpect" version = "4.8.0" @@ -1197,11 +867,6 @@ python-versions = "*" [package.dependencies] ptyprocess = ">=0.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pickleshare" version = "0.7.5" @@ -1210,11 +875,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "platformdirs" version = "2.4.0" @@ -1227,11 +887,6 @@ python-versions = ">=3.6" docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pluggy" version = "1.0.0" @@ -1247,11 +902,6 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "prometheus-client" version = "0.14.1" @@ -1263,11 +913,6 @@ python-versions = ">=3.6" [package.extras] twisted = ["twisted"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "prompt-toolkit" version = "3.0.29" @@ -1279,11 +924,6 @@ python-versions = ">=3.6.2" [package.dependencies] wcwidth = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "protobuf" version = "3.19.4" @@ -1292,11 +932,6 @@ category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "ptyprocess" version = "0.7.0" @@ -1305,11 +940,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "py" version = "1.11.0" @@ -1318,11 +948,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyasn1" version = "0.4.8" @@ -1331,11 +956,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pycodestyle" version = "2.8.0" @@ -1344,11 +964,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pycparser" version = "2.21" @@ -1357,11 +972,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pycrypto" version = "2.6.1" @@ -1370,11 +980,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pydantic" version = "1.9.1" @@ -1391,11 +996,6 @@ typing-extensions = ">=3.7.4.3" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyflakes" version = "2.4.0" @@ -1404,11 +1004,6 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pygments" version = "2.12.0" @@ -1417,11 +1012,6 @@ category = "dev" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyjwt" version = "1.7.1" @@ -1435,11 +1025,6 @@ crypto = ["cryptography (>=1.4)"] flake8 = ["flake8", "flake8-import-order", "pep8-naming"] test = ["pytest (>=4.0.1,<5.0.0)", "pytest-cov (>=2.6.0,<3.0.0)", "pytest-runner (>=4.2,<5.0.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pymysql" version = "1.0.2" @@ -1452,11 +1037,6 @@ python-versions = ">=3.6" ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pyparsing" version = "3.0.9" @@ -1466,12 +1046,7 @@ optional = false python-versions = ">=3.6.8" [package.extras] -diagrams = ["railroad-diagrams", "jinja2"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyproject-flake8" @@ -1485,11 +1060,6 @@ python-versions = "*" flake8 = "*" tomli = {version = "*", markers = "python_version < \"3.11\""} -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytest" version = "6.2.5" @@ -1512,11 +1082,6 @@ toml = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytest-cov" version = "2.12.1" @@ -1531,12 +1096,7 @@ pytest = ">=4.6" toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] [[package]] name = "pytest-django" @@ -1553,11 +1113,6 @@ pytest = ">=3.6" docs = ["sphinx", "sphinx-rtd-theme"] testing = ["django", "django-configurations (>=2.0)", "six"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-dateutil" version = "2.8.1" @@ -1569,11 +1124,6 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] six = ">=1.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-editor" version = "1.0.4" @@ -1582,11 +1132,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "python-json-logger" version = "2.0.2" @@ -1595,11 +1140,6 @@ category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "pytz" version = "2016.6.1" @@ -1608,11 +1148,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "requests" version = "2.21.0" @@ -1628,14 +1163,9 @@ idna = ">=2.5,<2.9" urllib3 = ">=1.21.1,<1.25" [package.extras] -security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)"] +security = ["cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "rsa" version = "3.4.2" @@ -1647,11 +1177,6 @@ python-versions = "*" [package.dependencies] pyasn1 = ">=0.1.3" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "sentry-sdk" version = "1.5.6" @@ -1672,21 +1197,16 @@ celery = ["celery (>=3)"] chalice = ["chalice (>=1.16.0)"] django = ["django (>=1.8)"] falcon = ["falcon (>=1.4)"] -flask = ["flask (>=0.11)", "blinker (>=1.1)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)"] httpx = ["httpx (>=0.16.0)"] -pure_eval = ["pure-eval", "executing", "asttokens"] +pure_eval = ["asttokens", "executing", "pure-eval"] pyspark = ["pyspark (>=2.4.4)"] -quart = ["quart (>=0.16.1)", "blinker (>=1.1)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] rq = ["rq (>=0.6)"] sanic = ["sanic (>=0.8)"] sqlalchemy = ["sqlalchemy (>=1.2)"] tornado = ["tornado (>=5)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "six" version = "1.16.0" @@ -1695,11 +1215,6 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "sqlparse" version = "0.4.2" @@ -1708,11 +1223,6 @@ category = "main" optional = false python-versions = ">=3.5" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "static3" version = "0.7.0" @@ -1725,11 +1235,6 @@ python-versions = "*" GenshiMagic = ["genshi"] KidMagic = ["kid"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "thrift" version = "0.16.0" @@ -1746,11 +1251,6 @@ all = ["tornado (>=4.0)", "twisted"] tornado = ["tornado (>=4.0)"] twisted = ["twisted"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "toml" version = "0.10.2" @@ -1759,11 +1259,6 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "tomli" version = "1.2.3" @@ -1772,11 +1267,6 @@ category = "dev" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "traitlets" version = "4.3.3" @@ -1791,12 +1281,7 @@ ipython-genutils = "*" six = "*" [package.extras] -test = ["pytest", "mock"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +test = ["mock", "pytest"] [[package]] name = "typed-ast" @@ -1806,11 +1291,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "typing-extensions" version = "4.1.1" @@ -1819,11 +1299,6 @@ category = "main" optional = false python-versions = ">=3.6" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "urllib3" version = "1.24.3" @@ -1833,14 +1308,9 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" [package.extras] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "watchdog" version = "1.0.2" @@ -1852,11 +1322,6 @@ python-versions = ">=3.6" [package.extras] watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "wcwidth" version = "0.2.5" @@ -1865,11 +1330,6 @@ category = "dev" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "werkzeug" version = "2.0.3" @@ -1884,11 +1344,6 @@ dataclasses = {version = "*", markers = "python_version < \"3.7\""} [package.extras] watchdog = ["watchdog"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "wrapt" version = "1.14.1" @@ -1897,11 +1352,6 @@ category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "xlrd" version = "1.0.0" @@ -1910,11 +1360,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "xlwt" version = "1.1.2" @@ -1923,11 +1368,6 @@ category = "main" optional = false python-versions = "*" -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "zipp" version = "3.6.0" @@ -1937,13 +1377,8 @@ optional = false python-versions = ">=3.6" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] - -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" +docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] [[package]] name = "zope.event" @@ -1957,11 +1392,6 @@ python-versions = "*" docs = ["sphinx"] test = ["zope.testrunner"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [[package]] name = "zope.interface" version = "5.4.0" @@ -1971,19 +1401,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.extras] -docs = ["sphinx", "repoze.sphinx.autointerface"] +docs = ["repoze.sphinx.autointerface", "sphinx"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] -[package.source] -type = "legacy" -url = "https://mirrors.tencent.com/pypi/simple" -reference = "tencent-mirrors" - [metadata] lock-version = "1.1" python-versions = "3.6.14" -content-hash = "459fc824c7fc700793e6cc0be74315835f6f99fe341c944394c351fbbf9af7cf" +content-hash = "e8f71bd25cd11df26e7d42861d5a6edbbb444828e1e4e6c4f0c6833fde815457" [metadata.files] aiocontextvars = [ @@ -2019,8 +1444,8 @@ black = [ {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, ] blue-krill = [ - {file = "blue-krill-1.0.15.tar.gz", hash = "md5:62c1ce7688b87434d53a16acc1bfb76a"}, - {file = "blue_krill-1.0.15-py3-none-any.whl", hash = "md5:b15667779ec92aa47bd33ad140835851"}, + {file = "blue-krill-1.0.15.tar.gz", hash = "sha256:d919626e9853ae3deb39ea31f56867d38a11045c2843da5d7e3db5e4240036a3"}, + {file = "blue_krill-1.0.15-py3-none-any.whl", hash = "sha256:1dcac31abd3afba30ccbce74135352519c4839c0f58b1775f07fbd70a97d0d51"}, ] cachetools = [ {file = "cachetools-3.1.1-py2.py3-none-any.whl", hash = "sha256:428266a1c0d36dc5aca63a2d7c5942e88c2c898d72139fca0e97fdd2380517ae"}, @@ -2613,7 +2038,18 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pycodestyle = [ @@ -2707,14 +2143,25 @@ python-dateutil = [ python-editor = [ {file = "python-editor-1.0.4.tar.gz", hash = "sha256:51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b"}, {file = "python_editor-1.0.4-py2-none-any.whl", hash = "sha256:5f98b069316ea1c2ed3f67e7f5df6c0d8f10b689964a4a811ff64f0106819ec8"}, + {file = "python_editor-1.0.4-py2.7.egg", hash = "sha256:ea87e17f6ec459e780e4221f295411462e0d0810858e055fc514684350a2f522"}, {file = "python_editor-1.0.4-py3-none-any.whl", hash = "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d"}, + {file = "python_editor-1.0.4-py3.5.egg", hash = "sha256:c3da2053dbab6b29c94e43c486ff67206eafbe7eb52dbec7390b5e2fb05aac77"}, ] python-json-logger = [ {file = "python-json-logger-2.0.2.tar.gz", hash = "sha256:202a4f29901a4b8002a6d1b958407eeb2dd1d83c18b18b816f5b64476dde9096"}, {file = "python_json_logger-2.0.2-py3-none-any.whl", hash = "sha256:99310d148f054e858cd5f4258794ed6777e7ad2c3fd7e1c1b527f1cba4d08420"}, ] pytz = [ + {file = "pytz-2016.6.1-py2.4.egg", hash = "sha256:97baa64915ef83b98d202ee2d4dbcc891b924b83410e69078523215fa2c72d0a"}, + {file = "pytz-2016.6.1-py2.5.egg", hash = "sha256:3495f56248eac90e59a1e742d13e2ce647eea46aadf453d0fa22b7eb3d665670"}, + {file = "pytz-2016.6.1-py2.6.egg", hash = "sha256:5cf3ed40944662a351b2cca0c5bb0c003e0a1b2c4d808e45fad73abf80f44b48"}, + {file = "pytz-2016.6.1-py2.7.egg", hash = "sha256:dec0bedfa2a91289e2505e4f771dbcb6a3930b6664e6a6ac010cd73f555900ba"}, {file = "pytz-2016.6.1-py2.py3-none-any.whl", hash = "sha256:7833bf559800232d3965b70e69642ebdadc76f7988f8d0a1440e072193ecd949"}, + {file = "pytz-2016.6.1-py3.1.egg", hash = "sha256:2f5fa04d1804ff0cd52ca3274ba9e74c775b4b70a18f25fcc537c903dfd5cc18"}, + {file = "pytz-2016.6.1-py3.2.egg", hash = "sha256:a44a3486a6657046879406dfd9ef0565b1211ffcf4779bddbe39c72496df1688"}, + {file = "pytz-2016.6.1-py3.3.egg", hash = "sha256:2298d266b831852d0a7ef7e17c57c09a0320d187b3f1c85e58903fb6088d268d"}, + {file = "pytz-2016.6.1-py3.4.egg", hash = "sha256:060cf9f8770765a7d0be9e0b3e512ab54bc346a15daa50d6c9dd59347a396d3a"}, + {file = "pytz-2016.6.1-py3.5.egg", hash = "sha256:1cc1fdda22d183ed6e6c9f65ecbba8e12a9208cfadd384d2d429e18dc0250a0f"}, {file = "pytz-2016.6.1.tar.bz2", hash = "sha256:b5aff44126cf828537581e534cc94299b223b945a2bb3b5434d37bf8c7f3a10c"}, {file = "pytz-2016.6.1.tar.gz", hash = "sha256:6f57732f0f8849817e9853eb9d50d85d1ebb1404f702dbc44ee627c642a486ca"}, {file = "pytz-2016.6.1.zip", hash = "sha256:51ad716f6081f2126deb436349924e069dfcd0cbd9e0cabdacb0b3a72a3b82e7"}, diff --git a/src/login/pyproject.toml b/src/login/pyproject.toml index 6c96f612b..eedc81988 100644 --- a/src/login/pyproject.toml +++ b/src/login/pyproject.toml @@ -2,7 +2,7 @@ name = "bk-login" version = "2.3.3" description = "bk-login" -authors = ["IMBlues "] +authors = ["TencentBlueKing "] [tool.poetry.dependencies] python = "3.6.14" @@ -53,9 +53,3 @@ pytest-cov = "^2.8.1" # mypy mypy = "^v0.910" - - -[[tool.poetry.source]] -name = "tencent-mirrors" -url = "https://mirrors.tencent.com/pypi/simple/" - diff --git a/src/login/wsgi.py b/src/login/wsgi.py index 7c07f0317..c1417195a 100755 --- a/src/login/wsgi.py +++ b/src/login/wsgi.py @@ -10,11 +10,14 @@ specific language governing permissions and limitations under the License. """ +import faulthandler import os from dj_static import Cling from django.core.wsgi import get_wsgi_application +faulthandler.enable() + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bklogin.config.prod") application = Cling(get_wsgi_application()) diff --git a/src/pages/package.json b/src/pages/package.json index 3bf9d2f45..3b7be6e02 100644 --- a/src/pages/package.json +++ b/src/pages/package.json @@ -57,6 +57,7 @@ "express-art-template": "1.0.1", "intl-tel-input": "16.0.0", "js-base64": "^3.7.2", + "jsencrypt": "3.3.1", "jsonp": "0.2.1", "query-string": "6.5.0", "sortablejs": "1.10.1", @@ -69,7 +70,8 @@ "vue-i18n": "8.9.0", "vue-image-crop-upload": "2.5.0", "vue-router": "3.0.6", - "vuex": "3.1.1" + "vuex": "3.1.1", + "xss": "1.0.13" }, "devDependencies": { "@babel/core": "7.11.0", diff --git a/src/pages/src/App.vue b/src/pages/src/App.vue index 3142c86a6..8a48a2a77 100644 --- a/src/pages/src/App.vue +++ b/src/pages/src/App.vue @@ -1,23 +1,11 @@