diff --git a/.gitignore b/.gitignore index 0c7e5c712f008b..2f44cf7934919b 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,5 @@ sdks/python-client/dify_client.egg-info .vscode/* !.vscode/launch.json pyrightconfig.json + +.idea/ diff --git a/api/Dockerfile b/api/Dockerfile index 53c33a76591fa4..55776f80e136c8 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -5,8 +5,7 @@ WORKDIR /app/api # Install Poetry ENV POETRY_VERSION=1.8.3 -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir --upgrade poetry==${POETRY_VERSION} +RUN pip install --no-cache-dir poetry==${POETRY_VERSION} # Configure Poetry ENV POETRY_CACHE_DIR=/tmp/poetry_cache diff --git a/api/README.md b/api/README.md index e949ac72a562d6..8d2afa5e809141 100644 --- a/api/README.md +++ b/api/README.md @@ -11,7 +11,7 @@ ```bash cd ../docker - cp .middleware.env.example .middleware.env + cp middleware.env.example middleware.env docker compose -f docker-compose.middleware.yaml -p dify up -d cd ../api ``` diff --git a/api/app.py b/api/app.py index e0cccd6183933f..f5a6d40e1ac978 100644 --- a/api/app.py +++ b/api/app.py @@ -2,7 +2,7 @@ from configs import dify_config -if not os.environ.get("DEBUG") or os.environ.get("DEBUG", "false").lower() != 'true': +if os.environ.get("DEBUG", "false").lower() != 'true': from gevent import monkey monkey.patch_all() @@ -43,6 +43,8 @@ from extensions.ext_database import db from extensions.ext_login import login_manager from libs.passport import PassportService + +# TODO: Find a way to avoid importing models here from models import account, dataset, model, source, task, tool, tools, web from services.account_service import AccountService diff --git a/api/configs/app_config.py b/api/configs/app_config.py index e5edc86bc3d2ee..38921affd93e86 100644 --- a/api/configs/app_config.py +++ b/api/configs/app_config.py @@ -1,3 +1,4 @@ +from pydantic import computed_field from pydantic_settings import BaseSettings, SettingsConfigDict from configs.deploy import DeploymentConfig @@ -43,3 +44,28 @@ class DifyConfig( # ignore extra attributes extra='ignore', ) + + CODE_MAX_NUMBER: int = 9223372036854775807 + CODE_MIN_NUMBER: int = -9223372036854775808 + CODE_MAX_STRING_LENGTH: int = 80000 + CODE_MAX_STRING_ARRAY_LENGTH: int = 30 + CODE_MAX_OBJECT_ARRAY_LENGTH: int = 30 + CODE_MAX_NUMBER_ARRAY_LENGTH: int = 1000 + + HTTP_REQUEST_MAX_CONNECT_TIMEOUT: int = 300 + HTTP_REQUEST_MAX_READ_TIMEOUT: int = 600 + HTTP_REQUEST_MAX_WRITE_TIMEOUT: int = 600 + HTTP_REQUEST_NODE_MAX_BINARY_SIZE: int = 1024 * 1024 * 10 + + @computed_field + def HTTP_REQUEST_NODE_READABLE_MAX_BINARY_SIZE(self) -> str: + return f'{self.HTTP_REQUEST_NODE_MAX_BINARY_SIZE / 1024 / 1024:.2f}MB' + + HTTP_REQUEST_NODE_MAX_TEXT_SIZE: int = 1024 * 1024 + + @computed_field + def HTTP_REQUEST_NODE_READABLE_MAX_TEXT_SIZE(self) -> str: + return f'{self.HTTP_REQUEST_NODE_MAX_TEXT_SIZE / 1024 / 1024:.2f}MB' + + SSRF_PROXY_HTTP_URL: str | None = None + SSRF_PROXY_HTTPS_URL: str | None = None \ No newline at end of file diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 20371c7828bc4c..1b202fad733d4c 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -17,6 +17,10 @@ class SecurityConfig(BaseModel): default=None, ) + RESET_PASSWORD_TOKEN_EXPIRY_HOURS: PositiveInt = Field( + description='Expiry time in hours for reset token', + default=24, + ) class AppExecutionConfig(BaseModel): """ diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py index 6b3ed1a1009ef5..1bf9650af9a595 100644 --- a/api/configs/middleware/__init__.py +++ b/api/configs/middleware/__init__.py @@ -81,6 +81,11 @@ class DatabaseConfig: default='', ) + DB_EXTRAS: str = Field( + description='db extras options. Example: keepalives_idle=60&keepalives=1', + default='', + ) + SQLALCHEMY_DATABASE_URI_SCHEME: str = Field( description='db uri scheme', default='postgresql', @@ -89,7 +94,12 @@ class DatabaseConfig: @computed_field @property def SQLALCHEMY_DATABASE_URI(self) -> str: - db_extras = f"?client_encoding={self.DB_CHARSET}" if self.DB_CHARSET else "" + db_extras = ( + f"{self.DB_EXTRAS}&client_encoding={self.DB_CHARSET}" + if self.DB_CHARSET + else self.DB_EXTRAS + ).strip("&") + db_extras = f"?{db_extras}" if db_extras else "" return (f"{self.SQLALCHEMY_DATABASE_URI_SCHEME}://" f"{self.DB_USERNAME}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_DATABASE}" f"{db_extras}") @@ -114,7 +124,7 @@ def SQLALCHEMY_DATABASE_URI(self) -> str: default=False, ) - SQLALCHEMY_ECHO: bool = Field( + SQLALCHEMY_ECHO: bool | str = Field( description='whether to enable SqlAlchemy echo', default=False, ) diff --git a/api/configs/middleware/vdb/tencent_vector_config.py b/api/configs/middleware/vdb/tencent_vector_config.py index 5cec62049e5c3f..340ebfc705d7cc 100644 --- a/api/configs/middleware/vdb/tencent_vector_config.py +++ b/api/configs/middleware/vdb/tencent_vector_config.py @@ -1,6 +1,6 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import BaseModel, Field, NonNegativeInt, PositiveInt class TencentVectorDBConfig(BaseModel): @@ -24,7 +24,7 @@ class TencentVectorDBConfig(BaseModel): ) TENCENT_VECTOR_DB_USERNAME: Optional[str] = Field( - description='Tencent Vector password', + description='Tencent Vector username', default=None, ) @@ -38,7 +38,7 @@ class TencentVectorDBConfig(BaseModel): default=1, ) - TENCENT_VECTOR_DB_REPLICAS: PositiveInt = Field( + TENCENT_VECTOR_DB_REPLICAS: NonNegativeInt = Field( description='Tencent Vector replicas', default=2, ) diff --git a/api/constants/languages.py b/api/constants/languages.py index 37ca583d2e4f0b..efc668d4eec888 100644 --- a/api/constants/languages.py +++ b/api/constants/languages.py @@ -14,7 +14,7 @@ 'vi-VN': 'Asia/Ho_Chi_Minh', 'ro-RO': 'Europe/Bucharest', 'pl-PL': 'Europe/Warsaw', - 'hi-IN': 'Asia/Kolkata' + 'hi-IN': 'Asia/Kolkata', } languages = list(language_timezone_mapping.keys()) diff --git a/api/controllers/console/__init__.py b/api/controllers/console/__init__.py index 8c67fef95f5f4c..bef40bea7eb32e 100644 --- a/api/controllers/console/__init__.py +++ b/api/controllers/console/__init__.py @@ -30,7 +30,7 @@ ) # Import auth controllers -from .auth import activate, data_source_bearer_auth, data_source_oauth, login, oauth +from .auth import activate, data_source_bearer_auth, data_source_oauth, forgot_password, login, oauth # Import billing controllers from .billing import billing diff --git a/api/controllers/console/auth/data_source_oauth.py b/api/controllers/console/auth/data_source_oauth.py index 293ec1c4d341c3..626834724481bd 100644 --- a/api/controllers/console/auth/data_source_oauth.py +++ b/api/controllers/console/auth/data_source_oauth.py @@ -6,6 +6,7 @@ from flask_restful import Resource from werkzeug.exceptions import Forbidden +from configs import dify_config from controllers.console import api from libs.login import login_required from libs.oauth_data_source import NotionOAuth @@ -16,11 +17,11 @@ def get_oauth_providers(): with current_app.app_context(): - notion_oauth = NotionOAuth(client_id=current_app.config.get('NOTION_CLIENT_ID'), - client_secret=current_app.config.get( - 'NOTION_CLIENT_SECRET'), - redirect_uri=current_app.config.get( - 'CONSOLE_API_URL') + '/console/api/oauth/data-source/callback/notion') + if not dify_config.NOTION_CLIENT_ID or not dify_config.NOTION_CLIENT_SECRET: + return {} + notion_oauth = NotionOAuth(client_id=dify_config.NOTION_CLIENT_ID, + client_secret=dify_config.NOTION_CLIENT_SECRET, + redirect_uri=dify_config.CONSOLE_API_URL + '/console/api/oauth/data-source/callback/notion') OAUTH_PROVIDERS = { 'notion': notion_oauth @@ -39,8 +40,10 @@ def get(self, provider: str): print(vars(oauth_provider)) if not oauth_provider: return {'error': 'Invalid provider'}, 400 - if current_app.config.get('NOTION_INTEGRATION_TYPE') == 'internal': - internal_secret = current_app.config.get('NOTION_INTERNAL_SECRET') + if dify_config.NOTION_INTEGRATION_TYPE == 'internal': + internal_secret = dify_config.NOTION_INTERNAL_SECRET + if not internal_secret: + return {'error': 'Internal secret is not set'}, oauth_provider.save_internal_access_token(internal_secret) return { 'data': '' } else: @@ -60,13 +63,13 @@ def get(self, provider: str): if 'code' in request.args: code = request.args.get('code') - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&code={code}') + return redirect(f'{dify_config.CONSOLE_WEB_URL}?type=notion&code={code}') elif 'error' in request.args: error = request.args.get('error') - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error={error}') + return redirect(f'{dify_config.CONSOLE_WEB_URL}?type=notion&error={error}') else: - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error=Access denied') + return redirect(f'{dify_config.CONSOLE_WEB_URL}?type=notion&error=Access denied') class OAuthDataSourceBinding(Resource): diff --git a/api/controllers/console/auth/error.py b/api/controllers/console/auth/error.py index c55ff8707d224f..53dab3298fbff3 100644 --- a/api/controllers/console/auth/error.py +++ b/api/controllers/console/auth/error.py @@ -5,3 +5,28 @@ class ApiKeyAuthFailedError(BaseHTTPException): error_code = 'auth_failed' description = "{message}" code = 500 + + +class InvalidEmailError(BaseHTTPException): + error_code = 'invalid_email' + description = "The email address is not valid." + code = 400 + + +class PasswordMismatchError(BaseHTTPException): + error_code = 'password_mismatch' + description = "The passwords do not match." + code = 400 + + +class InvalidTokenError(BaseHTTPException): + error_code = 'invalid_or_expired_token' + description = "The token is invalid or has expired." + code = 400 + + +class PasswordResetRateLimitExceededError(BaseHTTPException): + error_code = 'password_reset_rate_limit_exceeded' + description = "Password reset rate limit exceeded. Try again later." + code = 429 + diff --git a/api/controllers/console/auth/forgot_password.py b/api/controllers/console/auth/forgot_password.py new file mode 100644 index 00000000000000..d78be770abd094 --- /dev/null +++ b/api/controllers/console/auth/forgot_password.py @@ -0,0 +1,107 @@ +import base64 +import logging +import secrets + +from flask_restful import Resource, reqparse + +from controllers.console import api +from controllers.console.auth.error import ( + InvalidEmailError, + InvalidTokenError, + PasswordMismatchError, + PasswordResetRateLimitExceededError, +) +from controllers.console.setup import setup_required +from extensions.ext_database import db +from libs.helper import email as email_validate +from libs.password import hash_password, valid_password +from models.account import Account +from services.account_service import AccountService +from services.errors.account import RateLimitExceededError + + +class ForgotPasswordSendEmailApi(Resource): + + @setup_required + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('email', type=str, required=True, location='json') + args = parser.parse_args() + + email = args['email'] + + if not email_validate(email): + raise InvalidEmailError() + + account = Account.query.filter_by(email=email).first() + + if account: + try: + AccountService.send_reset_password_email(account=account) + except RateLimitExceededError: + logging.warning(f"Rate limit exceeded for email: {account.email}") + raise PasswordResetRateLimitExceededError() + else: + # Return success to avoid revealing email registration status + logging.warning(f"Attempt to reset password for unregistered email: {email}") + + return {"result": "success"} + + +class ForgotPasswordCheckApi(Resource): + + @setup_required + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('token', type=str, required=True, nullable=False, location='json') + args = parser.parse_args() + token = args['token'] + + reset_data = AccountService.get_reset_password_data(token) + + if reset_data is None: + return {'is_valid': False, 'email': None} + return {'is_valid': True, 'email': reset_data.get('email')} + + +class ForgotPasswordResetApi(Resource): + + @setup_required + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('token', type=str, required=True, nullable=False, location='json') + parser.add_argument('new_password', type=valid_password, required=True, nullable=False, location='json') + parser.add_argument('password_confirm', type=valid_password, required=True, nullable=False, location='json') + args = parser.parse_args() + + new_password = args['new_password'] + password_confirm = args['password_confirm'] + + if str(new_password).strip() != str(password_confirm).strip(): + raise PasswordMismatchError() + + token = args['token'] + reset_data = AccountService.get_reset_password_data(token) + + if reset_data is None: + raise InvalidTokenError() + + AccountService.revoke_reset_password_token(token) + + salt = secrets.token_bytes(16) + base64_salt = base64.b64encode(salt).decode() + + password_hashed = hash_password(new_password, salt) + base64_password_hashed = base64.b64encode(password_hashed).decode() + + account = Account.query.filter_by(email=reset_data.get('email')).first() + account.password = base64_password_hashed + account.password_salt = base64_salt + db.session.commit() + + return {'result': 'success'} + + +api.add_resource(ForgotPasswordSendEmailApi, '/forgot-password') +api.add_resource(ForgotPasswordCheckApi, '/forgot-password/validity') +api.add_resource(ForgotPasswordResetApi, '/forgot-password/resets') diff --git a/api/controllers/console/auth/login.py b/api/controllers/console/auth/login.py index 67d6dc8e95f718..3a0e5ea94dcc09 100644 --- a/api/controllers/console/auth/login.py +++ b/api/controllers/console/auth/login.py @@ -1,7 +1,7 @@ from typing import cast import flask_login -from flask import current_app, request +from flask import request from flask_restful import Resource, reqparse import services @@ -56,14 +56,14 @@ def get(self): class ResetPasswordApi(Resource): @setup_required def get(self): - parser = reqparse.RequestParser() - parser.add_argument('email', type=email, required=True, location='json') - args = parser.parse_args() + # parser = reqparse.RequestParser() + # parser.add_argument('email', type=email, required=True, location='json') + # args = parser.parse_args() # import mailchimp_transactional as MailchimpTransactional # from mailchimp_transactional.api_client import ApiClientError - account = {'email': args['email']} + # account = {'email': args['email']} # account = AccountService.get_by_email(args['email']) # if account is None: # raise ValueError('Email not found') @@ -71,22 +71,22 @@ def get(self): # AccountService.update_password(account, new_password) # todo: Send email - MAILCHIMP_API_KEY = current_app.config['MAILCHIMP_TRANSACTIONAL_API_KEY'] + # MAILCHIMP_API_KEY = current_app.config['MAILCHIMP_TRANSACTIONAL_API_KEY'] # mailchimp = MailchimpTransactional(MAILCHIMP_API_KEY) - message = { - 'from_email': 'noreply@example.com', - 'to': [{'email': account.email}], - 'subject': 'Reset your Dify password', - 'html': """ -

Dear User,

-

The Dify team has generated a new password for you, details as follows:

-

{new_password}

-

Please change your password to log in as soon as possible.

-

Regards,

-

The Dify Team

- """ - } + # message = { + # 'from_email': 'noreply@example.com', + # 'to': [{'email': account['email']}], + # 'subject': 'Reset your Dify password', + # 'html': """ + #

Dear User,

+ #

The Dify team has generated a new password for you, details as follows:

+ #

{new_password}

+ #

Please change your password to log in as soon as possible.

+ #

Regards,

+ #

The Dify Team

+ # """ + # } # response = mailchimp.messages.send({ # 'message': message, diff --git a/api/controllers/console/auth/oauth.py b/api/controllers/console/auth/oauth.py index 2e4a627e066033..4a651bfe7b009e 100644 --- a/api/controllers/console/auth/oauth.py +++ b/api/controllers/console/auth/oauth.py @@ -6,6 +6,7 @@ from flask import current_app, redirect, request from flask_restful import Resource +from configs import dify_config from constants.languages import languages from extensions.ext_database import db from libs.helper import get_remote_ip @@ -18,22 +19,24 @@ def get_oauth_providers(): with current_app.app_context(): - github_oauth = GitHubOAuth(client_id=current_app.config.get('GITHUB_CLIENT_ID'), - client_secret=current_app.config.get( - 'GITHUB_CLIENT_SECRET'), - redirect_uri=current_app.config.get( - 'CONSOLE_API_URL') + '/console/api/oauth/authorize/github') - - google_oauth = GoogleOAuth(client_id=current_app.config.get('GOOGLE_CLIENT_ID'), - client_secret=current_app.config.get( - 'GOOGLE_CLIENT_SECRET'), - redirect_uri=current_app.config.get( - 'CONSOLE_API_URL') + '/console/api/oauth/authorize/google') - - OAUTH_PROVIDERS = { - 'github': github_oauth, - 'google': google_oauth - } + if not dify_config.GITHUB_CLIENT_ID or not dify_config.GITHUB_CLIENT_SECRET: + github_oauth = None + else: + github_oauth = GitHubOAuth( + client_id=dify_config.GITHUB_CLIENT_ID, + client_secret=dify_config.GITHUB_CLIENT_SECRET, + redirect_uri=dify_config.CONSOLE_API_URL + '/console/api/oauth/authorize/github', + ) + if not dify_config.GOOGLE_CLIENT_ID or not dify_config.GOOGLE_CLIENT_SECRET: + google_oauth = None + else: + google_oauth = GoogleOAuth( + client_id=dify_config.GOOGLE_CLIENT_ID, + client_secret=dify_config.GOOGLE_CLIENT_SECRET, + redirect_uri=dify_config.CONSOLE_API_URL + '/console/api/oauth/authorize/google', + ) + + OAUTH_PROVIDERS = {'github': github_oauth, 'google': google_oauth} return OAUTH_PROVIDERS @@ -63,8 +66,7 @@ def get(self, provider: str): token = oauth_provider.get_access_token(code) user_info = oauth_provider.get_user_info(token) except requests.exceptions.HTTPError as e: - logging.exception( - f"An error occurred during the OAuth process with {provider}: {e.response.text}") + logging.exception(f'An error occurred during the OAuth process with {provider}: {e.response.text}') return {'error': 'OAuth process failed'}, 400 account = _generate_account(provider, user_info) @@ -81,7 +83,7 @@ def get(self, provider: str): token = AccountService.login(account, ip_address=get_remote_ip(request)) - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?console_token={token}') + return redirect(f'{dify_config.CONSOLE_WEB_URL}?console_token={token}') def _get_account_by_openid_or_email(provider: str, user_info: OAuthUserInfo) -> Optional[Account]: @@ -101,11 +103,7 @@ def _generate_account(provider: str, user_info: OAuthUserInfo): # Create account account_name = user_info.name if user_info.name else 'Dify' account = RegisterService.register( - email=user_info.email, - name=account_name, - password=None, - open_id=user_info.id, - provider=provider + email=user_info.email, name=account_name, password=None, open_id=user_info.id, provider=provider ) # Set interface language diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index d75e18e25e7f48..8e4278ed2940ff 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -226,9 +226,12 @@ def patch(self, dataset_id): raise NotFound("Dataset not found.") result_data = marshal(dataset, dataset_detail_fields) + tenant_id = current_user.current_tenant_id if data.get('partial_member_list') and data.get('permission') == 'partial_members': - DatasetPermissionService.update_partial_member_list(dataset_id_str, data.get('partial_member_list')) + DatasetPermissionService.update_partial_member_list( + tenant_id, dataset_id_str, data.get('partial_member_list') + ) else: DatasetPermissionService.clear_partial_member_list(dataset_id_str) diff --git a/api/controllers/console/workspace/account.py b/api/controllers/console/workspace/account.py index 198409bba78f7b..0b5c84c2a3d24d 100644 --- a/api/controllers/console/workspace/account.py +++ b/api/controllers/console/workspace/account.py @@ -245,6 +245,8 @@ def get(self): return {'data': integrate_data} + + # Register API resources api.add_resource(AccountInitApi, '/account/init') api.add_resource(AccountProfileApi, '/account/profile') diff --git a/api/core/app/apps/workflow/app_generator.py b/api/core/app/apps/workflow/app_generator.py index 3eb0bcf3dafe7b..0f547ca16427c1 100644 --- a/api/core/app/apps/workflow/app_generator.py +++ b/api/core/app/apps/workflow/app_generator.py @@ -94,7 +94,6 @@ def generate( application_generate_entity=application_generate_entity, invoke_from=invoke_from, stream=stream, - call_depth=call_depth, ) def _generate( @@ -104,7 +103,6 @@ def _generate( application_generate_entity: WorkflowAppGenerateEntity, invoke_from: InvokeFrom, stream: bool = True, - call_depth: int = 0 ) -> Union[dict, Generator[dict, None, None]]: """ Generate App response. @@ -166,10 +164,10 @@ def single_iteration_generate(self, app_model: App, """ if not node_id: raise ValueError('node_id is required') - + if args.get('inputs') is None: raise ValueError('inputs is required') - + extras = { "auto_generate_conversation_name": False } diff --git a/api/core/extension/api_based_extension_requestor.py b/api/core/extension/api_based_extension_requestor.py index 40e60687b2b11d..4db7a999736c5b 100644 --- a/api/core/extension/api_based_extension_requestor.py +++ b/api/core/extension/api_based_extension_requestor.py @@ -1,7 +1,6 @@ -import os - import requests +from configs import dify_config from models.api_based_extension import APIBasedExtensionPoint @@ -31,10 +30,10 @@ def request(self, point: APIBasedExtensionPoint, params: dict) -> dict: try: # proxy support for security proxies = None - if os.environ.get("SSRF_PROXY_HTTP_URL") and os.environ.get("SSRF_PROXY_HTTPS_URL"): + if dify_config.SSRF_PROXY_HTTP_URL and dify_config.SSRF_PROXY_HTTPS_URL: proxies = { - 'http': os.environ.get("SSRF_PROXY_HTTP_URL"), - 'https': os.environ.get("SSRF_PROXY_HTTPS_URL"), + 'http': dify_config.SSRF_PROXY_HTTP_URL, + 'https': dify_config.SSRF_PROXY_HTTPS_URL, } response = requests.request( diff --git a/api/core/file/message_file_parser.py b/api/core/file/message_file_parser.py index 52498eb8711f16..842b539ad1b03b 100644 --- a/api/core/file/message_file_parser.py +++ b/api/core/file/message_file_parser.py @@ -186,7 +186,7 @@ def _check_image_remote_url(self, url): } response = requests.head(url, headers=headers, allow_redirects=True) - if response.status_code == 200: + if response.status_code in {200, 304}: return True, "" else: return False, "URL does not exist." diff --git a/api/core/helper/code_executor/code_executor.py b/api/core/helper/code_executor/code_executor.py index ec731693b6af82..f094f7d79b58e0 100644 --- a/api/core/helper/code_executor/code_executor.py +++ b/api/core/helper/code_executor/code_executor.py @@ -1,5 +1,4 @@ import logging -import os import time from enum import Enum from threading import Lock @@ -9,6 +8,7 @@ from pydantic import BaseModel from yarl import URL +from configs import dify_config from core.helper.code_executor.entities import CodeDependency from core.helper.code_executor.javascript.javascript_transformer import NodeJsTemplateTransformer from core.helper.code_executor.jinja2.jinja2_transformer import Jinja2TemplateTransformer @@ -18,8 +18,8 @@ logger = logging.getLogger(__name__) # Code Executor -CODE_EXECUTION_ENDPOINT = os.environ.get('CODE_EXECUTION_ENDPOINT', 'http://sandbox:8194') -CODE_EXECUTION_API_KEY = os.environ.get('CODE_EXECUTION_API_KEY', 'dify-sandbox') +CODE_EXECUTION_ENDPOINT = dify_config.CODE_EXECUTION_ENDPOINT +CODE_EXECUTION_API_KEY = dify_config.CODE_EXECUTION_API_KEY CODE_EXECUTION_TIMEOUT= (10, 60) diff --git a/api/core/memory/token_buffer_memory.py b/api/core/memory/token_buffer_memory.py index 4f4f5045f52221..21f1965e93adac 100644 --- a/api/core/memory/token_buffer_memory.py +++ b/api/core/memory/token_buffer_memory.py @@ -12,7 +12,8 @@ UserPromptMessage, ) from extensions.ext_database import db -from models.model import AppMode, Conversation, Message +from models.model import AppMode, Conversation, Message, MessageFile +from models.workflow import WorkflowRun class TokenBufferMemory: @@ -30,33 +31,46 @@ def get_history_prompt_messages(self, max_token_limit: int = 2000, app_record = self.conversation.app # fetch limited messages, and return reversed - query = db.session.query(Message).filter( + query = db.session.query( + Message.id, + Message.query, + Message.answer, + Message.created_at, + Message.workflow_run_id + ).filter( Message.conversation_id == self.conversation.id, Message.answer != '' ).order_by(Message.created_at.desc()) if message_limit and message_limit > 0: - messages = query.limit(message_limit).all() + message_limit = message_limit if message_limit <= 500 else 500 else: - messages = query.all() + message_limit = 500 + + messages = query.limit(message_limit).all() messages = list(reversed(messages)) message_file_parser = MessageFileParser( tenant_id=app_record.tenant_id, app_id=app_record.id ) - prompt_messages = [] for message in messages: - files = message.message_files + files = db.session.query(MessageFile).filter(MessageFile.message_id == message.id).all() if files: + file_extra_config = None if self.conversation.mode not in [AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value]: - file_extra_config = FileUploadConfigManager.convert(message.app_model_config.to_dict()) + file_extra_config = FileUploadConfigManager.convert(self.conversation.model_config) else: - file_extra_config = FileUploadConfigManager.convert( - message.workflow_run.workflow.features_dict, - is_vision=False - ) + if message.workflow_run_id: + workflow_run = (db.session.query(WorkflowRun) + .filter(WorkflowRun.id == message.workflow_run_id).first()) + + if workflow_run: + file_extra_config = FileUploadConfigManager.convert( + workflow_run.workflow.features_dict, + is_vision=False + ) if file_extra_config: file_objs = message_file_parser.transform_message_files( @@ -136,4 +150,4 @@ def get_history_prompt_text(self, human_prefix: str = "Human", message = f"{role}: {m.content}" string_messages.append(message) - return "\n".join(string_messages) \ No newline at end of file + return "\n".join(string_messages) diff --git a/api/core/model_runtime/model_providers/bedrock/llm/llm.py b/api/core/model_runtime/model_providers/bedrock/llm/llm.py index f3ea705e19beb4..efb8c395fab056 100644 --- a/api/core/model_runtime/model_providers/bedrock/llm/llm.py +++ b/api/core/model_runtime/model_providers/bedrock/llm/llm.py @@ -554,7 +554,10 @@ def _convert_one_message_to_text(self, message: PromptMessage, model_prefix: str content = message.content if isinstance(message, UserPromptMessage): - message_text = f"{human_prompt_prefix} {content} {human_prompt_postfix}" + body = content + if (isinstance(content, list)): + body = "".join([c.data for c in content if c.type == PromptMessageContentType.TEXT]) + message_text = f"{human_prompt_prefix} {body} {human_prompt_postfix}" elif isinstance(message, AssistantPromptMessage): message_text = f"{ai_prompt} {content}" elif isinstance(message, SystemPromptMessage): diff --git a/api/core/model_runtime/model_providers/volcengine_maas/llm/models.py b/api/core/model_runtime/model_providers/volcengine_maas/llm/models.py index 3a793cd6a8dfdf..3e5938f3b494af 100644 --- a/api/core/model_runtime/model_providers/volcengine_maas/llm/models.py +++ b/api/core/model_runtime/model_providers/volcengine_maas/llm/models.py @@ -111,5 +111,71 @@ 'mode': 'chat', }, 'features': [], + }, + 'Moonshot-v1-8k': { + 'req_params': { + 'max_prompt_tokens': 8192, + 'max_new_tokens': 4096, + }, + 'model_properties': { + 'context_size': 8192, + 'mode': 'chat', + }, + 'features': [], + }, + 'Moonshot-v1-32k': { + 'req_params': { + 'max_prompt_tokens': 32768, + 'max_new_tokens': 16384, + }, + 'model_properties': { + 'context_size': 32768, + 'mode': 'chat', + }, + 'features': [], + }, + 'Moonshot-v1-128k': { + 'req_params': { + 'max_prompt_tokens': 131072, + 'max_new_tokens': 65536, + }, + 'model_properties': { + 'context_size': 131072, + 'mode': 'chat', + }, + 'features': [], + }, + 'GLM3-130B': { + 'req_params': { + 'max_prompt_tokens': 8192, + 'max_new_tokens': 4096, + }, + 'model_properties': { + 'context_size': 8192, + 'mode': 'chat', + }, + 'features': [], + }, + 'GLM3-130B-Fin': { + 'req_params': { + 'max_prompt_tokens': 8192, + 'max_new_tokens': 4096, + }, + 'model_properties': { + 'context_size': 8192, + 'mode': 'chat', + }, + 'features': [], + }, + 'Mistral-7B': { + 'req_params': { + 'max_prompt_tokens': 8192, + 'max_new_tokens': 2048, + }, + 'model_properties': { + 'context_size': 8192, + 'mode': 'chat', + }, + 'features': [], } } diff --git a/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml b/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml index 4d468969b74edd..a00c1b79944b5a 100644 --- a/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml +++ b/api/core/model_runtime/model_providers/volcengine_maas/volcengine_maas.yaml @@ -120,12 +120,6 @@ model_credential_schema: show_on: - variable: __model_type value: llm - - label: - en_US: Skylark2-pro-4k - value: Skylark2-pro-4k - show_on: - - variable: __model_type - value: llm - label: en_US: Llama3-8B value: Llama3-8B @@ -138,6 +132,42 @@ model_credential_schema: show_on: - variable: __model_type value: llm + - label: + en_US: Moonshot-v1-8k + value: Moonshot-v1-8k + show_on: + - variable: __model_type + value: llm + - label: + en_US: Moonshot-v1-32k + value: Moonshot-v1-32k + show_on: + - variable: __model_type + value: llm + - label: + en_US: Moonshot-v1-128k + value: Moonshot-v1-128k + show_on: + - variable: __model_type + value: llm + - label: + en_US: GLM3-130B + value: GLM3-130B + show_on: + - variable: __model_type + value: llm + - label: + en_US: GLM3-130B-Fin + value: GLM3-130B-Fin + show_on: + - variable: __model_type + value: llm + - label: + en_US: Mistral-7B + value: Mistral-7B + show_on: + - variable: __model_type + value: llm - label: en_US: Doubao-embedding value: Doubao-embedding @@ -181,7 +211,7 @@ model_credential_schema: zh_Hans: 模型上下文长度 en_US: Model Context Size type: text-input - default: '4096' + default: "4096" placeholder: zh_Hans: 输入您的模型上下文长度 en_US: Enter your Model Context Size @@ -195,7 +225,7 @@ model_credential_schema: label: zh_Hans: 最大 token 上限 en_US: Upper Bound for Max Tokens - default: '4096' + default: "4096" type: text-input placeholder: zh_Hans: 输入您的模型最大 token 上限 diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/_client.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/_client.py index 29b1746351194a..6588d1dd684900 100644 --- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/_client.py +++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/_client.py @@ -29,10 +29,8 @@ def __init__( http_client: httpx.Client | None = None, custom_headers: Mapping[str, str] | None = None ) -> None: - # if api_key is None: - # api_key = os.environ.get("ZHIPUAI_API_KEY") if api_key is None: - raise ZhipuAIError("未提供api_key,请通过参数或环境变量提供") + raise ZhipuAIError("No api_key provided, please provide it through parameters or environment variables") self.api_key = api_key if base_url is None: diff --git a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py index e13d2b023316a2..924d00912327c4 100644 --- a/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py +++ b/api/core/model_runtime/model_providers/zhipuai/zhipuai_sdk/core/_http_client.py @@ -7,6 +7,8 @@ import httpx import pydantic from httpx import URL, Timeout +from tenacity import retry +from tenacity.stop import stop_after_attempt from . import _errors from ._base_type import NOT_GIVEN, Body, Data, Headers, NotGiven, Query, RequestFiles, ResponseT @@ -221,6 +223,7 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): self.close() + @retry(stop=stop_after_attempt(ZHIPUAI_DEFAULT_MAX_RETRIES)) def request( self, *, diff --git a/api/core/model_runtime/utils/_compat.py b/api/core/model_runtime/utils/_compat.py deleted file mode 100644 index 5c34152751b035..00000000000000 --- a/api/core/model_runtime/utils/_compat.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Any, Literal - -from pydantic import BaseModel -from pydantic.version import VERSION as PYDANTIC_VERSION - -PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.") - -if PYDANTIC_V2: - from pydantic_core import Url as Url - - def _model_dump( - model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any - ) -> Any: - return model.model_dump(mode=mode, **kwargs) -else: - from pydantic import AnyUrl as Url # noqa: F401 - - def _model_dump( - model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any - ) -> Any: - return model.dict(**kwargs) diff --git a/api/core/model_runtime/utils/encoders.py b/api/core/model_runtime/utils/encoders.py index e41d49216c4f3c..5078f00bfa26d0 100644 --- a/api/core/model_runtime/utils/encoders.py +++ b/api/core/model_runtime/utils/encoders.py @@ -8,16 +8,20 @@ from pathlib import Path, PurePath from re import Pattern from types import GeneratorType -from typing import Any, Optional, Union +from typing import Any, Literal, Optional, Union from uuid import UUID from pydantic import BaseModel from pydantic.networks import AnyUrl, NameEmail from pydantic.types import SecretBytes, SecretStr +from pydantic_core import Url from pydantic_extra_types.color import Color -from ._compat import PYDANTIC_V2, Url, _model_dump +def _model_dump( + model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any +) -> Any: + return model.model_dump(mode=mode, **kwargs) # Taken from Pydantic v1 as is def isoformat(o: Union[datetime.date, datetime.time]) -> str: @@ -109,12 +113,6 @@ def jsonable_encoder( if isinstance(obj, encoder_type): return encoder_instance(obj) if isinstance(obj, BaseModel): - # TODO: remove when deprecating Pydantic v1 - encoders: dict[Any, Any] = {} - if not PYDANTIC_V2: - encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined] - if custom_encoder: - encoders.update(custom_encoder) obj_dict = _model_dump( obj, mode="json", @@ -131,8 +129,6 @@ def jsonable_encoder( obj_dict, exclude_none=exclude_none, exclude_defaults=exclude_defaults, - # TODO: remove when deprecating Pydantic v1 - custom_encoder=encoders, sqlalchemy_safe=sqlalchemy_safe, ) if dataclasses.is_dataclass(obj): diff --git a/api/core/ops/entities/config_entity.py b/api/core/ops/entities/config_entity.py index fd1310a24e03dc..221e6239ab9302 100644 --- a/api/core/ops/entities/config_entity.py +++ b/api/core/ops/entities/config_entity.py @@ -27,7 +27,7 @@ class LangfuseConfig(BaseTracingConfig): def set_value(cls, v, info: ValidationInfo): if v is None or v == "": v = 'https://api.langfuse.com' - if not v.startswith('https://') or not v.startswith('http://'): + if not v.startswith('https://') and not v.startswith('http://'): raise ValueError('host must start with https:// or http://') return v diff --git a/api/core/ops/langfuse_trace/langfuse_trace.py b/api/core/ops/langfuse_trace/langfuse_trace.py index 0441475921b83d..cb863964201cd5 100644 --- a/api/core/ops/langfuse_trace/langfuse_trace.py +++ b/api/core/ops/langfuse_trace/langfuse_trace.py @@ -107,7 +107,20 @@ def workflow_trace(self, trace_info: WorkflowTraceInfo): # through workflow_run_id get all_nodes_execution workflow_nodes_executions = ( - db.session.query(WorkflowNodeExecution) + db.session.query( + WorkflowNodeExecution.id, + WorkflowNodeExecution.tenant_id, + WorkflowNodeExecution.app_id, + WorkflowNodeExecution.title, + WorkflowNodeExecution.node_type, + WorkflowNodeExecution.status, + WorkflowNodeExecution.inputs, + WorkflowNodeExecution.outputs, + WorkflowNodeExecution.created_at, + WorkflowNodeExecution.elapsed_time, + WorkflowNodeExecution.process_data, + WorkflowNodeExecution.execution_metadata, + ) .filter(WorkflowNodeExecution.workflow_run_id == trace_info.workflow_run_id) .all() ) diff --git a/api/core/ops/langsmith_trace/langsmith_trace.py b/api/core/ops/langsmith_trace/langsmith_trace.py index 93d74cc9e34b09..0ce91db335cd94 100644 --- a/api/core/ops/langsmith_trace/langsmith_trace.py +++ b/api/core/ops/langsmith_trace/langsmith_trace.py @@ -100,7 +100,20 @@ def workflow_trace(self, trace_info: WorkflowTraceInfo): # through workflow_run_id get all_nodes_execution workflow_nodes_executions = ( - db.session.query(WorkflowNodeExecution) + db.session.query( + WorkflowNodeExecution.id, + WorkflowNodeExecution.tenant_id, + WorkflowNodeExecution.app_id, + WorkflowNodeExecution.title, + WorkflowNodeExecution.node_type, + WorkflowNodeExecution.status, + WorkflowNodeExecution.inputs, + WorkflowNodeExecution.outputs, + WorkflowNodeExecution.created_at, + WorkflowNodeExecution.elapsed_time, + WorkflowNodeExecution.process_data, + WorkflowNodeExecution.execution_metadata, + ) .filter(WorkflowNodeExecution.workflow_run_id == trace_info.workflow_run_id) .all() ) diff --git a/api/core/rag/extractor/notion_extractor.py b/api/core/rag/extractor/notion_extractor.py index 4ec0b4fc3861c7..7c6101010edcb7 100644 --- a/api/core/rag/extractor/notion_extractor.py +++ b/api/core/rag/extractor/notion_extractor.py @@ -140,11 +140,10 @@ def _get_notion_database_data( def _get_notion_block_data(self, page_id: str) -> list[str]: result_lines_arr = [] - cur_block_id = page_id + start_cursor = None + block_url = BLOCK_CHILD_URL_TMPL.format(block_id=page_id) while True: - block_url = BLOCK_CHILD_URL_TMPL.format(block_id=cur_block_id) - query_dict: dict[str, Any] = {} - + query_dict: dict[str, Any] = {} if not start_cursor else {'start_cursor': start_cursor} res = requests.request( "GET", block_url, @@ -153,7 +152,7 @@ def _get_notion_block_data(self, page_id: str) -> list[str]: "Content-Type": "application/json", "Notion-Version": "2022-06-28", }, - json=query_dict + params=query_dict ) data = res.json() for result in data["results"]: @@ -191,16 +190,16 @@ def _get_notion_block_data(self, page_id: str) -> list[str]: if data["next_cursor"] is None: break else: - cur_block_id = data["next_cursor"] + start_cursor = data["next_cursor"] return result_lines_arr def _read_block(self, block_id: str, num_tabs: int = 0) -> str: """Read a block.""" result_lines_arr = [] - cur_block_id = block_id + start_cursor = None + block_url = BLOCK_CHILD_URL_TMPL.format(block_id=block_id) while True: - block_url = BLOCK_CHILD_URL_TMPL.format(block_id=cur_block_id) - query_dict: dict[str, Any] = {} + query_dict: dict[str, Any] = {} if not start_cursor else {'start_cursor': start_cursor} res = requests.request( "GET", @@ -210,7 +209,7 @@ def _read_block(self, block_id: str, num_tabs: int = 0) -> str: "Content-Type": "application/json", "Notion-Version": "2022-06-28", }, - json=query_dict + params=query_dict ) data = res.json() if 'results' not in data or data["results"] is None: @@ -249,7 +248,7 @@ def _read_block(self, block_id: str, num_tabs: int = 0) -> str: if data["next_cursor"] is None: break else: - cur_block_id = data["next_cursor"] + start_cursor = data["next_cursor"] result_lines = "\n".join(result_lines_arr) return result_lines @@ -258,10 +257,10 @@ def _read_table_rows(self, block_id: str) -> str: """Read table rows.""" done = False result_lines_arr = [] - cur_block_id = block_id + start_cursor = None + block_url = BLOCK_CHILD_URL_TMPL.format(block_id=block_id) while not done: - block_url = BLOCK_CHILD_URL_TMPL.format(block_id=cur_block_id) - query_dict: dict[str, Any] = {} + query_dict: dict[str, Any] = {} if not start_cursor else {'start_cursor': start_cursor} res = requests.request( "GET", @@ -271,7 +270,7 @@ def _read_table_rows(self, block_id: str) -> str: "Content-Type": "application/json", "Notion-Version": "2022-06-28", }, - json=query_dict + params=query_dict ) data = res.json() # get table headers text @@ -300,7 +299,7 @@ def _read_table_rows(self, block_id: str) -> str: done = True break else: - cur_block_id = data["next_cursor"] + start_cursor = data["next_cursor"] result_lines = "\n".join(result_lines_arr) return result_lines diff --git a/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.yaml b/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.yaml index 1ca16e660f71ec..1913eed1d1fa3f 100644 --- a/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.yaml +++ b/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_ai.yaml @@ -31,6 +31,12 @@ parameters: - value: claude-3-haiku label: en_US: Claude 3 + - value: llama-3-70b + label: + en_US: Llama 3 + - value: mixtral-8x7b + label: + en_US: Mixtral default: gpt-3.5 label: en_US: Choose Model diff --git a/api/core/tools/provider/builtin/firecrawl/firecrawl.yaml b/api/core/tools/provider/builtin/firecrawl/firecrawl.yaml index edd28f7d22b88e..613a0e4679f165 100644 --- a/api/core/tools/provider/builtin/firecrawl/firecrawl.yaml +++ b/api/core/tools/provider/builtin/firecrawl/firecrawl.yaml @@ -6,7 +6,7 @@ identity: zh_CN: Firecrawl description: en_US: Firecrawl API integration for web crawling and scraping. - zh_CN: Firecrawl API 集成,用于网页爬取和数据抓取。 + zh_Hans: Firecrawl API 集成,用于网页爬取和数据抓取。 icon: icon.svg tags: - search @@ -17,20 +17,22 @@ credentials_for_provider: required: true label: en_US: Firecrawl API Key - zh_CN: Firecrawl API 密钥 + zh_Hans: Firecrawl API 密钥 placeholder: en_US: Please input your Firecrawl API key - zh_CN: 请输入您的 Firecrawl API 密钥 + zh_Hans: 请输入您的 Firecrawl API 密钥,如果是自托管版本,可以随意填写密钥 help: - en_US: Get your Firecrawl API key from your Firecrawl account settings. - zh_CN: 从您的 Firecrawl 账户设置中获取 Firecrawl API 密钥。 + en_US: Get your Firecrawl API key from your Firecrawl account settings.If you are using a self-hosted version, you may enter any key at your convenience. + zh_Hans: 从您的 Firecrawl 账户设置中获取 Firecrawl API 密钥。如果是自托管版本,可以随意填写密钥。 url: https://www.firecrawl.dev/account base_url: type: text-input required: false label: en_US: Firecrawl server's Base URL + zh_Hans: Firecrawl服务器的API URL pt_BR: Firecrawl server's Base URL placeholder: en_US: https://www.firecrawl.dev + zh_HansL: https://www.firecrawl.dev pt_BR: https://www.firecrawl.dev diff --git a/api/core/tools/provider/builtin/firecrawl/firecrawl_appx.py b/api/core/tools/provider/builtin/firecrawl/firecrawl_appx.py index a28f479170a267..23cb65965229b5 100644 --- a/api/core/tools/provider/builtin/firecrawl/firecrawl_appx.py +++ b/api/core/tools/provider/builtin/firecrawl/firecrawl_appx.py @@ -1,98 +1,93 @@ import time +from collections.abc import Mapping +from typing import Any import requests +from requests.exceptions import HTTPError class FirecrawlApp: - def __init__(self, api_key=None, base_url=None): + def __init__(self, api_key: str | None = None, base_url: str | None = None): self.api_key = api_key self.base_url = base_url or 'https://api.firecrawl.dev' - if self.api_key is None and self.base_url == 'https://api.firecrawl.dev': - raise ValueError('No API key provided') + if not self.api_key: + raise ValueError("API key is required") - def scrape_url(self, url, params=None) -> dict: + def _prepare_headers(self, idempotency_key: str | None = None): headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {self.api_key}' } - json_data = {'url': url} - if params: - json_data.update(params) - response = requests.post( - f'{self.base_url}/v0/scrape', - headers=headers, - json=json_data - ) - if response.status_code == 200: - response = response.json() - if response['success'] == True: - return response['data'] - else: - raise Exception(f'Failed to scrape URL. Error: {response["error"]}') + if idempotency_key: + headers['Idempotency-Key'] = idempotency_key + return headers - elif response.status_code in [402, 409, 500]: - error_message = response.json().get('error', 'Unknown error occurred') - raise Exception(f'Failed to scrape URL. Status code: {response.status_code}. Error: {error_message}') - else: - raise Exception(f'Failed to scrape URL. Status code: {response.status_code}') + def _request( + self, + method: str, + url: str, + data: Mapping[str, Any] | None = None, + headers: Mapping[str, str] | None = None, + retries: int = 3, + backoff_factor: float = 0.3, + ) -> Mapping[str, Any] | None: + for i in range(retries): + try: + response = requests.request(method, url, json=data, headers=headers) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + if i < retries - 1: + time.sleep(backoff_factor * (2 ** i)) + else: + raise + return None - def crawl_url(self, url, params=None, wait_until_done=True, timeout=2) -> str: + def scrape_url(self, url: str, **kwargs): + endpoint = f'{self.base_url}/v0/scrape' headers = self._prepare_headers() - json_data = {'url': url} - if params: - json_data.update(params) - response = self._post_request(f'{self.base_url}/v0/crawl', json_data, headers) - if response.status_code == 200: - job_id = response.json().get('jobId') - if wait_until_done: - return self._monitor_job_status(job_id, headers, timeout) - else: - return {'jobId': job_id} - else: - self._handle_error(response, 'start crawl job') + data = {'url': url, **kwargs} + response = self._request('POST', endpoint, data, headers) + if response is None: + raise HTTPError("Failed to scrape URL after multiple retries") + return response - def check_crawl_status(self, job_id) -> dict: + def search(self, query: str, **kwargs): + endpoint = f'{self.base_url}/v0/search' headers = self._prepare_headers() - response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) - if response.status_code == 200: - return response.json() - else: - self._handle_error(response, 'check crawl status') - - def _prepare_headers(self): - return { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {self.api_key}' - } + data = {'query': query, **kwargs} + response = self._request('POST', endpoint, data, headers) + if response is None: + raise HTTPError("Failed to perform search after multiple retries") + return response - def _post_request(self, url, data, headers): - return requests.post(url, headers=headers, json=data) + def crawl_url( + self, url: str, wait: bool = False, poll_interval: int = 5, idempotency_key: str | None = None, **kwargs + ): + endpoint = f'{self.base_url}/v0/crawl' + headers = self._prepare_headers(idempotency_key) + data = {'url': url, **kwargs} + response = self._request('POST', endpoint, data, headers) + if response is None: + raise HTTPError("Failed to initiate crawl after multiple retries") + job_id: str = response['jobId'] + if wait: + return self._monitor_job_status(job_id=job_id, poll_interval=poll_interval) + return job_id - def _get_request(self, url, headers): - return requests.get(url, headers=headers) + def check_crawl_status(self, job_id: str): + endpoint = f'{self.base_url}/v0/crawl/status/{job_id}' + headers = self._prepare_headers() + response = self._request('GET', endpoint, headers=headers) + if response is None: + raise HTTPError(f"Failed to check status for job {job_id} after multiple retries") + return response - def _monitor_job_status(self, job_id, headers, timeout): + def _monitor_job_status(self, job_id: str, poll_interval: int): while True: - status_response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) - if status_response.status_code == 200: - status_data = status_response.json() - if status_data['status'] == 'completed': - if 'data' in status_data: - return status_data['data'] - else: - raise Exception('Crawl job completed but no data was returned') - elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: - if timeout < 2: - timeout = 2 - time.sleep(timeout) # Wait for the specified timeout before checking again - else: - raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') - else: - self._handle_error(status_response, 'check crawl status') - - def _handle_error(self, response, action): - if response.status_code in [402, 409, 500]: - error_message = response.json().get('error', 'Unknown error occurred') - raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') - else: - raise Exception(f'Unexpected error occurred while trying to {action}. Status code: {response.status_code}') + status = self.check_crawl_status(job_id) + if status['status'] == 'completed': + return status + elif status['status'] == 'failed': + raise HTTPError(f'Job {job_id} failed: {status["error"]}') + time.sleep(poll_interval) diff --git a/api/core/tools/provider/builtin/firecrawl/tools/crawl.py b/api/core/tools/provider/builtin/firecrawl/tools/crawl.py index ab3a73dd03a792..b000c1c6ce5cb7 100644 --- a/api/core/tools/provider/builtin/firecrawl/tools/crawl.py +++ b/api/core/tools/provider/builtin/firecrawl/tools/crawl.py @@ -1,3 +1,4 @@ +import json from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage @@ -7,7 +8,6 @@ class CrawlTool(BuiltinTool): def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - # initialize the app object with the api key app = FirecrawlApp(api_key=self.runtime.credentials['firecrawl_api_key'], base_url=self.runtime.credentials['base_url']) options = { @@ -21,29 +21,16 @@ def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolIn } } - # crawl the url crawl_result = app.crawl_url( url=tool_parameters['url'], params=options, - wait_until_done=True, + wait=True ) - - # reformat crawl result - crawl_output = "**Crawl Result**\n\n" - try: - for result in crawl_result: - crawl_output += f"**- Title:** {result.get('metadata', {}).get('title', '')}\n" - crawl_output += f"**- Description:** {result.get('metadata', {}).get('description', '')}\n" - crawl_output += f"**- URL:** {result.get('metadata', {}).get('ogUrl', '')}\n\n" - crawl_output += f"**- Web Content:**\n{result.get('markdown', '')}\n\n" - crawl_output += "---\n\n" - except Exception as e: - crawl_output += f"An error occurred: {str(e)}\n" - crawl_output += f"**- Title:** {result.get('metadata', {}).get('title', '')}\n" - crawl_output += f"**- Description:** {result.get('metadata', {}).get('description','')}\n" - crawl_output += f"**- URL:** {result.get('metadata', {}).get('ogUrl', '')}\n\n" - crawl_output += f"**- Web Content:**\n{result.get('markdown', '')}\n\n" - crawl_output += "---\n\n" - - - return self.create_text_message(crawl_output) \ No newline at end of file + + if not isinstance(crawl_result, str): + crawl_result = json.dumps(crawl_result, ensure_ascii=False, indent=4) + + if not crawl_result: + return self.create_text_message("Crawl request failed.") + + return self.create_text_message(crawl_result) diff --git a/api/core/tools/provider/builtin/firecrawl/tools/scrape.py b/api/core/tools/provider/builtin/firecrawl/tools/scrape.py new file mode 100644 index 00000000000000..3a78dce8d09bff --- /dev/null +++ b/api/core/tools/provider/builtin/firecrawl/tools/scrape.py @@ -0,0 +1,26 @@ +import json +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.firecrawl.firecrawl_appx import FirecrawlApp +from core.tools.tool.builtin_tool import BuiltinTool + + +class ScrapeTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + app = FirecrawlApp(api_key=self.runtime.credentials['firecrawl_api_key'], base_url=self.runtime.credentials['base_url']) + + crawl_result = app.scrape_url( + url=tool_parameters['url'], + wait=True + ) + + if isinstance(crawl_result, dict): + result_message = json.dumps(crawl_result, ensure_ascii=False, indent=4) + else: + result_message = str(crawl_result) + + if not crawl_result: + return self.create_text_message("Scrape request failed.") + + return self.create_text_message(result_message) diff --git a/api/core/tools/provider/builtin/firecrawl/tools/scrape.yaml b/api/core/tools/provider/builtin/firecrawl/tools/scrape.yaml new file mode 100644 index 00000000000000..29aa5991aa8bf4 --- /dev/null +++ b/api/core/tools/provider/builtin/firecrawl/tools/scrape.yaml @@ -0,0 +1,23 @@ +identity: + name: scrape + author: ahasasjeb + label: + en_US: Scrape + zh_Hans: 抓取 +description: + human: + en_US: Extract data from a single URL. + zh_Hans: 从单个URL抓取数据。 + llm: This tool is designed to scrape URL and output the content in Markdown format. +parameters: + - name: url + type: string + required: true + label: + en_US: URL to scrape + zh_Hans: 要抓取的URL + human_description: + en_US: The URL of the website to scrape and extract data from. + zh_Hans: 要抓取并提取数据的网站URL。 + llm_description: The URL of the website that needs to be crawled. This is a required parameter. + form: llm diff --git a/api/core/tools/provider/builtin/firecrawl/tools/search.py b/api/core/tools/provider/builtin/firecrawl/tools/search.py new file mode 100644 index 00000000000000..0b118aa5f18dd2 --- /dev/null +++ b/api/core/tools/provider/builtin/firecrawl/tools/search.py @@ -0,0 +1,26 @@ +import json +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.firecrawl.firecrawl_appx import FirecrawlApp +from core.tools.tool.builtin_tool import BuiltinTool + + +class SearchTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + app = FirecrawlApp(api_key=self.runtime.credentials['firecrawl_api_key'], base_url=self.runtime.credentials['base_url']) + + crawl_result = app.search( + query=tool_parameters['keyword'], + wait=True + ) + + if isinstance(crawl_result, dict): + result_message = json.dumps(crawl_result, ensure_ascii=False, indent=4) + else: + result_message = str(crawl_result) + + if not crawl_result: + return self.create_text_message("Search request failed.") + + return self.create_text_message(result_message) diff --git a/api/core/tools/provider/builtin/firecrawl/tools/search.yaml b/api/core/tools/provider/builtin/firecrawl/tools/search.yaml new file mode 100644 index 00000000000000..b1513c914ec31f --- /dev/null +++ b/api/core/tools/provider/builtin/firecrawl/tools/search.yaml @@ -0,0 +1,23 @@ +identity: + name: search + author: ahasasjeb + label: + en_US: Search + zh_Hans: 搜索 +description: + human: + en_US: Search, and output in Markdown format + zh_Hans: 搜索,并且以Markdown格式输出 + llm: This tool can perform online searches and convert the results to Markdown format. +parameters: + - name: keyword + type: string + required: true + label: + en_US: keyword + zh_Hans: 关键词 + human_description: + en_US: Input keywords to use Firecrawl API for search. + zh_Hans: 输入关键词即可使用Firecrawl API进行搜索。 + llm_description: Efficiently extract keywords from user text. + form: llm diff --git a/api/core/tools/tool/api_tool.py b/api/core/tools/tool/api_tool.py index 0448a5df0c6e9c..c8b683f9ef14ac 100644 --- a/api/core/tools/tool/api_tool.py +++ b/api/core/tools/tool/api_tool.py @@ -249,9 +249,12 @@ def _convert_body_property_type(self, property: dict[str, Any], value: Any) -> A elif property['type'] == 'null': if value is None: return None - elif property['type'] == 'object': + elif property['type'] == 'object' or property['type'] == 'array': if isinstance(value, str): try: + # an array str like '[1,2]' also can convert to list [1,2] through json.loads + # json not support single quote, but we can support it + value = value.replace("'", '"') return json.loads(value) except ValueError: return value diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py index 9fcadbd3913335..e30a905cbcf309 100644 --- a/api/core/tools/tool_manager.py +++ b/api/core/tools/tool_manager.py @@ -154,7 +154,7 @@ def get_tool_runtime(cls, provider_type: str, 'invoke_from': invoke_from, 'tool_invoke_from': tool_invoke_from, }) - + elif provider_type == 'api': if tenant_id is None: raise ValueError('tenant id is required for api provider') @@ -201,7 +201,7 @@ def _init_runtime_parameter(cls, parameter_rule: ToolParameter, parameters: dict init runtime parameter """ parameter_value = parameters.get(parameter_rule.name) - if not parameter_value: + if not parameter_value and parameter_value != 0: # get default value parameter_value = parameter_rule.default if not parameter_value and parameter_rule.required: @@ -321,14 +321,14 @@ def list_builtin_providers(cls) -> Generator[BuiltinToolProviderController, None if cls._builtin_providers_loaded: yield from list(cls._builtin_providers.values()) return - + with cls._builtin_provider_lock: if cls._builtin_providers_loaded: yield from list(cls._builtin_providers.values()) return - + yield from cls._list_builtin_providers() - + @classmethod def _list_builtin_providers(cls) -> Generator[BuiltinToolProviderController, None, None]: """ @@ -492,7 +492,7 @@ def get_api_provider_controller(cls, tenant_id: str, provider_id: str) -> tuple[ controller = ApiToolProviderController.from_db( provider, - ApiProviderAuthType.API_KEY if provider.credentials['auth_type'] == 'api_key' else + ApiProviderAuthType.API_KEY if provider.credentials['auth_type'] == 'api_key' else ApiProviderAuthType.NONE ) controller.load_bundled_tools(provider.tools) diff --git a/api/core/workflow/nodes/code/code_node.py b/api/core/workflow/nodes/code/code_node.py index 610a23e704d1bb..e15c1c6f8750cd 100644 --- a/api/core/workflow/nodes/code/code_node.py +++ b/api/core/workflow/nodes/code/code_node.py @@ -1,6 +1,6 @@ -import os from typing import Optional, Union, cast +from configs import dify_config from core.helper.code_executor.code_executor import CodeExecutionException, CodeExecutor, CodeLanguage from core.helper.code_executor.code_node_provider import CodeNodeProvider from core.helper.code_executor.javascript.javascript_code_provider import JavascriptCodeProvider @@ -11,14 +11,14 @@ from core.workflow.nodes.code.entities import CodeNodeData from models.workflow import WorkflowNodeExecutionStatus -MAX_NUMBER = int(os.environ.get('CODE_MAX_NUMBER', '9223372036854775807')) -MIN_NUMBER = int(os.environ.get('CODE_MIN_NUMBER', '-9223372036854775808')) +MAX_NUMBER = dify_config.CODE_MAX_NUMBER +MIN_NUMBER = dify_config.CODE_MIN_NUMBER MAX_PRECISION = 20 MAX_DEPTH = 5 -MAX_STRING_LENGTH = int(os.environ.get('CODE_MAX_STRING_LENGTH', '80000')) -MAX_STRING_ARRAY_LENGTH = int(os.environ.get('CODE_MAX_STRING_ARRAY_LENGTH', '30')) -MAX_OBJECT_ARRAY_LENGTH = int(os.environ.get('CODE_MAX_OBJECT_ARRAY_LENGTH', '30')) -MAX_NUMBER_ARRAY_LENGTH = int(os.environ.get('CODE_MAX_NUMBER_ARRAY_LENGTH', '1000')) +MAX_STRING_LENGTH = dify_config.CODE_MAX_STRING_LENGTH +MAX_STRING_ARRAY_LENGTH = dify_config.CODE_MAX_STRING_ARRAY_LENGTH +MAX_OBJECT_ARRAY_LENGTH = dify_config.CODE_MAX_OBJECT_ARRAY_LENGTH +MAX_NUMBER_ARRAY_LENGTH = dify_config.CODE_MAX_NUMBER_ARRAY_LENGTH class CodeNode(BaseNode): diff --git a/api/core/workflow/nodes/http_request/entities.py b/api/core/workflow/nodes/http_request/entities.py index 00d72a8b0aca83..65451452c84ebe 100644 --- a/api/core/workflow/nodes/http_request/entities.py +++ b/api/core/workflow/nodes/http_request/entities.py @@ -1,57 +1,61 @@ -import os from typing import Literal, Optional, Union from pydantic import BaseModel, ValidationInfo, field_validator +from configs import dify_config from core.workflow.entities.base_node_data_entities import BaseNodeData -MAX_CONNECT_TIMEOUT = int(os.environ.get('HTTP_REQUEST_MAX_CONNECT_TIMEOUT', '300')) -MAX_READ_TIMEOUT = int(os.environ.get('HTTP_REQUEST_MAX_READ_TIMEOUT', '600')) -MAX_WRITE_TIMEOUT = int(os.environ.get('HTTP_REQUEST_MAX_WRITE_TIMEOUT', '600')) +MAX_CONNECT_TIMEOUT = dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT +MAX_READ_TIMEOUT = dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT +MAX_WRITE_TIMEOUT = dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT + + +class HttpRequestNodeAuthorizationConfig(BaseModel): + type: Literal[None, 'basic', 'bearer', 'custom'] + api_key: Union[None, str] = None + header: Union[None, str] = None + + +class HttpRequestNodeAuthorization(BaseModel): + type: Literal['no-auth', 'api-key'] + config: Optional[HttpRequestNodeAuthorizationConfig] = None + + @field_validator('config', mode='before') + @classmethod + def check_config(cls, v: HttpRequestNodeAuthorizationConfig, values: ValidationInfo): + """ + Check config, if type is no-auth, config should be None, otherwise it should be a dict. + """ + if values.data['type'] == 'no-auth': + return None + else: + if not v or not isinstance(v, dict): + raise ValueError('config should be a dict') + + return v + + +class HttpRequestNodeBody(BaseModel): + type: Literal['none', 'form-data', 'x-www-form-urlencoded', 'raw-text', 'json'] + data: Union[None, str] = None + + +class HttpRequestNodeTimeout(BaseModel): + connect: int = MAX_CONNECT_TIMEOUT + read: int = MAX_READ_TIMEOUT + write: int = MAX_WRITE_TIMEOUT + class HttpRequestNodeData(BaseNodeData): """ Code Node Data. """ - class Authorization(BaseModel): - # TODO[pydantic]: The `Config` class inherits from another class, please create the `model_config` manually. - # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information. - class Config(BaseModel): - type: Literal[None, 'basic', 'bearer', 'custom'] - api_key: Union[None, str] = None - header: Union[None, str] = None - - type: Literal['no-auth', 'api-key'] - config: Optional[Config] = None - - @field_validator('config', mode='before') - @classmethod - def check_config(cls, v: Config, values: ValidationInfo): - """ - Check config, if type is no-auth, config should be None, otherwise it should be a dict. - """ - if values.data['type'] == 'no-auth': - return None - else: - if not v or not isinstance(v, dict): - raise ValueError('config should be a dict') - - return v - - class Body(BaseModel): - type: Literal['none', 'form-data', 'x-www-form-urlencoded', 'raw-text', 'json'] - data: Union[None, str] = None - - class Timeout(BaseModel): - connect: Optional[int] = MAX_CONNECT_TIMEOUT - read: Optional[int] = MAX_READ_TIMEOUT - write: Optional[int] = MAX_WRITE_TIMEOUT method: Literal['get', 'post', 'put', 'patch', 'delete', 'head'] url: str - authorization: Authorization + authorization: HttpRequestNodeAuthorization headers: str params: str - body: Optional[Body] = None - timeout: Optional[Timeout] = None + body: Optional[HttpRequestNodeBody] = None + timeout: Optional[HttpRequestNodeTimeout] = None mask_authorization_header: Optional[bool] = True diff --git a/api/core/workflow/nodes/http_request/http_executor.py b/api/core/workflow/nodes/http_request/http_executor.py index 035a8604300a1f..902d821e408b9a 100644 --- a/api/core/workflow/nodes/http_request/http_executor.py +++ b/api/core/workflow/nodes/http_request/http_executor.py @@ -1,5 +1,4 @@ import json -import os from copy import deepcopy from random import randint from typing import Any, Optional, Union @@ -8,22 +7,28 @@ import httpx import core.helper.ssrf_proxy as ssrf_proxy +from configs import dify_config from core.workflow.entities.variable_entities import VariableSelector from core.workflow.entities.variable_pool import ValueType, VariablePool -from core.workflow.nodes.http_request.entities import HttpRequestNodeData +from core.workflow.nodes.http_request.entities import ( + HttpRequestNodeAuthorization, + HttpRequestNodeBody, + HttpRequestNodeData, + HttpRequestNodeTimeout, +) from core.workflow.utils.variable_template_parser import VariableTemplateParser -MAX_BINARY_SIZE = int(os.environ.get('HTTP_REQUEST_NODE_MAX_BINARY_SIZE', 1024 * 1024 * 10)) # 10MB -READABLE_MAX_BINARY_SIZE = f'{MAX_BINARY_SIZE / 1024 / 1024:.2f}MB' -MAX_TEXT_SIZE = int(os.environ.get('HTTP_REQUEST_NODE_MAX_TEXT_SIZE', 1024 * 1024)) # 1MB -READABLE_MAX_TEXT_SIZE = f'{MAX_TEXT_SIZE / 1024 / 1024:.2f}MB' +MAX_BINARY_SIZE = dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE +READABLE_MAX_BINARY_SIZE = dify_config.HTTP_REQUEST_NODE_READABLE_MAX_BINARY_SIZE +MAX_TEXT_SIZE = dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE +READABLE_MAX_TEXT_SIZE = dify_config.HTTP_REQUEST_NODE_READABLE_MAX_TEXT_SIZE class HttpExecutorResponse: headers: dict[str, str] response: httpx.Response - def __init__(self, response: httpx.Response = None): + def __init__(self, response: httpx.Response): self.response = response self.headers = dict(response.headers) if isinstance(self.response, httpx.Response) else {} @@ -40,7 +45,6 @@ def is_file(self) -> bool: def get_content_type(self) -> str: return self.headers.get('content-type', '') - def extract_file(self) -> tuple[str, bytes]: """ extract file from response if content type is file related @@ -88,17 +92,21 @@ def readable_size(self) -> str: class HttpExecutor: server_url: str method: str - authorization: HttpRequestNodeData.Authorization + authorization: HttpRequestNodeAuthorization params: dict[str, Any] headers: dict[str, Any] body: Union[None, str] files: Union[None, dict[str, Any]] boundary: str variable_selectors: list[VariableSelector] - timeout: HttpRequestNodeData.Timeout - - def __init__(self, node_data: HttpRequestNodeData, timeout: HttpRequestNodeData.Timeout, - variable_pool: Optional[VariablePool] = None): + timeout: HttpRequestNodeTimeout + + def __init__( + self, + node_data: HttpRequestNodeData, + timeout: HttpRequestNodeTimeout, + variable_pool: Optional[VariablePool] = None, + ): self.server_url = node_data.url self.method = node_data.method self.authorization = node_data.authorization @@ -113,11 +121,11 @@ def __init__(self, node_data: HttpRequestNodeData, timeout: HttpRequestNodeData. self._init_template(node_data, variable_pool) @staticmethod - def _is_json_body(body: HttpRequestNodeData.Body): + def _is_json_body(body: HttpRequestNodeBody): """ check if body is json """ - if body and body.type == 'json': + if body and body.type == 'json' and body.data: try: json.loads(body.data) return True @@ -146,7 +154,6 @@ def _to_dict(convert_text: str): return result def _init_template(self, node_data: HttpRequestNodeData, variable_pool: Optional[VariablePool] = None): - # extract all template in url self.server_url, server_url_variable_selectors = self._format_template(node_data.url, variable_pool) @@ -178,9 +185,7 @@ def _init_template(self, node_data: HttpRequestNodeData, variable_pool: Optional body = self._to_dict(body_data) if node_data.body.type == 'form-data': - self.files = { - k: ('', v) for k, v in body.items() - } + self.files = {k: ('', v) for k, v in body.items()} random_str = lambda n: ''.join([chr(randint(97, 122)) for _ in range(n)]) self.boundary = f'----WebKitFormBoundary{random_str(16)}' @@ -192,13 +197,24 @@ def _init_template(self, node_data: HttpRequestNodeData, variable_pool: Optional elif node_data.body.type == 'none': self.body = '' - self.variable_selectors = (server_url_variable_selectors + params_variable_selectors - + headers_variable_selectors + body_data_variable_selectors) + self.variable_selectors = ( + server_url_variable_selectors + + params_variable_selectors + + headers_variable_selectors + + body_data_variable_selectors + ) def _assembling_headers(self) -> dict[str, Any]: authorization = deepcopy(self.authorization) headers = deepcopy(self.headers) or {} if self.authorization.type == 'api-key': + if self.authorization.config is None: + raise ValueError('self.authorization config is required') + if authorization.config is None: + raise ValueError('authorization config is required') + if authorization.config.header is None: + raise ValueError('authorization config header is required') + if self.authorization.config.api_key is None: raise ValueError('api_key is required') @@ -216,7 +232,7 @@ def _assembling_headers(self) -> dict[str, Any]: def _validate_and_parse_response(self, response: httpx.Response) -> HttpExecutorResponse: """ - validate the response + validate the response """ if isinstance(response, httpx.Response): executor_response = HttpExecutorResponse(response) @@ -226,24 +242,26 @@ def _validate_and_parse_response(self, response: httpx.Response) -> HttpExecutor if executor_response.is_file: if executor_response.size > MAX_BINARY_SIZE: raise ValueError( - f'File size is too large, max size is {READABLE_MAX_BINARY_SIZE}, but current size is {executor_response.readable_size}.') + f'File size is too large, max size is {READABLE_MAX_BINARY_SIZE}, but current size is {executor_response.readable_size}.' + ) else: if executor_response.size > MAX_TEXT_SIZE: raise ValueError( - f'Text size is too large, max size is {READABLE_MAX_TEXT_SIZE}, but current size is {executor_response.readable_size}.') + f'Text size is too large, max size is {READABLE_MAX_TEXT_SIZE}, but current size is {executor_response.readable_size}.' + ) return executor_response def _do_http_request(self, headers: dict[str, Any]) -> httpx.Response: """ - do http request depending on api bundle + do http request depending on api bundle """ kwargs = { 'url': self.server_url, 'headers': headers, 'params': self.params, 'timeout': (self.timeout.connect, self.timeout.read, self.timeout.write), - 'follow_redirects': True + 'follow_redirects': True, } if self.method in ('get', 'head', 'post', 'put', 'delete', 'patch'): @@ -306,8 +324,9 @@ def to_raw_request(self, mask_authorization_header: Optional[bool] = True) -> st return raw_request - def _format_template(self, template: str, variable_pool: VariablePool, escape_quotes: bool = False) \ - -> tuple[str, list[VariableSelector]]: + def _format_template( + self, template: str, variable_pool: Optional[VariablePool], escape_quotes: bool = False + ) -> tuple[str, list[VariableSelector]]: """ format template """ @@ -318,14 +337,13 @@ def _format_template(self, template: str, variable_pool: VariablePool, escape_qu variable_value_mapping = {} for variable_selector in variable_selectors: value = variable_pool.get_variable_value( - variable_selector=variable_selector.value_selector, - target_value_type=ValueType.STRING + variable_selector=variable_selector.value_selector, target_value_type=ValueType.STRING ) if value is None: raise ValueError(f'Variable {variable_selector.variable} not found') - if escape_quotes: + if escape_quotes and isinstance(value, str): value = value.replace('"', '\\"') variable_value_mapping[variable_selector.variable] = value diff --git a/api/core/workflow/nodes/http_request/http_request_node.py b/api/core/workflow/nodes/http_request/http_request_node.py index 276c02f62df3e2..24acf984f2869f 100644 --- a/api/core/workflow/nodes/http_request/http_request_node.py +++ b/api/core/workflow/nodes/http_request/http_request_node.py @@ -5,6 +5,7 @@ from core.file.file_obj import FileTransferMethod, FileType, FileVar from core.tools.tool_file_manager import ToolFileManager +from core.workflow.entities.base_node_data_entities import BaseNodeData from core.workflow.entities.node_entities import NodeRunResult, NodeType from core.workflow.entities.variable_pool import VariablePool from core.workflow.nodes.base_node import BaseNode @@ -13,49 +14,50 @@ MAX_READ_TIMEOUT, MAX_WRITE_TIMEOUT, HttpRequestNodeData, + HttpRequestNodeTimeout, ) from core.workflow.nodes.http_request.http_executor import HttpExecutor, HttpExecutorResponse from models.workflow import WorkflowNodeExecutionStatus -HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeData.Timeout(connect=min(10, MAX_CONNECT_TIMEOUT), - read=min(60, MAX_READ_TIMEOUT), - write=min(20, MAX_WRITE_TIMEOUT)) +HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout( + connect=min(10, MAX_CONNECT_TIMEOUT), + read=min(60, MAX_READ_TIMEOUT), + write=min(20, MAX_WRITE_TIMEOUT), +) class HttpRequestNode(BaseNode): _node_data_cls = HttpRequestNodeData - node_type = NodeType.HTTP_REQUEST + _node_type = NodeType.HTTP_REQUEST @classmethod - def get_default_config(cls) -> dict: + def get_default_config(cls, filters: dict | None = None) -> dict: return { - "type": "http-request", - "config": { - "method": "get", - "authorization": { - "type": "no-auth", - }, - "body": { - "type": "none" + 'type': 'http-request', + 'config': { + 'method': 'get', + 'authorization': { + 'type': 'no-auth', }, - "timeout": { + 'body': {'type': 'none'}, + 'timeout': { **HTTP_REQUEST_DEFAULT_TIMEOUT.model_dump(), - "max_connect_timeout": MAX_CONNECT_TIMEOUT, - "max_read_timeout": MAX_READ_TIMEOUT, - "max_write_timeout": MAX_WRITE_TIMEOUT, - } + 'max_connect_timeout': MAX_CONNECT_TIMEOUT, + 'max_read_timeout': MAX_READ_TIMEOUT, + 'max_write_timeout': MAX_WRITE_TIMEOUT, + }, }, } def _run(self, variable_pool: VariablePool) -> NodeRunResult: - node_data: HttpRequestNodeData = cast(self._node_data_cls, self.node_data) + node_data: HttpRequestNodeData = cast(HttpRequestNodeData, self.node_data) # init http executor http_executor = None try: - http_executor = HttpExecutor(node_data=node_data, - timeout=self._get_request_timeout(node_data), - variable_pool=variable_pool) + http_executor = HttpExecutor( + node_data=node_data, timeout=self._get_request_timeout(node_data), variable_pool=variable_pool + ) # invoke http executor response = http_executor.invoke() @@ -70,7 +72,7 @@ def _run(self, variable_pool: VariablePool) -> NodeRunResult: return NodeRunResult( status=WorkflowNodeExecutionStatus.FAILED, error=str(e), - process_data=process_data + process_data=process_data, ) files = self.extract_files(http_executor.server_url, response) @@ -85,34 +87,32 @@ def _run(self, variable_pool: VariablePool) -> NodeRunResult: }, process_data={ 'request': http_executor.to_raw_request( - mask_authorization_header=node_data.mask_authorization_header + mask_authorization_header=node_data.mask_authorization_header, ), - } + }, ) - def _get_request_timeout(self, node_data: HttpRequestNodeData) -> HttpRequestNodeData.Timeout: + def _get_request_timeout(self, node_data: HttpRequestNodeData) -> HttpRequestNodeTimeout: timeout = node_data.timeout if timeout is None: return HTTP_REQUEST_DEFAULT_TIMEOUT - if timeout.connect is None: - timeout.connect = HTTP_REQUEST_DEFAULT_TIMEOUT.connect + timeout.connect = timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect timeout.connect = min(timeout.connect, MAX_CONNECT_TIMEOUT) - if timeout.read is None: - timeout.read = HTTP_REQUEST_DEFAULT_TIMEOUT.read + timeout.read = timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read timeout.read = min(timeout.read, MAX_READ_TIMEOUT) - if timeout.write is None: - timeout.write = HTTP_REQUEST_DEFAULT_TIMEOUT.write + timeout.write = timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write timeout.write = min(timeout.write, MAX_WRITE_TIMEOUT) return timeout @classmethod - def _extract_variable_selector_to_variable_mapping(cls, node_data: HttpRequestNodeData) -> dict[str, list[str]]: + def _extract_variable_selector_to_variable_mapping(cls, node_data: BaseNodeData) -> dict[str, list[str]]: """ Extract variable selector to variable mapping :param node_data: node data :return: """ + node_data = cast(HttpRequestNodeData, node_data) try: http_executor = HttpExecutor(node_data=node_data, timeout=HTTP_REQUEST_DEFAULT_TIMEOUT) @@ -124,7 +124,7 @@ def _extract_variable_selector_to_variable_mapping(cls, node_data: HttpRequestNo return variable_mapping except Exception as e: - logging.exception(f"Failed to extract variable selector to variable mapping: {e}") + logging.exception(f'Failed to extract variable selector to variable mapping: {e}') return {} def extract_files(self, url: str, response: HttpExecutorResponse) -> list[FileVar]: @@ -144,21 +144,23 @@ def extract_files(self, url: str, response: HttpExecutorResponse) -> list[FileVa extension = guess_extension(mimetype) or '.bin' tool_file = ToolFileManager.create_file_by_raw( - user_id=self.user_id, - tenant_id=self.tenant_id, - conversation_id=None, - file_binary=file_binary, + user_id=self.user_id, + tenant_id=self.tenant_id, + conversation_id=None, + file_binary=file_binary, mimetype=mimetype, ) - files.append(FileVar( - tenant_id=self.tenant_id, - type=FileType.IMAGE, - transfer_method=FileTransferMethod.TOOL_FILE, - related_id=tool_file.id, - filename=filename, - extension=extension, - mime_type=mimetype, - )) + files.append( + FileVar( + tenant_id=self.tenant_id, + type=FileType.IMAGE, + transfer_method=FileTransferMethod.TOOL_FILE, + related_id=tool_file.id, + filename=filename, + extension=extension, + mime_type=mimetype, + ) + ) return files diff --git a/api/libs/helper.py b/api/libs/helper.py index ebabb2ea474b6a..335c6688f49603 100644 --- a/api/libs/helper.py +++ b/api/libs/helper.py @@ -1,18 +1,23 @@ import json +import logging import random import re import string import subprocess +import time import uuid from collections.abc import Generator from datetime import datetime from hashlib import sha256 -from typing import Union +from typing import Any, Optional, Union from zoneinfo import available_timezones -from flask import Response, stream_with_context +from flask import Response, current_app, stream_with_context from flask_restful import fields +from extensions.ext_redis import redis_client +from models.account import Account + def run(script): return subprocess.getstatusoutput('source /root/.bashrc && ' + script) @@ -46,12 +51,12 @@ def uuid_value(value): error = ('{value} is not a valid uuid.' .format(value=value)) raise ValueError(error) - + def alphanumeric(value: str): # check if the value is alphanumeric and underlined if re.match(r'^[a-zA-Z0-9_]+$', value): return value - + raise ValueError(f'{value} is not a valid alphanumeric value') def timestamp_value(timestamp): @@ -163,3 +168,97 @@ def generate() -> Generator: return Response(stream_with_context(generate()), status=200, mimetype='text/event-stream') + + +class TokenManager: + + @classmethod + def generate_token(cls, account: Account, token_type: str, additional_data: dict = None) -> str: + old_token = cls._get_current_token_for_account(account.id, token_type) + if old_token: + if isinstance(old_token, bytes): + old_token = old_token.decode('utf-8') + cls.revoke_token(old_token, token_type) + + token = str(uuid.uuid4()) + token_data = { + 'account_id': account.id, + 'email': account.email, + 'token_type': token_type + } + if additional_data: + token_data.update(additional_data) + + expiry_hours = current_app.config[f'{token_type.upper()}_TOKEN_EXPIRY_HOURS'] + token_key = cls._get_token_key(token, token_type) + redis_client.setex( + token_key, + expiry_hours * 60 * 60, + json.dumps(token_data) + ) + + cls._set_current_token_for_account(account.id, token, token_type, expiry_hours) + return token + + @classmethod + def _get_token_key(cls, token: str, token_type: str) -> str: + return f'{token_type}:token:{token}' + + @classmethod + def revoke_token(cls, token: str, token_type: str): + token_key = cls._get_token_key(token, token_type) + redis_client.delete(token_key) + + @classmethod + def get_token_data(cls, token: str, token_type: str) -> Optional[dict[str, Any]]: + key = cls._get_token_key(token, token_type) + token_data_json = redis_client.get(key) + if token_data_json is None: + logging.warning(f"{token_type} token {token} not found with key {key}") + return None + token_data = json.loads(token_data_json) + return token_data + + @classmethod + def _get_current_token_for_account(cls, account_id: str, token_type: str) -> Optional[str]: + key = cls._get_account_token_key(account_id, token_type) + current_token = redis_client.get(key) + return current_token + + @classmethod + def _set_current_token_for_account(cls, account_id: str, token: str, token_type: str, expiry_hours: int): + key = cls._get_account_token_key(account_id, token_type) + redis_client.setex(key, expiry_hours * 60 * 60, token) + + @classmethod + def _get_account_token_key(cls, account_id: str, token_type: str) -> str: + return f'{token_type}:account:{account_id}' + + +class RateLimiter: + def __init__(self, prefix: str, max_attempts: int, time_window: int): + self.prefix = prefix + self.max_attempts = max_attempts + self.time_window = time_window + + def _get_key(self, email: str) -> str: + return f"{self.prefix}:{email}" + + def is_rate_limited(self, email: str) -> bool: + key = self._get_key(email) + current_time = int(time.time()) + window_start_time = current_time - self.time_window + + redis_client.zremrangebyscore(key, '-inf', window_start_time) + attempts = redis_client.zcard(key) + + if attempts and int(attempts) >= self.max_attempts: + return True + return False + + def increment_rate_limit(self, email: str): + key = self._get_key(email) + current_time = int(time.time()) + + redis_client.zadd(key, {current_time: current_time}) + redis_client.expire(key, self.time_window * 2) diff --git a/api/migrations/versions/161cadc1af8d_add_dataset_permission_tenant_id.py b/api/migrations/versions/161cadc1af8d_add_dataset_permission_tenant_id.py new file mode 100644 index 00000000000000..fa00004f1abe0b --- /dev/null +++ b/api/migrations/versions/161cadc1af8d_add_dataset_permission_tenant_id.py @@ -0,0 +1,49 @@ +"""add dataset permission tenant id + +Revision ID: 161cadc1af8d +Revises: 7e6a8693e07a +Create Date: 2024-07-05 14:30:59.472593 + +""" +import sqlalchemy as sa +from alembic import op + +import models as models + +# revision identifiers, used by Alembic. +revision = '161cadc1af8d' +down_revision = '7e6a8693e07a' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('dataset_permissions', schema=None) as batch_op: + # Step 1: Add column without NOT NULL constraint + op.add_column('dataset_permissions', sa.Column('tenant_id', sa.UUID(), nullable=True)) + + # Step 2: Update the column to set a default value for existing rows + op.execute( + """ + UPDATE dataset_permissions + SET tenant_id = ( + SELECT tenant_id + FROM datasets + WHERE datasets.id = dataset_permissions.dataset_id + ) + """ + ) + + # Step 3: Alter column to NOT NULL + op.alter_column('dataset_permissions', 'tenant_id', nullable=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('dataset_permissions', schema=None) as batch_op: + batch_op.drop_column('tenant_id') + + # ### end Alembic commands ### diff --git a/api/models/dataset.py b/api/models/dataset.py index 7c8a871aea1dc5..02d49380bdad01 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -670,11 +670,13 @@ class DatasetPermission(db.Model): __table_args__ = ( db.PrimaryKeyConstraint('id', name='dataset_permission_pkey'), db.Index('idx_dataset_permissions_dataset_id', 'dataset_id'), - db.Index('idx_dataset_permissions_account_id', 'account_id') + db.Index('idx_dataset_permissions_account_id', 'account_id'), + db.Index('idx_dataset_permissions_tenant_id', 'tenant_id') ) id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()'), primary_key=True) dataset_id = db.Column(StringUUID, nullable=False) account_id = db.Column(StringUUID, nullable=False) + tenant_id = db.Column(StringUUID, nullable=False) has_permission = db.Column(db.Boolean, nullable=False, server_default=db.text('true')) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) diff --git a/api/poetry.lock b/api/poetry.lock index 961b2748b44f76..ea99ae09d5cb70 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -126,13 +126,13 @@ frozenlist = ">=1.1.0" [[package]] name = "alembic" -version = "1.13.1" +version = "1.13.2" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.8" files = [ - {file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"}, - {file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"}, + {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, + {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, ] [package.dependencies] @@ -553,13 +553,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.136" +version = "1.34.139" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.136-py3-none-any.whl", hash = "sha256:c63fe9032091fb9e9477706a3ebfa4d0c109b807907051d892ed574f9b573e61"}, - {file = "botocore-1.34.136.tar.gz", hash = "sha256:7f7135178692b39143c8f152a618d2a3b71065a317569a7102d2306d4946f42f"}, + {file = "botocore-1.34.139-py3-none-any.whl", hash = "sha256:dd1e085d4caa2a4c1b7d83e3bc51416111c8238a35d498e9d3b04f3b63b086ba"}, + {file = "botocore-1.34.139.tar.gz", hash = "sha256:df023d8cf8999d574214dad4645cb90f9d2ccd1494f6ee2b57b1ab7522f6be77"}, ] [package.dependencies] @@ -572,54 +572,53 @@ crt = ["awscrt (==0.20.11)"] [[package]] name = "bottleneck" -version = "1.3.8" +version = "1.4.0" description = "Fast NumPy array functions written in C" optional = false python-versions = "*" files = [ - {file = "Bottleneck-1.3.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:865c8ed5b798c0198b0b80553e09cc0d890c4f5feb3d81d31661517ca7819fa3"}, - {file = "Bottleneck-1.3.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d073a31e259d40b25e29dbba80f73abf38afe98fd730c79dad7edd9a0ad6cff5"}, - {file = "Bottleneck-1.3.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b806b277ab47495032822f55f43b8d336e4b7e73f8506ed34d3ea3da6d644abc"}, - {file = "Bottleneck-1.3.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:770b517609916adeb39d3b1a386a29bc316da03dd61e7ee6e8a38325b80cc327"}, - {file = "Bottleneck-1.3.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2948502b0394ee419945b55b092585222a505c61d41a874c741be49f2cac056f"}, - {file = "Bottleneck-1.3.8-cp310-cp310-win32.whl", hash = "sha256:271b6333522beb8aee32e640ba49a2064491d2c10317baa58a5996be3dd443e4"}, - {file = "Bottleneck-1.3.8-cp310-cp310-win_amd64.whl", hash = "sha256:d41000ea7ca196b5fd39d6fccd34bf0704c8831731cedd2da2dcae3c6ac49c42"}, - {file = "Bottleneck-1.3.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0a7f454394cd3642498b6e077e70f4a6b9fd46a8eb908c83ac737fdc9f9a98c"}, - {file = "Bottleneck-1.3.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c4ea8b9024dcb4e83b5c118a3c8faa863ace2ad572849da548a74a8ee4e8f2a"}, - {file = "Bottleneck-1.3.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40724b6e965ff5b88b333d4a10097b1629e60c0db21bb3d08c24d7b1a904a16"}, - {file = "Bottleneck-1.3.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4bd7183b8dcca89d0e65abe4507c19667dd31dacfbcc8ed705bad642f26a46e1"}, - {file = "Bottleneck-1.3.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:20aa31a7d9d747c499ace1610a6e1f7aba6e3d4a9923e0312f6b4b6d68a59af3"}, - {file = "Bottleneck-1.3.8-cp311-cp311-win32.whl", hash = "sha256:350520105d9449e6565b3f0c4ce1f80a0b3e4d63695ebbf29db41f62e13f6461"}, - {file = "Bottleneck-1.3.8-cp311-cp311-win_amd64.whl", hash = "sha256:167a278902775defde7dfded6e98e3707dfe54971ffd9aec25c43bc74e4e381a"}, - {file = "Bottleneck-1.3.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c6e93ed45c6c83392f73d0333b310b38772df7eb78c120c1447245691bdedaf4"}, - {file = "Bottleneck-1.3.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3400f47dda0196b5af50b0b0678e33cc8c42e52e55ae0a63cdfed60725659bc"}, - {file = "Bottleneck-1.3.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fba5fd1805c71b2eeea50bea93d59be449c4af23ebd8da5f75fd74fd0331e314"}, - {file = "Bottleneck-1.3.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:60139c5c3d2a9c1454a04af5ee981a9f56548d27fa36f264069b149a6e9b01ed"}, - {file = "Bottleneck-1.3.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:99fab17fa26c811ccad63e208314726e718ae6605314329eca09641954550523"}, - {file = "Bottleneck-1.3.8-cp312-cp312-win32.whl", hash = "sha256:d3ae2bb5d4168912e438e377cc1301fa01df949ba59cd86317b3e00404fd4a97"}, - {file = "Bottleneck-1.3.8-cp312-cp312-win_amd64.whl", hash = "sha256:bcba1d5d5328c50f94852ab521fcb26f35d9e0ccd928d120d56455d1a5bb743f"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8d01fd5389d3160d54619119987ac24b020fa6810b7b398fff4945892237b3da"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca25f0003ef65264942f6306d793e0f270ece8b406c5a293dfc7d878146e9f8"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7763cf1516fa388c3587d12182fc1bc1c8089eab1a0a1bf09761f4c41af73c"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:38837c022350e2a656453f0e448416b7108cf67baccf11d04a0b3b70a48074dd"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:84ca5e741fae1c1796744dbdd0d2c1789cb74dd79c12ea8ec5834f83430f8520"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-win32.whl", hash = "sha256:f4dfc22a3450227e692ef2ff4657639c33eec88ad04ee3ce29d1a23a4942da24"}, - {file = "Bottleneck-1.3.8-cp37-cp37m-win_amd64.whl", hash = "sha256:90b87eed152bbd760c4eb11473c2cf036abdb26e2f84caeb00787da74fb08c40"}, - {file = "Bottleneck-1.3.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54a1b5d9d63b2d9f2955f8542eea26c418f97873e0abf86ca52beea0208c9306"}, - {file = "Bottleneck-1.3.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:019dd142d1e870388fb0b649213a0d8e569cce784326e183deba8f17826edd9f"}, - {file = "Bottleneck-1.3.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b5ed34a540eb7df59f45da659af9f792306637de1c69c95f020294f3b9fc4a8"}, - {file = "Bottleneck-1.3.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b69fcd4d818bcf9d53497d8accd0d5f852a447728baaa33b9b7168f8c4221d06"}, - {file = "Bottleneck-1.3.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:02616a830bd477f5ba51103396092da4b9d83cea2e88f5b8069e3f4f7b796704"}, - {file = "Bottleneck-1.3.8-cp38-cp38-win32.whl", hash = "sha256:93d359fb83eb3bdd6635ef6e64835c38ffdc211441fc190549f286e6af98b5f6"}, - {file = "Bottleneck-1.3.8-cp38-cp38-win_amd64.whl", hash = "sha256:51c8bb3dffeb72c14f0382b80de76eabac6726d316babbd48f7e4056267d7910"}, - {file = "Bottleneck-1.3.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:84453548b0f722c3be912ce3c6b685917fea842bf1252eeb63714a2c1fd1ffc9"}, - {file = "Bottleneck-1.3.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92700867504a213cafa9b8d9be529bd6e18dc83366b2ba00e86e80769b93f678"}, - {file = "Bottleneck-1.3.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fadfd2f3931fdff42f4b9867eb02ed7c662d01e6099ff6b347b6ced791450651"}, - {file = "Bottleneck-1.3.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:cfbc4a3a934b677bfbc37ac8757c4e1264a76262b774259bd3fa8a265dbd668b"}, - {file = "Bottleneck-1.3.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3c74c18f86a1ffac22280b005df8bb8a58505ac6663c4d6807f39873c17dc347"}, - {file = "Bottleneck-1.3.8-cp39-cp39-win32.whl", hash = "sha256:211f881159e8adb3a57df2263028ae6dc89ec4328bfd43f3421e507406c28654"}, - {file = "Bottleneck-1.3.8-cp39-cp39-win_amd64.whl", hash = "sha256:8615eeb75009ba7c0a112a5a6a5154ed3d61fd6b0879631778b3e42e2d9a6d65"}, - {file = "Bottleneck-1.3.8.tar.gz", hash = "sha256:6780d896969ba7f53c8995ba90c87c548beb3db435dc90c60b9a10ed1ab4d868"}, + {file = "Bottleneck-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2110af22aa8c2779faba8aa021d6b559df04449bdf21d510eacd7910934189fe"}, + {file = "Bottleneck-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:381cbd1e52338fcdf9ff01c962e6aa187b2d8b3b369d42e779b6d33ac61f8d35"}, + {file = "Bottleneck-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a91e40bbb8452e77772614d882be2c34b3b514d9f15460f703293525a6e173d"}, + {file = "Bottleneck-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:59604949aea476f5075b965129eaa3c2d90891fd43b0dfaf2ad7621bb5db14a5"}, + {file = "Bottleneck-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c2c92545e1bc8e859d8d137aefa3b24843bd374b17c9814dafa3bbcea9fc4ec0"}, + {file = "Bottleneck-1.4.0-cp310-cp310-win32.whl", hash = "sha256:f63e79bfa2f82a7432c8b147ed321d01ca7769bc17cc04644286a4ce58d30549"}, + {file = "Bottleneck-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:d69907d8d679cb5091a3f479c46bf1076f149f6311ff3298bac5089b86a2fab1"}, + {file = "Bottleneck-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67347b0f01f32a232a6269c37afc1c079e08f6455fa12e91f4a1cd12eb0d11a5"}, + {file = "Bottleneck-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1490348b3bbc0225523dc2c00c6bb3e66168c537d62797bd29783c0826c09838"}, + {file = "Bottleneck-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a704165552496cbcc8bcc5921bb679fd6fa66bb1e758888de091b1223231c9f0"}, + {file = "Bottleneck-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffb4e4edf7997069719b9269926cc00a2a12c6e015422d1ebc2f621c4541396a"}, + {file = "Bottleneck-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5d6bf45ed58d5e7414c0011ef2da75474fe597a51970df83596b0bcb79c14c5e"}, + {file = "Bottleneck-1.4.0-cp311-cp311-win32.whl", hash = "sha256:ed209f8f3cb9954773764b0fa2510a7a9247ad245593187ac90bd0747771bc5c"}, + {file = "Bottleneck-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d53f1a72b12cfd76b56934c33bc0cb7c1a295f23a2d3ffba8c764514c9b5e0ff"}, + {file = "Bottleneck-1.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e720ff24370324c84a82b1a18195274715c23181748b2b9e3dacad24198ca06f"}, + {file = "Bottleneck-1.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44305c70c2a1539b0ae968e033f301ad868a6146b47e3cccd73fdfe3fc07c4ee"}, + {file = "Bottleneck-1.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4dac5d2a871b7bd296c2b92426daa27d5b07aa84ef2557db097d29135da4eb"}, + {file = "Bottleneck-1.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fbcdd01db9e27741fb16a02b720cf02389d4b0b99cefe3c834c7df88c2d7412d"}, + {file = "Bottleneck-1.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:14b3334a39308fbb05dacd35ac100842aa9e9bc70afbdcebe43e46179d183fd0"}, + {file = "Bottleneck-1.4.0-cp312-cp312-win32.whl", hash = "sha256:520d7a83cd48b3f58e5df1a258acb547f8a5386a8c21ca9e1058d83a0d622fdf"}, + {file = "Bottleneck-1.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1339b9ad3ee217253f246cde5c3789eb527cf9dd31ff0a1f5a8bf7fc89eadad"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2749602200aaa0e12a0f3f936dd6d4035384ad10d3acf7ac4f418c501683397"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb79a2ac135567694f13339f0bebcee96aec09c596b324b61cd7fd5e306f49d"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c6097bf39723e76ff5bba160daab92ae599df212c859db8d46648548584d04a8"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b5f72b66ccc0272de46b67346cf8490737ba2adc6a302664f5326e7741b6d5ab"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:9903f017b9d6f2f69ce241b424ddad7265624f64dc6eafbe257d45661febf8bd"}, + {file = "Bottleneck-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:834816c316ad184cae7ecb615b69876a42cd2cafb07ee66c57a9c1ccacb63339"}, + {file = "Bottleneck-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:03c43150f180d86a5633a6da788660d335983f6798fca306ba7f47ff27a1b7e7"}, + {file = "Bottleneck-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea333dbcadb780356c54f5c4fa7754f143573b57508fff43d5daf63298eb26a"}, + {file = "Bottleneck-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6179791c0119aec3708ef74ddadab8d183e3742adb93a9028718e8696bdf572b"}, + {file = "Bottleneck-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:220b72405f77aebb0137b733b464c2526ded471e4289ac1e840bab8852759a55"}, + {file = "Bottleneck-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8746f0f727997ce4c7457dc1fec4e4e3c0fdd8803514baa3d1c4ea6515ab04b2"}, + {file = "Bottleneck-1.4.0-cp38-cp38-win32.whl", hash = "sha256:6a36280ee33d9db799163f04e88b950261e590cc71d089f5e179b21680b5d491"}, + {file = "Bottleneck-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:de17e012694e6a987bb4eb050dd7f0cf939195a8e00cb23aa93ebee5fd5e64a8"}, + {file = "Bottleneck-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28260197ab8a4a6b7adf810523147b1a3e85607f4e26a0f685eb9d155cfc75af"}, + {file = "Bottleneck-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90d5d188a0cca0b9655ff2904ee61e7f183079e97550be98c2541a2eec358a72"}, + {file = "Bottleneck-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2861ff645d236f1a6f5c6d1ddb3db37d19af1d91057bdc4fd7b76299a15b3079"}, + {file = "Bottleneck-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6136ce7dcf825c432a20b80ab1c460264a437d8430fff32536176147e0b6b832"}, + {file = "Bottleneck-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:889e6855b77345622b4ba927335d3118745d590492941f5f78554f157d259e92"}, + {file = "Bottleneck-1.4.0-cp39-cp39-win32.whl", hash = "sha256:817aa43a671ede696ea023d8f35839a391244662340cc95a0f46965dda8b35cf"}, + {file = "Bottleneck-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:23834d82177d6997f21fa63156550668cd07a9a6e5a1b66ea80f1a14ac6ffd07"}, + {file = "bottleneck-1.4.0.tar.gz", hash = "sha256:beb36df519b8709e7d357c0c9639b03b885ca6355bbf5e53752c685de51605b8"}, ] [package.dependencies] @@ -866,13 +865,13 @@ zstd = ["zstandard (==0.22.0)"] [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -1088,13 +1087,13 @@ numpy = "*" [[package]] name = "chromadb" -version = "0.5.1" +version = "0.5.3" description = "Chroma." optional = false python-versions = ">=3.8" files = [ - {file = "chromadb-0.5.1-py3-none-any.whl", hash = "sha256:61f1f75a672b6edce7f1c8875c67e2aaaaf130dc1c1684431fbc42ad7240d01d"}, - {file = "chromadb-0.5.1.tar.gz", hash = "sha256:e2b2b6a34c2a949bedcaa42fa7775f40c7f6667848fc8094dcbf97fc0d30bee7"}, + {file = "chromadb-0.5.3-py3-none-any.whl", hash = "sha256:b3874f08356e291c68c6d2e177db472cd51f22f3af7b9746215b748fd1e29982"}, + {file = "chromadb-0.5.3.tar.gz", hash = "sha256:05d887f56a46b2e0fc6ac5ab979503a27b9ee50d5ca9e455f83b2fb9840cd026"}, ] [package.dependencies] @@ -1841,33 +1840,32 @@ files = [ [[package]] name = "duckduckgo-search" -version = "6.1.6" +version = "6.1.9" description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine." optional = false python-versions = ">=3.8" files = [ - {file = "duckduckgo_search-6.1.6-py3-none-any.whl", hash = "sha256:6139ab17579e96ca7c5ed9398365245a36ecca8e7432545e3115ef90a9304eb7"}, - {file = "duckduckgo_search-6.1.6.tar.gz", hash = "sha256:42c83d58f4f1d717a580b89cc86861cbae59e46e75288243776c53349d006bf1"}, + {file = "duckduckgo_search-6.1.9-py3-none-any.whl", hash = "sha256:a208babf87b971290b1afed9908bc5ab6ac6c1738b90b48ad613267f7630cb77"}, + {file = "duckduckgo_search-6.1.9.tar.gz", hash = "sha256:0d7d746e003d6b3bcd0d0dc11927c9a69b6fa271f3b3f65df6f01ea4d9d2689d"}, ] [package.dependencies] click = ">=8.1.7" -orjson = ">=3.10.4" -pyreqwest-impersonate = ">=0.4.7" +pyreqwest-impersonate = ">=0.4.9" [package.extras] -dev = ["mypy (>=1.10.0)", "pytest (>=8.2.2)", "pytest-asyncio (>=0.23.7)", "ruff (>=0.4.8)"] +dev = ["mypy (>=1.10.1)", "pytest (>=8.2.2)", "pytest-asyncio (>=0.23.7)", "ruff (>=0.5.0)"] lxml = ["lxml (>=5.2.2)"] [[package]] name = "email-validator" -version = "2.1.1" +version = "2.2.0" description = "A robust email address syntax and deliverability validation library." optional = false python-versions = ">=3.8" files = [ - {file = "email_validator-2.1.1-py3-none-any.whl", hash = "sha256:97d882d174e2a65732fb43bfce81a3a834cbc1bde8bf419e30ef5ea976370a05"}, - {file = "email_validator-2.1.1.tar.gz", hash = "sha256:200a70680ba08904be6d1eef729205cc0d687634399a5924d842533efb824b84"}, + {file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"}, + {file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"}, ] [package.dependencies] @@ -2058,18 +2056,18 @@ sgmllib3k = "*" [[package]] name = "filelock" -version = "3.14.0" +version = "3.15.4" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ - {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, - {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, + {file = "filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"}, + {file = "filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-asyncio (>=0.21)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)", "virtualenv (>=20.26.2)"] typing = ["typing-extensions (>=4.8)"] [[package]] @@ -2083,20 +2081,6 @@ files = [ {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"}, ] -[[package]] -name = "firecrawl-py" -version = "0.0.5" -description = "Python SDK for Firecrawl API" -optional = false -python-versions = "*" -files = [ - {file = "firecrawl-py-0.0.5.tar.gz", hash = "sha256:3d1cc30b7d86c12aa06e6434ebb526072cd70ab9a0c8b145008efe044a1cd09c"}, - {file = "firecrawl_py-0.0.5-py3-none-any.whl", hash = "sha256:476694345141c0145a1bee9c01a8ad0103f75892c12a122dc511a3adad0785e7"}, -] - -[package.dependencies] -requests = "*" - [[package]] name = "flask" version = "3.0.3" @@ -2246,53 +2230,53 @@ files = [ [[package]] name = "fonttools" -version = "4.53.0" +version = "4.53.1" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.53.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20"}, - {file = "fonttools-4.53.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6"}, - {file = "fonttools-4.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9"}, - {file = "fonttools-4.53.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca"}, - {file = "fonttools-4.53.0-cp310-cp310-win32.whl", hash = "sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068"}, - {file = "fonttools-4.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec"}, - {file = "fonttools-4.53.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161"}, - {file = "fonttools-4.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6"}, - {file = "fonttools-4.53.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e"}, - {file = "fonttools-4.53.0-cp311-cp311-win32.whl", hash = "sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005"}, - {file = "fonttools-4.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a"}, - {file = "fonttools-4.53.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06"}, - {file = "fonttools-4.53.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109"}, - {file = "fonttools-4.53.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2"}, - {file = "fonttools-4.53.0-cp312-cp312-win32.whl", hash = "sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea"}, - {file = "fonttools-4.53.0-cp312-cp312-win_amd64.whl", hash = "sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12"}, - {file = "fonttools-4.53.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce"}, - {file = "fonttools-4.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206"}, - {file = "fonttools-4.53.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd"}, - {file = "fonttools-4.53.0-cp38-cp38-win32.whl", hash = "sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"}, - {file = "fonttools-4.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac"}, - {file = "fonttools-4.53.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1"}, - {file = "fonttools-4.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64"}, - {file = "fonttools-4.53.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0"}, - {file = "fonttools-4.53.0-cp39-cp39-win32.whl", hash = "sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9"}, - {file = "fonttools-4.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2"}, - {file = "fonttools-4.53.0-py3-none-any.whl", hash = "sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4"}, - {file = "fonttools-4.53.0.tar.gz", hash = "sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, + {file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, + {file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, + {file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, + {file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, + {file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, + {file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, + {file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, + {file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, + {file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, + {file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, + {file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, + {file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, + {file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, + {file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, + {file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, + {file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, + {file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, + {file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, + {file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, + {file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, + {file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, + {file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, + {file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, + {file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, + {file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, + {file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, + {file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, ] [package.extras] @@ -2439,13 +2423,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.6.0" +version = "2024.6.1" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.6.0-py3-none-any.whl", hash = "sha256:58d7122eb8a1a46f7f13453187bfea4972d66bf01618d37366521b1998034cee"}, - {file = "fsspec-2024.6.0.tar.gz", hash = "sha256:f579960a56e6d8038a9efc8f9c77279ec12e6299aa86b0769a7e9c46b94527c2"}, + {file = "fsspec-2024.6.1-py3-none-any.whl", hash = "sha256:3cb443f8bcd2efb31295a5b9fdb02aee81d8452c80d28f97a6d0959e6cee101e"}, + {file = "fsspec-2024.6.1.tar.gz", hash = "sha256:fad7d7e209dd4c1208e3bbfda706620e0da5142bebbd9c384afb95b07e798e49"}, ] [package.extras] @@ -2754,13 +2738,13 @@ xai = ["tensorflow (>=2.3.0,<3.0.0dev)"] [[package]] name = "google-cloud-bigquery" -version = "3.24.0" +version = "3.25.0" description = "Google BigQuery API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-bigquery-3.24.0.tar.gz", hash = "sha256:e95e6f6e0aa32e6c453d44e2b3298931fdd7947c309ea329a31b6ff1f939e17e"}, - {file = "google_cloud_bigquery-3.24.0-py2.py3-none-any.whl", hash = "sha256:bc08323ce99dee4e811b7c3d0cde8929f5bf0b1aeaed6bcd75fc89796dd87652"}, + {file = "google-cloud-bigquery-3.25.0.tar.gz", hash = "sha256:5b2aff3205a854481117436836ae1403f11f2594e6810a98886afd57eda28509"}, + {file = "google_cloud_bigquery-3.25.0-py2.py3-none-any.whl", hash = "sha256:7f0c371bc74d2a7fb74dacbc00ac0f90c8c2bec2289b51dd6685a275873b1ce9"}, ] [package.dependencies] @@ -3053,19 +3037,19 @@ test = ["objgraph", "psutil"] [[package]] name = "grpc-google-iam-v1" -version = "0.13.0" +version = "0.13.1" description = "IAM API client library" optional = false python-versions = ">=3.7" files = [ - {file = "grpc-google-iam-v1-0.13.0.tar.gz", hash = "sha256:fad318608b9e093258fbf12529180f400d1c44453698a33509cc6ecf005b294e"}, - {file = "grpc_google_iam_v1-0.13.0-py2.py3-none-any.whl", hash = "sha256:53902e2af7de8df8c1bd91373d9be55b0743ec267a7428ea638db3775becae89"}, + {file = "grpc-google-iam-v1-0.13.1.tar.gz", hash = "sha256:3ff4b2fd9d990965e410965253c0da6f66205d5a8291c4c31c6ebecca18a9001"}, + {file = "grpc_google_iam_v1-0.13.1-py2.py3-none-any.whl", hash = "sha256:c3e86151a981811f30d5e7330f271cee53e73bb87755e88cc3b6f0c7b5fe374e"}, ] [package.dependencies] googleapis-common-protos = {version = ">=1.56.0,<2.0.0dev", extras = ["grpc"]} grpcio = ">=1.44.0,<2.0.0dev" -protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev" [[package]] name = "grpcio" @@ -3918,16 +3902,17 @@ six = "*" [[package]] name = "langfuse" -version = "2.36.2" +version = "2.38.0" description = "A client library for accessing langfuse" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langfuse-2.36.2-py3-none-any.whl", hash = "sha256:66728feddcec0974e4eb31612151a282fcce2e333b5a61474182b5e67e78e090"}, - {file = "langfuse-2.36.2.tar.gz", hash = "sha256:3e784505d408aa2c9c2da79487b64d185d8f7fa8a855e5303bcce678454c715b"}, + {file = "langfuse-2.38.0-py3-none-any.whl", hash = "sha256:9e81757b88d26acb8949dbd1d25153df49f4ce8da39e5347c4aa23c3b9d4559c"}, + {file = "langfuse-2.38.0.tar.gz", hash = "sha256:0022a805a167d2e436759ac48b5efb45db2910b02e2f934e47eaf481ad3b21f5"}, ] [package.dependencies] +anyio = ">=4.4.0,<5.0.0" backoff = ">=1.10.0" httpx = ">=0.15.4,<1.0" idna = ">=3.7,<4.0" @@ -3942,48 +3927,51 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.81" +version = "0.1.83" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, - {file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, + {file = "langsmith-0.1.83-py3-none-any.whl", hash = "sha256:f54d8cd8479b648b6339f3f735d19292c3516d080f680933ecdca3eab4b67ed3"}, + {file = "langsmith-0.1.83.tar.gz", hash = "sha256:5cdd947212c8ad19adb992c06471c860185a777daa6859bb47150f90daf64bf3"}, ] [package.dependencies] orjson = ">=3.9.14,<4.0.0" -pydantic = ">=1,<3" +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] requests = ">=2,<3" [[package]] name = "llvmlite" -version = "0.42.0" +version = "0.43.0" description = "lightweight wrapper around basic LLVM functionality" optional = false python-versions = ">=3.9" files = [ - {file = "llvmlite-0.42.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3366938e1bf63d26c34fbfb4c8e8d2ded57d11e0567d5bb243d89aab1eb56098"}, - {file = "llvmlite-0.42.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c35da49666a21185d21b551fc3caf46a935d54d66969d32d72af109b5e7d2b6f"}, - {file = "llvmlite-0.42.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70f44ccc3c6220bd23e0ba698a63ec2a7d3205da0d848804807f37fc243e3f77"}, - {file = "llvmlite-0.42.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763f8d8717a9073b9e0246998de89929071d15b47f254c10eef2310b9aac033d"}, - {file = "llvmlite-0.42.0-cp310-cp310-win_amd64.whl", hash = "sha256:8d90edf400b4ceb3a0e776b6c6e4656d05c7187c439587e06f86afceb66d2be5"}, - {file = "llvmlite-0.42.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ae511caed28beaf1252dbaf5f40e663f533b79ceb408c874c01754cafabb9cbf"}, - {file = "llvmlite-0.42.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81e674c2fe85576e6c4474e8c7e7aba7901ac0196e864fe7985492b737dbab65"}, - {file = "llvmlite-0.42.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb3975787f13eb97629052edb5017f6c170eebc1c14a0433e8089e5db43bcce6"}, - {file = "llvmlite-0.42.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5bece0cdf77f22379f19b1959ccd7aee518afa4afbd3656c6365865f84903f9"}, - {file = "llvmlite-0.42.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e0c4c11c8c2aa9b0701f91b799cb9134a6a6de51444eff5a9087fc7c1384275"}, - {file = "llvmlite-0.42.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:08fa9ab02b0d0179c688a4216b8939138266519aaa0aa94f1195a8542faedb56"}, - {file = "llvmlite-0.42.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b2fce7d355068494d1e42202c7aff25d50c462584233013eb4470c33b995e3ee"}, - {file = "llvmlite-0.42.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebe66a86dc44634b59a3bc860c7b20d26d9aaffcd30364ebe8ba79161a9121f4"}, - {file = "llvmlite-0.42.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d47494552559e00d81bfb836cf1c4d5a5062e54102cc5767d5aa1e77ccd2505c"}, - {file = "llvmlite-0.42.0-cp312-cp312-win_amd64.whl", hash = "sha256:05cb7e9b6ce69165ce4d1b994fbdedca0c62492e537b0cc86141b6e2c78d5888"}, - {file = "llvmlite-0.42.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdd3888544538a94d7ec99e7c62a0cdd8833609c85f0c23fcb6c5c591aec60ad"}, - {file = "llvmlite-0.42.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d0936c2067a67fb8816c908d5457d63eba3e2b17e515c5fe00e5ee2bace06040"}, - {file = "llvmlite-0.42.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a78ab89f1924fc11482209f6799a7a3fc74ddc80425a7a3e0e8174af0e9e2301"}, - {file = "llvmlite-0.42.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7599b65c7af7abbc978dbf345712c60fd596aa5670496561cc10e8a71cebfb2"}, - {file = "llvmlite-0.42.0-cp39-cp39-win_amd64.whl", hash = "sha256:43d65cc4e206c2e902c1004dd5418417c4efa6c1d04df05c6c5675a27e8ca90e"}, - {file = "llvmlite-0.42.0.tar.gz", hash = "sha256:f92b09243c0cc3f457da8b983f67bd8e1295d0f5b3746c7a1861d7a99403854a"}, + {file = "llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761"}, + {file = "llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead"}, + {file = "llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a"}, + {file = "llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98"}, + {file = "llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2"}, + {file = "llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749"}, + {file = "llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7"}, + {file = "llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f"}, + {file = "llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844"}, + {file = "llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9cd2a7376f7b3367019b664c21f0c61766219faa3b03731113ead75107f3b66c"}, + {file = "llvmlite-0.43.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18e9953c748b105668487b7c81a3e97b046d8abf95c4ddc0cd3c94f4e4651ae8"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74937acd22dc11b33946b67dca7680e6d103d6e90eeaaaf932603bec6fe7b03a"}, + {file = "llvmlite-0.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9efc739cc6ed760f795806f67889923f7274276f0eb45092a1473e40d9b867"}, + {file = "llvmlite-0.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:47e147cdda9037f94b399bf03bfd8a6b6b1f2f90be94a454e3386f006455a9b4"}, + {file = "llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5"}, ] [[package]] @@ -4441,13 +4429,13 @@ tests = ["pytest (>=4.6)"] [[package]] name = "msal" -version = "1.28.1" +version = "1.29.0" description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." optional = false python-versions = ">=3.7" files = [ - {file = "msal-1.28.1-py3-none-any.whl", hash = "sha256:563c2d70de77a2ca9786aab84cb4e133a38a6897e6676774edc23d610bfc9e7b"}, - {file = "msal-1.28.1.tar.gz", hash = "sha256:d72bbfe2d5c2f2555f4bc6205be4450ddfd12976610dd9a16a9ab0f05c68b64d"}, + {file = "msal-1.29.0-py3-none-any.whl", hash = "sha256:6b301e63f967481f0cc1a3a3bac0cf322b276855bc1b0955468d9deb3f33d511"}, + {file = "msal-1.29.0.tar.gz", hash = "sha256:8f6725f099752553f9b2fe84125e2a5ebe47b49f92eacca33ebedd3a9ebaae25"}, ] [package.dependencies] @@ -4460,22 +4448,18 @@ broker = ["pymsalruntime (>=0.13.2,<0.17)"] [[package]] name = "msal-extensions" -version = "1.1.0" +version = "1.2.0" description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." optional = false python-versions = ">=3.7" files = [ - {file = "msal-extensions-1.1.0.tar.gz", hash = "sha256:6ab357867062db7b253d0bd2df6d411c7891a0ee7308d54d1e4317c1d1c54252"}, - {file = "msal_extensions-1.1.0-py3-none-any.whl", hash = "sha256:01be9711b4c0b1a151450068eeb2c4f0997df3bba085ac299de3a66f585e382f"}, + {file = "msal_extensions-1.2.0-py3-none-any.whl", hash = "sha256:cf5ba83a2113fa6dc011a254a72f1c223c88d7dfad74cc30617c4679a417704d"}, + {file = "msal_extensions-1.2.0.tar.gz", hash = "sha256:6f41b320bfd2933d631a215c91ca0dd3e67d84bd1a2f50ce917d5874ec646bef"}, ] [package.dependencies] -msal = ">=0.4.1,<2.0.0" -packaging = "*" -portalocker = [ - {version = ">=1.0,<3", markers = "platform_system != \"Windows\""}, - {version = ">=1.6,<3", markers = "platform_system == \"Windows\""}, -] +msal = ">=1.29,<2" +portalocker = ">=1.4,<3" [[package]] name = "msg-parser" @@ -4705,37 +4689,37 @@ requests = ">=2.27.1" [[package]] name = "numba" -version = "0.59.1" +version = "0.60.0" description = "compiling Python code using LLVM" optional = false python-versions = ">=3.9" files = [ - {file = "numba-0.59.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97385a7f12212c4f4bc28f648720a92514bee79d7063e40ef66c2d30600fd18e"}, - {file = "numba-0.59.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0b77aecf52040de2a1eb1d7e314497b9e56fba17466c80b457b971a25bb1576d"}, - {file = "numba-0.59.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3476a4f641bfd58f35ead42f4dcaf5f132569c4647c6f1360ccf18ee4cda3990"}, - {file = "numba-0.59.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:525ef3f820931bdae95ee5379c670d5c97289c6520726bc6937a4a7d4230ba24"}, - {file = "numba-0.59.1-cp310-cp310-win_amd64.whl", hash = "sha256:990e395e44d192a12105eca3083b61307db7da10e093972ca285c85bef0963d6"}, - {file = "numba-0.59.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43727e7ad20b3ec23ee4fc642f5b61845c71f75dd2825b3c234390c6d8d64051"}, - {file = "numba-0.59.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:411df625372c77959570050e861981e9d196cc1da9aa62c3d6a836b5cc338966"}, - {file = "numba-0.59.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2801003caa263d1e8497fb84829a7ecfb61738a95f62bc05693fcf1733e978e4"}, - {file = "numba-0.59.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dd2842fac03be4e5324ebbbd4d2d0c8c0fc6e0df75c09477dd45b288a0777389"}, - {file = "numba-0.59.1-cp311-cp311-win_amd64.whl", hash = "sha256:0594b3dfb369fada1f8bb2e3045cd6c61a564c62e50cf1f86b4666bc721b3450"}, - {file = "numba-0.59.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1cce206a3b92836cdf26ef39d3a3242fec25e07f020cc4feec4c4a865e340569"}, - {file = "numba-0.59.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8c8b4477763cb1fbd86a3be7050500229417bf60867c93e131fd2626edb02238"}, - {file = "numba-0.59.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d80bce4ef7e65bf895c29e3889ca75a29ee01da80266a01d34815918e365835"}, - {file = "numba-0.59.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f7ad1d217773e89a9845886401eaaab0a156a90aa2f179fdc125261fd1105096"}, - {file = "numba-0.59.1-cp312-cp312-win_amd64.whl", hash = "sha256:5bf68f4d69dd3a9f26a9b23548fa23e3bcb9042e2935257b471d2a8d3c424b7f"}, - {file = "numba-0.59.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e0318ae729de6e5dbe64c75ead1a95eb01fabfe0e2ebed81ebf0344d32db0ae"}, - {file = "numba-0.59.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0f68589740a8c38bb7dc1b938b55d1145244c8353078eea23895d4f82c8b9ec1"}, - {file = "numba-0.59.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:649913a3758891c77c32e2d2a3bcbedf4a69f5fea276d11f9119677c45a422e8"}, - {file = "numba-0.59.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9712808e4545270291d76b9a264839ac878c5eb7d8b6e02c970dc0ac29bc8187"}, - {file = "numba-0.59.1-cp39-cp39-win_amd64.whl", hash = "sha256:8d51ccd7008a83105ad6a0082b6a2b70f1142dc7cfd76deb8c5a862367eb8c86"}, - {file = "numba-0.59.1.tar.gz", hash = "sha256:76f69132b96028d2774ed20415e8c528a34e3299a40581bae178f0994a2f370b"}, -] - -[package.dependencies] -llvmlite = "==0.42.*" -numpy = ">=1.22,<1.27" + {file = "numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651"}, + {file = "numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781"}, + {file = "numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e"}, + {file = "numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198"}, + {file = "numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8"}, + {file = "numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703"}, + {file = "numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8"}, + {file = "numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2"}, + {file = "numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404"}, + {file = "numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e"}, + {file = "numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d"}, + {file = "numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347"}, + {file = "numba-0.60.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:01ef4cd7d83abe087d644eaa3d95831b777aa21d441a23703d649e06b8e06b74"}, + {file = "numba-0.60.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:819a3dfd4630d95fd574036f99e47212a1af41cbcb019bf8afac63ff56834449"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b983bd6ad82fe868493012487f34eae8bf7dd94654951404114f23c3466d34b"}, + {file = "numba-0.60.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c151748cd269ddeab66334bd754817ffc0cabd9433acb0f551697e5151917d25"}, + {file = "numba-0.60.0-cp39-cp39-win_amd64.whl", hash = "sha256:3031547a015710140e8c87226b4cfe927cac199835e5bf7d4fe5cb64e814e3ab"}, + {file = "numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16"}, +] + +[package.dependencies] +llvmlite = "==0.43.*" +numpy = ">=1.22,<2.1" [[package]] name = "numexpr" @@ -4868,42 +4852,42 @@ tests = ["pytest", "pytest-cov"] [[package]] name = "onnxruntime" -version = "1.18.0" +version = "1.18.1" description = "ONNX Runtime is a runtime accelerator for Machine Learning models" optional = false python-versions = "*" files = [ - {file = "onnxruntime-1.18.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:5a3b7993a5ecf4a90f35542a4757e29b2d653da3efe06cdd3164b91167bbe10d"}, - {file = "onnxruntime-1.18.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15b944623b2cdfe7f7945690bfb71c10a4531b51997c8320b84e7b0bb59af902"}, - {file = "onnxruntime-1.18.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e61ce5005118064b1a0ed73ebe936bc773a102f067db34108ea6c64dd62a179"}, - {file = "onnxruntime-1.18.0-cp310-cp310-win32.whl", hash = "sha256:a4fc8a2a526eb442317d280610936a9f73deece06c7d5a91e51570860802b93f"}, - {file = "onnxruntime-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:71ed219b768cab004e5cd83e702590734f968679bf93aa488c1a7ffbe6e220c3"}, - {file = "onnxruntime-1.18.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:3d24bd623872a72a7fe2f51c103e20fcca2acfa35d48f2accd6be1ec8633d960"}, - {file = "onnxruntime-1.18.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f15e41ca9b307a12550bfd2ec93f88905d9fba12bab7e578f05138ad0ae10d7b"}, - {file = "onnxruntime-1.18.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f45ca2887f62a7b847d526965686b2923efa72538c89b7703c7b3fe970afd59"}, - {file = "onnxruntime-1.18.0-cp311-cp311-win32.whl", hash = "sha256:9e24d9ecc8781323d9e2eeda019b4b24babc4d624e7d53f61b1fe1a929b0511a"}, - {file = "onnxruntime-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:f8608398976ed18aef450d83777ff6f77d0b64eced1ed07a985e1a7db8ea3771"}, - {file = "onnxruntime-1.18.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:f1d79941f15fc40b1ee67738b2ca26b23e0181bf0070b5fb2984f0988734698f"}, - {file = "onnxruntime-1.18.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99e8caf3a8565c853a22d323a3eebc2a81e3de7591981f085a4f74f7a60aab2d"}, - {file = "onnxruntime-1.18.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:498d2b8380635f5e6ebc50ec1b45f181588927280f32390fb910301d234f97b8"}, - {file = "onnxruntime-1.18.0-cp312-cp312-win32.whl", hash = "sha256:ba7cc0ce2798a386c082aaa6289ff7e9bedc3dee622eef10e74830cff200a72e"}, - {file = "onnxruntime-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:1fa175bd43f610465d5787ae06050c81f7ce09da2bf3e914eb282cb8eab363ef"}, - {file = "onnxruntime-1.18.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:0284c579c20ec8b1b472dd190290a040cc68b6caec790edb960f065d15cf164a"}, - {file = "onnxruntime-1.18.0-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d47353d036d8c380558a5643ea5f7964d9d259d31c86865bad9162c3e916d1f6"}, - {file = "onnxruntime-1.18.0-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:885509d2b9ba4b01f08f7fa28d31ee54b6477953451c7ccf124a84625f07c803"}, - {file = "onnxruntime-1.18.0-cp38-cp38-win32.whl", hash = "sha256:8614733de3695656411d71fc2f39333170df5da6c7efd6072a59962c0bc7055c"}, - {file = "onnxruntime-1.18.0-cp38-cp38-win_amd64.whl", hash = "sha256:47af3f803752fce23ea790fd8d130a47b2b940629f03193f780818622e856e7a"}, - {file = "onnxruntime-1.18.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:9153eb2b4d5bbab764d0aea17adadffcfc18d89b957ad191b1c3650b9930c59f"}, - {file = "onnxruntime-1.18.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c7fd86eca727c989bb8d9c5104f3c45f7ee45f445cc75579ebe55d6b99dfd7c"}, - {file = "onnxruntime-1.18.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac67a4de9c1326c4d87bcbfb652c923039b8a2446bb28516219236bec3b494f5"}, - {file = "onnxruntime-1.18.0-cp39-cp39-win32.whl", hash = "sha256:6ffb445816d06497df7a6dd424b20e0b2c39639e01e7fe210e247b82d15a23b9"}, - {file = "onnxruntime-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:46de6031cb6745f33f7eca9e51ab73e8c66037fb7a3b6b4560887c5b55ab5d5d"}, + {file = "onnxruntime-1.18.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:29ef7683312393d4ba04252f1b287d964bd67d5e6048b94d2da3643986c74d80"}, + {file = "onnxruntime-1.18.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc706eb1df06ddf55776e15a30519fb15dda7697f987a2bbda4962845e3cec05"}, + {file = "onnxruntime-1.18.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7de69f5ced2a263531923fa68bbec52a56e793b802fcd81a03487b5e292bc3a"}, + {file = "onnxruntime-1.18.1-cp310-cp310-win32.whl", hash = "sha256:221e5b16173926e6c7de2cd437764492aa12b6811f45abd37024e7cf2ae5d7e3"}, + {file = "onnxruntime-1.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:75211b619275199c861ee94d317243b8a0fcde6032e5a80e1aa9ded8ab4c6060"}, + {file = "onnxruntime-1.18.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:f26582882f2dc581b809cfa41a125ba71ad9e715738ec6402418df356969774a"}, + {file = "onnxruntime-1.18.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef36f3a8b768506d02be349ac303fd95d92813ba3ba70304d40c3cd5c25d6a4c"}, + {file = "onnxruntime-1.18.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:170e711393e0618efa8ed27b59b9de0ee2383bd2a1f93622a97006a5ad48e434"}, + {file = "onnxruntime-1.18.1-cp311-cp311-win32.whl", hash = "sha256:9b6a33419b6949ea34e0dc009bc4470e550155b6da644571ecace4b198b0d88f"}, + {file = "onnxruntime-1.18.1-cp311-cp311-win_amd64.whl", hash = "sha256:5c1380a9f1b7788da742c759b6a02ba771fe1ce620519b2b07309decbd1a2fe1"}, + {file = "onnxruntime-1.18.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:31bd57a55e3f983b598675dfc7e5d6f0877b70ec9864b3cc3c3e1923d0a01919"}, + {file = "onnxruntime-1.18.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9e03c4ba9f734500691a4d7d5b381cd71ee2f3ce80a1154ac8f7aed99d1ecaa"}, + {file = "onnxruntime-1.18.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:781aa9873640f5df24524f96f6070b8c550c66cb6af35710fd9f92a20b4bfbf6"}, + {file = "onnxruntime-1.18.1-cp312-cp312-win32.whl", hash = "sha256:3a2d9ab6254ca62adbb448222e630dc6883210f718065063518c8f93a32432be"}, + {file = "onnxruntime-1.18.1-cp312-cp312-win_amd64.whl", hash = "sha256:ad93c560b1c38c27c0275ffd15cd7f45b3ad3fc96653c09ce2931179982ff204"}, + {file = "onnxruntime-1.18.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:3b55dc9d3c67626388958a3eb7ad87eb7c70f75cb0f7ff4908d27b8b42f2475c"}, + {file = "onnxruntime-1.18.1-cp38-cp38-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f80dbcfb6763cc0177a31168b29b4bd7662545b99a19e211de8c734b657e0669"}, + {file = "onnxruntime-1.18.1-cp38-cp38-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1ff2c61a16d6c8631796c54139bafea41ee7736077a0fc64ee8ae59432f5c58"}, + {file = "onnxruntime-1.18.1-cp38-cp38-win32.whl", hash = "sha256:219855bd272fe0c667b850bf1a1a5a02499269a70d59c48e6f27f9c8bcb25d02"}, + {file = "onnxruntime-1.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:afdf16aa607eb9a2c60d5ca2d5abf9f448e90c345b6b94c3ed14f4fb7e6a2d07"}, + {file = "onnxruntime-1.18.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:128df253ade673e60cea0955ec9d0e89617443a6d9ce47c2d79eb3f72a3be3de"}, + {file = "onnxruntime-1.18.1-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9839491e77e5c5a175cab3621e184d5a88925ee297ff4c311b68897197f4cde9"}, + {file = "onnxruntime-1.18.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad3187c1faff3ac15f7f0e7373ef4788c582cafa655a80fdbb33eaec88976c66"}, + {file = "onnxruntime-1.18.1-cp39-cp39-win32.whl", hash = "sha256:34657c78aa4e0b5145f9188b550ded3af626651b15017bf43d280d7e23dbf195"}, + {file = "onnxruntime-1.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:9c14fd97c3ddfa97da5feef595e2c73f14c2d0ec1d4ecbea99c8d96603c89589"}, ] [package.dependencies] coloredlogs = "*" flatbuffers = "*" -numpy = ">=1.21.6" +numpy = ">=1.21.6,<2.0" packaging = "*" protobuf = "*" sympy = "*" @@ -4933,13 +4917,13 @@ datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] [[package]] name = "openpyxl" -version = "3.1.3" +version = "3.1.5" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "openpyxl-3.1.3-py2.py3-none-any.whl", hash = "sha256:25071b558db709de9e8782c3d3e058af3b23ffb2fc6f40c8f0c45a154eced2c3"}, - {file = "openpyxl-3.1.3.tar.gz", hash = "sha256:8dd482e5350125b2388070bb2477927be2e8ebc27df61178709bc8c8751da2f9"}, + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, ] [package.dependencies] @@ -5176,57 +5160,62 @@ cryptography = ">=3.2.1" [[package]] name = "orjson" -version = "3.10.4" +version = "3.10.6" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.4-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:afca963f19ca60c7aedadea9979f769139127288dd58ccf3f7c5e8e6dc62cabf"}, - {file = "orjson-3.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b112eff36ba7ccc7a9d6b87e17b9d6bde4312d05e3ddf66bf5662481dee846"}, - {file = "orjson-3.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02b192eaba048b1039eca9a0cef67863bd5623042f5c441889a9957121d97e14"}, - {file = "orjson-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:827c3d0e4fc44242c82bfdb1a773235b8c0575afee99a9fa9a8ce920c14e440f"}, - {file = "orjson-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca8ec09724f10ec209244caeb1f9f428b6bb03f2eda9ed5e2c4dd7f2b7fabd44"}, - {file = "orjson-3.10.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8eaa5d531a8fde11993cbcb27e9acf7d9c457ba301adccb7fa3a021bfecab46c"}, - {file = "orjson-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e112aa7fc4ea67367ec5e86c39a6bb6c5719eddc8f999087b1759e765ddaf2d4"}, - {file = "orjson-3.10.4-cp310-none-win32.whl", hash = "sha256:1538844fb88446c42da3889f8c4ecce95a630b5a5ba18ecdfe5aea596f4dff21"}, - {file = "orjson-3.10.4-cp310-none-win_amd64.whl", hash = "sha256:de02811903a2e434127fba5389c3cc90f689542339a6e52e691ab7f693407b5a"}, - {file = "orjson-3.10.4-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:358afaec75de7237dfea08e6b1b25d226e33a1e3b6dc154fc99eb697f24a1ffa"}, - {file = "orjson-3.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb4e292c3198ab3d93e5f877301d2746be4ca0ba2d9c513da5e10eb90e19ff52"}, - {file = "orjson-3.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c39e57cf6323a39238490092985d5d198a7da4a3be013cc891a33fef13a536e"}, - {file = "orjson-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f86df433fc01361ff9270ad27455ce1ad43cd05e46de7152ca6adb405a16b2f6"}, - {file = "orjson-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c9966276a2c97e93e6cbe8286537f88b2a071827514f0d9d47a0aefa77db458"}, - {file = "orjson-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c499a14155a1f5a1e16e0cd31f6cf6f93965ac60a0822bc8340e7e2d3dac1108"}, - {file = "orjson-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3087023ce904a327c29487eb7e1f2c060070e8dbb9a3991b8e7952a9c6e62f38"}, - {file = "orjson-3.10.4-cp311-none-win32.whl", hash = "sha256:f965893244fe348b59e5ce560693e6dd03368d577ce26849b5d261ce31c70101"}, - {file = "orjson-3.10.4-cp311-none-win_amd64.whl", hash = "sha256:c212f06fad6aa6ce85d5665e91a83b866579f29441a47d3865c57329c0857357"}, - {file = "orjson-3.10.4-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d0965a8b0131959833ca8a65af60285995d57ced0de2fd8f16fc03235975d238"}, - {file = "orjson-3.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b64695d9f2aef3ae15a0522e370ec95c946aaea7f2c97a1582a62b3bdd9169"}, - {file = "orjson-3.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:867d882ddee6a20be4c8b03ae3d2b0333894d53ad632d32bd9b8123649577171"}, - {file = "orjson-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0667458f8a8ceb6dee5c08fec0b46195f92c474cbbec71dca2a6b7fd5b67b8d"}, - {file = "orjson-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3eac9befc4eaec1d1ff3bba6210576be4945332dde194525601c5ddb5c060d3"}, - {file = "orjson-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4343245443552eae240a33047a6d1bcac7a754ad4b1c57318173c54d7efb9aea"}, - {file = "orjson-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:30153e269eea43e98918d4d462a36a7065031d9246407dfff2579a4e457515c1"}, - {file = "orjson-3.10.4-cp312-none-win32.whl", hash = "sha256:1a7d092ee043abf3db19c2183115e80676495c9911843fdb3ebd48ca7b73079e"}, - {file = "orjson-3.10.4-cp312-none-win_amd64.whl", hash = "sha256:07a2adbeb8b9efe6d68fc557685954a1f19d9e33f5cc018ae1a89e96647c1b65"}, - {file = "orjson-3.10.4-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f5a746f3d908bce1a1e347b9ca89864047533bdfab5a450066a0315f6566527b"}, - {file = "orjson-3.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:465b4a8a3e459f8d304c19071b4badaa9b267c59207a005a7dd9dfe13d3a423f"}, - {file = "orjson-3.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35858d260728c434a3d91b60685ab32418318567e8902039837e1c2af2719e0b"}, - {file = "orjson-3.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a5ba090d40c4460312dd69c232b38c2ff67a823185cfe667e841c9dd5c06841"}, - {file = "orjson-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dde86755d064664e62e3612a166c28298aa8dfd35a991553faa58855ae739cc"}, - {file = "orjson-3.10.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:020a9e9001cfec85c156ef3b185ff758b62ef986cefdb8384c4579facd5ce126"}, - {file = "orjson-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3bf8e6e3388a2e83a86466c912387e0f0a765494c65caa7e865f99969b76ba0d"}, - {file = "orjson-3.10.4-cp38-none-win32.whl", hash = "sha256:c5a1cca6a4a3129db3da68a25dc0a459a62ae58e284e363b35ab304202d9ba9e"}, - {file = "orjson-3.10.4-cp38-none-win_amd64.whl", hash = "sha256:ecd97d98d7bee3e3d51d0b51c92c457f05db4993329eea7c69764f9820e27eb3"}, - {file = "orjson-3.10.4-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:71362daa330a2fc85553a1469185ac448547392a8f83d34e67779f8df3a52743"}, - {file = "orjson-3.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d24b59d1fecb0fd080c177306118a143f7322335309640c55ed9580d2044e363"}, - {file = "orjson-3.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e906670aea5a605b083ebb58d575c35e88cf880fa372f7cedaac3d51e98ff164"}, - {file = "orjson-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ce32ed4bc4d632268e4978e595fe5ea07e026b751482b4a0feec48f66a90abc"}, - {file = "orjson-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dcd34286246e0c5edd0e230d1da2daab2c1b465fcb6bac85b8d44057229d40a"}, - {file = "orjson-3.10.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c45d4b8c403e50beedb1d006a8916d9910ed56bceaf2035dc253618b44d0a161"}, - {file = "orjson-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:aaed3253041b5002a4f5bfdf6f7b5cce657d974472b0699a469d439beba40381"}, - {file = "orjson-3.10.4-cp39-none-win32.whl", hash = "sha256:9a4f41b7dbf7896f8dbf559b9b43dcd99e31e0d49ac1b59d74f52ce51ab10eb9"}, - {file = "orjson-3.10.4-cp39-none-win_amd64.whl", hash = "sha256:6c4eb7d867ed91cb61e6514cb4f457aa01d7b0fd663089df60a69f3d38b69d4c"}, - {file = "orjson-3.10.4.tar.gz", hash = "sha256:c912ed25b787c73fe994a5decd81c3f3b256599b8a87d410d799d5d52013af2a"}, + {file = "orjson-3.10.6-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fb0ee33124db6eaa517d00890fc1a55c3bfe1cf78ba4a8899d71a06f2d6ff5c7"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c1c4b53b24a4c06547ce43e5fee6ec4e0d8fe2d597f4647fc033fd205707365"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eadc8fd310edb4bdbd333374f2c8fec6794bbbae99b592f448d8214a5e4050c0"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61272a5aec2b2661f4fa2b37c907ce9701e821b2c1285d5c3ab0207ebd358d38"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57985ee7e91d6214c837936dc1608f40f330a6b88bb13f5a57ce5257807da143"}, + {file = "orjson-3.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:633a3b31d9d7c9f02d49c4ab4d0a86065c4a6f6adc297d63d272e043472acab5"}, + {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1c680b269d33ec444afe2bdc647c9eb73166fa47a16d9a75ee56a374f4a45f43"}, + {file = "orjson-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f759503a97a6ace19e55461395ab0d618b5a117e8d0fbb20e70cfd68a47327f2"}, + {file = "orjson-3.10.6-cp310-none-win32.whl", hash = "sha256:95a0cce17f969fb5391762e5719575217bd10ac5a189d1979442ee54456393f3"}, + {file = "orjson-3.10.6-cp310-none-win_amd64.whl", hash = "sha256:df25d9271270ba2133cc88ee83c318372bdc0f2cd6f32e7a450809a111efc45c"}, + {file = "orjson-3.10.6-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b1ec490e10d2a77c345def52599311849fc063ae0e67cf4f84528073152bb2ba"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d43d3feb8f19d07e9f01e5b9be4f28801cf7c60d0fa0d279951b18fae1932b"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3045267e98fe749408eee1593a142e02357c5c99be0802185ef2170086a863"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c27bc6a28ae95923350ab382c57113abd38f3928af3c80be6f2ba7eb8d8db0b0"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d27456491ca79532d11e507cadca37fb8c9324a3976294f68fb1eff2dc6ced5a"}, + {file = "orjson-3.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05ac3d3916023745aa3b3b388e91b9166be1ca02b7c7e41045da6d12985685f0"}, + {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1335d4ef59ab85cab66fe73fd7a4e881c298ee7f63ede918b7faa1b27cbe5212"}, + {file = "orjson-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4bbc6d0af24c1575edc79994c20e1b29e6fb3c6a570371306db0993ecf144dc5"}, + {file = "orjson-3.10.6-cp311-none-win32.whl", hash = "sha256:450e39ab1f7694465060a0550b3f6d328d20297bf2e06aa947b97c21e5241fbd"}, + {file = "orjson-3.10.6-cp311-none-win_amd64.whl", hash = "sha256:227df19441372610b20e05bdb906e1742ec2ad7a66ac8350dcfd29a63014a83b"}, + {file = "orjson-3.10.6-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ea2977b21f8d5d9b758bb3f344a75e55ca78e3ff85595d248eee813ae23ecdfb"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6f3d167d13a16ed263b52dbfedff52c962bfd3d270b46b7518365bcc2121eed"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f710f346e4c44a4e8bdf23daa974faede58f83334289df80bc9cd12fe82573c7"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7275664f84e027dcb1ad5200b8b18373e9c669b2a9ec33d410c40f5ccf4b257e"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0943e4c701196b23c240b3d10ed8ecd674f03089198cf503105b474a4f77f21f"}, + {file = "orjson-3.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:446dee5a491b5bc7d8f825d80d9637e7af43f86a331207b9c9610e2f93fee22a"}, + {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:64c81456d2a050d380786413786b057983892db105516639cb5d3ee3c7fd5148"}, + {file = "orjson-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:960db0e31c4e52fa0fc3ecbaea5b2d3b58f379e32a95ae6b0ebeaa25b93dfd34"}, + {file = "orjson-3.10.6-cp312-none-win32.whl", hash = "sha256:a6ea7afb5b30b2317e0bee03c8d34c8181bc5a36f2afd4d0952f378972c4efd5"}, + {file = "orjson-3.10.6-cp312-none-win_amd64.whl", hash = "sha256:874ce88264b7e655dde4aeaacdc8fd772a7962faadfb41abe63e2a4861abc3dc"}, + {file = "orjson-3.10.6-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:66680eae4c4e7fc193d91cfc1353ad6d01b4801ae9b5314f17e11ba55e934183"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caff75b425db5ef8e8f23af93c80f072f97b4fb3afd4af44482905c9f588da28"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3722fddb821b6036fd2a3c814f6bd9b57a89dc6337b9924ecd614ebce3271394"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2c116072a8533f2fec435fde4d134610f806bdac20188c7bd2081f3e9e0133f"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6eeb13218c8cf34c61912e9df2de2853f1d009de0e46ea09ccdf3d757896af0a"}, + {file = "orjson-3.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965a916373382674e323c957d560b953d81d7a8603fbeee26f7b8248638bd48b"}, + {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03c95484d53ed8e479cade8628c9cea00fd9d67f5554764a1110e0d5aa2de96e"}, + {file = "orjson-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e060748a04cccf1e0a6f2358dffea9c080b849a4a68c28b1b907f272b5127e9b"}, + {file = "orjson-3.10.6-cp38-none-win32.whl", hash = "sha256:738dbe3ef909c4b019d69afc19caf6b5ed0e2f1c786b5d6215fbb7539246e4c6"}, + {file = "orjson-3.10.6-cp38-none-win_amd64.whl", hash = "sha256:d40f839dddf6a7d77114fe6b8a70218556408c71d4d6e29413bb5f150a692ff7"}, + {file = "orjson-3.10.6-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:697a35a083c4f834807a6232b3e62c8b280f7a44ad0b759fd4dce748951e70db"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd502f96bf5ea9a61cbc0b2b5900d0dd68aa0da197179042bdd2be67e51a1e4b"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f215789fb1667cdc874c1b8af6a84dc939fd802bf293a8334fce185c79cd359b"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2debd8ddce948a8c0938c8c93ade191d2f4ba4649a54302a7da905a81f00b56"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5410111d7b6681d4b0d65e0f58a13be588d01b473822483f77f513c7f93bd3b2"}, + {file = "orjson-3.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb1f28a137337fdc18384079fa5726810681055b32b92253fa15ae5656e1dddb"}, + {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bf2fbbce5fe7cd1aa177ea3eab2b8e6a6bc6e8592e4279ed3db2d62e57c0e1b2"}, + {file = "orjson-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:79b9b9e33bd4c517445a62b90ca0cc279b0f1f3970655c3df9e608bc3f91741a"}, + {file = "orjson-3.10.6-cp39-none-win32.whl", hash = "sha256:30b0a09a2014e621b1adf66a4f705f0809358350a757508ee80209b2d8dae219"}, + {file = "orjson-3.10.6-cp39-none-win_amd64.whl", hash = "sha256:49e3bc615652617d463069f91b867a4458114c5b104e13b7ae6872e5f79d0844"}, + {file = "orjson-3.10.6.tar.gz", hash = "sha256:e54b63d0a7c6c54a5f5f726bc93a2078111ef060fec4ecbf34c5db800ca3b3a7"}, ] [[package]] @@ -5396,84 +5385,95 @@ numpy = "*" [[package]] name = "pillow" -version = "10.3.0" +version = "10.4.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] + {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, + {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, + {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, + {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, + {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, + {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, + {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, + {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, + {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, + {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, + {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, + {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, + {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, + {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, + {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, + {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, + {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, + {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, + {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, + {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, + {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, + {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, + {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, + {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, + {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, + {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, + {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, + {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, + {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, + {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, + {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, + {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, + {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, + {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, + {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, + {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, + {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, + {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, + {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -5539,13 +5539,13 @@ files = [ [[package]] name = "portalocker" -version = "2.8.2" +version = "2.10.0" description = "Wraps the portalocker recipe for easy usage" optional = false python-versions = ">=3.8" files = [ - {file = "portalocker-2.8.2-py3-none-any.whl", hash = "sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e"}, - {file = "portalocker-2.8.2.tar.gz", hash = "sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33"}, + {file = "portalocker-2.10.0-py3-none-any.whl", hash = "sha256:48944147b2cd42520549bc1bb8fe44e220296e56f7c3d551bc6ecce69d9b0de1"}, + {file = "portalocker-2.10.0.tar.gz", hash = "sha256:49de8bc0a2f68ca98bf9e219c81a3e6b27097c7bf505a87c5a112ce1aaeb9b81"}, ] [package.dependencies] @@ -5595,20 +5595,20 @@ wcwidth = "*" [[package]] name = "proto-plus" -version = "1.23.0" +version = "1.24.0" description = "Beautiful, Pythonic protocol buffers." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "proto-plus-1.23.0.tar.gz", hash = "sha256:89075171ef11988b3fa157f5dbd8b9cf09d65fffee97e29ce403cd8defba19d2"}, - {file = "proto_plus-1.23.0-py3-none-any.whl", hash = "sha256:a829c79e619e1cf632de091013a4173deed13a55f326ef84f05af6f50ff4c82c"}, + {file = "proto-plus-1.24.0.tar.gz", hash = "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445"}, + {file = "proto_plus-1.24.0-py3-none-any.whl", hash = "sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12"}, ] [package.dependencies] -protobuf = ">=3.19.0,<5.0.0dev" +protobuf = ">=3.19.0,<6.0.0dev" [package.extras] -testing = ["google-api-core[grpc] (>=1.31.5)"] +testing = ["google-api-core (>=1.31.5)"] [[package]] name = "protobuf" @@ -5959,13 +5959,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-extra-types" -version = "2.8.1" +version = "2.8.2" description = "Extra Pydantic types." optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_extra_types-2.8.1-py3-none-any.whl", hash = "sha256:ca3fce71ee46bc1043bdf3d0e3c149a09ab162cb305c4ed8c501a5034a592dd6"}, - {file = "pydantic_extra_types-2.8.1.tar.gz", hash = "sha256:c7cabe403234658207dcefed3489f2e8bfc8f4a8e305e7ab25ee29eceed65b39"}, + {file = "pydantic_extra_types-2.8.2-py3-none-any.whl", hash = "sha256:f2400b3c3553fb7fa09a131967b4edf2d53f01ad9fa89d158784653f2e5c13d1"}, + {file = "pydantic_extra_types-2.8.2.tar.gz", hash = "sha256:4d2b3c52c1e2e4dfa31bf1d5a37b841b09e3c5a08ec2bffca0e07fc2ad7d5c4a"}, ] [package.dependencies] @@ -5980,13 +5980,13 @@ python-ulid = ["python-ulid (>=1,<2)", "python-ulid (>=1,<3)"] [[package]] name = "pydantic-settings" -version = "2.3.3" +version = "2.3.4" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.3.3-py3-none-any.whl", hash = "sha256:e4ed62ad851670975ec11285141db888fd24947f9440bd4380d7d8788d4965de"}, - {file = "pydantic_settings-2.3.3.tar.gz", hash = "sha256:87fda838b64b5039b970cd47c3e8a1ee460ce136278ff672980af21516f6e6ce"}, + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, ] [package.dependencies] @@ -6168,59 +6168,59 @@ files = [ [[package]] name = "pyreqwest-impersonate" -version = "0.4.7" +version = "0.4.9" description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints" optional = false python-versions = ">=3.8" files = [ - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c175dfc429c4231a6ce03841630b236f50995ca613ff1eea26fa4c75c730b562"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3f83c50cef2d5ed0a9246318fd3ef3bfeabe286d4eabf92df4835c05a0be7dc"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34930113aa42f47e0542418f6a67bdb2c23fe0e2fa1866f60b29280a036b829"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88d2792df548b845edd409a3e4284f76cb4fc2510fe4a69fde9e39d54910b935"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b27622d5183185dc63bcab9a7dd1de566688c63b844812b1d9366da7c459a494"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b7bf13d49ef127e659ed134129336e94f7107023ed0138c81a46321b9a580428"}, - {file = "pyreqwest_impersonate-0.4.7-cp310-none-win_amd64.whl", hash = "sha256:0cba006b076b85a875814a4b5dd8cb27f483ebeeb0de83984a3786060fe18e0d"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:370a8cb7a92b15749cbbe3ce7a9f09d35aac7d2a74505eb447f45419ea8ef2ff"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:33244ea10ccee08bac7a7ccdc3a8e6bef6e28f2466ed61de551fa24b76ee4b6a"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba24fb6db822cbd9cbac32539893cc19cc06dd1820e03536e685b9fd2a2ffdd"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e001ed09fc364cc00578fd31c0ae44d543cf75daf06b2657c7a82dcd99336ce"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:608525535f078e85114fcd4eeba0f0771ffc7093c29208e9c0a55147502723bf"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:38daedba0fc997e29cbc25c684a42a04aed38bfbcf85d8f1ffe8f87314d5f72f"}, - {file = "pyreqwest_impersonate-0.4.7-cp311-none-win_amd64.whl", hash = "sha256:d21f3e93ee0aecdc43d2914800bdf23501bde858d70ac7c0b06168f85f95bf22"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5caeee29370a06a322ea6951730d21ec3c641ce46417fd2b5805b283564f2fef"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1c7aa4b428ed58370975d828a95eaf10561712e79a4e2eafca1746a4654a34a8"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:887249adcab35487a44a5428ccab2a6363642785b36649a732d5e649df568b8e"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60f932de8033c15323ba79a7470406ca8228e07aa60078dee5a18e89f0a9fc88"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a2e6332fd6d78623a22f4e747688fe9e6005b61b6f208936d5428d2a65d34b39"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:349b005eef323195685ba5cb2b6f302da0db481e59f03696ef57099f232f0c1f"}, - {file = "pyreqwest_impersonate-0.4.7-cp312-none-win_amd64.whl", hash = "sha256:5620025ac138a10c46a9b14c91b6f58114d50063ff865a2d02ad632751b67b29"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ebf954e09b3dc800a7576c7bde9827b00064531364c7817356c7cc58eb4b46b2"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:112d9561f136548bd67d31cadb6b78d4c31751e526e62e09c6e581c2f1711455"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05213f5f014ecc6732d859a0f51b3dff0424748cc6e2d0d9a42aa1f7108b4eaa"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10fa70529a60fc043650ce03481fab7714e7519c3b06f5e81c95206b8b60aec6"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5b1288881eada1891db7e862c69b673fb159834a41f823b9b00fc52d0f096ccc"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:57ca562229c40615074f36e7f1ae5e57b8164f604eddb042132467c3a00fc2c5"}, - {file = "pyreqwest_impersonate-0.4.7-cp38-none-win_amd64.whl", hash = "sha256:c098ef1333511ea9a43be9a818fcc0866bd2caa63cdc9cf4ab48450ace675646"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:39d961330190bf2d59983ad16dafb4b42d5adcdfe7531ad099c8f3ab53f8d906"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d793591784b89953422b1efaa17460f57f6116de25b3e3065d9fa6cf220ef18"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:945116bb9ffb7e45a87e313f47de28c4da889b14bda620aebc5ba9c3600425cf"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b96a0955c49f346786ee997c755561fecf33b7886cecef861fe4db15c7b23ad3"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ed997197f907ccce9b86a75163b5e78743bc469d2ddcf8a22d4d90c2595573cb"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1f54788f6fb0ee8b31c1eaadba81fb003efb406a768844e2a1a50b855f4806bf"}, - {file = "pyreqwest_impersonate-0.4.7-cp39-none-win_amd64.whl", hash = "sha256:0a679e81b0175dcc670a5ed47a5c184d7031ce16b5c58bf6b2c650ab9f2496c8"}, - {file = "pyreqwest_impersonate-0.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bddb07e04e4006a2184608c44154983fdfa0ce2e230b0a7cec81cd4ba88dd07"}, - {file = "pyreqwest_impersonate-0.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:780c53bfd2fbda151081165733fba5d5b1e17dd61999360110820942e351d011"}, - {file = "pyreqwest_impersonate-0.4.7-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4bfa8ea763e6935e7660f8e885f1b00713b0d22f79a526c6ae6932b1856d1343"}, - {file = "pyreqwest_impersonate-0.4.7-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:96b23b0688a63cbd6c39237461baa95162a69a15e9533789163aabcaf3f572fb"}, - {file = "pyreqwest_impersonate-0.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b0eb56a8ad9d48952c613903d3ef6d8762d48dcec9807a509fee2a43e94ccac"}, - {file = "pyreqwest_impersonate-0.4.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9330176494e260521ea0eaae349ca06128dc527400248c57b378597c470d335c"}, - {file = "pyreqwest_impersonate-0.4.7-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6343bc3392781ff470e5dc47fea9f77bb61d8831b07e901900d31c46decec5d1"}, - {file = "pyreqwest_impersonate-0.4.7-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ecd598e16020a165029647ca80078311bf079e8317bf61c1b2fa824b8967e0db"}, - {file = "pyreqwest_impersonate-0.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a38f3014ac31b08f5fb1ef4e1eb6c6e810f51f6cb815d0066ab3f34ec0f82d98"}, - {file = "pyreqwest_impersonate-0.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db76a97068e5145f5b348037e09a91b2bed9c8eab92e79a3297b1306429fa839"}, - {file = "pyreqwest_impersonate-0.4.7-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1596a8ef8f20bbfe606a90ad524946747846611c8633cbdfbad0a4298b538218"}, - {file = "pyreqwest_impersonate-0.4.7-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dcee18bc350b3d3a0455422c446f1f03f00eb762b3e470066e2bc4664fd7110d"}, - {file = "pyreqwest_impersonate-0.4.7.tar.gz", hash = "sha256:74ba7e6e4f4f753da4f71a7e5dc12625b296bd7d6ddd64093a1fbff14d8d5df7"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a229f56575d992df0c520d93408b4b6b660b304387af06208e7b97d739cce2ff"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c00dbfd0ed878bed231384cd0c823d71a42220ae73c6d982b6fe77d2870338ca"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d4e6ce0e48b73740f08b1aa69cdbded5d66f4eec327d5eaf2ac42a4fce1a008"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690a5c5615b33cbab340e3a4247256ede157ebf39a02f563cff5356bf61c0c51"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7231511ee14faee27b90a84ec74e15515b7e2d1c389710698660765eaed6e2fd"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2fdbe8e146e595c02fa0afb776d70f9e3b351122e2de9af15934b83f3a548ecd"}, + {file = "pyreqwest_impersonate-0.4.9-cp310-none-win_amd64.whl", hash = "sha256:982b0e53db24c084675a056944dd769aa07cd1378abf972927f3f1afb23e08b0"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:60b1102b8aec7bbf91e0f7b8bbc3507776731a9acc6844de764911e8d64f7dd2"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37150478157e683374517d4c0eae0f991b8f5280067a8ee042b6a72fec088843"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc77cd1cdae22dad7549a4e9a1a4630619c2ff443add1b28c7d607accda81eb"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83e99e627d13f1f60d71ce2c2a2b03e1c7f57e8f6a73bde2827ff97cb96f1683"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:72d1adb73264db8c5e24d073d558a895d6690d13a5e38fd857b8b01c33fcbabf"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6253bd8a104316bbece0e6c658d28292f0bf37a99cccfaf476470b98252d185b"}, + {file = "pyreqwest_impersonate-0.4.9-cp311-none-win_amd64.whl", hash = "sha256:7e25628a900236fc76320e790fce90e5502371994523c476af2b1c938382f5fa"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:57e1e7f3bfc175c3229947cdd2b26564bcea2923135b8dec8ab157609e201a7c"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3aeb1c834f54fe685d3c7c0bec65dd981bd988fa3725ee3c7b5656eb7c44a1f7"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27bc384f18099573817d7ed68d12eb67d33dfc5d2b30ab2ac5a69cdf19c22b6f"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd604444ddf86ed222b49dd5e3f050c4c0e980dd7be0b3ea0f208fb70544c4b6"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5206dc7311081accf5b7d021c9e0e68219fd7bb35b0cd755b2d72c3ebfa41842"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76802f0738c2d00bb4e057938ec048c4c7c4efc5c44f04b9d877ad4419b21ee8"}, + {file = "pyreqwest_impersonate-0.4.9-cp312-none-win_amd64.whl", hash = "sha256:7cf94f6365bc144f787658e844f94dad38107fb9ff61d65079fb6510447777fe"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:66e92bd868146028dac1ef9cd2b4aac57e7e6cbd8806fa8a4c77ac5becf396e1"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dc3ff7ac332879e40301d737b3ec1f3691b1de7492728bea26e75e26d05f89ec"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c9e9eba83620852d4253023e50e3436726aee16e2de94afbd468da4373830dc"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d6b47d403c63b461a97efa2aed668f0f06ed26cf61c23d7d6dab4f5a0c81ffc"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:88f695a01e8699ec3a1547d793617b9fd00f810c05c2b4dc0d1472c7f12eed97"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:abb4fbfaa1a3c3adeb7f46baa1d67663af85ab24f2b4cdd15a668ddc6be3a375"}, + {file = "pyreqwest_impersonate-0.4.9-cp38-none-win_amd64.whl", hash = "sha256:884c1399fe0157dcd0a5a71e3600910df50faa0108c64602d47c15e75b32e60b"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bf5cd99276207510d64b48eff5602e12f049754d3b0f1194a024e1a080a61d3d"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:029eea1d386d12856da767d685169835f0b0c025ae312c1ee7bc0d8cb47a7d3d"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1bfb8795fe0a46aee883abcf510a9ecdb4e9acf75c3a5a23571276f555f5e88"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fe35ce48e7e6b570304ee15915da0e6fab82dcae2b7a1d1a92593b522ebe852"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dfa377a842bd2e73d1f201bfc33194dd98c148372409d376f6d57efe338ff0eb"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d46880e68eb779cd071648e94a7ec50b3b77a28210f218be407eda1b0c8df343"}, + {file = "pyreqwest_impersonate-0.4.9-cp39-none-win_amd64.whl", hash = "sha256:ac431e4a94f8529a19a396750d78c66cc4fa11a8cc61d4bed7f0e0295a9394a9"}, + {file = "pyreqwest_impersonate-0.4.9-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12fd04d8da4d23ab5720402fd9f3b6944fb388c19952f2ec9121b46ac1f74616"}, + {file = "pyreqwest_impersonate-0.4.9-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b52df560d78681cde2fbc39bee547a42a79c8fd33655b79618835ecc412e6933"}, + {file = "pyreqwest_impersonate-0.4.9-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e1a2828942f9d589ee6161496444a380d3305e78bda25ff63e4f993b0545b193"}, + {file = "pyreqwest_impersonate-0.4.9-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:beebedf6d8c0d5fdee9ae15bc64a74e51b35f98eb0d049bf2db067702fbf4e53"}, + {file = "pyreqwest_impersonate-0.4.9-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a3d47dea1f46410b58ab60795b5818c8c99d901f6c93fbb6a9d23fa55adb2b1"}, + {file = "pyreqwest_impersonate-0.4.9-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bb871adc5d12b2bcbb5af167384d49fc4e7e5e07d12cf912b931149163df724"}, + {file = "pyreqwest_impersonate-0.4.9-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d1b0b5556d2bd14a4ffa32654291fe2a9ef1eaac35b5514d9220e7e333a6c727"}, + {file = "pyreqwest_impersonate-0.4.9-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5d50feaec78c06d51e1dd65cdbe80a1fc62ff93c8114555482f8a8cc5fe14895"}, + {file = "pyreqwest_impersonate-0.4.9-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2a9cfc41917200d8eee61b87a5668abe7d1f924a55b7437065540edf613beed"}, + {file = "pyreqwest_impersonate-0.4.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8106e3df0c1dca4df99e0f998f0e085ea3e1facfaa5afc268160a496ddf7256f"}, + {file = "pyreqwest_impersonate-0.4.9-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ff66bb7dc6b1f52cf950b5e9cb0e53baffd1a15da595fd1ef933cd9e36396403"}, + {file = "pyreqwest_impersonate-0.4.9-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39f2a3ed17cf08098dc637459e88fb86d3fa7bdf9502659c82218be75651649c"}, + {file = "pyreqwest_impersonate-0.4.9.tar.gz", hash = "sha256:4ec8df7fe813e89f61e814c5ef75f6fd71164c8e26299c1a42dcd0d42f0bc96c"}, ] [package.extras] @@ -6653,104 +6653,104 @@ test = ["coverage", "pytest"] [[package]] name = "rapidfuzz" -version = "3.9.3" +version = "3.9.4" description = "rapid fuzzy string matching" optional = false python-versions = ">=3.8" files = [ - {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdb8c5b8e29238ec80727c2ba3b301efd45aa30c6a7001123a6647b8e6f77ea4"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3bd0d9632088c63a241f217742b1cf86e2e8ae573e01354775bd5016d12138c"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:153f23c03d4917f6a1fc2fb56d279cc6537d1929237ff08ee7429d0e40464a18"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96c5225e840f1587f1bac8fa6f67562b38e095341576e82b728a82021f26d62"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b777cd910ceecd738adc58593d6ed42e73f60ad04ecdb4a841ae410b51c92e0e"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53e06e4b81f552da04940aa41fc556ba39dee5513d1861144300c36c33265b76"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c7ca5b6050f18fdcacdada2dc5fb7619ff998cd9aba82aed2414eee74ebe6cd"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:87bb8d84cb41446a808c4b5f746e29d8a53499381ed72f6c4e456fe0f81c80a8"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:959a15186d18425d19811bea86a8ffbe19fd48644004d29008e636631420a9b7"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a24603dd05fb4e3c09d636b881ce347e5f55f925a6b1b4115527308a323b9f8e"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0d055da0e801c71dd74ba81d72d41b2fa32afa182b9fea6b4b199d2ce937450d"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:875b581afb29a7213cf9d98cb0f98df862f1020bce9d9b2e6199b60e78a41d14"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-win32.whl", hash = "sha256:6073a46f61479a89802e3f04655267caa6c14eb8ac9d81a635a13805f735ebc1"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:119c010e20e561249b99ca2627f769fdc8305b07193f63dbc07bca0a6c27e892"}, - {file = "rapidfuzz-3.9.3-cp310-cp310-win_arm64.whl", hash = "sha256:790b0b244f3213581d42baa2fed8875f9ee2b2f9b91f94f100ec80d15b140ba9"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f57e8305c281e8c8bc720515540e0580355100c0a7a541105c6cafc5de71daae"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4fc7b784cf987dbddc300cef70e09a92ed1bce136f7bb723ea79d7e297fe76d"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b422c0a6fe139d5447a0766268e68e6a2a8c2611519f894b1f31f0a392b9167"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f50fed4a9b0c9825ff37cf0bccafd51ff5792090618f7846a7650f21f85579c9"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b80eb7cbe62348c61d3e67e17057cddfd6defab168863028146e07d5a8b24a89"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f45be77ec82da32ce5709a362e236ccf801615cc7163b136d1778cf9e31b14"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd84b7f652a5610733400307dc732f57c4a907080bef9520412e6d9b55bc9adc"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e6d27dad8c990218b8cd4a5c99cbc8834f82bb46ab965a7265d5aa69fc7ced7"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:05ee0696ebf0dfe8f7c17f364d70617616afc7dafe366532730ca34056065b8a"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2bc8391749e5022cd9e514ede5316f86e332ffd3cfceeabdc0b17b7e45198a8c"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93981895602cf5944d89d317ae3b1b4cc684d175a8ae2a80ce5b65615e72ddd0"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:754b719a4990735f66653c9e9261dcf52fd4d925597e43d6b9069afcae700d21"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-win32.whl", hash = "sha256:14c9f268ade4c88cf77ab007ad0fdf63699af071ee69378de89fff7aa3cae134"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc1991b4cde6c9d3c0bbcb83d5581dc7621bec8c666c095c65b4277233265a82"}, - {file = "rapidfuzz-3.9.3-cp311-cp311-win_arm64.whl", hash = "sha256:0c34139df09a61b1b557ab65782ada971b4a3bce7081d1b2bee45b0a52231adb"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d6a210347d6e71234af5c76d55eeb0348b026c9bb98fe7c1cca89bac50fb734"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b300708c917ce52f6075bdc6e05b07c51a085733650f14b732c087dc26e0aaad"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83ea7ca577d76778250421de61fb55a719e45b841deb769351fc2b1740763050"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8319838fb5b7b5f088d12187d91d152b9386ce3979ed7660daa0ed1bff953791"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:505d99131afd21529293a9a7b91dfc661b7e889680b95534756134dc1cc2cd86"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c52970f7784518d7c82b07a62a26e345d2de8c2bd8ed4774e13342e4b3ff4200"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:143caf7247449055ecc3c1e874b69e42f403dfc049fc2f3d5f70e1daf21c1318"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b8ab0fa653d9225195a8ff924f992f4249c1e6fa0aea563f685e71b81b9fcccf"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57e7c5bf7b61c7320cfa5dde1e60e678d954ede9bb7da8e763959b2138391401"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51fa1ba84653ab480a2e2044e2277bd7f0123d6693051729755addc0d015c44f"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:17ff7f7eecdb169f9236e3b872c96dbbaf116f7787f4d490abd34b0116e3e9c8"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:afe7c72d3f917b066257f7ff48562e5d462d865a25fbcabf40fca303a9fa8d35"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-win32.whl", hash = "sha256:e53ed2e9b32674ce96eed80b3b572db9fd87aae6742941fb8e4705e541d861ce"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:35b7286f177e4d8ba1e48b03612f928a3c4bdac78e5651379cec59f95d8651e6"}, - {file = "rapidfuzz-3.9.3-cp312-cp312-win_arm64.whl", hash = "sha256:e6e4b9380ed4758d0cb578b0d1970c3f32dd9e87119378729a5340cb3169f879"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a39890013f6d5b056cc4bfdedc093e322462ece1027a57ef0c636537bdde7531"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b5bc0fdbf419493163c5c9cb147c5fbe95b8e25844a74a8807dcb1a125e630cf"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe6e200a75a792d37b960457904c4fce7c928a96ae9e5d21d2bd382fe39066e"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de077c468c225d4c18f7188c47d955a16d65f21aab121cbdd98e3e2011002c37"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f917eaadf5388466a95f6a236f678a1588d231e52eda85374077101842e794e"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:858ba57c05afd720db8088a8707079e8d024afe4644001fe0dbd26ef7ca74a65"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d36447d21b05f90282a6f98c5a33771805f9222e5d0441d03eb8824e33e5bbb4"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:acbe4b6f1ccd5b90c29d428e849aa4242e51bb6cab0448d5f3c022eb9a25f7b1"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:53c7f27cdf899e94712972237bda48cfd427646aa6f5d939bf45d084780e4c16"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6175682a829c6dea4d35ed707f1dadc16513270ef64436568d03b81ccb6bdb74"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5276df395bd8497397197fca2b5c85f052d2e6a66ffc3eb0544dd9664d661f95"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:77b5c4f3e72924d7845f0e189c304270066d0f49635cf8a3938e122c437e58de"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-win32.whl", hash = "sha256:8add34061e5cd561c72ed4febb5c15969e7b25bda2bb5102d02afc3abc1f52d0"}, - {file = "rapidfuzz-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:604e0502a39cf8e67fa9ad239394dddad4cdef6d7008fdb037553817d420e108"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21047f55d674614eb4b0ab34e35c3dc66f36403b9fbfae645199c4a19d4ed447"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a56da3aff97cb56fe85d9ca957d1f55dbac7c27da927a86a2a86d8a7e17f80aa"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:964c08481aec2fe574f0062e342924db2c6b321391aeb73d68853ed42420fd6d"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e2b827258beefbe5d3f958243caa5a44cf46187eff0c20e0b2ab62d1550327a"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6e65a301fcd19fbfbee3a514cc0014ff3f3b254b9fd65886e8a9d6957fb7bca"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe93ba1725a8d47d2b9dca6c1f435174859427fbc054d83de52aea5adc65729"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca21c0a34adee582775da997a600283e012a608a107398d80a42f9a57ad323d"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:256e07d3465173b2a91c35715a2277b1ee3ae0b9bbab4e519df6af78570741d0"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:802ca2cc8aa6b8b34c6fdafb9e32540c1ba05fca7ad60b3bbd7ec89ed1797a87"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:dd789100fc852cffac1449f82af0da139d36d84fd9faa4f79fc4140a88778343"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:5d0abbacdb06e27ff803d7ae0bd0624020096802758068ebdcab9bd49cf53115"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:378d1744828e27490a823fc6fe6ebfb98c15228d54826bf4e49e4b76eb5f5579"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-win32.whl", hash = "sha256:5d0cb272d43e6d3c0dedefdcd9d00007471f77b52d2787a4695e9dd319bb39d2"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:15e4158ac4b3fb58108072ec35b8a69165f651ba1c8f43559a36d518dbf9fb3f"}, - {file = "rapidfuzz-3.9.3-cp39-cp39-win_arm64.whl", hash = "sha256:58c6a4936190c558d5626b79fc9e16497e5df7098589a7e80d8bff68148ff096"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5410dc848c947a603792f4f51b904a3331cf1dc60621586bfbe7a6de72da1091"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:282d55700a1a3d3a7980746eb2fcd48c9bbc1572ebe0840d0340d548a54d01fe"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc1037507810833646481f5729901a154523f98cbebb1157ba3a821012e16402"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e33f779391caedcba2ba3089fb6e8e557feab540e9149a5c3f7fea7a3a7df37"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41a81a9f311dc83d22661f9b1a1de983b201322df0c4554042ffffd0f2040c37"}, - {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a93250bd8fae996350c251e1752f2c03335bb8a0a5b0c7e910a593849121a435"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3617d1aa7716c57d120b6adc8f7c989f2d65bc2b0cbd5f9288f1fc7bf469da11"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad04a3f5384b82933213bba2459f6424decc2823df40098920856bdee5fd6e88"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8709918da8a88ad73c9d4dd0ecf24179a4f0ceba0bee21efc6ea21a8b5290349"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b770f85eab24034e6ef7df04b2bfd9a45048e24f8a808e903441aa5abde8ecdd"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930b4e6fdb4d914390141a2b99a6f77a52beacf1d06aa4e170cba3a98e24c1bc"}, - {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c8444e921bfc3757c475c4f4d7416a7aa69b2d992d5114fe55af21411187ab0d"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c1d3ef3878f871abe6826e386c3d61b5292ef5f7946fe646f4206b85836b5da"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d861bf326ee7dabc35c532a40384541578cd1ec1e1b7db9f9ecbba56eb76ca22"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cde6b9d9ba5007077ee321ec722fa714ebc0cbd9a32ccf0f4dd3cc3f20952d71"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb6546e7b6bed1aefbe24f68a5fb9b891cc5aef61bca6c1a7b1054b7f0359bb"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d8a57261ef7996d5ced7c8cba9189ada3fbeffd1815f70f635e4558d93766cb"}, - {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:67201c02efc596923ad950519e0b75ceb78d524177ea557134d6567b9ac2c283"}, - {file = "rapidfuzz-3.9.3.tar.gz", hash = "sha256:b398ea66e8ed50451bce5997c430197d5e4b06ac4aa74602717f792d8d8d06e2"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9b9793c19bdf38656c8eaefbcf4549d798572dadd70581379e666035c9df781"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:015b5080b999404fe06ec2cb4f40b0be62f0710c926ab41e82dfbc28e80675b4"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc5ceca9c1e1663f3e6c23fb89a311f69b7615a40ddd7645e3435bf3082688a"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1424e238bc3f20e1759db1e0afb48a988a9ece183724bef91ea2a291c0b92a95"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed01378f605aa1f449bee82cd9c83772883120d6483e90aa6c5a4ce95dc5c3aa"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb26d412271e5a76cdee1c2d6bf9881310665d3fe43b882d0ed24edfcb891a84"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f37e9e1f17be193c41a31c864ad4cd3ebd2b40780db11cd5c04abf2bcf4201b"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d070ec5cf96b927c4dc5133c598c7ff6db3b833b363b2919b13417f1002560bc"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:10e61bb7bc807968cef09a0e32ce253711a2d450a4dce7841d21d45330ffdb24"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:31a2fc60bb2c7face4140010a7aeeafed18b4f9cdfa495cc644a68a8c60d1ff7"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fbebf1791a71a2e89f5c12b78abddc018354d5859e305ec3372fdae14f80a826"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:aee9fc9e3bb488d040afc590c0a7904597bf4ccd50d1491c3f4a5e7e67e6cd2c"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-win32.whl", hash = "sha256:005a02688a51c7d2451a2d41c79d737aa326ff54167211b78a383fc2aace2c2c"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:3a2e75e41ee3274754d3b2163cc6c82cd95b892a85ab031f57112e09da36455f"}, + {file = "rapidfuzz-3.9.4-cp310-cp310-win_arm64.whl", hash = "sha256:2c99d355f37f2b289e978e761f2f8efeedc2b14f4751d9ff7ee344a9a5ca98d9"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:07141aa6099e39d48637ce72a25b893fc1e433c50b3e837c75d8edf99e0c63e1"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db1664eaff5d7d0f2542dd9c25d272478deaf2c8412e4ad93770e2e2d828e175"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc01a223f6605737bec3202e94dcb1a449b6c76d46082cfc4aa980f2a60fd40e"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1869c42e73e2a8910b479be204fa736418741b63ea2325f9cc583c30f2ded41a"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62ea7007941fb2795fff305ac858f3521ec694c829d5126e8f52a3e92ae75526"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:698e992436bf7f0afc750690c301215a36ff952a6dcd62882ec13b9a1ebf7a39"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b76f611935f15a209d3730c360c56b6df8911a9e81e6a38022efbfb96e433bab"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129627d730db2e11f76169344a032f4e3883d34f20829419916df31d6d1338b1"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:90a82143c14e9a14b723a118c9ef8d1bbc0c5a16b1ac622a1e6c916caff44dd8"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ded58612fe3b0e0d06e935eaeaf5a9fd27da8ba9ed3e2596307f40351923bf72"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f16f5d1c4f02fab18366f2d703391fcdbd87c944ea10736ca1dc3d70d8bd2d8b"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:26aa7eece23e0df55fb75fbc2a8fb678322e07c77d1fd0e9540496e6e2b5f03e"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-win32.whl", hash = "sha256:f187a9c3b940ce1ee324710626daf72c05599946bd6748abe9e289f1daa9a077"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d8e9130fe5d7c9182990b366ad78fd632f744097e753e08ace573877d67c32f8"}, + {file = "rapidfuzz-3.9.4-cp311-cp311-win_arm64.whl", hash = "sha256:40419e98b10cd6a00ce26e4837a67362f658fc3cd7a71bd8bd25c99f7ee8fea5"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b5d5072b548db1b313a07d62d88fe0b037bd2783c16607c647e01b070f6cf9e5"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cf5bcf22e1f0fd273354462631d443ef78d677f7d2fc292de2aec72ae1473e66"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c8fc973adde8ed52810f590410e03fb6f0b541bbaeb04c38d77e63442b2df4c"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2464bb120f135293e9a712e342c43695d3d83168907df05f8c4ead1612310c7"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d9d58689aca22057cf1a5851677b8a3ccc9b535ca008c7ed06dc6e1899f7844"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167e745f98baa0f3034c13583e6302fb69249a01239f1483d68c27abb841e0a1"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db0bf0663b4b6da1507869722420ea9356b6195aa907228d6201303e69837af9"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cd6ac61b74fdb9e23f04d5f068e6cf554f47e77228ca28aa2347a6ca8903972f"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:60ff67c690acecf381759c16cb06c878328fe2361ddf77b25d0e434ea48a29da"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:cb934363380c60f3a57d14af94325125cd8cded9822611a9f78220444034e36e"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fe833493fb5cc5682c823ea3e2f7066b07612ee8f61ecdf03e1268f262106cdd"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2797fb847d89e04040d281cb1902cbeffbc4b5131a5c53fc0db490fd76b2a547"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-win32.whl", hash = "sha256:52e3d89377744dae68ed7c84ad0ddd3f5e891c82d48d26423b9e066fc835cc7c"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:c76da20481c906e08400ee9be230f9e611d5931a33707d9df40337c2655c84b5"}, + {file = "rapidfuzz-3.9.4-cp312-cp312-win_arm64.whl", hash = "sha256:f2d2846f3980445864c7e8b8818a29707fcaff2f0261159ef6b7bd27ba139296"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:355fc4a268ffa07bab88d9adee173783ec8d20136059e028d2a9135c623c44e6"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4d81a78f90269190b568a8353d4ea86015289c36d7e525cd4d43176c88eff429"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e618625ffc4660b26dc8e56225f8b966d5842fa190e70c60db6cd393e25b86e"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b712336ad6f2bacdbc9f1452556e8942269ef71f60a9e6883ef1726b52d9228a"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc1ee19fdad05770c897e793836c002344524301501d71ef2e832847425707"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1950f8597890c0c707cb7e0416c62a1cf03dcdb0384bc0b2dbda7e05efe738ec"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a6c35f272ec9c430568dc8c1c30cb873f6bc96be2c79795e0bce6db4e0e101d"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:1df0f9e9239132a231c86ae4f545ec2b55409fa44470692fcfb36b1bd00157ad"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:d2c51955329bfccf99ae26f63d5928bf5be9fcfcd9f458f6847fd4b7e2b8986c"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:3c522f462d9fc504f2ea8d82e44aa580e60566acc754422c829ad75c752fbf8d"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:d8a52fc50ded60d81117d7647f262c529659fb21d23e14ebfd0b35efa4f1b83d"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:04dbdfb0f0bfd3f99cf1e9e24fadc6ded2736d7933f32f1151b0f2abb38f9a25"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-win32.whl", hash = "sha256:4968c8bd1df84b42f382549e6226710ad3476f976389839168db3e68fd373298"}, + {file = "rapidfuzz-3.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:3fe4545f89f8d6c27b6bbbabfe40839624873c08bd6700f63ac36970a179f8f5"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9f256c8fb8f3125574c8c0c919ab0a1f75d7cba4d053dda2e762dcc36357969d"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5fdc09cf6e9d8eac3ce48a4615b3a3ee332ea84ac9657dbbefef913b13e632f"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d395d46b80063d3b5d13c0af43d2c2cedf3ab48c6a0c2aeec715aa5455b0c632"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa714fb96ce9e70c37e64c83b62fe8307030081a0bfae74a76fac7ba0f91715"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bc1a0f29f9119be7a8d3c720f1d2068317ae532e39e4f7f948607c3a6de8396"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6022674aa1747d6300f699cd7c54d7dae89bfe1f84556de699c4ac5df0838082"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcb72e5f9762fd469701a7e12e94b924af9004954f8c739f925cb19c00862e38"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad04ae301129f0eb5b350a333accd375ce155a0c1cec85ab0ec01f770214e2e4"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f46a22506f17c0433e349f2d1dc11907c393d9b3601b91d4e334fa9a439a6a4d"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:01b42a8728c36011718da409aa86b84984396bf0ca3bfb6e62624f2014f6022c"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e590d5d5443cf56f83a51d3c4867bd1f6be8ef8cfcc44279522bcef3845b2a51"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4c72078b5fdce34ba5753f9299ae304e282420e6455e043ad08e4488ca13a2b0"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-win32.whl", hash = "sha256:f75639277304e9b75e6a7b3c07042d2264e16740a11e449645689ed28e9c2124"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:e81e27e8c32a1e1278a4bb1ce31401bfaa8c2cc697a053b985a6f8d013df83ec"}, + {file = "rapidfuzz-3.9.4-cp39-cp39-win_arm64.whl", hash = "sha256:15bc397ee9a3ed1210b629b9f5f1da809244adc51ce620c504138c6e7095b7bd"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:20488ade4e1ddba3cfad04f400da7a9c1b91eff5b7bd3d1c50b385d78b587f4f"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:e61b03509b1a6eb31bc5582694f6df837d340535da7eba7bedb8ae42a2fcd0b9"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:098d231d4e51644d421a641f4a5f2f151f856f53c252b03516e01389b2bfef99"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17ab8b7d10fde8dd763ad428aa961c0f30a1b44426e675186af8903b5d134fb0"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e272df61bee0a056a3daf99f9b1bd82cf73ace7d668894788139c868fdf37d6f"}, + {file = "rapidfuzz-3.9.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d6481e099ff8c4edda85b8b9b5174c200540fd23c8f38120016c765a86fa01f5"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad61676e9bdae677d577fe80ec1c2cea1d150c86be647e652551dcfe505b1113"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:af65020c0dd48d0d8ae405e7e69b9d8ae306eb9b6249ca8bf511a13f465fad85"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d38b4e026fcd580e0bda6c0ae941e0e9a52c6bc66cdce0b8b0da61e1959f5f8"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f74ed072c2b9dc6743fb19994319d443a4330b0e64aeba0aa9105406c7c5b9c2"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aee5f6b8321f90615c184bd8a4c676e9becda69b8e4e451a90923db719d6857c"}, + {file = "rapidfuzz-3.9.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3a555e3c841d6efa350f862204bb0a3fea0c006b8acc9b152b374fa36518a1c6"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0772150d37bf018110351c01d032bf9ab25127b966a29830faa8ad69b7e2f651"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:addcdd3c3deef1bd54075bd7aba0a6ea9f1d01764a08620074b7a7b1e5447cb9"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fe86b82b776554add8f900b6af202b74eb5efe8f25acdb8680a5c977608727f"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0fc91ac59f4414d8542454dfd6287a154b8e6f1256718c898f695bdbb993467"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a944e546a296a5fdcaabb537b01459f1b14d66f74e584cb2a91448bffadc3c1"}, + {file = "rapidfuzz-3.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4fb96ba96d58c668a17a06b5b5e8340fedc26188e87b0d229d38104556f30cd8"}, + {file = "rapidfuzz-3.9.4.tar.gz", hash = "sha256:366bf8947b84e37f2f4cf31aaf5f37c39f620d8c0eddb8b633e6ba0129ca4a0a"}, ] [package.extras] @@ -6780,13 +6780,13 @@ test = ["coveralls", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-benc [[package]] name = "redis" -version = "5.0.5" +version = "5.0.7" description = "Python client for Redis database and key-value store" optional = false python-versions = ">=3.7" files = [ - {file = "redis-5.0.5-py3-none-any.whl", hash = "sha256:30b47d4ebb6b7a0b9b40c1275a19b87bb6f46b3bed82a89012cf56dea4024ada"}, - {file = "redis-5.0.5.tar.gz", hash = "sha256:3417688621acf6ee368dec4a04dd95881be24efd34c79f00d31f62bb528800ae"}, + {file = "redis-5.0.7-py3-none-any.whl", hash = "sha256:0e479e24da960c690be5d9b96d21f7b918a98c0cf49af3b6fafaa0753f93a0db"}, + {file = "redis-5.0.7.tar.gz", hash = "sha256:8f611490b93c8109b50adc317b31bfd84fff31def3475b92e7e80bf39f48175b"}, ] [package.dependencies] @@ -7006,28 +7006,28 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.4.8" +version = "0.4.10" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"}, - {file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"}, - {file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"}, - {file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"}, - {file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"}, - {file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"}, - {file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"}, - {file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"}, + {file = "ruff-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c2c4d0859305ac5a16310eec40e4e9a9dec5dcdfbe92697acd99624e8638dac"}, + {file = "ruff-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a79489607d1495685cdd911a323a35871abfb7a95d4f98fc6f85e799227ac46e"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1dd1681dfa90a41b8376a61af05cc4dc5ff32c8f14f5fe20dba9ff5deb80cd6"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c75c53bb79d71310dc79fb69eb4902fba804a81f374bc86a9b117a8d077a1784"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18238c80ee3d9100d3535d8eb15a59c4a0753b45cc55f8bf38f38d6a597b9739"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d8f71885bce242da344989cae08e263de29752f094233f932d4f5cfb4ef36a81"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:330421543bd3222cdfec481e8ff3460e8702ed1e58b494cf9d9e4bf90db52b9d"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e9b6fb3a37b772628415b00c4fc892f97954275394ed611056a4b8a2631365e"}, + {file = "ruff-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f54c481b39a762d48f64d97351048e842861c6662d63ec599f67d515cb417f6"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:67fe086b433b965c22de0b4259ddfe6fa541c95bf418499bedb9ad5fb8d1c631"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:acfaaab59543382085f9eb51f8e87bac26bf96b164839955f244d07125a982ef"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3cea07079962b2941244191569cf3a05541477286f5cafea638cd3aa94b56815"}, + {file = "ruff-0.4.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:338a64ef0748f8c3a80d7f05785930f7965d71ca260904a9321d13be24b79695"}, + {file = "ruff-0.4.10-py3-none-win32.whl", hash = "sha256:ffe3cd2f89cb54561c62e5fa20e8f182c0a444934bf430515a4b422f1ab7b7ca"}, + {file = "ruff-0.4.10-py3-none-win_amd64.whl", hash = "sha256:67f67cef43c55ffc8cc59e8e0b97e9e60b4837c8f21e8ab5ffd5d66e196e25f7"}, + {file = "ruff-0.4.10-py3-none-win_arm64.whl", hash = "sha256:dd1fcee327c20addac7916ca4e2653fbbf2e8388d8a6477ce5b4e986b68ae6c0"}, + {file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"}, ] [[package]] @@ -7213,45 +7213,45 @@ tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy ( [[package]] name = "scipy" -version = "1.13.1" +version = "1.14.0" description = "Fundamental algorithms for scientific computing in Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, -] - -[package.dependencies] -numpy = ">=1.22.4,<2.3" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, + {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, + {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, + {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, + {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, + {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, + {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, + {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, +] + +[package.dependencies] +numpy = ">=1.23.5,<2.3" + +[package.extras] +dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "sentry-sdk" @@ -7303,18 +7303,18 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "70.0.0" +version = "70.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, - {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, + {file = "setuptools-70.2.0-py3-none-any.whl", hash = "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05"}, + {file = "setuptools-70.2.0.tar.gz", hash = "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "sgmllib3k" @@ -7457,64 +7457,64 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.30" +version = "2.0.31" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win32.whl", hash = "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win_amd64.whl", hash = "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win32.whl", hash = "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win_amd64.whl", hash = "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win32.whl", hash = "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win_amd64.whl", hash = "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win32.whl", hash = "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win_amd64.whl", hash = "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win32.whl", hash = "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win_amd64.whl", hash = "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221"}, - {file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"}, - {file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win32.whl", hash = "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win_amd64.whl", hash = "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win32.whl", hash = "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win_amd64.whl", hash = "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win32.whl", hash = "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win_amd64.whl", hash = "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win32.whl", hash = "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win_amd64.whl", hash = "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win32.whl", hash = "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win_amd64.whl", hash = "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc"}, + {file = "SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911"}, + {file = "SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} typing-extensions = ">=4.6.0" [package.extras] @@ -7634,13 +7634,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tencentcloud-sdk-python-common" -version = "3.0.1166" +version = "3.0.1183" description = "Tencent Cloud Common SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-common-3.0.1166.tar.gz", hash = "sha256:7e20a98f94cd82302f4f9a6c28cd1d1d90e1043767a9ff98eebe10def84ec7b9"}, - {file = "tencentcloud_sdk_python_common-3.0.1166-py2.py3-none-any.whl", hash = "sha256:e230159b275427c0ff95bd708df2ad625ab4a45ff495d9a89d4199d535ce68e9"}, + {file = "tencentcloud-sdk-python-common-3.0.1183.tar.gz", hash = "sha256:59f8175cd2be20badfbed035637794d1d827071dd4e9d746543689254a9eae47"}, + {file = "tencentcloud_sdk_python_common-3.0.1183-py2.py3-none-any.whl", hash = "sha256:9deb38d80f7d8fbaf45b46f201f8c0c324a78cc0cb6c5034c1da84a06116af88"}, ] [package.dependencies] @@ -7648,17 +7648,17 @@ requests = ">=2.16.0" [[package]] name = "tencentcloud-sdk-python-hunyuan" -version = "3.0.1166" +version = "3.0.1183" description = "Tencent Cloud Hunyuan SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-hunyuan-3.0.1166.tar.gz", hash = "sha256:9be5f6ca91facdc40da91a0b9c300a0c54a83cf3792305d0e83c4216ca2a2e18"}, - {file = "tencentcloud_sdk_python_hunyuan-3.0.1166-py2.py3-none-any.whl", hash = "sha256:572d41d034a68a898ac74dd4d92f6b764cdb2b993cf71e6fbc52a40e65b0b4b4"}, + {file = "tencentcloud-sdk-python-hunyuan-3.0.1183.tar.gz", hash = "sha256:5648994f0124c694ee75dd498d991ca632c8dc8d55b6d349d8cc7fd5bc33b1bd"}, + {file = "tencentcloud_sdk_python_hunyuan-3.0.1183-py2.py3-none-any.whl", hash = "sha256:01bfdf33ea04ed791931636c3eafa569a0387f623967ef880ff220b3c548e6f5"}, ] [package.dependencies] -tencentcloud-sdk-python-common = "3.0.1166" +tencentcloud-sdk-python-common = "3.0.1183" [[package]] name = "threadpoolctl" @@ -8044,13 +8044,13 @@ typing-extensions = ">=3.7.4.3" [[package]] name = "types-requests" -version = "2.32.0.20240602" +version = "2.32.0.20240622" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.32.0.20240602.tar.gz", hash = "sha256:3f98d7bbd0dd94ebd10ff43a7fbe20c3b8528acace6d8efafef0b6a184793f06"}, - {file = "types_requests-2.32.0.20240602-py3-none-any.whl", hash = "sha256:ed3946063ea9fbc6b5fc0c44fa279188bae42d582cb63760be6cb4b9d06c3de8"}, + {file = "types-requests-2.32.0.20240622.tar.gz", hash = "sha256:ed5e8a412fcc39159d6319385c009d642845f250c63902718f605cd90faade31"}, + {file = "types_requests-2.32.0.20240622-py3-none-any.whl", hash = "sha256:97bac6b54b5bd4cf91d407e62f0932a74821bc2211f22116d9ee1dd643826caf"}, ] [package.dependencies] @@ -8293,18 +8293,18 @@ files = [ [[package]] name = "urllib3" -version = "2.0.7" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -9095,4 +9095,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "90f0e77567fbe5100d15bf2bc9472007aafc53c2fd594b6a90dd8455dea58582" +content-hash = "a31e1524d35da47f63f5e8d24236cbe14585e6a5d9edf9b734d517d24f83e287" diff --git a/api/pyproject.toml b/api/pyproject.toml index c919b33856af28..3c633675e2c1e7 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -115,7 +115,6 @@ chardet = "~5.1.0" cohere = "~5.2.4" cos-python-sdk-v5 = "1.9.30" dashscope = { version = "~1.17.0", extras = ["tokenizer"] } -firecrawl-py = "0.0.5" flask = "~3.0.1" flask-compress = "~1.14" flask-cors = "~4.0.0" @@ -186,7 +185,7 @@ zhipuai = "1.0.7" arxiv = "2.1.0" matplotlib = "~3.8.2" newspaper3k = "0.2.8" -duckduckgo-search = "~6.1.5" +duckduckgo-search = "^6.1.8" jsonpath-ng = "1.6.1" numexpr = "~2.9.0" opensearch-py = "2.4.0" diff --git a/api/services/account_service.py b/api/services/account_service.py index 3112ad80a8b871..3fd2b5c62772f2 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -13,6 +13,7 @@ from constants.languages import language_timezone_mapping, languages from events.tenant_event import tenant_was_created from extensions.ext_redis import redis_client +from libs.helper import RateLimiter, TokenManager from libs.passport import PassportService from libs.password import compare_password, hash_password, valid_password from libs.rsa import generate_key_pair @@ -29,14 +30,22 @@ LinkAccountIntegrateError, MemberNotInTenantError, NoPermissionError, + RateLimitExceededError, RoleAlreadyAssignedError, TenantNotFound, ) from tasks.mail_invite_member_task import send_invite_member_mail_task +from tasks.mail_reset_password_task import send_reset_password_mail_task class AccountService: + reset_password_rate_limiter = RateLimiter( + prefix="reset_password_rate_limit", + max_attempts=5, + time_window=60 * 60 + ) + @staticmethod def load_user(user_id: str) -> Account: account = Account.query.filter_by(id=user_id).first() @@ -222,9 +231,33 @@ def load_logged_in_account(*, account_id: str, token: str): return None return AccountService.load_user(account_id) + @classmethod + def send_reset_password_email(cls, account): + if cls.reset_password_rate_limiter.is_rate_limited(account.email): + raise RateLimitExceededError(f"Rate limit exceeded for email: {account.email}. Please try again later.") + + token = TokenManager.generate_token(account, 'reset_password') + send_reset_password_mail_task.delay( + language=account.interface_language, + to=account.email, + token=token + ) + cls.reset_password_rate_limiter.increment_rate_limit(account.email) + return token + + @classmethod + def revoke_reset_password_token(cls, token: str): + TokenManager.revoke_token(token, 'reset_password') + + @classmethod + def get_reset_password_data(cls, token: str) -> Optional[dict[str, Any]]: + return TokenManager.get_token_data(token, 'reset_password') + + def _get_login_cache_key(*, account_id: str, token: str): return f"account_login:{account_id}:{token}" + class TenantService: @staticmethod diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 739b80a0fc0dc3..a44e730b14ed04 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -61,7 +61,10 @@ def get_datasets(page, per_page, provider="vendor", tenant_id=None, user=None, s if user: if user.current_role == TenantAccountRole.DATASET_OPERATOR: - dataset_permission = DatasetPermission.query.filter_by(account_id=user.id).all() + dataset_permission = DatasetPermission.query.filter_by( + account_id=user.id, + tenant_id=tenant_id + ).all() if dataset_permission: dataset_ids = [dp.dataset_id for dp in dataset_permission] query = query.filter(Dataset.id.in_(dataset_ids)) @@ -355,6 +358,7 @@ def filter_datasets_by_permission(user, datasets): (dataset.id in permitted_dataset_ids) ] + filtered_datasets.sort(key=lambda x: x.created_at, reverse=True) filtered_count = len(filtered_datasets) return filtered_datasets, filtered_count @@ -1587,12 +1591,13 @@ def get_dataset_partial_member_list(cls, dataset_id): return user_list @classmethod - def update_partial_member_list(cls, dataset_id, user_list): + def update_partial_member_list(cls, tenant_id, dataset_id, user_list): try: db.session.query(DatasetPermission).filter(DatasetPermission.dataset_id == dataset_id).delete() permissions = [] for user in user_list: permission = DatasetPermission( + tenant_id=tenant_id, dataset_id=dataset_id, account_id=user['user_id'], ) diff --git a/api/services/errors/account.py b/api/services/errors/account.py index 14612eed7572fc..ddc2dbdea86265 100644 --- a/api/services/errors/account.py +++ b/api/services/errors/account.py @@ -51,3 +51,8 @@ class MemberNotInTenantError(BaseServiceError): class RoleAlreadyAssignedError(BaseServiceError): pass + + +class RateLimitExceededError(BaseServiceError): + pass + diff --git a/api/tasks/mail_invite_member_task.py b/api/tasks/mail_invite_member_task.py index 3341f5f4b82d57..1f40c05077c0a8 100644 --- a/api/tasks/mail_invite_member_task.py +++ b/api/tasks/mail_invite_member_task.py @@ -39,16 +39,15 @@ def send_invite_member_mail_task(language: str, to: str, token: str, inviter_nam mail.send(to=to, subject="立即加入 Dify 工作空间", html=html_content) else: html_content = render_template('invite_member_mail_template_en-US.html', - to=to, - inviter_name=inviter_name, - workspace_name=workspace_name, - url=url) + to=to, + inviter_name=inviter_name, + workspace_name=workspace_name, + url=url) mail.send(to=to, subject="Join Dify Workspace Now", html=html_content) - end_at = time.perf_counter() logging.info( click.style('Send invite member mail to {} succeeded: latency: {}'.format(to, end_at - start_at), fg='green')) except Exception: - logging.exception("Send invite member mail to {} failed".format(to)) + logging.exception("Send invite member mail to {} failed".format(to)) \ No newline at end of file diff --git a/api/tasks/mail_reset_password_task.py b/api/tasks/mail_reset_password_task.py new file mode 100644 index 00000000000000..0e64c6f1632e1d --- /dev/null +++ b/api/tasks/mail_reset_password_task.py @@ -0,0 +1,44 @@ +import logging +import time + +import click +from celery import shared_task +from flask import current_app, render_template + +from extensions.ext_mail import mail + + +@shared_task(queue='mail') +def send_reset_password_mail_task(language: str, to: str, token: str): + """ + Async Send reset password mail + :param language: Language in which the email should be sent (e.g., 'en', 'zh') + :param to: Recipient email address + :param token: Reset password token to be included in the email + """ + if not mail.is_inited(): + return + + logging.info(click.style('Start password reset mail to {}'.format(to), fg='green')) + start_at = time.perf_counter() + + # send reset password mail using different languages + try: + url = f'{current_app.config.get("CONSOLE_WEB_URL")}/forgot-password?token={token}' + if language == 'zh-Hans': + html_content = render_template('reset_password_mail_template_zh-CN.html', + to=to, + url=url) + mail.send(to=to, subject="重置您的 Dify 密码", html=html_content) + else: + html_content = render_template('reset_password_mail_template_en-US.html', + to=to, + url=url) + mail.send(to=to, subject="Reset Your Dify Password", html=html_content) + + end_at = time.perf_counter() + logging.info( + click.style('Send password reset mail to {} succeeded: latency: {}'.format(to, end_at - start_at), + fg='green')) + except Exception: + logging.exception("Send password reset mail to {} failed".format(to)) diff --git a/api/templates/reset_password_mail_template_en-US.html b/api/templates/reset_password_mail_template_en-US.html new file mode 100644 index 00000000000000..ffc558ab66f365 --- /dev/null +++ b/api/templates/reset_password_mail_template_en-US.html @@ -0,0 +1,72 @@ + + + + + + + +
+
+ Dify Logo +
+
+

Dear {{ to }},

+

We have received a request to reset your password. If you initiated this request, please click the button below to reset your password:

+

Reset Password

+

If you did not request a password reset, please ignore this email and your account will remain secure.

+
+ +
+ + diff --git a/api/templates/reset_password_mail_template_zh-CN.html b/api/templates/reset_password_mail_template_zh-CN.html new file mode 100644 index 00000000000000..b74b23ac3f0de9 --- /dev/null +++ b/api/templates/reset_password_mail_template_zh-CN.html @@ -0,0 +1,72 @@ + + + + + + + +
+
+ Dify Logo +
+
+

尊敬的 {{ to }},

+

我们收到了您关于重置密码的请求。如果是您本人操作,请点击以下按钮重置您的密码:

+

重置密码

+

如果您没有请求重置密码,请忽略此邮件,您的账户信息将保持安全。

+
+ +
+ + diff --git a/api/tests/integration_tests/model_runtime/localai/test_rerank.py b/api/tests/integration_tests/model_runtime/localai/test_rerank.py index a75439337eb5c0..99847bc8528a0a 100644 --- a/api/tests/integration_tests/model_runtime/localai/test_rerank.py +++ b/api/tests/integration_tests/model_runtime/localai/test_rerank.py @@ -1,64 +1,8 @@ import os import pytest -from api.core.model_runtime.entities.rerank_entities import RerankResult - -from core.model_runtime.errors.validate import CredentialsValidateFailedError -from core.model_runtime.model_providers.localai.rerank.rerank import LocalaiRerankModel - - -def test_validate_credentials_for_chat_model(): - model = LocalaiRerankModel() - - with pytest.raises(CredentialsValidateFailedError): - model.validate_credentials( - model='bge-reranker-v2-m3', - credentials={ - 'server_url': 'hahahaha', - 'completion_type': 'completion', - } - ) - - model.validate_credentials( - model='bge-reranker-base', - credentials={ - 'server_url': os.environ.get('LOCALAI_SERVER_URL'), - 'completion_type': 'completion', - } - ) - -def test_invoke_rerank_model(): - model = LocalaiRerankModel() - - response = model.invoke( - model='bge-reranker-base', - credentials={ - 'server_url': os.environ.get('LOCALAI_SERVER_URL') - }, - query='Organic skincare products for sensitive skin', - docs=[ - "Eco-friendly kitchenware for modern homes", - "Biodegradable cleaning supplies for eco-conscious consumers", - "Organic cotton baby clothes for sensitive skin", - "Natural organic skincare range for sensitive skin", - "Tech gadgets for smart homes: 2024 edition", - "Sustainable gardening tools and compost solutions", - "Sensitive skin-friendly facial cleansers and toners", - "Organic food wraps and storage solutions", - "Yoga mats made from recycled materials" - ], - top_n=3, - score_threshold=0.75, - user="abc-123" - ) - - assert isinstance(response, RerankResult) - assert len(response.docs) == 3 -import os - -import pytest -from api.core.model_runtime.entities.rerank_entities import RerankDocument, RerankResult +from core.model_runtime.entities.rerank_entities import RerankDocument, RerankResult from core.model_runtime.errors.validate import CredentialsValidateFailedError from core.model_runtime.model_providers.localai.rerank.rerank import LocalaiRerankModel diff --git a/docker/.env.example b/docker/.env.example index 008d5cd4cc2232..fd2cbe2b9d3289 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -427,6 +427,10 @@ INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=1000 # Default: 72. INVITE_EXPIRY_HOURS=72 +# Reset password token valid time (hours), +# Default: 24. +RESET_PASSWORD_TOKEN_EXPIRY_HOURS=24 + # The sandbox service endpoint. CODE_EXECUTION_ENDPOINT=http://sandbox:8194 CODE_MAX_NUMBER=9223372036854775807 diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 788206d22f5eee..d947532301560b 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -145,6 +145,7 @@ x-shared-env: &shared-api-worker-env RESEND_API_URL: https://api.resend.com INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-1000} INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72} + RESET_PASSWORD_TOKEN_EXPIRY_HOURS: ${RESET_PASSWORD_TOKEN_EXPIRY_HOURS:-24} CODE_EXECUTION_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194} CODE_EXECUTION_API_KEY: ${SANDBOX_API_KEY:-dify-sandbox} CODE_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807} diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 958c55a871e99a..11db2f727c68e8 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -103,7 +103,7 @@ const useLazyLoad = (ref: RefObject): boolean => { // visit https://reactjs.org/docs/error-decoder.html?invariant=185 for the full message // or use the non-minified dev environment for full errors and additional helpful warnings. const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props }) => { - const [isSVG, setIsSVG] = useState(false) + const [isSVG, setIsSVG] = useState(true) const match = /language-(\w+)/.exec(className || '') const language = match?.[1] const languageShowName = getCorrectCapitalizationLanguageName(language || '') diff --git a/web/app/components/base/mermaid/index.tsx b/web/app/components/base/mermaid/index.tsx index 86f472c06e535f..bef26b7a364ca8 100644 --- a/web/app/components/base/mermaid/index.tsx +++ b/web/app/components/base/mermaid/index.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useRef, useState } from 'react' import mermaid from 'mermaid' import CryptoJS from 'crypto-js' +import LoadingAnim from '@/app/components/base/chat/chat/loading-anim' let mermaidAPI: any mermaidAPI = null @@ -23,12 +24,24 @@ const style = { overflow: 'auto', } +const svgToBase64 = (svgGraph: string) => { + const svgBytes = new TextEncoder().encode(svgGraph) + const blob = new Blob([svgBytes], { type: 'image/svg+xml;charset=utf-8' }) + return new Promise((resolve, reject) => { + const reader = new FileReader() + reader.onloadend = () => resolve(reader.result) + reader.onerror = reject + reader.readAsDataURL(blob) + }) +} + const Flowchart = React.forwardRef((props: { PrimitiveCode: string }, ref) => { const [svgCode, setSvgCode] = useState(null) const chartId = useRef(`flowchart_${CryptoJS.MD5(props.PrimitiveCode).toString()}`) - const [isRender, setIsRender] = useState(true) + const [isRender, setIsRender] = useState(false) + const [isLoading, setIsLoading] = useState(true) const clearFlowchartCache = () => { for (let i = localStorage.length - 1; i >= 0; --i) { @@ -43,14 +56,19 @@ const Flowchart = React.forwardRef((props: { const cachedSvg: any = localStorage.getItem(chartId.current) if (cachedSvg) { setSvgCode(cachedSvg) + setIsLoading(false) return } if (typeof window !== 'undefined' && mermaidAPI) { const svgGraph = await mermaidAPI.render(chartId.current, PrimitiveCode) - // eslint-disable-next-line @typescript-eslint/no-use-before-define + const dom = new DOMParser().parseFromString(svgGraph.svg, 'text/xml') + if (!dom.querySelector('g.main')) + throw new Error('empty svg') + const base64Svg: any = await svgToBase64(svgGraph.svg) setSvgCode(base64Svg) + setIsLoading(false) if (chartId.current && base64Svg) localStorage.setItem(chartId.current, base64Svg) } @@ -62,17 +80,6 @@ const Flowchart = React.forwardRef((props: { } } - const svgToBase64 = (svgGraph: string) => { - const svgBytes = new TextEncoder().encode(svgGraph) - const blob = new Blob([svgBytes], { type: 'image/svg+xml;charset=utf-8' }) - return new Promise((resolve, reject) => { - const reader = new FileReader() - reader.onloadend = () => resolve(reader.result) - reader.onerror = reject - reader.readAsDataURL(blob) - }) - } - const handleReRender = () => { setIsRender(false) setSvgCode(null) @@ -99,10 +106,15 @@ const Flowchart = React.forwardRef((props: {
{ isRender - &&
+ &&
{svgCode && Mermaid chart}
} + {isLoading + &&
+ +
+ }
) }) diff --git a/web/app/components/base/select/index.tsx b/web/app/components/base/select/index.tsx index 51e371ac09aa7b..b342ef29bbb474 100644 --- a/web/app/components/base/select/index.tsx +++ b/web/app/components/base/select/index.tsx @@ -191,6 +191,7 @@ const SimpleSelect: FC = ({ onClick={(e) => { e.stopPropagation() setSelectedItem(null) + onSelect({ value: null }) }} className="h-5 w-5 text-gray-400 cursor-pointer" aria-hidden="false" diff --git a/web/app/components/datasets/create/website/firecrawl/index.tsx b/web/app/components/datasets/create/website/firecrawl/index.tsx index bdd99b6dcd31fc..55a9f6b7ef7267 100644 --- a/web/app/components/datasets/create/website/firecrawl/index.tsx +++ b/web/app/components/datasets/create/website/firecrawl/index.tsx @@ -118,6 +118,7 @@ const FireCrawl: FC = ({ ...res, total: Math.min(res.total, parseFloat(crawlOptions.limit as string)), }) + onCheckedCrawlResultChange(res.data || []) // default select the crawl result await sleep(2500) return await waitForCrawlFinished(jobId) } @@ -162,6 +163,7 @@ const FireCrawl: FC = ({ } else { setCrawlResult(data) + onCheckedCrawlResultChange(data.data || []) // default select the crawl result setCrawlErrorMessage('') } } diff --git a/web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx b/web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx index 63ad8df0d896c2..19ec75c6c645a5 100644 --- a/web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx +++ b/web/app/components/header/account-setting/data-source-page/data-source-website/index.tsx @@ -77,7 +77,7 @@ const DataSourceWebsite: FC = () => { logo: ({ className }: { className: string }) => (
🔥
), - name: 'FireCrawl', + name: 'Firecrawl', isActive: true, }))} onRemove={handleRemove(DataSourceProvider.fireCrawl)} diff --git a/web/app/components/header/account-setting/data-source-page/panel/index.tsx b/web/app/components/header/account-setting/data-source-page/panel/index.tsx index 2c27005d1d2718..95475059e8e8f5 100644 --- a/web/app/components/header/account-setting/data-source-page/panel/index.tsx +++ b/web/app/components/header/account-setting/data-source-page/panel/index.tsx @@ -46,7 +46,7 @@ const Panel: FC = ({
{t(`common.dataSource.${type}.title`)}
{isWebsite && (
- {t('common.dataSource.website.with')} 🔥 FireCrawl + {t('common.dataSource.website.with')} 🔥 Firecrawl
)}
diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx index ca9f3cbd38c00b..cc8aa92fec734b 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx @@ -114,7 +114,7 @@ const Form: FC = ({ validated={validatedSuccess} placeholder={placeholder?.[language] || placeholder?.en_US} disabled={disabed} - type={formSchema.type === FormTypeEnum.textNumber ? 'number' : 'text'} + type={formSchema.type === FormTypeEnum.textNumber ? 'number' : formSchema.type === FormTypeEnum.secretInput ? 'password' : 'text'} {...(formSchema.type === FormTypeEnum.textNumber ? { min: (formSchema as CredentialFormSchemaNumberInput).min, max: (formSchema as CredentialFormSchemaNumberInput).max } : {})} /> {fieldMoreInfo?.(formSchema)} @@ -229,6 +229,7 @@ const Form: FC = ({ variable, label, show_on, + required, } = formSchema as CredentialFormSchemaRadio if (show_on.length && !show_on.every(showOnItem => value[showOnItem.variable] === showOnItem.value)) @@ -239,11 +240,16 @@ const Form: FC = ({
{label[language] || label.en_US} + { + required && ( + * + ) + } {tooltipContent}
handleFormChange(variable, val === 1)} > True diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx index 12244a5cef88ea..86d52619e69ddc 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Input.tsx @@ -53,7 +53,7 @@ const Input: FC = ({ onChange={e => onChange(e.target.value)} onBlur={e => toLimit(e.target.value)} onFocus={onFocus} - value={value || ''} + value={value} disabled={disabled} type={type} min={min} diff --git a/web/app/components/workflow/constants.ts b/web/app/components/workflow/constants.ts index a6f313e98e4434..1786ca4b47fedd 100644 --- a/web/app/components/workflow/constants.ts +++ b/web/app/components/workflow/constants.ts @@ -377,6 +377,10 @@ export const TOOL_OUTPUT_STRUCT: Var[] = [ variable: 'files', type: VarType.arrayFile, }, + { + variable: 'json', + type: VarType.arrayObject, + }, ] export const PARAMETER_EXTRACTOR_COMMON_STRUCT: Var[] = [ diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx index d944aade8e2b39..09891ff05e6f8a 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useCallback, useEffect, useRef, useState } from 'react' +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import cn from 'classnames' import { @@ -71,7 +71,9 @@ const VarReferencePicker: FC = ({ const isChatMode = useIsChatMode() const { getTreeLeafNodes, getBeforeNodesInSameBranch } = useWorkflow() - const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranch(nodeId)) + const availableNodes = useMemo(() => { + return passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranch(nodeId)) + }, [getBeforeNodesInSameBranch, getTreeLeafNodes, nodeId, onlyLeafNodeVar, passedInAvailableNodes]) const startNode = availableNodes.find((node: any) => { return node.data.type === BlockEnum.Start }) @@ -91,7 +93,7 @@ const VarReferencePicker: FC = ({ const [varKindType, setVarKindType] = useState(defaultVarKindType) const isConstant = isSupportConstantValue && varKindType === VarKindType.constant - const outputVars = (() => { + const outputVars = useMemo(() => { if (availableVars) return availableVars @@ -104,7 +106,8 @@ const VarReferencePicker: FC = ({ }) return vars - })() + }, [iterationNode, availableNodes, isChatMode, filterVar, availableVars, t]) + const [open, setOpen] = useState(false) useEffect(() => { onOpen() @@ -112,16 +115,16 @@ const VarReferencePicker: FC = ({ }, [open]) const hasValue = !isConstant && value.length > 0 - const isIterationVar = (() => { + const isIterationVar = useMemo(() => { if (!isInIteration) return false if (value[0] === node?.parentId && ['item', 'index'].includes(value[1])) return true return false - })() + }, [isInIteration, value, node]) const outputVarNodeId = hasValue ? value[0] : '' - const outputVarNode = (() => { + const outputVarNode = useMemo(() => { if (!hasValue || isConstant) return null @@ -132,16 +135,16 @@ const VarReferencePicker: FC = ({ return startNode?.data return getNodeInfoById(availableNodes, outputVarNodeId)?.data - })() + }, [value, hasValue, isConstant, isIterationVar, iterationNode, availableNodes, outputVarNodeId, startNode]) - const varName = (() => { + const varName = useMemo(() => { if (hasValue) { const isSystem = isSystemVar(value as ValueSelector) const varName = value.length >= 3 ? (value as ValueSelector).slice(-2).join('.') : value[value.length - 1] return `${isSystem ? 'sys.' : ''}${varName}` } return '' - })() + }, [hasValue, value]) const varKindTypes = [ { diff --git a/web/app/components/workflow/nodes/tool/panel.tsx b/web/app/components/workflow/nodes/tool/panel.tsx index e783e56ca71de3..1b00045c0feecf 100644 --- a/web/app/components/workflow/nodes/tool/panel.tsx +++ b/web/app/components/workflow/nodes/tool/panel.tsx @@ -131,6 +131,11 @@ const Panel: FC> = ({ type='Array[File]' description={t(`${i18nPrefix}.outputVars.files.title`)} /> +
diff --git a/web/app/forgot-password/ChangePasswordForm.tsx b/web/app/forgot-password/ChangePasswordForm.tsx new file mode 100644 index 00000000000000..d8786604161c45 --- /dev/null +++ b/web/app/forgot-password/ChangePasswordForm.tsx @@ -0,0 +1,178 @@ +'use client' +import { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import useSWR from 'swr' +import { useSearchParams } from 'next/navigation' +import cn from 'classnames' +import { CheckCircleIcon } from '@heroicons/react/24/solid' +import Button from '@/app/components/base/button' +import { changePasswordWithToken, verifyForgotPasswordToken } from '@/service/common' +import Toast from '@/app/components/base/toast' +import Loading from '@/app/components/base/loading' + +const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ + +const ChangePasswordForm = () => { + const { t } = useTranslation() + const searchParams = useSearchParams() + const token = searchParams.get('token') + + const verifyTokenParams = { + url: '/forgot-password/validity', + body: { token }, + } + const { data: verifyTokenRes, mutate: revalidateToken } = useSWR(verifyTokenParams, verifyForgotPasswordToken, { + revalidateOnFocus: false, + }) + + const [password, setPassword] = useState('') + const [confirmPassword, setConfirmPassword] = useState('') + const [showSuccess, setShowSuccess] = useState(false) + + const showErrorMessage = useCallback((message: string) => { + Toast.notify({ + type: 'error', + message, + }) + }, []) + + const valid = useCallback(() => { + if (!password.trim()) { + showErrorMessage(t('login.error.passwordEmpty')) + return false + } + if (!validPassword.test(password)) { + showErrorMessage(t('login.error.passwordInvalid')) + return false + } + if (password !== confirmPassword) { + showErrorMessage(t('common.account.notEqual')) + return false + } + return true + }, [password, confirmPassword, showErrorMessage, t]) + + const handleChangePassword = useCallback(async () => { + const token = searchParams.get('token') || '' + + if (!valid()) + return + try { + await changePasswordWithToken({ + url: '/forgot-password/resets', + body: { + token, + new_password: password, + password_confirm: confirmPassword, + }, + }) + setShowSuccess(true) + } + catch { + await revalidateToken() + } + }, [password, revalidateToken, token, valid]) + + return ( +
+ {!verifyTokenRes && } + {verifyTokenRes && !verifyTokenRes.is_valid && ( +
+
+
🤷‍♂️
+

{t('login.invalid')}

+
+ +
+ )} + {verifyTokenRes && verifyTokenRes.is_valid && !showSuccess && ( +
+
+

+ {t('login.changePassword')} +

+

+ {t('login.changePasswordTip')} +

+
+ +
+
+ {/* Password */} +
+ +
+ setPassword(e.target.value)} + placeholder={t('login.passwordPlaceholder') || ''} + className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'} + /> +
+
{t('login.error.passwordInvalid')}
+
+ {/* Confirm Password */} +
+ +
+ setConfirmPassword(e.target.value)} + placeholder={t('login.confirmPasswordPlaceholder') || ''} + className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'} + /> +
+
+
+ +
+
+
+
+ )} + {verifyTokenRes && verifyTokenRes.is_valid && showSuccess && ( +
+
+
+ +
+

+ {t('login.passwordChangedTip')} +

+
+ +
+ )} +
+ ) +} + +export default ChangePasswordForm diff --git a/web/app/forgot-password/ForgotPasswordForm.tsx b/web/app/forgot-password/ForgotPasswordForm.tsx new file mode 100644 index 00000000000000..6fd69a3638cbbf --- /dev/null +++ b/web/app/forgot-password/ForgotPasswordForm.tsx @@ -0,0 +1,122 @@ +'use client' +import React, { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' + +import { useRouter } from 'next/navigation' + +import { useForm } from 'react-hook-form' +import { z } from 'zod' +import { zodResolver } from '@hookform/resolvers/zod' +import Loading from '../components/base/loading' +import Button from '@/app/components/base/button' + +import { + fetchInitValidateStatus, + fetchSetupStatus, + sendForgotPasswordEmail, +} from '@/service/common' +import type { InitValidateStatusResponse, SetupStatusResponse } from '@/models/common' + +const accountFormSchema = z.object({ + email: z + .string() + .min(1, { message: 'login.error.emailInValid' }) + .email('login.error.emailInValid'), +}) + +type AccountFormValues = z.infer + +const ForgotPasswordForm = () => { + const { t } = useTranslation() + const router = useRouter() + const [loading, setLoading] = useState(true) + const [isEmailSent, setIsEmailSent] = useState(false) + const { register, trigger, getValues, formState: { errors } } = useForm({ + resolver: zodResolver(accountFormSchema), + defaultValues: { email: '' }, + }) + + const handleSendResetPasswordEmail = async (email: string) => { + try { + const res = await sendForgotPasswordEmail({ + url: '/forgot-password', + body: { email }, + }) + if (res.result === 'success') + setIsEmailSent(true) + + else console.error('Email verification failed') + } + catch (error) { + console.error('Request failed:', error) + } + } + + const handleSendResetPasswordClick = async () => { + if (isEmailSent) { + router.push('/signin') + } + else { + const isValid = await trigger('email') + if (isValid) { + const email = getValues('email') + await handleSendResetPasswordEmail(email) + } + } + } + + useEffect(() => { + fetchSetupStatus().then((res: SetupStatusResponse) => { + fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { + if (res.status === 'not_started') + window.location.href = '/init' + }) + + setLoading(false) + }) + }, []) + + return ( + loading + ? + : <> +
+

+ {isEmailSent ? t('login.resetLinkSent') : t('login.forgotPassword')} +

+

+ {isEmailSent ? t('login.checkEmailForResetLink') : t('login.forgotPasswordDesc')} +

+
+
+
+
+ {!isEmailSent && ( +
+ +
+ + {errors.email && {t(`${errors.email?.message}`)}} +
+
+ )} +
+ +
+
+
+
+ + ) +} + +export default ForgotPasswordForm diff --git a/web/app/forgot-password/page.tsx b/web/app/forgot-password/page.tsx new file mode 100644 index 00000000000000..fa44d1a20c689a --- /dev/null +++ b/web/app/forgot-password/page.tsx @@ -0,0 +1,38 @@ +'use client' +import React from 'react' +import classNames from 'classnames' +import { useSearchParams } from 'next/navigation' +import Header from '../signin/_header' +import style from '../signin/page.module.css' +import ForgotPasswordForm from './ForgotPasswordForm' +import ChangePasswordForm from '@/app/forgot-password/ChangePasswordForm' + +const ForgotPassword = () => { + const searchParams = useSearchParams() + const token = searchParams.get('token') + + return ( +
+
+
+ {token ? : } +
+ © {new Date().getFullYear()} Dify, Inc. All rights reserved. +
+
+
+ ) +} + +export default ForgotPassword diff --git a/web/app/signin/normalForm.tsx b/web/app/signin/normalForm.tsx index f23a04e4e4486a..40912c6e1f890f 100644 --- a/web/app/signin/normalForm.tsx +++ b/web/app/signin/normalForm.tsx @@ -224,21 +224,9 @@ const NormalForm = () => {
- } - > - {t('login.forget')} - */} + + {t('login.forget')} +
en la indicación arriba.', + learnMore: 'Aprender más', + editModal: { + title: 'Editar Nombres de Roles de Conversación', + userPrefix: 'Prefijo de Usuario', + assistantPrefix: 'Prefijo de Asistente', + }, + }, + toolbox: { + title: 'CAJA DE HERRAMIENTAS', + }, + moderation: { + title: 'Moderación de contenido', + description: 'Asegura la salida del modelo utilizando API de moderación o manteniendo una lista de palabras sensibles.', + allEnabled: 'Contenido de ENTRADA/SALIDA Habilitado', + inputEnabled: 'Contenido de ENTRADA Habilitado', + outputEnabled: 'Contenido de SALIDA Habilitado', + modal: { + title: 'Configuración de moderación de contenido', + provider: { + title: 'Proveedor', + openai: 'Moderación de OpenAI', + openaiTip: { + prefix: 'La Moderación de OpenAI requiere una clave API de OpenAI configurada en la ', + suffix: '.', + }, + keywords: 'Palabras clave', + }, + keywords: { + tip: 'Una por línea, separadas por saltos de línea. Hasta 100 caracteres por línea.', + placeholder: 'Una por línea, separadas por saltos de línea', + line: 'Línea', + }, + content: { + input: 'Moderar Contenido de ENTRADA', + output: 'Moderar Contenido de SALIDA', + preset: 'Respuestas predefinidas', + placeholder: 'Contenido de respuestas predefinidas aquí', + condition: 'Moderar Contenido de ENTRADA y SALIDA habilitado al menos uno', + fromApi: 'Las respuestas predefinidas son devueltas por la API', + errorMessage: 'Las respuestas predefinidas no pueden estar vacías', + supportMarkdown: 'Markdown soportado', + }, + openaiNotConfig: { + before: 'La Moderación de OpenAI requiere una clave API de OpenAI configurada en la', + after: '', + }, + }, + }, + }, + automatic: { + title: 'Orquestación automatizada de aplicaciones', + description: 'Describe tu escenario, Dify orquestará una aplicación para ti.', + intendedAudience: '¿Quién es el público objetivo?', + intendedAudiencePlaceHolder: 'p.ej. Estudiante', + solveProblem: '¿Qué problemas esperan que la IA pueda resolver para ellos?', + solveProblemPlaceHolder: 'p.ej. Extraer ideas y resumir información de informes y artículos largos', + generate: 'Generar', + audiencesRequired: 'Audiencia requerida', + problemRequired: 'Problema requerido', + resTitle: 'Hemos orquestado la siguiente aplicación para ti.', + apply: 'Aplicar esta orquestación', + noData: 'Describe tu caso de uso a la izquierda, la vista previa de la orquestación se mostrará aquí.', + loading: 'Orquestando la aplicación para ti...', + overwriteTitle: '¿Sobrescribir configuración existente?', + overwriteMessage: 'Aplicar esta orquestación sobrescribirá la configuración existente.', + }, + resetConfig: { + title: '¿Confirmar restablecimiento?', + message: 'Restablecer descarta cambios, restaurando la última configuración publicada.', + }, + errorMessage: { + nameOfKeyRequired: 'nombre de la clave: {{key}} requerido', + valueOfVarRequired: 'el valor de {{key}} no puede estar vacío', + queryRequired: 'Se requiere texto de solicitud.', + waitForResponse: 'Por favor espera la respuesta al mensaje anterior para completar.', + waitForBatchResponse: 'Por favor espera la respuesta a la tarea por lotes para completar.', + notSelectModel: 'Por favor elige un modelo', + waitForImgUpload: 'Por favor espera a que la imagen se cargue', + }, + chatSubTitle: 'Instrucciones', + completionSubTitle: 'Prefijo de la Indicación', + promptTip: 'Las indicaciones guían las respuestas de la IA con instrucciones y restricciones. Inserta variables como {{input}}. Esta indicación no será visible para los usuarios.', + formattingChangedTitle: 'Formato cambiado', + formattingChangedText: 'Modificar el formato restablecerá el área de depuración, ¿estás seguro?', + variableTitle: 'Variables', + variableTip: 'Los usuarios completan las variables en un formulario, reemplazando automáticamente las variables en la indicación.', + notSetVar: 'Las variables permiten a los usuarios introducir palabras de indicación u observaciones de apertura al completar formularios. Puedes intentar ingresar "{{input}}" en las palabras de indicación.', + autoAddVar: 'Variables no definidas referenciadas en la pre-indicación, ¿quieres agregarlas en el formulario de entrada del usuario?', + variableTable: { + key: 'Clave de Variable', + name: 'Nombre del Campo de Entrada del Usuario', + optional: 'Opcional', + type: 'Tipo de Entrada', + action: 'Acciones', + typeString: 'Cadena', + typeSelect: 'Seleccionar', + }, + varKeyError: { + canNoBeEmpty: 'La clave de la variable no puede estar vacía', + tooLong: 'Clave de la variable: {{key}} demasiado larga. No puede tener más de 30 caracteres', + notValid: 'Clave de la variable: {{key}} no es válida. Solo puede contener letras, números y guiones bajos', + notStartWithNumber: 'Clave de la variable: {{key}} no puede comenzar con un número', + keyAlreadyExists: 'Clave de la variable: {{key}} ya existe', + }, + otherError: { + promptNoBeEmpty: 'La indicación no puede estar vacía', + historyNoBeEmpty: 'El historial de conversaciones debe establecerse en la indicación', + queryNoBeEmpty: 'La consulta debe establecerse en la indicación', + }, + variableConig: { + 'addModalTitle': 'Agregar Campo de Entrada', + 'editModalTitle': 'Editar Campo de Entrada', + 'description': 'Configuración para la variable {{varName}}', + 'fieldType': 'Tipo de campo', + 'string': 'Texto corto', + 'text-input': 'Texto corto', + 'paragraph': 'Párrafo', + 'select': 'Seleccionar', + 'number': 'Número', + 'notSet': 'No configurado, intenta escribir {{input}} en la indicación de prefijo', + 'stringTitle': 'Opciones de cuadro de texto de formulario', + 'maxLength': 'Longitud máxima', + 'options': 'Opciones', + 'addOption': 'Agregar opción', + 'apiBasedVar': 'Variable basada en API', + 'varName': 'Nombre de la Variable', + 'labelName': 'Nombre de la Etiqueta', + 'inputPlaceholder': 'Por favor ingresa', + 'content': 'Contenido', + 'required': 'Requerido', + 'errorMsg': { + varNameRequired: 'Nombre de la variable es requerido', + labelNameRequired: 'Nombre de la etiqueta es requerido', + varNameCanBeRepeat: 'El nombre de la variable no puede repetirse', + atLeastOneOption: 'Se requiere al menos una opción', + optionRepeat: 'Hay opciones repetidas', + }, + }, + vision: { + name: 'Visión', + description: 'Habilitar Visión permitirá al modelo recibir imágenes y responder preguntas sobre ellas.', + settings: 'Configuraciones', + visionSettings: { + title: 'Configuraciones de Visión', + resolution: 'Resolución', + resolutionTooltip: `Baja resolución permitirá que el modelo reciba una versión de baja resolución de 512 x 512 de la imagen, y represente la imagen con un presupuesto de 65 tokens. Esto permite que la API devuelva respuestas más rápidas y consuma menos tokens de entrada para casos de uso que no requieren alta detalle. + \n + Alta resolución permitirá primero que el modelo vea la imagen de baja resolución y luego crea recortes detallados de las imágenes de entrada como cuadrados de 512px basados en el tamaño de la imagen de entrada. Cada uno de los recortes detallados usa el doble del presupuesto de tokens para un total de 129 tokens.`, + high: 'Alta', + low: 'Baja', + uploadMethod: 'Método de carga', + both: 'Ambos', + localUpload: 'Carga Local', + url: 'URL', + uploadLimit: 'Límite de carga', + }, + }, + voice: { + name: 'Voz', + defaultDisplay: 'Voz Predeterminada', + description: 'Configuraciones de voz a texto', + settings: 'Configuraciones', + voiceSettings: { + title: 'Configuraciones de Voz', + language: 'Idioma', + resolutionTooltip: 'Soporte de idioma para voz a texto.', + voice: 'Voz', + }, + }, + openingStatement: { + title: 'Apertura de Conversación', + add: 'Agregar', + writeOpener: 'Escribir apertura', + placeholder: 'Escribe tu mensaje de apertura aquí, puedes usar variables, intenta escribir {{variable}}.', + openingQuestion: 'Preguntas de Apertura', + noDataPlaceHolder: 'Iniciar la conversación con el usuario puede ayudar a la IA a establecer una conexión más cercana con ellos en aplicaciones de conversación.', + varTip: 'Puedes usar variables, intenta escribir {{variable}}', + tooShort: 'Se requieren al menos 20 palabras en la indicación inicial para generar una apertura de conversación.', + notIncludeKey: 'La indicación inicial no incluye la variable: {{key}}. Por favor agrégala a la indicación inicial.', + }, + modelConfig: { + model: 'Modelo', + setTone: 'Establecer tono de respuestas', + title: 'Modelo y Parámetros', + modeType: { + chat: 'Chat', + completion: 'Completar', + }, + }, + inputs: { + title: 'Depurar y Previsualizar', + noPrompt: 'Intenta escribir alguna indicación en la entrada de pre-indicación', + userInputField: 'Campo de Entrada del Usuario', + noVar: 'Completa el valor de la variable, que se reemplazará automáticamente en la palabra de indicación cada vez que se inicie una nueva sesión.', + chatVarTip: 'Completa el valor de la variable, que se reemplazará automáticamente en la palabra de indicación cada vez que se inicie una nueva sesión', + completionVarTip: 'Completa el valor de la variable, que se reemplazará automáticamente en las palabras de indicación cada vez que se envíe una pregunta.', + previewTitle: 'Vista previa de la indicación', + queryTitle: 'Contenido de la consulta', + queryPlaceholder: 'Por favor ingresa el texto de la solicitud.', + run: 'EJECUTAR', + }, + result: 'Texto de salida', + datasetConfig: { + settingTitle: 'Configuraciones de Recuperación', + knowledgeTip: 'Haz clic en el botón “+” para agregar conocimiento', + retrieveOneWay: { + title: 'Recuperación N-a-1', + description: 'Basado en la intención del usuario y las descripciones de Conocimiento, el Agente selecciona autónomamente el mejor Conocimiento para consultar. Ideal para aplicaciones con Conocimiento limitado y distintivo.', + }, + retrieveMultiWay: { + title: 'Recuperación Multi-camino', + description: 'Basado en la intención del usuario, consulta a través de todo el Conocimiento, recupera texto relevante de múltiples fuentes y selecciona los mejores resultados que coinciden con la consulta del usuario después de reordenar. Se requiere configuración de la API del modelo de Reordenar.', + }, + rerankModelRequired: 'Se requiere modelo de Reordenar', + params: 'Parámetros', + top_k: 'Top K', + top_kTip: 'Usado para filtrar fragmentos que son más similares a las preguntas del usuario. El sistema también ajustará dinámicamente el valor de Top K, de acuerdo con los max_tokens del modelo seleccionado.', + score_threshold: 'Umbral de Puntuación', + score_thresholdTip: 'Usado para establecer el umbral de similitud para la filtración de fragmentos.', + retrieveChangeTip: 'Modificar el modo de índice y el modo de recuperación puede afectar las aplicaciones asociadas con este Conocimiento.', + }, + debugAsSingleModel: 'Depurar como Modelo Único', + debugAsMultipleModel: 'Depurar como Múltiples Modelos', + duplicateModel: 'Duplicar', + publishAs: 'Publicar como', + assistantType: { + name: 'Tipo de Asistente', + chatAssistant: { + name: 'Asistente Básico', + description: 'Construye un asistente basado en chat usando un Modelo de Lenguaje Grande', + }, + agentAssistant: { + name: 'Asistente Agente', + description: 'Construye un Agente inteligente que puede elegir herramientas autónomamente para completar tareas', + }, + }, + agent: { + agentMode: 'Modo Agente', + agentModeDes: 'Establecer el tipo de modo de inferencia para el agente', + agentModeType: { + ReACT: 'ReAct', + functionCall: 'Llamada de Función', + }, + setting: { + name: 'Configuraciones del Agente', + description: 'Las configuraciones del Asistente Agente permiten establecer el modo del agente y funciones avanzadas como indicaciones integradas, disponibles solo en el tipo Agente.', + maximumIterations: { + name: 'Iteraciones Máximas', + description: 'Limitar el número de iteraciones que un asistente agente puede ejecutar', + }, + }, + buildInPrompt: 'Indicación Integrada', + firstPrompt: 'Primera Indicación', + nextIteration: 'Próxima Iteración', + promptPlaceholder: 'Escribe tu indicación aquí', + tools: { + name: 'Herramientas', + description: 'El uso de herramientas puede extender las capacidades del LLM, como buscar en internet o realizar cálculos científicos', + enabled: 'Habilitado', + }, + }, +} + +export default translation diff --git a/web/i18n/es-ES/app-log.ts b/web/i18n/es-ES/app-log.ts new file mode 100644 index 00000000000000..2a6c9f57dacf5a --- /dev/null +++ b/web/i18n/es-ES/app-log.ts @@ -0,0 +1,91 @@ +const translation = { + title: 'Registros', + description: 'Los registros registran el estado de ejecución de la aplicación, incluyendo las entradas de usuario y las respuestas de la IA.', + dateTimeFormat: 'MM/DD/YYYY hh:mm A', + table: { + header: { + time: 'Tiempo', + endUser: 'Usuario Final', + input: 'Entrada', + output: 'Salida', + summary: 'Título', + messageCount: 'Cantidad de Mensajes', + userRate: 'Tasa de Usuario', + adminRate: 'Tasa de Op.', + startTime: 'HORA DE INICIO', + status: 'ESTADO', + runtime: 'TIEMPO DE EJECUCIÓN', + tokens: 'TOKENS', + user: 'USUARIO FINAL', + version: 'VERSIÓN', + }, + pagination: { + previous: 'Anterior', + next: 'Siguiente', + }, + empty: { + noChat: 'Aún no hay conversación', + noOutput: 'Sin salida', + element: { + title: '¿Hay alguien ahí?', + content: 'Observa y anota las interacciones entre los usuarios finales y las aplicaciones de IA aquí para mejorar continuamente la precisión de la IA. Puedes probar compartiendo o probando la aplicación web tú mismo, y luego regresar a esta página.', + }, + }, + }, + detail: { + time: 'Tiempo', + conversationId: 'ID de Conversación', + promptTemplate: 'Plantilla de Indicación', + promptTemplateBeforeChat: 'Plantilla de Indicación Antes de la Conversación · Como Mensaje del Sistema', + annotationTip: 'Mejoras Marcadas por {{user}}', + timeConsuming: '', + second: 's', + tokenCost: 'Tokens gastados', + loading: 'cargando', + operation: { + like: 'me gusta', + dislike: 'no me gusta', + addAnnotation: 'Agregar Mejora', + editAnnotation: 'Editar Mejora', + annotationPlaceholder: 'Ingresa la respuesta esperada que deseas que la IA responda, lo cual se puede utilizar para el ajuste del modelo y la mejora continua de la calidad de generación de texto en el futuro.', + }, + variables: 'Variables', + uploadImages: 'Imágenes Cargadas', + }, + filter: { + period: { + today: 'Hoy', + last7days: 'Últimos 7 Días', + last4weeks: 'Últimas 4 semanas', + last3months: 'Últimos 3 meses', + last12months: 'Últimos 12 meses', + monthToDate: 'Mes hasta la fecha', + quarterToDate: 'Trimestre hasta la fecha', + yearToDate: 'Año hasta la fecha', + allTime: 'Todo el tiempo', + }, + annotation: { + all: 'Todos', + annotated: 'Mejoras Anotadas ({{count}} elementos)', + not_annotated: 'No Anotadas', + }, + }, + workflowTitle: 'Registros de Flujo de Trabajo', + workflowSubtitle: 'El registro registró la operación de Automate.', + runDetail: { + title: 'Registro de Conversación', + workflowTitle: 'Detalle del Registro', + }, + promptLog: 'Registro de Indicación', + agentLog: 'Registro de Agente', + viewLog: 'Ver Registro', + agentLogDetail: { + agentMode: 'Modo de Agente', + toolUsed: 'Herramienta Utilizada', + iterations: 'Iteraciones', + iteration: 'Iteración', + finalProcessing: 'Procesamiento Final', + }, +} + +export default translation diff --git a/web/i18n/es-ES/app-overview.ts b/web/i18n/es-ES/app-overview.ts new file mode 100644 index 00000000000000..f3aaf1f737ce04 --- /dev/null +++ b/web/i18n/es-ES/app-overview.ts @@ -0,0 +1,156 @@ +const translation = { + welcome: { + firstStepTip: 'Para comenzar,', + enterKeyTip: 'ingresa tu clave de API de OpenAI a continuación', + getKeyTip: 'Obtén tu clave de API desde el panel de control de OpenAI', + placeholder: 'Tu clave de API de OpenAI (ej. sk-xxxx)', + }, + apiKeyInfo: { + cloud: { + trial: { + title: 'Estás utilizando la cuota de prueba de {{providerName}}.', + description: 'La cuota de prueba se proporciona para su uso de prueba. Antes de que se agoten las llamadas de la cuota de prueba, configure su propio proveedor de modelos o compre cuota adicional.', + }, + exhausted: { + title: 'Tu cuota de prueba se ha agotado, por favor configura tu APIKey.', + description: 'Tu cuota de prueba se ha agotado. Por favor, configure su propio proveedor de modelos o compre cuota adicional.', + }, + }, + selfHost: { + title: { + row1: 'Para comenzar,', + row2: 'configura primero tu proveedor de modelos.', + }, + }, + callTimes: 'Veces llamadas', + usedToken: 'Token utilizados', + setAPIBtn: 'Ir a configurar proveedor de modelos', + tryCloud: 'O prueba la versión en la nube de Dify con una cotización gratuita', + }, + overview: { + title: 'Resumen', + appInfo: { + explanation: 'Aplicación web de IA lista para usar', + accessibleAddress: 'URL pública', + preview: 'Vista previa', + regenerate: 'Regenerar', + regenerateNotice: '¿Deseas regenerar la URL pública?', + preUseReminder: 'Por favor, habilita la aplicación web antes de continuar.', + settings: { + entry: 'Configuración', + title: 'Configuración de la aplicación web', + webName: 'Nombre de la aplicación web', + webDesc: 'Descripción de la aplicación web', + webDescTip: 'Este texto se mostrará en el lado del cliente, proporcionando una guía básica sobre cómo usar la aplicación', + webDescPlaceholder: 'Ingresa la descripción de la aplicación web', + language: 'Idioma', + workflow: { + title: 'Pasos del flujo de trabajo', + show: 'Mostrar', + hide: 'Ocultar', + }, + chatColorTheme: 'Tema de color del chat', + chatColorThemeDesc: 'Establece el tema de color del chatbot', + chatColorThemeInverted: 'Invertido', + invalidHexMessage: 'Valor hexadecimal no válido', + more: { + entry: 'Mostrar más configuraciones', + copyright: 'Derechos de autor', + copyRightPlaceholder: 'Ingresa el nombre del autor o la organización', + privacyPolicy: 'Política de privacidad', + privacyPolicyPlaceholder: 'Ingresa el enlace de la política de privacidad', + privacyPolicyTip: 'Ayuda a los visitantes a comprender los datos que recopila la aplicación, consulta la Política de privacidad de Dify.', + customDisclaimer: 'Descargo de responsabilidad personalizado', + customDisclaimerPlaceholder: 'Ingresa el texto de descargo de responsabilidad personalizado', + customDisclaimerTip: 'El texto de descargo de responsabilidad personalizado se mostrará en el lado del cliente, proporcionando información adicional sobre la aplicación', + }, + }, + embedded: { + entry: 'Incrustado', + title: 'Incrustar en el sitio web', + explanation: 'Elige la forma de incrustar la aplicación de chat en tu sitio web', + iframe: 'Para agregar la aplicación de chat en cualquier lugar de tu sitio web, agrega este iframe a tu código HTML.', + scripts: 'Para agregar una aplicación de chat en la esquina inferior derecha de tu sitio web, agrega este código a tu HTML.', + chromePlugin: 'Instalar la extensión de Chrome de Dify Chatbot', + copied: 'Copiado', + copy: 'Copiar', + }, + qrcode: { + title: 'Código QR para compartir', + scan: 'Escanear para compartir la aplicación', + download: 'Descargar código QR', + }, + customize: { + way: 'forma', + entry: 'Personalizar', + title: 'Personalizar la aplicación web de IA', + explanation: 'Puedes personalizar el frontend de la aplicación web para adaptarlo a tus necesidades y estilo.', + way1: { + name: 'Bifurca el código del cliente, modifícalo y despliégalo en Vercel (recomendado)', + step1: 'Bifurca el código del cliente y modifícalo', + step1Tip: 'Haz clic aquí para bifurcar el código fuente en tu cuenta de GitHub y modificar el código', + step1Operation: 'Dify-WebClient', + step2: 'Despliégalo en Vercel', + step2Tip: 'Haz clic aquí para importar el repositorio en Vercel y desplegarlo', + step2Operation: 'Importar repositorio', + step3: 'Configura las variables de entorno', + step3Tip: 'Agrega las siguientes variables de entorno en Vercel', + }, + way2: { + name: 'Escribe código del lado del cliente para llamar a la API y despliégalo en un servidor', + operation: 'Documentación', + }, + }, + }, + apiInfo: { + title: 'API del servicio backend', + explanation: 'Fácilmente integrable en tu aplicación', + accessibleAddress: 'Punto de conexión de la API del servicio', + doc: 'Referencia de la API', + }, + status: { + running: 'En servicio', + disable: 'Deshabilitar', + }, + }, + analysis: { + title: 'Análisis', + ms: 'ms', + tokenPS: 'Token/s', + totalMessages: { + title: 'Mensajes totales', + explanation: 'Recuento diario de interacciones de IA; excluye la ingeniería/depuración de prompts.', + }, + activeUsers: { + title: 'Usuarios activos', + explanation: 'Usuarios únicos que interactúan en preguntas y respuestas con IA; excluye la ingeniería/depuración de prompts.', + }, + tokenUsage: { + title: 'Uso de tokens', + explanation: 'Refleja el uso diario de tokens del modelo de lenguaje para la aplicación, útil para el control de costos.', + consumed: 'Consumidos', + }, + avgSessionInteractions: { + title: 'Interacciones promedio por sesión', + explanation: 'Recuento continuo de comunicación usuario-IA; para aplicaciones basadas en conversaciones.', + }, + avgUserInteractions: { + title: 'Interacciones promedio por usuario', + explanation: 'Refleja la frecuencia de uso diario de los usuarios. Esta métrica refleja la fidelidad del usuario.', + }, + userSatisfactionRate: { + title: 'Tasa de satisfacción del usuario', + explanation: 'El número de likes por cada 1,000 mensajes. Esto indica la proporción de respuestas con las que los usuarios están muy satisfechos.', + }, + avgResponseTime: { + title: 'Tiempo promedio de respuesta', + explanation: 'Tiempo (ms) que tarda la IA en procesar/responder; para aplicaciones basadas en texto.', + }, + tps: { + title: 'Velocidad de salida de tokens', + explanation: 'Mide el rendimiento del LLM. Cuenta la velocidad de salida de tokens del LLM desde el inicio de la solicitud hasta la finalización de la salida.', + }, + }, +} + +export default translation diff --git a/web/i18n/es-ES/app.ts b/web/i18n/es-ES/app.ts new file mode 100644 index 00000000000000..82359b40b0bd26 --- /dev/null +++ b/web/i18n/es-ES/app.ts @@ -0,0 +1,126 @@ +const translation = { + createApp: 'CREAR APP', + types: { + all: 'Todos', + chatbot: 'Chatbot', + agent: 'Agente', + workflow: 'Flujo de trabajo', + completion: 'Finalización', + }, + duplicate: 'Duplicar', + duplicateTitle: 'Duplicar App', + export: 'Exportar DSL', + exportFailed: 'Error al exportar DSL.', + importDSL: 'Importar archivo DSL', + createFromConfigFile: 'Crear desde archivo DSL', + deleteAppConfirmTitle: '¿Eliminar esta app?', + deleteAppConfirmContent: + 'Eliminar la app es irreversible. Los usuarios ya no podrán acceder a tu app y todas las configuraciones y registros de prompts se eliminarán permanentemente.', + appDeleted: 'App eliminada', + appDeleteFailed: 'Error al eliminar app', + join: 'Únete a la comunidad', + communityIntro: + 'Discute con miembros del equipo, colaboradores y desarrolladores en diferentes canales.', + roadmap: 'Ver nuestro plan de desarrollo', + newApp: { + startFromBlank: 'Crear desde cero', + startFromTemplate: 'Crear desde plantilla', + captionAppType: '¿Qué tipo de app quieres crear?', + chatbotDescription: 'Crea una aplicación basada en chat. Esta app utiliza un formato de pregunta y respuesta, permitiendo múltiples rondas de conversación continua.', + completionDescription: 'Crea una aplicación que genera texto de alta calidad basado en prompts, como la generación de artículos, resúmenes, traducciones y más.', + completionWarning: 'Este tipo de app ya no será compatible.', + agentDescription: 'Crea un Agente inteligente que puede elegir herramientas de forma autónoma para completar tareas', + workflowDescription: 'Crea una aplicación que genera texto de alta calidad basado en flujos de trabajo con un alto grado de personalización. Es adecuado para usuarios experimentados.', + workflowWarning: 'Actualmente en beta', + chatbotType: 'Método de orquestación del Chatbot', + basic: 'Básico', + basicTip: 'Para principiantes, se puede cambiar a Chatflow más adelante', + basicFor: 'PARA PRINCIPIANTES', + basicDescription: 'La Orquestación Básica permite la orquestación de una app de Chatbot utilizando configuraciones simples, sin la capacidad de modificar los prompts incorporados. Es adecuado para principiantes.', + advanced: 'Chatflow', + advancedFor: 'Para usuarios avanzados', + advancedDescription: 'La Orquestación de Flujo de Trabajo orquesta Chatbots en forma de flujos de trabajo, ofreciendo un alto grado de personalización, incluida la capacidad de editar los prompts incorporados. Es adecuado para usuarios experimentados.', + captionName: 'Icono y nombre de la app', + appNamePlaceholder: 'Asigna un nombre a tu app', + captionDescription: 'Descripción', + appDescriptionPlaceholder: 'Ingresa la descripción de la app', + useTemplate: 'Usar esta plantilla', + previewDemo: 'Vista previa de demostración', + chatApp: 'Asistente', + chatAppIntro: + 'Quiero construir una aplicación basada en chat. Esta app utiliza un formato de pregunta y respuesta, permitiendo múltiples rondas de conversación continua.', + agentAssistant: 'Nuevo Asistente de Agente', + completeApp: 'Generador de Texto', + completeAppIntro: + 'Quiero crear una aplicación que genera texto de alta calidad basado en prompts, como la generación de artículos, resúmenes, traducciones y más.', + showTemplates: 'Quiero elegir una plantilla', + hideTemplates: 'Volver a la selección de modo', + Create: 'Crear', + Cancel: 'Cancelar', + nameNotEmpty: 'El nombre no puede estar vacío', + appTemplateNotSelected: 'Por favor, selecciona una plantilla', + appTypeRequired: 'Por favor, selecciona un tipo de app', + appCreated: 'App creada', + appCreateFailed: 'Error al crear app', + }, + editApp: 'Editar información', + editAppTitle: 'Editar información de la app', + editDone: 'Información de la app actualizada', + editFailed: 'Error al actualizar información de la app', + emoji: { + ok: 'OK', + cancel: 'Cancelar', + }, + switch: 'Cambiar a Orquestación de Flujo de Trabajo', + switchTipStart: 'Se creará una nueva copia de la app para ti y la nueva copia cambiará a Orquestación de Flujo de Trabajo. La nueva copia no permitirá', + switchTip: 'volver', + switchTipEnd: ' a la Orquestación Básica.', + switchLabel: 'La copia de la app a crear', + removeOriginal: 'Eliminar la app original', + switchStart: 'Iniciar cambio', + typeSelector: { + all: 'Todos los tipos', + chatbot: 'Chatbot', + agent: 'Agente', + workflow: 'Flujo de trabajo', + completion: 'Finalización', + }, + tracing: { + title: 'Rastreo del rendimiento de la app', + description: 'Configuración de un proveedor de LLMOps de terceros y rastreo del rendimiento de la app.', + config: 'Configurar', + collapse: 'Contraer', + expand: 'Expandir', + tracing: 'Rastreo', + disabled: 'Deshabilitado', + disabledTip: 'Por favor, configura el proveedor primero', + enabled: 'En servicio', + tracingDescription: 'Captura el contexto completo de la ejecución de la app, incluyendo llamadas LLM, contexto, prompts, solicitudes HTTP y más, en una plataforma de rastreo de terceros.', + configProviderTitle: { + configured: 'Configurado', + notConfigured: 'Configurar proveedor para habilitar el rastreo', + moreProvider: 'Más proveedores', + }, + langsmith: { + title: 'LangSmith', + description: 'Una plataforma de desarrollo todo en uno para cada paso del ciclo de vida de la aplicación impulsada por LLM.', + }, + langfuse: { + title: 'Langfuse', + description: 'Rastrea, evalúa, gestiona prompts y métricas para depurar y mejorar tu aplicación LLM.', + }, + inUse: 'En uso', + configProvider: { + title: 'Configurar ', + placeholder: 'Ingresa tu {{key}}', + project: 'Proyecto', + publicKey: 'Clave pública', + secretKey: 'Clave secreta', + viewDocsLink: 'Ver documentación de {{key}}', + removeConfirmTitle: '¿Eliminar la configuración de {{key}}?', + removeConfirmContent: 'La configuración actual está en uso, eliminarla desactivará la función de rastreo.', + }, + }, +} + +export default translation diff --git a/web/i18n/es-ES/billing.ts b/web/i18n/es-ES/billing.ts new file mode 100644 index 00000000000000..8dcee420f5d912 --- /dev/null +++ b/web/i18n/es-ES/billing.ts @@ -0,0 +1,118 @@ +const translation = { + currentPlan: 'Plan Actual', + upgradeBtn: { + plain: 'Actualizar Plan', + encourage: 'Actualizar Ahora', + encourageShort: 'Actualizar', + }, + viewBilling: 'Administrar facturación y suscripciones', + buyPermissionDeniedTip: 'Por favor, contacta al administrador de tu empresa para suscribirte', + plansCommon: { + title: 'Elige un plan que sea adecuado para ti', + yearlyTip: '¡Obtén 2 meses gratis al suscribirte anualmente!', + mostPopular: 'Más Popular', + planRange: { + monthly: 'Mensual', + yearly: 'Anual', + }, + month: 'mes', + year: 'año', + save: 'Ahorra ', + free: 'Gratis', + currentPlan: 'Plan Actual', + contractSales: 'Contactar ventas', + contractOwner: 'Contactar al administrador del equipo', + startForFree: 'Empezar gratis', + getStartedWith: 'Empezar con ', + contactSales: 'Contactar Ventas', + talkToSales: 'Hablar con Ventas', + modelProviders: 'Proveedores de Modelos', + teamMembers: 'Miembros del Equipo', + annotationQuota: 'Cuota de Anotación', + buildApps: 'Crear Aplicaciones', + vectorSpace: 'Espacio Vectorial', + vectorSpaceBillingTooltip: 'Cada 1MB puede almacenar aproximadamente 1.2 millones de caracteres de datos vectorizados (estimado utilizando OpenAI Embeddings, varía según los modelos).', + vectorSpaceTooltip: 'El Espacio Vectorial es el sistema de memoria a largo plazo necesario para que los LLMs comprendan tus datos.', + documentsUploadQuota: 'Cuota de Carga de Documentos', + documentProcessingPriority: 'Prioridad de Procesamiento de Documentos', + documentProcessingPriorityTip: 'Para una mayor prioridad de procesamiento de documentos, por favor actualiza tu plan.', + documentProcessingPriorityUpgrade: 'Procesa más datos con mayor precisión y velocidad.', + priority: { + 'standard': 'Estándar', + 'priority': 'Prioridad', + 'top-priority': 'Prioridad Máxima', + }, + logsHistory: 'Historial de Registros', + customTools: 'Herramientas Personalizadas', + unavailable: 'No disponible', + days: 'días', + unlimited: 'Ilimitado', + support: 'Soporte', + supportItems: { + communityForums: 'Foros Comunitarios', + emailSupport: 'Soporte por Correo Electrónico', + priorityEmail: 'Soporte Prioritario por Correo Electrónico y Chat', + logoChange: 'Cambio de Logotipo', + SSOAuthentication: 'Autenticación SSO', + personalizedSupport: 'Soporte Personalizado', + dedicatedAPISupport: 'Soporte API Dedicado', + customIntegration: 'Integración y Soporte Personalizado', + ragAPIRequest: 'Solicitudes API RAG', + bulkUpload: 'Carga Masiva de Documentos', + agentMode: 'Modo Agente', + workflow: 'Flujo de Trabajo', + llmLoadingBalancing: 'Balanceo de Carga LLM', + llmLoadingBalancingTooltip: 'Agrega múltiples claves API a los modelos, evitando efectivamente los límites de velocidad de API.', + }, + comingSoon: 'Próximamente', + member: 'Miembro', + memberAfter: 'Miembro', + messageRequest: { + title: 'Créditos de Mensajes', + tooltip: 'Cuotas de invocación de mensajes para varios planes utilizando modelos de OpenAI (excepto gpt4). Los mensajes que excedan el límite utilizarán tu clave API de OpenAI.', + }, + annotatedResponse: { + title: 'Límites de Cuota de Anotación', + tooltip: 'Edición manual y anotación de respuestas proporciona habilidades de respuesta a preguntas personalizadas y de alta calidad para aplicaciones (aplicable solo en aplicaciones de chat).', + }, + ragAPIRequestTooltip: 'Se refiere al número de llamadas API que invocan solo las capacidades de procesamiento de base de conocimientos de Dify.', + receiptInfo: 'Solo el propietario del equipo y el administrador del equipo pueden suscribirse y ver la información de facturación.', + }, + plans: { + sandbox: { + name: 'Sandbox', + description: 'Prueba gratuita de 200 veces GPT', + includesTitle: 'Incluye:', + }, + professional: { + name: 'Profesional', + description: 'Para individuos y pequeños equipos que desean desbloquear más poder de manera asequible.', + includesTitle: 'Todo en el plan gratuito, más:', + }, + team: { + name: 'Equipo', + description: 'Colabora sin límites y disfruta de un rendimiento de primera categoría.', + includesTitle: 'Todo en el plan Profesional, más:', + }, + enterprise: { + name: 'Empresa', + description: 'Obtén capacidades completas y soporte para sistemas críticos a gran escala.', + includesTitle: 'Todo en el plan Equipo, más:', + }, + }, + vectorSpace: { + fullTip: 'El Espacio Vectorial está lleno.', + fullSolution: 'Actualiza tu plan para obtener más espacio.', + }, + apps: { + fullTipLine1: 'Actualiza tu plan para', + fullTipLine2: 'crear más aplicaciones.', + }, + annotatedResponse: { + fullTipLine1: 'Actualiza tu plan para', + fullTipLine2: 'anotar más conversaciones.', + quotaTitle: 'Cuota de Respuesta Anotada', + }, +} + +export default translation diff --git a/web/i18n/es-ES/common.ts b/web/i18n/es-ES/common.ts new file mode 100644 index 00000000000000..e60c5441a79b06 --- /dev/null +++ b/web/i18n/es-ES/common.ts @@ -0,0 +1,571 @@ +const translation = { + api: { + success: 'Éxito', + actionSuccess: 'Acción exitosa', + saved: 'Guardado', + create: 'Creado', + remove: 'Eliminado', + }, + operation: { + create: 'Crear', + confirm: 'Confirmar', + cancel: 'Cancelar', + clear: 'Limpiar', + save: 'Guardar', + saveAndEnable: 'Guardar y habilitar', + edit: 'Editar', + add: 'Agregar', + added: 'Agregado', + refresh: 'Reiniciar', + reset: 'Restablecer', + search: 'Buscar', + change: 'Cambiar', + remove: 'Eliminar', + send: 'Enviar', + copy: 'Copiar', + lineBreak: 'Salto de línea', + sure: 'Estoy seguro', + download: 'Descargar', + delete: 'Eliminar', + settings: 'Configuraciones', + setup: 'Configurar', + getForFree: 'Obtener gratis', + reload: 'Recargar', + ok: 'OK', + log: 'Registro', + learnMore: 'Aprender más', + params: 'Parámetros', + duplicate: 'Duplicar', + rename: 'Renombrar', + }, + errorMsg: { + fieldRequired: '{{field}} es requerido', + urlError: 'la URL debe comenzar con http:// o https://', + }, + placeholder: { + input: 'Por favor ingresa', + select: 'Por favor selecciona', + }, + voice: { + language: { + zhHans: 'Chino', + zhHant: 'Chino Tradicional', + enUS: 'Inglés', + deDE: 'Alemán', + frFR: 'Francés', + esES: 'Español', + itIT: 'Italiano', + thTH: 'Tailandés', + idID: 'Indonesio', + jaJP: 'Japonés', + koKR: 'Coreano', + ptBR: 'Portugués', + ruRU: 'Ruso', + ukUA: 'Ucraniano', + viVN: 'Vietnamita', + plPL: 'Polaco', + }, + }, + unit: { + char: 'caracteres', + }, + actionMsg: { + noModification: 'No hay modificaciones en este momento.', + modifiedSuccessfully: 'Modificado exitosamente', + modifiedUnsuccessfully: 'Modificación no exitosa', + copySuccessfully: 'Copiado exitosamente', + paySucceeded: 'Pago exitoso', + payCancelled: 'Pago cancelado', + generatedSuccessfully: 'Generado exitosamente', + generatedUnsuccessfully: 'Generación no exitosa', + }, + model: { + params: { + temperature: 'Temperatura', + temperatureTip: + 'Controla la aleatoriedad: Reducir resulta en completaciones menos aleatorias. A medida que la temperatura se acerca a cero, el modelo se vuelve determinista y repetitivo.', + top_p: 'Top P', + top_pTip: + 'Controla la diversidad mediante el muestreo de núcleo: 0.5 significa que se consideran la mitad de todas las opciones ponderadas por probabilidad.', + presence_penalty: 'Penalización por presencia', + presence_penaltyTip: + 'Cuánto penalizar los nuevos tokens según si aparecen en el texto hasta ahora.\nAumenta la probabilidad del modelo de hablar sobre nuevos temas.', + frequency_penalty: 'Penalización por frecuencia', + frequency_penaltyTip: + 'Cuánto penalizar los nuevos tokens según su frecuencia existente en el texto hasta ahora.\nDisminuye la probabilidad del modelo de repetir la misma línea literalmente.', + max_tokens: 'Tokens máximos', + max_tokensTip: + 'Se usa para limitar la longitud máxima de la respuesta, en tokens. \nValores más grandes pueden limitar el espacio disponible para palabras de indicación, registros de chat y Conocimiento. \nSe recomienda configurarlo por debajo de dos tercios\ngpt-4-1106-preview, gpt-4-vision-preview tokens máximos (entrada 128k salida 4k)', + maxTokenSettingTip: 'Tu configuración de tokens máximos es alta, lo que puede limitar el espacio para indicaciones, consultas y datos. Considera configurarlo por debajo de 2/3.', + setToCurrentModelMaxTokenTip: 'Tokens máximos actualizados al 80% del máximo de tokens del modelo actual {{maxToken}}.', + stop_sequences: 'Secuencias de parada', + stop_sequencesTip: 'Hasta cuatro secuencias donde la API dejará de generar más tokens. El texto devuelto no contendrá la secuencia de parada.', + stop_sequencesPlaceholder: 'Ingresa la secuencia y presiona Tab', + }, + tone: { + Creative: 'Creativo', + Balanced: 'Equilibrado', + Precise: 'Preciso', + Custom: 'Personalizado', + }, + addMoreModel: 'Ir a configuraciones para agregar más modelos', + }, + menus: { + status: 'beta', + explore: 'Explorar', + apps: 'Estudio', + plugins: 'Plugins', + pluginsTips: 'Integrar plugins de terceros o crear Plugins AI compatibles con ChatGPT.', + datasets: 'Conocimiento', + datasetsTips: 'PRÓXIMAMENTE: Importa tus propios datos de texto o escribe datos en tiempo real a través de Webhook para la mejora del contexto LLM.', + newApp: 'Nueva App', + newDataset: 'Crear Conocimiento', + tools: 'Herramientas', + }, + userProfile: { + settings: 'Configuraciones', + workspace: 'Espacio de trabajo', + createWorkspace: 'Crear espacio de trabajo', + helpCenter: 'Ayuda', + roadmapAndFeedback: 'Comentarios', + community: 'Comunidad', + about: 'Acerca de', + logout: 'Cerrar sesión', + }, + settings: { + accountGroup: 'CUENTA', + workplaceGroup: 'ESPACIO DE TRABAJO', + account: 'Mi cuenta', + members: 'Miembros', + billing: 'Facturación', + integrations: 'Integraciones', + language: 'Idioma', + provider: 'Proveedor de Modelo', + dataSource: 'Fuente de Datos', + plugin: 'Plugins', + apiBasedExtension: 'Extensión basada en API', + }, + account: { + avatar: 'Avatar', + name: 'Nombre', + email: 'Correo electrónico', + password: 'Contraseña', + passwordTip: 'Puedes establecer una contraseña permanente si no deseas usar códigos de inicio de sesión temporales', + setPassword: 'Establecer una contraseña', + resetPassword: 'Restablecer contraseña', + currentPassword: 'Contraseña actual', + newPassword: 'Nueva contraseña', + confirmPassword: 'Confirmar contraseña', + notEqual: 'Las dos contraseñas son diferentes.', + langGeniusAccount: 'Cuenta Dify', + langGeniusAccountTip: 'Tu cuenta Dify y los datos de usuario asociados.', + editName: 'Editar Nombre', + showAppLength: 'Mostrar {{length}} apps', + delete: 'Eliminar cuenta', + deleteTip: 'Eliminar tu cuenta borrará permanentemente todos tus datos y no se podrán recuperar.', + deleteConfirmTip: 'Para confirmar, por favor envía lo siguiente desde tu correo electrónico registrado a ', + }, + members: { + team: 'Equipo', + invite: 'Agregar', + name: 'NOMBRE', + lastActive: 'ÚLTIMA ACTIVIDAD', + role: 'ROLES', + pending: 'Pendiente...', + owner: 'Propietario', + admin: 'Administrador', + adminTip: 'Puede crear aplicaciones y administrar configuraciones del equipo', + normal: 'Normal', + normalTip: 'Solo puede usar aplicaciones, no puede crear aplicaciones', + builder: 'Constructor', + builderTip: 'Puede crear y editar sus propias aplicaciones', + editor: 'Editor', + editorTip: 'Puede crear y editar aplicaciones', + datasetOperator: 'Administrador de Conocimiento', + datasetOperatorTip: 'Solo puede administrar la base de conocimiento', + inviteTeamMember: 'Agregar miembro del equipo', + inviteTeamMemberTip: 'Pueden acceder a tus datos del equipo directamente después de iniciar sesión.', + email: 'Correo electrónico', + emailInvalid: 'Formato de correo electrónico inválido', + emailPlaceholder: 'Por favor ingresa correos electrónicos', + sendInvite: 'Enviar invitación', + invitedAsRole: 'Invitado como usuario {{role}}', + invitationSent: 'Invitación enviada', + invitationSentTip: 'Invitación enviada, y pueden iniciar sesión en Dify para acceder a tus datos del equipo.', + invitationLink: 'Enlace de invitación', + failedinvitationEmails: 'Los siguientes usuarios no fueron invitados exitosamente', + ok: 'OK', + removeFromTeam: 'Eliminar del equipo', + removeFromTeamTip: 'Se eliminará el acceso al equipo', + setAdmin: 'Establecer como administrador', + setMember: 'Establecer como miembro ordinario', + setBuilder: 'Establecer como constructor', + setEditor: 'Establecer como editor', + disinvite: 'Cancelar la invitación', + deleteMember: 'Eliminar miembro', + you: '(Tú)', + }, + integrations: { + connected: 'Conectado', + google: 'Google', + googleAccount: 'Iniciar sesión con cuenta de Google', + github: 'GitHub', + githubAccount: 'Iniciar sesión con cuenta de GitHub', + connect: 'Conectar', + }, + language: { + displayLanguage: 'Idioma de visualización', + timezone: 'Zona horaria', + }, + provider: { + apiKey: 'Clave API', + enterYourKey: 'Ingresa tu clave API aquí', + invalidKey: 'Clave API de OpenAI inválida', + validatedError: 'Validación fallida: ', + validating: 'Validando clave...', + saveFailed: 'Error al guardar la clave API', + apiKeyExceedBill: 'Esta CLAVE API no tiene cuota disponible, por favor lee', + addKey: 'Agregar Clave', + comingSoon: 'Próximamente', + editKey: 'Editar', + invalidApiKey: 'Clave API inválida', + azure: { + apiBase: 'Base API', + apiBasePlaceholder: 'La URL base de la API de tu Endpoint de Azure OpenAI.', + apiKey: 'Clave API', + apiKeyPlaceholder: 'Ingresa tu clave API aquí', + helpTip: 'Aprender sobre el Servicio Azure OpenAI', + }, + openaiHosted: { + openaiHosted: 'OpenAI Hospedado', + onTrial: 'EN PRUEBA', + exhausted: 'CUOTA AGOTADA', + desc: 'El servicio de hospedaje OpenAI proporcionado por Dify te permite usar modelos como GPT-3.5. Antes de que se agote tu cuota de prueba, necesitas configurar otros proveedores de modelos.', + callTimes: 'Tiempos de llamada', + usedUp: 'Cuota de prueba agotada. Agrega tu propio proveedor de modelos.', + useYourModel: 'Actualmente usando tu propio proveedor de modelos.', + close: 'Cerrar', + }, + anthropicHosted: { + anthropicHosted: 'Claude de Anthropíc', + onTrial: 'EN PRUEBA', + exhausted: 'CUOTA AGOTADA', + desc: 'Modelo poderoso, que se destaca en una amplia gama de tareas, desde diálogos sofisticados y generación de contenido creativo hasta instrucciones detalladas.', + callTimes: 'Tiempos de llamada', + usedUp: 'Cuota de prueba agotada. Agrega tu propio proveedor de modelos.', + useYourModel: 'Actualmente usando tu propio proveedor de modelos.', + close: 'Cerrar', + }, + anthropic: { + using: 'La capacidad de incrustación está usando', + enableTip: 'Para habilitar el modelo de Anthropíc, primero necesitas vincularte al Servicio OpenAI o Azure OpenAI.', + notEnabled: 'No habilitado', + keyFrom: 'Obtén tu clave API de Anthropíc', + }, + encrypted: { + front: 'Tu CLAVE API será encriptada y almacenada usando', + back: ' tecnología.', + }, + }, + modelProvider: { + notConfigured: 'El modelo del sistema aún no ha sido completamente configurado, y algunas funciones pueden no estar disponibles.', + systemModelSettings: 'Configuraciones del Modelo del Sistema', + systemModelSettingsLink: '¿Por qué es necesario configurar un modelo del sistema?', + selectModel: 'Selecciona tu modelo', + setupModelFirst: 'Por favor configura tu modelo primero', + systemReasoningModel: { + key: 'Modelo de Razonamiento del Sistema', + tip: 'Establece el modelo de inferencia predeterminado para ser usado en la creación de aplicaciones, así como características como la generación de nombres de diálogo y sugerencias de la próxima pregunta también usarán el modelo de inferencia predeterminado.', + }, + embeddingModel: { + key: 'Modelo de Incrustación', + tip: 'Establece el modelo predeterminado para el procesamiento de incrustación de documentos del Conocimiento, tanto la recuperación como la importación del Conocimiento utilizan este modelo de Incrustación para el procesamiento de vectorización. Cambiarlo causará que la dimensión del vector entre el Conocimiento importado y la pregunta sea inconsistente, resultando en fallos en la recuperación. Para evitar fallos en la recuperación, por favor no cambies este modelo a voluntad.', + required: 'El Modelo de Incrustación es requerido', + }, + speechToTextModel: { + key: 'Modelo de Voz a Texto', + tip: 'Establece el modelo predeterminado para la entrada de voz a texto en la conversación.', + }, + ttsModel: { + key: 'Modelo de Texto a Voz', + tip: 'Establece el modelo predeterminado para la entrada de texto a voz en la conversación.', + }, + rerankModel: { + key: 'Modelo de Reordenar', + tip: 'El modelo de reordenar reordenará la lista de documentos candidatos basada en la coincidencia semántica con la consulta del usuario, mejorando los resultados de clasificación semántica', + }, + apiKey: 'CLAVE API', + quota: 'Cuota', + searchModel: 'Modelo de búsqueda', + noModelFound: 'No se encontró modelo para {{model}}', + models: 'Modelos', + showMoreModelProvider: 'Mostrar más proveedores de modelos', + selector: { + tip: 'Este modelo ha sido eliminado. Por favor agrega un modelo o selecciona otro modelo.', + emptyTip: 'No hay modelos disponibles', + emptySetting: 'Por favor ve a configuraciones para configurar', + rerankTip: 'Por favor configura el modelo de Reordenar', + }, + card: { + quota: 'CUOTA', + onTrial: 'En prueba', + paid: 'Pagado', + quotaExhausted: 'Cuota agotada', + callTimes: 'Tiempos de llamada', + tokens: 'Tokens', + buyQuota: 'Comprar Cuota', + priorityUse: 'Uso prioritario', + removeKey: 'Eliminar CLAVE API', + tip: 'Se dará prioridad al uso de la cuota pagada. La cuota de prueba se utilizará después de que se agote la cuota pagada.', + }, + item: { + deleteDesc: '{{modelName}} se está utilizando como modelo de razonamiento del sistema. Algunas funciones no estarán disponibles después de la eliminación. Por favor confirma.', + freeQuota: 'CUOTA GRATUITA', + }, + addApiKey: 'Agrega tu CLAVE API', + invalidApiKey: 'Clave API inválida', + encrypted: { + front: 'Tu CLAVE API será encriptada y almacenada usando', + back: ' tecnología.', + }, + freeQuota: { + howToEarn: 'Cómo ganar', + }, + addMoreModelProvider: 'AGREGAR MÁS PROVEEDORES DE MODELOS', + addModel: 'Agregar Modelo', + modelsNum: '{{num}} Modelos', + showModels: 'Mostrar Modelos', + showModelsNum: 'Mostrar {{num}} Modelos', + collapse: 'Colapsar', + config: 'Configurar', + modelAndParameters: 'Modelo y Parámetros', + model: 'Modelo', + featureSupported: '{{feature}} soportado', + callTimes: 'Tiempos de llamada', + credits: 'Créditos de Mensaje', + buyQuota: 'Comprar Cuota', + getFreeTokens: 'Obtener Tokens gratis', + priorityUsing: 'Uso prioritario', + deprecated: 'Desaprobado', + confirmDelete: '¿Confirmar eliminación?', + quotaTip: 'Tokens gratuitos restantes disponibles', + loadPresets: 'Cargar Presets', + parameters: 'PARÁMETROS', + loadBalancing: 'Balanceo de carga', + loadBalancingDescription: 'Reduce la presión con múltiples conjuntos de credenciales.', + loadBalancingHeadline: 'Balanceo de Carga', + configLoadBalancing: 'Configurar Balanceo de Carga', + modelHasBeenDeprecated: 'Este modelo ha sido desaprobado', + providerManaged: 'Gestionado por el proveedor', + providerManagedDescription: 'Usa el único conjunto de credenciales proporcionado por el proveedor del modelo.', + defaultConfig: 'Configuración Predeterminada', + apiKeyStatusNormal: 'El estado de la CLAVE API es normal', + apiKeyRateLimit: 'Se alcanzó el límite de velocidad, disponible después de {{seconds}}s', + addConfig: 'Agregar Configuración', + editConfig: 'Editar Configuración', + loadBalancingLeastKeyWarning: 'Para habilitar el balanceo de carga se deben habilitar al menos 2 claves.', + loadBalancingInfo: 'Por defecto, el balanceo de carga usa la estrategia Round-robin. Si se activa el límite de velocidad, se aplicará un período de enfriamiento de 1 minuto.', + upgradeForLoadBalancing: 'Actualiza tu plan para habilitar el Balanceo de Carga.', + }, + dataSource: { + add: 'Agregar una fuente de datos', + connect: 'Conectar', + configure: 'Configurar', + notion: { + title: 'Notion', + description: 'Usando Notion como fuente de datos para el Conocimiento.', + connectedWorkspace: 'Espacio de trabajo conectado', + addWorkspace: 'Agregar espacio de trabajo', + connected: 'Conectado', + disconnected: 'Desconectado', + changeAuthorizedPages: 'Cambiar páginas autorizadas', + pagesAuthorized: 'Páginas autorizadas', + sync: 'Sincronizar', + remove: 'Eliminar', + selector: { + pageSelected: 'Páginas seleccionadas', + searchPages: 'Buscar páginas...', + noSearchResult: 'No hay resultados de búsqueda', + addPages: 'Agregar páginas', + preview: 'VISTA PREVIA', + }, + }, + website: { + title: 'Sitio web', + description: 'Importar contenido de sitios web usando un rastreador web.', + with: 'Con', + configuredCrawlers: 'Rastreadores configurados', + active: 'Activo', + inactive: 'Inactivo', + }, + }, + plugin: { + serpapi: { + apiKey: 'Clave API', + apiKeyPlaceholder: 'Ingresa tu clave API', + keyFrom: 'Obtén tu clave API de SerpAPI en la página de cuenta de SerpAPI', + }, + }, + apiBasedExtension: { + title: 'Las extensiones basadas en API proporcionan una gestión centralizada de API, simplificando la configuración para su fácil uso en las aplicaciones de Dify.', + link: 'Aprende cómo desarrollar tu propia Extensión API.', + linkUrl: 'https://docs.dify.ai/features/extension/api_based_extension', + add: 'Agregar Extensión API', + selector: { + title: 'Extensión API', + placeholder: 'Por favor selecciona extensión API', + manage: 'Gestionar Extensión API', + }, + modal: { + title: 'Agregar Extensión API', + editTitle: 'Editar Extensión API', + name: { + title: 'Nombre', + placeholder: 'Por favor ingresa el nombre', + }, + apiEndpoint: { + title: 'Punto final de la API', + placeholder: 'Por favor ingresa el punto final de la API', + }, + apiKey: { + title: 'Clave API', + placeholder: 'Por favor ingresa la clave API', + lengthError: 'La longitud de la clave API no puede ser menor a 5 caracteres', + }, + }, + type: 'Tipo', + }, + about: { + changeLog: 'Registro de cambios', + updateNow: 'Actualizar ahora', + nowAvailable: 'Dify {{version}} ya está disponible.', + latestAvailable: 'Dify {{version}} es la última versión disponible.', + }, + appMenus: { + overview: 'Monitoreo', + promptEng: 'Orquestar', + apiAccess: 'Acceso API', + logAndAnn: 'Registros y Anuncios', + logs: 'Registros', + }, + environment: { + testing: 'PRUEBAS', + development: 'DESARROLLO', + }, + appModes: { + completionApp: 'Generador de Texto', + chatApp: 'Aplicación de Chat', + }, + datasetMenus: { + documents: 'Documentos', + hitTesting: 'Pruebas de Recuperación', + settings: 'Configuraciones', + emptyTip: 'El Conocimiento no ha sido asociado, por favor ve a la aplicación o plugin para completar la asociación.', + viewDoc: 'Ver documentación', + relatedApp: 'aplicaciones vinculadas', + }, + voiceInput: { + speaking: 'Habla ahora...', + converting: 'Convirtiendo a texto...', + notAllow: 'micrófono no autorizado', + }, + modelName: { + 'gpt-3.5-turbo': 'GPT-3.5-Turbo', + 'gpt-3.5-turbo-16k': 'GPT-3.5-Turbo-16K', + 'gpt-4': 'GPT-4', + 'gpt-4-32k': 'GPT-4-32K', + 'text-davinci-003': 'Text-Davinci-003', + 'text-embedding-ada-002': 'Text-Embedding-Ada-002', + 'whisper-1': 'Whisper-1', + 'claude-instant-1': 'Claude-Instant', + 'claude-2': 'Claude-2', + }, + chat: { + renameConversation: 'Renombrar Conversación', + conversationName: 'Nombre de la conversación', + conversationNamePlaceholder: 'Por favor ingresa el nombre de la conversación', + conversationNameCanNotEmpty: 'Nombre de la conversación requerido', + citation: { + title: 'CITAS', + linkToDataset: 'Enlace al Conocimiento', + characters: 'Caracteres:', + hitCount: 'Conteo de recuperaciones:', + vectorHash: 'Hash de vector:', + hitScore: 'Puntuación de recuperación:', + }, + }, + promptEditor: { + placeholder: 'Escribe tu palabra de indicación aquí, ingresa \'{\' para insertar una variable, ingresa \'/\' para insertar un bloque de contenido de indicación', + context: { + item: { + title: 'Contexto', + desc: 'Insertar plantilla de contexto', + }, + modal: { + title: '{{num}} Conocimiento en Contexto', + add: 'Agregar Contexto ', + footer: 'Puedes gestionar contextos en la sección de Contexto abajo.', + }, + }, + history: { + item: { + title: 'Historial de Conversación', + desc: 'Insertar plantilla de mensaje histórico', + }, + modal: { + title: 'EJEMPLO', + user: 'Hola', + assistant: '¡Hola! ¿Cómo puedo asistirte hoy?', + edit: 'Editar Nombres de Roles de Conversación', + }, + }, + variable: { + item: { + title: 'Variables y Herramientas Externas', + desc: 'Insertar Variables y Herramientas Externas', + }, + outputToolDisabledItem: { + title: 'Variables', + desc: 'Insertar Variables', + }, + modal: { + add: 'Nueva variable', + addTool: 'Nueva herramienta', + }, + }, + query: { + item: { + title: 'Consulta', + desc: 'Insertar plantilla de consulta del usuario', + }, + }, + existed: 'Ya existe en la indicación', + }, + imageUploader: { + uploadFromComputer: 'Cargar desde la Computadora', + uploadFromComputerReadError: 'Lectura de imagen fallida, por favor intenta nuevamente.', + uploadFromComputerUploadError: 'Carga de imagen fallida, por favor carga nuevamente.', + uploadFromComputerLimit: 'Las imágenes cargadas no pueden exceder {{size}} MB', + pasteImageLink: 'Pegar enlace de imagen', + pasteImageLinkInputPlaceholder: 'Pega el enlace de imagen aquí', + pasteImageLinkInvalid: 'Enlace de imagen inválido', + imageUpload: 'Carga de Imagen', + }, + tag: { + placeholder: 'Todas las Etiquetas', + addNew: 'Agregar nueva etiqueta', + noTag: 'Sin etiquetas', + noTagYet: 'Aún sin etiquetas', + addTag: 'Agregar etiquetas', + editTag: 'Editar etiquetas', + manageTags: 'Gestionar Etiquetas', + selectorPlaceholder: 'Escribe para buscar o crear', + create: 'Crear', + delete: 'Eliminar etiqueta', + deleteTip: 'La etiqueta se está utilizando, ¿eliminarla?', + created: 'Etiqueta creada exitosamente', + failed: 'Creación de etiqueta fallida', + }, +} + +export default translation diff --git a/web/i18n/es-ES/custom.ts b/web/i18n/es-ES/custom.ts new file mode 100644 index 00000000000000..0dd65125891352 --- /dev/null +++ b/web/i18n/es-ES/custom.ts @@ -0,0 +1,30 @@ +const translation = { + custom: 'Personalización', + upgradeTip: { + prefix: 'Actualiza tu plan para', + suffix: 'personalizar tu marca.', + }, + webapp: { + title: 'Personalizar marca de WebApp', + removeBrand: 'Eliminar Powered by Dify', + changeLogo: 'Cambiar Imagen de Marca Powered by', + changeLogoTip: 'Formato SVG o PNG con un tamaño mínimo de 40x40px', + }, + app: { + title: 'Personalizar encabezado de la aplicación', + changeLogoTip: 'Formato SVG o PNG con un tamaño mínimo de 80x80px', + }, + upload: 'Subir', + uploading: 'Subiendo', + uploadedFail: 'Error al subir la imagen, por favor vuelve a intentar.', + change: 'Cambiar', + apply: 'Aplicar', + restore: 'Restaurar valores predeterminados', + customize: { + contactUs: ' contáctanos ', + prefix: 'Para personalizar el logotipo de la marca dentro de la aplicación, por favor', + suffix: 'para actualizar a la edición Enterprise.', + }, +} + +export default translation diff --git a/web/i18n/es-ES/dataset-creation.ts b/web/i18n/es-ES/dataset-creation.ts new file mode 100644 index 00000000000000..f8ef14f89b1730 --- /dev/null +++ b/web/i18n/es-ES/dataset-creation.ts @@ -0,0 +1,161 @@ +const translation = { + steps: { + header: { + creation: 'Crear conocimiento', + update: 'Agregar datos', + }, + one: 'Elegir fuente de datos', + two: 'Preprocesamiento y limpieza de texto', + three: 'Ejecutar y finalizar', + }, + error: { + unavailable: 'Este conocimiento no está disponible', + }, + firecrawl: { + configFirecrawl: 'Configurar 🔥Firecrawl', + apiKeyPlaceholder: 'Clave de API de firecrawl.dev', + getApiKeyLinkText: 'Obtener tu clave de API de firecrawl.dev', + }, + stepOne: { + filePreview: 'Vista previa del archivo', + pagePreview: 'Vista previa de la página', + dataSourceType: { + file: 'Importar desde archivo', + notion: 'Sincronizar desde Notion', + web: 'Sincronizar desde sitio web', + }, + uploader: { + title: 'Cargar archivo', + button: 'Arrastra y suelta el archivo, o', + browse: 'Buscar', + tip: 'Soporta {{supportTypes}}. Máximo {{size}}MB cada uno.', + validation: { + typeError: 'Tipo de archivo no soportado', + size: 'Archivo demasiado grande. El máximo es {{size}}MB', + count: 'No se admiten varios archivos', + filesNumber: 'Has alcanzado el límite de carga por lotes de {{filesNumber}}.', + }, + cancel: 'Cancelar', + change: 'Cambiar', + failed: 'Error al cargar', + }, + notionSyncTitle: 'Notion no está conectado', + notionSyncTip: 'Para sincronizar con Notion, primero se debe establecer la conexión con Notion.', + connect: 'Ir a conectar', + button: 'Siguiente', + emptyDatasetCreation: 'Quiero crear un conocimiento vacío', + modal: { + title: 'Crear un conocimiento vacío', + tip: 'Un conocimiento vacío no contendrá documentos y podrás cargar documentos en cualquier momento.', + input: 'Nombre del conocimiento', + placeholder: 'Por favor ingresa', + nameNotEmpty: 'El nombre no puede estar vacío', + nameLengthInvaild: 'El nombre debe tener entre 1 y 40 caracteres', + cancelButton: 'Cancelar', + confirmButton: 'Crear', + failed: 'Error al crear', + }, + website: { + fireCrawlNotConfigured: 'Firecrawl no está configurado', + fireCrawlNotConfiguredDescription: 'Configura Firecrawl con la clave de API para poder utilizarlo.', + configure: 'Configurar', + run: 'Ejecutar', + firecrawlTitle: 'Extraer contenido web con 🔥Firecrawl', + firecrawlDoc: 'Documentación de Firecrawl', + firecrawlDocLink: 'https://docs.dify.ai/guides/knowledge-base/sync_from_website', + options: 'Opciones', + crawlSubPage: 'Rastrear subpáginas', + limit: 'Límite', + maxDepth: 'Profundidad máxima', + excludePaths: 'Excluir rutas', + includeOnlyPaths: 'Incluir solo rutas', + extractOnlyMainContent: 'Extraer solo el contenido principal (sin encabezados, navegación, pies de página, etc.)', + exceptionErrorTitle: 'Se produjo una excepción al ejecutar el trabajo de Firecrawl:', + unknownError: 'Error desconocido', + totalPageScraped: 'Total de páginas extraídas:', + selectAll: 'Seleccionar todo', + resetAll: 'Restablecer todo', + scrapTimeInfo: 'Se extrajeron {{total}} páginas en total en {{time}}s', + preview: 'Vista previa', + maxDepthTooltip: 'Profundidad máxima para rastrear en relación con la URL ingresada. La profundidad 0 solo extrae la página de la URL ingresada, la profundidad 1 extrae la URL y todo lo después de la URL ingresada + una /, y así sucesivamente.', + }, + }, + stepTwo: { + segmentation: 'Configuración de fragmentos', + auto: 'Automático', + autoDescription: 'Configura automáticamente las reglas de fragmentación y preprocesamiento. Se recomienda seleccionar esto para usuarios no familiarizados.', + custom: 'Personalizado', + customDescription: 'Personaliza las reglas de fragmentación, longitud de fragmentos y reglas de preprocesamiento, etc.', + separator: 'Identificador de segmento', + separatorPlaceholder: 'Por ejemplo, salto de línea (\\\\n) o separador especial (como "***")', + maxLength: 'Longitud máxima del fragmento', + overlap: 'Superposición de fragmentos', + overlapTip: 'Configurar la superposición de fragmentos puede mantener la relevancia semántica entre ellos, mejorando el efecto de recuperación. Se recomienda configurar el 10%-25% del tamaño máximo del fragmento.', + overlapCheck: 'La superposición de fragmentos no debe ser mayor que la longitud máxima del fragmento', + rules: 'Reglas de preprocesamiento de texto', + removeExtraSpaces: 'Reemplazar espacios, saltos de línea y tabulaciones consecutivas', + removeUrlEmails: 'Eliminar todas las URL y direcciones de correo electrónico', + removeStopwords: 'Eliminar palabras vacías como "un", "una", "el"', + preview: 'Confirmar y vista previa', + reset: 'Restablecer', + indexMode: 'Modo de índice', + qualified: 'Alta calidad', + recommend: 'Recomendado', + qualifiedTip: 'Llama a la interfaz de incrustación del sistema por defecto para proporcionar una mayor precisión cuando los usuarios realizan consultas.', + warning: 'Por favor, configura primero la clave de API del proveedor del modelo.', + click: 'Ir a configuración', + economical: 'Económico', + economicalTip: 'Utiliza motores de vector sin conexión, índices de palabras clave, etc. para reducir la precisión sin gastar tokens', + QATitle: 'Segmentación en formato de pregunta y respuesta', + QATip: 'Habilitar esta opción consumirá más tokens', + QALanguage: 'Segmentar usando', + emstimateCost: 'Estimación', + emstimateSegment: 'Fragmentos estimados', + segmentCount: 'fragmentos', + calculating: 'Calculando...', + fileSource: 'Preprocesar documentos', + notionSource: 'Preprocesar páginas', + websiteSource: 'Preprocesar sitio web', + other: 'y otros ', + fileUnit: ' archivos', + notionUnit: ' páginas', + webpageUnit: ' páginas', + previousStep: 'Paso anterior', + nextStep: 'Guardar y procesar', + save: 'Guardar y procesar', + cancel: 'Cancelar', + sideTipTitle: '¿Por qué fragmentar y preprocesar?', + sideTipP1: 'Al procesar datos de texto, la fragmentación y la limpieza son dos pasos de preprocesamiento importantes.', + sideTipP2: 'La segmentación divide el texto largo en párrafos para que los modelos puedan entenderlo mejor. Esto mejora la calidad y relevancia de los resultados del modelo.', + sideTipP3: 'La limpieza elimina caracteres y formatos innecesarios, haciendo que el conocimiento sea más limpio y fácil de analizar.', + sideTipP4: 'Una fragmentación y limpieza adecuadas mejoran el rendimiento del modelo, proporcionando resultados más precisos y valiosos.', + previewTitle: 'Vista previa', + previewTitleButton: 'Vista previa', + previewButton: 'Cambiar a formato de pregunta y respuesta', + previewSwitchTipStart: 'La vista previa actual del fragmento está en formato de texto, cambiar a una vista previa en formato de pregunta y respuesta', + previewSwitchTipEnd: ' consumirá tokens adicionales', + characters: 'caracteres', + indexSettedTip: 'Para cambiar el método de índice, por favor ve a la ', + retrivalSettedTip: 'Para cambiar el método de índice, por favor ve a la ', + datasetSettingLink: 'configuración del conocimiento.', + }, + stepThree: { + creationTitle: '🎉 Conocimiento creado', + creationContent: 'Hemos asignado automáticamente un nombre al conocimiento, puedes modificarlo en cualquier momento', + label: 'Nombre del conocimiento', + additionTitle: '🎉 Documento cargado', + additionP1: 'El documento se ha cargado en el conocimiento', + additionP2: ', puedes encontrarlo en la lista de documentos del conocimiento.', + stop: 'Detener procesamiento', + resume: 'Reanudar procesamiento', + navTo: 'Ir al documento', + sideTipTitle: '¿Qué sigue?', + sideTipContent: 'Después de que el documento termine de indexarse, el conocimiento se puede integrar en la aplicación como contexto. Puedes encontrar la configuración de contexto en la página de orquestación de indicaciones. También puedes crearlo como un plugin de indexación ChatGPT independiente para su lanzamiento.', + modelTitle: '¿Estás seguro de detener la incrustación?', + modelContent: 'Si necesitas reanudar el procesamiento más tarde, continuarás desde donde lo dejaste.', + modelButtonConfirm: 'Confirmar', + modelButtonCancel: 'Cancelar', + }, +} + +export default translation diff --git a/web/i18n/es-ES/dataset-documents.ts b/web/i18n/es-ES/dataset-documents.ts new file mode 100644 index 00000000000000..6a5191ce536db2 --- /dev/null +++ b/web/i18n/es-ES/dataset-documents.ts @@ -0,0 +1,352 @@ +const translation = { + list: { + title: 'Documentos', + desc: 'Aquí se muestran todos los archivos del Conocimiento, y todo el Conocimiento se puede vincular a citas de Dify o indexarse a través del complemento de Chat.', + addFile: 'Agregar archivo', + addPages: 'Agregar páginas', + addUrl: 'Agregar URL', + table: { + header: { + fileName: 'NOMBRE DEL ARCHIVO', + words: 'PALABRAS', + hitCount: 'CANTIDAD DE RECUPERACIÓN', + uploadTime: 'TIEMPO DE CARGA', + status: 'ESTADO', + action: 'ACCIÓN', + }, + rename: 'Renombrar', + name: 'Nombre', + }, + action: { + uploadFile: 'Subir nuevo archivo', + settings: 'Configuración de segmento', + addButton: 'Agregar fragmento', + add: 'Agregar un fragmento', + batchAdd: 'Agregar en lotes', + archive: 'Archivar', + unarchive: 'Desarchivar', + delete: 'Eliminar', + enableWarning: 'El archivo archivado no puede habilitarse', + sync: 'Sincronizar', + }, + index: { + enable: 'Habilitar', + disable: 'Deshabilitar', + all: 'Todos', + enableTip: 'El archivo se puede indexar', + disableTip: 'El archivo no se puede indexar', + }, + status: { + queuing: 'En cola', + indexing: 'Indexando', + paused: 'Pausado', + error: 'Error', + available: 'Disponible', + enabled: 'Habilitado', + disabled: 'Deshabilitado', + archived: 'Archivado', + }, + empty: { + title: 'Aún no hay documentación', + upload: { + tip: 'Puedes subir archivos, sincronizar desde el sitio web o desde aplicaciones web como Notion, GitHub, etc.', + }, + sync: { + tip: 'Dify descargará periódicamente archivos desde tu Notion y completará el procesamiento.', + }, + }, + delete: { + title: '¿Seguro que deseas eliminar?', + content: 'Si necesitas reanudar el procesamiento más tarde, continuarás desde donde lo dejaste.', + }, + batchModal: { + title: 'Agregar fragmentos en lotes', + csvUploadTitle: 'Arrastra y suelta tu archivo CSV aquí, o ', + browse: 'navega', + tip: 'El archivo CSV debe cumplir con la siguiente estructura:', + question: 'pregunta', + answer: 'respuesta', + contentTitle: 'contenido del fragmento', + content: 'contenido', + template: 'Descarga la plantilla aquí', + cancel: 'Cancelar', + run: 'Ejecutar en lotes', + runError: 'Error al ejecutar en lotes', + processing: 'Procesamiento en lotes', + completed: 'Importación completada', + error: 'Error de importación', + ok: 'Aceptar', + }, + }, + metadata: { + title: 'Metadatos', + desc: 'Etiquetar metadatos para documentos permite que la IA acceda a ellos de manera oportuna y expone la fuente de referencias para los usuarios.', + dateTimeFormat: 'MMMM D, YYYY hh:mm A', + docTypeSelectTitle: 'Por favor, selecciona un tipo de documento', + docTypeChangeTitle: 'Cambiar tipo de documento', + docTypeSelectWarning: + 'Si se cambia el tipo de documento, los metadatos ahora llenos ya no se conservarán.', + firstMetaAction: 'Vamos D', + placeholder: { + add: 'Agregar ', + select: 'Seleccionar ', + }, + source: { + upload_file: 'Subir archivo', + notion: 'Sincronizar desde Notion', + github: 'Sincronizar desde GitHub', + }, + type: { + book: 'Libro', + webPage: 'Página Web', + paper: 'Artículo', + socialMediaPost: 'Publicación en Redes Sociales', + personalDocument: 'Documento Personal', + businessDocument: 'Documento de Negocios', + IMChat: 'Chat IM', + wikipediaEntry: 'Entrada de Wikipedia', + notion: 'Sincronizar desde Notion', + github: 'Sincronizar desde GitHub', + technicalParameters: 'Parámetros Técnicos', + }, + field: { + processRule: { + processDoc: 'Procesar documento', + segmentRule: 'Regla de segmentación', + segmentLength: 'Longitud de fragmentos', + processClean: 'Limpieza de texto procesado', + }, + book: { + title: 'Título', + language: 'Idioma', + author: 'Autor', + publisher: 'Editorial', + publicationDate: 'Fecha de publicación', + ISBN: 'ISBN', + category: 'Categoría', + }, + webPage: { + title: 'Título', + url: 'URL', + language: 'Idioma', + authorPublisher: 'Autor/Editorial', + publishDate: 'Fecha de publicación', + topicsKeywords: 'Temas/Palabras clave', + description: 'Descripción', + }, + paper: { + title: 'Título', + language: 'Idioma', + author: 'Autor', + publishDate: 'Fecha de publicación', + journalConferenceName: 'Nombre de la revista/conferencia', + volumeIssuePage: 'Volumen/Número/Página', + DOI: 'DOI', + topicsKeywords: 'Temas/Palabras clave', + abstract: 'Resumen', + }, + socialMediaPost: { + platform: 'Plataforma', + authorUsername: 'Autor/Nombre de usuario', + publishDate: 'Fecha de publicación', + postURL: 'URL de la publicación', + topicsTags: 'Temas/Etiquetas', + }, + personalDocument: { + title: 'Título', + author: 'Autor', + creationDate: 'Fecha de creación', + lastModifiedDate: 'Última fecha de modificación', + documentType: 'Tipo de documento', + tagsCategory: 'Etiquetas/Categoría', + }, + businessDocument: { + title: 'Título', + author: 'Autor', + creationDate: 'Fecha de creación', + lastModifiedDate: 'Última fecha de modificación', + documentType: 'Tipo de documento', + departmentTeam: 'Departamento/Equipo', + }, + IMChat: { + chatPlatform: 'Plataforma de chat', + chatPartiesGroupName: 'Partes de chat/Nombre del grupo', + participants: 'Participantes', + startDate: 'Fecha de inicio', + endDate: 'Fecha de fin', + topicsKeywords: 'Temas/Palabras clave', + fileType: 'Tipo de archivo', + }, + wikipediaEntry: { + title: 'Título', + language: 'Idioma', + webpageURL: 'URL de la página web', + editorContributor: 'Editor/Contribuidor', + lastEditDate: 'Última fecha de edición', + summaryIntroduction: 'Resumen/Introducción', + }, + notion: { + title: 'Título', + language: 'Idioma', + author: 'Autor', + createdTime: 'Fecha de creación', + lastModifiedTime: 'Última fecha de modificación', + url: 'URL', + tag: 'Etiqueta', + description: 'Descripción', + }, + github: { + repoName: 'Nombre del repositorio', + repoDesc: 'Descripción del repositorio', + repoOwner: 'Propietario del repositorio', + fileName: 'Nombre del archivo', + filePath: 'Ruta del archivo', + programmingLang: 'Lenguaje de programación', + url: 'URL', + license: 'Licencia', + lastCommitTime: 'Última hora de compromiso', + lastCommitAuthor: 'Último autor del compromiso', + }, + originInfo: { + originalFilename: 'Nombre de archivo original', + originalFileSize: 'Tamaño de archivo original', + uploadDate: 'Fecha de carga', + lastUpdateDate: 'Última fecha de actualización', + source: 'Fuente', + }, + technicalParameters: { + segmentSpecification: 'Especificación de fragmentos', + segmentLength: 'Longitud de fragmentos', + avgParagraphLength: 'Longitud promedio del párrafo', + paragraphs: 'Párrafos', + hitCount: 'Cantidad de recuperación', + embeddingTime: 'Tiempo de incrustación', + embeddedSpend: 'Gasto incrustado', + }, + }, + languageMap: { + zh: 'Chino', + en: 'Inglés', + es: 'Español', + fr: 'Francés', + de: 'Alemán', + ja: 'Japonés', + ko: 'Coreano', + ru: 'Ruso', + ar: 'Árabe', + pt: 'Portugués', + it: 'Italiano', + nl: 'Holandés', + pl: 'Polaco', + sv: 'Sueco', + tr: 'Turco', + he: 'Hebreo', + hi: 'Hindi', + da: 'Danés', + fi: 'Finlandés', + no: 'Noruego', + hu: 'Húngaro', + el: 'Griego', + cs: 'Checo', + th: 'Tailandés', + id: 'Indonesio', + }, + categoryMap: { + book: { + fiction: 'Ficción', + biography: 'Biografía', + history: 'Historia', + science: 'Ciencia', + technology: 'Tecnología', + education: 'Educación', + philosophy: 'Filosofía', + religion: 'Religión', + socialSciences: 'Ciencias Sociales', + art: 'Arte', + travel: 'Viaje', + health: 'Salud', + selfHelp: 'Autoayuda', + businessEconomics: 'Negocios y Economía', + cooking: 'Cocina', + childrenYoungAdults: 'Niños y Jóvenes Adultos', + comicsGraphicNovels: 'Cómics y Novelas Gráficas', + poetry: 'Poesía', + drama: 'Drama', + other: 'Otros', + }, + personalDoc: { + notes: 'Notas', + blogDraft: 'Borrador de blog', + diary: 'Diario', + researchReport: 'Informe de investigación', + bookExcerpt: 'Extracto de libro', + schedule: 'Horario', + list: 'Lista', + projectOverview: 'Visión general del proyecto', + photoCollection: 'Colección de fotos', + creativeWriting: 'Escritura creativa', + codeSnippet: 'Fragmento de código', + designDraft: 'Borrador de diseño', + personalResume: 'Currículum personal', + other: 'Otros', + }, + businessDoc: { + meetingMinutes: 'Minutos de reunión', + researchReport: 'Informe de investigación', + proposal: 'Propuesta', + employeeHandbook: 'Manual del empleado', + trainingMaterials: 'Materiales de capacitación', + requirementsDocument: 'Documento de requisitos', + designDocument: 'Documento de diseño', + productSpecification: 'Especificación del producto', + financialReport: 'Informe financiero', + marketAnalysis: 'Análisis de mercado', + projectPlan: 'Plan de proyecto', + teamStructure: 'Estructura del equipo', + policiesProcedures: 'Políticas y procedimientos', + contractsAgreements: 'Contratos y acuerdos', + emailCorrespondence: 'Correspondencia por correo electrónico', + other: 'Otros', + }, + }, + }, + embedding: { + processing: 'Procesando incrustación...', + paused: 'Incrustación pausada', + completed: 'Incrustación completada', + error: 'Error de incrustación', + docName: 'Preprocesamiento del documento', + mode: 'Regla de segmentación', + segmentLength: 'Longitud de fragmentos', + textCleaning: 'Definición de texto y limpieza previa', + segments: 'Párrafos', + highQuality: 'Modo de alta calidad', + economy: 'Modo económico', + estimate: 'Consumo estimado', + stop: 'Detener procesamiento', + resume: 'Reanudar procesamiento', + automatic: 'Automático', + custom: 'Personalizado', + previewTip: 'La vista previa del párrafo estará disponible después de que se complete la incrustación', + }, + segment: { + paragraphs: 'Párrafos', + keywords: 'Palabras clave', + addKeyWord: 'Agregar palabra clave', + keywordError: 'La longitud máxima de la palabra clave es 20', + characters: 'caracteres', + hitCount: 'Cantidad de recuperación', + vectorHash: 'Hash de vector: ', + questionPlaceholder: 'agregar pregunta aquí', + questionEmpty: 'La pregunta no puede estar vacía', + answerPlaceholder: 'agregar respuesta aquí', + answerEmpty: 'La respuesta no puede estar vacía', + contentPlaceholder: 'agregar contenido aquí', + contentEmpty: 'El contenido no puede estar vacío', + newTextSegment: 'Nuevo segmento de texto', + newQaSegment: 'Nuevo segmento de preguntas y respuestas', + delete: '¿Eliminar este fragmento?', + }, +} + +export default translation diff --git a/web/i18n/es-ES/dataset-hit-testing.ts b/web/i18n/es-ES/dataset-hit-testing.ts new file mode 100644 index 00000000000000..4ebdd03b9d7e4c --- /dev/null +++ b/web/i18n/es-ES/dataset-hit-testing.ts @@ -0,0 +1,28 @@ +const translation = { + title: 'Prueba de recuperación', + desc: 'Prueba del efecto de impacto del conocimiento basado en el texto de consulta proporcionado.', + dateTimeFormat: 'MM/DD/YYYY hh:mm A', + recents: 'Recientes', + table: { + header: { + source: 'Fuente', + text: 'Texto', + time: 'Tiempo', + }, + }, + input: { + title: 'Texto fuente', + placeholder: 'Por favor ingrese un texto, se recomienda una oración declarativa corta.', + countWarning: 'Hasta 200 caracteres.', + indexWarning: 'Solo conocimiento de alta calidad.', + testing: 'Prueba', + }, + hit: { + title: 'PÁRRAFOS DE RECUPERACIÓN', + emptyTip: 'Los resultados de la prueba de recuperación se mostrarán aquí', + }, + noRecentTip: 'No hay resultados de consulta recientes aquí', + viewChart: 'Ver GRÁFICO VECTORIAL', +} + +export default translation diff --git a/web/i18n/es-ES/dataset-settings.ts b/web/i18n/es-ES/dataset-settings.ts new file mode 100644 index 00000000000000..984b3783769a89 --- /dev/null +++ b/web/i18n/es-ES/dataset-settings.ts @@ -0,0 +1,35 @@ +const translation = { + title: 'Configuración del conjunto de datos', + desc: 'Aquí puedes modificar las propiedades y los métodos de trabajo del conjunto de datos.', + form: { + name: 'Nombre del conjunto de datos', + namePlaceholder: 'Por favor ingresa el nombre del conjunto de datos', + nameError: 'El nombre no puede estar vacío', + desc: 'Descripción del conjunto de datos', + descInfo: 'Por favor escribe una descripción textual clara para delinear el contenido del conjunto de datos. Esta descripción se utilizará como base para la coincidencia al seleccionar entre múltiples conjuntos de datos para la inferencia.', + descPlaceholder: 'Describe lo que hay en este conjunto de datos. Una descripción detallada permite que la IA acceda al contenido del conjunto de datos de manera oportuna. Si está vacío, Dify utilizará la estrategia de coincidencia predeterminada.', + descWrite: 'Aprende cómo escribir una buena descripción del conjunto de datos.', + permissions: 'Permisos', + permissionsOnlyMe: 'Solo yo', + permissionsAllMember: 'Todos los miembros del equipo', + permissionsInvitedMembers: 'Miembros del equipo invitados', + me: '(Tú)', + indexMethod: 'Método de indexación', + indexMethodHighQuality: 'Alta calidad', + indexMethodHighQualityTip: 'Llama al modelo de incrustación para procesar y proporcionar una mayor precisión cuando los usuarios realizan consultas.', + indexMethodEconomy: 'Económico', + indexMethodEconomyTip: 'Utiliza motores de vectores sin conexión, índices de palabras clave, etc. para reducir la precisión sin gastar tokens.', + embeddingModel: 'Modelo de incrustación', + embeddingModelTip: 'Cambia el modelo de incrustación, por favor ve a ', + embeddingModelTipLink: 'Configuración', + retrievalSetting: { + title: 'Configuración de recuperación', + learnMore: 'Aprende más', + description: ' sobre el método de recuperación.', + longDescription: ' sobre el método de recuperación, puedes cambiar esto en cualquier momento en la configuración del conjunto de datos.', + }, + save: 'Guardar', + }, +} + +export default translation diff --git a/web/i18n/es-ES/dataset.ts b/web/i18n/es-ES/dataset.ts new file mode 100644 index 00000000000000..307187b60554f1 --- /dev/null +++ b/web/i18n/es-ES/dataset.ts @@ -0,0 +1,50 @@ +const translation = { + knowledge: 'Conocimiento', + documentCount: ' documentos', + wordCount: ' mil palabras', + appCount: ' aplicaciones vinculadas', + createDataset: 'Crear Conocimiento', + createDatasetIntro: 'Importa tus propios datos de texto o escribe datos en tiempo real a través de Webhook para mejorar el contexto de LLM.', + deleteDatasetConfirmTitle: '¿Eliminar este Conocimiento?', + deleteDatasetConfirmContent: + 'Eliminar el Conocimiento es irreversible. Los usuarios ya no podrán acceder a tu Conocimiento y todas las configuraciones y registros de las sugerencias se eliminarán permanentemente.', + datasetUsedByApp: 'El conocimiento está siendo utilizado por algunas aplicaciones. Las aplicaciones ya no podrán utilizar este Conocimiento y todas las configuraciones y registros de las sugerencias se eliminarán permanentemente.', + datasetDeleted: 'Conocimiento eliminado', + datasetDeleteFailed: 'Error al eliminar el Conocimiento', + didYouKnow: '¿Sabías?', + intro1: 'El Conocimiento se puede integrar en la aplicación Dify ', + intro2: 'como contexto', + intro3: ',', + intro4: 'o ', + intro5: 'se puede crear', + intro6: ' como un complemento independiente de ChatGPT para publicar', + unavailable: 'No disponible', + unavailableTip: 'El modelo de incrustación no está disponible, es necesario configurar el modelo de incrustación predeterminado', + datasets: 'CONOCIMIENTO', + datasetsApi: 'ACCESO A LA API', + retrieval: { + semantic_search: { + title: 'Búsqueda Vectorial', + description: 'Genera incrustaciones de consulta y busca el fragmento de texto más similar a su representación vectorial.', + }, + full_text_search: { + title: 'Búsqueda de Texto Completo', + description: 'Indexa todos los términos del documento, lo que permite a los usuarios buscar cualquier término y recuperar el fragmento de texto relevante que contiene esos términos.', + }, + hybrid_search: { + title: 'Búsqueda Híbrida', + description: 'Ejecuta búsquedas de texto completo y búsquedas vectoriales simultáneamente, reordena para seleccionar la mejor coincidencia para la consulta del usuario. Es necesaria la configuración de las API del modelo de reordenamiento.', + recommend: 'Recomendar', + }, + invertedIndex: { + title: 'Índice Invertido', + description: 'El Índice Invertido es una estructura utilizada para la recuperación eficiente. Organizado por términos, cada término apunta a documentos o páginas web que lo contienen.', + }, + change: 'Cambiar', + changeRetrievalMethod: 'Cambiar método de recuperación', + }, + docsFailedNotice: 'no se pudieron indexar los documentos', + retry: 'Reintentar', +} + +export default translation diff --git a/web/i18n/es-ES/explore.ts b/web/i18n/es-ES/explore.ts new file mode 100644 index 00000000000000..5f85d423629bf0 --- /dev/null +++ b/web/i18n/es-ES/explore.ts @@ -0,0 +1,41 @@ +const translation = { + title: 'Explorar', + sidebar: { + discovery: 'Descubrimiento', + chat: 'Chat', + workspace: 'Espacio de trabajo', + action: { + pin: 'Anclar', + unpin: 'Desanclar', + rename: 'Renombrar', + delete: 'Eliminar', + }, + delete: { + title: 'Eliminar aplicación', + content: '¿Estás seguro de que quieres eliminar esta aplicación?', + }, + }, + apps: { + title: 'Explorar aplicaciones de Dify', + description: 'Utiliza estas aplicaciones de plantilla al instante o personaliza tus propias aplicaciones basadas en las plantillas.', + allCategories: 'Recomendado', + }, + appCard: { + addToWorkspace: 'Agregar al espacio de trabajo', + customize: 'Personalizar', + }, + appCustomize: { + title: 'Crear aplicación a partir de {{name}}', + subTitle: 'Icono y nombre de la aplicación', + nameRequired: 'El nombre de la aplicación es obligatorio', + }, + category: { + Assistant: 'Asistente', + Writing: 'Escritura', + Translate: 'Traducción', + Programming: 'Programación', + HR: 'Recursos Humanos', + }, +} + +export default translation diff --git a/web/i18n/es-ES/layout.ts b/web/i18n/es-ES/layout.ts new file mode 100644 index 00000000000000..928649474b4dcd --- /dev/null +++ b/web/i18n/es-ES/layout.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/es-ES/login.ts b/web/i18n/es-ES/login.ts new file mode 100644 index 00000000000000..dc12cfc32ffe6b --- /dev/null +++ b/web/i18n/es-ES/login.ts @@ -0,0 +1,75 @@ +const translation = { + pageTitle: '¡Hola, vamos a empezar!👋', + welcome: 'Bienvenido a Dify, por favor inicia sesión para continuar.', + email: 'Correo electrónico', + emailPlaceholder: 'Tu correo electrónico', + password: 'Contraseña', + passwordPlaceholder: 'Tu contraseña', + name: 'Nombre de usuario', + namePlaceholder: 'Tu nombre de usuario', + forget: '¿Olvidaste tu contraseña?', + signBtn: 'Iniciar sesión', + sso: 'Continuar con SSO', + installBtn: 'Configurar', + setAdminAccount: 'Configurando una cuenta de administrador', + setAdminAccountDesc: 'Privilegios máximos para la cuenta de administrador, que se puede utilizar para crear aplicaciones y administrar proveedores de LLM, etc.', + createAndSignIn: 'Crear e iniciar sesión', + oneMoreStep: 'Un paso más', + createSample: 'Con esta información, crearemos una aplicación de muestra para ti', + invitationCode: 'Código de invitación', + invitationCodePlaceholder: 'Tu código de invitación', + interfaceLanguage: 'Idioma de interfaz', + timezone: 'Zona horaria', + go: 'Ir a Dify', + sendUsMail: 'Envíanos un correo electrónico con tu presentación y nosotros nos encargaremos de la solicitud de invitación.', + acceptPP: 'He leído y acepto la política de privacidad', + reset: 'Por favor, ejecuta el siguiente comando para restablecer tu contraseña', + withGitHub: 'Continuar con GitHub', + withGoogle: 'Continuar con Google', + rightTitle: 'Desbloquea todo el potencial de LLM', + rightDesc: 'Construye de manera sencilla aplicaciones de IA visualmente cautivadoras, operables y mejorables.', + tos: 'Términos de servicio', + pp: 'Política de privacidad', + tosDesc: 'Al registrarte, aceptas nuestros', + goToInit: 'Si no has inicializado la cuenta, por favor ve a la página de inicialización', + donthave: '¿No tienes?', + invalidInvitationCode: 'Código de invitación inválido', + accountAlreadyInited: 'La cuenta ya está inicializada', + forgotPassword: '¿Olvidaste tu contraseña?', + resetLinkSent: 'Enlace de restablecimiento enviado', + sendResetLink: 'Enviar enlace de restablecimiento', + backToSignIn: 'Volver a iniciar sesión', + forgotPasswordDesc: 'Por favor, ingresa tu dirección de correo electrónico para restablecer tu contraseña. Te enviaremos un correo electrónico con instrucciones sobre cómo restablecer tu contraseña.', + checkEmailForResetLink: 'Por favor, revisa tu correo electrónico para encontrar un enlace para restablecer tu contraseña. Si no aparece en unos minutos, asegúrate de revisar tu carpeta de spam.', + passwordChanged: 'Inicia sesión ahora', + changePassword: 'Cambiar contraseña', + changePasswordTip: 'Por favor, ingresa una nueva contraseña para tu cuenta', + invalidToken: 'Token inválido o expirado', + confirmPassword: 'Confirmar contraseña', + confirmPasswordPlaceholder: 'Confirma tu nueva contraseña', + passwordChangedTip: 'Tu contraseña se ha cambiado correctamente', + error: { + emailEmpty: 'Se requiere una dirección de correo electrónico', + emailInValid: 'Por favor, ingresa una dirección de correo electrónico válida', + nameEmpty: 'Se requiere un nombre', + passwordEmpty: 'Se requiere una contraseña', + passwordLengthInValid: 'La contraseña debe tener al menos 8 caracteres', + passwordInvalid: 'La contraseña debe contener letras y números, y tener una longitud mayor a 8', + }, + license: { + tip: 'Antes de comenzar con Dify Community Edition, lee la', + link: 'Licencia de código abierto de GitHub', + }, + join: 'Unirse', + joinTipStart: 'Te invita a unirte al equipo de', + joinTipEnd: 'en Dify', + invalid: 'El enlace ha expirado', + explore: 'Explorar Dify', + activatedTipStart: 'Te has unido al equipo de', + activatedTipEnd: '', + activated: 'Inicia sesión ahora', + adminInitPassword: 'Contraseña de inicialización de administrador', + validate: 'Validar', +} + +export default translation diff --git a/web/i18n/es-ES/register.ts b/web/i18n/es-ES/register.ts new file mode 100644 index 00000000000000..928649474b4dcd --- /dev/null +++ b/web/i18n/es-ES/register.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/es-ES/run-log.ts b/web/i18n/es-ES/run-log.ts new file mode 100644 index 00000000000000..134764e60d0d0a --- /dev/null +++ b/web/i18n/es-ES/run-log.ts @@ -0,0 +1,29 @@ +const translation = { + input: 'ENTRADA', + result: 'RESULTADO', + detail: 'DETALLE', + tracing: 'TRAZADO', + resultPanel: { + status: 'ESTADO', + time: 'TIEMPO TRANSCURRIDO', + tokens: 'TOTAL DE TOKENS', + }, + meta: { + title: 'METADATOS', + status: 'Estado', + version: 'Versión', + executor: 'Ejecutor', + startTime: 'Hora de inicio', + time: 'Tiempo transcurrido', + tokens: 'Total de tokens', + steps: 'Pasos de ejecución', + }, + resultEmpty: { + title: 'Esta ejecución solo produce formato JSON,', + tipLeft: 'por favor ve al ', + link: 'panel de detalle', + tipRight: ' para verlo.', + }, +} + +export default translation diff --git a/web/i18n/es-ES/share-app.ts b/web/i18n/es-ES/share-app.ts new file mode 100644 index 00000000000000..ad242df478958f --- /dev/null +++ b/web/i18n/es-ES/share-app.ts @@ -0,0 +1,74 @@ +const translation = { + common: { + welcome: 'Bienvenido/a al uso', + appUnavailable: 'La aplicación no está disponible', + appUnkonwError: 'La aplicación no está disponible', + }, + chat: { + newChat: 'Nuevo chat', + pinnedTitle: 'Fijados', + unpinnedTitle: 'Chats', + newChatDefaultName: 'Nueva conversación', + resetChat: 'Reiniciar conversación', + powerBy: 'Desarrollado por', + prompt: 'Indicación', + privatePromptConfigTitle: 'Configuración de la conversación', + publicPromptConfigTitle: 'Indicación inicial', + configStatusDes: 'Antes de comenzar, puedes modificar la configuración de la conversación', + configDisabled: + 'Se han utilizado las configuraciones de la sesión anterior para esta sesión.', + startChat: 'Iniciar chat', + privacyPolicyLeft: + 'Por favor, lee la ', + privacyPolicyMiddle: + 'política de privacidad', + privacyPolicyRight: + ' proporcionada por el desarrollador de la aplicación.', + deleteConversation: { + title: 'Eliminar conversación', + content: '¿Estás seguro/a de que quieres eliminar esta conversación?', + }, + tryToSolve: 'Intentar resolver', + temporarySystemIssue: 'Lo sentimos, hay un problema temporal del sistema.', + }, + generation: { + tabs: { + create: 'Ejecutar una vez', + batch: 'Ejecutar en lote', + saved: 'Guardado', + }, + savedNoData: { + title: '¡Aún no has guardado ningún resultado!', + description: 'Comienza a generar contenido y encuentra tus resultados guardados aquí.', + startCreateContent: 'Comenzar a crear contenido', + }, + title: 'Completado por IA', + queryTitle: 'Contenido de la consulta', + completionResult: 'Resultado del completado', + queryPlaceholder: 'Escribe tu contenido de consulta...', + run: 'Ejecutar', + copy: 'Copiar', + resultTitle: 'Completado por IA', + noData: 'La IA te dará lo que deseas aquí.', + csvUploadTitle: 'Arrastra y suelta tu archivo CSV aquí, o ', + browse: 'navega', + csvStructureTitle: 'El archivo CSV debe cumplir con la siguiente estructura:', + downloadTemplate: 'Descarga la plantilla aquí', + field: 'Campo', + batchFailed: { + info: '{{num}} ejecuciones fallidas', + retry: 'Reintentar', + outputPlaceholder: 'Sin contenido de salida', + }, + errorMsg: { + empty: 'Por favor, ingresa contenido en el archivo cargado.', + fileStructNotMatch: 'El archivo CSV cargado no coincide con la estructura.', + emptyLine: 'La fila {{rowIndex}} está vacía', + invalidLine: 'Fila {{rowIndex}}: el valor de {{varName}} no puede estar vacío', + moreThanMaxLengthLine: 'Fila {{rowIndex}}: el valor de {{varName}} no puede tener más de {{maxLength}} caracteres', + atLeastOne: 'Por favor, ingresa al menos una fila en el archivo cargado.', + }, + }, +} + +export default translation diff --git a/web/i18n/es-ES/tools.ts b/web/i18n/es-ES/tools.ts new file mode 100644 index 00000000000000..546591f1aabf13 --- /dev/null +++ b/web/i18n/es-ES/tools.ts @@ -0,0 +1,153 @@ +const translation = { + title: 'Herramientas', + createCustomTool: 'Crear Herramienta Personalizada', + customToolTip: 'Aprende más sobre las herramientas personalizadas de Dify', + type: { + all: 'Todas', + builtIn: 'Incorporadas', + custom: 'Personalizadas', + workflow: 'Flujo de Trabajo', + }, + contribute: { + line1: 'Estoy interesado en ', + line2: 'contribuir herramientas a Dify.', + viewGuide: 'Ver la guía', + }, + author: 'Por', + auth: { + unauthorized: 'Para Autorizar', + authorized: 'Autorizado', + setup: 'Configurar la autorización para usar', + setupModalTitle: 'Configurar Autorización', + setupModalTitleDescription: 'Después de configurar las credenciales, todos los miembros dentro del espacio de trabajo pueden usar esta herramienta al orquestar aplicaciones.', + }, + includeToolNum: '{{num}} herramientas incluidas', + addTool: 'Agregar Herramienta', + addToolModal: { + type: 'tipo', + category: 'categoría', + add: 'agregar', + added: 'agregada', + manageInTools: 'Administrar en Herramientas', + emptyTitle: 'No hay herramientas de flujo de trabajo disponibles', + emptyTip: 'Ir a "Flujo de Trabajo -> Publicar como Herramienta"', + }, + createTool: { + title: 'Crear Herramienta Personalizada', + editAction: 'Configurar', + editTitle: 'Editar Herramienta Personalizada', + name: 'Nombre', + toolNamePlaceHolder: 'Ingresa el nombre de la herramienta', + nameForToolCall: 'Nombre de llamada de la herramienta', + nameForToolCallPlaceHolder: 'Utilizado para el reconocimiento automático, como getCurrentWeather, list_pets', + nameForToolCallTip: 'Solo soporta números, letras y guiones bajos.', + description: 'Descripción', + descriptionPlaceholder: 'Breve descripción del propósito de la herramienta, por ejemplo, obtener la temperatura de una ubicación específica.', + schema: 'Esquema', + schemaPlaceHolder: 'Ingresa tu esquema OpenAPI aquí', + viewSchemaSpec: 'Ver la Especificación OpenAPI-Swagger', + importFromUrl: 'Importar desde URL', + importFromUrlPlaceHolder: 'https://...', + urlError: 'Por favor, ingresa una URL válida', + examples: 'Ejemplos', + exampleOptions: { + json: 'Clima (JSON)', + yaml: 'Tienda de Mascotas (YAML)', + blankTemplate: 'Plantilla en Blanco', + }, + availableTools: { + title: 'Herramientas Disponibles', + name: 'Nombre', + description: 'Descripción', + method: 'Método', + path: 'Ruta', + action: 'Acciones', + test: 'Probar', + }, + authMethod: { + title: 'Método de Autorización', + type: 'Tipo de Autorización', + keyTooltip: 'Clave del encabezado HTTP, puedes dejarla como "Authorization" si no tienes idea de qué es o configurarla con un valor personalizado', + types: { + none: 'Ninguno', + api_key: 'Clave API', + apiKeyPlaceholder: 'Nombre del encabezado HTTP para la Clave API', + apiValuePlaceholder: 'Ingresa la Clave API', + }, + key: 'Clave', + value: 'Valor', + }, + authHeaderPrefix: { + title: 'Tipo de Autenticación', + types: { + basic: 'Básica', + bearer: 'Bearer', + custom: 'Personalizada', + }, + }, + privacyPolicy: 'Política de Privacidad', + privacyPolicyPlaceholder: 'Por favor, ingresa la política de privacidad', + toolInput: { + title: 'Entrada de la Herramienta', + name: 'Nombre', + required: 'Requerido', + method: 'Método', + methodSetting: 'Configuración', + methodSettingTip: 'El usuario completa la configuración de la herramienta', + methodParameter: 'Parámetro', + methodParameterTip: 'LLM completa durante la inferencia', + label: 'Etiquetas', + labelPlaceholder: 'Elige etiquetas (opcional)', + description: 'Descripción', + descriptionPlaceholder: 'Descripción del significado del parámetro', + }, + customDisclaimer: 'Descargo de responsabilidad personalizado', + customDisclaimerPlaceholder: 'Por favor, ingresa el descargo de responsabilidad personalizado', + confirmTitle: '¿Confirmar para guardar?', + confirmTip: 'Las aplicaciones que usen esta herramienta se verán afectadas', + deleteToolConfirmTitle: '¿Eliminar esta Herramienta?', + deleteToolConfirmContent: 'Eliminar la herramienta es irreversible. Los usuarios ya no podrán acceder a tu herramienta.', + }, + test: { + title: 'Probar', + parametersValue: 'Parámetros y Valor', + parameters: 'Parámetros', + value: 'Valor', + testResult: 'Resultados de la Prueba', + testResultPlaceholder: 'El resultado de la prueba se mostrará aquí', + }, + thought: { + using: 'Usando', + used: 'Usado', + requestTitle: 'Solicitud a', + responseTitle: 'Respuesta de', + }, + setBuiltInTools: { + info: 'Información', + setting: 'Ajuste', + toolDescription: 'Descripción de la herramienta', + parameters: 'parámetros', + string: 'cadena', + number: 'número', + required: 'Requerido', + infoAndSetting: 'Información y Ajustes', + }, + noCustomTool: { + title: '¡Sin herramientas personalizadas!', + content: 'Agrega y administra tus herramientas personalizadas aquí para construir aplicaciones de inteligencia artificial.', + createTool: 'Crear Herramienta', + }, + noSearchRes: { + title: '¡Lo sentimos, no hay resultados!', + content: 'No encontramos herramientas que coincidan con tu búsqueda.', + reset: 'Restablecer Búsqueda', + }, + builtInPromptTitle: 'Aviso', + toolRemoved: 'Herramienta eliminada', + notAuthorized: 'Herramienta no autorizada', + howToGet: 'Cómo obtener', + openInStudio: 'Abrir en Studio', + toolNameUsageTip: 'Nombre de llamada de la herramienta para razonamiento y promoción de agentes', +} + +export default translation diff --git a/web/i18n/es-ES/workflow.ts b/web/i18n/es-ES/workflow.ts new file mode 100644 index 00000000000000..5db18939fe3121 --- /dev/null +++ b/web/i18n/es-ES/workflow.ts @@ -0,0 +1,476 @@ +const translation = { + common: { + undo: 'Deshacer', + redo: 'Rehacer', + editing: 'Editando', + autoSaved: 'Guardado automático', + unpublished: 'No publicado', + published: 'Publicado', + publish: 'Publicar', + update: 'Actualizar', + run: 'Ejecutar', + running: 'Ejecutando', + inRunMode: 'En modo de ejecución', + inPreview: 'En vista previa', + inPreviewMode: 'En modo de vista previa', + preview: 'Vista previa', + viewRunHistory: 'Ver historial de ejecución', + runHistory: 'Historial de ejecución', + goBackToEdit: 'Volver al editor', + conversationLog: 'Registro de conversación', + features: 'Funcionalidades', + debugAndPreview: 'Depurar y previsualizar', + restart: 'Reiniciar', + currentDraft: 'Borrador actual', + currentDraftUnpublished: 'Borrador actual no publicado', + latestPublished: 'Último publicado', + publishedAt: 'Publicado el', + restore: 'Restaurar', + runApp: 'Ejecutar aplicación', + batchRunApp: 'Ejecutar aplicación en lote', + accessAPIReference: 'Acceder a la referencia de la API', + embedIntoSite: 'Insertar en el sitio', + addTitle: 'Agregar título...', + addDescription: 'Agregar descripción...', + noVar: 'Sin variable', + searchVar: 'Buscar variable', + variableNamePlaceholder: 'Nombre de la variable', + setVarValuePlaceholder: 'Establecer variable', + needConnecttip: 'Este paso no está conectado a nada', + maxTreeDepth: 'Límite máximo de {{depth}} nodos por rama', + needEndNode: 'Debe agregarse el bloque de Fin', + needAnswerNode: 'Debe agregarse el bloque de Respuesta', + workflowProcess: 'Proceso de flujo de trabajo', + notRunning: 'Aún no se está ejecutando', + previewPlaceholder: 'Ingrese contenido en el cuadro de abajo para comenzar a depurar el Chatbot', + effectVarConfirm: { + title: 'Eliminar variable', + content: 'La variable se utiliza en otros nodos. ¿Aún quieres eliminarla?', + }, + insertVarTip: 'Presiona la tecla \'/\' para insertar rápidamente', + processData: 'Procesar datos', + input: 'Entrada', + output: 'Salida', + jinjaEditorPlaceholder: 'Escribe \'/\' o \'{\' para insertar una variable', + viewOnly: 'Solo vista', + showRunHistory: 'Mostrar historial de ejecución', + enableJinja: 'Habilitar soporte de plantillas Jinja', + learnMore: 'Más información', + copy: 'Copiar', + duplicate: 'Duplicar', + addBlock: 'Agregar bloque', + pasteHere: 'Pegar aquí', + pointerMode: 'Modo puntero', + handMode: 'Modo mano', + model: 'Modelo', + workflowAsTool: 'Flujo de trabajo como herramienta', + configureRequired: 'Configuración requerida', + configure: 'Configurar', + manageInTools: 'Administrar en Herramientas', + workflowAsToolTip: 'Se requiere la reconfiguración de la herramienta después de la actualización del flujo de trabajo.', + viewDetailInTracingPanel: 'Ver detalles', + syncingData: 'Sincronizando datos, solo unos segundos.', + importDSL: 'Importar DSL', + importDSLTip: 'El borrador actual se sobrescribirá. Exporta el flujo de trabajo como respaldo antes de importar.', + backupCurrentDraft: 'Respaldar borrador actual', + chooseDSL: 'Elegir archivo DSL (yml)', + overwriteAndImport: 'Sobrescribir e importar', + importFailure: 'Error al importar', + importSuccess: 'Importación exitosa', + }, + changeHistory: { + title: 'Historial de cambios', + placeholder: 'Aún no has realizado cambios', + clearHistory: 'Borrar historial', + hint: 'Sugerencia', + hintText: 'Tus acciones de edición se registran en un historial de cambios, que se almacena en tu dispositivo durante esta sesión. Este historial se borrará cuando salgas del editor.', + stepBackward_one: '{{count}} paso hacia atrás', + stepBackward_other: '{{count}} pasos hacia atrás', + stepForward_one: '{{count}} paso hacia adelante', + stepForward_other: '{{count}} pasos hacia adelante', + sessionStart: 'Inicio de sesión', + currentState: 'Estado actual', + nodeTitleChange: 'Se cambió el título del bloque', + nodeDescriptionChange: 'Se cambió la descripción del bloque', + nodeDragStop: 'Bloque movido', + nodeChange: 'Bloque cambiado', + nodeConnect: 'Bloque conectado', + nodePaste: 'Bloque pegado', + nodeDelete: 'Bloque eliminado', + nodeAdd: 'Bloque agregado', + nodeResize: 'Bloque redimensionado', + noteAdd: 'Nota agregada', + noteChange: 'Nota cambiada', + noteDelete: 'Nota eliminada', + edgeDelete: 'Bloque desconectado', + }, + errorMsg: { + fieldRequired: 'Se requiere {{field}}', + authRequired: 'Se requiere autorización', + invalidJson: '{{field}} no es un JSON válido', + fields: { + variable: 'Nombre de la variable', + variableValue: 'Valor de la variable', + code: 'Código', + model: 'Modelo', + rerankModel: 'Modelo de reordenamiento', + }, + invalidVariable: 'Variable no válida', + }, + singleRun: { + testRun: 'Ejecución de prueba', + startRun: 'Iniciar ejecución', + running: 'Ejecutando', + testRunIteration: 'Iteración de ejecución de prueba', + back: 'Atrás', + iteration: 'Iteración', + }, + tabs: { + 'searchBlock': 'Buscar bloque', + 'blocks': 'Bloques', + 'tools': 'Herramientas', + 'allTool': 'Todos', + 'builtInTool': 'Incorporadas', + 'customTool': 'Personalizadas', + 'workflowTool': 'Flujo de trabajo', + 'question-understand': 'Entender pregunta', + 'logic': 'Lógica', + 'transform': 'Transformar', + 'utilities': 'Utilidades', + 'noResult': 'No se encontraron coincidencias', + }, + blocks: { + 'start': 'Inicio', + 'end': 'Fin', + 'answer': 'Respuesta', + 'llm': 'LLM', + 'knowledge-retrieval': 'Recuperación de conocimiento', + 'question-classifier': 'Clasificador de preguntas', + 'if-else': 'SI/SINO', + 'code': 'Código', + 'template-transform': 'Plantilla', + 'http-request': 'Solicitud HTTP', + 'variable-assigner': 'Asignador de variables', + 'variable-aggregator': 'Agregador de variables', + 'iteration-start': 'Inicio de iteración', + 'iteration': 'Iteración', + 'parameter-extractor': 'Extractor de parámetros', + }, + blocksAbout: { + 'start': 'Define los parámetros iniciales para iniciar un flujo de trabajo', + 'end': 'Define el final y el tipo de resultado de un flujo de trabajo', + 'answer': 'Define el contenido de respuesta de una conversación de chat', + 'llm': 'Invoca modelos de lenguaje grandes para responder preguntas o procesar lenguaje natural', + 'knowledge-retrieval': 'Te permite consultar contenido de texto relacionado con las preguntas de los usuarios desde el conocimiento', + 'question-classifier': 'Define las condiciones de clasificación de las preguntas de los usuarios, LLM puede definir cómo progresa la conversación en función de la descripción de clasificación', + 'if-else': 'Te permite dividir el flujo de trabajo en dos ramas basadas en condiciones SI/SINO', + 'code': 'Ejecuta un fragmento de código Python o NodeJS para implementar lógica personalizada', + 'template-transform': 'Convierte datos en una cadena utilizando la sintaxis de plantillas Jinja', + 'http-request': 'Permite enviar solicitudes al servidor a través del protocolo HTTP', + 'variable-assigner': 'Agrega variables de múltiples ramas en una sola variable para configurar de manera unificada los nodos descendentes.', + 'variable-aggregator': 'Agrega variables de múltiples ramas en una sola variable para configurar de manera unificada los nodos descendentes.', + 'iteration': 'Realiza múltiples pasos en un objeto de lista hasta que se generen todos los resultados.', + 'parameter-extractor': 'Utiliza LLM para extraer parámetros estructurados del lenguaje natural para invocaciones de herramientas o solicitudes HTTP.', + }, + operator: { + zoomIn: 'Acercar', + zoomOut: 'Alejar', + zoomTo50: 'Zoom al 50%', + zoomTo100: 'Zoom al 100%', + zoomToFit: 'Ajustar al tamaño', + }, + panel: { + userInputField: 'Campo de entrada del usuario', + changeBlock: 'Cambiar bloque', + helpLink: 'Enlace de ayuda', + about: 'Acerca de', + createdBy: 'Creado por ', + nextStep: 'Siguiente paso', + addNextStep: 'Agregar el siguiente bloque en este flujo de trabajo', + selectNextStep: 'Seleccionar siguiente bloque', + runThisStep: 'Ejecutar este paso', + checklist: 'Lista de verificación', + checklistTip: 'Asegúrate de resolver todos los problemas antes de publicar', + checklistResolved: 'Se resolvieron todos los problemas', + organizeBlocks: 'Organizar bloques', + change: 'Cambiar', + }, + nodes: { + common: { + outputVars: 'Variables de salida', + insertVarTip: 'Insertar variable', + memory: { + memory: 'Memoria', + memoryTip: 'Configuración de memoria de chat', + windowSize: 'Tamaño de ventana', + conversationRoleName: 'Nombre del rol de conversación', + user: 'Prefijo de usuario', + assistant: 'Prefijo de asistente', + }, + memories: { + title: 'Memorias', + tip: 'Memoria de chat', + builtIn: 'Incorporada', + }, + }, + start: { + required: 'requerido', + inputField: 'Campo de entrada', + builtInVar: 'Variables incorporadas', + outputVars: { + query: 'Entrada del usuario', + memories: { + des: 'Historial de conversación', + type: 'tipo de mensaje', + content: 'contenido del mensaje', + }, + files: 'Lista de archivos', + }, + noVarTip: 'Establece las entradas que se pueden utilizar en el flujo de trabajo', + }, + end: { + outputs: 'Salidas', + output: { + type: 'tipo de salida', + variable: 'variable de salida', + }, + type: { + 'none': 'Ninguno', + 'plain-text': 'Texto sin formato', + 'structured': 'Estructurado', + }, + }, + answer: { + answer: 'Respuesta', + outputVars: 'Variables de salida', + }, + llm: { + model: 'modelo', + variables: 'variables', + context: 'contexto', + contextTooltip: 'Puedes importar el conocimiento como contexto', + notSetContextInPromptTip: 'Para habilitar la función de contexto, completa la variable de contexto en PROMPT.', + prompt: 'indicación', + roleDescription: { + system: 'Proporciona instrucciones generales para la conversación', + user: 'Proporciona instrucciones, consultas o cualquier entrada basada en texto al modelo', + assistant: 'Las respuestas del modelo basadas en los mensajes del usuario', + }, + addMessage: 'Agregar mensaje', + vision: 'visión', + files: 'Archivos', + resolution: { + name: 'Resolución', + high: 'Alta', + low: 'Baja', + }, + outputVars: { + output: 'Generar contenido', + usage: 'Información de uso del modelo', + }, + singleRun: { + variable: 'Variable', + }, + sysQueryInUser: 'se requiere sys.query en el mensaje del usuario', + }, + knowledgeRetrieval: { + queryVariable: 'Variable de consulta', + knowledge: 'Conocimiento', + outputVars: { + output: 'Datos segmentados de recuperación', + content: 'Contenido segmentado', + title: 'Título segmentado', + icon: 'Ícono segmentado', + url: 'URL segmentada', + metadata: 'Metadatos adicionales', + }, + }, + http: { + inputVars: 'Variables de entrada', + api: 'API', + apiPlaceholder: 'Ingresa la URL, escribe \'/\' para insertar una variable', + notStartWithHttp: 'La API debe comenzar con http:// o https://', + key: 'Clave', + value: 'Valor', + bulkEdit: 'Edición masiva', + keyValueEdit: 'Edición clave-valor', + headers: 'Encabezados', + params: 'Parámetros', + body: 'Cuerpo', + outputVars: { + body: 'Contenido de la respuesta', + statusCode: 'Código de estado de la respuesta', + headers: 'Lista de encabezados de respuesta en formato JSON', + files: 'Lista de archivos', + }, + authorization: { + 'authorization': 'Autorización', + 'authorizationType': 'Tipo de autorización', + 'no-auth': 'Ninguna', + 'api-key': 'Clave de API', + 'auth-type': 'Tipo de autenticación', + 'basic': 'Básica', + 'bearer': 'Bearer', + 'custom': 'Personalizada', + 'api-key-title': 'Clave de API', + 'header': 'Encabezado', + }, + insertVarPlaceholder: 'escribe \'/\' para insertar una variable', + timeout: { + title: 'Tiempo de espera', + connectLabel: 'Tiempo de espera de conexión', + connectPlaceholder: 'Ingresa el tiempo de espera de conexión en segundos', + readLabel: 'Tiempo de espera de lectura', + readPlaceholder: 'Ingresa el tiempo de espera de lectura en segundos', + writeLabel: 'Tiempo de espera de escritura', + writePlaceholder: 'Ingresa el tiempo de espera de escritura en segundos', + }, + }, + code: { + inputVars: 'Variables de entrada', + outputVars: 'Variables de salida', + advancedDependencies: 'Dependencias avanzadas', + advancedDependenciesTip: 'Agrega algunas dependencias precargadas que consumen más tiempo o no son incorporadas por defecto aquí', + searchDependencies: 'Buscar dependencias', + }, + templateTransform: { + inputVars: 'Variables de entrada', + code: 'Código', + codeSupportTip: 'Solo admite Jinja2', + outputVars: { + output: 'Contenido transformado', + }, + }, + ifElse: { + if: 'Si', + else: 'Sino', + elseDescription: 'Se utiliza para definir la lógica que se debe ejecutar cuando no se cumple la condición del si.', + and: 'y', + or: 'o', + operator: 'Operador', + notSetVariable: 'Por favor, establece primero la variable', + comparisonOperator: { + 'contains': 'contiene', + 'not contains': 'no contiene', + 'start with': 'comienza con', + 'end with': 'termina con', + 'is': 'es', + 'is not': 'no es', + 'empty': 'está vacío', + 'not empty': 'no está vacío', + 'null': 'es nulo', + 'not null': 'no es nulo', + }, + enterValue: 'Ingresa un valor', + addCondition: 'Agregar condición', + conditionNotSetup: 'Condición NO configurada', + }, + variableAssigner: { + title: 'Asignar variables', + outputType: 'Tipo de salida', + varNotSet: 'Variable no establecida', + noVarTip: 'Agrega las variables que se asignarán', + type: { + string: 'Cadena', + number: 'Número', + object: 'Objeto', + array: 'Arreglo', + }, + aggregationGroup: 'Grupo de agregación', + aggregationGroupTip: 'Al habilitar esta función, el agregador de variables puede agregar múltiples conjuntos de variables.', + addGroup: 'Agregar grupo', + outputVars: { + varDescribe: 'Salida de {{groupName}}', + }, + setAssignVariable: 'Establecer variable asignada', + }, + tool: { + toAuthorize: 'Para autorizar', + inputVars: 'Variables de entrada', + outputVars: { + text: 'Contenido generado por la herramienta', + files: { + title: 'Archivos generados por la herramienta', + type: 'Tipo de soporte. Ahora solo admite imágenes', + transfer_method: 'Método de transferencia. El valor es remote_url o local_file', + url: 'URL de la imagen', + upload_file_id: 'ID de archivo cargado', + }, + json: 'JSON generado por la herramienta', + }, + }, + questionClassifiers: { + model: 'modelo', + inputVars: 'Variables de entrada', + outputVars: { + className: 'Nombre de la clase', + }, + class: 'Clase', + classNamePlaceholder: 'Escribe el nombre de tu clase', + advancedSetting: 'Configuración avanzada', + topicName: 'Nombre del tema', + topicPlaceholder: 'Escribe el nombre de tu tema', + addClass: 'Agregar clase', + instruction: 'Instrucción', + instructionTip: 'Input additional instructions to help the question classifier better understand how to categorize questions.', + instructionPlaceholder: 'Write your instruction', + }, + parameterExtractor: { + inputVar: 'Variable de entrada', + extractParameters: 'Extraer parámetros', + importFromTool: 'Importar desde herramientas', + addExtractParameter: 'Agregar parámetro de extracción', + addExtractParameterContent: { + name: 'Nombre', + namePlaceholder: 'Nombre del parámetro de extracción', + type: 'Tipo', + typePlaceholder: 'Tipo de parámetro de extracción', + description: 'Descripción', + descriptionPlaceholder: 'Descripción del parámetro de extracción', + required: 'Requerido', + requiredContent: 'El campo requerido se utiliza solo como referencia para la inferencia del modelo, y no para la validación obligatoria de la salida del parámetro.', + }, + extractParametersNotSet: 'Parámetros de extracción no configurados', + instruction: 'Instrucción', + instructionTip: 'Ingrese instrucciones adicionales para ayudar al extractor de parámetros a entender cómo extraer parámetros.', + advancedSetting: 'Configuración avanzada', + reasoningMode: 'Modo de razonamiento', + reasoningModeTip: 'Puede elegir el modo de razonamiento apropiado basado en la capacidad del modelo para responder a instrucciones para llamadas de funciones o indicaciones.', + isSuccess: 'Es éxito. En caso de éxito el valor es 1, en caso de fallo el valor es 0.', + errorReason: 'Motivo del error', + }, + iteration: { + deleteTitle: '¿Eliminar nodo de iteración?', + deleteDesc: 'Eliminar el nodo de iteración eliminará todos los nodos secundarios', + input: 'Entrada', + output: 'Variables de salida', + iteration_one: '{{count}} Iteración', + iteration_other: '{{count}} Iteraciones', + currentIteration: 'Iteración actual', + }, + note: { + addNote: 'Agregar nota', + editor: { + placeholder: 'Escribe tu nota...', + small: 'Pequeño', + medium: 'Mediano', + large: 'Grande', + bold: 'Negrita', + italic: 'Itálica', + strikethrough: 'Tachado', + link: 'Enlace', + openLink: 'Abrir', + unlink: 'Quitar enlace', + enterUrl: 'Introducir URL...', + invalidUrl: 'URL inválida', + bulletList: 'Lista de viñetas', + showAuthor: 'Mostrar autor', + }, + }, + tracing: { + stopBy: 'Detenido por {{user}}', + }, + }, +} + +export default translation diff --git a/web/i18n/fr-FR/login.ts b/web/i18n/fr-FR/login.ts index 71cc15f61a6a61..c905320b223a4c 100644 --- a/web/i18n/fr-FR/login.ts +++ b/web/i18n/fr-FR/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: 'Vous n\'avez pas ?', invalidInvitationCode: 'Code d\'invitation invalide', accountAlreadyInited: 'Compte déjà initialisé', + forgotPassword: 'Mot de passe oublié?', + resetLinkSent: 'Lien de réinitialisation envoyé', + sendResetLink: 'Envoyer le lien de réinitialisation', + backToSignIn: 'Retour à la connexion', + forgotPasswordDesc: 'Veuillez entrer votre adresse e-mail pour réinitialiser votre mot de passe. Nous vous enverrons un e-mail avec des instructions sur la réinitialisation de votre mot de passe.', + checkEmailForResetLink: 'Veuillez vérifier votre e-mail pour un lien de réinitialisation de votre mot de passe. S\'il n\'apparaît pas dans quelques minutes, assurez-vous de vérifier votre dossier de spam.', + passwordChanged: 'Connectez-vous maintenant', + changePassword: 'Changer le mot de passe', + changePasswordTip: 'Veuillez entrer un nouveau mot de passe pour votre compte', + invalidToken: 'Token invalide ou expiré', + confirmPassword: 'Confirmez le mot de passe', + confirmPasswordPlaceholder: 'Confirmez votre nouveau mot de passe', + passwordChangedTip: 'Votre mot de passe a été changé avec succès', error: { emailEmpty: 'Une adresse e-mail est requise', emailInValid: 'Veuillez entrer une adresse email valide', diff --git a/web/i18n/hi-IN/login.ts b/web/i18n/hi-IN/login.ts index 06edd2c0888944..3ecba9a1861281 100644 --- a/web/i18n/hi-IN/login.ts +++ b/web/i18n/hi-IN/login.ts @@ -39,6 +39,19 @@ const translation = { donthave: 'नहीं है?', invalidInvitationCode: 'अवैध निमंत्रण कोड', accountAlreadyInited: 'खाता पहले से प्रारंभ किया गया है', + forgotPassword: 'क्या आपने अपना पासवर्ड भूल गए हैं?', + resetLinkSent: 'रीसेट लिंक भेजी गई', + sendResetLink: 'रीसेट लिंक भेजें', + backToSignIn: 'साइन इन पर वापस जाएं', + forgotPasswordDesc: 'कृपया अपना ईमेल पता दर्ज करें ताकि हम आपको अपना पासवर्ड रीसेट करने के निर्देशों के साथ एक ईमेल भेज सकें।', + checkEmailForResetLink: 'कृपया अपना पासवर्ड रीसेट करने के लिए लिंक के लिए अपना ईमेल चेक करें। अगर यह कुछ मिनटों के भीतर नहीं आता है, तो कृपया अपना स्पैम फोल्डर भी चेक करें।', + passwordChanged: 'अब साइन इन करें', + changePassword: 'पासवर्ड बदलें', + changePasswordTip: 'कृपया अपने खाते के लिए नया पासवर्ड दर्ज करें', + invalidToken: 'अमान्य या समाप्त टोकन', + confirmPassword: 'पासवर्ड की पुष्टि करें', + confirmPasswordPlaceholder: 'अपना नया पासवर्ड पुष्टि करें', + passwordChangedTip: 'आपका पासवर्ड सफलतापूर्वक बदल दिया गया है', error: { emailEmpty: 'ईमेल पता आवश्यक है', emailInValid: 'कृपया एक मान्य ईमेल पता दर्ज करें', diff --git a/web/i18n/ja-JP/login.ts b/web/i18n/ja-JP/login.ts index ef87dd3df6d8a2..4015bf448d4e2c 100644 --- a/web/i18n/ja-JP/login.ts +++ b/web/i18n/ja-JP/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: 'お持ちでない場合', invalidInvitationCode: '無効な招待コード', accountAlreadyInited: 'アカウントは既に初期化されています', + forgotPassword: 'パスワードを忘れましたか?', + resetLinkSent: 'リセットリンクが送信されました', + sendResetLink: 'リセットリンクを送信', + backToSignIn: 'サインインに戻る', + forgotPasswordDesc: 'パスワードをリセットするためにメールアドレスを入力してください。パスワードのリセット方法に関する指示が記載されたメールを送信します。', + checkEmailForResetLink: 'パスワードリセットリンクを確認するためにメールを確認してください。数分以内に表示されない場合は、スパムフォルダーを確認してください。', + passwordChanged: '今すぐサインイン', + changePassword: 'パスワードを変更する', + changePasswordTip: 'アカウントの新しいパスワードを入力してください', + invalidToken: '無効または期限切れのトークン', + confirmPassword: 'パスワードを確認', + confirmPasswordPlaceholder: '新しいパスワードを確認してください', + passwordChangedTip: 'パスワードが正常に変更されました', error: { emailEmpty: 'メールアドレスは必須です', emailInValid: '有効なメールアドレスを入力してください', diff --git a/web/i18n/ko-KR/login.ts b/web/i18n/ko-KR/login.ts index ee0867d1dbc1b8..01d1f538fe8496 100644 --- a/web/i18n/ko-KR/login.ts +++ b/web/i18n/ko-KR/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: '계정이 없으신가요?', invalidInvitationCode: '유효하지 않은 초대 코드입니다.', accountAlreadyInited: '계정은 이미 초기화되었습니다.', + forgotPassword: '비밀번호를 잊으셨나요?', + resetLinkSent: '재설정 링크가 전송되었습니다', + sendResetLink: '재설정 링크 보내기', + backToSignIn: '로그인으로 돌아가기', + forgotPasswordDesc: '비밀번호를 재설정하려면 이메일 주소를 입력하세요. 비밀번호 재설정 방법에 대한 이메일을 보내드리겠습니다.', + checkEmailForResetLink: '비밀번호 재설정 링크를 확인하려면 이메일을 확인하세요. 몇 분 내에 나타나지 않으면 스팸 폴더를 확인하세요.', + passwordChanged: '지금 로그인', + changePassword: '비밀번호 변경', + changePasswordTip: '계정의 새 비밀번호를 입력하세요', + invalidToken: '유효하지 않거나 만료된 토큰', + confirmPassword: '비밀번호 확인', + confirmPasswordPlaceholder: '새 비밀번호를 확인하세요', + passwordChangedTip: '비밀번호가 성공적으로 변경되었습니다', error: { emailEmpty: '이메일 주소를 입력하세요.', emailInValid: '유효한 이메일 주소를 입력하세요.', diff --git a/web/i18n/languages.json b/web/i18n/languages.json index 1017344471ed91..d93d163db04c2b 100644 --- a/web/i18n/languages.json +++ b/web/i18n/languages.json @@ -33,7 +33,7 @@ "name": "Español (España)", "prompt_name": "Spanish", "example": "Saluton, Dify!", - "supported": false + "supported": true }, { "value": "fr-FR", diff --git a/web/i18n/pl-PL/login.ts b/web/i18n/pl-PL/login.ts index b629ee598ac191..075b79b91384fc 100644 --- a/web/i18n/pl-PL/login.ts +++ b/web/i18n/pl-PL/login.ts @@ -39,6 +39,19 @@ const translation = { donthave: 'Nie masz?', invalidInvitationCode: 'Niewłaściwy kod zaproszenia', accountAlreadyInited: 'Konto już zainicjowane', + forgotPassword: 'Zapomniałeś hasła?', + resetLinkSent: 'Link resetujący został wysłany', + sendResetLink: 'Wyślij link resetujący', + backToSignIn: 'Powrót do logowania', + forgotPasswordDesc: 'Proszę podać swój adres e-mail, aby zresetować hasło. Wyślemy Ci e-mail z instrukcjami, jak zresetować hasło.', + checkEmailForResetLink: 'Proszę sprawdzić swój e-mail w poszukiwaniu linku do resetowania hasła. Jeśli nie pojawi się w ciągu kilku minut, sprawdź folder spam.', + passwordChanged: 'Zaloguj się teraz', + changePassword: 'Zmień hasło', + changePasswordTip: 'Wprowadź nowe hasło do swojego konta', + invalidToken: 'Nieprawidłowy lub wygasły token', + confirmPassword: 'Potwierdź hasło', + confirmPasswordPlaceholder: 'Potwierdź nowe hasło', + passwordChangedTip: 'Twoje hasło zostało pomyślnie zmienione', error: { emailEmpty: 'Adres e-mail jest wymagany', emailInValid: 'Proszę wpisać prawidłowy adres e-mail', diff --git a/web/i18n/pt-BR/login.ts b/web/i18n/pt-BR/login.ts index 722c7eecf2898e..88312778c38dae 100644 --- a/web/i18n/pt-BR/login.ts +++ b/web/i18n/pt-BR/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: 'Não tem?', invalidInvitationCode: 'Código de convite inválido', accountAlreadyInited: 'Conta já iniciada', + forgotPassword: 'Esqueceu sua senha?', + resetLinkSent: 'Link de redefinição enviado', + sendResetLink: 'Enviar link de redefinição', + backToSignIn: 'Voltar para login', + forgotPasswordDesc: 'Por favor, insira seu endereço de e-mail para redefinir sua senha. Enviaremos um e-mail com instruções sobre como redefinir sua senha.', + checkEmailForResetLink: 'Verifique seu e-mail para um link para redefinir sua senha. Se não aparecer dentro de alguns minutos, verifique sua pasta de spam.', + passwordChanged: 'Entre agora', + changePassword: 'Mudar a senha', + changePasswordTip: 'Por favor, insira uma nova senha para sua conta', + invalidToken: 'Token inválido ou expirado', + confirmPassword: 'Confirme a Senha', + confirmPasswordPlaceholder: 'Confirme sua nova senha', + passwordChangedTip: 'Sua senha foi alterada com sucesso', error: { emailEmpty: 'O endereço de e-mail é obrigatório', emailInValid: 'Digite um endereço de e-mail válido', diff --git a/web/i18n/ro-RO/login.ts b/web/i18n/ro-RO/login.ts index 3f22f8d169c5e5..c8a0fad91cbcee 100644 --- a/web/i18n/ro-RO/login.ts +++ b/web/i18n/ro-RO/login.ts @@ -35,6 +35,19 @@ const translation = { donthave: 'Nu ai?', invalidInvitationCode: 'Cod de invitație invalid', accountAlreadyInited: 'Contul este deja inițializat', + forgotPassword: 'Ați uitat parola?', + resetLinkSent: 'Link de resetare trimis', + sendResetLink: 'Trimiteți linkul de resetare', + backToSignIn: 'Înapoi la autentificare', + forgotPasswordDesc: 'Vă rugăm să introduceți adresa de e-mail pentru a reseta parola. Vă vom trimite un e-mail cu instrucțiuni despre cum să resetați parola.', + checkEmailForResetLink: 'Vă rugăm să verificați e-mailul pentru un link de resetare a parolei. Dacă nu apare în câteva minute, verificați folderul de spam.', + passwordChanged: 'Conectează-te acum', + changePassword: 'Schimbă parola', + changePasswordTip: 'Vă rugăm să introduceți o nouă parolă pentru contul dvs', + invalidToken: 'Token invalid sau expirat', + confirmPassword: 'Confirmă parola', + confirmPasswordPlaceholder: 'Confirmați noua parolă', + passwordChangedTip: 'Parola dvs. a fost schimbată cu succes', error: { emailEmpty: 'Adresa de email este obligatorie', emailInValid: 'Te rugăm să introduci o adresă de email validă', diff --git a/web/i18n/uk-UA/login.ts b/web/i18n/uk-UA/login.ts index 95bb7ccfea9ca8..46de22bec204e8 100644 --- a/web/i18n/uk-UA/login.ts +++ b/web/i18n/uk-UA/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: 'Не маєте?', invalidInvitationCode: 'Недійсний код запрошення', accountAlreadyInited: 'Обліковий запис уже ініціалізовано', + forgotPassword: 'Забули пароль?', + resetLinkSent: 'Посилання для скидання надіслано', + sendResetLink: 'Надіслати посилання для скидання', + backToSignIn: 'Повернутися до входу', + forgotPasswordDesc: 'Будь ласка, введіть свою електронну адресу, щоб скинути пароль. Ми надішлемо вам електронного листа з інструкціями щодо скидання пароля.', + checkEmailForResetLink: 'Будь ласка, перевірте свою електронну пошту на наявність посилання для скидання пароля. Якщо протягом кількох хвилин не з’явиться, перевірте папку зі спамом.', + passwordChanged: 'Увійдіть зараз', + changePassword: 'Змінити пароль', + changePasswordTip: 'Будь ласка, введіть новий пароль для свого облікового запису', + invalidToken: 'Недійсний або прострочений токен', + confirmPassword: 'Підтвердити пароль', + confirmPasswordPlaceholder: 'Підтвердьте новий пароль', + passwordChangedTip: 'Ваш пароль було успішно змінено', error: { emailEmpty: 'Адреса електронної пошти обов\'язкова', emailInValid: 'Введіть дійсну адресу електронної пошти', diff --git a/web/i18n/vi-VN/login.ts b/web/i18n/vi-VN/login.ts index b8ae56a01756fd..1fd3e55dfe1b32 100644 --- a/web/i18n/vi-VN/login.ts +++ b/web/i18n/vi-VN/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: 'Chưa có?', invalidInvitationCode: 'Mã mời không hợp lệ', accountAlreadyInited: 'Tài khoản đã được khởi tạo', + forgotPassword: 'Quên mật khẩu?', + resetLinkSent: 'Đã gửi liên kết đặt lại mật khẩu', + sendResetLink: 'Gửi liên kết đặt lại mật khẩu', + backToSignIn: 'Quay lại đăng nhập', + forgotPasswordDesc: 'Vui lòng nhập địa chỉ email của bạn để đặt lại mật khẩu. Chúng tôi sẽ gửi cho bạn một email với hướng dẫn về cách đặt lại mật khẩu.', + checkEmailForResetLink: 'Vui lòng kiểm tra email của bạn để nhận liên kết đặt lại mật khẩu. Nếu không thấy trong vài phút, hãy kiểm tra thư mục spam.', + passwordChanged: 'Đăng nhập ngay', + changePassword: 'Đổi mật khẩu', + changePasswordTip: 'Vui lòng nhập mật khẩu mới cho tài khoản của bạn', + invalidToken: 'Mã thông báo không hợp lệ hoặc đã hết hạn', + confirmPassword: 'Xác nhận mật khẩu', + confirmPasswordPlaceholder: 'Xác nhận mật khẩu mới của bạn', + passwordChangedTip: 'Mật khẩu của bạn đã được thay đổi thành công', error: { emailEmpty: 'Địa chỉ Email là bắt buộc', emailInValid: 'Vui lòng nhập một địa chỉ email hợp lệ', diff --git a/web/i18n/zh-Hans/login.ts b/web/i18n/zh-Hans/login.ts index 10c5ee44976c48..5ac9b9fcb42a88 100644 --- a/web/i18n/zh-Hans/login.ts +++ b/web/i18n/zh-Hans/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: '还没有邀请码?', invalidInvitationCode: '无效的邀请码', accountAlreadyInited: '账户已经初始化', + forgotPassword: '忘记密码?', + resetLinkSent: '重置链接已发送', + sendResetLink: '发送重置链接', + backToSignIn: '返回登录', + forgotPasswordDesc: '请输入您的电子邮件地址以重置密码。我们将向您发送一封电子邮件,包含如何重置密码的说明。', + checkEmailForResetLink: '请检查您的电子邮件以获取重置密码的链接。如果几分钟内没有收到,请检查您的垃圾邮件文件夹。', + passwordChanged: '立即登录', + changePassword: '更改密码', + changePasswordTip: '请输入您的新密码', + invalidToken: '无效或已过期的令牌', + confirmPassword: '确认密码', + confirmPasswordPlaceholder: '确认您的新密码', + passwordChangedTip: '您的密码已成功更改', error: { emailEmpty: '邮箱不能为空', emailInValid: '请输入有效的邮箱地址', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index fe38904e5b7b60..a71b22c8e0720b 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -396,6 +396,7 @@ const translation = { url: '图片链接', upload_file_id: '上传文件ID', }, + json: '工具生成的json', }, }, questionClassifiers: { diff --git a/web/i18n/zh-Hant/login.ts b/web/i18n/zh-Hant/login.ts index 3b8a986fd01e20..cce869f38a38c4 100644 --- a/web/i18n/zh-Hant/login.ts +++ b/web/i18n/zh-Hant/login.ts @@ -34,6 +34,19 @@ const translation = { donthave: '還沒有邀請碼?', invalidInvitationCode: '無效的邀請碼', accountAlreadyInited: '賬戶已經初始化', + forgotPassword: '忘記密碼?', + resetLinkSent: '重設連結已發送', + sendResetLink: '發送重設連結', + backToSignIn: '返回登錄', + forgotPasswordDesc: '請輸入您的電子郵件地址以重設密碼。我們將向您發送一封電子郵件,說明如何重設密碼。', + checkEmailForResetLink: '請檢查您的電子郵件以獲取重設密碼的連結。如果幾分鐘內沒有收到,請檢查您的垃圾郵件文件夾。', + passwordChanged: '立即登入', + changePassword: '更改密碼', + changePasswordTip: '請輸入您的新密碼', + invalidToken: '無效或已過期的令牌', + confirmPassword: '確認密碼', + confirmPasswordPlaceholder: '確認您的新密碼', + passwordChangedTip: '您的密碼已成功更改', error: { emailEmpty: '郵箱不能為空', emailInValid: '請輸入有效的郵箱地址', diff --git a/web/service/common.ts b/web/service/common.ts index a68aeb2256391b..3fbcde2a2ab3bd 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -298,3 +298,13 @@ export const enableModel = (url: string, body: { model: string; model_type: Mode export const disableModel = (url: string, body: { model: string; model_type: ModelTypeEnum }) => patch(url, { body }) + +export const sendForgotPasswordEmail: Fetcher = ({ url, body }) => + post(url, { body }) + +export const verifyForgotPasswordToken: Fetcher = ({ url, body }) => { + return post(url, { body }) as Promise +} + +export const changePasswordWithToken: Fetcher = ({ url, body }) => + post(url, { body })