| @@ -1,6 +1,6 @@ | |||
| from typing import Optional | |||
| from pydantic import AliasChoices, Field, NegativeInt, NonNegativeInt, PositiveInt, computed_field | |||
| from pydantic import AliasChoices, Field, HttpUrl, NegativeInt, NonNegativeInt, PositiveInt, computed_field | |||
| from pydantic_settings import BaseSettings | |||
| from configs.feature.hosted_service import HostedServiceConfig | |||
| @@ -45,7 +45,7 @@ class CodeExecutionSandboxConfig(BaseSettings): | |||
| Code Execution Sandbox configs | |||
| """ | |||
| CODE_EXECUTION_ENDPOINT: str = Field( | |||
| CODE_EXECUTION_ENDPOINT: HttpUrl = Field( | |||
| description="endpoint URL of code execution servcie", | |||
| default="http://sandbox:8194", | |||
| ) | |||
| @@ -55,6 +55,21 @@ class CodeExecutionSandboxConfig(BaseSettings): | |||
| default="dify-sandbox", | |||
| ) | |||
| CODE_EXECUTION_CONNECT_TIMEOUT: Optional[float] = Field( | |||
| description="connect timeout in seconds for code execution request", | |||
| default=10.0, | |||
| ) | |||
| CODE_EXECUTION_READ_TIMEOUT: Optional[float] = Field( | |||
| description="read timeout in seconds for code execution request", | |||
| default=60.0, | |||
| ) | |||
| CODE_EXECUTION_WRITE_TIMEOUT: Optional[float] = Field( | |||
| description="write timeout in seconds for code execution request", | |||
| default=10.0, | |||
| ) | |||
| CODE_MAX_NUMBER: PositiveInt = Field( | |||
| description="max depth for code execution", | |||
| default=9223372036854775807, | |||
| @@ -15,12 +15,6 @@ from core.helper.code_executor.template_transformer import TemplateTransformer | |||
| logger = logging.getLogger(__name__) | |||
| # Code Executor | |||
| CODE_EXECUTION_ENDPOINT = dify_config.CODE_EXECUTION_ENDPOINT | |||
| CODE_EXECUTION_API_KEY = dify_config.CODE_EXECUTION_API_KEY | |||
| CODE_EXECUTION_TIMEOUT = Timeout(connect=10, write=10, read=60, pool=None) | |||
| class CodeExecutionException(Exception): | |||
| pass | |||
| @@ -71,10 +65,10 @@ class CodeExecutor: | |||
| :param code: code | |||
| :return: | |||
| """ | |||
| url = URL(CODE_EXECUTION_ENDPOINT) / 'v1' / 'sandbox' / 'run' | |||
| url = URL(str(dify_config.CODE_EXECUTION_ENDPOINT)) / 'v1' / 'sandbox' / 'run' | |||
| headers = { | |||
| 'X-Api-Key': CODE_EXECUTION_API_KEY | |||
| 'X-Api-Key': dify_config.CODE_EXECUTION_API_KEY | |||
| } | |||
| data = { | |||
| @@ -85,7 +79,12 @@ class CodeExecutor: | |||
| } | |||
| try: | |||
| response = post(str(url), json=data, headers=headers, timeout=CODE_EXECUTION_TIMEOUT) | |||
| response = post(str(url), json=data, headers=headers, | |||
| timeout=Timeout( | |||
| connect=dify_config.CODE_EXECUTION_CONNECT_TIMEOUT, | |||
| read=dify_config.CODE_EXECUTION_READ_TIMEOUT, | |||
| write=dify_config.CODE_EXECUTION_WRITE_TIMEOUT, | |||
| pool=None)) | |||
| if response.status_code == 503: | |||
| raise CodeExecutionException('Code execution service is unavailable') | |||
| elif response.status_code != 200: | |||
| @@ -96,7 +95,7 @@ class CodeExecutor: | |||
| raise CodeExecutionException('Failed to execute code, which is likely a network issue,' | |||
| ' please check if the sandbox service is running.' | |||
| f' ( Error: {str(e)} )') | |||
| try: | |||
| response = response.json() | |||
| except: | |||
| @@ -104,12 +103,12 @@ class CodeExecutor: | |||
| if (code := response.get('code')) != 0: | |||
| raise CodeExecutionException(f"Got error code: {code}. Got error msg: {response.get('message')}") | |||
| response = CodeExecutionResponse(**response) | |||
| if response.data.error: | |||
| raise CodeExecutionException(response.data.error) | |||
| return response.data.stdout or '' | |||
| @classmethod | |||
| @@ -133,4 +132,3 @@ class CodeExecutor: | |||
| raise e | |||
| return template_transformer.transform_response(response) | |||
| @@ -6821,13 +6821,13 @@ files = [ | |||
| [[package]] | |||
| name = "pytest" | |||
| version = "8.1.2" | |||
| version = "8.3.2" | |||
| description = "pytest: simple powerful testing with Python" | |||
| optional = false | |||
| python-versions = ">=3.8" | |||
| files = [ | |||
| {file = "pytest-8.1.2-py3-none-any.whl", hash = "sha256:6c06dc309ff46a05721e6fd48e492a775ed8165d2ecdf57f156a80c7e95bb142"}, | |||
| {file = "pytest-8.1.2.tar.gz", hash = "sha256:f3c45d1d5eed96b01a2aea70dee6a4a366d51d38f9957768083e4fecfc77f3ef"}, | |||
| {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, | |||
| {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, | |||
| ] | |||
| [package.dependencies] | |||
| @@ -6835,11 +6835,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} | |||
| exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} | |||
| iniconfig = "*" | |||
| packaging = "*" | |||
| pluggy = ">=1.4,<2.0" | |||
| pluggy = ">=1.5,<2" | |||
| tomli = {version = ">=1", markers = "python_version < \"3.11\""} | |||
| [package.extras] | |||
| testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] | |||
| dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] | |||
| [[package]] | |||
| name = "pytest-benchmark" | |||
| @@ -10063,4 +10063,4 @@ cffi = ["cffi (>=1.11)"] | |||
| [metadata] | |||
| lock-version = "2.0" | |||
| python-versions = ">=3.10,<3.13" | |||
| content-hash = "0b912a7d500c4ff3c7f0c51877e55de70cec5317a990f9e882600e32a30a610e" | |||
| content-hash = "e4c00268514d26bd07c6b72925e0e3b4558ec972895d252e60e9571e3ac38895" | |||
| @@ -243,7 +243,7 @@ optional = true | |||
| [tool.poetry.group.dev.dependencies] | |||
| coverage = "~7.2.4" | |||
| pytest = "~8.1.1" | |||
| pytest = "~8.3.2" | |||
| pytest-benchmark = "~4.0.0" | |||
| pytest-env = "~1.1.3" | |||
| pytest-mock = "~3.14.0" | |||
| @@ -3,6 +3,7 @@ from textwrap import dedent | |||
| import pytest | |||
| from flask import Flask | |||
| from yarl import URL | |||
| from configs.app_config import DifyConfig | |||
| @@ -84,3 +85,6 @@ def test_flask_configs(example_env_file): | |||
| assert config["CONSOLE_WEB_URL"] == "https://example.com" | |||
| assert config["CONSOLE_CORS_ALLOW_ORIGINS"] == ["https://example.com"] | |||
| assert config["WEB_API_CORS_ALLOW_ORIGINS"] == ["*"] | |||
| assert str(config["CODE_EXECUTION_ENDPOINT"]) == "http://sandbox:8194/" | |||
| assert str(URL(str(config["CODE_EXECUTION_ENDPOINT"])) / "v1") == "http://sandbox:8194/v1" | |||