rasa-pro 3.11.0__py3-none-any.whl → 3.11.0a1__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.
- README.md +396 -17
- rasa/__main__.py +15 -31
- rasa/api.py +1 -5
- rasa/cli/arguments/default_arguments.py +2 -1
- rasa/cli/arguments/shell.py +1 -5
- rasa/cli/arguments/train.py +0 -14
- rasa/cli/e2e_test.py +1 -1
- rasa/cli/evaluate.py +8 -8
- rasa/cli/inspect.py +7 -15
- rasa/cli/interactive.py +0 -1
- rasa/cli/llm_fine_tuning.py +1 -1
- rasa/cli/project_templates/calm/config.yml +7 -5
- rasa/cli/project_templates/calm/endpoints.yml +2 -15
- rasa/cli/project_templates/tutorial/config.yml +5 -8
- rasa/cli/project_templates/tutorial/data/flows.yml +1 -1
- rasa/cli/project_templates/tutorial/data/patterns.yml +0 -5
- rasa/cli/project_templates/tutorial/domain.yml +0 -14
- rasa/cli/project_templates/tutorial/endpoints.yml +0 -5
- rasa/cli/run.py +1 -1
- rasa/cli/scaffold.py +2 -4
- rasa/cli/studio/studio.py +8 -18
- rasa/cli/studio/upload.py +15 -0
- rasa/cli/train.py +0 -3
- rasa/cli/utils.py +1 -6
- rasa/cli/x.py +8 -8
- rasa/constants.py +1 -3
- rasa/core/actions/action.py +33 -75
- rasa/core/actions/e2e_stub_custom_action_executor.py +1 -5
- rasa/core/actions/http_custom_action_executor.py +0 -4
- rasa/core/channels/__init__.py +0 -2
- rasa/core/channels/channel.py +0 -20
- rasa/core/channels/development_inspector.py +3 -10
- rasa/core/channels/inspector/dist/assets/{arc-bc141fb2.js → arc-86942a71.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{c4Diagram-d0fbc5ce-be2db283.js → c4Diagram-d0fbc5ce-b0290676.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-936ed81e-55366915.js → classDiagram-936ed81e-f6405f6e.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{classDiagram-v2-c3cb15f1-bb529518.js → classDiagram-v2-c3cb15f1-ef61ac77.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{createText-62fc7601-b0ec81d6.js → createText-62fc7601-f0411e58.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{edges-f2ad444c-6166330c.js → edges-f2ad444c-7dcc4f3b.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{erDiagram-9d236eb7-5ccc6a8e.js → erDiagram-9d236eb7-e0c092d7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDb-1972c806-fca3bfe4.js → flowDb-1972c806-fba2e3ce.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{flowDiagram-7ea5b25a-4739080f.js → flowDiagram-7ea5b25a-7a70b71a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-24a5f41a.js +1 -0
- rasa/core/channels/inspector/dist/assets/{flowchart-elk-definition-abe16c3d-7c1b0e0f.js → flowchart-elk-definition-abe16c3d-00a59b68.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{ganttDiagram-9b5ea136-772fd050.js → ganttDiagram-9b5ea136-293c91fa.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{gitGraphDiagram-99d0ae7c-8eae1dc9.js → gitGraphDiagram-99d0ae7c-07b2d68c.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-2c4b9a3b-f55afcdf.js → index-2c4b9a3b-bc959fbd.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{index-e7cef9de.js → index-3a8a5a28.js} +143 -143
- rasa/core/channels/inspector/dist/assets/{infoDiagram-736b4530-124d4a14.js → infoDiagram-736b4530-4a350f72.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{journeyDiagram-df861f2b-7c4fae44.js → journeyDiagram-df861f2b-af464fb7.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{layout-b9885fb6.js → layout-0071f036.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{line-7c59abb6.js → line-2f73cc83.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{linear-4776f780.js → linear-f014b4cc.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{mindmap-definition-beec6740-2332c46c.js → mindmap-definition-beec6740-d2426fb6.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{pieDiagram-dbbf0591-8fb39303.js → pieDiagram-dbbf0591-776f01a2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{quadrantDiagram-4d7f4fd6-3c7180a2.js → quadrantDiagram-4d7f4fd6-82e00b57.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{requirementDiagram-6fc4c22a-e910bcb8.js → requirementDiagram-6fc4c22a-ea13c6bb.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sankeyDiagram-8f13d901-ead16c89.js → sankeyDiagram-8f13d901-1feca7e9.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{sequenceDiagram-b655622a-29a02a19.js → sequenceDiagram-b655622a-070c61d2.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-59f0c015-042b3137.js → stateDiagram-59f0c015-24f46263.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{stateDiagram-v2-2b26beab-2178c0f3.js → stateDiagram-v2-2b26beab-c9056051.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-080da4f6-23ffa4fc.js → styles-080da4f6-08abc34a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-3dcbcfbf-94f59763.js → styles-3dcbcfbf-bc74c25a.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{styles-9c745c82-78a6bebc.js → styles-9c745c82-4e5d66de.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{svgDrawCommon-4835440b-eae2a6f6.js → svgDrawCommon-4835440b-849c4517.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{timeline-definition-5b62e21b-5c968d92.js → timeline-definition-5b62e21b-d0fb1598.js} +1 -1
- rasa/core/channels/inspector/dist/assets/{xychartDiagram-2b33534f-fd3db0d5.js → xychartDiagram-2b33534f-04d115e2.js} +1 -1
- rasa/core/channels/inspector/dist/index.html +1 -1
- rasa/core/channels/inspector/src/App.tsx +1 -1
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +3 -6
- rasa/core/channels/socketio.py +2 -7
- rasa/core/channels/telegram.py +1 -1
- rasa/core/channels/twilio.py +1 -1
- rasa/core/channels/voice_ready/audiocodes.py +4 -15
- rasa/core/channels/voice_ready/jambonz.py +4 -15
- rasa/core/channels/voice_ready/twilio_voice.py +21 -6
- rasa/core/channels/voice_ready/utils.py +5 -6
- rasa/core/channels/voice_stream/asr/asr_engine.py +1 -19
- rasa/core/channels/voice_stream/asr/asr_event.py +0 -5
- rasa/core/channels/voice_stream/asr/deepgram.py +15 -28
- rasa/core/channels/voice_stream/audio_bytes.py +0 -1
- rasa/core/channels/voice_stream/tts/azure.py +3 -9
- rasa/core/channels/voice_stream/tts/cartesia.py +8 -12
- rasa/core/channels/voice_stream/tts/tts_engine.py +1 -11
- rasa/core/channels/voice_stream/twilio_media_streams.py +19 -28
- rasa/core/channels/voice_stream/util.py +4 -4
- rasa/core/channels/voice_stream/voice_channel.py +42 -222
- rasa/core/featurizers/single_state_featurizer.py +1 -22
- rasa/core/featurizers/tracker_featurizers.py +18 -115
- rasa/core/information_retrieval/qdrant.py +0 -1
- rasa/core/nlg/contextual_response_rephraser.py +25 -44
- rasa/core/persistor.py +34 -191
- rasa/core/policies/enterprise_search_policy.py +60 -119
- rasa/core/policies/flows/flow_executor.py +4 -7
- rasa/core/policies/intentless_policy.py +22 -82
- rasa/core/policies/ted_policy.py +33 -58
- rasa/core/policies/unexpected_intent_policy.py +7 -15
- rasa/core/processor.py +13 -89
- rasa/core/run.py +2 -2
- rasa/core/training/interactive.py +35 -34
- rasa/core/utils.py +22 -58
- rasa/dialogue_understanding/coexistence/llm_based_router.py +12 -39
- rasa/dialogue_understanding/commands/__init__.py +0 -4
- rasa/dialogue_understanding/commands/change_flow_command.py +0 -6
- rasa/dialogue_understanding/commands/utils.py +0 -5
- rasa/dialogue_understanding/generator/constants.py +0 -2
- rasa/dialogue_understanding/generator/flow_retrieval.py +4 -49
- rasa/dialogue_understanding/generator/llm_based_command_generator.py +23 -37
- rasa/dialogue_understanding/generator/multi_step/multi_step_llm_command_generator.py +10 -57
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +1 -19
- rasa/dialogue_understanding/generator/single_step/command_prompt_template.jinja2 +0 -3
- rasa/dialogue_understanding/generator/single_step/single_step_llm_command_generator.py +10 -90
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +0 -53
- rasa/dialogue_understanding/processor/command_processor.py +1 -21
- rasa/e2e_test/assertions.py +16 -133
- rasa/e2e_test/assertions_schema.yml +0 -23
- rasa/e2e_test/e2e_test_case.py +6 -85
- rasa/e2e_test/e2e_test_runner.py +4 -6
- rasa/e2e_test/utils/io.py +1 -3
- rasa/engine/loader.py +0 -12
- rasa/engine/validation.py +11 -541
- rasa/keys +1 -0
- rasa/llm_fine_tuning/notebooks/unsloth_finetuning.ipynb +407 -0
- rasa/model_training.py +7 -29
- rasa/nlu/classifiers/diet_classifier.py +25 -38
- rasa/nlu/classifiers/logistic_regression_classifier.py +9 -22
- rasa/nlu/classifiers/sklearn_intent_classifier.py +16 -37
- rasa/nlu/extractors/crf_entity_extractor.py +50 -93
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +16 -45
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +17 -52
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +3 -5
- rasa/nlu/tokenizers/whitespace_tokenizer.py +14 -3
- rasa/server.py +1 -3
- rasa/shared/constants.py +0 -61
- rasa/shared/core/constants.py +0 -9
- rasa/shared/core/domain.py +5 -8
- rasa/shared/core/flows/flow.py +0 -5
- rasa/shared/core/flows/flows_list.py +1 -5
- rasa/shared/core/flows/flows_yaml_schema.json +0 -10
- rasa/shared/core/flows/validation.py +0 -96
- rasa/shared/core/flows/yaml_flows_io.py +4 -13
- rasa/shared/core/slots.py +0 -5
- rasa/shared/importers/importer.py +2 -19
- rasa/shared/importers/rasa.py +1 -5
- rasa/shared/nlu/training_data/features.py +2 -120
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +3 -18
- rasa/shared/providers/_configs/azure_openai_client_config.py +3 -5
- rasa/shared/providers/_configs/openai_client_config.py +1 -1
- rasa/shared/providers/_configs/self_hosted_llm_client_config.py +0 -1
- rasa/shared/providers/_configs/utils.py +0 -16
- rasa/shared/providers/embedding/_base_litellm_embedding_client.py +29 -18
- rasa/shared/providers/embedding/azure_openai_embedding_client.py +21 -54
- rasa/shared/providers/embedding/default_litellm_embedding_client.py +0 -24
- rasa/shared/providers/llm/_base_litellm_client.py +31 -63
- rasa/shared/providers/llm/azure_openai_llm_client.py +29 -50
- rasa/shared/providers/llm/default_litellm_llm_client.py +0 -24
- rasa/shared/providers/llm/self_hosted_llm_client.py +29 -17
- rasa/shared/providers/mappings.py +0 -19
- rasa/shared/utils/common.py +2 -37
- rasa/shared/utils/io.py +6 -28
- rasa/shared/utils/llm.py +46 -353
- rasa/shared/utils/yaml.py +82 -181
- rasa/studio/auth.py +5 -3
- rasa/studio/config.py +4 -13
- rasa/studio/constants.py +0 -1
- rasa/studio/data_handler.py +4 -13
- rasa/studio/upload.py +80 -175
- rasa/telemetry.py +17 -94
- rasa/tracing/config.py +1 -3
- rasa/tracing/instrumentation/attribute_extractors.py +17 -94
- rasa/tracing/instrumentation/instrumentation.py +0 -121
- rasa/utils/common.py +0 -5
- rasa/utils/endpoints.py +1 -27
- rasa/utils/io.py +81 -7
- rasa/utils/log_utils.py +2 -9
- rasa/utils/tensorflow/model_data.py +193 -2
- rasa/validator.py +4 -110
- rasa/version.py +1 -1
- rasa_pro-3.11.0a1.dist-info/METADATA +576 -0
- {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/RECORD +182 -216
- rasa/core/actions/action_repeat_bot_messages.py +0 -89
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-736177bf.js +0 -1
- rasa/core/channels/inspector/src/helpers/audiostream.ts +0 -165
- rasa/core/channels/voice_stream/asr/azure.py +0 -129
- rasa/core/channels/voice_stream/browser_audio.py +0 -107
- rasa/core/channels/voice_stream/call_state.py +0 -23
- rasa/dialogue_understanding/commands/repeat_bot_messages_command.py +0 -60
- rasa/dialogue_understanding/commands/user_silence_command.py +0 -59
- rasa/dialogue_understanding/patterns/repeat.py +0 -37
- rasa/dialogue_understanding/patterns/user_silence.py +0 -37
- rasa/model_manager/__init__.py +0 -0
- rasa/model_manager/config.py +0 -40
- rasa/model_manager/model_api.py +0 -559
- rasa/model_manager/runner_service.py +0 -286
- rasa/model_manager/socket_bridge.py +0 -146
- rasa/model_manager/studio_jwt_auth.py +0 -86
- rasa/model_manager/trainer_service.py +0 -325
- rasa/model_manager/utils.py +0 -87
- rasa/model_manager/warm_rasa_process.py +0 -187
- rasa/model_service.py +0 -112
- rasa/shared/core/flows/utils.py +0 -39
- rasa/shared/providers/_configs/litellm_router_client_config.py +0 -220
- rasa/shared/providers/_configs/model_group_config.py +0 -167
- rasa/shared/providers/_configs/rasa_llm_client_config.py +0 -73
- rasa/shared/providers/_utils.py +0 -79
- rasa/shared/providers/embedding/litellm_router_embedding_client.py +0 -135
- rasa/shared/providers/llm/litellm_router_llm_client.py +0 -182
- rasa/shared/providers/llm/rasa_llm_client.py +0 -112
- rasa/shared/providers/router/__init__.py +0 -0
- rasa/shared/providers/router/_base_litellm_router_client.py +0 -183
- rasa/shared/providers/router/router_client.py +0 -73
- rasa/shared/utils/health_check/__init__.py +0 -0
- rasa/shared/utils/health_check/embeddings_health_check_mixin.py +0 -31
- rasa/shared/utils/health_check/health_check.py +0 -258
- rasa/shared/utils/health_check/llm_health_check_mixin.py +0 -31
- rasa/utils/sanic_error_handler.py +0 -32
- rasa/utils/tensorflow/feature_array.py +0 -366
- rasa_pro-3.11.0.dist-info/METADATA +0 -198
- {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/NOTICE +0 -0
- {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/WHEEL +0 -0
- {rasa_pro-3.11.0.dist-info → rasa_pro-3.11.0a1.dist-info}/entry_points.txt +0 -0
rasa/core/persistor.py
CHANGED
|
@@ -4,19 +4,16 @@ import abc
|
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
6
|
from enum import Enum
|
|
7
|
-
from pathlib import Path
|
|
8
7
|
from typing import TYPE_CHECKING, List, Optional, Text, Tuple, Union
|
|
9
8
|
|
|
10
9
|
import structlog
|
|
11
10
|
|
|
12
|
-
from rasa.exceptions import ModelNotFound
|
|
13
11
|
import rasa.shared.utils.common
|
|
14
12
|
import rasa.utils.common
|
|
15
13
|
from rasa.constants import (
|
|
16
14
|
HTTP_STATUS_FORBIDDEN,
|
|
17
15
|
HTTP_STATUS_NOT_FOUND,
|
|
18
16
|
MODEL_ARCHIVE_EXTENSION,
|
|
19
|
-
DEFAULT_BUCKET_NAME,
|
|
20
17
|
)
|
|
21
18
|
from rasa.env import (
|
|
22
19
|
AWS_ENDPOINT_URL_ENV,
|
|
@@ -31,7 +28,6 @@ from rasa.shared.utils.io import raise_warning
|
|
|
31
28
|
|
|
32
29
|
if TYPE_CHECKING:
|
|
33
30
|
from azure.storage.blob import ContainerClient
|
|
34
|
-
from botocore.exceptions import ClientError
|
|
35
31
|
|
|
36
32
|
structlogger = structlog.get_logger()
|
|
37
33
|
|
|
@@ -90,15 +86,14 @@ def get_persistor(storage: StorageType) -> Optional[Persistor]:
|
|
|
90
86
|
|
|
91
87
|
if storage == RemoteStorageType.AWS.value:
|
|
92
88
|
return AWSPersistor(
|
|
93
|
-
os.environ.get(BUCKET_NAME_ENV,
|
|
94
|
-
os.environ.get(AWS_ENDPOINT_URL_ENV),
|
|
89
|
+
os.environ.get(BUCKET_NAME_ENV), os.environ.get(AWS_ENDPOINT_URL_ENV)
|
|
95
90
|
)
|
|
96
91
|
if storage == RemoteStorageType.GCS.value:
|
|
97
|
-
return GCSPersistor(os.environ.get(BUCKET_NAME_ENV
|
|
92
|
+
return GCSPersistor(os.environ.get(BUCKET_NAME_ENV))
|
|
98
93
|
|
|
99
94
|
if storage == RemoteStorageType.AZURE.value:
|
|
100
95
|
return AzurePersistor(
|
|
101
|
-
os.environ.get(AZURE_CONTAINER_ENV
|
|
96
|
+
os.environ.get(AZURE_CONTAINER_ENV),
|
|
102
97
|
os.environ.get(AZURE_ACCOUNT_NAME_ENV),
|
|
103
98
|
os.environ.get(AZURE_ACCOUNT_KEY_ENV),
|
|
104
99
|
)
|
|
@@ -123,8 +118,7 @@ class Persistor(abc.ABC):
|
|
|
123
118
|
|
|
124
119
|
def persist(self, trained_model: str) -> None:
|
|
125
120
|
"""Uploads a trained model persisted in the `target_dir` to cloud storage."""
|
|
126
|
-
|
|
127
|
-
file_key = Path(absolute_file_key).name
|
|
121
|
+
file_key = self._create_file_key(trained_model)
|
|
128
122
|
self._persist_tar(file_key, trained_model)
|
|
129
123
|
|
|
130
124
|
def retrieve(self, model_name: Text, target_path: Text) -> Text:
|
|
@@ -143,8 +137,7 @@ class Persistor(abc.ABC):
|
|
|
143
137
|
# ensure backward compatibility
|
|
144
138
|
tar_name = self._tar_name(model_name)
|
|
145
139
|
tar_name = self._create_file_key(tar_name)
|
|
146
|
-
|
|
147
|
-
self._retrieve_tar(target_filename)
|
|
140
|
+
self._retrieve_tar(tar_name)
|
|
148
141
|
self._copy(os.path.basename(tar_name), target_path)
|
|
149
142
|
|
|
150
143
|
if os.path.isdir(target_path):
|
|
@@ -152,36 +145,6 @@ class Persistor(abc.ABC):
|
|
|
152
145
|
|
|
153
146
|
return target_path
|
|
154
147
|
|
|
155
|
-
def size_of_persisted_model(self, model_name: Text) -> int:
|
|
156
|
-
"""Returns the size of the model that has been persisted to cloud storage.
|
|
157
|
-
|
|
158
|
-
Args:
|
|
159
|
-
model_name: The name of the model to retrieve.
|
|
160
|
-
"""
|
|
161
|
-
tar_name = model_name
|
|
162
|
-
if not model_name.endswith(MODEL_ARCHIVE_EXTENSION):
|
|
163
|
-
# ensure backward compatibility
|
|
164
|
-
tar_name = self._tar_name(model_name)
|
|
165
|
-
tar_name = self._create_file_key(tar_name)
|
|
166
|
-
target_filename = os.path.basename(tar_name)
|
|
167
|
-
return self._retrieve_tar_size(target_filename)
|
|
168
|
-
|
|
169
|
-
def _retrieve_tar_size(self, filename: Text) -> int:
|
|
170
|
-
"""Returns the size of the model that has been persisted to cloud storage."""
|
|
171
|
-
structlogger.warning(
|
|
172
|
-
"persistor.retrieve_tar_size.not_implemented",
|
|
173
|
-
filename=filename,
|
|
174
|
-
event_info=(
|
|
175
|
-
"This method should be implemented in the persistor. "
|
|
176
|
-
"The default implementation will download the model "
|
|
177
|
-
"to calculate the size. Most persistors should override "
|
|
178
|
-
"this method to avoid downloading the model and get the "
|
|
179
|
-
"size directly from the cloud storage."
|
|
180
|
-
),
|
|
181
|
-
)
|
|
182
|
-
self._retrieve_tar(filename)
|
|
183
|
-
return os.path.getsize(os.path.basename(filename))
|
|
184
|
-
|
|
185
148
|
@abc.abstractmethod
|
|
186
149
|
def _retrieve_tar(self, filename: Text) -> None:
|
|
187
150
|
"""Downloads a model previously persisted to cloud storage."""
|
|
@@ -218,7 +181,7 @@ class Persistor(abc.ABC):
|
|
|
218
181
|
|
|
219
182
|
@staticmethod
|
|
220
183
|
def _create_file_key(model_path: str) -> Text:
|
|
221
|
-
"""Appends remote storage folders when provided to upload or retrieve file
|
|
184
|
+
"""Appends remote storage folders when provided to upload or retrieve file"""
|
|
222
185
|
bucket_object_path = os.environ.get(REMOTE_STORAGE_PATH_ENV)
|
|
223
186
|
|
|
224
187
|
# To keep the backward compatibility, if REMOTE_STORAGE_PATH is not provided,
|
|
@@ -230,7 +193,10 @@ class Persistor(abc.ABC):
|
|
|
230
193
|
f"{REMOTE_STORAGE_PATH_ENV} is deprecated and will be "
|
|
231
194
|
"removed in future versions. "
|
|
232
195
|
"Please use the -m path/to/model.tar.gz option to "
|
|
233
|
-
"specify the model path when loading a model."
|
|
196
|
+
"specify the model path when loading a model."
|
|
197
|
+
"Or use --output and --fixed-model-name to specify the "
|
|
198
|
+
"output directory and the model name when saving a "
|
|
199
|
+
"trained model to remote storage.",
|
|
234
200
|
)
|
|
235
201
|
|
|
236
202
|
file_key = os.path.basename(model_path)
|
|
@@ -263,13 +229,14 @@ class AWSPersistor(Persistor):
|
|
|
263
229
|
def _ensure_bucket_exists(
|
|
264
230
|
self, bucket_name: Text, region_name: Optional[Text] = None
|
|
265
231
|
) -> None:
|
|
266
|
-
|
|
232
|
+
import botocore
|
|
267
233
|
|
|
268
234
|
# noinspection PyUnresolvedReferences
|
|
269
235
|
try:
|
|
270
236
|
self.s3.meta.client.head_bucket(Bucket=bucket_name)
|
|
271
|
-
except exceptions.ClientError as
|
|
272
|
-
|
|
237
|
+
except botocore.exceptions.ClientError as e:
|
|
238
|
+
error_code = int(e.response["Error"]["Code"])
|
|
239
|
+
if error_code == HTTP_STATUS_FORBIDDEN:
|
|
273
240
|
log = (
|
|
274
241
|
f"Access to the specified bucket '{bucket_name}' is forbidden. "
|
|
275
242
|
"Please make sure you have the necessary "
|
|
@@ -281,7 +248,7 @@ class AWSPersistor(Persistor):
|
|
|
281
248
|
event_info=log,
|
|
282
249
|
)
|
|
283
250
|
raise RasaException(log)
|
|
284
|
-
elif
|
|
251
|
+
elif error_code == HTTP_STATUS_NOT_FOUND:
|
|
285
252
|
log = (
|
|
286
253
|
f"The specified bucket '{bucket_name}' does not exist. "
|
|
287
254
|
"Please make sure to create the bucket first."
|
|
@@ -293,57 +260,16 @@ class AWSPersistor(Persistor):
|
|
|
293
260
|
)
|
|
294
261
|
raise RasaException(log)
|
|
295
262
|
|
|
296
|
-
@staticmethod
|
|
297
|
-
def _error_code(e: "ClientError") -> int:
|
|
298
|
-
return int(e.response["Error"]["Code"])
|
|
299
|
-
|
|
300
263
|
def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
|
|
301
264
|
"""Uploads a model persisted in the `target_dir` to s3."""
|
|
302
265
|
with open(tar_path, "rb") as f:
|
|
303
266
|
self.s3.Object(self.bucket_name, file_key).put(Body=f)
|
|
304
267
|
|
|
305
|
-
def
|
|
306
|
-
"""Returns the size of the model that has been persisted to s3."""
|
|
307
|
-
try:
|
|
308
|
-
obj = self.s3.Object(self.bucket_name, model_path)
|
|
309
|
-
return obj.content_length
|
|
310
|
-
except Exception:
|
|
311
|
-
raise ModelNotFound()
|
|
312
|
-
|
|
313
|
-
def _retrieve_tar(self, target_filename: str) -> None:
|
|
268
|
+
def _retrieve_tar(self, model_path: Text) -> None:
|
|
314
269
|
"""Downloads a model that has previously been persisted to s3."""
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
f"Model '{target_filename}' not found in the specified bucket "
|
|
319
|
-
f"'{self.bucket_name}'. Please make sure the model exists "
|
|
320
|
-
f"in the bucket."
|
|
321
|
-
)
|
|
322
|
-
|
|
323
|
-
try:
|
|
324
|
-
with open(target_filename, "wb") as f:
|
|
325
|
-
self.bucket.download_fileobj(target_filename, f)
|
|
326
|
-
|
|
327
|
-
structlogger.debug(
|
|
328
|
-
"aws_persistor.retrieve_tar.object_found", object_key=target_filename
|
|
329
|
-
)
|
|
330
|
-
except exceptions.ClientError as exc:
|
|
331
|
-
if self._error_code(exc) == HTTP_STATUS_NOT_FOUND:
|
|
332
|
-
structlogger.error(
|
|
333
|
-
"aws_persistor.retrieve_tar.model_not_found",
|
|
334
|
-
bucket_name=self.bucket_name,
|
|
335
|
-
target_filename=target_filename,
|
|
336
|
-
event_info=log,
|
|
337
|
-
)
|
|
338
|
-
raise ModelNotFound() from exc
|
|
339
|
-
except exceptions.BotoCoreError as exc:
|
|
340
|
-
structlogger.error(
|
|
341
|
-
"aws_persistor.retrieve_tar.model_download_error",
|
|
342
|
-
bucket_name=self.bucket_name,
|
|
343
|
-
target_filename=target_filename,
|
|
344
|
-
event_info=log,
|
|
345
|
-
)
|
|
346
|
-
raise ModelNotFound() from exc
|
|
270
|
+
tar_name = os.path.basename(model_path)
|
|
271
|
+
with open(tar_name, "wb") as f:
|
|
272
|
+
self.bucket.download_fileobj(model_path, f)
|
|
347
273
|
|
|
348
274
|
|
|
349
275
|
class GCSPersistor(Persistor):
|
|
@@ -368,95 +294,42 @@ class GCSPersistor(Persistor):
|
|
|
368
294
|
|
|
369
295
|
def _ensure_bucket_exists(self, bucket_name: Text) -> None:
|
|
370
296
|
from google.cloud import exceptions
|
|
371
|
-
from google.auth import exceptions as auth_exceptions
|
|
372
297
|
|
|
373
298
|
try:
|
|
374
299
|
self.storage_client.get_bucket(bucket_name)
|
|
375
|
-
except
|
|
300
|
+
except exceptions.NotFound:
|
|
376
301
|
log = (
|
|
377
|
-
f"
|
|
378
|
-
|
|
379
|
-
f"to access the bucket '{bucket_name}'."
|
|
380
|
-
)
|
|
381
|
-
structlogger.error(
|
|
382
|
-
"gcp_persistor.ensure_bucket_exists.authentication_error",
|
|
383
|
-
bucket_name=bucket_name,
|
|
384
|
-
event_info=log,
|
|
385
|
-
)
|
|
386
|
-
raise RasaException(log) from exc
|
|
387
|
-
except exceptions.NotFound as exc:
|
|
388
|
-
log = (
|
|
389
|
-
f"The specified Google Cloud Storage bucket '{bucket_name}' "
|
|
390
|
-
f"does not exist. Please make sure to create the bucket first or "
|
|
391
|
-
f"provide an alternative valid bucket name."
|
|
302
|
+
f"The specified bucket '{bucket_name}' does not exist. "
|
|
303
|
+
"Please make sure to create the bucket first."
|
|
392
304
|
)
|
|
393
305
|
structlogger.error(
|
|
394
306
|
"gcp_persistor.ensure_bucket_exists.bucket_not_found",
|
|
395
307
|
bucket_name=bucket_name,
|
|
396
308
|
event_info=log,
|
|
397
309
|
)
|
|
398
|
-
raise RasaException(log)
|
|
399
|
-
except exceptions.Forbidden
|
|
310
|
+
raise RasaException(log)
|
|
311
|
+
except exceptions.Forbidden:
|
|
400
312
|
log = (
|
|
401
|
-
f"Access to the specified
|
|
402
|
-
|
|
403
|
-
|
|
313
|
+
f"Access to the specified bucket '{bucket_name}' is forbidden. "
|
|
314
|
+
"Please make sure you have the necessary "
|
|
315
|
+
"permission to access the bucket. "
|
|
404
316
|
)
|
|
405
317
|
structlogger.error(
|
|
406
318
|
"gcp_persistor.ensure_bucket_exists.bucket_access_forbidden",
|
|
407
319
|
bucket_name=bucket_name,
|
|
408
320
|
event_info=log,
|
|
409
321
|
)
|
|
410
|
-
raise RasaException(log)
|
|
411
|
-
except ValueError as exc:
|
|
412
|
-
# bucket_name is None
|
|
413
|
-
log = (
|
|
414
|
-
"The specified Google Cloud Storage bucket name is None. Please "
|
|
415
|
-
"make sure to provide a valid bucket name."
|
|
416
|
-
)
|
|
417
|
-
structlogger.error(
|
|
418
|
-
"gcp_persistor.ensure_bucket_exists.bucket_name_none",
|
|
419
|
-
event_info=log,
|
|
420
|
-
)
|
|
421
|
-
raise RasaException(log) from exc
|
|
322
|
+
raise RasaException(log)
|
|
422
323
|
|
|
423
324
|
def _persist_tar(self, file_key: Text, tar_path: Text) -> None:
|
|
424
325
|
"""Uploads a model persisted in the `target_dir` to GCS."""
|
|
425
326
|
blob = self.bucket.blob(file_key)
|
|
426
327
|
blob.upload_from_filename(tar_path)
|
|
427
328
|
|
|
428
|
-
def _retrieve_tar_size(self, target_filename: Text) -> int:
|
|
429
|
-
"""Returns the size of the model that has been persisted to GCS."""
|
|
430
|
-
try:
|
|
431
|
-
blob = self.bucket.blob(target_filename)
|
|
432
|
-
return blob.size
|
|
433
|
-
except Exception:
|
|
434
|
-
raise ModelNotFound()
|
|
435
|
-
|
|
436
329
|
def _retrieve_tar(self, target_filename: Text) -> None:
|
|
437
330
|
"""Downloads a model that has previously been persisted to GCS."""
|
|
438
|
-
from google.api_core import exceptions
|
|
439
|
-
|
|
440
331
|
blob = self.bucket.blob(target_filename)
|
|
441
|
-
|
|
442
|
-
blob.download_to_filename(target_filename)
|
|
443
|
-
|
|
444
|
-
structlogger.debug(
|
|
445
|
-
"gcs_persistor.retrieve_tar.object_found", object_key=target_filename
|
|
446
|
-
)
|
|
447
|
-
except exceptions.NotFound as exc:
|
|
448
|
-
log = (
|
|
449
|
-
f"Model '{target_filename}' not found in the specified bucket "
|
|
450
|
-
f"'{self.bucket_name}'. Please make sure the model exists "
|
|
451
|
-
f"in the bucket."
|
|
452
|
-
)
|
|
453
|
-
structlogger.error(
|
|
454
|
-
"gcp_persistor.retrieve_tar.model_not_found",
|
|
455
|
-
bucket_name=self.bucket_name,
|
|
456
|
-
target_filename=target_filename,
|
|
457
|
-
event_info=log,
|
|
458
|
-
)
|
|
459
|
-
raise ModelNotFound() from exc
|
|
332
|
+
blob.download_to_filename(target_filename)
|
|
460
333
|
|
|
461
334
|
|
|
462
335
|
class AzurePersistor(Persistor):
|
|
@@ -482,8 +355,7 @@ class AzurePersistor(Persistor):
|
|
|
482
355
|
else:
|
|
483
356
|
log = (
|
|
484
357
|
f"The specified container '{self.container_name}' does not exist."
|
|
485
|
-
"Please make sure to create the
|
|
486
|
-
f"provide an alternative valid bucket name."
|
|
358
|
+
"Please make sure to create the container first."
|
|
487
359
|
)
|
|
488
360
|
structlogger.error(
|
|
489
361
|
"azure_persistor.ensure_container_exists.container_not_found",
|
|
@@ -500,39 +372,10 @@ class AzurePersistor(Persistor):
|
|
|
500
372
|
with open(tar_path, "rb") as data:
|
|
501
373
|
self._container_client().upload_blob(name=file_key, data=data)
|
|
502
374
|
|
|
503
|
-
def _retrieve_tar_size(self, target_filename: Text) -> int:
|
|
504
|
-
"""Returns the size of the model that has been persisted to Azure."""
|
|
505
|
-
try:
|
|
506
|
-
blob_client = self._container_client().get_blob_client(target_filename)
|
|
507
|
-
properties = blob_client.get_blob_properties()
|
|
508
|
-
return properties.size
|
|
509
|
-
except Exception:
|
|
510
|
-
raise ModelNotFound()
|
|
511
|
-
|
|
512
375
|
def _retrieve_tar(self, target_filename: Text) -> None:
|
|
513
376
|
"""Downloads a model that has previously been persisted to Azure."""
|
|
514
|
-
|
|
377
|
+
blob_client = self._container_client().get_blob_client(target_filename)
|
|
515
378
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
download_stream = blob_client.download_blob()
|
|
520
|
-
model_file.write(download_stream.readall())
|
|
521
|
-
structlogger.debug(
|
|
522
|
-
"azure_persistor.retrieve_tar.blob_found", blob_name=target_filename
|
|
523
|
-
)
|
|
524
|
-
except AzureError as exc:
|
|
525
|
-
log = (
|
|
526
|
-
f"An exception occurred while trying to download "
|
|
527
|
-
f"the model '{target_filename}' in the specified container "
|
|
528
|
-
f"'{self.container_name}'. Please make sure the model exists "
|
|
529
|
-
f"in the container."
|
|
530
|
-
)
|
|
531
|
-
structlogger.error(
|
|
532
|
-
"azure_persistor.retrieve_tar.model_download_error",
|
|
533
|
-
container_name=self.container_name,
|
|
534
|
-
target_filename=target_filename,
|
|
535
|
-
event_info=log,
|
|
536
|
-
exception=exc,
|
|
537
|
-
)
|
|
538
|
-
raise ModelNotFound() from exc
|
|
379
|
+
with open(target_filename, "wb") as blob:
|
|
380
|
+
download_stream = blob_client.download_blob()
|
|
381
|
+
blob.write(download_stream.readall())
|