| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | # -*- coding:utf-8 -*- | 
					
						
							|  |  |  | import json | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from datetime import datetime | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-21 13:57:18 +08:00
										 |  |  | from flask_login import current_user | 
					
						
							| 
									
										
										
										
											2023-10-08 05:21:32 -05:00
										 |  |  | from libs.login import login_required | 
					
						
							|  |  |  | from flask_restful import Resource, reqparse, marshal_with, abort, inputs | 
					
						
							| 
									
										
										
										
											2023-08-12 00:57:00 +08:00
										 |  |  | from werkzeug.exceptions import Forbidden | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | from constants.model_template import model_templates, demo_model_templates | 
					
						
							|  |  |  | from controllers.console import api | 
					
						
							| 
									
										
										
										
											2023-08-12 00:57:00 +08:00
										 |  |  | from controllers.console.app.error import AppNotFoundError, ProviderNotInitializeError | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from controllers.console.setup import setup_required | 
					
						
							|  |  |  | from controllers.console.wraps import account_initialization_required | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  | from core.model_providers.error import ProviderTokenNotInitError, LLMBadRequestError | 
					
						
							| 
									
										
										
										
											2023-08-12 00:57:00 +08:00
										 |  |  | from core.model_providers.model_factory import ModelFactory | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  | from core.model_providers.model_provider_factory import ModelProviderFactory | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from events.app_event import app_was_created, app_was_deleted | 
					
						
							| 
									
										
										
										
											2023-09-27 16:06:32 +08:00
										 |  |  | from fields.app_fields import app_pagination_fields, app_detail_fields, template_list_fields, \ | 
					
						
							|  |  |  |     app_detail_fields_with_site | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from extensions.ext_database import db | 
					
						
							| 
									
										
										
										
											2023-05-31 22:03:15 +08:00
										 |  |  | from models.model import App, AppModelConfig, Site | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from services.app_model_config_service import AppModelConfigService | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _get_app(app_id, tenant_id): | 
					
						
							|  |  |  |     app = db.session.query(App).filter(App.id == app_id, App.tenant_id == tenant_id).first() | 
					
						
							|  |  |  |     if not app: | 
					
						
							|  |  |  |         raise AppNotFoundError | 
					
						
							|  |  |  |     return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppListApi(Resource): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_pagination_fields) | 
					
						
							|  |  |  |     def get(self): | 
					
						
							|  |  |  |         """Get app list""" | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('page', type=inputs.int_range(1, 99999), required=False, default=1, location='args') | 
					
						
							|  |  |  |         parser.add_argument('limit', type=inputs.int_range(1, 100), required=False, default=20, location='args') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_models = db.paginate( | 
					
						
							| 
									
										
										
										
											2023-07-27 13:08:57 +08:00
										 |  |  |             db.select(App).where(App.tenant_id == current_user.current_tenant_id, | 
					
						
							|  |  |  |                                  App.is_universal == False).order_by(App.created_at.desc()), | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             page=args['page'], | 
					
						
							|  |  |  |             per_page=args['limit'], | 
					
						
							|  |  |  |             error_out=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return app_models | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self): | 
					
						
							|  |  |  |         """Create app""" | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('name', type=str, required=True, location='json') | 
					
						
							|  |  |  |         parser.add_argument('mode', type=str, choices=['completion', 'chat'], location='json') | 
					
						
							|  |  |  |         parser.add_argument('icon', type=str, location='json') | 
					
						
							|  |  |  |         parser.add_argument('icon_background', type=str, location='json') | 
					
						
							|  |  |  |         parser.add_argument('model_config', type=dict, location='json') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # The role of the current user in the ta table must be admin or owner | 
					
						
							|  |  |  |         if current_user.current_tenant.current_role not in ['admin', 'owner']: | 
					
						
							|  |  |  |             raise Forbidden() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  |         try: | 
					
						
							|  |  |  |             default_model = ModelFactory.get_text_generation_model( | 
					
						
							|  |  |  |                 tenant_id=current_user.current_tenant_id | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         except (ProviderTokenNotInitError, LLMBadRequestError): | 
					
						
							|  |  |  |             default_model = None | 
					
						
							|  |  |  |         except Exception as e: | 
					
						
							|  |  |  |             logging.exception(e) | 
					
						
							|  |  |  |             default_model = None | 
					
						
							| 
									
										
										
										
											2023-08-16 20:48:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         if args['model_config'] is not None: | 
					
						
							|  |  |  |             # validate config | 
					
						
							| 
									
										
										
										
											2023-08-16 20:48:42 +08:00
										 |  |  |             model_config_dict = args['model_config'] | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # get model provider | 
					
						
							|  |  |  |             model_provider = ModelProviderFactory.get_preferred_model_provider( | 
					
						
							|  |  |  |                 current_user.current_tenant_id, | 
					
						
							|  |  |  |                 model_config_dict["model"]["provider"] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if not model_provider: | 
					
						
							|  |  |  |                 if not default_model: | 
					
						
							|  |  |  |                     raise ProviderNotInitializeError( | 
					
						
							|  |  |  |                         f"No Default System Reasoning Model available. Please configure " | 
					
						
							|  |  |  |                         f"in the Settings -> Model Provider.") | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     model_config_dict["model"]["provider"] = default_model.model_provider.provider_name | 
					
						
							|  |  |  |                     model_config_dict["model"]["name"] = default_model.name | 
					
						
							| 
									
										
										
										
											2023-08-16 20:48:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             model_configuration = AppModelConfigService.validate_configuration( | 
					
						
							| 
									
										
										
										
											2023-08-12 00:57:00 +08:00
										 |  |  |                 tenant_id=current_user.current_tenant_id, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |                 account=current_user, | 
					
						
							| 
									
										
										
										
											2023-09-27 14:53:22 +08:00
										 |  |  |                 config=model_config_dict, | 
					
						
							|  |  |  |                 mode=args['mode'] | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             app = App( | 
					
						
							|  |  |  |                 enable_site=True, | 
					
						
							|  |  |  |                 enable_api=True, | 
					
						
							|  |  |  |                 is_demo=False, | 
					
						
							|  |  |  |                 api_rpm=0, | 
					
						
							|  |  |  |                 api_rph=0, | 
					
						
							|  |  |  |                 status='normal' | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-16 20:48:42 +08:00
										 |  |  |             app_model_config = AppModelConfig() | 
					
						
							|  |  |  |             app_model_config = app_model_config.from_model_config_dict(model_configuration) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if 'mode' not in args or args['mode'] is None: | 
					
						
							|  |  |  |                 abort(400, message="mode is required") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             model_config_template = model_templates[args['mode'] + '_default'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             app = App(**model_config_template['app']) | 
					
						
							|  |  |  |             app_model_config = AppModelConfig(**model_config_template['model_config']) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-16 22:29:18 +08:00
										 |  |  |             # get model provider | 
					
						
							|  |  |  |             model_provider = ModelProviderFactory.get_preferred_model_provider( | 
					
						
							|  |  |  |                 current_user.current_tenant_id, | 
					
						
							|  |  |  |                 app_model_config.model_dict["provider"] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if not model_provider: | 
					
						
							|  |  |  |                 if not default_model: | 
					
						
							|  |  |  |                     raise ProviderNotInitializeError( | 
					
						
							|  |  |  |                         f"No Default System Reasoning Model available. Please configure " | 
					
						
							|  |  |  |                         f"in the Settings -> Model Provider.") | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     model_dict = app_model_config.model_dict | 
					
						
							|  |  |  |                     model_dict['provider'] = default_model.model_provider.provider_name | 
					
						
							|  |  |  |                     model_dict['name'] = default_model.name | 
					
						
							|  |  |  |                     app_model_config.model = json.dumps(model_dict) | 
					
						
							| 
									
										
										
										
											2023-08-12 00:57:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         app.name = args['name'] | 
					
						
							|  |  |  |         app.mode = args['mode'] | 
					
						
							|  |  |  |         app.icon = args['icon'] | 
					
						
							|  |  |  |         app.icon_background = args['icon_background'] | 
					
						
							|  |  |  |         app.tenant_id = current_user.current_tenant_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         db.session.add(app) | 
					
						
							|  |  |  |         db.session.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_model_config.app_id = app.id | 
					
						
							|  |  |  |         db.session.add(app_model_config) | 
					
						
							|  |  |  |         db.session.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.app_model_config_id = app_model_config.id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         account = current_user | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         site = Site( | 
					
						
							|  |  |  |             app_id=app.id, | 
					
						
							|  |  |  |             title=app.name, | 
					
						
							|  |  |  |             default_language=account.interface_language, | 
					
						
							|  |  |  |             customize_token_strategy='not_allow', | 
					
						
							|  |  |  |             code=Site.generate_code(16) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         db.session.add(site) | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_was_created.send(app) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return app, 201 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppTemplateApi(Resource): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(template_list_fields) | 
					
						
							|  |  |  |     def get(self): | 
					
						
							|  |  |  |         """Get app demo templates""" | 
					
						
							|  |  |  |         account = current_user | 
					
						
							|  |  |  |         interface_language = account.interface_language | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 10:06:49 +08:00
										 |  |  |         templates = demo_model_templates.get(interface_language) | 
					
						
							|  |  |  |         if not templates: | 
					
						
							|  |  |  |             templates = demo_model_templates.get('en-US') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'data': templates} | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppApi(Resource): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields_with_site) | 
					
						
							|  |  |  |     def get(self, app_id): | 
					
						
							|  |  |  |         """Get app detail""" | 
					
						
							|  |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     def delete(self, app_id): | 
					
						
							|  |  |  |         """Delete app""" | 
					
						
							|  |  |  |         app_id = str(app_id) | 
					
						
							| 
									
										
										
										
											2023-08-12 14:18:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if current_user.current_tenant.current_role not in ['admin', 'owner']: | 
					
						
							|  |  |  |             raise Forbidden() | 
					
						
							| 
									
										
										
										
											2023-08-21 13:57:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         db.session.delete(app) | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # todo delete related data?? | 
					
						
							|  |  |  |         # model_config, site, api_token, conversation, message, message_feedback, message_annotation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_was_deleted.send(app) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return {'result': 'success'}, 204 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppNameApi(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self, app_id): | 
					
						
							| 
									
										
										
										
											2023-08-06 16:11:04 +08:00
										 |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('name', type=str, required=True, location='json') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.name = args.get('name') | 
					
						
							|  |  |  |         app.updated_at = datetime.utcnow() | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  |         return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppIconApi(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self, app_id): | 
					
						
							| 
									
										
										
										
											2023-08-06 16:11:04 +08:00
										 |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('icon', type=str, location='json') | 
					
						
							|  |  |  |         parser.add_argument('icon_background', type=str, location='json') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.icon = args.get('icon') | 
					
						
							|  |  |  |         app.icon_background = args.get('icon_background') | 
					
						
							|  |  |  |         app.updated_at = datetime.utcnow() | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppSiteStatus(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self, app_id): | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('enable_site', type=bool, required=True, location='json') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = db.session.query(App).filter(App.id == app_id, App.tenant_id == current_user.current_tenant_id).first() | 
					
						
							|  |  |  |         if not app: | 
					
						
							|  |  |  |             raise AppNotFoundError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if args.get('enable_site') == app.enable_site: | 
					
						
							|  |  |  |             return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.enable_site = args.get('enable_site') | 
					
						
							|  |  |  |         app.updated_at = datetime.utcnow() | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  |         return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppApiStatus(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self, app_id): | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument('enable_api', type=bool, required=True, location='json') | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if args.get('enable_api') == app.enable_api: | 
					
						
							|  |  |  |             return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app.enable_api = args.get('enable_api') | 
					
						
							|  |  |  |         app.updated_at = datetime.utcnow() | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  |         return app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppCopy(Resource): | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def create_app_copy(app): | 
					
						
							|  |  |  |         copy_app = App( | 
					
						
							|  |  |  |             name=app.name + ' copy', | 
					
						
							|  |  |  |             icon=app.icon, | 
					
						
							|  |  |  |             icon_background=app.icon_background, | 
					
						
							|  |  |  |             tenant_id=app.tenant_id, | 
					
						
							|  |  |  |             mode=app.mode, | 
					
						
							|  |  |  |             app_model_config_id=app.app_model_config_id, | 
					
						
							|  |  |  |             enable_site=app.enable_site, | 
					
						
							|  |  |  |             enable_api=app.enable_api, | 
					
						
							|  |  |  |             api_rpm=app.api_rpm, | 
					
						
							|  |  |  |             api_rph=app.api_rph | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         return copy_app | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def create_app_model_config_copy(app_config, copy_app_id): | 
					
						
							| 
									
										
										
										
											2023-08-16 20:48:42 +08:00
										 |  |  |         copy_app_model_config = app_config.copy() | 
					
						
							|  |  |  |         copy_app_model_config.app_id = copy_app_id | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         return copy_app_model_config | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_detail_fields) | 
					
						
							|  |  |  |     def post(self, app_id): | 
					
						
							|  |  |  |         app_id = str(app_id) | 
					
						
							|  |  |  |         app = _get_app(app_id, current_user.current_tenant_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         copy_app = self.create_app_copy(app) | 
					
						
							|  |  |  |         db.session.add(copy_app) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         app_config = db.session.query(AppModelConfig). \ | 
					
						
							|  |  |  |             filter(AppModelConfig.app_id == app_id). \ | 
					
						
							|  |  |  |             one_or_none() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if app_config: | 
					
						
							|  |  |  |             copy_app_model_config = self.create_app_model_config_copy(app_config, copy_app.id) | 
					
						
							|  |  |  |             db.session.add(copy_app_model_config) | 
					
						
							|  |  |  |             db.session.commit() | 
					
						
							|  |  |  |             copy_app.app_model_config_id = copy_app_model_config.id | 
					
						
							|  |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return copy_app, 201 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | api.add_resource(AppListApi, '/apps') | 
					
						
							|  |  |  | api.add_resource(AppTemplateApi, '/app-templates') | 
					
						
							|  |  |  | api.add_resource(AppApi, '/apps/<uuid:app_id>') | 
					
						
							|  |  |  | api.add_resource(AppCopy, '/apps/<uuid:app_id>/copy') | 
					
						
							|  |  |  | api.add_resource(AppNameApi, '/apps/<uuid:app_id>/name') | 
					
						
							| 
									
										
										
										
											2023-08-06 16:21:35 +08:00
										 |  |  | api.add_resource(AppIconApi, '/apps/<uuid:app_id>/icon') | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | api.add_resource(AppSiteStatus, '/apps/<uuid:app_id>/site-enable') | 
					
						
							|  |  |  | api.add_resource(AppApiStatus, '/apps/<uuid:app_id>/api-enable') |