Fix/replace datetime patterns with naive utc now (#22654)

This commit is contained in:
Aryan Raj 2025-07-20 08:35:53 +05:30 committed by GitHub
parent 5985055aef
commit ce794335e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 99 additions and 92 deletions

View File

@ -1,4 +1,4 @@
from datetime import UTC, datetime from datetime import datetime
import pytz # pip install pytz import pytz # pip install pytz
from flask_login import current_user from flask_login import current_user
@ -19,6 +19,7 @@ from fields.conversation_fields import (
conversation_pagination_fields, conversation_pagination_fields,
conversation_with_summary_pagination_fields, conversation_with_summary_pagination_fields,
) )
from libs.datetime_utils import naive_utc_now
from libs.helper import DatetimeString from libs.helper import DatetimeString
from libs.login import login_required from libs.login import login_required
from models import Conversation, EndUser, Message, MessageAnnotation from models import Conversation, EndUser, Message, MessageAnnotation
@ -315,7 +316,7 @@ def _get_conversation(app_model, conversation_id):
raise NotFound("Conversation Not Exists.") raise NotFound("Conversation Not Exists.")
if not conversation.read_at: if not conversation.read_at:
conversation.read_at = datetime.now(UTC).replace(tzinfo=None) conversation.read_at = naive_utc_now()
conversation.read_account_id = current_user.id conversation.read_account_id = current_user.id
db.session.commit() db.session.commit()

View File

@ -1,5 +1,3 @@
from datetime import UTC, datetime
from flask_login import current_user from flask_login import current_user
from flask_restful import Resource, marshal_with, reqparse from flask_restful import Resource, marshal_with, reqparse
from werkzeug.exceptions import Forbidden, NotFound from werkzeug.exceptions import Forbidden, NotFound
@ -10,6 +8,7 @@ from controllers.console.app.wraps import get_app_model
from controllers.console.wraps import account_initialization_required, setup_required from controllers.console.wraps import account_initialization_required, setup_required
from extensions.ext_database import db from extensions.ext_database import db
from fields.app_fields import app_site_fields from fields.app_fields import app_site_fields
from libs.datetime_utils import naive_utc_now
from libs.login import login_required from libs.login import login_required
from models import Site from models import Site
@ -77,7 +76,7 @@ class AppSite(Resource):
setattr(site, attr_name, value) setattr(site, attr_name, value)
site.updated_by = current_user.id site.updated_by = current_user.id
site.updated_at = datetime.now(UTC).replace(tzinfo=None) site.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return site return site
@ -101,7 +100,7 @@ class AppSiteAccessTokenReset(Resource):
site.code = Site.generate_code(16) site.code = Site.generate_code(16)
site.updated_by = current_user.id site.updated_by = current_user.id
site.updated_at = datetime.now(UTC).replace(tzinfo=None) site.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return site return site

View File

@ -1,5 +1,3 @@
import datetime
from flask import request from flask import request
from flask_restful import Resource, reqparse from flask_restful import Resource, reqparse
@ -7,6 +5,7 @@ from constants.languages import supported_language
from controllers.console import api from controllers.console import api
from controllers.console.error import AlreadyActivateError from controllers.console.error import AlreadyActivateError
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from libs.helper import StrLen, email, extract_remote_ip, timezone from libs.helper import StrLen, email, extract_remote_ip, timezone
from models.account import AccountStatus from models.account import AccountStatus
from services.account_service import AccountService, RegisterService from services.account_service import AccountService, RegisterService
@ -65,7 +64,7 @@ class ActivateApi(Resource):
account.timezone = args["timezone"] account.timezone = args["timezone"]
account.interface_theme = "light" account.interface_theme = "light"
account.status = AccountStatus.ACTIVE.value account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
db.session.commit() db.session.commit()
token_pair = AccountService.login(account, ip_address=extract_remote_ip(request)) token_pair = AccountService.login(account, ip_address=extract_remote_ip(request))

View File

@ -1,5 +1,4 @@
import logging import logging
from datetime import UTC, datetime
from typing import Optional from typing import Optional
import requests import requests
@ -13,6 +12,7 @@ from configs import dify_config
from constants.languages import languages from constants.languages import languages
from events.tenant_event import tenant_was_created from events.tenant_event import tenant_was_created
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from libs.helper import extract_remote_ip from libs.helper import extract_remote_ip
from libs.oauth import GitHubOAuth, GoogleOAuth, OAuthUserInfo from libs.oauth import GitHubOAuth, GoogleOAuth, OAuthUserInfo
from models import Account from models import Account
@ -110,7 +110,7 @@ class OAuthCallback(Resource):
if account.status == AccountStatus.PENDING.value: if account.status == AccountStatus.PENDING.value:
account.status = AccountStatus.ACTIVE.value account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.now(UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
db.session.commit() db.session.commit()
try: try:

View File

@ -1,4 +1,3 @@
import datetime
import json import json
from flask import request from flask import request
@ -15,6 +14,7 @@ from core.rag.extractor.entity.extract_setting import ExtractSetting
from core.rag.extractor.notion_extractor import NotionExtractor from core.rag.extractor.notion_extractor import NotionExtractor
from extensions.ext_database import db from extensions.ext_database import db
from fields.data_source_fields import integrate_list_fields, integrate_notion_info_list_fields from fields.data_source_fields import integrate_list_fields, integrate_notion_info_list_fields
from libs.datetime_utils import naive_utc_now
from libs.login import login_required from libs.login import login_required
from models import DataSourceOauthBinding, Document from models import DataSourceOauthBinding, Document
from services.dataset_service import DatasetService, DocumentService from services.dataset_service import DatasetService, DocumentService
@ -88,7 +88,7 @@ class DataSourceApi(Resource):
if action == "enable": if action == "enable":
if data_source_binding.disabled: if data_source_binding.disabled:
data_source_binding.disabled = False data_source_binding.disabled = False
data_source_binding.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data_source_binding.updated_at = naive_utc_now()
db.session.add(data_source_binding) db.session.add(data_source_binding)
db.session.commit() db.session.commit()
else: else:
@ -97,7 +97,7 @@ class DataSourceApi(Resource):
if action == "disable": if action == "disable":
if not data_source_binding.disabled: if not data_source_binding.disabled:
data_source_binding.disabled = True data_source_binding.disabled = True
data_source_binding.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data_source_binding.updated_at = naive_utc_now()
db.session.add(data_source_binding) db.session.add(data_source_binding)
db.session.commit() db.session.commit()
else: else:

View File

@ -1,6 +1,5 @@
import logging import logging
from argparse import ArgumentTypeError from argparse import ArgumentTypeError
from datetime import UTC, datetime
from typing import cast from typing import cast
from flask import request from flask import request
@ -49,6 +48,7 @@ from fields.document_fields import (
document_status_fields, document_status_fields,
document_with_segments_fields, document_with_segments_fields,
) )
from libs.datetime_utils import naive_utc_now
from libs.login import login_required from libs.login import login_required
from models import Dataset, DatasetProcessRule, Document, DocumentSegment, UploadFile from models import Dataset, DatasetProcessRule, Document, DocumentSegment, UploadFile
from services.dataset_service import DatasetService, DocumentService from services.dataset_service import DatasetService, DocumentService
@ -750,7 +750,7 @@ class DocumentProcessingApi(DocumentResource):
raise InvalidActionError("Document not in indexing state.") raise InvalidActionError("Document not in indexing state.")
document.paused_by = current_user.id document.paused_by = current_user.id
document.paused_at = datetime.now(UTC).replace(tzinfo=None) document.paused_at = naive_utc_now()
document.is_paused = True document.is_paused = True
db.session.commit() db.session.commit()
@ -830,7 +830,7 @@ class DocumentMetadataApi(DocumentResource):
document.doc_metadata[key] = value document.doc_metadata[key] = value
document.doc_type = doc_type document.doc_type = doc_type
document.updated_at = datetime.now(UTC).replace(tzinfo=None) document.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return {"result": "success", "message": "Document metadata updated."}, 200 return {"result": "success", "message": "Document metadata updated."}, 200

View File

@ -1,5 +1,4 @@
import logging import logging
from datetime import UTC, datetime
from flask_login import current_user from flask_login import current_user
from flask_restful import reqparse from flask_restful import reqparse
@ -27,6 +26,7 @@ from core.errors.error import (
from core.model_runtime.errors.invoke import InvokeError from core.model_runtime.errors.invoke import InvokeError
from extensions.ext_database import db from extensions.ext_database import db
from libs import helper from libs import helper
from libs.datetime_utils import naive_utc_now
from libs.helper import uuid_value from libs.helper import uuid_value
from models.model import AppMode from models.model import AppMode
from services.app_generate_service import AppGenerateService from services.app_generate_service import AppGenerateService
@ -51,7 +51,7 @@ class CompletionApi(InstalledAppResource):
streaming = args["response_mode"] == "streaming" streaming = args["response_mode"] == "streaming"
args["auto_generate_name"] = False args["auto_generate_name"] = False
installed_app.last_used_at = datetime.now(UTC).replace(tzinfo=None) installed_app.last_used_at = naive_utc_now()
db.session.commit() db.session.commit()
try: try:
@ -111,7 +111,7 @@ class ChatApi(InstalledAppResource):
args["auto_generate_name"] = False args["auto_generate_name"] = False
installed_app.last_used_at = datetime.now(UTC).replace(tzinfo=None) installed_app.last_used_at = naive_utc_now()
db.session.commit() db.session.commit()
try: try:

View File

@ -1,5 +1,4 @@
import logging import logging
from datetime import UTC, datetime
from typing import Any from typing import Any
from flask import request from flask import request
@ -13,6 +12,7 @@ from controllers.console.explore.wraps import InstalledAppResource
from controllers.console.wraps import account_initialization_required, cloud_edition_billing_resource_check from controllers.console.wraps import account_initialization_required, cloud_edition_billing_resource_check
from extensions.ext_database import db from extensions.ext_database import db
from fields.installed_app_fields import installed_app_list_fields from fields.installed_app_fields import installed_app_list_fields
from libs.datetime_utils import naive_utc_now
from libs.login import login_required from libs.login import login_required
from models import App, InstalledApp, RecommendedApp from models import App, InstalledApp, RecommendedApp
from services.account_service import TenantService from services.account_service import TenantService
@ -122,7 +122,7 @@ class InstalledAppsListApi(Resource):
tenant_id=current_tenant_id, tenant_id=current_tenant_id,
app_owner_tenant_id=app.tenant_id, app_owner_tenant_id=app.tenant_id,
is_pinned=False, is_pinned=False,
last_used_at=datetime.now(UTC).replace(tzinfo=None), last_used_at=naive_utc_now(),
) )
db.session.add(new_installed_app) db.session.add(new_installed_app)
db.session.commit() db.session.commit()

View File

@ -1,5 +1,3 @@
import datetime
import pytz import pytz
from flask import request from flask import request
from flask_login import current_user from flask_login import current_user
@ -35,6 +33,7 @@ from controllers.console.wraps import (
) )
from extensions.ext_database import db from extensions.ext_database import db
from fields.member_fields import account_fields from fields.member_fields import account_fields
from libs.datetime_utils import naive_utc_now
from libs.helper import TimestampField, email, extract_remote_ip, timezone from libs.helper import TimestampField, email, extract_remote_ip, timezone
from libs.login import login_required from libs.login import login_required
from models import AccountIntegrate, InvitationCode from models import AccountIntegrate, InvitationCode
@ -80,7 +79,7 @@ class AccountInitApi(Resource):
raise InvalidInvitationCodeError() raise InvalidInvitationCodeError()
invitation_code.status = "used" invitation_code.status = "used"
invitation_code.used_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) invitation_code.used_at = naive_utc_now()
invitation_code.used_by_tenant_id = account.current_tenant_id invitation_code.used_by_tenant_id = account.current_tenant_id
invitation_code.used_by_account_id = account.id invitation_code.used_by_account_id = account.id
@ -88,7 +87,7 @@ class AccountInitApi(Resource):
account.timezone = args["timezone"] account.timezone = args["timezone"]
account.interface_theme = "light" account.interface_theme = "light"
account.status = "active" account.status = "active"
account.initialized_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
db.session.commit() db.session.commit()
return {"result": "success"} return {"result": "success"}

View File

@ -1,6 +1,6 @@
import time import time
from collections.abc import Callable from collections.abc import Callable
from datetime import UTC, datetime, timedelta from datetime import timedelta
from enum import Enum from enum import Enum
from functools import wraps from functools import wraps
from typing import Optional from typing import Optional
@ -15,6 +15,7 @@ from werkzeug.exceptions import Forbidden, NotFound, Unauthorized
from extensions.ext_database import db from extensions.ext_database import db
from extensions.ext_redis import redis_client from extensions.ext_redis import redis_client
from libs.datetime_utils import naive_utc_now
from libs.login import _get_user from libs.login import _get_user
from models.account import Account, Tenant, TenantAccountJoin, TenantStatus from models.account import Account, Tenant, TenantAccountJoin, TenantStatus
from models.dataset import Dataset, RateLimitLog from models.dataset import Dataset, RateLimitLog
@ -256,7 +257,7 @@ def validate_and_get_api_token(scope: str | None = None):
if auth_scheme != "bearer": if auth_scheme != "bearer":
raise Unauthorized("Authorization scheme must be 'Bearer'") raise Unauthorized("Authorization scheme must be 'Bearer'")
current_time = datetime.now(UTC).replace(tzinfo=None) current_time = naive_utc_now()
cutoff_time = current_time - timedelta(minutes=1) cutoff_time = current_time - timedelta(minutes=1)
with Session(db.engine, expire_on_commit=False) as session: with Session(db.engine, expire_on_commit=False) as session:
update_stmt = ( update_stmt = (

View File

@ -1,7 +1,6 @@
import json import json
import logging import logging
from collections.abc import Generator from collections.abc import Generator
from datetime import UTC, datetime
from typing import Optional, Union, cast from typing import Optional, Union, cast
from core.app.app_config.entities import EasyUIBasedAppConfig, EasyUIBasedAppModelConfigFrom from core.app.app_config.entities import EasyUIBasedAppConfig, EasyUIBasedAppModelConfigFrom
@ -25,6 +24,7 @@ from core.app.entities.task_entities import (
from core.app.task_pipeline.easy_ui_based_generate_task_pipeline import EasyUIBasedGenerateTaskPipeline from core.app.task_pipeline.easy_ui_based_generate_task_pipeline import EasyUIBasedGenerateTaskPipeline
from core.prompt.utils.prompt_template_parser import PromptTemplateParser from core.prompt.utils.prompt_template_parser import PromptTemplateParser
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models import Account from models import Account
from models.enums import CreatorUserRole from models.enums import CreatorUserRole
from models.model import App, AppMode, AppModelConfig, Conversation, EndUser, Message, MessageFile from models.model import App, AppMode, AppModelConfig, Conversation, EndUser, Message, MessageFile
@ -184,7 +184,7 @@ class MessageBasedAppGenerator(BaseAppGenerator):
db.session.commit() db.session.commit()
db.session.refresh(conversation) db.session.refresh(conversation)
else: else:
conversation.updated_at = datetime.now(UTC).replace(tzinfo=None) conversation.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
message = Message( message = Message(

View File

@ -1,6 +1,6 @@
from collections.abc import Mapping from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
from datetime import UTC, datetime from datetime import datetime
from typing import Any, Optional, Union from typing import Any, Optional, Union
from uuid import uuid4 from uuid import uuid4
@ -71,7 +71,7 @@ class WorkflowCycleManager:
workflow_version=self._workflow_info.version, workflow_version=self._workflow_info.version,
graph=self._workflow_info.graph_data, graph=self._workflow_info.graph_data,
inputs=inputs, inputs=inputs,
started_at=datetime.now(UTC).replace(tzinfo=None), started_at=naive_utc_now(),
) )
return self._save_and_cache_workflow_execution(execution) return self._save_and_cache_workflow_execution(execution)
@ -356,7 +356,7 @@ class WorkflowCycleManager:
created_at: Optional[datetime] = None, created_at: Optional[datetime] = None,
) -> WorkflowNodeExecution: ) -> WorkflowNodeExecution:
"""Create a node execution from an event.""" """Create a node execution from an event."""
now = datetime.now(UTC).replace(tzinfo=None) now = naive_utc_now()
created_at = created_at or now created_at = created_at or now
metadata = { metadata = {
@ -403,7 +403,7 @@ class WorkflowCycleManager:
handle_special_values: bool = False, handle_special_values: bool = False,
) -> None: ) -> None:
"""Update node execution with completion data.""" """Update node execution with completion data."""
finished_at = datetime.now(UTC).replace(tzinfo=None) finished_at = naive_utc_now()
elapsed_time = (finished_at - event.start_at).total_seconds() elapsed_time = (finished_at - event.start_at).total_seconds()
# Process data # Process data

View File

@ -1,4 +1,3 @@
import datetime
import logging import logging
import time import time
@ -8,6 +7,7 @@ from werkzeug.exceptions import NotFound
from core.indexing_runner import DocumentIsPausedError, IndexingRunner from core.indexing_runner import DocumentIsPausedError, IndexingRunner
from events.event_handlers.document_index_event import document_index_created from events.event_handlers.document_index_event import document_index_created
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models.dataset import Document from models.dataset import Document
@ -33,7 +33,7 @@ def handle(sender, **kwargs):
raise NotFound("Document not found") raise NotFound("Document not found")
document.indexing_status = "parsing" document.indexing_status = "parsing"
document.processing_started_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) document.processing_started_at = naive_utc_now()
documents.append(document) documents.append(document)
db.session.add(document) db.session.add(document)
db.session.commit() db.session.commit()

View File

@ -1,5 +1,5 @@
from collections.abc import Generator from collections.abc import Generator
from datetime import UTC, datetime, timedelta from datetime import timedelta
from typing import Optional from typing import Optional
from azure.identity import ChainedTokenCredential, DefaultAzureCredential from azure.identity import ChainedTokenCredential, DefaultAzureCredential
@ -8,6 +8,7 @@ from azure.storage.blob import AccountSasPermissions, BlobServiceClient, Resourc
from configs import dify_config from configs import dify_config
from extensions.ext_redis import redis_client from extensions.ext_redis import redis_client
from extensions.storage.base_storage import BaseStorage from extensions.storage.base_storage import BaseStorage
from libs.datetime_utils import naive_utc_now
class AzureBlobStorage(BaseStorage): class AzureBlobStorage(BaseStorage):
@ -78,7 +79,7 @@ class AzureBlobStorage(BaseStorage):
account_key=self.account_key or "", account_key=self.account_key or "",
resource_types=ResourceTypes(service=True, container=True, object=True), resource_types=ResourceTypes(service=True, container=True, object=True),
permission=AccountSasPermissions(read=True, write=True, delete=True, list=True, add=True, create=True), permission=AccountSasPermissions(read=True, write=True, delete=True, list=True, add=True, create=True),
expiry=datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1), expiry=naive_utc_now() + timedelta(hours=1),
) )
redis_client.set(cache_key, sas_token, ex=3000) redis_client.set(cache_key, sas_token, ex=3000)
return BlobServiceClient(account_url=self.account_url or "", credential=sas_token) return BlobServiceClient(account_url=self.account_url or "", credential=sas_token)

View File

@ -1,4 +1,3 @@
import datetime
import urllib.parse import urllib.parse
from typing import Any from typing import Any
@ -6,6 +5,7 @@ import requests
from flask_login import current_user from flask_login import current_user
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models.source import DataSourceOauthBinding from models.source import DataSourceOauthBinding
@ -75,7 +75,7 @@ class NotionOAuth(OAuthDataSource):
if data_source_binding: if data_source_binding:
data_source_binding.source_info = source_info data_source_binding.source_info = source_info
data_source_binding.disabled = False data_source_binding.disabled = False
data_source_binding.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data_source_binding.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
else: else:
new_data_source_binding = DataSourceOauthBinding( new_data_source_binding = DataSourceOauthBinding(
@ -115,7 +115,7 @@ class NotionOAuth(OAuthDataSource):
if data_source_binding: if data_source_binding:
data_source_binding.source_info = source_info data_source_binding.source_info = source_info
data_source_binding.disabled = False data_source_binding.disabled = False
data_source_binding.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data_source_binding.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
else: else:
new_data_source_binding = DataSourceOauthBinding( new_data_source_binding = DataSourceOauthBinding(
@ -154,7 +154,7 @@ class NotionOAuth(OAuthDataSource):
} }
data_source_binding.source_info = new_source_info data_source_binding.source_info = new_source_info
data_source_binding.disabled = False data_source_binding.disabled = False
data_source_binding.updated_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data_source_binding.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
else: else:
raise ValueError("Data source binding not found") raise ValueError("Data source binding not found")

View File

@ -1,7 +1,6 @@
from datetime import UTC, datetime
from celery import states # type: ignore from celery import states # type: ignore
from libs.datetime_utils import naive_utc_now
from models.base import Base from models.base import Base
from .engine import db from .engine import db
@ -18,8 +17,8 @@ class CeleryTask(Base):
result = db.Column(db.PickleType, nullable=True) result = db.Column(db.PickleType, nullable=True)
date_done = db.Column( date_done = db.Column(
db.DateTime, db.DateTime,
default=lambda: datetime.now(UTC).replace(tzinfo=None), default=lambda: naive_utc_now(),
onupdate=lambda: datetime.now(UTC).replace(tzinfo=None), onupdate=lambda: naive_utc_now(),
nullable=True, nullable=True,
) )
traceback = db.Column(db.Text, nullable=True) traceback = db.Column(db.Text, nullable=True)
@ -39,4 +38,4 @@ class CeleryTaskSet(Base):
id = db.Column(db.Integer, db.Sequence("taskset_id_sequence"), autoincrement=True, primary_key=True) id = db.Column(db.Integer, db.Sequence("taskset_id_sequence"), autoincrement=True, primary_key=True)
taskset_id = db.Column(db.String(155), unique=True) taskset_id = db.Column(db.String(155), unique=True)
result = db.Column(db.PickleType, nullable=True) result = db.Column(db.PickleType, nullable=True)
date_done = db.Column(db.DateTime, default=lambda: datetime.now(UTC).replace(tzinfo=None), nullable=True) date_done = db.Column(db.DateTime, default=lambda: naive_utc_now(), nullable=True)

View File

@ -1,7 +1,7 @@
import json import json
import logging import logging
from collections.abc import Mapping, Sequence from collections.abc import Mapping, Sequence
from datetime import UTC, datetime from datetime import datetime
from enum import Enum, StrEnum from enum import Enum, StrEnum
from typing import TYPE_CHECKING, Any, Optional, Union from typing import TYPE_CHECKING, Any, Optional, Union
from uuid import uuid4 from uuid import uuid4
@ -16,6 +16,7 @@ from core.variables.variables import FloatVariable, IntegerVariable, StringVaria
from core.workflow.constants import CONVERSATION_VARIABLE_NODE_ID, SYSTEM_VARIABLE_NODE_ID from core.workflow.constants import CONVERSATION_VARIABLE_NODE_ID, SYSTEM_VARIABLE_NODE_ID
from core.workflow.nodes.enums import NodeType from core.workflow.nodes.enums import NodeType
from factories.variable_factory import TypeMismatchError, build_segment_with_type from factories.variable_factory import TypeMismatchError, build_segment_with_type
from libs.datetime_utils import naive_utc_now
from libs.helper import extract_tenant_id from libs.helper import extract_tenant_id
from ._workflow_exc import NodeNotFoundError, WorkflowDataError from ._workflow_exc import NodeNotFoundError, WorkflowDataError
@ -138,7 +139,7 @@ class Workflow(Base):
updated_at: Mapped[datetime] = mapped_column( updated_at: Mapped[datetime] = mapped_column(
db.DateTime, db.DateTime,
nullable=False, nullable=False,
default=datetime.now(UTC).replace(tzinfo=None), default=naive_utc_now(),
server_onupdate=func.current_timestamp(), server_onupdate=func.current_timestamp(),
) )
_environment_variables: Mapped[str] = mapped_column( _environment_variables: Mapped[str] = mapped_column(
@ -179,7 +180,7 @@ class Workflow(Base):
workflow.conversation_variables = conversation_variables or [] workflow.conversation_variables = conversation_variables or []
workflow.marked_name = marked_name workflow.marked_name = marked_name
workflow.marked_comment = marked_comment workflow.marked_comment = marked_comment
workflow.created_at = datetime.now(UTC).replace(tzinfo=None) workflow.created_at = naive_utc_now()
workflow.updated_at = workflow.created_at workflow.updated_at = workflow.created_at
return workflow return workflow
@ -907,7 +908,7 @@ _EDITABLE_SYSTEM_VARIABLE = frozenset(["query", "files"])
def _naive_utc_datetime(): def _naive_utc_datetime():
return datetime.now(UTC).replace(tzinfo=None) return naive_utc_now()
class WorkflowDraftVariable(Base): class WorkflowDraftVariable(Base):

View File

@ -17,6 +17,7 @@ from constants.languages import language_timezone_mapping, languages
from events.tenant_event import tenant_was_created from events.tenant_event import tenant_was_created
from extensions.ext_database import db from extensions.ext_database import db
from extensions.ext_redis import redis_client, redis_fallback from extensions.ext_redis import redis_client, redis_fallback
from libs.datetime_utils import naive_utc_now
from libs.helper import RateLimiter, TokenManager from libs.helper import RateLimiter, TokenManager
from libs.passport import PassportService from libs.passport import PassportService
from libs.password import compare_password, hash_password, valid_password from libs.password import compare_password, hash_password, valid_password
@ -135,8 +136,8 @@ class AccountService:
available_ta.current = True available_ta.current = True
db.session.commit() db.session.commit()
if datetime.now(UTC).replace(tzinfo=None) - account.last_active_at > timedelta(minutes=10): if naive_utc_now() - account.last_active_at > timedelta(minutes=10):
account.last_active_at = datetime.now(UTC).replace(tzinfo=None) account.last_active_at = naive_utc_now()
db.session.commit() db.session.commit()
return cast(Account, account) return cast(Account, account)
@ -180,7 +181,7 @@ class AccountService:
if account.status == AccountStatus.PENDING.value: if account.status == AccountStatus.PENDING.value:
account.status = AccountStatus.ACTIVE.value account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.now(UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
db.session.commit() db.session.commit()
@ -318,7 +319,7 @@ class AccountService:
# If it exists, update the record # If it exists, update the record
account_integrate.open_id = open_id account_integrate.open_id = open_id
account_integrate.encrypted_token = "" # todo account_integrate.encrypted_token = "" # todo
account_integrate.updated_at = datetime.now(UTC).replace(tzinfo=None) account_integrate.updated_at = naive_utc_now()
else: else:
# If it does not exist, create a new record # If it does not exist, create a new record
account_integrate = AccountIntegrate( account_integrate = AccountIntegrate(
@ -353,7 +354,7 @@ class AccountService:
@staticmethod @staticmethod
def update_login_info(account: Account, *, ip_address: str) -> None: def update_login_info(account: Account, *, ip_address: str) -> None:
"""Update last login time and ip""" """Update last login time and ip"""
account.last_login_at = datetime.now(UTC).replace(tzinfo=None) account.last_login_at = naive_utc_now()
account.last_login_ip = ip_address account.last_login_ip = ip_address
db.session.add(account) db.session.add(account)
db.session.commit() db.session.commit()
@ -1117,7 +1118,7 @@ class RegisterService:
) )
account.last_login_ip = ip_address account.last_login_ip = ip_address
account.initialized_at = datetime.now(UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
TenantService.create_owner_tenant_if_not_exist(account=account, is_setup=True) TenantService.create_owner_tenant_if_not_exist(account=account, is_setup=True)
@ -1158,7 +1159,7 @@ class RegisterService:
is_setup=is_setup, is_setup=is_setup,
) )
account.status = AccountStatus.ACTIVE.value if not status else status.value account.status = AccountStatus.ACTIVE.value if not status else status.value
account.initialized_at = datetime.now(UTC).replace(tzinfo=None) account.initialized_at = naive_utc_now()
if open_id is not None and provider is not None: if open_id is not None and provider is not None:
AccountService.link_account_integrate(provider, open_id, account) AccountService.link_account_integrate(provider, open_id, account)

View File

@ -1,6 +1,5 @@
import json import json
import logging import logging
from datetime import UTC, datetime
from typing import Optional, cast from typing import Optional, cast
from flask_login import current_user from flask_login import current_user
@ -17,6 +16,7 @@ from core.tools.tool_manager import ToolManager
from core.tools.utils.configuration import ToolParameterConfigurationManager from core.tools.utils.configuration import ToolParameterConfigurationManager
from events.app_event import app_was_created from events.app_event import app_was_created
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models.account import Account from models.account import Account
from models.model import App, AppMode, AppModelConfig, Site from models.model import App, AppMode, AppModelConfig, Site
from models.tools import ApiToolProvider from models.tools import ApiToolProvider
@ -235,7 +235,7 @@ class AppService:
app.use_icon_as_answer_icon = args.get("use_icon_as_answer_icon", False) app.use_icon_as_answer_icon = args.get("use_icon_as_answer_icon", False)
app.max_active_requests = args.get("max_active_requests") app.max_active_requests = args.get("max_active_requests")
app.updated_by = current_user.id app.updated_by = current_user.id
app.updated_at = datetime.now(UTC).replace(tzinfo=None) app.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return app return app
@ -249,7 +249,7 @@ class AppService:
""" """
app.name = name app.name = name
app.updated_by = current_user.id app.updated_by = current_user.id
app.updated_at = datetime.now(UTC).replace(tzinfo=None) app.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return app return app
@ -265,7 +265,7 @@ class AppService:
app.icon = icon app.icon = icon
app.icon_background = icon_background app.icon_background = icon_background
app.updated_by = current_user.id app.updated_by = current_user.id
app.updated_at = datetime.now(UTC).replace(tzinfo=None) app.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return app return app
@ -282,7 +282,7 @@ class AppService:
app.enable_site = enable_site app.enable_site = enable_site
app.updated_by = current_user.id app.updated_by = current_user.id
app.updated_at = datetime.now(UTC).replace(tzinfo=None) app.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return app return app
@ -299,7 +299,7 @@ class AppService:
app.enable_api = enable_api app.enable_api = enable_api
app.updated_by = current_user.id app.updated_by = current_user.id
app.updated_at = datetime.now(UTC).replace(tzinfo=None) app.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return app return app

View File

@ -1,5 +1,4 @@
from collections.abc import Callable, Sequence from collections.abc import Callable, Sequence
from datetime import UTC, datetime
from typing import Optional, Union from typing import Optional, Union
from sqlalchemy import asc, desc, func, or_, select from sqlalchemy import asc, desc, func, or_, select
@ -8,6 +7,7 @@ from sqlalchemy.orm import Session
from core.app.entities.app_invoke_entities import InvokeFrom from core.app.entities.app_invoke_entities import InvokeFrom
from core.llm_generator.llm_generator import LLMGenerator from core.llm_generator.llm_generator import LLMGenerator
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from libs.infinite_scroll_pagination import InfiniteScrollPagination from libs.infinite_scroll_pagination import InfiniteScrollPagination
from models import ConversationVariable from models import ConversationVariable
from models.account import Account from models.account import Account
@ -113,7 +113,7 @@ class ConversationService:
return cls.auto_generate_name(app_model, conversation) return cls.auto_generate_name(app_model, conversation)
else: else:
conversation.name = name conversation.name = name
conversation.updated_at = datetime.now(UTC).replace(tzinfo=None) conversation.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return conversation return conversation
@ -169,7 +169,7 @@ class ConversationService:
conversation = cls.get_conversation(app_model, conversation_id, user) conversation = cls.get_conversation(app_model, conversation_id, user)
conversation.is_deleted = True conversation.is_deleted = True
conversation.updated_at = datetime.now(UTC).replace(tzinfo=None) conversation.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
@classmethod @classmethod

View File

@ -26,6 +26,7 @@ from events.document_event import document_was_deleted
from extensions.ext_database import db from extensions.ext_database import db
from extensions.ext_redis import redis_client from extensions.ext_redis import redis_client
from libs import helper from libs import helper
from libs.datetime_utils import naive_utc_now
from models.account import Account, TenantAccountRole from models.account import Account, TenantAccountRole
from models.dataset import ( from models.dataset import (
AppDatasetJoin, AppDatasetJoin,
@ -428,7 +429,7 @@ class DatasetService:
# Add metadata fields # Add metadata fields
filtered_data["updated_by"] = user.id filtered_data["updated_by"] = user.id
filtered_data["updated_at"] = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) filtered_data["updated_at"] = naive_utc_now()
# update Retrieval model # update Retrieval model
filtered_data["retrieval_model"] = data["retrieval_model"] filtered_data["retrieval_model"] = data["retrieval_model"]
@ -994,7 +995,7 @@ class DocumentService:
# update document to be paused # update document to be paused
document.is_paused = True document.is_paused = True
document.paused_by = current_user.id document.paused_by = current_user.id
document.paused_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) document.paused_at = naive_utc_now()
db.session.add(document) db.session.add(document)
db.session.commit() db.session.commit()

View File

@ -1,6 +1,5 @@
import json import json
from copy import deepcopy from copy import deepcopy
from datetime import UTC, datetime
from typing import Any, Optional, Union, cast from typing import Any, Optional, Union, cast
from urllib.parse import urlparse from urllib.parse import urlparse
@ -11,6 +10,7 @@ from constants import HIDDEN_VALUE
from core.helper import ssrf_proxy from core.helper import ssrf_proxy
from core.rag.entities.metadata_entities import MetadataCondition from core.rag.entities.metadata_entities import MetadataCondition
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models.dataset import ( from models.dataset import (
Dataset, Dataset,
ExternalKnowledgeApis, ExternalKnowledgeApis,
@ -120,7 +120,7 @@ class ExternalDatasetService:
external_knowledge_api.description = args.get("description", "") external_knowledge_api.description = args.get("description", "")
external_knowledge_api.settings = json.dumps(args.get("settings"), ensure_ascii=False) external_knowledge_api.settings = json.dumps(args.get("settings"), ensure_ascii=False)
external_knowledge_api.updated_by = user_id external_knowledge_api.updated_by = user_id
external_knowledge_api.updated_at = datetime.now(UTC).replace(tzinfo=None) external_knowledge_api.updated_at = naive_utc_now()
db.session.commit() db.session.commit()
return external_knowledge_api return external_knowledge_api

View File

@ -2,7 +2,6 @@ import json
import time import time
import uuid import uuid
from collections.abc import Callable, Generator, Mapping, Sequence from collections.abc import Callable, Generator, Mapping, Sequence
from datetime import UTC, datetime
from typing import Any, Optional, cast from typing import Any, Optional, cast
from uuid import uuid4 from uuid import uuid4
@ -33,6 +32,7 @@ from core.workflow.workflow_entry import WorkflowEntry
from events.app_event import app_draft_workflow_was_synced, app_published_workflow_was_updated from events.app_event import app_draft_workflow_was_synced, app_published_workflow_was_updated
from extensions.ext_database import db from extensions.ext_database import db
from factories.file_factory import build_from_mapping, build_from_mappings from factories.file_factory import build_from_mapping, build_from_mappings
from libs.datetime_utils import naive_utc_now
from models.account import Account from models.account import Account
from models.model import App, AppMode from models.model import App, AppMode
from models.tools import WorkflowToolProvider from models.tools import WorkflowToolProvider
@ -232,7 +232,7 @@ class WorkflowService:
workflow.graph = json.dumps(graph) workflow.graph = json.dumps(graph)
workflow.features = json.dumps(features) workflow.features = json.dumps(features)
workflow.updated_by = account.id workflow.updated_by = account.id
workflow.updated_at = datetime.now(UTC).replace(tzinfo=None) workflow.updated_at = naive_utc_now()
workflow.environment_variables = environment_variables workflow.environment_variables = environment_variables
workflow.conversation_variables = conversation_variables workflow.conversation_variables = conversation_variables
@ -268,7 +268,7 @@ class WorkflowService:
tenant_id=app_model.tenant_id, tenant_id=app_model.tenant_id,
app_id=app_model.id, app_id=app_model.id,
type=draft_workflow.type, type=draft_workflow.type,
version=Workflow.version_from_datetime(datetime.now(UTC).replace(tzinfo=None)), version=Workflow.version_from_datetime(naive_utc_now()),
graph=draft_workflow.graph, graph=draft_workflow.graph,
features=draft_workflow.features, features=draft_workflow.features,
created_by=account.id, created_by=account.id,
@ -523,8 +523,8 @@ class WorkflowService:
node_type=node.type_, node_type=node.type_,
title=node.title, title=node.title,
elapsed_time=time.perf_counter() - start_at, elapsed_time=time.perf_counter() - start_at,
created_at=datetime.now(UTC).replace(tzinfo=None), created_at=naive_utc_now(),
finished_at=datetime.now(UTC).replace(tzinfo=None), finished_at=naive_utc_now(),
) )
if run_succeeded and node_run_result: if run_succeeded and node_run_result:
@ -621,7 +621,7 @@ class WorkflowService:
setattr(workflow, field, value) setattr(workflow, field, value)
workflow.updated_by = account_id workflow.updated_by = account_id
workflow.updated_at = datetime.now(UTC).replace(tzinfo=None) workflow.updated_at = naive_utc_now()
return workflow return workflow

View File

@ -1,4 +1,3 @@
import datetime
import logging import logging
import time import time
@ -8,6 +7,7 @@ from celery import shared_task # type: ignore
from configs import dify_config from configs import dify_config
from core.indexing_runner import DocumentIsPausedError, IndexingRunner from core.indexing_runner import DocumentIsPausedError, IndexingRunner
from extensions.ext_database import db from extensions.ext_database import db
from libs.datetime_utils import naive_utc_now
from models.dataset import Dataset, Document from models.dataset import Dataset, Document
from services.feature_service import FeatureService from services.feature_service import FeatureService
@ -53,7 +53,7 @@ def document_indexing_task(dataset_id: str, document_ids: list):
if document: if document:
document.indexing_status = "error" document.indexing_status = "error"
document.error = str(e) document.error = str(e)
document.stopped_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) document.stopped_at = naive_utc_now()
db.session.add(document) db.session.add(document)
db.session.commit() db.session.commit()
db.session.close() db.session.close()
@ -68,7 +68,7 @@ def document_indexing_task(dataset_id: str, document_ids: list):
if document: if document:
document.indexing_status = "parsing" document.indexing_status = "parsing"
document.processing_started_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) document.processing_started_at = naive_utc_now()
documents.append(document) documents.append(document)
db.session.add(document) db.session.add(document)
db.session.commit() db.session.commit()

View File

@ -102,17 +102,16 @@ class TestDatasetServiceUpdateDataset:
patch("services.dataset_service.DatasetService.get_dataset") as mock_get_dataset, patch("services.dataset_service.DatasetService.get_dataset") as mock_get_dataset,
patch("services.dataset_service.DatasetService.check_dataset_permission") as mock_check_perm, patch("services.dataset_service.DatasetService.check_dataset_permission") as mock_check_perm,
patch("extensions.ext_database.db.session") as mock_db, patch("extensions.ext_database.db.session") as mock_db,
patch("services.dataset_service.datetime") as mock_datetime, patch("services.dataset_service.naive_utc_now") as mock_naive_utc_now,
): ):
current_time = datetime.datetime(2023, 1, 1, 12, 0, 0) current_time = datetime.datetime(2023, 1, 1, 12, 0, 0)
mock_datetime.datetime.now.return_value = current_time mock_naive_utc_now.return_value = current_time
mock_datetime.UTC = datetime.UTC
yield { yield {
"get_dataset": mock_get_dataset, "get_dataset": mock_get_dataset,
"check_permission": mock_check_perm, "check_permission": mock_check_perm,
"db_session": mock_db, "db_session": mock_db,
"datetime": mock_datetime, "naive_utc_now": mock_naive_utc_now,
"current_time": current_time, "current_time": current_time,
} }
@ -292,7 +291,7 @@ class TestDatasetServiceUpdateDataset:
"embedding_model_provider": "openai", "embedding_model_provider": "openai",
"embedding_model": "text-embedding-ada-002", "embedding_model": "text-embedding-ada-002",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(
@ -327,7 +326,7 @@ class TestDatasetServiceUpdateDataset:
"indexing_technique": "high_quality", "indexing_technique": "high_quality",
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
actual_call_args = mock_dataset_service_dependencies[ actual_call_args = mock_dataset_service_dependencies[
@ -365,7 +364,7 @@ class TestDatasetServiceUpdateDataset:
"collection_binding_id": None, "collection_binding_id": None,
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(
@ -422,7 +421,7 @@ class TestDatasetServiceUpdateDataset:
"collection_binding_id": "binding-456", "collection_binding_id": "binding-456",
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(
@ -463,7 +462,7 @@ class TestDatasetServiceUpdateDataset:
"collection_binding_id": "binding-123", "collection_binding_id": "binding-123",
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(
@ -525,7 +524,7 @@ class TestDatasetServiceUpdateDataset:
"collection_binding_id": "binding-789", "collection_binding_id": "binding-789",
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(
@ -568,7 +567,7 @@ class TestDatasetServiceUpdateDataset:
"collection_binding_id": "binding-123", "collection_binding_id": "binding-123",
"retrieval_model": "new_model", "retrieval_model": "new_model",
"updated_by": user.id, "updated_by": user.id,
"updated_at": mock_dataset_service_dependencies["current_time"].replace(tzinfo=None), "updated_at": mock_dataset_service_dependencies["current_time"],
} }
self._assert_database_update_called( self._assert_database_update_called(

View File

@ -1 +1,7 @@
from dify_client.client import ChatClient, CompletionClient, WorkflowClient, KnowledgeBaseClient, DifyClient from dify_client.client import (
ChatClient,
CompletionClient,
WorkflowClient,
KnowledgeBaseClient,
DifyClient,
)