Skip to content

Commit 896998e

Browse files
chore: refine python dependency list and check dependencies in order (#9061)
1 parent 4abca86 commit 896998e

File tree

7 files changed

+112
-36
lines changed

7 files changed

+112
-36
lines changed

.github/workflows/api-tests.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,17 @@ jobs:
3939
api/pyproject.toml
4040
api/poetry.lock
4141
42-
- name: Poetry check
42+
- name: Check Poetry lockfile
4343
run: |
4444
poetry check -C api --lock
4545
poetry show -C api
4646
4747
- name: Install dependencies
4848
run: poetry install -C api --with dev
4949

50+
- name: Check dependencies in pyproject.toml
51+
run: poetry run -C api bash dev/pytest/pytest_artifacts.sh
52+
5053
- name: Run Unit tests
5154
run: poetry run -C api bash dev/pytest/pytest_unit_tests.sh
5255

api/poetry.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/pyproject.toml

+39-34
Original file line numberDiff line numberDiff line change
@@ -104,33 +104,31 @@ name = "dify-api"
104104
package-mode = false
105105

106106
############################################################
107-
# Main dependencies
107+
# [ Main ] Dependency group
108108
############################################################
109109

110110
[tool.poetry.dependencies]
111111
anthropic = "~0.23.1"
112112
authlib = "1.3.1"
113+
azure-ai-inference = "~1.0.0b3"
114+
azure-ai-ml = "~1.20.0"
113115
azure-identity = "1.16.1"
114116
azure-storage-blob = "12.13.0"
115117
beautifulsoup4 = "4.12.2"
116118
boto3 = "1.35.17"
117-
sagemaker = "2.231.0"
118119
bs4 = "~0.0.1"
119120
cachetools = "~5.3.0"
120121
celery = "~5.3.6"
121122
chardet = "~5.1.0"
122123
cohere = "~5.2.4"
123-
cos-python-sdk-v5 = "1.9.30"
124-
esdk-obs-python = "3.24.6.1"
125-
bce-python-sdk = "~0.9.23"
126124
dashscope = { version = "~1.17.0", extras = ["tokenizer"] }
127125
flask = "~3.0.1"
128126
flask-compress = "~1.14"
129127
flask-cors = "~4.0.0"
130128
flask-login = "~0.6.3"
131129
flask-migrate = "~4.0.5"
132130
flask-restful = "~0.3.10"
133-
Flask-SQLAlchemy = "~3.1.1"
131+
flask-sqlalchemy = "~3.1.1"
134132
gevent = "~23.9.1"
135133
gmpy2 = "~2.2.1"
136134
google-ai-generativelanguage = "0.6.9"
@@ -139,22 +137,22 @@ google-api-python-client = "2.90.0"
139137
google-auth = "2.29.0"
140138
google-auth-httplib2 = "0.2.0"
141139
google-cloud-aiplatform = "1.49.0"
142-
google-cloud-storage = "2.16.0"
143140
google-generativeai = "0.8.1"
144141
googleapis-common-protos = "1.63.0"
145142
gunicorn = "~22.0.0"
146143
httpx = { version = "~0.27.0", extras = ["socks"] }
147144
huggingface-hub = "~0.16.4"
148145
jieba = "0.42.1"
149-
langfuse = "^2.48.0"
150-
langsmith = "^0.1.77"
146+
langfuse = "~2.51.3"
147+
langsmith = "~0.1.77"
151148
mailchimp-transactional = "~1.0.50"
152149
markdown = "~3.5.1"
153-
novita-client = "^0.5.7"
150+
nomic = "~3.1.2"
151+
novita-client = "~0.5.7"
154152
numpy = "~1.26.4"
153+
oci = "~2.135.1"
155154
openai = "~1.29.0"
156155
openpyxl = "~3.1.5"
157-
oss2 = "2.18.5"
158156
pandas = { version = "~2.2.2", extras = ["performance", "excel"] }
159157
psycopg2-binary = "~2.9.6"
160158
pycryptodome = "3.19.1"
@@ -171,14 +169,17 @@ readabilipy = "0.2.0"
171169
redis = { version = "~5.0.3", extras = ["hiredis"] }
172170
replicate = "~0.22.0"
173171
resend = "~0.7.0"
174-
scikit-learn = "^1.5.1"
172+
sagemaker = "2.231.0"
173+
scikit-learn = "~1.5.1"
175174
sentry-sdk = { version = "~1.44.1", extras = ["flask"] }
176175
sqlalchemy = "~2.0.29"
177176
tencentcloud-sdk-python-hunyuan = "~3.0.1158"
178177
tiktoken = "~0.7.0"
179178
tokenizers = "~0.15.0"
180179
transformers = "~4.35.0"
181180
unstructured = { version = "~0.10.27", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] }
181+
validators = "0.21.0"
182+
volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"}
182183
websocket-client = "~1.7.0"
183184
werkzeug = "~3.0.1"
184185
xinference-client = "0.15.2"
@@ -187,44 +188,50 @@ zhipuai = "1.0.7"
187188
# Before adding new dependency, consider place it in alphabet order (a-z) and suitable group.
188189

189190
############################################################
191+
# [ Indirect ] dependency group
190192
# Related transparent dependencies with pinned version
191193
# required by main implementations
192194
############################################################
193-
azure-ai-ml = "^1.19.0"
194-
azure-ai-inference = "^1.0.0b3"
195-
volcengine-python-sdk = {extras = ["ark"], version = "^1.0.98"}
196-
oci = "^2.133.0"
197-
tos = "^2.7.1"
198-
nomic = "^3.1.2"
199-
validators = "0.21.0"
200-
[tool.poetry.group.indriect.dependencies]
195+
[tool.poetry.group.indirect.dependencies]
201196
kaleido = "0.2.1"
202197
rank-bm25 = "~0.2.2"
203198
safetensors = "~0.4.3"
204199

205200
############################################################
206-
# Tool dependencies required by tool implementations
201+
# [ Tools ] dependency group
207202
############################################################
208-
209-
[tool.poetry.group.tool.dependencies]
203+
[tool.poetry.group.tools.dependencies]
210204
arxiv = "2.1.0"
211205
cloudscraper = "1.2.71"
212-
matplotlib = "~3.8.2"
213-
newspaper3k = "0.2.8"
214206
duckduckgo-search = "~6.3.0"
215207
jsonpath-ng = "1.6.1"
208+
matplotlib = "~3.8.2"
209+
newspaper3k = "0.2.8"
210+
nltk = "3.8.1"
216211
numexpr = "~2.9.0"
217212
opensearch-py = "2.4.0"
218213
qrcode = "~7.4.2"
219214
twilio = "~9.0.4"
220215
vanna = { version = "0.5.5", extras = ["postgres", "mysql", "clickhouse", "duckdb"] }
221216
wikipedia = "1.4.0"
222217
yfinance = "~0.2.40"
223-
nltk = "3.8.1"
218+
224219
############################################################
225-
# VDB dependencies required by vector store clients
220+
# [ Storage ] dependency group
221+
# Required for storage clients
226222
############################################################
223+
[tool.poetry.group.storage.dependencies]
224+
bce-python-sdk = "~0.9.23"
225+
cos-python-sdk-v5 = "1.9.30"
226+
esdk-obs-python = "3.24.6.1"
227+
google-cloud-storage = "2.16.0"
228+
oss2 = "2.18.5"
229+
tos = "~2.7.1"
227230

231+
############################################################
232+
# [ VDB ] dependency group
233+
# Required by vector store clients
234+
############################################################
228235
[tool.poetry.group.vdb.dependencies]
229236
alibabacloud_gpdb20160503 = "~3.8.0"
230237
alibabacloud_tea_openapi = "~0.3.9"
@@ -235,18 +242,17 @@ oracledb = "~2.2.1"
235242
pgvecto-rs = { version = "~0.2.1", extras = ['sqlalchemy'] }
236243
pgvector = "0.2.5"
237244
pymilvus = "~2.4.4"
245+
qdrant-client = "1.7.3"
238246
tcvectordb = "1.3.2"
239247
tidb-vector = "0.0.9"
240-
qdrant-client = "1.7.3"
241248
weaviate-client = "~3.21.0"
242249

243250
############################################################
244-
# Dev dependencies for running tests
251+
# [ Dev ] dependency group
252+
# Required for development and running tests
245253
############################################################
246-
247254
[tool.poetry.group.dev]
248255
optional = true
249-
250256
[tool.poetry.group.dev.dependencies]
251257
coverage = "~7.2.4"
252258
pytest = "~8.3.2"
@@ -255,12 +261,11 @@ pytest-env = "~1.1.3"
255261
pytest-mock = "~3.14.0"
256262

257263
############################################################
258-
# Lint dependencies for code style linting
264+
# [ Lint ] dependency group
265+
# Required for code style linting
259266
############################################################
260-
261267
[tool.poetry.group.lint]
262268
optional = true
263-
264269
[tool.poetry.group.lint.dependencies]
265270
dotenv-linter = "~0.5.0"
266271
ruff = "~0.6.9"

api/tests/artifact_tests/dependencies/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from typing import Any
2+
3+
import toml
4+
5+
ALL_DEPENDENCY_GROUP_NAMES = [
6+
# default main group
7+
"",
8+
# required groups
9+
"indirect",
10+
"storage",
11+
"tools",
12+
"vdb",
13+
# optional groups
14+
"dev",
15+
"lint",
16+
]
17+
18+
19+
def load_api_poetry_configs() -> dict[str, Any]:
20+
pyproject_toml = toml.load("api/pyproject.toml")
21+
return pyproject_toml.get("tool").get("poetry")
22+
23+
24+
def load_dependency_groups() -> dict[str, dict[str, dict[str, Any]]]:
25+
poetry_configs = load_api_poetry_configs()
26+
group_name_to_dependencies = {
27+
group_name: (poetry_configs.get("group").get(group_name) if group_name else poetry_configs).get("dependencies")
28+
for group_name in ALL_DEPENDENCY_GROUP_NAMES
29+
}
30+
return group_name_to_dependencies
31+
32+
33+
def test_group_dependencies_sorted():
34+
for group_name, dependencies in load_dependency_groups().items():
35+
dependency_names = list(dependencies.keys())
36+
expected_dependency_names = sorted(set(dependency_names))
37+
section = f"tool.poetry.group.{group_name}.dependencies" if group_name else "tool.poetry.dependencies"
38+
assert expected_dependency_names == dependency_names, (
39+
f"Dependencies in group {group_name} are not sorted. "
40+
f"Check and fix [{section}] section in pyproject.toml file"
41+
)
42+
43+
44+
def test_group_dependencies_version_operator():
45+
for group_name, dependencies in load_dependency_groups().items():
46+
for dependency_name, specification in dependencies.items():
47+
version_spec = specification if isinstance(specification, str) else specification.get("version")
48+
assert not version_spec.startswith("^"), (
49+
f"'^' is not allowed in dependency version," f" but found in '{dependency_name} = {version_spec}'"
50+
)
51+
52+
53+
def test_duplicated_dependency_crossing_groups():
54+
all_dependency_names: list[str] = []
55+
for dependencies in load_dependency_groups().values():
56+
dependency_names = list(dependencies.keys())
57+
all_dependency_names.extend(dependency_names)
58+
expected_all_dependency_names = set(all_dependency_names)
59+
assert sorted(expected_all_dependency_names) == sorted(
60+
all_dependency_names
61+
), "Duplicated dependencies crossing groups are found"

dev/pytest/pytest_artifacts.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
set -x
3+
4+
pytest api/tests/artifact_tests/

dev/sync-poetry

+3
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@ poetry check -C api --lock
1111
if [ $? -ne 0 ]; then
1212
# update poetry.lock
1313
# refreshing lockfile only without updating locked versions
14+
echo "poetry.lock is outdated, refreshing without updating locked versions ..."
1415
poetry lock -C api --no-update
16+
else
17+
echo "poetry.lock is ready."
1518
fi

0 commit comments

Comments
 (0)