mirror of
https://github.com/langgenius/dify.git
synced 2026-08-24 12:32:54 -04:00
84 lines
2.2 KiB
Python
84 lines
2.2 KiB
Python
"""Application service for first-time Dify setup."""
|
|
|
|
from contextlib import AbstractContextManager
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from typing import Protocol
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SetupInput:
|
|
email: str
|
|
name: str
|
|
password: str
|
|
ip_address: str
|
|
language: str | None
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SetupStatus:
|
|
completed: bool
|
|
setup_at: datetime | None = None
|
|
|
|
|
|
class SetupState(Protocol):
|
|
def get_setup_at(self) -> datetime | None: ...
|
|
|
|
def has_tenants(self) -> bool: ...
|
|
|
|
|
|
class SetupAccountProvisioner(Protocol):
|
|
def provision(self, setup: SetupInput) -> None: ...
|
|
|
|
|
|
class SetupLock(Protocol):
|
|
def acquire(self) -> AbstractContextManager[None]: ...
|
|
|
|
|
|
class SetupAlreadyCompletedError(Exception):
|
|
"""Raised when setup has already created persistent installation state."""
|
|
|
|
|
|
class InitializationValidationRequiredError(Exception):
|
|
"""Raised when initialization-password validation has not completed."""
|
|
|
|
|
|
class SetupService:
|
|
def __init__(
|
|
self,
|
|
*,
|
|
state: SetupState,
|
|
accounts: SetupAccountProvisioner,
|
|
lock: SetupLock,
|
|
setup_required: bool,
|
|
) -> None:
|
|
self._state = state
|
|
self._accounts = accounts
|
|
self._lock = lock
|
|
self._setup_required = setup_required
|
|
|
|
def get_status(self) -> SetupStatus:
|
|
if not self._setup_required:
|
|
return SetupStatus(completed=True)
|
|
|
|
setup_at = self._state.get_setup_at()
|
|
return SetupStatus(completed=setup_at is not None, setup_at=setup_at)
|
|
|
|
def initialize(self, setup: SetupInput, *, initialization_validated: bool) -> None:
|
|
with self._lock.acquire():
|
|
if self._state.get_setup_at() is not None or self._state.has_tenants():
|
|
raise SetupAlreadyCompletedError
|
|
|
|
if not initialization_validated:
|
|
raise InitializationValidationRequiredError
|
|
|
|
self._accounts.provision(
|
|
SetupInput(
|
|
email=setup.email.lower(),
|
|
name=setup.name,
|
|
password=setup.password,
|
|
ip_address=setup.ip_address,
|
|
language=setup.language,
|
|
)
|
|
)
|