Skip to content

Commit 56e15d0

Browse files
authored
feat: mypy for all type check (#10921)
1 parent c91e8b1 commit 56e15d0

File tree

584 files changed

+3980
-2831
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

584 files changed

+3980
-2831
lines changed

Diff for: .github/workflows/api-tests.yml

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ jobs:
5656
- name: Run Tool
5757
run: poetry run -C api bash dev/pytest/pytest_tools.sh
5858

59+
- name: Run mypy
60+
run: |
61+
pushd api
62+
poetry run python -m mypy --install-types --non-interactive .
63+
popd
64+
5965
- name: Set up dotenvs
6066
run: |
6167
cp docker/.env.example docker/.env

Diff for: api/commands.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,7 @@ def migrate_annotation_vector_database():
159159
try:
160160
# get apps info
161161
apps = (
162-
db.session.query(App)
163-
.filter(App.status == "normal")
162+
App.query.filter(App.status == "normal")
164163
.order_by(App.created_at.desc())
165164
.paginate(page=page, per_page=50)
166165
)
@@ -285,8 +284,7 @@ def migrate_knowledge_vector_database():
285284
while True:
286285
try:
287286
datasets = (
288-
db.session.query(Dataset)
289-
.filter(Dataset.indexing_technique == "high_quality")
287+
Dataset.query.filter(Dataset.indexing_technique == "high_quality")
290288
.order_by(Dataset.created_at.desc())
291289
.paginate(page=page, per_page=50)
292290
)
@@ -450,7 +448,8 @@ def convert_to_agent_apps():
450448
if app_id not in proceeded_app_ids:
451449
proceeded_app_ids.append(app_id)
452450
app = db.session.query(App).filter(App.id == app_id).first()
453-
apps.append(app)
451+
if app is not None:
452+
apps.append(app)
454453

455454
if len(apps) == 0:
456455
break
@@ -621,6 +620,10 @@ def fix_app_site_missing():
621620

622621
try:
623622
app = db.session.query(App).filter(App.id == app_id).first()
623+
if not app:
624+
print(f"App {app_id} not found")
625+
continue
626+
624627
tenant = app.tenant
625628
if tenant:
626629
accounts = tenant.get_accounts()

Diff for: api/configs/feature/__init__.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ class HttpConfig(BaseSettings):
239239
)
240240

241241
@computed_field
242-
@property
243242
def CONSOLE_CORS_ALLOW_ORIGINS(self) -> list[str]:
244243
return self.inner_CONSOLE_CORS_ALLOW_ORIGINS.split(",")
245244

@@ -250,7 +249,6 @@ def CONSOLE_CORS_ALLOW_ORIGINS(self) -> list[str]:
250249
)
251250

252251
@computed_field
253-
@property
254252
def WEB_API_CORS_ALLOW_ORIGINS(self) -> list[str]:
255253
return self.inner_WEB_API_CORS_ALLOW_ORIGINS.split(",")
256254

@@ -715,27 +713,27 @@ class PositionConfig(BaseSettings):
715713
default="",
716714
)
717715

718-
@computed_field
716+
@property
719717
def POSITION_PROVIDER_PINS_LIST(self) -> list[str]:
720718
return [item.strip() for item in self.POSITION_PROVIDER_PINS.split(",") if item.strip() != ""]
721719

722-
@computed_field
720+
@property
723721
def POSITION_PROVIDER_INCLUDES_SET(self) -> set[str]:
724722
return {item.strip() for item in self.POSITION_PROVIDER_INCLUDES.split(",") if item.strip() != ""}
725723

726-
@computed_field
724+
@property
727725
def POSITION_PROVIDER_EXCLUDES_SET(self) -> set[str]:
728726
return {item.strip() for item in self.POSITION_PROVIDER_EXCLUDES.split(",") if item.strip() != ""}
729727

730-
@computed_field
728+
@property
731729
def POSITION_TOOL_PINS_LIST(self) -> list[str]:
732730
return [item.strip() for item in self.POSITION_TOOL_PINS.split(",") if item.strip() != ""]
733731

734-
@computed_field
732+
@property
735733
def POSITION_TOOL_INCLUDES_SET(self) -> set[str]:
736734
return {item.strip() for item in self.POSITION_TOOL_INCLUDES.split(",") if item.strip() != ""}
737735

738-
@computed_field
736+
@property
739737
def POSITION_TOOL_EXCLUDES_SET(self) -> set[str]:
740738
return {item.strip() for item in self.POSITION_TOOL_EXCLUDES.split(",") if item.strip() != ""}
741739

Diff for: api/configs/middleware/__init__.py

-4
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ class DatabaseConfig(BaseSettings):
130130
)
131131

132132
@computed_field
133-
@property
134133
def SQLALCHEMY_DATABASE_URI(self) -> str:
135134
db_extras = (
136135
f"{self.DB_EXTRAS}&client_encoding={self.DB_CHARSET}" if self.DB_CHARSET else self.DB_EXTRAS
@@ -168,7 +167,6 @@ def SQLALCHEMY_DATABASE_URI(self) -> str:
168167
)
169168

170169
@computed_field
171-
@property
172170
def SQLALCHEMY_ENGINE_OPTIONS(self) -> dict[str, Any]:
173171
return {
174172
"pool_size": self.SQLALCHEMY_POOL_SIZE,
@@ -206,15 +204,13 @@ class CeleryConfig(DatabaseConfig):
206204
)
207205

208206
@computed_field
209-
@property
210207
def CELERY_RESULT_BACKEND(self) -> str | None:
211208
return (
212209
"db+{}".format(self.SQLALCHEMY_DATABASE_URI)
213210
if self.CELERY_BACKEND == "database"
214211
else self.CELERY_BROKER_URL
215212
)
216213

217-
@computed_field
218214
@property
219215
def BROKER_USE_SSL(self) -> bool:
220216
return self.CELERY_BROKER_URL.startswith("rediss://") if self.CELERY_BROKER_URL else False

Diff for: api/configs/remote_settings_sources/apollo/client.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import threading
66
import time
7+
from collections.abc import Mapping
78
from pathlib import Path
89

910
from .python_3x import http_request, makedirs_wrapper
@@ -255,8 +256,8 @@ def _listener(self):
255256
logger.info("stopped, long_poll")
256257

257258
# add the need for endorsement to the header
258-
def _sign_headers(self, url):
259-
headers = {}
259+
def _sign_headers(self, url: str) -> Mapping[str, str]:
260+
headers: dict[str, str] = {}
260261
if self.secret == "":
261262
return headers
262263
uri = url[len(self.config_url) : len(url)]

Diff for: api/constants/model_template.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import json
2+
from collections.abc import Mapping
23

34
from models.model import AppMode
45

5-
default_app_templates = {
6+
default_app_templates: Mapping[AppMode, Mapping] = {
67
# workflow default mode
78
AppMode.WORKFLOW: {
89
"app": {

Diff for: api/controllers/common/fields.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from flask_restful import fields
1+
from flask_restful import fields # type: ignore
22

33
parameters__system_parameters = {
44
"image_file_size_limit": fields.Integer,

Diff for: api/controllers/console/__init__.py

+90-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@
33
from libs.external_api import ExternalApi
44

55
from .app.app_import import AppImportApi, AppImportConfirmApi
6+
from .explore.audio import ChatAudioApi, ChatTextApi
7+
from .explore.completion import ChatApi, ChatStopApi, CompletionApi, CompletionStopApi
8+
from .explore.conversation import (
9+
ConversationApi,
10+
ConversationListApi,
11+
ConversationPinApi,
12+
ConversationRenameApi,
13+
ConversationUnPinApi,
14+
)
15+
from .explore.message import (
16+
MessageFeedbackApi,
17+
MessageListApi,
18+
MessageMoreLikeThisApi,
19+
MessageSuggestedQuestionApi,
20+
)
21+
from .explore.workflow import (
22+
InstalledAppWorkflowRunApi,
23+
InstalledAppWorkflowTaskStopApi,
24+
)
625
from .files import FileApi, FilePreviewApi, FileSupportTypeApi
726
from .remote_files import RemoteFileInfoApi, RemoteFileUploadApi
827

@@ -66,15 +85,81 @@
6685

6786
# Import explore controllers
6887
from .explore import (
69-
audio,
70-
completion,
71-
conversation,
7288
installed_app,
73-
message,
7489
parameter,
7590
recommended_app,
7691
saved_message,
77-
workflow,
92+
)
93+
94+
# Explore Audio
95+
api.add_resource(ChatAudioApi, "/installed-apps/<uuid:installed_app_id>/audio-to-text", endpoint="installed_app_audio")
96+
api.add_resource(ChatTextApi, "/installed-apps/<uuid:installed_app_id>/text-to-audio", endpoint="installed_app_text")
97+
98+
# Explore Completion
99+
api.add_resource(
100+
CompletionApi, "/installed-apps/<uuid:installed_app_id>/completion-messages", endpoint="installed_app_completion"
101+
)
102+
api.add_resource(
103+
CompletionStopApi,
104+
"/installed-apps/<uuid:installed_app_id>/completion-messages/<string:task_id>/stop",
105+
endpoint="installed_app_stop_completion",
106+
)
107+
api.add_resource(
108+
ChatApi, "/installed-apps/<uuid:installed_app_id>/chat-messages", endpoint="installed_app_chat_completion"
109+
)
110+
api.add_resource(
111+
ChatStopApi,
112+
"/installed-apps/<uuid:installed_app_id>/chat-messages/<string:task_id>/stop",
113+
endpoint="installed_app_stop_chat_completion",
114+
)
115+
116+
# Explore Conversation
117+
api.add_resource(
118+
ConversationRenameApi,
119+
"/installed-apps/<uuid:installed_app_id>/conversations/<uuid:c_id>/name",
120+
endpoint="installed_app_conversation_rename",
121+
)
122+
api.add_resource(
123+
ConversationListApi, "/installed-apps/<uuid:installed_app_id>/conversations", endpoint="installed_app_conversations"
124+
)
125+
api.add_resource(
126+
ConversationApi,
127+
"/installed-apps/<uuid:installed_app_id>/conversations/<uuid:c_id>",
128+
endpoint="installed_app_conversation",
129+
)
130+
api.add_resource(
131+
ConversationPinApi,
132+
"/installed-apps/<uuid:installed_app_id>/conversations/<uuid:c_id>/pin",
133+
endpoint="installed_app_conversation_pin",
134+
)
135+
api.add_resource(
136+
ConversationUnPinApi,
137+
"/installed-apps/<uuid:installed_app_id>/conversations/<uuid:c_id>/unpin",
138+
endpoint="installed_app_conversation_unpin",
139+
)
140+
141+
142+
# Explore Message
143+
api.add_resource(MessageListApi, "/installed-apps/<uuid:installed_app_id>/messages", endpoint="installed_app_messages")
144+
api.add_resource(
145+
MessageFeedbackApi,
146+
"/installed-apps/<uuid:installed_app_id>/messages/<uuid:message_id>/feedbacks",
147+
endpoint="installed_app_message_feedback",
148+
)
149+
api.add_resource(
150+
MessageMoreLikeThisApi,
151+
"/installed-apps/<uuid:installed_app_id>/messages/<uuid:message_id>/more-like-this",
152+
endpoint="installed_app_more_like_this",
153+
)
154+
api.add_resource(
155+
MessageSuggestedQuestionApi,
156+
"/installed-apps/<uuid:installed_app_id>/messages/<uuid:message_id>/suggested-questions",
157+
endpoint="installed_app_suggested_question",
158+
)
159+
# Explore Workflow
160+
api.add_resource(InstalledAppWorkflowRunApi, "/installed-apps/<uuid:installed_app_id>/workflows/run")
161+
api.add_resource(
162+
InstalledAppWorkflowTaskStopApi, "/installed-apps/<uuid:installed_app_id>/workflows/tasks/<string:task_id>/stop"
78163
)
79164

80165
# Import tag controllers

Diff for: api/controllers/console/admin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from functools import wraps
22

33
from flask import request
4-
from flask_restful import Resource, reqparse
4+
from flask_restful import Resource, reqparse # type: ignore
55
from werkzeug.exceptions import NotFound, Unauthorized
66

77
from configs import dify_config

Diff for: api/controllers/console/apikey.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import flask_restful
2-
from flask_login import current_user
1+
from typing import Any
2+
3+
import flask_restful # type: ignore
4+
from flask_login import current_user # type: ignore
35
from flask_restful import Resource, fields, marshal_with
46
from werkzeug.exceptions import Forbidden
57

@@ -35,14 +37,15 @@ def _get_resource(resource_id, tenant_id, resource_model):
3537
class BaseApiKeyListResource(Resource):
3638
method_decorators = [account_initialization_required, login_required, setup_required]
3739

38-
resource_type = None
39-
resource_model = None
40-
resource_id_field = None
41-
token_prefix = None
40+
resource_type: str | None = None
41+
resource_model: Any = None
42+
resource_id_field: str | None = None
43+
token_prefix: str | None = None
4244
max_keys = 10
4345

4446
@marshal_with(api_key_list)
4547
def get(self, resource_id):
48+
assert self.resource_id_field is not None, "resource_id_field must be set"
4649
resource_id = str(resource_id)
4750
_get_resource(resource_id, current_user.current_tenant_id, self.resource_model)
4851
keys = (
@@ -54,6 +57,7 @@ def get(self, resource_id):
5457

5558
@marshal_with(api_key_fields)
5659
def post(self, resource_id):
60+
assert self.resource_id_field is not None, "resource_id_field must be set"
5761
resource_id = str(resource_id)
5862
_get_resource(resource_id, current_user.current_tenant_id, self.resource_model)
5963
if not current_user.is_editor:
@@ -86,11 +90,12 @@ def post(self, resource_id):
8690
class BaseApiKeyResource(Resource):
8791
method_decorators = [account_initialization_required, login_required, setup_required]
8892

89-
resource_type = None
90-
resource_model = None
91-
resource_id_field = None
93+
resource_type: str | None = None
94+
resource_model: Any = None
95+
resource_id_field: str | None = None
9296

9397
def delete(self, resource_id, api_key_id):
98+
assert self.resource_id_field is not None, "resource_id_field must be set"
9499
resource_id = str(resource_id)
95100
api_key_id = str(api_key_id)
96101
_get_resource(resource_id, current_user.current_tenant_id, self.resource_model)

Diff for: api/controllers/console/app/advanced_prompt_template.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from flask_restful import Resource, reqparse
1+
from flask_restful import Resource, reqparse # type: ignore
22

33
from controllers.console import api
44
from controllers.console.wraps import account_initialization_required, setup_required

Diff for: api/controllers/console/app/agent.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from flask_restful import Resource, reqparse
1+
from flask_restful import Resource, reqparse # type: ignore
22

33
from controllers.console import api
44
from controllers.console.app.wraps import get_app_model

Diff for: api/controllers/console/app/annotation.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from flask import request
2-
from flask_login import current_user
3-
from flask_restful import Resource, marshal, marshal_with, reqparse
2+
from flask_login import current_user # type: ignore
3+
from flask_restful import Resource, marshal, marshal_with, reqparse # type: ignore
44
from werkzeug.exceptions import Forbidden
55

66
from controllers.console import api
@@ -110,7 +110,7 @@ def get(self, app_id):
110110

111111
page = request.args.get("page", default=1, type=int)
112112
limit = request.args.get("limit", default=20, type=int)
113-
keyword = request.args.get("keyword", default=None, type=str)
113+
keyword = request.args.get("keyword", default="", type=str)
114114

115115
app_id = str(app_id)
116116
annotation_list, total = AppAnnotationService.get_annotation_list_by_app_id(app_id, page, limit, keyword)

Diff for: api/controllers/console/app/app.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import uuid
22
from typing import cast
33

4-
from flask_login import current_user
5-
from flask_restful import Resource, inputs, marshal, marshal_with, reqparse
4+
from flask_login import current_user # type: ignore
5+
from flask_restful import Resource, inputs, marshal, marshal_with, reqparse # type: ignore
66
from sqlalchemy import select
77
from sqlalchemy.orm import Session
88
from werkzeug.exceptions import BadRequest, Forbidden, abort

Diff for: api/controllers/console/app/app_import.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import cast
22

3-
from flask_login import current_user
4-
from flask_restful import Resource, marshal_with, reqparse
3+
from flask_login import current_user # type: ignore
4+
from flask_restful import Resource, marshal_with, reqparse # type: ignore
55
from sqlalchemy.orm import Session
66
from werkzeug.exceptions import Forbidden
77

0 commit comments

Comments
 (0)