provider_manager.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. import json
  2. from collections import defaultdict
  3. from json import JSONDecodeError
  4. from typing import Optional
  5. from sqlalchemy.exc import IntegrityError
  6. from core.entities.model_entities import DefaultModelEntity, DefaultModelProviderEntity
  7. from core.entities.provider_configuration import ProviderConfigurations, ProviderConfiguration, ProviderModelBundle
  8. from core.entities.provider_entities import CustomConfiguration, CustomProviderConfiguration, CustomModelConfiguration, \
  9. SystemConfiguration, QuotaConfiguration
  10. from core.helper import encrypter
  11. from core.helper.model_provider_cache import ProviderCredentialsCache, ProviderCredentialsCacheType
  12. from core.model_runtime.entities.model_entities import ModelType
  13. from core.model_runtime.entities.provider_entities import ProviderEntity, CredentialFormSchema, FormType
  14. from core.model_runtime.model_providers import model_provider_factory
  15. from extensions import ext_hosting_provider
  16. from extensions.ext_database import db
  17. from models.provider import TenantDefaultModel, Provider, ProviderModel, ProviderQuotaType, ProviderType, \
  18. TenantPreferredModelProvider
  19. class ProviderManager:
  20. """
  21. ProviderManager is a class that manages the model providers includes Hosting and Customize Model Providers.
  22. """
  23. def get_configurations(self, tenant_id: str) -> ProviderConfigurations:
  24. """
  25. Get model provider configurations.
  26. Construct ProviderConfiguration objects for each provider
  27. Including:
  28. 1. Basic information of the provider
  29. 2. Hosting configuration information, including:
  30. (1. Whether to enable (support) hosting type, if enabled, the following information exists
  31. (2. List of hosting type provider configurations
  32. (including quota type, quota limit, current remaining quota, etc.)
  33. (3. The current hosting type in use (whether there is a quota or not)
  34. paid quotas > provider free quotas > hosting trial quotas
  35. (4. Unified credentials for hosting providers
  36. 3. Custom configuration information, including:
  37. (1. Whether to enable (support) custom type, if enabled, the following information exists
  38. (2. Custom provider configuration (including credentials)
  39. (3. List of custom provider model configurations (including credentials)
  40. 4. Hosting/custom preferred provider type.
  41. Provide methods:
  42. - Get the current configuration (including credentials)
  43. - Get the availability and status of the hosting configuration: active available,
  44. quota_exceeded insufficient quota, unsupported hosting
  45. - Get the availability of custom configuration
  46. Custom provider available conditions:
  47. (1. custom provider credentials available
  48. (2. at least one custom model credentials available
  49. - Verify, update, and delete custom provider configuration
  50. - Verify, update, and delete custom provider model configuration
  51. - Get the list of available models (optional provider filtering, model type filtering)
  52. Append custom provider models to the list
  53. - Get provider instance
  54. - Switch selection priority
  55. :param tenant_id:
  56. :return:
  57. """
  58. # Get all provider records of the workspace
  59. provider_name_to_provider_records_dict = self._get_all_providers(tenant_id)
  60. # Initialize trial provider records if not exist
  61. provider_name_to_provider_records_dict = self._init_trial_provider_records(
  62. tenant_id,
  63. provider_name_to_provider_records_dict
  64. )
  65. # Get all provider model records of the workspace
  66. provider_name_to_provider_model_records_dict = self._get_all_provider_models(tenant_id)
  67. # Get all provider entities
  68. provider_entities = model_provider_factory.get_providers()
  69. # Get All preferred provider types of the workspace
  70. provider_name_to_preferred_model_provider_records_dict = self._get_all_preferred_model_providers(tenant_id)
  71. provider_configurations = ProviderConfigurations(
  72. tenant_id=tenant_id
  73. )
  74. # Construct ProviderConfiguration objects for each provider
  75. for provider_entity in provider_entities:
  76. provider_name = provider_entity.provider
  77. provider_records = provider_name_to_provider_records_dict.get(provider_entity.provider)
  78. if not provider_records:
  79. provider_records = []
  80. provider_model_records = provider_name_to_provider_model_records_dict.get(provider_entity.provider)
  81. if not provider_model_records:
  82. provider_model_records = []
  83. # Convert to custom configuration
  84. custom_configuration = self._to_custom_configuration(
  85. tenant_id,
  86. provider_entity,
  87. provider_records,
  88. provider_model_records
  89. )
  90. # Convert to system configuration
  91. system_configuration = self._to_system_configuration(
  92. tenant_id,
  93. provider_entity,
  94. provider_records
  95. )
  96. # Get preferred provider type
  97. preferred_provider_type_record = provider_name_to_preferred_model_provider_records_dict.get(provider_name)
  98. if preferred_provider_type_record:
  99. preferred_provider_type = ProviderType.value_of(preferred_provider_type_record.preferred_provider_type)
  100. else:
  101. if custom_configuration.provider or custom_configuration.models:
  102. preferred_provider_type = ProviderType.CUSTOM
  103. elif system_configuration.enabled:
  104. preferred_provider_type = ProviderType.SYSTEM
  105. else:
  106. preferred_provider_type = ProviderType.CUSTOM
  107. using_provider_type = preferred_provider_type
  108. if preferred_provider_type == ProviderType.SYSTEM:
  109. if not system_configuration.enabled:
  110. using_provider_type = ProviderType.CUSTOM
  111. has_valid_quota = False
  112. for quota_configuration in system_configuration.quota_configurations:
  113. if quota_configuration.is_valid:
  114. has_valid_quota = True
  115. break
  116. if not has_valid_quota:
  117. using_provider_type = ProviderType.CUSTOM
  118. else:
  119. if not custom_configuration.provider and not custom_configuration.models:
  120. if system_configuration.enabled:
  121. has_valid_quota = False
  122. for quota_configuration in system_configuration.quota_configurations:
  123. if quota_configuration.is_valid:
  124. has_valid_quota = True
  125. break
  126. if has_valid_quota:
  127. using_provider_type = ProviderType.SYSTEM
  128. provider_configuration = ProviderConfiguration(
  129. tenant_id=tenant_id,
  130. provider=provider_entity,
  131. preferred_provider_type=preferred_provider_type,
  132. using_provider_type=using_provider_type,
  133. system_configuration=system_configuration,
  134. custom_configuration=custom_configuration
  135. )
  136. provider_configurations[provider_name] = provider_configuration
  137. # Return the encapsulated object
  138. return provider_configurations
  139. def get_provider_model_bundle(self, tenant_id: str, provider: str, model_type: ModelType) -> ProviderModelBundle:
  140. """
  141. Get provider model bundle.
  142. :param tenant_id: workspace id
  143. :param provider: provider name
  144. :param model_type: model type
  145. :return:
  146. """
  147. provider_configurations = self.get_configurations(tenant_id)
  148. # get provider instance
  149. provider_configuration = provider_configurations.get(provider)
  150. if not provider_configuration:
  151. raise ValueError(f"Provider {provider} does not exist.")
  152. provider_instance = provider_configuration.get_provider_instance()
  153. model_type_instance = provider_instance.get_model_instance(model_type)
  154. return ProviderModelBundle(
  155. configuration=provider_configuration,
  156. provider_instance=provider_instance,
  157. model_type_instance=model_type_instance
  158. )
  159. def get_default_model(self, tenant_id: str, model_type: ModelType) -> Optional[DefaultModelEntity]:
  160. """
  161. Get default model.
  162. :param tenant_id: workspace id
  163. :param model_type: model type
  164. :return:
  165. """
  166. # Get the corresponding TenantDefaultModel record
  167. default_model = db.session.query(TenantDefaultModel) \
  168. .filter(
  169. TenantDefaultModel.tenant_id == tenant_id,
  170. TenantDefaultModel.model_type == model_type.to_origin_model_type()
  171. ).first()
  172. # If it does not exist, get the first available provider model from get_configurations
  173. # and update the TenantDefaultModel record
  174. if not default_model:
  175. # Get provider configurations
  176. provider_configurations = self.get_configurations(tenant_id)
  177. # get available models from provider_configurations
  178. available_models = provider_configurations.get_models(
  179. model_type=model_type,
  180. only_active=True
  181. )
  182. if available_models:
  183. available_model = available_models[0]
  184. default_model = TenantDefaultModel(
  185. tenant_id=tenant_id,
  186. model_type=model_type.to_origin_model_type(),
  187. provider_name=available_model.provider.provider,
  188. model_name=available_model.model
  189. )
  190. db.session.add(default_model)
  191. db.session.commit()
  192. if not default_model:
  193. return None
  194. provider_instance = model_provider_factory.get_provider_instance(default_model.provider_name)
  195. provider_schema = provider_instance.get_provider_schema()
  196. return DefaultModelEntity(
  197. model=default_model.model_name,
  198. model_type=model_type,
  199. provider=DefaultModelProviderEntity(
  200. provider=provider_schema.provider,
  201. label=provider_schema.label,
  202. icon_small=provider_schema.icon_small,
  203. icon_large=provider_schema.icon_large,
  204. supported_model_types=provider_schema.supported_model_types
  205. )
  206. )
  207. def update_default_model_record(self, tenant_id: str, model_type: ModelType, provider: str, model: str) \
  208. -> TenantDefaultModel:
  209. """
  210. Update default model record.
  211. :param tenant_id: workspace id
  212. :param model_type: model type
  213. :param provider: provider name
  214. :param model: model name
  215. :return:
  216. """
  217. provider_configurations = self.get_configurations(tenant_id)
  218. if provider not in provider_configurations:
  219. raise ValueError(f"Provider {provider} does not exist.")
  220. # get available models from provider_configurations
  221. available_models = provider_configurations.get_models(
  222. model_type=model_type,
  223. only_active=True
  224. )
  225. # check if the model is exist in available models
  226. model_names = [model.model for model in available_models]
  227. if model not in model_names:
  228. raise ValueError(f"Model {model} does not exist.")
  229. # Get the list of available models from get_configurations and check if it is LLM
  230. default_model = db.session.query(TenantDefaultModel) \
  231. .filter(
  232. TenantDefaultModel.tenant_id == tenant_id,
  233. TenantDefaultModel.model_type == model_type.to_origin_model_type()
  234. ).first()
  235. # create or update TenantDefaultModel record
  236. if default_model:
  237. # update default model
  238. default_model.provider_name = provider
  239. default_model.model_name = model
  240. db.session.commit()
  241. else:
  242. # create default model
  243. default_model = TenantDefaultModel(
  244. tenant_id=tenant_id,
  245. model_type=model_type.value,
  246. provider_name=provider,
  247. model_name=model,
  248. )
  249. db.session.add(default_model)
  250. db.session.commit()
  251. return default_model
  252. def _get_all_providers(self, tenant_id: str) -> dict[str, list[Provider]]:
  253. """
  254. Get all provider records of the workspace.
  255. :param tenant_id: workspace id
  256. :return:
  257. """
  258. providers = db.session.query(Provider) \
  259. .filter(
  260. Provider.tenant_id == tenant_id,
  261. Provider.is_valid == True
  262. ).all()
  263. provider_name_to_provider_records_dict = defaultdict(list)
  264. for provider in providers:
  265. provider_name_to_provider_records_dict[provider.provider_name].append(provider)
  266. return provider_name_to_provider_records_dict
  267. def _get_all_provider_models(self, tenant_id: str) -> dict[str, list[ProviderModel]]:
  268. """
  269. Get all provider model records of the workspace.
  270. :param tenant_id: workspace id
  271. :return:
  272. """
  273. # Get all provider model records of the workspace
  274. provider_models = db.session.query(ProviderModel) \
  275. .filter(
  276. ProviderModel.tenant_id == tenant_id,
  277. ProviderModel.is_valid == True
  278. ).all()
  279. provider_name_to_provider_model_records_dict = defaultdict(list)
  280. for provider_model in provider_models:
  281. provider_name_to_provider_model_records_dict[provider_model.provider_name].append(provider_model)
  282. return provider_name_to_provider_model_records_dict
  283. def _get_all_preferred_model_providers(self, tenant_id: str) -> dict[str, TenantPreferredModelProvider]:
  284. """
  285. Get All preferred provider types of the workspace.
  286. :param tenant_id:
  287. :return:
  288. """
  289. preferred_provider_types = db.session.query(TenantPreferredModelProvider) \
  290. .filter(
  291. TenantPreferredModelProvider.tenant_id == tenant_id
  292. ).all()
  293. provider_name_to_preferred_provider_type_records_dict = {
  294. preferred_provider_type.provider_name: preferred_provider_type
  295. for preferred_provider_type in preferred_provider_types
  296. }
  297. return provider_name_to_preferred_provider_type_records_dict
  298. def _init_trial_provider_records(self, tenant_id: str,
  299. provider_name_to_provider_records_dict: dict[str, list]) -> dict[str, list]:
  300. """
  301. Initialize trial provider records if not exists.
  302. :param tenant_id: workspace id
  303. :param provider_name_to_provider_records_dict: provider name to provider records dict
  304. :return:
  305. """
  306. # Get hosting configuration
  307. hosting_configuration = ext_hosting_provider.hosting_configuration
  308. for provider_name, configuration in hosting_configuration.provider_map.items():
  309. if not configuration.enabled:
  310. continue
  311. provider_records = provider_name_to_provider_records_dict.get(provider_name)
  312. if not provider_records:
  313. provider_records = []
  314. provider_quota_to_provider_record_dict = dict()
  315. for provider_record in provider_records:
  316. if provider_record.provider_type != ProviderType.SYSTEM.value:
  317. continue
  318. provider_quota_to_provider_record_dict[ProviderQuotaType.value_of(provider_record.quota_type)] \
  319. = provider_record
  320. for quota in configuration.quotas:
  321. if quota.quota_type == ProviderQuotaType.TRIAL:
  322. # Init trial provider records if not exists
  323. if ProviderQuotaType.TRIAL not in provider_quota_to_provider_record_dict:
  324. try:
  325. provider_record = Provider(
  326. tenant_id=tenant_id,
  327. provider_name=provider_name,
  328. provider_type=ProviderType.SYSTEM.value,
  329. quota_type=ProviderQuotaType.TRIAL.value,
  330. quota_limit=quota.quota_limit,
  331. quota_used=0,
  332. is_valid=True
  333. )
  334. db.session.add(provider_record)
  335. db.session.commit()
  336. except IntegrityError:
  337. db.session.rollback()
  338. provider_record = db.session.query(Provider) \
  339. .filter(
  340. Provider.tenant_id == tenant_id,
  341. Provider.provider_name == provider_name,
  342. Provider.provider_type == ProviderType.SYSTEM.value,
  343. Provider.quota_type == ProviderQuotaType.TRIAL.value
  344. ).first()
  345. if provider_record and not provider_record.is_valid:
  346. provider_record.is_valid = True
  347. db.session.commit()
  348. provider_name_to_provider_records_dict[provider_name].append(provider_record)
  349. return provider_name_to_provider_records_dict
  350. def _to_custom_configuration(self,
  351. tenant_id: str,
  352. provider_entity: ProviderEntity,
  353. provider_records: list[Provider],
  354. provider_model_records: list[ProviderModel]) -> CustomConfiguration:
  355. """
  356. Convert to custom configuration.
  357. :param tenant_id: workspace id
  358. :param provider_entity: provider entity
  359. :param provider_records: provider records
  360. :param provider_model_records: provider model records
  361. :return:
  362. """
  363. # Get provider credential secret variables
  364. provider_credential_secret_variables = self._extract_secret_variables(
  365. provider_entity.provider_credential_schema.credential_form_schemas
  366. if provider_entity.provider_credential_schema else []
  367. )
  368. # Get custom provider record
  369. custom_provider_record = None
  370. for provider_record in provider_records:
  371. if provider_record.provider_type == ProviderType.SYSTEM.value:
  372. continue
  373. if not provider_record.encrypted_config:
  374. continue
  375. custom_provider_record = provider_record
  376. # Get custom provider credentials
  377. custom_provider_configuration = None
  378. if custom_provider_record:
  379. provider_credentials_cache = ProviderCredentialsCache(
  380. tenant_id=tenant_id,
  381. identity_id=custom_provider_record.id,
  382. cache_type=ProviderCredentialsCacheType.PROVIDER
  383. )
  384. # Get cached provider credentials
  385. cached_provider_credentials = provider_credentials_cache.get()
  386. if not cached_provider_credentials:
  387. try:
  388. # fix origin data
  389. if (custom_provider_record.encrypted_config
  390. and not custom_provider_record.encrypted_config.startswith("{")):
  391. provider_credentials = {
  392. "openai_api_key": custom_provider_record.encrypted_config
  393. }
  394. else:
  395. provider_credentials = json.loads(custom_provider_record.encrypted_config)
  396. except JSONDecodeError:
  397. provider_credentials = {}
  398. # Get decoding rsa key and cipher for decrypting credentials
  399. decoding_rsa_key, decoding_cipher_rsa = encrypter.get_decrypt_decoding(tenant_id)
  400. for variable in provider_credential_secret_variables:
  401. if variable in provider_credentials:
  402. try:
  403. provider_credentials[variable] = encrypter.decrypt_token_with_decoding(
  404. provider_credentials.get(variable),
  405. decoding_rsa_key,
  406. decoding_cipher_rsa
  407. )
  408. except ValueError:
  409. pass
  410. # cache provider credentials
  411. provider_credentials_cache.set(
  412. credentials=provider_credentials
  413. )
  414. else:
  415. provider_credentials = cached_provider_credentials
  416. custom_provider_configuration = CustomProviderConfiguration(
  417. credentials=provider_credentials
  418. )
  419. # Get provider model credential secret variables
  420. model_credential_secret_variables = self._extract_secret_variables(
  421. provider_entity.model_credential_schema.credential_form_schemas
  422. if provider_entity.model_credential_schema else []
  423. )
  424. # Get custom provider model credentials
  425. custom_model_configurations = []
  426. for provider_model_record in provider_model_records:
  427. if not provider_model_record.encrypted_config:
  428. continue
  429. provider_model_credentials_cache = ProviderCredentialsCache(
  430. tenant_id=tenant_id,
  431. identity_id=provider_model_record.id,
  432. cache_type=ProviderCredentialsCacheType.MODEL
  433. )
  434. # Get cached provider model credentials
  435. cached_provider_model_credentials = provider_model_credentials_cache.get()
  436. if not cached_provider_model_credentials:
  437. try:
  438. provider_model_credentials = json.loads(provider_model_record.encrypted_config)
  439. except JSONDecodeError:
  440. continue
  441. # Get decoding rsa key and cipher for decrypting credentials
  442. decoding_rsa_key, decoding_cipher_rsa = encrypter.get_decrypt_decoding(tenant_id)
  443. for variable in model_credential_secret_variables:
  444. if variable in provider_model_credentials:
  445. try:
  446. provider_model_credentials[variable] = encrypter.decrypt_token_with_decoding(
  447. provider_model_credentials.get(variable),
  448. decoding_rsa_key,
  449. decoding_cipher_rsa
  450. )
  451. except ValueError:
  452. pass
  453. # cache provider model credentials
  454. provider_model_credentials_cache.set(
  455. credentials=provider_model_credentials
  456. )
  457. else:
  458. provider_model_credentials = cached_provider_model_credentials
  459. custom_model_configurations.append(
  460. CustomModelConfiguration(
  461. model=provider_model_record.model_name,
  462. model_type=ModelType.value_of(provider_model_record.model_type),
  463. credentials=provider_model_credentials
  464. )
  465. )
  466. return CustomConfiguration(
  467. provider=custom_provider_configuration,
  468. models=custom_model_configurations
  469. )
  470. def _to_system_configuration(self,
  471. tenant_id: str,
  472. provider_entity: ProviderEntity,
  473. provider_records: list[Provider]) -> SystemConfiguration:
  474. """
  475. Convert to system configuration.
  476. :param tenant_id: workspace id
  477. :param provider_entity: provider entity
  478. :param provider_records: provider records
  479. :return:
  480. """
  481. # Get hosting configuration
  482. hosting_configuration = ext_hosting_provider.hosting_configuration
  483. if provider_entity.provider not in hosting_configuration.provider_map \
  484. or not hosting_configuration.provider_map.get(provider_entity.provider).enabled:
  485. return SystemConfiguration(
  486. enabled=False
  487. )
  488. provider_hosting_configuration = hosting_configuration.provider_map.get(provider_entity.provider)
  489. # Convert provider_records to dict
  490. quota_type_to_provider_records_dict = dict()
  491. for provider_record in provider_records:
  492. if provider_record.provider_type != ProviderType.SYSTEM.value:
  493. continue
  494. quota_type_to_provider_records_dict[ProviderQuotaType.value_of(provider_record.quota_type)] \
  495. = provider_record
  496. quota_configurations = []
  497. for provider_quota in provider_hosting_configuration.quotas:
  498. if provider_quota.quota_type not in quota_type_to_provider_records_dict:
  499. continue
  500. provider_record = quota_type_to_provider_records_dict[provider_quota.quota_type]
  501. quota_configuration = QuotaConfiguration(
  502. quota_type=provider_quota.quota_type,
  503. quota_unit=provider_hosting_configuration.quota_unit,
  504. quota_used=provider_record.quota_used,
  505. quota_limit=provider_record.quota_limit,
  506. is_valid=provider_record.quota_limit > provider_record.quota_used or provider_record.quota_limit == -1,
  507. restrict_llms=provider_quota.restrict_llms
  508. )
  509. quota_configurations.append(quota_configuration)
  510. if len(quota_configurations) == 0:
  511. return SystemConfiguration(
  512. enabled=False
  513. )
  514. current_quota_type = self._choice_current_using_quota_type(quota_configurations)
  515. current_using_credentials = provider_hosting_configuration.credentials
  516. if current_quota_type == ProviderQuotaType.FREE:
  517. provider_record = quota_type_to_provider_records_dict.get(current_quota_type)
  518. if provider_record:
  519. provider_credentials_cache = ProviderCredentialsCache(
  520. tenant_id=tenant_id,
  521. identity_id=provider_record.id,
  522. cache_type=ProviderCredentialsCacheType.PROVIDER
  523. )
  524. # Get cached provider credentials
  525. cached_provider_credentials = provider_credentials_cache.get()
  526. if not cached_provider_credentials:
  527. try:
  528. provider_credentials = json.loads(provider_record.encrypted_config)
  529. except JSONDecodeError:
  530. provider_credentials = {}
  531. # Get provider credential secret variables
  532. provider_credential_secret_variables = self._extract_secret_variables(
  533. provider_entity.provider_credential_schema.credential_form_schemas
  534. if provider_entity.provider_credential_schema else []
  535. )
  536. # Get decoding rsa key and cipher for decrypting credentials
  537. decoding_rsa_key, decoding_cipher_rsa = encrypter.get_decrypt_decoding(tenant_id)
  538. for variable in provider_credential_secret_variables:
  539. if variable in provider_credentials:
  540. try:
  541. provider_credentials[variable] = encrypter.decrypt_token_with_decoding(
  542. provider_credentials.get(variable),
  543. decoding_rsa_key,
  544. decoding_cipher_rsa
  545. )
  546. except ValueError:
  547. pass
  548. current_using_credentials = provider_credentials
  549. # cache provider credentials
  550. provider_credentials_cache.set(
  551. credentials=current_using_credentials
  552. )
  553. else:
  554. current_using_credentials = cached_provider_credentials
  555. else:
  556. current_using_credentials = {}
  557. return SystemConfiguration(
  558. enabled=True,
  559. current_quota_type=current_quota_type,
  560. quota_configurations=quota_configurations,
  561. credentials=current_using_credentials
  562. )
  563. def _choice_current_using_quota_type(self, quota_configurations: list[QuotaConfiguration]) -> ProviderQuotaType:
  564. """
  565. Choice current using quota type.
  566. paid quotas > provider free quotas > hosting trial quotas
  567. If there is still quota for the corresponding quota type according to the sorting,
  568. :param quota_configurations:
  569. :return:
  570. """
  571. # convert to dict
  572. quota_type_to_quota_configuration_dict = {
  573. quota_configuration.quota_type: quota_configuration
  574. for quota_configuration in quota_configurations
  575. }
  576. last_quota_configuration = None
  577. for quota_type in [ProviderQuotaType.PAID, ProviderQuotaType.FREE, ProviderQuotaType.TRIAL]:
  578. if quota_type in quota_type_to_quota_configuration_dict:
  579. last_quota_configuration = quota_type_to_quota_configuration_dict[quota_type]
  580. if last_quota_configuration.is_valid:
  581. return quota_type
  582. if last_quota_configuration:
  583. return last_quota_configuration.quota_type
  584. raise ValueError('No quota type available')
  585. def _extract_secret_variables(self, credential_form_schemas: list[CredentialFormSchema]) -> list[str]:
  586. """
  587. Extract secret input form variables.
  588. :param credential_form_schemas:
  589. :return:
  590. """
  591. secret_input_form_variables = []
  592. for credential_form_schema in credential_form_schemas:
  593. if credential_form_schema.type == FormType.SECRET_INPUT:
  594. secret_input_form_variables.append(credential_form_schema.variable)
  595. return secret_input_form_variables