Update datetime handling in ApiKey and Variable models (#1673)
* Update datetime handling in ApiKey and Variable models * Refactor test_login_successful function in test_login.py * Fix nullable attribute for created_at and updated_at fields in Variable model
This commit is contained in:
parent
4ee9b72634
commit
836ac08d80
6 changed files with 24 additions and 18 deletions
|
|
@ -9,7 +9,6 @@ from typing import Sequence, Union
|
|||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import postgresql
|
||||
from sqlalchemy.engine.reflection import Inspector
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
|
|
@ -35,7 +34,9 @@ def upgrade() -> None:
|
|||
"created_at",
|
||||
existing_type=sa.TIMESTAMP(timezone=True),
|
||||
nullable=True,
|
||||
existing_server_default=sa.text("now()"),
|
||||
# existing_server_default expects str | bool | Identity | Computed | None
|
||||
# sa.text("now()") is not a valid value for existing_server_default
|
||||
existing_server_default=False,
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -54,7 +55,7 @@ def downgrade() -> None:
|
|||
"created_at",
|
||||
existing_type=sa.TIMESTAMP(timezone=True),
|
||||
nullable=False,
|
||||
existing_server_default=sa.text("now()"),
|
||||
existing_server_default=False,
|
||||
)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from pydantic import validator
|
||||
from pydantic import field_validator, validator
|
||||
from sqlmodel import Field, Relationship, SQLModel, Column, func, DateTime
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -11,7 +11,9 @@ if TYPE_CHECKING:
|
|||
|
||||
class ApiKeyBase(SQLModel):
|
||||
name: Optional[str] = Field(index=True, nullable=True, default=None)
|
||||
created_at: datetime = Field(sa_column=Column(DateTime(timezone=True), server_default=func.now(), nullable=False))
|
||||
created_at: datetime = Field(
|
||||
default=None, sa_column=Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
|
||||
)
|
||||
last_used_at: Optional[datetime] = Field(default=None, nullable=True)
|
||||
total_uses: int = Field(default=0)
|
||||
is_active: bool = Field(default=True)
|
||||
|
|
@ -33,6 +35,10 @@ class ApiKeyCreate(ApiKeyBase):
|
|||
api_key: Optional[str] = None
|
||||
user_id: Optional[UUID] = None
|
||||
|
||||
@field_validator("created_at", mode="before")
|
||||
def set_created_at(cls, v):
|
||||
return v or datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class UnmaskedApiKeyRead(ApiKeyBase):
|
||||
id: UUID
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@ class Variable(VariableBase, table=True):
|
|||
)
|
||||
# name is unique per user
|
||||
created_at: datetime = Field(
|
||||
default=None,
|
||||
sa_column=Column(DateTime(timezone=True), server_default=func.now(), nullable=True),
|
||||
description="Creation time of the variable",
|
||||
)
|
||||
updated_at: Optional[datetime] = Field(
|
||||
default=None,
|
||||
sa_column=Column(DateTime(timezone=True), nullable=True),
|
||||
description="Last update time of the variable",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import pytest
|
||||
|
||||
from langflow.services.database.models.api_key import ApiKeyCreate
|
||||
|
||||
|
||||
|
|
@ -7,7 +6,7 @@ from langflow.services.database.models.api_key import ApiKeyCreate
|
|||
def api_key(client, logged_in_headers, active_user):
|
||||
api_key = ApiKeyCreate(name="test-api-key")
|
||||
|
||||
response = client.post("api/v1/api_key", data=api_key.json(), headers=logged_in_headers)
|
||||
response = client.post("api/v1/api_key", data=api_key.model_dump_json(), headers=logged_in_headers)
|
||||
assert response.status_code == 200, response.text
|
||||
return response.json()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from langflow.graph.graph.base import Graph
|
||||
from langflow.graph.schema import RunOutputs
|
||||
from langflow.initial_setup.setup import (
|
||||
STARTER_FOLDER_NAME,
|
||||
create_or_update_starter_projects,
|
||||
get_project_data,
|
||||
load_starter_projects,
|
||||
)
|
||||
from langflow.memory import delete_messages
|
||||
from langflow.processing.process import process_tweaks
|
||||
from langflow.services.database.models.flow.model import Flow
|
||||
from langflow.services.deps import session_scope
|
||||
from sqlalchemy import func
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import pytest
|
||||
from langflow.services.auth.utils import get_password_hash
|
||||
from langflow.services.database.models.user import User
|
||||
from langflow.services.database.utils import session_getter
|
||||
from langflow.services.deps import get_db_service
|
||||
from langflow.services.deps import session_scope
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -17,9 +17,12 @@ def test_user():
|
|||
|
||||
def test_login_successful(client, test_user):
|
||||
# Adding the test user to the database
|
||||
with session_getter(get_db_service()) as session:
|
||||
session.add(test_user)
|
||||
session.commit()
|
||||
try:
|
||||
with session_scope() as session:
|
||||
session.add(test_user)
|
||||
session.commit()
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
response = client.post("api/v1/login", data={"username": "testuser", "password": "testpassword"})
|
||||
assert response.status_code == 200
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue