Feat/environment variables in workflow (#6515)

Co-authored-by: JzoNg <jzongcode@gmail.com>
This commit is contained in:
-LAN-
2024-07-22 15:29:39 +08:00
committed by GitHub
parent 87d583f454
commit 5e6fc58db3
146 changed files with 2486 additions and 746 deletions

View File

@@ -47,7 +47,7 @@ class AccountService:
)
@staticmethod
def load_user(user_id: str) -> Account:
def load_user(user_id: str) -> None | Account:
account = Account.query.filter_by(id=user_id).first()
if not account:
return None
@@ -55,7 +55,7 @@ class AccountService:
if account.status in [AccountStatus.BANNED.value, AccountStatus.CLOSED.value]:
raise Unauthorized("Account is banned or closed.")
current_tenant = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first()
current_tenant: TenantAccountJoin = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first()
if current_tenant:
account.current_tenant_id = current_tenant.tenant_id
else:

View File

@@ -3,6 +3,7 @@ import logging
import httpx
import yaml # type: ignore
from core.app.segments import factory
from events.app_event import app_model_config_was_updated, app_was_created
from extensions.ext_database import db
from models.account import Account
@@ -150,7 +151,7 @@ class AppDslService:
)
@classmethod
def export_dsl(cls, app_model: App) -> str:
def export_dsl(cls, app_model: App, include_secret:bool = False) -> str:
"""
Export app
:param app_model: App instance
@@ -171,7 +172,7 @@ class AppDslService:
}
if app_mode in [AppMode.ADVANCED_CHAT, AppMode.WORKFLOW]:
cls._append_workflow_export_data(export_data, app_model)
cls._append_workflow_export_data(export_data=export_data, app_model=app_model, include_secret=include_secret)
else:
cls._append_model_config_export_data(export_data, app_model)
@@ -235,13 +236,16 @@ class AppDslService:
)
# init draft workflow
environment_variables_list = workflow_data.get('environment_variables') or []
environment_variables = [factory.build_variable_from_mapping(obj) for obj in environment_variables_list]
workflow_service = WorkflowService()
draft_workflow = workflow_service.sync_draft_workflow(
app_model=app,
graph=workflow_data.get('graph', {}),
features=workflow_data.get('../core/app/features', {}),
unique_hash=None,
account=account
account=account,
environment_variables=environment_variables,
)
workflow_service.publish_workflow(
app_model=app,
@@ -276,12 +280,15 @@ class AppDslService:
unique_hash = None
# sync draft workflow
environment_variables_list = workflow_data.get('environment_variables') or []
environment_variables = [factory.build_variable_from_mapping(obj) for obj in environment_variables_list]
draft_workflow = workflow_service.sync_draft_workflow(
app_model=app_model,
graph=workflow_data.get('graph', {}),
features=workflow_data.get('features', {}),
unique_hash=unique_hash,
account=account
account=account,
environment_variables=environment_variables,
)
return draft_workflow
@@ -377,7 +384,7 @@ class AppDslService:
return app
@classmethod
def _append_workflow_export_data(cls, export_data: dict, app_model: App) -> None:
def _append_workflow_export_data(cls, *, export_data: dict, app_model: App, include_secret: bool) -> None:
"""
Append workflow export data
:param export_data: export data
@@ -388,10 +395,7 @@ class AppDslService:
if not workflow:
raise ValueError("Missing draft workflow configuration, please check.")
export_data['workflow'] = {
"graph": workflow.graph_dict,
"features": workflow.features_dict
}
export_data['workflow'] = workflow.to_dict(include_secret=include_secret)
@classmethod
def _append_model_config_export_data(cls, export_data: dict, app_model: App) -> None:

View File

@@ -133,6 +133,7 @@ class ModelLoadBalancingService:
# move the inherit configuration to the first
for i, load_balancing_config in enumerate(load_balancing_configs):
if load_balancing_config.name == '__inherit__':
# FIXME: Mutation to loop iterable `load_balancing_configs` during iteration
inherit_config = load_balancing_configs.pop(i)
load_balancing_configs.insert(0, inherit_config)

View File

@@ -4,7 +4,6 @@ from os import path
from typing import Optional
import requests
from flask import current_app
from configs import dify_config
from constants.languages import languages

View File

@@ -199,7 +199,8 @@ class WorkflowConverter:
version='draft',
graph=json.dumps(graph),
features=json.dumps(features),
created_by=account_id
created_by=account_id,
environment_variables=[],
)
db.session.add(workflow)

View File

@@ -1,10 +1,12 @@
import json
import time
from collections.abc import Sequence
from datetime import datetime, timezone
from typing import Optional
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager
from core.app.segments import Variable
from core.model_runtime.utils.encoders import jsonable_encoder
from core.workflow.entities.node_entities import NodeType
from core.workflow.errors import WorkflowNodeRunFailedError
@@ -61,11 +63,16 @@ class WorkflowService:
return workflow
def sync_draft_workflow(self, app_model: App,
graph: dict,
features: dict,
unique_hash: Optional[str],
account: Account) -> Workflow:
def sync_draft_workflow(
self,
*,
app_model: App,
graph: dict,
features: dict,
unique_hash: Optional[str],
account: Account,
environment_variables: Sequence[Variable],
) -> Workflow:
"""
Sync draft workflow
:raises WorkflowHashNotEqualError
@@ -73,10 +80,8 @@ class WorkflowService:
# fetch draft workflow by app_model
workflow = self.get_draft_workflow(app_model=app_model)
if workflow:
# validate unique hash
if workflow.unique_hash != unique_hash:
raise WorkflowHashNotEqualError()
if workflow and workflow.unique_hash != unique_hash:
raise WorkflowHashNotEqualError()
# validate features structure
self.validate_features_structure(
@@ -93,7 +98,8 @@ class WorkflowService:
version='draft',
graph=json.dumps(graph),
features=json.dumps(features),
created_by=account.id
created_by=account.id,
environment_variables=environment_variables
)
db.session.add(workflow)
# update draft workflow if found
@@ -102,6 +108,7 @@ class WorkflowService:
workflow.features = json.dumps(features)
workflow.updated_by = account.id
workflow.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
workflow.environment_variables = environment_variables
# commit db session changes
db.session.commit()
@@ -137,7 +144,8 @@ class WorkflowService:
version=str(datetime.now(timezone.utc).replace(tzinfo=None)),
graph=draft_workflow.graph,
features=draft_workflow.features,
created_by=account.id
created_by=account.id,
environment_variables=draft_workflow.environment_variables
)
# commit db session changes