rasa-pro 3.11.0rc3__py3-none-any.whl → 3.11.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rasa-pro might be problematic. Click here for more details.

Files changed (92) hide show
  1. rasa/__main__.py +9 -3
  2. rasa/cli/llm_fine_tuning.py +19 -11
  3. rasa/cli/project_templates/tutorial/config.yml +1 -3
  4. rasa/cli/project_templates/tutorial/endpoints.yml +8 -3
  5. rasa/cli/studio/upload.py +0 -15
  6. rasa/cli/train.py +9 -0
  7. rasa/cli/utils.py +1 -1
  8. rasa/core/channels/development_inspector.py +4 -1
  9. rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-861ddd57.js} +1 -1
  10. rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-921f02db.js} +1 -1
  11. rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-b436c4f8.js} +1 -1
  12. rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-511a23cb.js} +1 -1
  13. rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-ef476ecd.js} +1 -1
  14. rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-f1878e0a.js} +1 -1
  15. rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-fac75185.js} +1 -1
  16. rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-201c5bbc.js} +1 -1
  17. rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-f904ae41.js} +1 -1
  18. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-b080d6f2.js +1 -0
  19. rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-1813da66.js} +1 -1
  20. rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-872af172.js} +1 -1
  21. rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-34a0af5a.js} +1 -1
  22. rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-42ba3e3d.js} +1 -1
  23. rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-37817b51.js} +68 -68
  24. rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-6b731386.js} +1 -1
  25. rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-e8579ac6.js} +1 -1
  26. rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-89e6403a.js} +1 -1
  27. rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-dc73d3fc.js} +1 -1
  28. rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-f5b1d2bc.js} +1 -1
  29. rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-82cb74fa.js} +1 -1
  30. rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-bdf5f29b.js} +1 -1
  31. rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-c7a0cbe4.js} +1 -1
  32. rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-7ec5410f.js} +1 -1
  33. rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-caee5554.js} +1 -1
  34. rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-2935f8db.js} +1 -1
  35. rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-8f5d9693.js} +1 -1
  36. rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-d565d1de.js} +1 -1
  37. rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-75ad421d.js} +1 -1
  38. rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-7e764226.js} +1 -1
  39. rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-7a4e0e61.js} +1 -1
  40. rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-4019d1bf.js} +1 -1
  41. rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-01ea12df.js} +1 -1
  42. rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-89407137.js} +1 -1
  43. rasa/core/channels/inspector/dist/index.html +1 -1
  44. rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +1 -1
  45. rasa/core/channels/inspector/src/helpers/audiostream.ts +28 -2
  46. rasa/core/channels/voice_stream/asr/asr_engine.py +19 -1
  47. rasa/core/channels/voice_stream/asr/azure.py +13 -3
  48. rasa/core/channels/voice_stream/asr/deepgram.py +4 -3
  49. rasa/core/channels/voice_stream/tts/azure.py +3 -1
  50. rasa/core/channels/voice_stream/tts/cartesia.py +3 -3
  51. rasa/core/channels/voice_stream/tts/tts_engine.py +10 -1
  52. rasa/core/information_retrieval/qdrant.py +1 -0
  53. rasa/core/persistor.py +93 -49
  54. rasa/core/policies/flows/flow_executor.py +18 -8
  55. rasa/core/processor.py +7 -5
  56. rasa/core/utils.py +3 -1
  57. rasa/e2e_test/aggregate_test_stats_calculator.py +11 -1
  58. rasa/e2e_test/assertions.py +183 -19
  59. rasa/e2e_test/assertions_schema.yml +23 -0
  60. rasa/e2e_test/e2e_test_runner.py +4 -3
  61. rasa/engine/graph.py +9 -3
  62. rasa/engine/loader.py +12 -0
  63. rasa/engine/validation.py +345 -85
  64. rasa/model_manager/config.py +8 -0
  65. rasa/model_manager/model_api.py +166 -61
  66. rasa/model_manager/runner_service.py +31 -26
  67. rasa/model_manager/trainer_service.py +14 -23
  68. rasa/model_manager/warm_rasa_process.py +187 -0
  69. rasa/model_service.py +3 -5
  70. rasa/model_training.py +3 -1
  71. rasa/shared/constants.py +27 -0
  72. rasa/shared/core/domain.py +8 -5
  73. rasa/shared/core/flows/yaml_flows_io.py +13 -4
  74. rasa/shared/importers/importer.py +19 -2
  75. rasa/shared/importers/rasa.py +5 -1
  76. rasa/shared/nlu/training_data/formats/rasa_yaml.py +18 -3
  77. rasa/shared/providers/_utils.py +79 -0
  78. rasa/shared/providers/embedding/default_litellm_embedding_client.py +24 -0
  79. rasa/shared/providers/llm/default_litellm_llm_client.py +24 -0
  80. rasa/shared/utils/common.py +29 -2
  81. rasa/shared/utils/health_check/health_check.py +26 -24
  82. rasa/shared/utils/yaml.py +116 -31
  83. rasa/studio/data_handler.py +3 -1
  84. rasa/studio/upload.py +119 -57
  85. rasa/validator.py +40 -4
  86. rasa/version.py +1 -1
  87. {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/METADATA +2 -2
  88. {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/RECORD +91 -89
  89. rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
  90. {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/NOTICE +0 -0
  91. {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/WHEEL +0 -0
  92. {rasa_pro-3.11.0rc3.dist-info → rasa_pro-3.11.2.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import sys
2
3
  from typing import Optional, Dict, Any
3
4
 
4
5
  from rasa.shared.constants import (
@@ -9,7 +10,6 @@ from rasa.shared.constants import (
9
10
  from rasa.shared.exceptions import ProviderClientValidationError
10
11
  from rasa.shared.providers.embedding.embedding_client import EmbeddingClient
11
12
  from rasa.shared.providers.llm.llm_client import LLMClient
12
- from rasa.shared.utils.cli import print_error_and_exit
13
13
  from rasa.shared.utils.llm import llm_factory, structlogger, embedder_factory
14
14
 
15
15
 
@@ -25,15 +25,15 @@ def try_instantiate_llm_client(
25
25
  except (ProviderClientValidationError, ValueError) as e:
26
26
  structlogger.error(
27
27
  f"{log_source_function}.llm_instantiation_failed",
28
- message="Unable to instantiate LLM client.",
28
+ event_info=(
29
+ f"Unable to create the LLM client for component - "
30
+ f"{log_source_component}. "
31
+ f"Please make sure you specified the required environment variables "
32
+ f"and configuration keys. "
33
+ ),
29
34
  error=e,
30
35
  )
31
- print_error_and_exit(
32
- f"Unable to create the LLM client for component - {log_source_component}. "
33
- f"Please make sure you specified the required environment variables "
34
- f"and configuration keys. "
35
- f"Error: {e}"
36
- )
36
+ sys.exit(1)
37
37
 
38
38
 
39
39
  def try_instantiate_embedder(
@@ -48,14 +48,14 @@ def try_instantiate_embedder(
48
48
  except (ProviderClientValidationError, ValueError) as e:
49
49
  structlogger.error(
50
50
  f"{log_source_function}.embedder_instantiation_failed",
51
- message="Unable to instantiate Embedding client.",
51
+ event_info=(
52
+ f"Unable to create the Embedding client for component - "
53
+ f"{log_source_component}. Please make sure you specified the required "
54
+ f"environment variables and configuration keys."
55
+ ),
52
56
  error=e,
53
57
  )
54
- print_error_and_exit(
55
- f"Unable to create the Embedding client for component - "
56
- f"{log_source_component}. Please make sure you specified the required "
57
- f"environment variables and configuration keys. Error: {e}"
58
- )
58
+ sys.exit(1)
59
59
 
60
60
 
61
61
  def perform_llm_health_check(
@@ -202,13 +202,14 @@ def send_test_llm_api_request(
202
202
  except Exception as e:
203
203
  structlogger.error(
204
204
  f"{log_source_function}.send_test_llm_api_request_failed",
205
- event_info="Test call to the LLM API failed.",
205
+ event_info=(
206
+ f"Test call to the LLM API failed for component - "
207
+ f"{log_source_component}.",
208
+ ),
209
+ config=llm_client.config,
206
210
  error=e,
207
211
  )
208
- print_error_and_exit(
209
- f"Test call to the LLM API failed for component - {log_source_component}. "
210
- f"Error: {e}"
211
- )
212
+ sys.exit(1)
212
213
 
213
214
 
214
215
  def send_test_embeddings_api_request(
@@ -232,13 +233,14 @@ def send_test_embeddings_api_request(
232
233
  except Exception as e:
233
234
  structlogger.error(
234
235
  f"{log_source_function}.send_test_llm_api_request_failed",
235
- event_info="Test call to the Embeddings API failed.",
236
+ event_info=(
237
+ f"Test call to the Embeddings API failed for component - "
238
+ f"{log_source_component}."
239
+ ),
240
+ config=embedder.config,
236
241
  error=e,
237
242
  )
238
- print_error_and_exit(
239
- f"Test call to the Embeddings API failed for component - "
240
- f"{log_source_component}. Error: {e}"
241
- )
243
+ sys.exit(1)
242
244
 
243
245
 
244
246
  def is_api_health_check_enabled() -> bool:
rasa/shared/utils/yaml.py CHANGED
@@ -1,3 +1,4 @@
1
+ from contextlib import contextmanager
1
2
  import datetime
2
3
  import io
3
4
  import logging
@@ -9,7 +10,7 @@ from dataclasses import field
9
10
  from functools import lru_cache
10
11
  from io import StringIO
11
12
  from pathlib import Path
12
- from typing import Any, List, Optional, Tuple, Dict, Callable, Union
13
+ from typing import Any, Generator, List, Optional, Tuple, Dict, Callable, Union
13
14
 
14
15
  import jsonschema
15
16
  from importlib_resources import files
@@ -26,7 +27,7 @@ from rasa.shared.constants import (
26
27
  LATEST_TRAINING_DATA_FORMAT_VERSION,
27
28
  SCHEMA_EXTENSIONS_FILE,
28
29
  RESPONSES_SCHEMA_FILE,
29
- API_KEY,
30
+ SENSITIVE_DATA,
30
31
  )
31
32
  from rasa.shared.exceptions import (
32
33
  YamlException,
@@ -59,7 +60,6 @@ YAML_VERSION = (1, 2)
59
60
  READ_YAML_FILE_CACHE_MAXSIZE = os.environ.get(
60
61
  READ_YAML_FILE_CACHE_MAXSIZE_ENV_VAR, DEFAULT_READ_YAML_FILE_CACHE_MAXSIZE
61
62
  )
62
- SENSITIVE_DATA = [API_KEY]
63
63
 
64
64
 
65
65
  @dataclass
@@ -88,13 +88,19 @@ def fix_yaml_loader() -> None:
88
88
  yaml.Loader.add_constructor("tag:yaml.org,2002:str", construct_yaml_str)
89
89
  yaml.SafeLoader.add_constructor("tag:yaml.org,2002:str", construct_yaml_str)
90
90
 
91
+ _add_env_var_resolver()
91
92
 
92
- def replace_environment_variables() -> None:
93
- """Enable yaml loader to process the environment variables in the yaml."""
93
+
94
+ def _add_env_var_resolver() -> None:
95
+ """Enable yaml loader to detect the environment variables in the yaml."""
94
96
  # eg. ${USER_NAME}, ${PASSWORD}
95
97
  env_var_pattern = re.compile(r"^(.*)\$\{(.*)\}(.*)$")
96
98
  yaml.Resolver.add_implicit_resolver("!env_var", env_var_pattern, None)
97
99
 
100
+
101
+ def _add_yaml_constructor_to_replace_environment_variables() -> None:
102
+ """Enable yaml loader to replace the environment variables in the yaml."""
103
+
98
104
  def env_var_constructor(loader: BaseConstructor, node: ScalarNode) -> str:
99
105
  """Process environment variables found in the YAML."""
100
106
  value = loader.construct_scalar(node)
@@ -121,7 +127,6 @@ def replace_environment_variables() -> None:
121
127
 
122
128
 
123
129
  fix_yaml_loader()
124
- replace_environment_variables()
125
130
 
126
131
 
127
132
  class YamlValidationException(YamlException, ValueError):
@@ -343,7 +348,7 @@ class YamlValidationException(YamlException, ValueError):
343
348
 
344
349
 
345
350
  def read_schema_file(
346
- schema_file: str, package_name: str = PACKAGE_NAME
351
+ schema_file: str, package_name: str = PACKAGE_NAME, expand_env_vars: bool = True
347
352
  ) -> Union[List[Any], Dict[str, Any]]:
348
353
  """Read a schema file from the package.
349
354
 
@@ -351,12 +356,13 @@ def read_schema_file(
351
356
  schema_file: The schema file to read.
352
357
  package_name: the name of the package the schema is located in. defaults
353
358
  to `rasa`.
359
+ expand_env_vars: Whether to expand environment variables in the file.
354
360
 
355
361
  Returns:
356
362
  The schema as a dictionary.
357
363
  """
358
364
  schema_path = str(files(package_name).joinpath(schema_file))
359
- return read_yaml_file(schema_path)
365
+ return read_yaml_file(schema_path, expand_env_vars=expand_env_vars)
360
366
 
361
367
 
362
368
  def parse_raw_yaml(raw_yaml_content: str) -> Dict[str, Any]:
@@ -430,6 +436,7 @@ def validate_raw_yaml_using_schema(
430
436
  raw_yaml_content: str,
431
437
  schema_content: Dict[str, Any],
432
438
  schema_extensions: Optional[List[str]] = None,
439
+ expand_env_vars: bool = True,
433
440
  ) -> None:
434
441
  """Validate raw yaml content using a schema.
435
442
 
@@ -439,6 +446,7 @@ def validate_raw_yaml_using_schema(
439
446
  raw_yaml_content: the raw YAML content to be validated (usually a string)
440
447
  schema_content: the schema for the yaml_file_content
441
448
  schema_extensions: pykwalify schema extension files
449
+ expand_env_vars: Whether to expand environment variables.
442
450
  """
443
451
  try:
444
452
  # we need "rt" since
@@ -446,7 +454,11 @@ def validate_raw_yaml_using_schema(
446
454
  # will include e.g. at which line an object was parsed. this is very
447
455
  # helpful when we validate files later on and want to point the user to the
448
456
  # right line
449
- yaml_data = read_yaml(raw_yaml_content, reader_type=["safe", "rt"])
457
+ yaml_data = read_yaml(
458
+ raw_yaml_content,
459
+ reader_type=["safe", "rt"],
460
+ expand_env_vars=expand_env_vars,
461
+ )
450
462
  except (YAMLError, DuplicateKeyError) as e:
451
463
  raise YamlSyntaxException(underlying_yaml_exception=e)
452
464
 
@@ -454,7 +466,10 @@ def validate_raw_yaml_using_schema(
454
466
 
455
467
 
456
468
  def validate_raw_yaml_using_schema_file(
457
- raw_yaml_content: str, schema_path: str, package_name: str = PACKAGE_NAME
469
+ raw_yaml_content: str,
470
+ schema_path: str,
471
+ package_name: str = PACKAGE_NAME,
472
+ expand_env_vars: bool = True,
458
473
  ) -> None:
459
474
  """Validate raw yaml content using a schema from file.
460
475
 
@@ -463,15 +478,21 @@ def validate_raw_yaml_using_schema_file(
463
478
  schema_path: the schema used for validation
464
479
  package_name: the name of the package the schema is located in. defaults
465
480
  to `rasa`.
481
+ expand_env_vars: Whether to expand environment variables in the file.
466
482
  """
467
- schema_content = read_schema_file(schema_path, package_name)
468
- validate_raw_yaml_using_schema(raw_yaml_content, schema_content)
483
+ schema_content = read_schema_file(
484
+ schema_path, package_name, expand_env_vars=expand_env_vars
485
+ )
486
+ validate_raw_yaml_using_schema(
487
+ raw_yaml_content, schema_content, expand_env_vars=expand_env_vars
488
+ )
469
489
 
470
490
 
471
491
  def validate_raw_yaml_content_using_schema_with_responses(
472
492
  raw_yaml_content: str,
473
493
  schema_content: Union[List[Any], Dict[str, Any]],
474
494
  package_name: str = PACKAGE_NAME,
495
+ expand_env_vars: bool = True,
475
496
  ) -> None:
476
497
  """Validate raw yaml content using a schema with responses sub-schema.
477
498
 
@@ -480,18 +501,26 @@ def validate_raw_yaml_content_using_schema_with_responses(
480
501
  schema_content: the content of the YAML schema
481
502
  package_name: the name of the package the schema is located in. defaults
482
503
  to `rasa`.
504
+ expand_env_vars: Whether to expand environment variables in the file.
483
505
  """
484
506
  # bot responses are part of the schema extension
485
507
  # it will be included if the schema explicitly references it with include: responses
486
- bot_responses_schema_content = read_schema_file(RESPONSES_SCHEMA_FILE, package_name)
508
+ bot_responses_schema_content = read_schema_file(
509
+ RESPONSES_SCHEMA_FILE, package_name, expand_env_vars=expand_env_vars
510
+ )
487
511
  schema_content = dict(schema_content, **bot_responses_schema_content)
488
512
  schema_extensions = [str(files(package_name).joinpath(SCHEMA_EXTENSIONS_FILE))]
489
513
 
490
- validate_raw_yaml_using_schema(raw_yaml_content, schema_content, schema_extensions)
514
+ validate_raw_yaml_using_schema(
515
+ raw_yaml_content, schema_content, schema_extensions, expand_env_vars
516
+ )
491
517
 
492
518
 
493
519
  def validate_raw_yaml_using_schema_file_with_responses(
494
- raw_yaml_content: str, schema_path: str, package_name: str = PACKAGE_NAME
520
+ raw_yaml_content: str,
521
+ schema_path: str,
522
+ package_name: str = PACKAGE_NAME,
523
+ expand_env_vars: bool = True,
495
524
  ) -> None:
496
525
  """Validate domain yaml content using a schema from file with responses sub-schema.
497
526
 
@@ -500,13 +529,32 @@ def validate_raw_yaml_using_schema_file_with_responses(
500
529
  schema_path: the schema of the yaml file
501
530
  package_name: the name of the package the schema is located in. defaults
502
531
  to `rasa`.
532
+ expand_env_vars: Whether to expand environment variables in the file.
503
533
  """
504
- schema_content = read_schema_file(schema_path, package_name)
534
+ schema_content = read_schema_file(schema_path, package_name, expand_env_vars)
505
535
  validate_raw_yaml_content_using_schema_with_responses(
506
- raw_yaml_content, schema_content, package_name
536
+ raw_yaml_content, schema_content, package_name, expand_env_vars
507
537
  )
508
538
 
509
539
 
540
+ @contextmanager
541
+ def environment_variables_replaced(
542
+ yaml_parser: yaml.YAML,
543
+ ) -> Generator[None, None, None]:
544
+ """Replace environment variables during yaml loading.
545
+
546
+ Resets the environment variable constructor after the context manager exits.
547
+ """
548
+ try:
549
+ _add_yaml_constructor_to_replace_environment_variables()
550
+ yield
551
+ finally:
552
+ # replace env var constructor with one that does not expand env vars
553
+ yaml_parser.constructor.add_constructor(
554
+ "!env_var", lambda loader, node: loader.construct_scalar(node)
555
+ )
556
+
557
+
510
558
  def read_yaml(
511
559
  content: str,
512
560
  reader_type: Union[str, List[str]] = "safe",
@@ -523,12 +571,17 @@ def read_yaml(
523
571
  ruamel.yaml.parser.ParserError: If there was an error when parsing the YAML.
524
572
  """
525
573
  custom_constructor = kwargs.get("custom_constructor", None)
574
+ expand_env_vars = kwargs.get("expand_env_vars", True)
526
575
 
527
576
  # Create YAML parser with custom constructor
528
577
  yaml_parser, reset_constructors = create_yaml_parser(
529
578
  reader_type, custom_constructor
530
579
  )
531
- yaml_content = yaml_parser.load(content) or {}
580
+ if expand_env_vars:
581
+ with environment_variables_replaced(yaml_parser):
582
+ yaml_content = yaml_parser.load(content) or {}
583
+ else:
584
+ yaml_content = yaml_parser.load(content) or {}
532
585
 
533
586
  # Reset to default constructors
534
587
  reset_constructors()
@@ -544,9 +597,9 @@ def create_yaml_parser(
544
597
 
545
598
  Args:
546
599
  reader_type (str): The type of the reader
547
- (e.g., 'safe', 'rt', 'unsafe').
600
+ (e.g., 'safe', 'rt', 'unsafe').
548
601
  custom_constructor (Optional[Callable]):
549
- A custom constructor function for YAML parsing.
602
+ A custom constructor function for YAML parsing.
550
603
 
551
604
  Returns:
552
605
  Tuple[yaml.YAML, Callable[[], None]]: A tuple containing
@@ -617,7 +670,9 @@ def _is_ascii(text: str) -> bool:
617
670
 
618
671
  @lru_cache(maxsize=READ_YAML_FILE_CACHE_MAXSIZE)
619
672
  def read_yaml_file(
620
- filename: Union[str, Path], reader_type: Union[str, Tuple[str]] = "safe"
673
+ filename: Union[str, Path],
674
+ reader_type: Union[str, Tuple[str]] = "safe",
675
+ expand_env_vars: bool = True,
621
676
  ) -> Union[List[Any], Dict[str, Any]]:
622
677
  """Parses a yaml file.
623
678
 
@@ -626,6 +681,7 @@ def read_yaml_file(
626
681
  Args:
627
682
  filename: The path to the file which should be read.
628
683
  reader_type: Reader type to use. By default "safe" will be used.
684
+ expand_env_vars: Whether to expand environment variables in the file.
629
685
 
630
686
  Returns:
631
687
  Parsed content of the file.
@@ -634,7 +690,11 @@ def read_yaml_file(
634
690
  fixed_reader_type = (
635
691
  list(reader_type) if isinstance(reader_type, tuple) else reader_type
636
692
  )
637
- return read_yaml(read_file(filename, DEFAULT_ENCODING), fixed_reader_type)
693
+ return read_yaml(
694
+ read_file(filename, DEFAULT_ENCODING),
695
+ fixed_reader_type,
696
+ expand_env_vars=expand_env_vars,
697
+ )
638
698
  except (YAMLError, DuplicateKeyError) as e:
639
699
  raise YamlSyntaxException(filename, e)
640
700
 
@@ -657,11 +717,14 @@ def read_config_file(
657
717
  return read_validated_yaml(filename, CONFIG_SCHEMA_FILE, reader_type)
658
718
 
659
719
 
660
- def read_model_configuration(filename: Union[Path, str]) -> Dict[str, Any]:
720
+ def read_model_configuration(
721
+ filename: Union[Path, str], expand_env_vars: bool = True
722
+ ) -> Dict[str, Any]:
661
723
  """Parses a model configuration file.
662
724
 
663
725
  Args:
664
726
  filename: The path to the file which should be read.
727
+ expand_env_vars: Whether to expand environment variables in the file.
665
728
 
666
729
  Raises:
667
730
  YamlValidationException: In case the model configuration doesn't match the
@@ -670,24 +733,34 @@ def read_model_configuration(filename: Union[Path, str]) -> Dict[str, Any]:
670
733
  Returns:
671
734
  Parsed config file.
672
735
  """
673
- return read_validated_yaml(filename, MODEL_CONFIG_SCHEMA_FILE)
736
+ return read_validated_yaml(
737
+ filename, MODEL_CONFIG_SCHEMA_FILE, expand_env_vars=expand_env_vars
738
+ )
674
739
 
675
740
 
676
741
  def dump_obj_as_yaml_to_string(
677
- obj: Any, should_preserve_key_order: bool = False
742
+ obj: Any,
743
+ should_preserve_key_order: bool = False,
744
+ transform: Optional[Callable] = None,
678
745
  ) -> str:
679
746
  """Writes data (python dict) to a yaml string.
680
747
 
681
748
  Args:
682
749
  obj: The object to dump. Has to be serializable.
683
750
  should_preserve_key_order: Whether to force preserve key order in `data`.
751
+ transform: A function to transform the data before writing it to the file.
684
752
 
685
753
  Returns:
686
754
  The object converted to a YAML string.
687
755
  """
688
756
  buffer = StringIO()
689
757
 
690
- write_yaml(obj, buffer, should_preserve_key_order=should_preserve_key_order)
758
+ write_yaml(
759
+ obj,
760
+ buffer,
761
+ should_preserve_key_order=should_preserve_key_order,
762
+ transform=transform,
763
+ )
691
764
 
692
765
  return buffer.getvalue()
693
766
 
@@ -708,6 +781,7 @@ def write_yaml(
708
781
  data: Any,
709
782
  target: Union[str, Path, StringIO],
710
783
  should_preserve_key_order: bool = False,
784
+ transform: Optional[Callable[[Any], Any]] = None,
711
785
  ) -> None:
712
786
  """Writes a yaml to the file or to the stream.
713
787
 
@@ -715,6 +789,7 @@ def write_yaml(
715
789
  data: The data to write.
716
790
  target: The path to the file which should be written or a stream object
717
791
  should_preserve_key_order: Whether to force preserve key order in `data`.
792
+ transform: A function to transform the data before writing it to the file.
718
793
  """
719
794
  _enable_ordered_dict_yaml_dumping()
720
795
 
@@ -732,11 +807,11 @@ def write_yaml(
732
807
  )
733
808
 
734
809
  if isinstance(target, StringIO):
735
- dumper.dump(data, target)
810
+ dumper.dump(data, target, transform=transform)
736
811
  return
737
812
 
738
813
  with Path(target).open("w", encoding=DEFAULT_ENCODING) as outfile:
739
- dumper.dump(data, outfile)
814
+ dumper.dump(data, outfile, transform=transform)
740
815
 
741
816
 
742
817
  def is_key_in_yaml(file_path: Union[str, Path], *keys: str) -> bool:
@@ -768,6 +843,7 @@ def read_validated_yaml(
768
843
  filename: Union[str, Path],
769
844
  schema: str,
770
845
  reader_type: Union[str, List[str]] = "safe",
846
+ expand_env_vars: bool = True,
771
847
  ) -> Any:
772
848
  """Validates YAML file content and returns parsed content.
773
849
 
@@ -776,6 +852,7 @@ def read_validated_yaml(
776
852
  schema: The path to the schema file which should be used for validating the
777
853
  file content.
778
854
  reader_type: Reader type to use. By default, "safe" will be used.
855
+ expand_env_vars: Whether to expand environment variables in the file.
779
856
 
780
857
  Returns:
781
858
  The parsed file content.
@@ -786,8 +863,10 @@ def read_validated_yaml(
786
863
  """
787
864
  content = read_file(filename)
788
865
 
789
- validate_raw_yaml_using_schema_file(content, schema)
790
- return read_yaml(content, reader_type)
866
+ validate_raw_yaml_using_schema_file(
867
+ content, schema, expand_env_vars=expand_env_vars
868
+ )
869
+ return read_yaml(content, reader_type, expand_env_vars=expand_env_vars)
791
870
 
792
871
 
793
872
  def validate_training_data(json_data: Dict[str, Any], schema: Dict[str, Any]) -> None:
@@ -906,6 +985,7 @@ def validate_yaml_with_jsonschema(
906
985
  humanize_error: Callable[
907
986
  [jsonschema.ValidationError], str
908
987
  ] = default_error_humanizer,
988
+ expand_env_vars: bool = True,
909
989
  ) -> None:
910
990
  """Validate data format.
911
991
 
@@ -916,6 +996,7 @@ def validate_yaml_with_jsonschema(
916
996
  to `rasa`.
917
997
  humanize_error: a function to convert a jsonschema.ValidationError into a
918
998
  human-readable error message. Defaults to `default_error_humanizer`.
999
+ expand_env_vars: Whether to expand environment variables in the file.
919
1000
 
920
1001
  Raises:
921
1002
  YamlSyntaxException: if the yaml file is not valid.
@@ -933,7 +1014,11 @@ def validate_yaml_with_jsonschema(
933
1014
  # will include e.g. at which line an object was parsed. this is very
934
1015
  # helpful when we validate files later on and want to point the user to the
935
1016
  # right line
936
- source_data = read_yaml(yaml_file_content, reader_type=["safe", "rt"])
1017
+ source_data = read_yaml(
1018
+ yaml_file_content,
1019
+ reader_type=["safe", "rt"],
1020
+ expand_env_vars=expand_env_vars,
1021
+ )
937
1022
  except (YAMLError, DuplicateKeyError) as e:
938
1023
  raise YamlSyntaxException(underlying_yaml_exception=e)
939
1024
 
@@ -360,7 +360,9 @@ def import_data_from_studio(
360
360
  studio_domain.persist(domain_file)
361
361
 
362
362
  data_from_studio = TrainingDataImporter.load_from_dict(
363
- domain_path=str(domain_file), training_data_paths=data_paths
363
+ domain_path=str(domain_file),
364
+ training_data_paths=data_paths,
365
+ expand_env_vars=False,
364
366
  )
365
367
 
366
368
  return data_from_studio, data_original