feat: Deprecate datetime.utcnow() in favor of datetime.now(timezone.utc).replace(tzinfo=None) for better timezone handling (#3408) (#3416)

This commit is contained in:
LIU HONGWEI 2024-04-12 16:22:24 +08:00 • committed by GitHub
commit c227f3d985
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 112 additions and 112 deletions

View file

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
import pytz
from flask_login import current_user
@ -262,7 +262,7 @@ def _get_conversation(app_model, conversation_id):
raise NotFound("Conversation Not Exists.")
if not conversation.read_at:
conversation.read_at = datetime.utcnow()
conversation.read_at = datetime.now(timezone.utc).replace(tzinfo=None)
conversation.read_account_id = current_user.id
db.session.commit()

View file

@ -1,6 +1,6 @@
import base64
import datetime
import secrets
from datetime import datetime
from flask_restful import Resource, reqparse
@ -66,7 +66,7 @@ class ActivateApi(Resource):
account.timezone = args['timezone']
account.interface_theme = 'light'
account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.utcnow()
account.initialized_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
return {'result': 'success'}

View file

@ -1,5 +1,5 @@
import logging
from datetime import datetime
from datetime import datetime, timezone
from typing import Optional
import requests
@ -73,7 +73,7 @@ class OAuthCallback(Resource):
if account.status == AccountStatus.PENDING.value:
account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.utcnow()
account.initialized_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
TenantService.create_owner_tenant_if_not_exist(account)

View file

@ -80,7 +80,7 @@ class DataSourceApi(Resource):
if action == 'enable':
if data_source_binding.disabled:
data_source_binding.disabled = False
data_source_binding.updated_at = datetime.datetime.utcnow()
data_source_binding.updated_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.add(data_source_binding)
db.session.commit()
else:
@ -89,7 +89,7 @@ class DataSourceApi(Resource):
if action == 'disable':
if not data_source_binding.disabled:
data_source_binding.disabled = True
data_source_binding.updated_at = datetime.datetime.utcnow()
data_source_binding.updated_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.add(data_source_binding)
db.session.commit()
else:

View file

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from flask import request
from flask_login import current_user
@ -637,7 +637,7 @@ class DocumentProcessingApi(DocumentResource):
raise InvalidActionError('Document not in indexing state.')
document.paused_by = current_user.id
document.paused_at = datetime.utcnow()
document.paused_at = datetime.now(timezone.utc).replace(tzinfo=None)
document.is_paused = True
db.session.commit()
@ -717,7 +717,7 @@ class DocumentMetadataApi(DocumentResource):
document.doc_metadata[key] = value
document.doc_type = doc_type
document.updated_at = datetime.utcnow()
document.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
return {'result': 'success', 'message': 'Document metadata updated.'}, 200
@ -755,7 +755,7 @@ class DocumentStatusApi(DocumentResource):
document.enabled = True
document.disabled_at = None
document.disabled_by = None
document.updated_at = datetime.utcnow()
document.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
# Set cache to prevent indexing the same document multiple times
@ -772,9 +772,9 @@ class DocumentStatusApi(DocumentResource):
raise InvalidActionError('Document already disabled.')
document.enabled = False
document.disabled_at = datetime.utcnow()
document.disabled_at = datetime.now(timezone.utc).replace(tzinfo=None)
document.disabled_by = current_user.id
document.updated_at = datetime.utcnow()
document.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
# Set cache to prevent indexing the same document multiple times
@ -789,9 +789,9 @@ class DocumentStatusApi(DocumentResource):
raise InvalidActionError('Document already archived.')
document.archived = True
document.archived_at = datetime.utcnow()
document.archived_at = datetime.now(timezone.utc).replace(tzinfo=None)
document.archived_by = current_user.id
document.updated_at = datetime.utcnow()
document.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
if document.enabled:
@ -808,7 +808,7 @@ class DocumentStatusApi(DocumentResource):
document.archived = False
document.archived_at = None
document.archived_by = None
document.updated_at = datetime.utcnow()
document.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
# Set cache to prevent indexing the same document multiple times

View file

@ -1,5 +1,5 @@
import uuid
from datetime import datetime
from datetime import datetime, timezone
import pandas as pd
from flask import request
@ -192,7 +192,7 @@ class DatasetDocumentSegmentApi(Resource):
raise InvalidActionError("Segment is already disabled.")
segment.enabled = False
segment.disabled_at = datetime.utcnow()
segment.disabled_at = datetime.now(timezone.utc).replace(tzinfo=None)
segment.disabled_by = current_user.id
db.session.commit()

View file

@ -1,5 +1,5 @@
import logging
from datetime import datetime
from datetime import datetime, timezone
from flask_login import current_user
from flask_restful import reqparse
@ -47,7 +47,7 @@ class CompletionApi(InstalledAppResource):
streaming = args['response_mode'] == 'streaming'
args['auto_generate_name'] = False
installed_app.last_used_at = datetime.utcnow()
installed_app.last_used_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
try:
@ -110,7 +110,7 @@ class ChatApi(InstalledAppResource):
args['auto_generate_name'] = False
installed_app.last_used_at = datetime.utcnow()
installed_app.last_used_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
try:

View file

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from flask_login import current_user
from flask_restful import Resource, inputs, marshal_with, reqparse
@ -81,7 +81,7 @@ class InstalledAppsListApi(Resource):
tenant_id=current_tenant_id,
app_owner_tenant_id=app.tenant_id,
is_pinned=False,
last_used_at=datetime.utcnow()
last_used_at=datetime.now(timezone.utc).replace(tzinfo=None)
)
db.session.add(new_installed_app)
db.session.commit()

View file

@ -1,4 +1,4 @@
from datetime import datetime
import datetime
import pytz
from flask import current_app, request
@ -59,7 +59,7 @@ class AccountInitApi(Resource):
raise InvalidInvitationCodeError()
invitation_code.status = 'used'
invitation_code.used_at = datetime.utcnow()
invitation_code.used_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
invitation_code.used_by_tenant_id = account.current_tenant_id
invitation_code.used_by_account_id = account.id
@ -67,7 +67,7 @@ class AccountInitApi(Resource):
account.timezone = args['timezone']
account.interface_theme = 'light'
account.status = 'active'
account.initialized_at = datetime.utcnow()
account.initialized_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
return {'result': 'success'}

View file

@ -1,5 +1,5 @@
from collections.abc import Callable
from datetime import datetime
from datetime import datetime, timezone
from enum import Enum
from functools import wraps
from typing import Optional
@ -183,7 +183,7 @@ def validate_and_get_api_token(scope=None):
if not api_token:
raise Unauthorized("Access token is invalid")
api_token.last_used_at = datetime.utcnow()
api_token.last_used_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
return api_token

View file

@ -1,7 +1,7 @@
import json
import logging
import uuid
from datetime import datetime
from datetime import datetime, timezone
from typing import Optional, Union, cast
from core.agent.entities import AgentEntity, AgentToolEntity
@ -440,7 +440,7 @@ class BaseAgentRunner(AppRunner):
ToolConversationVariables.conversation_id == self.message.conversation_id,
).first()
db_variables.updated_at = datetime.utcnow()
db_variables.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
db_variables.variables_str = json.dumps(jsonable_encoder(tool_variables.pool))
db.session.commit()
db.session.close()

View file

@ -1,6 +1,6 @@
import json
import time
from datetime import datetime
from datetime import datetime, timezone
from typing import Any, Optional, Union, cast
from core.app.entities.app_invoke_entities import AdvancedChatAppGenerateEntity, InvokeFrom, WorkflowAppGenerateEntity
@ -120,7 +120,7 @@ class WorkflowCycleManage:
workflow_run.elapsed_time = time.perf_counter() - start_at
workflow_run.total_tokens = total_tokens
workflow_run.total_steps = total_steps
workflow_run.finished_at = datetime.utcnow()
workflow_run.finished_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
db.session.refresh(workflow_run)
@ -149,7 +149,7 @@ class WorkflowCycleManage:
workflow_run.elapsed_time = time.perf_counter() - start_at
workflow_run.total_tokens = total_tokens
workflow_run.total_steps = total_steps
workflow_run.finished_at = datetime.utcnow()
workflow_run.finished_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
db.session.refresh(workflow_run)
@ -223,7 +223,7 @@ class WorkflowCycleManage:
workflow_node_execution.outputs = json.dumps(outputs) if outputs else None
workflow_node_execution.execution_metadata = json.dumps(jsonable_encoder(execution_metadata)) \
if execution_metadata else None
workflow_node_execution.finished_at = datetime.utcnow()
workflow_node_execution.finished_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
db.session.refresh(workflow_node_execution)
@ -251,7 +251,7 @@ class WorkflowCycleManage:
workflow_node_execution.status = WorkflowNodeExecutionStatus.FAILED.value
workflow_node_execution.error = error
workflow_node_execution.elapsed_time = time.perf_counter() - start_at
workflow_node_execution.finished_at = datetime.utcnow()
workflow_node_execution.finished_at = datetime.now(timezone.utc).replace(tzinfo=None)
workflow_node_execution.inputs = json.dumps(inputs) if inputs else None
workflow_node_execution.process_data = json.dumps(process_data) if process_data else None
workflow_node_execution.outputs = json.dumps(outputs) if outputs else None

View file

@ -203,7 +203,7 @@ class ProviderConfiguration(BaseModel):
if provider_record:
provider_record.encrypted_config = json.dumps(credentials)
provider_record.is_valid = True
provider_record.updated_at = datetime.datetime.utcnow()
provider_record.updated_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
else:
provider_record = Provider(
@ -351,7 +351,7 @@ class ProviderConfiguration(BaseModel):
if provider_model_record:
provider_model_record.encrypted_config = json.dumps(credentials)
provider_model_record.is_valid = True
provider_model_record.updated_at = datetime.datetime.utcnow()
provider_model_record.updated_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
else:
provider_model_record = ProviderModel(

View file

@ -81,7 +81,7 @@ class IndexingRunner:
except ProviderTokenNotInitError as e:
dataset_document.indexing_status = 'error'
dataset_document.error = str(e.description)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
except ObjectDeletedError:
logging.warning('Document deleted, document id: {}'.format(dataset_document.id))
@ -89,7 +89,7 @@ class IndexingRunner:
logging.exception("consume document failed")
dataset_document.indexing_status = 'error'
dataset_document.error = str(e)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
def run_in_splitting_status(self, dataset_document: DatasetDocument):
@ -140,13 +140,13 @@ class IndexingRunner:
except ProviderTokenNotInitError as e:
dataset_document.indexing_status = 'error'
dataset_document.error = str(e.description)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
except Exception as e:
logging.exception("consume document failed")
dataset_document.indexing_status = 'error'
dataset_document.error = str(e)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
def run_in_indexing_status(self, dataset_document: DatasetDocument):
@ -202,13 +202,13 @@ class IndexingRunner:
except ProviderTokenNotInitError as e:
dataset_document.indexing_status = 'error'
dataset_document.error = str(e.description)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
except Exception as e:
logging.exception("consume document failed")
dataset_document.indexing_status = 'error'
dataset_document.error = str(e)
dataset_document.stopped_at = datetime.datetime.utcnow()
dataset_document.stopped_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.commit()
def indexing_estimate(self, tenant_id: str, extract_settings: list[ExtractSetting], tmp_processing_rule: dict,
@ -382,7 +382,7 @@ class IndexingRunner:
after_indexing_status="splitting",
extra_update_params={
DatasetDocument.word_count: sum([len(text_doc.page_content) for text_doc in text_docs]),
DatasetDocument.parsing_completed_at: datetime.datetime.utcnow()
DatasetDocument.parsing_completed_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
}
)
@ -467,7 +467,7 @@ class IndexingRunner:
doc_store.add_documents(documents)
# update document status to indexing
cur_time = datetime.datetime.utcnow()
cur_time = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
self._update_document_index_status(
document_id=dataset_document.id,
after_indexing_status="indexing",
@ -482,7 +482,7 @@ class IndexingRunner:
dataset_document_id=dataset_document.id,
update_params={
DocumentSegment.status: "indexing",
DocumentSegment.indexing_at: datetime.datetime.utcnow()
DocumentSegment.indexing_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
}
)
@ -685,7 +685,7 @@ class IndexingRunner:
after_indexing_status="completed",
extra_update_params={
DatasetDocument.tokens: tokens,
DatasetDocument.completed_at: datetime.datetime.utcnow(),
DatasetDocument.completed_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None),
DatasetDocument.indexing_latency: indexing_end_at - indexing_start_at,
}
)
@ -706,7 +706,7 @@ class IndexingRunner:
).update({
DocumentSegment.status: "completed",
DocumentSegment.enabled: True,
DocumentSegment.completed_at: datetime.datetime.utcnow()
DocumentSegment.completed_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
})
db.session.commit()
@ -739,7 +739,7 @@ class IndexingRunner:
).update({
DocumentSegment.status: "completed",
DocumentSegment.enabled: True,
DocumentSegment.completed_at: datetime.datetime.utcnow()
DocumentSegment.completed_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
})
db.session.commit()
@ -838,7 +838,7 @@ class IndexingRunner:
doc_store.add_documents(documents)
# update document status to indexing
cur_time = datetime.datetime.utcnow()
cur_time = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
self._update_document_index_status(
document_id=dataset_document.id,
after_indexing_status="indexing",
@ -853,7 +853,7 @@ class IndexingRunner:
dataset_document_id=dataset_document.id,
update_params={
DocumentSegment.status: "indexing",
DocumentSegment.indexing_at: datetime.datetime.utcnow()
DocumentSegment.indexing_at: datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
}
)
pass

View file

@ -29,7 +29,7 @@ def handle(sender, **kwargs):
raise NotFound('Document not found')
document.indexing_status = 'parsing'
document.processing_started_at = datetime.datetime.utcnow()
document.processing_started_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
documents.append(document)
db.session.add(document)
db.session.commit()

View file

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from core.app.entities.app_invoke_entities import AgentChatAppGenerateEntity, ChatAppGenerateEntity
from events.message_event import message_was_created
@ -17,5 +17,5 @@ def handle(sender, **kwargs):
db.session.query(Provider).filter(
Provider.tenant_id == application_generate_entity.app_config.tenant_id,
Provider.provider_name == application_generate_entity.model_config.provider
).update({'last_used': datetime.utcnow()})
).update({'last_used': datetime.now(timezone.utc).replace(tzinfo=None)})
db.session.commit()

View file

@ -2,7 +2,7 @@ import os
import shutil
from collections.abc import Generator
from contextlib import closing
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Union
import boto3
@ -38,7 +38,7 @@ class Storage:
account_key=app.config.get('AZURE_BLOB_ACCOUNT_KEY'),
resource_types=ResourceTypes(service=True, container=True, object=True),
permission=AccountSasPermissions(read=True, write=True, delete=True, list=True, add=True, create=True),
expiry=datetime.utcnow() + timedelta(hours=1)
expiry=datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(hours=1)
)
self.client = BlobServiceClient(account_url=app.config.get('AZURE_BLOB_ACCOUNT_URL'),
credential=sas_token)

View file

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timezone
from celery import states
@ -15,8 +15,8 @@ class CeleryTask(db.Model):
task_id = db.Column(db.String(155), unique=True)
status = db.Column(db.String(50), default=states.PENDING)
result = db.Column(db.PickleType, nullable=True)
date_done = db.Column(db.DateTime, default=datetime.utcnow,
onupdate=datetime.utcnow, nullable=True)
date_done = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc).replace(tzinfo=None),
onupdate=lambda: datetime.now(timezone.utc).replace(tzinfo=None), nullable=True)
traceback = db.Column(db.Text, nullable=True)
name = db.Column(db.String(155), nullable=True)
args = db.Column(db.LargeBinary, nullable=True)
@ -35,5 +35,5 @@ class CeleryTaskSet(db.Model):
autoincrement=True, primary_key=True)
taskset_id = db.Column(db.String(155), unique=True)
result = db.Column(db.PickleType, nullable=True)
date_done = db.Column(db.DateTime, default=datetime.utcnow,
date_done = db.Column(db.DateTime, default=lambda: datetime.now(timezone.utc).replace(tzinfo=None),
nullable=True)

View file

@ -2,7 +2,7 @@ import base64
import logging
import secrets
import uuid
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from hashlib import sha256
from typing import Any, Optional
@ -59,8 +59,8 @@ class AccountService:
available_ta.current = True
db.session.commit()
if datetime.utcnow() - account.last_active_at > timedelta(minutes=10):
account.last_active_at = datetime.utcnow()
if datetime.now(timezone.utc).replace(tzinfo=None) - account.last_active_at > timedelta(minutes=10):
account.last_active_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
return account
@ -70,7 +70,7 @@ class AccountService:
def get_account_jwt_token(account):
payload = {
"user_id": account.id,
"exp": datetime.utcnow() + timedelta(days=30),
"exp": datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(days=30),
"iss": current_app.config['EDITION'],
"sub": 'Console API Passport',
}
@ -91,7 +91,7 @@ class AccountService:
if account.status == AccountStatus.PENDING.value:
account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.utcnow()
account.initialized_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()
if account.password is None or not compare_password(password, account.password, account.password_salt):
@ -163,7 +163,7 @@ class AccountService:
# If it exists, update the record
account_integrate.open_id = open_id
account_integrate.encrypted_token = "" # todo
account_integrate.updated_at = datetime.utcnow()
account_integrate.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
else:
# If it does not exist, create a new record
account_integrate = AccountIntegrate(account_id=account.id, provider=provider, open_id=open_id,
@ -197,7 +197,7 @@ class AccountService:
@staticmethod
def update_last_login(account: Account, request) -> None:
"""Update last login time and ip"""
account.last_login_at = datetime.utcnow()
account.last_login_at = datetime.now(timezone.utc).replace(tzinfo=None)
account.last_login_ip = get_remote_ip(request)
db.session.add(account)
db.session.commit()
@ -431,7 +431,7 @@ class RegisterService:
password=password
)
account.status = AccountStatus.ACTIVE.value if not status else status.value
account.initialized_at = datetime.utcnow()
account.initialized_at = datetime.now(timezone.utc).replace(tzinfo=None)
if open_id is not None or provider is not None:
AccountService.link_account_integrate(provider, open_id, account)

View file

@ -415,7 +415,7 @@ class AppAnnotationService:
raise NotFound("App annotation not found")
annotation_setting.score_threshold = args['score_threshold']
annotation_setting.updated_user_id = current_user.id
annotation_setting.updated_at = datetime.datetime.utcnow()
annotation_setting.updated_at = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
db.session.add(annotation_setting)
db.session.commit()

Some files were not shown because too many files have changed in this diff Show more