Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions admin/server/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ def login_admin(email: str, password: str):
resp = user.to_json()
user.access_token = get_uuid()
login_user(user)
user.update_time = (current_timestamp(),)
user.update_date = (datetime_format(datetime.now()),)
user.update_time = current_timestamp()
user.update_date = datetime_format(datetime.utcnow())
user.last_login_time = get_format_time()
user.save()
msg = "Welcome back!"
Expand Down
2 changes: 1 addition & 1 deletion admin/server/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def generate_user_api_key(username: str) -> tuple[Response, int]:
"token": key,
"beta": generate_confirmation_token().replace("ragflow-", "")[:32],
"create_time": current_timestamp(),
"create_date": datetime_format(datetime.now()),
"create_date": datetime_format(datetime.utcnow()),
"update_time": None,
"update_date": None,
}
Expand Down
4 changes: 2 additions & 2 deletions api/apps/api_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ def stats():
tenants[0].tenant_id,
request.args.get(
"from_date",
(datetime.now() -
(datetime.utcnow() -
timedelta(
days=7)).strftime("%Y-%m-%d 00:00:00")),
request.args.get(
"to_date",
datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")),
"agent" if "canvas_id" in request.args else None)

res = {"pv": [], "uv": [], "speed": [], "tokens": [], "round": [], "thumb_up": []}
Expand Down
5 changes: 3 additions & 2 deletions api/apps/chunk_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,9 @@ async def create():
if not isinstance(d["question_kwd"], list):
return get_data_error_result(message="`question_kwd` is required to be a list")
d["question_tks"] = rag_tokenizer.tokenize("\n".join(d["question_kwd"]))
d["create_time"] = str(datetime.datetime.now()).replace("T", " ")[:19]
d["create_timestamp_flt"] = datetime.datetime.now().timestamp()
now_utc = datetime.datetime.now(datetime.timezone.utc)
d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
d["create_timestamp_flt"] = now_utc.timestamp()
if "tag_kwd" in req:
if not isinstance(req["tag_kwd"], list):
return get_data_error_result(message="`tag_kwd` is required to be a list")
Expand Down
2 changes: 1 addition & 1 deletion api/apps/restful_apis/system_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def new_token():
"token": generate_confirmation_token(),
"beta": generate_confirmation_token().replace("ragflow-", "")[:32],
"create_time": current_timestamp(),
"create_date": datetime_format(datetime.now()),
"create_date": datetime_format(datetime.utcnow()),
"update_time": None,
"update_date": None,
}
Expand Down
5 changes: 3 additions & 2 deletions api/apps/sdk/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,8 +952,9 @@ async def add_chunk(tenant_id, dataset_id, document_id):
d["important_tks"] = rag_tokenizer.tokenize(" ".join(req.get("important_keywords", [])))
d["question_kwd"] = [str(q).strip() for q in req.get("questions", []) if str(q).strip()]
d["question_tks"] = rag_tokenizer.tokenize("\n".join(req.get("questions", [])))
d["create_time"] = str(datetime.datetime.now()).replace("T", " ")[:19]
d["create_timestamp_flt"] = datetime.datetime.now().timestamp()
now_utc = datetime.datetime.now(datetime.timezone.utc)
d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
d["create_timestamp_flt"] = now_utc.timestamp()
d["kb_id"] = dataset_id
d["docnm_kwd"] = doc.name
d["doc_id"] = document_id
Expand Down
4 changes: 2 additions & 2 deletions api/apps/system_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License
#
import logging
from datetime import datetime
from datetime import datetime, timezone
import json

from api.apps import login_required
Expand Down Expand Up @@ -127,7 +127,7 @@ def status():
task_executor_heartbeats = {}
try:
task_executors = REDIS_CONN.smembers("TASKEXE")
now = datetime.now().timestamp()
now = datetime.now(timezone.utc).timestamp()
for task_executor_id in task_executors:
heartbeats = REDIS_CONN.zrangebyscore(task_executor_id, now - 60 * 30, now)
heartbeats = [json.loads(heartbeat) for heartbeat in heartbeats]
Expand Down
2 changes: 1 addition & 1 deletion api/apps/user_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ async def login():
user.access_token = get_uuid()
login_user(user)
user.update_time = current_timestamp()
user.update_date = datetime_format(datetime.now())
user.update_date = datetime_format(datetime.utcnow())
user.save()
msg = "Welcome back!"

Expand Down
2 changes: 1 addition & 1 deletion api/db/services/api_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class APITokenService(CommonService):
def used(cls, token):
return cls.model.update({
"update_time": current_timestamp(),
"update_date": datetime_format(datetime.now()),
"update_date": datetime_format(datetime.utcnow()),
}).where(
cls.model.token == token
)
Expand Down
8 changes: 4 additions & 4 deletions api/db/services/common_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def insert(cls, **kwargs):
if "id" not in kwargs:
kwargs["id"] = get_uuid()
timestamp = current_timestamp()
cur_datetime = datetime_format(datetime.now())
cur_datetime = datetime_format(datetime.utcnow())
kwargs["create_time"] = timestamp
kwargs["create_date"] = cur_datetime
kwargs["update_time"] = timestamp
Expand All @@ -228,7 +228,7 @@ def insert_many(cls, data_list, batch_size=100):
batch_size (int, optional): Number of records to insert in each batch. Defaults to 100.
"""
current_ts = current_timestamp()
current_datetime = datetime_format(datetime.now())
current_datetime = datetime_format(datetime.utcnow())
with DB.atomic():
for d in data_list:
d["create_time"] = current_ts
Expand All @@ -253,7 +253,7 @@ def update_many_by_id(cls, data_list):
"""

timestamp = current_timestamp()
cur_datetime = datetime_format(datetime.now())
cur_datetime = datetime_format(datetime.utcnow())
for data in data_list:
data["update_time"] = timestamp
data["update_date"] = cur_datetime
Expand All @@ -272,7 +272,7 @@ def update_by_id(cls, pid, data):
# Returns:
# Number of records updated
data["update_time"] = current_timestamp()
data["update_date"] = datetime_format(datetime.now())
data["update_date"] = datetime_format(datetime.utcnow())
num = cls.model.update(data).where(cls.model.id == pid).execute()
return num

Expand Down
2 changes: 1 addition & 1 deletion api/db/services/connector_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def list_sync_tasks(cls, connector_id=None, page_number=None, items_per_page=15)

@classmethod
def start(cls, id, connector_id):
cls.update_by_id(id, {"status": TaskStatus.RUNNING, "time_started": datetime.now().strftime('%Y-%m-%d %H:%M:%S') })
cls.update_by_id(id, {"status": TaskStatus.RUNNING, "time_started": datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') })
ConnectorService.update_by_id(connector_id, {"status": TaskStatus.RUNNING})

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion api/db/services/dialog_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def update_many_by_id(cls, data_list):
with DB.atomic():
for data in data_list:
data["update_time"] = current_timestamp()
data["update_date"] = datetime_format(datetime.now())
data["update_date"] = datetime_format(datetime.utcnow())
cls.model.update(data).where(cls.model.id == data["id"]).execute()

@classmethod
Expand Down
15 changes: 9 additions & 6 deletions api/db/services/document_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,13 +881,14 @@ def _sync_progress(cls, docs: list[dict]):
# only for special task and parsed docs and unfinished
freeze_progress = special_task_running and doc_progress >= 1 and not finished
msg = "\n".join(sorted(msg))
now_utc = datetime.utcnow()
begin_at = d.get("process_begin_at")
if not begin_at:
begin_at = datetime.now()
begin_at = now_utc
# fallback
cls.update_by_id(d["id"], {"process_begin_at": begin_at})

info = {"process_duration": max(datetime.timestamp(datetime.now()) - begin_at.timestamp(), 0), "run": status}
info = {"process_duration": max((now_utc - begin_at).total_seconds(), 0), "run": status}
if prg != 0 and not freeze_progress:
info["progress"] = prg
if msg:
Expand Down Expand Up @@ -997,14 +998,15 @@ def queue_raptor_o_graphrag_tasks(sample_doc, ty, priority, fake_doc_id="", doc_
hasher.update(str(chunking_config[field]).encode("utf-8"))

def new_task():
now_utc = datetime.utcnow()
return {
"id": get_uuid(),
"doc_id": fake_doc_id,
"from_page": 100000000,
"to_page": 100000000,
"task_type": ty,
"progress_msg": datetime.now().strftime("%H:%M:%S") + " created task " + ty,
"begin_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"progress_msg": now_utc.strftime("%H:%M:%S") + " created task " + ty,
"begin_at": now_utc.strftime("%Y-%m-%d %H:%M:%S"),
}

task = new_task()
Expand Down Expand Up @@ -1079,8 +1081,9 @@ def dummy(prog=None, msg=""):
d = deepcopy(doc)
d.update(ck)
d["id"] = xxhash.xxh64((ck["content_with_weight"] + str(d["doc_id"])).encode("utf-8")).hexdigest()
d["create_time"] = str(datetime.now()).replace("T", " ")[:19]
d["create_timestamp_flt"] = datetime.now().timestamp()
now_utc = datetime.utcnow()
d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
d["create_timestamp_flt"] = now_utc.timestamp()
Comment on lines +1084 to +1086
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In Python 3, does datetime.timestamp() interpret naive datetime objects as local time, and is datetime.now(timezone.utc) the recommended UTC-safe approach over datetime.utcnow() for epoch conversion?

💡 Result:

Yes, in Python 3, datetime.timestamp interprets naive datetime objects as local time. For UTC-safe epoch conversion, datetime.now(timezone.utc) is the recommended approach over the deprecated datetime.utcnow.

Citations:


🏁 Script executed:

# First, verify the file exists and check lines around 1084-1086
head -1090 api/db/services/document_service.py | tail -20

Repository: infiniflow/ragflow

Length of output: 989


🏁 Script executed:

# Check imports at the top of the file
head -50 api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 1993


🏁 Script executed:

# Search for all datetime imports in the file
rg "from datetime import|import datetime" api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 91


🏁 Script executed:

rg "datetime\.utcnow" api/db/services/document_service.py -n

Repository: infiniflow/ragflow

Length of output: 195


🏁 Script executed:

# Check context around line 884
sed -n '880,890p' api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 551


🏁 Script executed:

# Check context around line 1001
sed -n '998,1008p' api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 448


create_timestamp_flt is incorrect with naive utcnow() + .timestamp().

At Line 1086, now_utc is naive (datetime.utcnow()), and .timestamp() treats naive datetimes as local time. On non-UTC servers this stores an offset epoch value, which breaks the UTC-fix objective.

Proposed fix
-from datetime import datetime
+from datetime import datetime, timezone
@@
-            now_utc = datetime.utcnow()
+            now_utc = datetime.now(timezone.utc)
             d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
             d["create_timestamp_flt"] = now_utc.timestamp()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/db/services/document_service.py` around lines 1084 - 1086, now_utc is
created as a naive datetime via datetime.utcnow() so calling .timestamp() will
be interpreted as local time on non-UTC hosts; change creation of now_utc to an
aware UTC datetime (e.g. datetime.now(timezone.utc) or
datetime.utcnow().replace(tzinfo=timezone.utc)) before setting d["create_time"]
and d["create_timestamp_flt"] so that d["create_timestamp_flt"] is the true UTC
epoch seconds for the document.

if not d.get("image"):
docs.append(d)
continue
Expand Down
2 changes: 1 addition & 1 deletion api/db/services/evaluation_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def start_evaluation(cls, dataset_id: str, dialog_id: str,
# Create evaluation run
run_id = get_uuid()
if not name:
name = f"Evaluation Run {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
name = f"Evaluation Run {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC"

run = {
"id": run_id,
Expand Down
4 changes: 2 additions & 2 deletions api/db/services/file2document_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ def delete_by_document_id(cls, doc_id):
@DB.connection_context()
def update_by_file_id(cls, file_id, obj):
obj["update_time"] = current_timestamp()
obj["update_date"] = datetime_format(datetime.now())
cls.model.update(obj).where(cls.model.id == file_id).execute()
obj["update_date"] = datetime_format(datetime.utcnow())
cls.model.update(obj).where(cls.model.file_id == file_id).execute()
return File2Document(**obj)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

@classmethod
Expand Down
4 changes: 2 additions & 2 deletions api/db/services/knowledgebase_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def get_kb_by_name(cls, kb_name, user_id):
def atomic_increase_doc_num_by_id(cls, kb_id):
data = {}
data["update_time"] = current_timestamp()
data["update_date"] = datetime_format(datetime.now())
data["update_date"] = datetime_format(datetime.utcnow())
data["doc_num"] = cls.model.doc_num + 1
num = cls.model.update(data).where(cls.model.id == kb_id).execute()
return num
Expand Down Expand Up @@ -568,7 +568,7 @@ def decrease_document_num_in_delete(cls, kb_id, doc_num_info: dict):
'chunk_num': kb_row.chunk_num - doc_num_info['chunk_num'],
'token_num': kb_row.token_num - doc_num_info['token_num'],
'update_time': current_timestamp(),
'update_date': datetime_format(datetime.now())
'update_date': datetime_format(datetime.utcnow())
}
return cls.model.update(update_dict).where(cls.model.id == kb_id).execute()

Expand Down
4 changes: 2 additions & 2 deletions api/db/services/langfuse_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ def delete_ty_tenant_id(cls, tenant_id):
@classmethod
def update_by_tenant(cls, tenant_id, langfuse_keys):
langfuse_keys["update_time"] = current_timestamp()
langfuse_keys["update_date"] = datetime_format(datetime.now())
langfuse_keys["update_date"] = datetime_format(datetime.utcnow())
return cls.model.update(**langfuse_keys).where(cls.model.tenant_id == tenant_id).execute()

@classmethod
def save(cls, **kwargs):
current_ts = current_timestamp()
current_date = datetime_format(datetime.now())
current_date = datetime_format(datetime.utcnow())

kwargs["create_time"] = current_ts
kwargs["create_date"] = current_date
Expand Down
2 changes: 1 addition & 1 deletion api/db/services/pipeline_operation_log_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def create(cls, document_id, pipeline_id, task_type, task_id=None, referred_docu
avatar=avatar,
)
timestamp = current_timestamp()
datetime_now = datetime_format(datetime.now())
datetime_now = datetime_format(datetime.utcnow())
log["create_time"] = timestamp
log["create_date"] = datetime_now
log["update_time"] = timestamp
Expand Down
2 changes: 1 addition & 1 deletion api/db/services/search_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class SearchService(CommonService):
@classmethod
def save(cls, **kwargs):
current_ts = current_timestamp()
current_date = datetime_format(datetime.now())
current_date = datetime_format(datetime.utcnow())

kwargs["create_time"] = current_ts
kwargs["create_date"] = current_date
Expand Down
2 changes: 1 addition & 1 deletion api/db/services/system_settings_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_by_name(cls, name):
@DB.connection_context()
def update_by_name(cls, name, obj):
obj["update_time"] = current_timestamp()
obj["update_date"] = datetime_format(datetime.now())
obj["update_date"] = datetime_format(datetime.utcnow())
cls.model.update(obj).where(cls.model.name == name).execute()
return SystemSettings(**obj)

Expand Down
13 changes: 8 additions & 5 deletions api/db/services/task_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def get_task(cls, task_id, doc_ids=[]):
if not docs:
return None

msg = f"\n{datetime.now().strftime('%H:%M:%S')} Task has been received."
msg = f"\n{datetime.utcnow().strftime('%H:%M:%S')} Task has been received."
prog = random.random() / 10.0
if docs[0]["retry_count"] >= 3:
msg = "\nERROR: Task is abandoned after 3 times attempts."
Expand Down Expand Up @@ -342,7 +342,10 @@ def update_progress(cls, id, info):
((prog == -1) | (prog > cls.model.progress))))
).execute()

process_duration = (datetime.now() - task.begin_at).total_seconds()
if task.begin_at:
process_duration = max((datetime.utcnow() - task.begin_at).total_seconds(), 0)
else:
process_duration = 0
cls.model.update(process_duration=process_duration).where(cls.model.id == id).execute()

@classmethod
Expand Down Expand Up @@ -380,7 +383,7 @@ def new_task():
"progress": 0.0,
"from_page": 0,
"to_page": 100000000,
"begin_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"begin_at": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
}

parse_task_array = []
Expand Down Expand Up @@ -500,7 +503,7 @@ def reuse_prev_task_chunks(task: dict, prev_tasks: list[dict], chunking_config:
else:
task["progress_msg"] = ""
task["progress_msg"] = " ".join(
[datetime.now().strftime("%H:%M:%S"), task["progress_msg"], "Reused previous task's chunks."])
[datetime.utcnow().strftime("%H:%M:%S"), task["progress_msg"], "Reused previous task's chunks."])
prev_task["chunk_ids"] = ""

return len(task["chunk_ids"].split())
Expand Down Expand Up @@ -533,7 +536,7 @@ def queue_dataflow(tenant_id:str, flow_id:str, task_id:str, doc_id:str=CANVAS_DE
to_page=100000000,
task_type="dataflow" if not rerun else "dataflow_rerun",
priority=priority,
begin_at= datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
begin_at= datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
)
if doc_id not in [CANVAS_DEBUG_DOC_ID, GRAPH_RAPTOR_FAKE_DOC_ID]:
TaskService.model.delete().where(TaskService.model.doc_id == doc_id).execute()
Expand Down
6 changes: 3 additions & 3 deletions api/db/services/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def save(cls, **kwargs):
str(kwargs["password"]))

current_ts = current_timestamp()
current_date = datetime_format(datetime.now())
current_date = datetime_format(datetime.utcnow())

kwargs["create_time"] = current_ts
kwargs["create_date"] = current_date
Expand All @@ -139,7 +139,7 @@ def update_user(cls, user_id, user_dict):
with DB.atomic():
if user_dict:
user_dict["update_time"] = current_timestamp()
user_dict["update_date"] = datetime_format(datetime.now())
user_dict["update_date"] = datetime_format(datetime.utcnow())
cls.model.update(user_dict).where(
cls.model.id == user_id).execute()

Expand All @@ -150,7 +150,7 @@ def update_user_password(cls, user_id, new_password):
update_dict = {
"password": generate_password_hash(str(new_password)),
"update_time": current_timestamp(),
"update_date": datetime_format(datetime.now())
"update_date": datetime_format(datetime.utcnow())
}
cls.model.update(update_dict).where(cls.model.id == user_id).execute()

Expand Down
4 changes: 2 additions & 2 deletions api/utils/health_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
from datetime import datetime
from datetime import datetime, timezone
import json
import os
import requests
Expand Down Expand Up @@ -309,7 +309,7 @@ def check_task_executor_alive():
task_executor_heartbeats = {}
try:
task_executors = REDIS_CONN.smembers("TASKEXE")
now = datetime.now().timestamp()
now = datetime.now(timezone.utc).timestamp()
for task_executor_id in task_executors:
heartbeats = REDIS_CONN.zrangebyscore(task_executor_id, now - 60 * 30, now)
heartbeats = [json.loads(heartbeat) for heartbeat in heartbeats]
Expand Down
Loading
Loading