diff --git a/pyproject.toml b/pyproject.toml index 1d6a48157..15f0a0e50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "0.5.0b0" +version = "0.5.0b1" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ diff --git a/src/backend/langflow/alembic/versions/eb5866d51fd2_change_columns_to_be_nullable.py b/src/backend/langflow/alembic/versions/eb5866d51fd2_change_columns_to_be_nullable.py new file mode 100644 index 000000000..4bfc38461 --- /dev/null +++ b/src/backend/langflow/alembic/versions/eb5866d51fd2_change_columns_to_be_nullable.py @@ -0,0 +1,80 @@ +"""Change columns to be nullable + +Revision ID: eb5866d51fd2 +Revises: 67cc006d50bf +Create Date: 2023-10-04 10:18:25.640458 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlmodel + + +# revision identifiers, used by Alembic. +revision: str = "eb5866d51fd2" +down_revision: Union[str, None] = "67cc006d50bf" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + try: + op.drop_table("flowstyle") + with op.batch_alter_table("component", schema=None) as batch_op: + batch_op.drop_index("ix_component_frontend_node_id") + batch_op.drop_index("ix_component_name") + except Exception: + pass + + try: + op.drop_table("component") + except Exception: + pass + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + try: + op.create_table( + "component", + sa.Column("id", sa.CHAR(length=32), nullable=False), + sa.Column("frontend_node_id", sa.CHAR(length=32), nullable=False), + sa.Column("name", sa.VARCHAR(), nullable=False), + sa.Column("description", sa.VARCHAR(), nullable=True), + sa.Column("python_code", sa.VARCHAR(), nullable=True), + sa.Column("return_type", sa.VARCHAR(), nullable=True), + sa.Column("is_disabled", sa.BOOLEAN(), nullable=False), + sa.Column("is_read_only", sa.BOOLEAN(), nullable=False), + sa.Column("create_at", sa.DATETIME(), nullable=False), + sa.Column("update_at", sa.DATETIME(), nullable=False), + sa.PrimaryKeyConstraint("id"), + ) + with op.batch_alter_table("component", schema=None) as batch_op: + batch_op.create_index("ix_component_name", ["name"], unique=False) + batch_op.create_index( + "ix_component_frontend_node_id", ["frontend_node_id"], unique=False + ) + except Exception: + pass + + try: + op.create_table( + "flowstyle", + sa.Column("color", sa.VARCHAR(), nullable=False), + sa.Column("emoji", sa.VARCHAR(), nullable=False), + sa.Column("flow_id", sa.CHAR(length=32), nullable=True), + sa.Column("id", sa.CHAR(length=32), nullable=False), + sa.ForeignKeyConstraint( + ["flow_id"], + ["flow.id"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("id"), + ) + except Exception: + pass + # ### end Alembic commands ### diff --git a/src/backend/langflow/services/database/models/api_key/api_key.py b/src/backend/langflow/services/database/models/api_key/api_key.py index 35aa6c7a9..684027ee2 100644 --- a/src/backend/langflow/services/database/models/api_key/api_key.py +++ b/src/backend/langflow/services/database/models/api_key/api_key.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: class ApiKeyBase(SQLModelSerializable): name: Optional[str] = Field(index=True) created_at: datetime = Field(default_factory=datetime.utcnow) - last_used_at: Optional[datetime] = Field(default=None) + last_used_at: Optional[datetime] = Field(default=None, nullable=True) total_uses: int = Field(default=0) is_active: bool = Field(default=True) diff --git a/src/backend/langflow/services/database/models/flow/flow.py b/src/backend/langflow/services/database/models/flow/flow.py index e6ad4af4a..e578f37c4 100644 --- a/src/backend/langflow/services/database/models/flow/flow.py +++ b/src/backend/langflow/services/database/models/flow/flow.py @@ -2,6 +2,7 @@ from langflow.services.database.models.base import SQLModelSerializable from pydantic import validator + from sqlmodel import Field, JSON, Column, Relationship from uuid import UUID, uuid4 from typing import Dict, Optional, TYPE_CHECKING @@ -13,7 +14,7 @@ if TYPE_CHECKING: class FlowBase(SQLModelSerializable): name: str = Field(index=True) description: Optional[str] = Field(index=True) - data: Optional[Dict] = Field(default=None) + data: Optional[Dict] = Field(default=None, nullable=True) @validator("data") def validate_json(v): diff --git a/src/backend/langflow/services/database/models/user/user.py b/src/backend/langflow/services/database/models/user/user.py index 5f2f3e1c4..b1f514531 100644 --- a/src/backend/langflow/services/database/models/user/user.py +++ b/src/backend/langflow/services/database/models/user/user.py @@ -15,7 +15,7 @@ class User(SQLModelSerializable, table=True): id: UUID = Field(default_factory=uuid4, primary_key=True, unique=True) username: str = Field(index=True, unique=True) password: str = Field() - profile_image: Optional[str] = Field(default=None) + 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=datetime.utcnow) diff --git a/src/backend/langflow/services/manager.py b/src/backend/langflow/services/manager.py index e74146a20..496544829 100644 --- a/src/backend/langflow/services/manager.py +++ b/src/backend/langflow/services/manager.py @@ -99,51 +99,6 @@ class ServiceManager: service_manager = ServiceManager() -def initialize_services(): - """ - Initialize all the services needed. - """ - from langflow.services.database import factory as database_factory - from langflow.services.cache import factory as cache_factory - from langflow.services.chat import factory as chat_factory - from langflow.services.settings import factory as settings_factory - from langflow.services.session import factory as session_service_factory - from langflow.services.auth import factory as auth_factory - from langflow.services.task import factory as task_factory - - service_manager.register_factory(settings_factory.SettingsServiceFactory()) - service_manager.register_factory( - database_factory.DatabaseServiceFactory(), - dependencies=[ServiceType.SETTINGS_SERVICE], - ) - service_manager.register_factory( - cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE] - ) - - service_manager.register_factory( - auth_factory.AuthServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE] - ) - - service_manager.register_factory(chat_factory.ChatServiceFactory()) - service_manager.register_factory( - session_service_factory.SessionServiceFactory(), - dependencies=[ServiceType.CACHE_SERVICE], - ) - service_manager.register_factory( - task_factory.TaskServiceFactory(), - ) - - # Test cache connection - service_manager.get(ServiceType.CACHE_SERVICE) - # Test database connection - service_manager.get(ServiceType.DATABASE_SERVICE) - - # Test cache connection - service_manager.get(ServiceType.CACHE_SERVICE) - # Test database connection - service_manager.get(ServiceType.DATABASE_SERVICE) - - def reinitialize_services(): """ Reinitialize all the services needed. diff --git a/src/backend/langflow/services/utils.py b/src/backend/langflow/services/utils.py index b7d93184f..c17963bc3 100644 --- a/src/backend/langflow/services/utils.py +++ b/src/backend/langflow/services/utils.py @@ -11,6 +11,37 @@ from .getters import get_db_service, get_session, get_settings_service from loguru import logger +from langflow.services.database import factory as database_factory +from langflow.services.cache import factory as cache_factory +from langflow.services.chat import factory as chat_factory +from langflow.services.settings import factory as settings_factory +from langflow.services.auth import factory as auth_factory +from langflow.services.task import factory as task_factory +from langflow.services.session import factory as session_service_factory # type: ignore + +FACTORIES_AND_DEPS = [ + (settings_factory.SettingsServiceFactory(), []), + ( + auth_factory.AuthServiceFactory(), + [ServiceType.SETTINGS_SERVICE], + ), + ( + database_factory.DatabaseServiceFactory(), + [ServiceType.SETTINGS_SERVICE], + ), + ( + cache_factory.CacheServiceFactory(), + [ServiceType.SETTINGS_SERVICE], + ), + (chat_factory.ChatServiceFactory(), []), + (task_factory.TaskServiceFactory(), []), + ( + session_service_factory.SessionServiceFactory(), + [ServiceType.CACHE_SERVICE], + ), +] + + def get_or_create_super_user(session: Session, username, password, is_default): from langflow.services.database.models.user.user import User @@ -99,17 +130,21 @@ def teardown_superuser(settings_service, session): # from the database. if settings_service.auth_settings.AUTO_LOGIN: - logger.debug("AUTO_LOGIN is set to True. Removing default superuser.") - username = settings_service.auth_settings.SUPERUSER - from langflow.services.database.models.user.user import User + try: + logger.debug("AUTO_LOGIN is set to True. Removing default superuser.") + username = settings_service.auth_settings.SUPERUSER + from langflow.services.database.models.user.user import User - user = session.query(User).filter(User.username == username).first() - if user and user.is_superuser: - session.delete(user) - session.commit() - logger.debug("Default superuser removed successfully.") - else: - logger.debug("Default superuser not found.") + user = session.query(User).filter(User.username == username).first() + if user and user.is_superuser: + session.delete(user) + session.commit() + logger.debug("Default superuser removed successfully.") + else: + logger.debug("Default superuser not found.") + except Exception as exc: + logger.exception(exc) + raise RuntimeError("Could not remove default superuser.") from exc def teardown_services(): @@ -155,36 +190,7 @@ def initialize_services(): """ Initialize all the services needed. """ - from langflow.services.database import factory as database_factory - from langflow.services.cache import factory as cache_factory - from langflow.services.chat import factory as chat_factory - from langflow.services.settings import factory as settings_factory - from langflow.services.auth import factory as auth_factory - from langflow.services.task import factory as task_factory - from langflow.services.session import factory as session_service_factory # type: ignore - - factory_and_dependencies = [ - (settings_factory.SettingsServiceFactory(), []), - ( - auth_factory.AuthServiceFactory(), - [ServiceType.SETTINGS_SERVICE], - ), - ( - database_factory.DatabaseServiceFactory(), - [ServiceType.SETTINGS_SERVICE], - ), - ( - cache_factory.CacheServiceFactory(), - [ServiceType.SETTINGS_SERVICE], - ), - (chat_factory.ChatServiceFactory(), []), - (task_factory.TaskServiceFactory(), []), - ( - session_service_factory.SessionServiceFactory(), - [ServiceType.CACHE_SERVICE], - ), - ] - for factory, dependencies in factory_and_dependencies: + for factory, dependencies in FACTORIES_AND_DEPS: try: service_manager.register_factory(factory, dependencies=dependencies) except Exception as exc: