Refactor datetime handling to use utc_now utility

Replaced multiple occurrences of `datetime.now(timezone.utc)` with
a single `utc_now` utility function across various modules. This
enhances code consistency and reusability, and reduces redundancy.

No behavioral changes are intended; only the implementation detail
is modified to leverage the utility function for getting the current
UTC datetime.

Fixes #1234
```
This commit is contained in:
Rodrigo 2024-06-16 16:44:59 -03:00
commit 29a31083e5
11 changed files with 37 additions and 22 deletions

View file

@ -19,6 +19,7 @@ from langflow.services.database.models.folder.model import Folder
from langflow.services.database.models.user.model import User
from langflow.services.deps import get_session, get_settings_service
from langflow.services.settings.service import SettingsService
from langflow.utils.util import utc_now
# build router
router = APIRouter(prefix="/flows", tags=["Flows"])
@ -52,7 +53,7 @@ def create_flow(
flow.name = f"{flow.name} (1)"
db_flow = Flow.model_validate(flow, from_attributes=True)
db_flow.updated_at = datetime.now(timezone.utc)
db_flow.updated_at = utc_now()
if db_flow.folder_id is None:
# Make sure flows always have a folder
@ -188,7 +189,7 @@ def update_flow(
setattr(db_flow, key, value)
webhook_component = get_webhook_component_in_flow(db_flow.data)
db_flow.webhook = webhook_component is not None
db_flow.updated_at = datetime.now(timezone.utc)
db_flow.updated_at = utc_now()
if db_flow.folder_id is None:
default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first()
if default_folder:

View file

@ -14,6 +14,7 @@ from langflow.services.database.models.api_key.model import ApiKeyRead
from langflow.services.database.models.base import orjson_dumps
from langflow.services.database.models.flow import FlowCreate, FlowRead
from langflow.services.database.models.user import UserRead
from langflow.utils.util import utc_now
class BuildStatus(Enum):
@ -263,7 +264,7 @@ class VertexBuildResponse(BaseModel):
"""JSON string of the params."""
data: ResultDataResponse
"""Mapping of vertex ids to result dict containing the param name and result value."""
timestamp: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc))
timestamp: Optional[datetime] = Field(default_factory=lambda: utc_now())
"""Timestamp of the build."""

View file

@ -9,6 +9,7 @@ from langflow.services.auth.utils import get_current_active_user
from langflow.services.database.models.user.model import User
from langflow.services.database.models.variable import Variable, VariableCreate, VariableRead, VariableUpdate
from langflow.services.deps import get_session, get_settings_service
from langflow.utils.util import utc_now
router = APIRouter(prefix="/variables", tags=["Variables"])
@ -89,7 +90,7 @@ def update_variable(
variable_data = variable.model_dump(exclude_unset=True)
for key, value in variable_data.items():
setattr(db_variable, key, value)
db_variable.updated_at = datetime.now(timezone.utc)
db_variable.updated_at = utc_now()
session.commit()
session.refresh(db_variable)
return db_variable

View file

@ -8,7 +8,7 @@ from pydantic import BeforeValidator, ConfigDict, Field, field_serializer
from langflow.schema.data import Data
from langflow.schema.image import Image, get_file_paths, is_image_file
from langflow.utils.util import utc_now
def _timestamp_to_str(timestamp: datetime) -> str:
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
@ -24,7 +24,7 @@ class Message(Data):
files: Optional[list[str | Image]] = Field(default=[])
session_id: Optional[str] = Field(default="")
timestamp: Annotated[str, BeforeValidator(_timestamp_to_str)] = Field(
default=datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
default=utc_now(stringify=True)
)
flow_id: Optional[str] = None
@ -41,7 +41,7 @@ class Message(Data):
self,
) -> BaseMessage:
"""
Converts the Data to a BaseMessage.
Converts the Data into a BaseMessage.
Returns:
BaseMessage: The converted BaseMessage.

View file

@ -16,6 +16,8 @@ from langflow.services.database.models.api_key.model import ApiKey
from langflow.services.database.models.user.crud import get_user_by_id, get_user_by_username, update_user_last_login_at
from langflow.services.database.models.user.model import User
from langflow.services.deps import get_session, get_settings_service
from langflow.utils.util import utc_now
oauth2_login = OAuth2PasswordBearer(tokenUrl="api/v1/login", auto_error=False)
@ -112,7 +114,7 @@ async def get_current_user_by_jwt(
token_type: str = payload.get("type")
if expires := payload.get("exp", None):
expires_datetime = datetime.fromtimestamp(expires, timezone.utc)
if datetime.now(timezone.utc) > expires_datetime:
if utc_now() > expires_datetime:
logger.info("Token expired for user")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
@ -189,7 +191,7 @@ def create_token(data: dict, expires_delta: timedelta):
settings_service = get_settings_service()
to_encode = data.copy()
expire = datetime.now(timezone.utc) + expires_delta
expire = utc_now() + expires_delta
to_encode["exp"] = expire
return jwt.encode(

View file

@ -5,14 +5,13 @@ from uuid import UUID, uuid4
from pydantic import field_validator
from sqlmodel import Column, DateTime, Field, Relationship, SQLModel, func
from langflow.utils.util import utc_now
if TYPE_CHECKING:
from langflow.services.database.models.user import User
def utc_now():
return datetime.now(timezone.utc)
class ApiKeyBase(SQLModel):
name: Optional[str] = Field(index=True, nullable=True, default=None)
last_used_at: Optional[datetime] = Field(default=None, nullable=True)

View file

@ -14,6 +14,7 @@ from sqlalchemy import UniqueConstraint
from sqlmodel import JSON, Column, Field, Relationship, SQLModel
from langflow.schema import Data
from langflow.utils.util import utc_now
if TYPE_CHECKING:
from langflow.services.database.models.folder import Folder
@ -27,7 +28,7 @@ class FlowBase(SQLModel):
icon_bg_color: Optional[str] = Field(default=None, nullable=True)
data: Optional[Dict] = Field(default=None, nullable=True)
is_component: Optional[bool] = Field(default=False, nullable=True)
updated_at: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc), nullable=True)
updated_at: Optional[datetime] = Field(default_factory=lambda: utc_now(), nullable=True)
webhook: Optional[bool] = Field(default=False, nullable=True, description="Can be used on the webhook endpoint")
endpoint_name: Optional[str] = Field(default=None, nullable=True, index=True)

View file

@ -9,6 +9,7 @@ from sqlmodel import Session, select
from langflow.services.database.models.user.model import User, UserUpdate
from langflow.services.deps import get_session
from langflow.utils.util import utc_now
def get_user_by_username(db: Session, username: str) -> Union[User, None]:
@ -37,7 +38,7 @@ def update_user(user_db: Optional[User], user: UserUpdate, db: Session = Depends
if not changed:
raise HTTPException(status_code=status.HTTP_304_NOT_MODIFIED, detail="Nothing to update")
user_db.updated_at = datetime.now(timezone.utc)
user_db.updated_at = utc_now()
flag_modified(user_db, "updated_at")
try:
@ -51,7 +52,7 @@ def update_user(user_db: Optional[User], user: UserUpdate, db: Session = Depends
def update_user_last_login_at(user_id: UUID, db: Session = Depends(get_session)):
try:
user_data = UserUpdate(last_login_at=datetime.now(timezone.utc)) # type: ignore
user_data = UserUpdate(last_login_at=utc_now()) # type: ignore
user = get_user_by_id(db, user_id)
return update_user(user, user_data, db)
except Exception:

View file

@ -4,6 +4,8 @@ from uuid import UUID, uuid4
from sqlmodel import Field, Relationship, SQLModel
from langflow.utils.util import utc_now
if TYPE_CHECKING:
from langflow.services.database.models.api_key import ApiKey
from langflow.services.database.models.variable import Variable
@ -18,8 +20,8 @@ class User(SQLModel, table=True):
profile_image: Optional[str] = Field(default=None, nullable=True)
is_active: bool = Field(default=False)
is_superuser: bool = Field(default=False)
create_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
create_at: datetime = Field(default_factory=lambda: utc_now())
updated_at: datetime = Field(default_factory=lambda: utc_now())
last_login_at: Optional[datetime] = Field(default=None, nullable=True)
api_keys: list["ApiKey"] = Relationship(
back_populates="user",

View file

@ -4,14 +4,13 @@ from uuid import UUID, uuid4
from sqlmodel import JSON, Column, DateTime, Field, Relationship, SQLModel, func
from langflow.utils.util import utc_now
if TYPE_CHECKING:
from langflow.services.database.models.user.model import User
def utc_now():
return datetime.now(timezone.utc)
class VariableBase(SQLModel):
name: str = Field(description="Name of the variable")
value: str = Field(description="Encrypted value of the variable")

View file

@ -4,6 +4,7 @@ import re
from functools import wraps
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from datetime import datetime, timezone
from docstring_parser import parse
@ -14,6 +15,13 @@ from langflow.utils import constants
from langflow.utils.logger import logger
def utc_now(stringify=False):
if stringify:
return datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
return datetime.now(timezone.utc)
def unescape_string(s: str):
# Replace escaped new line characters with actual new line characters
return s.replace("\\n", "\n")