refactor: define the Dify project version in pyproject.toml (#20910)
This commit is contained in:
8
.github/workflows/api-tests.yml
vendored
8
.github/workflows/api-tests.yml
vendored
@@ -47,15 +47,17 @@ jobs:
|
|||||||
- name: Run Unit tests
|
- name: Run Unit tests
|
||||||
run: |
|
run: |
|
||||||
uv run --project api bash dev/pytest/pytest_unit_tests.sh
|
uv run --project api bash dev/pytest/pytest_unit_tests.sh
|
||||||
|
|
||||||
|
- name: Coverage Summary
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
# Extract coverage percentage and create a summary
|
# Extract coverage percentage and create a summary
|
||||||
TOTAL_COVERAGE=$(python -c 'import json; print(json.load(open("coverage.json"))["totals"]["percent_covered_display"])')
|
TOTAL_COVERAGE=$(python -c 'import json; print(json.load(open("coverage.json"))["totals"]["percent_covered_display"])')
|
||||||
|
|
||||||
# Create a detailed coverage summary
|
# Create a detailed coverage summary
|
||||||
echo "### Test Coverage Summary :test_tube:" >> $GITHUB_STEP_SUMMARY
|
echo "### Test Coverage Summary :test_tube:" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "Total Coverage: ${TOTAL_COVERAGE}%" >> $GITHUB_STEP_SUMMARY
|
echo "Total Coverage: ${TOTAL_COVERAGE}%" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
uv run --project api coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
|
||||||
uv run --project api coverage report >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|
||||||
- name: Run dify config tests
|
- name: Run dify config tests
|
||||||
run: uv run --project api dev/pytest/pytest_config_tests.py
|
run: uv run --project api dev/pytest/pytest_config_tests.py
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from pydantic.fields import FieldInfo
|
from pydantic.fields import FieldInfo
|
||||||
from pydantic_settings import BaseSettings, PydanticBaseSettingsSource, SettingsConfigDict
|
from pydantic_settings import BaseSettings, PydanticBaseSettingsSource, SettingsConfigDict, TomlConfigSettingsSource
|
||||||
|
|
||||||
|
from libs.file_utils import search_file_upwards
|
||||||
|
|
||||||
from .deploy import DeploymentConfig
|
from .deploy import DeploymentConfig
|
||||||
from .enterprise import EnterpriseFeatureConfig
|
from .enterprise import EnterpriseFeatureConfig
|
||||||
@@ -99,4 +102,12 @@ class DifyConfig(
|
|||||||
RemoteSettingsSourceFactory(settings_cls),
|
RemoteSettingsSourceFactory(settings_cls),
|
||||||
dotenv_settings,
|
dotenv_settings,
|
||||||
file_secret_settings,
|
file_secret_settings,
|
||||||
|
TomlConfigSettingsSource(
|
||||||
|
settings_cls=settings_cls,
|
||||||
|
toml_file=search_file_upwards(
|
||||||
|
base_dir_path=Path(__file__).parent,
|
||||||
|
target_file_name="pyproject.toml",
|
||||||
|
max_search_parent_depth=2,
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from pydantic_settings import BaseSettings
|
|
||||||
|
from configs.packaging.pyproject import PyProjectConfig, PyProjectTomlConfig
|
||||||
|
|
||||||
|
|
||||||
class PackagingInfo(BaseSettings):
|
class PackagingInfo(PyProjectTomlConfig):
|
||||||
"""
|
"""
|
||||||
Packaging build information
|
Packaging build information
|
||||||
"""
|
"""
|
||||||
|
17
api/configs/packaging/pyproject.py
Normal file
17
api/configs/packaging/pyproject.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from pydantic_settings import BaseSettings
|
||||||
|
|
||||||
|
|
||||||
|
class PyProjectConfig(BaseModel):
|
||||||
|
version: str = Field(description="Dify version", default="")
|
||||||
|
|
||||||
|
|
||||||
|
class PyProjectTomlConfig(BaseSettings):
|
||||||
|
"""
|
||||||
|
configs in api/pyproject.toml
|
||||||
|
"""
|
||||||
|
|
||||||
|
project: PyProjectConfig = Field(
|
||||||
|
description="configs in the project section of pyproject.toml",
|
||||||
|
default=PyProjectConfig(),
|
||||||
|
)
|
@@ -18,7 +18,7 @@ class VersionApi(Resource):
|
|||||||
check_update_url = dify_config.CHECK_UPDATE_URL
|
check_update_url = dify_config.CHECK_UPDATE_URL
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"version": dify_config.CURRENT_VERSION,
|
"version": dify_config.project.version,
|
||||||
"release_date": "",
|
"release_date": "",
|
||||||
"release_notes": "",
|
"release_notes": "",
|
||||||
"can_auto_update": False,
|
"can_auto_update": False,
|
||||||
|
@@ -9,7 +9,7 @@ class IndexApi(Resource):
|
|||||||
return {
|
return {
|
||||||
"welcome": "Dify OpenAPI",
|
"welcome": "Dify OpenAPI",
|
||||||
"api_version": "v1",
|
"api_version": "v1",
|
||||||
"server_version": dify_config.CURRENT_VERSION,
|
"server_version": dify_config.project.version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -12,14 +12,14 @@ def init_app(app: DifyApp):
|
|||||||
@app.after_request
|
@app.after_request
|
||||||
def after_request(response):
|
def after_request(response):
|
||||||
"""Add Version headers to the response."""
|
"""Add Version headers to the response."""
|
||||||
response.headers.add("X-Version", dify_config.CURRENT_VERSION)
|
response.headers.add("X-Version", dify_config.project.version)
|
||||||
response.headers.add("X-Env", dify_config.DEPLOY_ENV)
|
response.headers.add("X-Env", dify_config.DEPLOY_ENV)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@app.route("/health")
|
@app.route("/health")
|
||||||
def health():
|
def health():
|
||||||
return Response(
|
return Response(
|
||||||
json.dumps({"pid": os.getpid(), "status": "ok", "version": dify_config.CURRENT_VERSION}),
|
json.dumps({"pid": os.getpid(), "status": "ok", "version": dify_config.project.version}),
|
||||||
status=200,
|
status=200,
|
||||||
content_type="application/json",
|
content_type="application/json",
|
||||||
)
|
)
|
||||||
|
@@ -49,7 +49,7 @@ def init_app(app: DifyApp):
|
|||||||
logging.getLogger().addHandler(exception_handler)
|
logging.getLogger().addHandler(exception_handler)
|
||||||
|
|
||||||
def init_flask_instrumentor(app: DifyApp):
|
def init_flask_instrumentor(app: DifyApp):
|
||||||
meter = get_meter("http_metrics", version=dify_config.CURRENT_VERSION)
|
meter = get_meter("http_metrics", version=dify_config.project.version)
|
||||||
_http_response_counter = meter.create_counter(
|
_http_response_counter = meter.create_counter(
|
||||||
"http.server.response.count",
|
"http.server.response.count",
|
||||||
description="Total number of HTTP responses by status code, method and target",
|
description="Total number of HTTP responses by status code, method and target",
|
||||||
@@ -163,7 +163,7 @@ def init_app(app: DifyApp):
|
|||||||
resource = Resource(
|
resource = Resource(
|
||||||
attributes={
|
attributes={
|
||||||
ResourceAttributes.SERVICE_NAME: dify_config.APPLICATION_NAME,
|
ResourceAttributes.SERVICE_NAME: dify_config.APPLICATION_NAME,
|
||||||
ResourceAttributes.SERVICE_VERSION: f"dify-{dify_config.CURRENT_VERSION}-{dify_config.COMMIT_SHA}",
|
ResourceAttributes.SERVICE_VERSION: f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}",
|
||||||
ResourceAttributes.PROCESS_PID: os.getpid(),
|
ResourceAttributes.PROCESS_PID: os.getpid(),
|
||||||
ResourceAttributes.DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}",
|
ResourceAttributes.DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}",
|
||||||
ResourceAttributes.HOST_NAME: socket.gethostname(),
|
ResourceAttributes.HOST_NAME: socket.gethostname(),
|
||||||
|
@@ -35,6 +35,6 @@ def init_app(app: DifyApp):
|
|||||||
traces_sample_rate=dify_config.SENTRY_TRACES_SAMPLE_RATE,
|
traces_sample_rate=dify_config.SENTRY_TRACES_SAMPLE_RATE,
|
||||||
profiles_sample_rate=dify_config.SENTRY_PROFILES_SAMPLE_RATE,
|
profiles_sample_rate=dify_config.SENTRY_PROFILES_SAMPLE_RATE,
|
||||||
environment=dify_config.DEPLOY_ENV,
|
environment=dify_config.DEPLOY_ENV,
|
||||||
release=f"dify-{dify_config.CURRENT_VERSION}-{dify_config.COMMIT_SHA}",
|
release=f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}",
|
||||||
before_send=before_send,
|
before_send=before_send,
|
||||||
)
|
)
|
||||||
|
30
api/libs/file_utils.py
Normal file
30
api/libs/file_utils.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def search_file_upwards(
|
||||||
|
base_dir_path: Path,
|
||||||
|
target_file_name: str,
|
||||||
|
max_search_parent_depth: int,
|
||||||
|
) -> Path:
|
||||||
|
"""
|
||||||
|
Find a target file in the current directory or its parent directories up to a specified depth.
|
||||||
|
:param base_dir_path: Starting directory path to search from.
|
||||||
|
:param target_file_name: Name of the file to search for.
|
||||||
|
:param max_search_parent_depth: Maximum number of parent directories to search upwards.
|
||||||
|
:return: Path of the file if found, otherwise None.
|
||||||
|
"""
|
||||||
|
current_path = base_dir_path.resolve()
|
||||||
|
for _ in range(max_search_parent_depth):
|
||||||
|
candidate_path = current_path / target_file_name
|
||||||
|
if candidate_path.is_file():
|
||||||
|
return candidate_path
|
||||||
|
parent_path = current_path.parent
|
||||||
|
if parent_path == current_path: # reached the root directory
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
current_path = parent_path
|
||||||
|
|
||||||
|
raise ValueError(
|
||||||
|
f"File '{target_file_name}' not found in the directory '{base_dir_path.resolve()}' or its parent directories"
|
||||||
|
f" in depth of {max_search_parent_depth}."
|
||||||
|
)
|
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "dify-api"
|
name = "dify-api"
|
||||||
dynamic = ["version"]
|
version = "1.4.3"
|
||||||
requires-python = ">=3.11,<3.13"
|
requires-python = ">=3.11,<3.13"
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
@@ -889,7 +889,7 @@ class RegisterService:
|
|||||||
|
|
||||||
TenantService.create_owner_tenant_if_not_exist(account=account, is_setup=True)
|
TenantService.create_owner_tenant_if_not_exist(account=account, is_setup=True)
|
||||||
|
|
||||||
dify_setup = DifySetup(version=dify_config.CURRENT_VERSION)
|
dify_setup = DifySetup(version=dify_config.project.version)
|
||||||
db.session.add(dify_setup)
|
db.session.add(dify_setup)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
1
api/uv.lock
generated
1
api/uv.lock
generated
@@ -1198,6 +1198,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dify-api"
|
name = "dify-api"
|
||||||
|
version = "1.4.3"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "authlib" },
|
{ name = "authlib" },
|
||||||
|
Reference in New Issue
Block a user