Fix time zone problem of doc status
This commit is contained in:
@@ -9,7 +9,7 @@ import aiofiles
|
|||||||
import shutil
|
import shutil
|
||||||
import traceback
|
import traceback
|
||||||
import pipmaster as pm
|
import pipmaster as pm
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Any, Literal
|
from typing import Dict, List, Optional, Any, Literal
|
||||||
from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile
|
from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile
|
||||||
@@ -20,6 +20,30 @@ from lightrag.base import DocProcessingStatus, DocStatus
|
|||||||
from lightrag.api.utils_api import get_combined_auth_dependency
|
from lightrag.api.utils_api import get_combined_auth_dependency
|
||||||
from ..config import global_args
|
from ..config import global_args
|
||||||
|
|
||||||
|
# Function to format datetime to ISO format string with timezone information
|
||||||
|
def format_datetime(dt: Any) -> Optional[str]:
|
||||||
|
"""Format datetime to ISO format string with timezone information
|
||||||
|
|
||||||
|
Args:
|
||||||
|
dt: Datetime object, string, or None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ISO format string with timezone information, or None if input is None
|
||||||
|
"""
|
||||||
|
if dt is None:
|
||||||
|
return None
|
||||||
|
if isinstance(dt, str):
|
||||||
|
return dt
|
||||||
|
|
||||||
|
# Check if datetime object has timezone information
|
||||||
|
if isinstance(dt, datetime):
|
||||||
|
# If datetime object has no timezone info (naive datetime), add UTC timezone
|
||||||
|
if dt.tzinfo is None:
|
||||||
|
dt = dt.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
# Return ISO format string with timezone information
|
||||||
|
return dt.isoformat()
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/documents",
|
prefix="/documents",
|
||||||
tags=["documents"],
|
tags=["documents"],
|
||||||
@@ -207,14 +231,6 @@ Attributes:
|
|||||||
|
|
||||||
|
|
||||||
class DocStatusResponse(BaseModel):
|
class DocStatusResponse(BaseModel):
|
||||||
@staticmethod
|
|
||||||
def format_datetime(dt: Any) -> Optional[str]:
|
|
||||||
if dt is None:
|
|
||||||
return None
|
|
||||||
if isinstance(dt, str):
|
|
||||||
return dt
|
|
||||||
return dt.isoformat()
|
|
||||||
|
|
||||||
id: str = Field(description="Document identifier")
|
id: str = Field(description="Document identifier")
|
||||||
content_summary: str = Field(description="Summary of document content")
|
content_summary: str = Field(description="Summary of document content")
|
||||||
content_length: int = Field(description="Length of document content in characters")
|
content_length: int = Field(description="Length of document content in characters")
|
||||||
@@ -300,7 +316,7 @@ class PipelineStatusResponse(BaseModel):
|
|||||||
autoscanned: Whether auto-scan has started
|
autoscanned: Whether auto-scan has started
|
||||||
busy: Whether the pipeline is currently busy
|
busy: Whether the pipeline is currently busy
|
||||||
job_name: Current job name (e.g., indexing files/indexing texts)
|
job_name: Current job name (e.g., indexing files/indexing texts)
|
||||||
job_start: Job start time as ISO format string (optional)
|
job_start: Job start time as ISO format string with timezone (optional)
|
||||||
docs: Total number of documents to be indexed
|
docs: Total number of documents to be indexed
|
||||||
batchs: Number of batches for processing documents
|
batchs: Number of batches for processing documents
|
||||||
cur_batch: Current processing batch
|
cur_batch: Current processing batch
|
||||||
@@ -322,6 +338,12 @@ class PipelineStatusResponse(BaseModel):
|
|||||||
history_messages: Optional[List[str]] = None
|
history_messages: Optional[List[str]] = None
|
||||||
update_status: Optional[dict] = None
|
update_status: Optional[dict] = None
|
||||||
|
|
||||||
|
@field_validator('job_start', mode='before')
|
||||||
|
@classmethod
|
||||||
|
def parse_job_start(cls, value):
|
||||||
|
"""Process datetime and return as ISO format string with timezone"""
|
||||||
|
return format_datetime(value)
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
extra = "allow" # Allow additional fields from the pipeline status
|
extra = "allow" # Allow additional fields from the pipeline status
|
||||||
|
|
||||||
@@ -1188,9 +1210,10 @@ def create_document_routes(
|
|||||||
if "history_messages" in status_dict:
|
if "history_messages" in status_dict:
|
||||||
status_dict["history_messages"] = list(status_dict["history_messages"])
|
status_dict["history_messages"] = list(status_dict["history_messages"])
|
||||||
|
|
||||||
# Format the job_start time if it exists
|
# Ensure job_start is properly formatted as a string with timezone information
|
||||||
if status_dict.get("job_start"):
|
if "job_start" in status_dict and status_dict["job_start"]:
|
||||||
status_dict["job_start"] = str(status_dict["job_start"])
|
# Use format_datetime to ensure consistent formatting
|
||||||
|
status_dict["job_start"] = format_datetime(status_dict["job_start"])
|
||||||
|
|
||||||
return PipelineStatusResponse(**status_dict)
|
return PipelineStatusResponse(**status_dict)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1240,10 +1263,10 @@ def create_document_routes(
|
|||||||
content_summary=doc_status.content_summary,
|
content_summary=doc_status.content_summary,
|
||||||
content_length=doc_status.content_length,
|
content_length=doc_status.content_length,
|
||||||
status=doc_status.status,
|
status=doc_status.status,
|
||||||
created_at=DocStatusResponse.format_datetime(
|
created_at=format_datetime(
|
||||||
doc_status.created_at
|
doc_status.created_at
|
||||||
),
|
),
|
||||||
updated_at=DocStatusResponse.format_datetime(
|
updated_at=format_datetime(
|
||||||
doc_status.updated_at
|
doc_status.updated_at
|
||||||
),
|
),
|
||||||
chunks_count=doc_status.chunks_count,
|
chunks_count=doc_status.chunks_count,
|
||||||
|
@@ -6,7 +6,7 @@ import configparser
|
|||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from dataclasses import asdict, dataclass, field
|
from dataclasses import asdict, dataclass, field
|
||||||
from datetime import datetime
|
from datetime import datetime, timezone
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
@@ -756,8 +756,8 @@ class LightRAG:
|
|||||||
"content": content_data["content"],
|
"content": content_data["content"],
|
||||||
"content_summary": get_content_summary(content_data["content"]),
|
"content_summary": get_content_summary(content_data["content"]),
|
||||||
"content_length": len(content_data["content"]),
|
"content_length": len(content_data["content"]),
|
||||||
"created_at": datetime.now().isoformat(),
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||||
"updated_at": datetime.now().isoformat(),
|
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
"file_path": content_data[
|
"file_path": content_data[
|
||||||
"file_path"
|
"file_path"
|
||||||
], # Store file path in document status
|
], # Store file path in document status
|
||||||
@@ -840,7 +840,7 @@ class LightRAG:
|
|||||||
{
|
{
|
||||||
"busy": True,
|
"busy": True,
|
||||||
"job_name": "Default Job",
|
"job_name": "Default Job",
|
||||||
"job_start": datetime.now().isoformat(),
|
"job_start": datetime.now(timezone.utc).isoformat(),
|
||||||
"docs": 0,
|
"docs": 0,
|
||||||
"batchs": 0, # Total number of files to be processed
|
"batchs": 0, # Total number of files to be processed
|
||||||
"cur_batch": 0, # Number of files already processed
|
"cur_batch": 0, # Number of files already processed
|
||||||
@@ -958,7 +958,7 @@ class LightRAG:
|
|||||||
"content_summary": status_doc.content_summary,
|
"content_summary": status_doc.content_summary,
|
||||||
"content_length": status_doc.content_length,
|
"content_length": status_doc.content_length,
|
||||||
"created_at": status_doc.created_at,
|
"created_at": status_doc.created_at,
|
||||||
"updated_at": datetime.now().isoformat(),
|
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
"file_path": file_path,
|
"file_path": file_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,7 +1018,7 @@ class LightRAG:
|
|||||||
"content_summary": status_doc.content_summary,
|
"content_summary": status_doc.content_summary,
|
||||||
"content_length": status_doc.content_length,
|
"content_length": status_doc.content_length,
|
||||||
"created_at": status_doc.created_at,
|
"created_at": status_doc.created_at,
|
||||||
"updated_at": datetime.now().isoformat(),
|
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
"file_path": file_path,
|
"file_path": file_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1053,7 @@ class LightRAG:
|
|||||||
"content_summary": status_doc.content_summary,
|
"content_summary": status_doc.content_summary,
|
||||||
"content_length": status_doc.content_length,
|
"content_length": status_doc.content_length,
|
||||||
"created_at": status_doc.created_at,
|
"created_at": status_doc.created_at,
|
||||||
"updated_at": datetime.now().isoformat(),
|
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||||
"file_path": file_path,
|
"file_path": file_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -158,7 +158,16 @@ export default function PipelineStatusDialog({
|
|||||||
<div className="rounded-md border p-3 space-y-2">
|
<div className="rounded-md border p-3 space-y-2">
|
||||||
<div>{t('documentPanel.pipelineStatus.jobName')}: {status?.job_name || '-'}</div>
|
<div>{t('documentPanel.pipelineStatus.jobName')}: {status?.job_name || '-'}</div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span>{t('documentPanel.pipelineStatus.startTime')}: {status?.job_start ? new Date(status.job_start).toLocaleString() : '-'}</span>
|
<span>{t('documentPanel.pipelineStatus.startTime')}: {status?.job_start
|
||||||
|
? new Date(status.job_start).toLocaleString(undefined, {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'numeric',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
second: 'numeric'
|
||||||
|
})
|
||||||
|
: '-'}</span>
|
||||||
<span>{t('documentPanel.pipelineStatus.progress')}: {status ? `${status.cur_batch}/${status.batchs} ${t('documentPanel.pipelineStatus.unit')}` : '-'}</span>
|
<span>{t('documentPanel.pipelineStatus.progress')}: {status ? `${status.cur_batch}/${status.batchs} ${t('documentPanel.pipelineStatus.unit')}` : '-'}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user