Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into celery
Browse files Browse the repository at this point in the history
  • Loading branch information
ogabrielluiz committed Sep 22, 2023
2 parents a658f5a + 758d5ac commit b3febf2
Show file tree
Hide file tree
Showing 31 changed files with 598 additions and 279 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,10 @@ LANGFLOW_REMOVE_API_KEYS=
# LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600)
LANGFLOW_CACHE_TYPE=

# Superuser username
# Example: LANGFLOW_SUPERUSER=admin
LANGFLOW_SUPERUSER=

# Superuser password
# Example: LANGFLOW_SUPERUSER_PASSWORD=123456
LANGFLOW_SUPERUSER_PASSWORD=
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ coverage:
--cov-report term-missing:skip-covered

tests:
@make install_backend
poetry run pytest tests -n auto

format:
Expand Down
138 changes: 69 additions & 69 deletions poetry.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/backend/langflow/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ def superuser(
# Verify that the superuser was created
from langflow.services.database.models.user.user import User

user = session.query(User).filter(User.username == username).first()
if user is None:
user: User = session.query(User).filter(User.username == username).first()
if user is None or not user.is_superuser:
typer.echo("Superuser creation failed.")
return

Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/api/v1/api_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
delete_api_key,
)
from langflow.services.database.models.user.user import User
from langflow.services.utils import get_session
from langflow.services.getters import get_session
from sqlmodel import Session


Expand Down
4 changes: 2 additions & 2 deletions src/backend/langflow/api/v1/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

from langflow.graph.graph.base import Graph
from langflow.services.auth.utils import get_current_active_user, get_current_user
from langflow.services.utils import get_cache_service, get_session
from loguru import logger
from langflow.services.utils import get_chat_service
from langflow.services.getters import get_chat_service, get_session, get_cache_service
from cachetools import LRUCache
from sqlmodel import Session
from langflow.services.chat.manager import ChatService
from langflow.services.cache.manager import BaseCacheService
Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/api/v1/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import List
from uuid import UUID
from langflow.services.database.models.component import Component, ComponentModel
from langflow.services.utils import get_session
from langflow.services.getters import get_session
from sqlmodel import Session, select
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.exc import IntegrityError
Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/api/v1/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from langflow.services.database.models.flow import Flow
from langflow.processing.process import process_graph_cached, process_tweaks
from langflow.services.database.models.user.user import User
from langflow.services.utils import get_settings_service, get_task_service
from langflow.services.getters import get_settings_service, get_task_service
from loguru import logger
from fastapi import APIRouter, Depends, HTTPException, UploadFile, Body, status
import sqlalchemy as sa
Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/api/v1/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm

from langflow.services.utils import get_session
from langflow.services.getters import get_session
from langflow.api.v1.schemas import Token
from langflow.services.auth.utils import (
authenticate_user,
Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/api/v1/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from sqlmodel import Session, select
from fastapi import APIRouter, Depends, HTTPException

from langflow.services.utils import get_session
from langflow.services.getters import get_session
from langflow.services.auth.utils import (
get_current_active_superuser,
get_current_active_user,
Expand Down
11 changes: 7 additions & 4 deletions src/backend/langflow/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@


from langflow.interface.utils import setup_llm_caching
from langflow.services.database.utils import initialize_database
from langflow.services.manager import initialize_services, teardown_services
from langflow.services.utils import initialize_services
from langflow.services.plugins.langfuse import LangfuseInstance
from langflow.services.utils import (
teardown_services,
)
from langflow.utils.logger import configure


Expand Down Expand Up @@ -39,11 +41,12 @@ def health():
app.include_router(router)

app.on_event("startup")(initialize_services)
app.on_event("startup")(initialize_database)
app.on_event("startup")(setup_llm_caching)
app.on_event("shutdown")(teardown_services)
app.on_event("startup")(LangfuseInstance.update)

app.on_event("shutdown")(teardown_services)
app.on_event("shutdown")(LangfuseInstance.teardown)

return app


Expand Down
12 changes: 5 additions & 7 deletions src/backend/langflow/services/auth/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,13 @@ async def api_key_security(
result: Optional[Union[ApiKey, User]] = None
if settings_service.auth_settings.AUTO_LOGIN:
# Get the first user
if not settings_service.auth_settings.FIRST_SUPERUSER:
if not settings_manager.auth_settings.SUPERUSER:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Missing first superuser credentials",
)

result = get_user_by_username(
db, settings_service.auth_settings.FIRST_SUPERUSER
)
result = get_user_by_username(db, settings_manager.auth_settings.SUPERUSER)

elif not query_param and not header_param:
raise HTTPException(
Expand Down Expand Up @@ -181,9 +179,9 @@ def create_super_user(


def create_user_longterm_token(db: Session = Depends(get_session)) -> dict:
settings_service = get_settings_service()
username = settings_service.auth_settings.FIRST_SUPERUSER
password = settings_service.auth_settings.FIRST_SUPERUSER_PASSWORD
settings_manager = get_settings_service()
username = settings_manager.auth_settings.SUPERUSER
password = settings_manager.auth_settings.SUPERUSER_PASSWORD
if not username or not password:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
Expand Down
4 changes: 4 additions & 0 deletions src/backend/langflow/services/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

class Service(ABC):
name: str
ready: bool = False

def teardown(self):
pass

def set_ready(self):
self.ready = True
4 changes: 2 additions & 2 deletions src/backend/langflow/services/database/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ def teardown(self):
try:
settings_service = get_settings_service()
# remove the default superuser if auto_login is enabled
# using the FIRST_SUPERUSER to get the user
# using the SUPERUSER to get the user
if settings_service.auth_settings.AUTO_LOGIN:
logger.debug("Removing default superuser")
username = settings_service.auth_settings.FIRST_SUPERUSER
username = settings_service.auth_settings.SUPERUSER
with Session(self.engine) as session:
user = get_user_by_username(session, username)
session.delete(user)
Expand Down
2 changes: 1 addition & 1 deletion src/backend/langflow/services/database/models/user/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from uuid import UUID
from fastapi import Depends, HTTPException, status
from langflow.services.database.models.user.user import User, UserUpdate
from langflow.services.utils import get_session
from langflow.services.getters import get_session
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session
from typing import Optional
Expand Down
26 changes: 26 additions & 0 deletions src/backend/langflow/services/getters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from langflow.services import ServiceType, service_manager
from typing import TYPE_CHECKING, Generator


if TYPE_CHECKING:
from langflow.services.database.manager import DatabaseManager
from langflow.services.settings.manager import SettingsManager
from langflow.services.chat.manager import ChatManager
from sqlmodel import Session


def get_settings_manager() -> "SettingsManager":
return service_manager.get(ServiceType.SETTINGS_MANAGER)


def get_db_manager() -> "DatabaseManager":
return service_manager.get(ServiceType.DATABASE_MANAGER)


def get_session() -> Generator["Session", None, None]:
db_manager = service_manager.get(ServiceType.DATABASE_MANAGER)
yield from db_manager.get_session()


def get_chat_manager() -> "ChatManager":
return service_manager.get(ServiceType.CHAT_MANAGER)
43 changes: 22 additions & 21 deletions src/backend/langflow/services/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def _create_service(self, service_name: ServiceType):
self.services[service_name] = self.factories[service_name].create(
**dependent_services
)
self.services[service_name].set_ready()

def _validate_service_creation(self, service_name: ServiceType):
"""
Expand Down Expand Up @@ -113,34 +114,34 @@ def initialize_services():
service_manager.register_factory(settings_factory.SettingsServiceFactory())
service_manager.register_factory(
database_factory.DatabaseServiceFactory(),
dependencies=[ServiceType.SETTINGS_MANAGER],
dependencies=[ServiceType.SETTINGS_SERVICE],
)
service_manager.register_factory(
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER]
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE]
)

service_manager.register_factory(
auth_factory.AuthServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER]
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_MANAGER],
dependencies=[ServiceType.CACHE_SERVICE],
)
service_manager.register_factory(
task_factory.TaskServiceFactory(),
)

# Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER)
service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER)
service_manager.get(ServiceType.DATABASE_SERVICE)

# Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER)
service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER)
service_manager.get(ServiceType.DATABASE_SERVICE)


def reinitialize_services():
Expand All @@ -155,23 +156,23 @@ def reinitialize_services():
from langflow.services.auth import factory as auth_factory
from langflow.services.task import factory as task_factory

service_manager.update(ServiceType.SETTINGS_MANAGER)
service_manager.update(ServiceType.DATABASE_MANAGER)
service_manager.update(ServiceType.CACHE_MANAGER)
service_manager.update(ServiceType.CHAT_MANAGER)
service_manager.update(ServiceType.SESSION_MANAGER)
service_manager.update(ServiceType.AUTH_MANAGER)
service_manager.update(ServiceType.TASK_MANAGER)
service_manager.update(ServiceType.SETTINGS_SERVICE)
service_manager.update(ServiceType.DATABASE_SERVICE)
service_manager.update(ServiceType.CACHE_SERVICE)
service_manager.update(ServiceType.CHAT_SERVICE)
service_manager.update(ServiceType.SESSION_SERVICE)
service_manager.update(ServiceType.AUTH_SERVICE)
service_manager.update(ServiceType.TASK_SERVICE)

# Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER)
service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER)
service_manager.get(ServiceType.DATABASE_SERVICE)

# Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER)
service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER)
service_manager.get(ServiceType.DATABASE_SERVICE)


def initialize_settings_service():
Expand All @@ -193,12 +194,12 @@ def initialize_session_service():
initialize_settings_service()

service_manager.register_factory(
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER]
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE]
)

service_manager.register_factory(
session_service_factory.SessionServiceFactory(),
dependencies=[ServiceType.CACHE_MANAGER],
dependencies=[ServiceType.CACHE_SERVICE],
)


Expand Down
32 changes: 29 additions & 3 deletions src/backend/langflow/services/settings/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from pathlib import Path
from typing import Optional
import secrets
from langflow.services.settings.constants import (
DEFAULT_SUPERUSER,
DEFAULT_SUPERUSER_PASSWORD,
)
from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file

from pydantic import BaseSettings, Field, validator
Expand Down Expand Up @@ -30,9 +34,9 @@ class AuthSettings(BaseSettings):

# If AUTO_LOGIN = True
# > The application does not request login and logs in automatically as a super user.
AUTO_LOGIN: bool = True
FIRST_SUPERUSER: str = "langflow"
FIRST_SUPERUSER_PASSWORD: str = "langflow"
AUTO_LOGIN: bool = False
SUPERUSER: str = DEFAULT_SUPERUSER
SUPERUSER_PASSWORD: str = DEFAULT_SUPERUSER_PASSWORD

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

Expand All @@ -41,6 +45,28 @@ class Config:
extra = "ignore"
env_prefix = "LANGFLOW_"

def reset_credentials(self):
self.SUPERUSER = DEFAULT_SUPERUSER
self.SUPERUSER_PASSWORD = DEFAULT_SUPERUSER_PASSWORD

# If autologin is true, then we need to set the credentials to
# the default values
# so we need to validate the superuser and superuser_password
# fields
@validator("SUPERUSER", "SUPERUSER_PASSWORD", pre=True)
def validate_superuser(cls, value, values):
if values.get("AUTO_LOGIN"):
if value != DEFAULT_SUPERUSER:
value = DEFAULT_SUPERUSER
logger.debug("Resetting superuser to default value")
if values.get("SUPERUSER_PASSWORD") != DEFAULT_SUPERUSER_PASSWORD:
values["SUPERUSER_PASSWORD"] = DEFAULT_SUPERUSER_PASSWORD
logger.debug("Resetting superuser password to default value")

return value

return value

@validator("SECRET_KEY", pre=True)
def get_secret_key(cls, value, values):
config_dir = values.get("CONFIG_DIR")
Expand Down
2 changes: 2 additions & 0 deletions src/backend/langflow/services/settings/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DEFAULT_SUPERUSER = "langflow"
DEFAULT_SUPERUSER_PASSWORD = "langflow"
Loading

0 comments on commit b3febf2

Please sign in to comment.