rasa-pro 3.8.16__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 +380 -0
- rasa/__init__.py +10 -0
- rasa/__main__.py +151 -0
- rasa/anonymization/__init__.py +2 -0
- rasa/anonymization/anonymisation_rule_yaml_reader.py +91 -0
- rasa/anonymization/anonymization_pipeline.py +287 -0
- rasa/anonymization/anonymization_rule_executor.py +260 -0
- rasa/anonymization/anonymization_rule_orchestrator.py +120 -0
- rasa/anonymization/schemas/config.yml +47 -0
- rasa/anonymization/utils.py +117 -0
- rasa/api.py +146 -0
- rasa/cli/__init__.py +5 -0
- rasa/cli/arguments/__init__.py +0 -0
- rasa/cli/arguments/data.py +81 -0
- rasa/cli/arguments/default_arguments.py +165 -0
- rasa/cli/arguments/evaluate.py +65 -0
- rasa/cli/arguments/export.py +51 -0
- rasa/cli/arguments/interactive.py +74 -0
- rasa/cli/arguments/run.py +204 -0
- rasa/cli/arguments/shell.py +13 -0
- rasa/cli/arguments/test.py +211 -0
- rasa/cli/arguments/train.py +263 -0
- rasa/cli/arguments/visualize.py +34 -0
- rasa/cli/arguments/x.py +30 -0
- rasa/cli/data.py +292 -0
- rasa/cli/e2e_test.py +566 -0
- rasa/cli/evaluate.py +222 -0
- rasa/cli/export.py +251 -0
- rasa/cli/inspect.py +63 -0
- rasa/cli/interactive.py +164 -0
- rasa/cli/license.py +65 -0
- rasa/cli/markers.py +78 -0
- rasa/cli/project_templates/__init__.py +0 -0
- rasa/cli/project_templates/calm/actions/__init__.py +0 -0
- rasa/cli/project_templates/calm/actions/action_template.py +27 -0
- rasa/cli/project_templates/calm/actions/add_contact.py +30 -0
- rasa/cli/project_templates/calm/actions/db.py +57 -0
- rasa/cli/project_templates/calm/actions/list_contacts.py +22 -0
- rasa/cli/project_templates/calm/actions/remove_contact.py +35 -0
- rasa/cli/project_templates/calm/config.yml +12 -0
- rasa/cli/project_templates/calm/credentials.yml +33 -0
- rasa/cli/project_templates/calm/data/flows/add_contact.yml +31 -0
- rasa/cli/project_templates/calm/data/flows/list_contacts.yml +14 -0
- rasa/cli/project_templates/calm/data/flows/remove_contact.yml +29 -0
- rasa/cli/project_templates/calm/db/contacts.json +10 -0
- rasa/cli/project_templates/calm/domain/add_contact.yml +33 -0
- rasa/cli/project_templates/calm/domain/list_contacts.yml +14 -0
- rasa/cli/project_templates/calm/domain/remove_contact.yml +31 -0
- rasa/cli/project_templates/calm/domain/shared.yml +5 -0
- rasa/cli/project_templates/calm/e2e_tests/cancelations/user_cancels_during_a_correction.yml +16 -0
- rasa/cli/project_templates/calm/e2e_tests/cancelations/user_changes_mind_on_a_whim.yml +7 -0
- rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_handle.yml +20 -0
- rasa/cli/project_templates/calm/e2e_tests/corrections/user_corrects_contact_name.yml +19 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_adds_contact_to_their_list.yml +15 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_lists_contacts.yml +5 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact.yml +11 -0
- rasa/cli/project_templates/calm/e2e_tests/happy_paths/user_removes_contact_from_list.yml +12 -0
- rasa/cli/project_templates/calm/endpoints.yml +45 -0
- rasa/cli/project_templates/default/actions/__init__.py +0 -0
- rasa/cli/project_templates/default/actions/actions.py +27 -0
- rasa/cli/project_templates/default/config.yml +44 -0
- rasa/cli/project_templates/default/credentials.yml +33 -0
- rasa/cli/project_templates/default/data/nlu.yml +91 -0
- rasa/cli/project_templates/default/data/rules.yml +13 -0
- rasa/cli/project_templates/default/data/stories.yml +30 -0
- rasa/cli/project_templates/default/domain.yml +34 -0
- rasa/cli/project_templates/default/endpoints.yml +42 -0
- rasa/cli/project_templates/default/tests/test_stories.yml +91 -0
- rasa/cli/project_templates/tutorial/actions.py +22 -0
- rasa/cli/project_templates/tutorial/config.yml +11 -0
- rasa/cli/project_templates/tutorial/credentials.yml +33 -0
- rasa/cli/project_templates/tutorial/data/flows.yml +8 -0
- rasa/cli/project_templates/tutorial/domain.yml +17 -0
- rasa/cli/project_templates/tutorial/endpoints.yml +45 -0
- rasa/cli/run.py +136 -0
- rasa/cli/scaffold.py +268 -0
- rasa/cli/shell.py +141 -0
- rasa/cli/studio/__init__.py +0 -0
- rasa/cli/studio/download.py +51 -0
- rasa/cli/studio/studio.py +110 -0
- rasa/cli/studio/train.py +59 -0
- rasa/cli/studio/upload.py +85 -0
- rasa/cli/telemetry.py +90 -0
- rasa/cli/test.py +280 -0
- rasa/cli/train.py +260 -0
- rasa/cli/utils.py +453 -0
- rasa/cli/visualize.py +40 -0
- rasa/cli/x.py +205 -0
- rasa/constants.py +37 -0
- rasa/core/__init__.py +17 -0
- rasa/core/actions/__init__.py +0 -0
- rasa/core/actions/action.py +1450 -0
- rasa/core/actions/action_clean_stack.py +59 -0
- rasa/core/actions/action_run_slot_rejections.py +207 -0
- rasa/core/actions/action_trigger_chitchat.py +31 -0
- rasa/core/actions/action_trigger_flow.py +109 -0
- rasa/core/actions/action_trigger_search.py +31 -0
- rasa/core/actions/constants.py +2 -0
- rasa/core/actions/forms.py +737 -0
- rasa/core/actions/loops.py +111 -0
- rasa/core/actions/two_stage_fallback.py +186 -0
- rasa/core/agent.py +557 -0
- rasa/core/auth_retry_tracker_store.py +122 -0
- rasa/core/brokers/__init__.py +0 -0
- rasa/core/brokers/broker.py +126 -0
- rasa/core/brokers/file.py +58 -0
- rasa/core/brokers/kafka.py +322 -0
- rasa/core/brokers/pika.py +387 -0
- rasa/core/brokers/sql.py +86 -0
- rasa/core/channels/__init__.py +55 -0
- rasa/core/channels/audiocodes.py +463 -0
- rasa/core/channels/botframework.py +339 -0
- rasa/core/channels/callback.py +85 -0
- rasa/core/channels/channel.py +419 -0
- rasa/core/channels/console.py +243 -0
- rasa/core/channels/development_inspector.py +93 -0
- rasa/core/channels/facebook.py +422 -0
- rasa/core/channels/hangouts.py +335 -0
- rasa/core/channels/inspector/.eslintrc.cjs +25 -0
- rasa/core/channels/inspector/.gitignore +23 -0
- rasa/core/channels/inspector/README.md +54 -0
- rasa/core/channels/inspector/assets/favicon.ico +0 -0
- rasa/core/channels/inspector/assets/rasa-chat.js +2 -0
- rasa/core/channels/inspector/custom.d.ts +3 -0
- rasa/core/channels/inspector/dist/assets/arc-5623b6dc.js +1 -0
- rasa/core/channels/inspector/dist/assets/array-9f3ba611.js +1 -0
- rasa/core/channels/inspector/dist/assets/c4Diagram-d0fbc5ce-685c106a.js +10 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-936ed81e-8cbed007.js +2 -0
- rasa/core/channels/inspector/dist/assets/classDiagram-v2-c3cb15f1-5889cf12.js +2 -0
- rasa/core/channels/inspector/dist/assets/createText-62fc7601-24c249d7.js +7 -0
- rasa/core/channels/inspector/dist/assets/edges-f2ad444c-7dd06a75.js +4 -0
- rasa/core/channels/inspector/dist/assets/erDiagram-9d236eb7-62c1e54c.js +51 -0
- rasa/core/channels/inspector/dist/assets/flowDb-1972c806-ce49b86f.js +6 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-7ea5b25a-4067e48f.js +4 -0
- rasa/core/channels/inspector/dist/assets/flowDiagram-v2-855bc5b3-85583a23.js +1 -0
- rasa/core/channels/inspector/dist/assets/flowchart-elk-definition-abe16c3d-59fe4051.js +139 -0
- rasa/core/channels/inspector/dist/assets/ganttDiagram-9b5ea136-47e3a43b.js +266 -0
- rasa/core/channels/inspector/dist/assets/gitGraphDiagram-99d0ae7c-5a2ac0d9.js +70 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-128cfa44.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-21dbcb97.woff +0 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-222b5e26.svg +329 -0
- rasa/core/channels/inspector/dist/assets/ibm-plex-mono-v4-latin-regular-9ad89b2a.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/index-268a75c0.js +1040 -0
- rasa/core/channels/inspector/dist/assets/index-2c4b9a3b-dfb8efc4.js +1 -0
- rasa/core/channels/inspector/dist/assets/index-3ee28881.css +1 -0
- rasa/core/channels/inspector/dist/assets/infoDiagram-736b4530-b0c470f2.js +7 -0
- rasa/core/channels/inspector/dist/assets/init-77b53fdd.js +1 -0
- rasa/core/channels/inspector/dist/assets/journeyDiagram-df861f2b-2edb829a.js +139 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-60c05ee4.woff +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-8335d9b8.svg +438 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-9cc39c75.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-700-ead13ccf.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-16705655.woff2 +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-5aeb07f9.woff +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9c459044.ttf +0 -0
- rasa/core/channels/inspector/dist/assets/lato-v14-latin-regular-9e2898a4.svg +435 -0
- rasa/core/channels/inspector/dist/assets/layout-b6873d69.js +1 -0
- rasa/core/channels/inspector/dist/assets/line-1efc5781.js +1 -0
- rasa/core/channels/inspector/dist/assets/linear-661e9b94.js +1 -0
- rasa/core/channels/inspector/dist/assets/mindmap-definition-beec6740-2d2e727f.js +109 -0
- rasa/core/channels/inspector/dist/assets/ordinal-ba9b4969.js +1 -0
- rasa/core/channels/inspector/dist/assets/path-53f90ab3.js +1 -0
- rasa/core/channels/inspector/dist/assets/pieDiagram-dbbf0591-9d3ea93d.js +35 -0
- rasa/core/channels/inspector/dist/assets/quadrantDiagram-4d7f4fd6-06a178a2.js +7 -0
- rasa/core/channels/inspector/dist/assets/requirementDiagram-6fc4c22a-0bfedffc.js +52 -0
- rasa/core/channels/inspector/dist/assets/sankeyDiagram-8f13d901-d76d0a04.js +8 -0
- rasa/core/channels/inspector/dist/assets/sequenceDiagram-b655622a-37bb4341.js +122 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-59f0c015-f52f7f57.js +1 -0
- rasa/core/channels/inspector/dist/assets/stateDiagram-v2-2b26beab-4a986a20.js +1 -0
- rasa/core/channels/inspector/dist/assets/styles-080da4f6-7dd9ae12.js +110 -0
- rasa/core/channels/inspector/dist/assets/styles-3dcbcfbf-46e1ca14.js +159 -0
- rasa/core/channels/inspector/dist/assets/styles-9c745c82-4a97439a.js +207 -0
- rasa/core/channels/inspector/dist/assets/svgDrawCommon-4835440b-823917a3.js +1 -0
- rasa/core/channels/inspector/dist/assets/timeline-definition-5b62e21b-9ea72896.js +61 -0
- rasa/core/channels/inspector/dist/assets/xychartDiagram-2b33534f-b631a8b6.js +7 -0
- rasa/core/channels/inspector/dist/index.html +39 -0
- rasa/core/channels/inspector/index.html +37 -0
- rasa/core/channels/inspector/jest.config.ts +13 -0
- rasa/core/channels/inspector/package.json +48 -0
- rasa/core/channels/inspector/setupTests.ts +2 -0
- rasa/core/channels/inspector/src/App.tsx +170 -0
- rasa/core/channels/inspector/src/components/DiagramFlow.tsx +97 -0
- rasa/core/channels/inspector/src/components/DialogueInformation.tsx +187 -0
- rasa/core/channels/inspector/src/components/DialogueStack.tsx +151 -0
- rasa/core/channels/inspector/src/components/ExpandIcon.tsx +16 -0
- rasa/core/channels/inspector/src/components/FullscreenButton.tsx +45 -0
- rasa/core/channels/inspector/src/components/LoadingSpinner.tsx +19 -0
- rasa/core/channels/inspector/src/components/NoActiveFlow.tsx +21 -0
- rasa/core/channels/inspector/src/components/RasaLogo.tsx +32 -0
- rasa/core/channels/inspector/src/components/SaraDiagrams.tsx +39 -0
- rasa/core/channels/inspector/src/components/Slots.tsx +91 -0
- rasa/core/channels/inspector/src/components/Welcome.tsx +54 -0
- rasa/core/channels/inspector/src/helpers/formatters.test.ts +385 -0
- rasa/core/channels/inspector/src/helpers/formatters.ts +239 -0
- rasa/core/channels/inspector/src/helpers/utils.ts +42 -0
- rasa/core/channels/inspector/src/main.tsx +13 -0
- rasa/core/channels/inspector/src/theme/Button/Button.ts +29 -0
- rasa/core/channels/inspector/src/theme/Heading/Heading.ts +31 -0
- rasa/core/channels/inspector/src/theme/Input/Input.ts +27 -0
- rasa/core/channels/inspector/src/theme/Link/Link.ts +10 -0
- rasa/core/channels/inspector/src/theme/Modal/Modal.ts +47 -0
- rasa/core/channels/inspector/src/theme/Table/Table.tsx +38 -0
- rasa/core/channels/inspector/src/theme/Tooltip/Tooltip.ts +12 -0
- rasa/core/channels/inspector/src/theme/base/breakpoints.ts +8 -0
- rasa/core/channels/inspector/src/theme/base/colors.ts +88 -0
- rasa/core/channels/inspector/src/theme/base/fonts/fontFaces.css +29 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.svg +329 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/ibm-plex-mono-v4-latin/ibm-plex-mono-v4-latin-regular.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.svg +438 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-700.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.eot +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.svg +435 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.ttf +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff +0 -0
- rasa/core/channels/inspector/src/theme/base/fonts/lato-v14-latin/lato-v14-latin-regular.woff2 +0 -0
- rasa/core/channels/inspector/src/theme/base/radii.ts +9 -0
- rasa/core/channels/inspector/src/theme/base/shadows.ts +7 -0
- rasa/core/channels/inspector/src/theme/base/sizes.ts +7 -0
- rasa/core/channels/inspector/src/theme/base/space.ts +15 -0
- rasa/core/channels/inspector/src/theme/base/styles.ts +13 -0
- rasa/core/channels/inspector/src/theme/base/typography.ts +24 -0
- rasa/core/channels/inspector/src/theme/base/zIndices.ts +19 -0
- rasa/core/channels/inspector/src/theme/index.ts +101 -0
- rasa/core/channels/inspector/src/types.ts +64 -0
- rasa/core/channels/inspector/src/vite-env.d.ts +1 -0
- rasa/core/channels/inspector/tests/__mocks__/fileMock.ts +1 -0
- rasa/core/channels/inspector/tests/__mocks__/matchMedia.ts +16 -0
- rasa/core/channels/inspector/tests/__mocks__/styleMock.ts +1 -0
- rasa/core/channels/inspector/tests/renderWithProviders.tsx +14 -0
- rasa/core/channels/inspector/tsconfig.json +26 -0
- rasa/core/channels/inspector/tsconfig.node.json +10 -0
- rasa/core/channels/inspector/vite.config.ts +8 -0
- rasa/core/channels/inspector/yarn.lock +6156 -0
- rasa/core/channels/mattermost.py +229 -0
- rasa/core/channels/rasa_chat.py +126 -0
- rasa/core/channels/rest.py +210 -0
- rasa/core/channels/rocketchat.py +175 -0
- rasa/core/channels/slack.py +620 -0
- rasa/core/channels/socketio.py +274 -0
- rasa/core/channels/telegram.py +298 -0
- rasa/core/channels/twilio.py +169 -0
- rasa/core/channels/twilio_voice.py +367 -0
- rasa/core/channels/vier_cvg.py +374 -0
- rasa/core/channels/webexteams.py +135 -0
- rasa/core/concurrent_lock_store.py +210 -0
- rasa/core/constants.py +107 -0
- rasa/core/evaluation/__init__.py +0 -0
- rasa/core/evaluation/marker.py +267 -0
- rasa/core/evaluation/marker_base.py +925 -0
- rasa/core/evaluation/marker_stats.py +294 -0
- rasa/core/evaluation/marker_tracker_loader.py +103 -0
- rasa/core/exceptions.py +29 -0
- rasa/core/exporter.py +284 -0
- rasa/core/featurizers/__init__.py +0 -0
- rasa/core/featurizers/precomputation.py +410 -0
- rasa/core/featurizers/single_state_featurizer.py +402 -0
- rasa/core/featurizers/tracker_featurizers.py +1172 -0
- rasa/core/http_interpreter.py +89 -0
- rasa/core/information_retrieval/__init__.py +0 -0
- rasa/core/information_retrieval/faiss.py +116 -0
- rasa/core/information_retrieval/information_retrieval.py +72 -0
- rasa/core/information_retrieval/milvus.py +59 -0
- rasa/core/information_retrieval/qdrant.py +102 -0
- rasa/core/jobs.py +63 -0
- rasa/core/lock.py +139 -0
- rasa/core/lock_store.py +344 -0
- rasa/core/migrate.py +404 -0
- rasa/core/nlg/__init__.py +3 -0
- rasa/core/nlg/callback.py +147 -0
- rasa/core/nlg/contextual_response_rephraser.py +270 -0
- rasa/core/nlg/generator.py +230 -0
- rasa/core/nlg/interpolator.py +143 -0
- rasa/core/nlg/response.py +155 -0
- rasa/core/nlg/summarize.py +69 -0
- rasa/core/policies/__init__.py +0 -0
- rasa/core/policies/ensemble.py +329 -0
- rasa/core/policies/enterprise_search_policy.py +717 -0
- rasa/core/policies/enterprise_search_prompt_template.jinja2 +62 -0
- rasa/core/policies/flow_policy.py +205 -0
- rasa/core/policies/flows/__init__.py +0 -0
- rasa/core/policies/flows/flow_exceptions.py +44 -0
- rasa/core/policies/flows/flow_executor.py +582 -0
- rasa/core/policies/flows/flow_step_result.py +43 -0
- rasa/core/policies/intentless_policy.py +924 -0
- rasa/core/policies/intentless_prompt_template.jinja2 +22 -0
- rasa/core/policies/memoization.py +538 -0
- rasa/core/policies/policy.py +716 -0
- rasa/core/policies/rule_policy.py +1276 -0
- rasa/core/policies/ted_policy.py +2146 -0
- rasa/core/policies/unexpected_intent_policy.py +1015 -0
- rasa/core/processor.py +1331 -0
- rasa/core/run.py +315 -0
- rasa/core/secrets_manager/__init__.py +0 -0
- rasa/core/secrets_manager/constants.py +32 -0
- rasa/core/secrets_manager/endpoints.py +391 -0
- rasa/core/secrets_manager/factory.py +233 -0
- rasa/core/secrets_manager/secret_manager.py +262 -0
- rasa/core/secrets_manager/vault.py +576 -0
- rasa/core/test.py +1337 -0
- rasa/core/tracker_store.py +1664 -0
- rasa/core/train.py +107 -0
- rasa/core/training/__init__.py +89 -0
- rasa/core/training/converters/__init__.py +0 -0
- rasa/core/training/converters/responses_prefix_converter.py +119 -0
- rasa/core/training/interactive.py +1742 -0
- rasa/core/training/story_conflict.py +381 -0
- rasa/core/training/training.py +93 -0
- rasa/core/utils.py +344 -0
- rasa/core/visualize.py +70 -0
- rasa/dialogue_understanding/__init__.py +0 -0
- rasa/dialogue_understanding/coexistence/__init__.py +0 -0
- rasa/dialogue_understanding/coexistence/constants.py +4 -0
- rasa/dialogue_understanding/coexistence/intent_based_router.py +189 -0
- rasa/dialogue_understanding/coexistence/llm_based_router.py +261 -0
- rasa/dialogue_understanding/coexistence/router_template.jinja2 +12 -0
- rasa/dialogue_understanding/commands/__init__.py +45 -0
- rasa/dialogue_understanding/commands/can_not_handle_command.py +61 -0
- rasa/dialogue_understanding/commands/cancel_flow_command.py +116 -0
- rasa/dialogue_understanding/commands/chit_chat_answer_command.py +48 -0
- rasa/dialogue_understanding/commands/clarify_command.py +77 -0
- rasa/dialogue_understanding/commands/command.py +85 -0
- rasa/dialogue_understanding/commands/correct_slots_command.py +288 -0
- rasa/dialogue_understanding/commands/error_command.py +67 -0
- rasa/dialogue_understanding/commands/free_form_answer_command.py +9 -0
- rasa/dialogue_understanding/commands/handle_code_change_command.py +64 -0
- rasa/dialogue_understanding/commands/human_handoff_command.py +57 -0
- rasa/dialogue_understanding/commands/knowledge_answer_command.py +48 -0
- rasa/dialogue_understanding/commands/noop_command.py +45 -0
- rasa/dialogue_understanding/commands/set_slot_command.py +125 -0
- rasa/dialogue_understanding/commands/skip_question_command.py +66 -0
- rasa/dialogue_understanding/commands/start_flow_command.py +98 -0
- rasa/dialogue_understanding/generator/__init__.py +6 -0
- rasa/dialogue_understanding/generator/command_generator.py +257 -0
- rasa/dialogue_understanding/generator/command_prompt_template.jinja2 +57 -0
- rasa/dialogue_understanding/generator/flow_document_template.jinja2 +4 -0
- rasa/dialogue_understanding/generator/flow_retrieval.py +410 -0
- rasa/dialogue_understanding/generator/llm_command_generator.py +637 -0
- rasa/dialogue_understanding/generator/nlu_command_adapter.py +157 -0
- rasa/dialogue_understanding/patterns/__init__.py +0 -0
- rasa/dialogue_understanding/patterns/cancel.py +111 -0
- rasa/dialogue_understanding/patterns/cannot_handle.py +43 -0
- rasa/dialogue_understanding/patterns/chitchat.py +37 -0
- rasa/dialogue_understanding/patterns/clarify.py +97 -0
- rasa/dialogue_understanding/patterns/code_change.py +41 -0
- rasa/dialogue_understanding/patterns/collect_information.py +90 -0
- rasa/dialogue_understanding/patterns/completed.py +40 -0
- rasa/dialogue_understanding/patterns/continue_interrupted.py +42 -0
- rasa/dialogue_understanding/patterns/correction.py +278 -0
- rasa/dialogue_understanding/patterns/default_flows_for_patterns.yml +243 -0
- rasa/dialogue_understanding/patterns/human_handoff.py +37 -0
- rasa/dialogue_understanding/patterns/internal_error.py +47 -0
- rasa/dialogue_understanding/patterns/search.py +37 -0
- rasa/dialogue_understanding/patterns/skip_question.py +38 -0
- rasa/dialogue_understanding/processor/__init__.py +0 -0
- rasa/dialogue_understanding/processor/command_processor.py +578 -0
- rasa/dialogue_understanding/processor/command_processor_component.py +39 -0
- rasa/dialogue_understanding/stack/__init__.py +0 -0
- rasa/dialogue_understanding/stack/dialogue_stack.py +178 -0
- rasa/dialogue_understanding/stack/frames/__init__.py +19 -0
- rasa/dialogue_understanding/stack/frames/chit_chat_frame.py +27 -0
- rasa/dialogue_understanding/stack/frames/dialogue_stack_frame.py +137 -0
- rasa/dialogue_understanding/stack/frames/flow_stack_frame.py +157 -0
- rasa/dialogue_understanding/stack/frames/pattern_frame.py +10 -0
- rasa/dialogue_understanding/stack/frames/search_frame.py +27 -0
- rasa/dialogue_understanding/stack/utils.py +211 -0
- rasa/e2e_test/__init__.py +0 -0
- rasa/e2e_test/constants.py +10 -0
- rasa/e2e_test/e2e_test_case.py +322 -0
- rasa/e2e_test/e2e_test_result.py +34 -0
- rasa/e2e_test/e2e_test_runner.py +659 -0
- rasa/e2e_test/e2e_test_schema.yml +67 -0
- rasa/engine/__init__.py +0 -0
- rasa/engine/caching.py +464 -0
- rasa/engine/constants.py +17 -0
- rasa/engine/exceptions.py +14 -0
- rasa/engine/graph.py +625 -0
- rasa/engine/loader.py +36 -0
- rasa/engine/recipes/__init__.py +0 -0
- rasa/engine/recipes/config_files/default_config.yml +44 -0
- rasa/engine/recipes/default_components.py +99 -0
- rasa/engine/recipes/default_recipe.py +1252 -0
- rasa/engine/recipes/graph_recipe.py +79 -0
- rasa/engine/recipes/recipe.py +93 -0
- rasa/engine/runner/__init__.py +0 -0
- rasa/engine/runner/dask.py +256 -0
- rasa/engine/runner/interface.py +49 -0
- rasa/engine/storage/__init__.py +0 -0
- rasa/engine/storage/local_model_storage.py +248 -0
- rasa/engine/storage/resource.py +110 -0
- rasa/engine/storage/storage.py +203 -0
- rasa/engine/training/__init__.py +0 -0
- rasa/engine/training/components.py +176 -0
- rasa/engine/training/fingerprinting.py +64 -0
- rasa/engine/training/graph_trainer.py +256 -0
- rasa/engine/training/hooks.py +164 -0
- rasa/engine/validation.py +839 -0
- rasa/env.py +5 -0
- rasa/exceptions.py +69 -0
- rasa/graph_components/__init__.py +0 -0
- rasa/graph_components/converters/__init__.py +0 -0
- rasa/graph_components/converters/nlu_message_converter.py +48 -0
- rasa/graph_components/providers/__init__.py +0 -0
- rasa/graph_components/providers/domain_for_core_training_provider.py +87 -0
- rasa/graph_components/providers/domain_provider.py +71 -0
- rasa/graph_components/providers/flows_provider.py +74 -0
- rasa/graph_components/providers/forms_provider.py +44 -0
- rasa/graph_components/providers/nlu_training_data_provider.py +56 -0
- rasa/graph_components/providers/responses_provider.py +44 -0
- rasa/graph_components/providers/rule_only_provider.py +49 -0
- rasa/graph_components/providers/story_graph_provider.py +43 -0
- rasa/graph_components/providers/training_tracker_provider.py +55 -0
- rasa/graph_components/validators/__init__.py +0 -0
- rasa/graph_components/validators/default_recipe_validator.py +552 -0
- rasa/graph_components/validators/finetuning_validator.py +302 -0
- rasa/hooks.py +113 -0
- rasa/jupyter.py +63 -0
- rasa/keys +1 -0
- rasa/markers/__init__.py +0 -0
- rasa/markers/marker.py +269 -0
- rasa/markers/marker_base.py +828 -0
- rasa/markers/upload.py +74 -0
- rasa/markers/validate.py +21 -0
- rasa/model.py +118 -0
- rasa/model_testing.py +457 -0
- rasa/model_training.py +535 -0
- rasa/nlu/__init__.py +7 -0
- rasa/nlu/classifiers/__init__.py +3 -0
- rasa/nlu/classifiers/classifier.py +5 -0
- rasa/nlu/classifiers/diet_classifier.py +1874 -0
- rasa/nlu/classifiers/fallback_classifier.py +192 -0
- rasa/nlu/classifiers/keyword_intent_classifier.py +188 -0
- rasa/nlu/classifiers/llm_intent_classifier.py +519 -0
- rasa/nlu/classifiers/logistic_regression_classifier.py +240 -0
- rasa/nlu/classifiers/mitie_intent_classifier.py +156 -0
- rasa/nlu/classifiers/regex_message_handler.py +56 -0
- rasa/nlu/classifiers/sklearn_intent_classifier.py +309 -0
- rasa/nlu/constants.py +77 -0
- rasa/nlu/convert.py +40 -0
- rasa/nlu/emulators/__init__.py +0 -0
- rasa/nlu/emulators/dialogflow.py +55 -0
- rasa/nlu/emulators/emulator.py +49 -0
- rasa/nlu/emulators/luis.py +86 -0
- rasa/nlu/emulators/no_emulator.py +10 -0
- rasa/nlu/emulators/wit.py +56 -0
- rasa/nlu/extractors/__init__.py +0 -0
- rasa/nlu/extractors/crf_entity_extractor.py +672 -0
- rasa/nlu/extractors/duckling_entity_extractor.py +206 -0
- rasa/nlu/extractors/entity_synonyms.py +178 -0
- rasa/nlu/extractors/extractor.py +470 -0
- rasa/nlu/extractors/mitie_entity_extractor.py +293 -0
- rasa/nlu/extractors/regex_entity_extractor.py +220 -0
- rasa/nlu/extractors/spacy_entity_extractor.py +95 -0
- rasa/nlu/featurizers/__init__.py +0 -0
- rasa/nlu/featurizers/dense_featurizer/__init__.py +0 -0
- rasa/nlu/featurizers/dense_featurizer/convert_featurizer.py +449 -0
- rasa/nlu/featurizers/dense_featurizer/dense_featurizer.py +57 -0
- rasa/nlu/featurizers/dense_featurizer/lm_featurizer.py +772 -0
- rasa/nlu/featurizers/dense_featurizer/mitie_featurizer.py +170 -0
- rasa/nlu/featurizers/dense_featurizer/spacy_featurizer.py +132 -0
- rasa/nlu/featurizers/featurizer.py +89 -0
- rasa/nlu/featurizers/sparse_featurizer/__init__.py +0 -0
- rasa/nlu/featurizers/sparse_featurizer/count_vectors_featurizer.py +840 -0
- rasa/nlu/featurizers/sparse_featurizer/lexical_syntactic_featurizer.py +539 -0
- rasa/nlu/featurizers/sparse_featurizer/regex_featurizer.py +269 -0
- rasa/nlu/featurizers/sparse_featurizer/sparse_featurizer.py +9 -0
- rasa/nlu/model.py +24 -0
- rasa/nlu/persistor.py +240 -0
- rasa/nlu/run.py +27 -0
- rasa/nlu/selectors/__init__.py +0 -0
- rasa/nlu/selectors/response_selector.py +990 -0
- rasa/nlu/test.py +1943 -0
- rasa/nlu/tokenizers/__init__.py +0 -0
- rasa/nlu/tokenizers/jieba_tokenizer.py +148 -0
- rasa/nlu/tokenizers/mitie_tokenizer.py +75 -0
- rasa/nlu/tokenizers/spacy_tokenizer.py +72 -0
- rasa/nlu/tokenizers/tokenizer.py +239 -0
- rasa/nlu/tokenizers/whitespace_tokenizer.py +106 -0
- rasa/nlu/utils/__init__.py +35 -0
- rasa/nlu/utils/bilou_utils.py +462 -0
- rasa/nlu/utils/hugging_face/__init__.py +0 -0
- rasa/nlu/utils/hugging_face/registry.py +108 -0
- rasa/nlu/utils/hugging_face/transformers_pre_post_processors.py +311 -0
- rasa/nlu/utils/mitie_utils.py +113 -0
- rasa/nlu/utils/pattern_utils.py +168 -0
- rasa/nlu/utils/spacy_utils.py +312 -0
- rasa/plugin.py +90 -0
- rasa/server.py +1536 -0
- rasa/shared/__init__.py +0 -0
- rasa/shared/constants.py +181 -0
- rasa/shared/core/__init__.py +0 -0
- rasa/shared/core/constants.py +168 -0
- rasa/shared/core/conversation.py +46 -0
- rasa/shared/core/domain.py +2106 -0
- rasa/shared/core/events.py +2507 -0
- rasa/shared/core/flows/__init__.py +7 -0
- rasa/shared/core/flows/flow.py +353 -0
- rasa/shared/core/flows/flow_step.py +146 -0
- rasa/shared/core/flows/flow_step_links.py +319 -0
- rasa/shared/core/flows/flow_step_sequence.py +70 -0
- rasa/shared/core/flows/flows_list.py +211 -0
- rasa/shared/core/flows/flows_yaml_schema.json +217 -0
- rasa/shared/core/flows/nlu_trigger.py +117 -0
- rasa/shared/core/flows/steps/__init__.py +24 -0
- rasa/shared/core/flows/steps/action.py +51 -0
- rasa/shared/core/flows/steps/call.py +64 -0
- rasa/shared/core/flows/steps/collect.py +112 -0
- rasa/shared/core/flows/steps/constants.py +5 -0
- rasa/shared/core/flows/steps/continuation.py +36 -0
- rasa/shared/core/flows/steps/end.py +22 -0
- rasa/shared/core/flows/steps/internal.py +44 -0
- rasa/shared/core/flows/steps/link.py +51 -0
- rasa/shared/core/flows/steps/no_operation.py +48 -0
- rasa/shared/core/flows/steps/set_slots.py +50 -0
- rasa/shared/core/flows/steps/start.py +30 -0
- rasa/shared/core/flows/validation.py +527 -0
- rasa/shared/core/flows/yaml_flows_io.py +278 -0
- rasa/shared/core/generator.py +907 -0
- rasa/shared/core/slot_mappings.py +235 -0
- rasa/shared/core/slots.py +647 -0
- rasa/shared/core/trackers.py +1159 -0
- rasa/shared/core/training_data/__init__.py +0 -0
- rasa/shared/core/training_data/loading.py +90 -0
- rasa/shared/core/training_data/story_reader/__init__.py +0 -0
- rasa/shared/core/training_data/story_reader/story_reader.py +129 -0
- rasa/shared/core/training_data/story_reader/story_step_builder.py +168 -0
- rasa/shared/core/training_data/story_reader/yaml_story_reader.py +888 -0
- rasa/shared/core/training_data/story_writer/__init__.py +0 -0
- rasa/shared/core/training_data/story_writer/story_writer.py +76 -0
- rasa/shared/core/training_data/story_writer/yaml_story_writer.py +442 -0
- rasa/shared/core/training_data/structures.py +838 -0
- rasa/shared/core/training_data/visualization.html +146 -0
- rasa/shared/core/training_data/visualization.py +603 -0
- rasa/shared/data.py +192 -0
- rasa/shared/engine/__init__.py +0 -0
- rasa/shared/engine/caching.py +26 -0
- rasa/shared/exceptions.py +129 -0
- rasa/shared/importers/__init__.py +0 -0
- rasa/shared/importers/importer.py +705 -0
- rasa/shared/importers/multi_project.py +203 -0
- rasa/shared/importers/rasa.py +100 -0
- rasa/shared/importers/utils.py +34 -0
- rasa/shared/nlu/__init__.py +0 -0
- rasa/shared/nlu/constants.py +45 -0
- rasa/shared/nlu/interpreter.py +10 -0
- rasa/shared/nlu/training_data/__init__.py +0 -0
- rasa/shared/nlu/training_data/entities_parser.py +209 -0
- rasa/shared/nlu/training_data/features.py +374 -0
- rasa/shared/nlu/training_data/formats/__init__.py +10 -0
- rasa/shared/nlu/training_data/formats/dialogflow.py +162 -0
- rasa/shared/nlu/training_data/formats/luis.py +87 -0
- rasa/shared/nlu/training_data/formats/rasa.py +135 -0
- rasa/shared/nlu/training_data/formats/rasa_yaml.py +605 -0
- rasa/shared/nlu/training_data/formats/readerwriter.py +245 -0
- rasa/shared/nlu/training_data/formats/wit.py +52 -0
- rasa/shared/nlu/training_data/loading.py +137 -0
- rasa/shared/nlu/training_data/lookup_tables_parser.py +30 -0
- rasa/shared/nlu/training_data/message.py +477 -0
- rasa/shared/nlu/training_data/schemas/__init__.py +0 -0
- rasa/shared/nlu/training_data/schemas/data_schema.py +85 -0
- rasa/shared/nlu/training_data/schemas/nlu.yml +53 -0
- rasa/shared/nlu/training_data/schemas/responses.yml +70 -0
- rasa/shared/nlu/training_data/synonyms_parser.py +42 -0
- rasa/shared/nlu/training_data/training_data.py +732 -0
- rasa/shared/nlu/training_data/util.py +223 -0
- rasa/shared/providers/__init__.py +0 -0
- rasa/shared/providers/openai/__init__.py +0 -0
- rasa/shared/providers/openai/clients.py +43 -0
- rasa/shared/providers/openai/session_handler.py +110 -0
- rasa/shared/utils/__init__.py +0 -0
- rasa/shared/utils/cli.py +72 -0
- rasa/shared/utils/common.py +308 -0
- rasa/shared/utils/constants.py +1 -0
- rasa/shared/utils/io.py +403 -0
- rasa/shared/utils/llm.py +405 -0
- rasa/shared/utils/pykwalify_extensions.py +26 -0
- rasa/shared/utils/schemas/__init__.py +0 -0
- rasa/shared/utils/schemas/config.yml +2 -0
- rasa/shared/utils/schemas/domain.yml +142 -0
- rasa/shared/utils/schemas/events.py +212 -0
- rasa/shared/utils/schemas/model_config.yml +46 -0
- rasa/shared/utils/schemas/stories.yml +173 -0
- rasa/shared/utils/yaml.py +777 -0
- rasa/studio/__init__.py +0 -0
- rasa/studio/auth.py +252 -0
- rasa/studio/config.py +127 -0
- rasa/studio/constants.py +16 -0
- rasa/studio/data_handler.py +352 -0
- rasa/studio/download.py +350 -0
- rasa/studio/train.py +136 -0
- rasa/studio/upload.py +408 -0
- rasa/telemetry.py +1583 -0
- rasa/tracing/__init__.py +0 -0
- rasa/tracing/config.py +338 -0
- rasa/tracing/constants.py +38 -0
- rasa/tracing/instrumentation/__init__.py +0 -0
- rasa/tracing/instrumentation/attribute_extractors.py +663 -0
- rasa/tracing/instrumentation/instrumentation.py +939 -0
- rasa/tracing/instrumentation/intentless_policy_instrumentation.py +142 -0
- rasa/tracing/instrumentation/metrics.py +206 -0
- rasa/tracing/metric_instrument_provider.py +125 -0
- rasa/utils/__init__.py +0 -0
- rasa/utils/beta.py +83 -0
- rasa/utils/cli.py +27 -0
- rasa/utils/common.py +635 -0
- rasa/utils/converter.py +53 -0
- rasa/utils/endpoints.py +303 -0
- rasa/utils/io.py +326 -0
- rasa/utils/licensing.py +319 -0
- rasa/utils/log_utils.py +174 -0
- rasa/utils/mapper.py +210 -0
- rasa/utils/ml_utils.py +145 -0
- rasa/utils/plotting.py +362 -0
- rasa/utils/singleton.py +23 -0
- rasa/utils/tensorflow/__init__.py +0 -0
- rasa/utils/tensorflow/callback.py +112 -0
- rasa/utils/tensorflow/constants.py +116 -0
- rasa/utils/tensorflow/crf.py +492 -0
- rasa/utils/tensorflow/data_generator.py +440 -0
- rasa/utils/tensorflow/environment.py +161 -0
- rasa/utils/tensorflow/exceptions.py +5 -0
- rasa/utils/tensorflow/layers.py +1565 -0
- rasa/utils/tensorflow/layers_utils.py +113 -0
- rasa/utils/tensorflow/metrics.py +281 -0
- rasa/utils/tensorflow/model_data.py +991 -0
- rasa/utils/tensorflow/model_data_utils.py +500 -0
- rasa/utils/tensorflow/models.py +936 -0
- rasa/utils/tensorflow/rasa_layers.py +1094 -0
- rasa/utils/tensorflow/transformer.py +640 -0
- rasa/utils/tensorflow/types.py +6 -0
- rasa/utils/train_utils.py +572 -0
- rasa/utils/yaml.py +54 -0
- rasa/validator.py +1035 -0
- rasa/version.py +3 -0
- rasa_pro-3.8.16.dist-info/METADATA +528 -0
- rasa_pro-3.8.16.dist-info/NOTICE +5 -0
- rasa_pro-3.8.16.dist-info/RECORD +644 -0
- rasa_pro-3.8.16.dist-info/WHEEL +4 -0
- rasa_pro-3.8.16.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import functools
|
|
3
|
+
import importlib
|
|
4
|
+
import inspect
|
|
5
|
+
import logging
|
|
6
|
+
import pkgutil
|
|
7
|
+
import sys
|
|
8
|
+
from types import ModuleType
|
|
9
|
+
from typing import Text, Dict, Optional, Any, List, Callable, Collection, Type
|
|
10
|
+
|
|
11
|
+
import rasa.shared.utils.io
|
|
12
|
+
from rasa.shared.constants import DOCS_URL_MIGRATION_GUIDE
|
|
13
|
+
from rasa.shared.exceptions import RasaException
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def class_from_module_path(
|
|
19
|
+
module_path: Text, lookup_path: Optional[Text] = None
|
|
20
|
+
) -> Type:
|
|
21
|
+
"""Given the module name and path of a class, tries to retrieve the class.
|
|
22
|
+
|
|
23
|
+
The loaded class can be used to instantiate new objects.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
module_path: either an absolute path to a Python class,
|
|
27
|
+
or the name of the class in the local / global scope.
|
|
28
|
+
lookup_path: a path where to load the class from, if it cannot
|
|
29
|
+
be found in the local / global scope.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
a Python class
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ImportError, in case the Python class cannot be found.
|
|
36
|
+
RasaException, in case the imported result is something other than a class
|
|
37
|
+
"""
|
|
38
|
+
warn_and_exit_if_module_path_contains_rasa_plus(module_path, lookup_path)
|
|
39
|
+
|
|
40
|
+
klass = None
|
|
41
|
+
if "." in module_path:
|
|
42
|
+
module_name, _, class_name = module_path.rpartition(".")
|
|
43
|
+
m = importlib.import_module(module_name)
|
|
44
|
+
klass = getattr(m, class_name, None)
|
|
45
|
+
elif lookup_path:
|
|
46
|
+
# try to import the class from the lookup path
|
|
47
|
+
m = importlib.import_module(lookup_path)
|
|
48
|
+
klass = getattr(m, module_path, None)
|
|
49
|
+
|
|
50
|
+
if klass is None:
|
|
51
|
+
raise ImportError(f"Cannot retrieve class from path {module_path}.")
|
|
52
|
+
|
|
53
|
+
if not inspect.isclass(klass):
|
|
54
|
+
raise RasaException(
|
|
55
|
+
f"`class_from_module_path()` is expected to return a class, "
|
|
56
|
+
f"but for {module_path} we got a {type(klass)}."
|
|
57
|
+
)
|
|
58
|
+
return klass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def import_package_modules(package_name: str) -> List[ModuleType]:
|
|
62
|
+
"""Import all modules in a package."""
|
|
63
|
+
package = importlib.import_module(package_name)
|
|
64
|
+
return [
|
|
65
|
+
importlib.import_module(f"{package_name}.{module_name}")
|
|
66
|
+
for _, module_name, _ in pkgutil.iter_modules(package.__path__)
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def all_subclasses(cls: Any) -> List[Any]:
|
|
71
|
+
"""Returns all known (imported) subclasses of a class."""
|
|
72
|
+
classes = cls.__subclasses__() + [
|
|
73
|
+
g for s in cls.__subclasses__() for g in all_subclasses(s)
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
return [subclass for subclass in classes if not inspect.isabstract(subclass)]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def module_path_from_instance(inst: Any) -> Text:
|
|
80
|
+
"""Return the module path of an instance's class."""
|
|
81
|
+
return inst.__module__ + "." + inst.__class__.__name__
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def sort_list_of_dicts_by_first_key(dicts: List[Dict]) -> List[Dict]:
|
|
85
|
+
"""Sorts a list of dictionaries by their first key."""
|
|
86
|
+
return sorted(dicts, key=lambda d: next(iter(d.keys())))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def lazy_property(function: Callable) -> Any:
|
|
90
|
+
"""Allows to avoid recomputing a property over and over.
|
|
91
|
+
|
|
92
|
+
The result gets stored in a local var. Computation of the property
|
|
93
|
+
will happen once, on the first call of the property. All
|
|
94
|
+
succeeding calls will use the value stored in the private property.
|
|
95
|
+
"""
|
|
96
|
+
attr_name = "_lazy_" + function.__name__
|
|
97
|
+
|
|
98
|
+
def _lazyprop(self: Any) -> Any:
|
|
99
|
+
if not hasattr(self, attr_name):
|
|
100
|
+
setattr(self, attr_name, function(self))
|
|
101
|
+
return getattr(self, attr_name)
|
|
102
|
+
|
|
103
|
+
return property(_lazyprop)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def cached_method(f: Callable[..., Any]) -> Callable[..., Any]:
|
|
107
|
+
"""Caches method calls based on the call's `args` and `kwargs`.
|
|
108
|
+
|
|
109
|
+
Works for `async` and `sync` methods. Don't apply this to functions.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
f: The decorated method whose return value should be cached.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
The return value which the method gives for the first call with the given
|
|
116
|
+
arguments.
|
|
117
|
+
"""
|
|
118
|
+
assert "self" in arguments_of(f), "This decorator can only be used with methods."
|
|
119
|
+
|
|
120
|
+
class Cache:
|
|
121
|
+
"""Helper class to abstract the caching details."""
|
|
122
|
+
|
|
123
|
+
def __init__(self, caching_object: object, args: Any, kwargs: Any) -> None:
|
|
124
|
+
self.caching_object = caching_object
|
|
125
|
+
self.cache = getattr(caching_object, self._cache_name(), {})
|
|
126
|
+
# noinspection PyUnresolvedReferences
|
|
127
|
+
self.cache_key = functools._make_key(args, kwargs, typed=False)
|
|
128
|
+
|
|
129
|
+
def _cache_name(self) -> Text:
|
|
130
|
+
return f"_cached_{self.caching_object.__class__.__name__}_{f.__name__}"
|
|
131
|
+
|
|
132
|
+
def is_cached(self) -> bool:
|
|
133
|
+
return self.cache_key in self.cache
|
|
134
|
+
|
|
135
|
+
def cache_result(self, result: Any) -> None:
|
|
136
|
+
self.cache[self.cache_key] = result
|
|
137
|
+
setattr(self.caching_object, self._cache_name(), self.cache)
|
|
138
|
+
|
|
139
|
+
def cached_result(self) -> Any:
|
|
140
|
+
return self.cache[self.cache_key]
|
|
141
|
+
|
|
142
|
+
if asyncio.iscoroutinefunction(f):
|
|
143
|
+
|
|
144
|
+
@functools.wraps(f)
|
|
145
|
+
async def decorated(self: object, *args: Any, **kwargs: Any) -> Any:
|
|
146
|
+
cache = Cache(self, args, kwargs)
|
|
147
|
+
if not cache.is_cached():
|
|
148
|
+
# Store the task immediately so that other concurrent calls of the
|
|
149
|
+
# method can re-use the same task and don't schedule a second execution.
|
|
150
|
+
to_cache = asyncio.ensure_future(f(self, *args, **kwargs))
|
|
151
|
+
cache.cache_result(to_cache)
|
|
152
|
+
return await cache.cached_result()
|
|
153
|
+
|
|
154
|
+
return decorated
|
|
155
|
+
else:
|
|
156
|
+
|
|
157
|
+
@functools.wraps(f)
|
|
158
|
+
def decorated(self: object, *args: Any, **kwargs: Any) -> Any:
|
|
159
|
+
cache = Cache(self, args, kwargs)
|
|
160
|
+
if not cache.is_cached():
|
|
161
|
+
to_cache = f(self, *args, **kwargs)
|
|
162
|
+
cache.cache_result(to_cache)
|
|
163
|
+
return cache.cached_result()
|
|
164
|
+
|
|
165
|
+
return decorated
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def transform_collection_to_sentence(collection: Collection[Text]) -> Text:
|
|
169
|
+
"""Transforms e.g. a list like ['A', 'B', 'C'] into a sentence 'A, B and C'."""
|
|
170
|
+
x = list(collection)
|
|
171
|
+
if len(x) >= 2:
|
|
172
|
+
return ", ".join(map(str, x[:-1])) + " and " + x[-1]
|
|
173
|
+
return "".join(collection)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def minimal_kwargs(
|
|
177
|
+
kwargs: Dict[Text, Any], func: Callable, excluded_keys: Optional[List] = None
|
|
178
|
+
) -> Dict[Text, Any]:
|
|
179
|
+
"""Returns only the kwargs which are required by a function. Keys, contained in
|
|
180
|
+
the exception list, are not included.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
kwargs: All available kwargs.
|
|
184
|
+
func: The function which should be called.
|
|
185
|
+
excluded_keys: Keys to exclude from the result.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Subset of kwargs which are accepted by `func`.
|
|
189
|
+
|
|
190
|
+
"""
|
|
191
|
+
excluded_keys = excluded_keys or []
|
|
192
|
+
|
|
193
|
+
possible_arguments = arguments_of(func)
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
k: v
|
|
197
|
+
for k, v in kwargs.items()
|
|
198
|
+
if k in possible_arguments and k not in excluded_keys
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def mark_as_experimental_feature(feature_name: Text) -> None:
|
|
203
|
+
"""Warns users that they are using an experimental feature."""
|
|
204
|
+
logger.warning(
|
|
205
|
+
f"The {feature_name} is currently experimental and might change or be "
|
|
206
|
+
"removed in the future 🔬 Please share your feedback on it in the "
|
|
207
|
+
"forum (https://forum.rasa.com) to help us make this feature "
|
|
208
|
+
"ready for production."
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def arguments_of(func: Callable) -> List[Text]:
|
|
213
|
+
"""Return the parameters of the function `func` as a list of names."""
|
|
214
|
+
import inspect
|
|
215
|
+
|
|
216
|
+
return list(inspect.signature(func).parameters.keys())
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def extract_duplicates(list1: List[Any], list2: List[Any]) -> List[Any]:
|
|
220
|
+
"""Extracts duplicates from two lists."""
|
|
221
|
+
if list1:
|
|
222
|
+
dict1 = {
|
|
223
|
+
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in list1
|
|
224
|
+
}
|
|
225
|
+
else:
|
|
226
|
+
dict1 = {}
|
|
227
|
+
|
|
228
|
+
if list2:
|
|
229
|
+
dict2 = {
|
|
230
|
+
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in list2
|
|
231
|
+
}
|
|
232
|
+
else:
|
|
233
|
+
dict2 = {}
|
|
234
|
+
|
|
235
|
+
set1 = set(dict1.keys())
|
|
236
|
+
set2 = set(dict2.keys())
|
|
237
|
+
dupes = set1.intersection(set2)
|
|
238
|
+
return sorted(list(dupes))
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def clean_duplicates(dupes: Dict[Text, Any]) -> Dict[Text, Any]:
|
|
242
|
+
"""Removes keys for empty values."""
|
|
243
|
+
duplicates = dupes.copy()
|
|
244
|
+
for k in dupes:
|
|
245
|
+
if not dupes[k]:
|
|
246
|
+
duplicates.pop(k)
|
|
247
|
+
|
|
248
|
+
return duplicates
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def merge_dicts(
|
|
252
|
+
tempDict1: Dict[Text, Any],
|
|
253
|
+
tempDict2: Dict[Text, Any],
|
|
254
|
+
override_existing_values: bool = False,
|
|
255
|
+
) -> Dict[Text, Any]:
|
|
256
|
+
"""Merges two dicts."""
|
|
257
|
+
if override_existing_values:
|
|
258
|
+
merged_dicts, b = tempDict1.copy(), tempDict2.copy()
|
|
259
|
+
|
|
260
|
+
else:
|
|
261
|
+
merged_dicts, b = tempDict2.copy(), tempDict1.copy()
|
|
262
|
+
merged_dicts.update(b)
|
|
263
|
+
return merged_dicts
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def merge_lists(
|
|
267
|
+
list1: List[Any], list2: List[Any], override: bool = False
|
|
268
|
+
) -> List[Any]:
|
|
269
|
+
"""Merges two lists."""
|
|
270
|
+
return sorted(list(set(list1 + list2)))
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def merge_lists_of_dicts(
|
|
274
|
+
dict_list1: List[Dict],
|
|
275
|
+
dict_list2: List[Dict],
|
|
276
|
+
override_existing_values: bool = False,
|
|
277
|
+
) -> List[Dict]:
|
|
278
|
+
"""Merges two dict lists."""
|
|
279
|
+
dict1 = {
|
|
280
|
+
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in dict_list1
|
|
281
|
+
}
|
|
282
|
+
dict2 = {
|
|
283
|
+
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in dict_list2
|
|
284
|
+
}
|
|
285
|
+
merged_dicts = merge_dicts(dict1, dict2, override_existing_values)
|
|
286
|
+
return list(merged_dicts.values())
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def warn_and_exit_if_module_path_contains_rasa_plus(
|
|
290
|
+
module_path: Text, lookup_path: Optional[str] = None
|
|
291
|
+
) -> None:
|
|
292
|
+
"""Warns and exits if the module path contains `rasa_plus`.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
module_path: The module path to check.
|
|
296
|
+
lookup_path: The lookup path to check.
|
|
297
|
+
"""
|
|
298
|
+
if "rasa_plus" in module_path.lower() or (
|
|
299
|
+
lookup_path and "rasa_plus" in lookup_path.lower()
|
|
300
|
+
):
|
|
301
|
+
rasa.shared.utils.io.raise_warning(
|
|
302
|
+
f"Your module path '{module_path}' contains 'rasa_plus'. "
|
|
303
|
+
f"The path to this Rasa Pro component has changed, please "
|
|
304
|
+
f"follow the migration guide in the official documentation "
|
|
305
|
+
f"to update your code: ",
|
|
306
|
+
docs=DOCS_URL_MIGRATION_GUIDE,
|
|
307
|
+
)
|
|
308
|
+
sys.exit(1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DEFAULT_ENCODING = "utf-8"
|
rasa/shared/utils/io.py
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
from collections import OrderedDict
|
|
2
|
+
import errno
|
|
3
|
+
import glob
|
|
4
|
+
from hashlib import md5
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, List, Optional, Text, Type, Union
|
|
10
|
+
import warnings
|
|
11
|
+
import random
|
|
12
|
+
import string
|
|
13
|
+
import portalocker
|
|
14
|
+
|
|
15
|
+
from rasa.shared.constants import (
|
|
16
|
+
DEFAULT_LOG_LEVEL,
|
|
17
|
+
ENV_LOG_LEVEL,
|
|
18
|
+
NEXT_MAJOR_VERSION_FOR_DEPRECATIONS,
|
|
19
|
+
)
|
|
20
|
+
from rasa.shared.exceptions import (
|
|
21
|
+
FileIOException,
|
|
22
|
+
FileNotFoundException,
|
|
23
|
+
)
|
|
24
|
+
from rasa.shared.utils.constants import DEFAULT_ENCODING
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class bcolors:
|
|
28
|
+
HEADER = "\033[95m"
|
|
29
|
+
OKBLUE = "\033[94m"
|
|
30
|
+
OKGREEN = "\033[92m"
|
|
31
|
+
WARNING = "\033[93m"
|
|
32
|
+
FAIL = "\033[91m"
|
|
33
|
+
ENDC = "\033[0m"
|
|
34
|
+
BOLD = "\033[1m"
|
|
35
|
+
UNDERLINE = "\033[4m"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def wrap_with_color(*args: Any, color: Text) -> Text:
|
|
39
|
+
return color + " ".join(str(s) for s in args) + bcolors.ENDC
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def raise_warning(
|
|
43
|
+
message: Text,
|
|
44
|
+
category: Optional[Type[Warning]] = None,
|
|
45
|
+
docs: Optional[Text] = None,
|
|
46
|
+
**kwargs: Any,
|
|
47
|
+
) -> None:
|
|
48
|
+
"""Emit a `warnings.warn` with sensible defaults and a colored warning msg."""
|
|
49
|
+
original_formatter = warnings.formatwarning
|
|
50
|
+
|
|
51
|
+
def should_show_source_line() -> bool:
|
|
52
|
+
if "stacklevel" not in kwargs:
|
|
53
|
+
if category == UserWarning or category is None:
|
|
54
|
+
return False
|
|
55
|
+
if category == FutureWarning:
|
|
56
|
+
return False
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
def formatwarning(
|
|
60
|
+
message: Union[Warning, Text],
|
|
61
|
+
category: Type[Warning],
|
|
62
|
+
filename: Text,
|
|
63
|
+
lineno: int,
|
|
64
|
+
line: Optional[Text] = None,
|
|
65
|
+
) -> Text:
|
|
66
|
+
"""Function to format a warning the standard way."""
|
|
67
|
+
if not should_show_source_line():
|
|
68
|
+
if docs:
|
|
69
|
+
line = f"More info at {docs}"
|
|
70
|
+
else:
|
|
71
|
+
line = ""
|
|
72
|
+
|
|
73
|
+
formatted_message = original_formatter(
|
|
74
|
+
message, category, filename, lineno, line
|
|
75
|
+
)
|
|
76
|
+
return wrap_with_color(formatted_message, color=bcolors.WARNING)
|
|
77
|
+
|
|
78
|
+
if "stacklevel" not in kwargs:
|
|
79
|
+
# try to set useful defaults for the most common warning categories
|
|
80
|
+
if category == DeprecationWarning:
|
|
81
|
+
kwargs["stacklevel"] = 3
|
|
82
|
+
elif category in (UserWarning, FutureWarning):
|
|
83
|
+
kwargs["stacklevel"] = 2
|
|
84
|
+
|
|
85
|
+
warnings.formatwarning = formatwarning
|
|
86
|
+
warnings.warn(message, category=category, **kwargs)
|
|
87
|
+
warnings.formatwarning = original_formatter
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def write_text_file(
|
|
91
|
+
content: Text,
|
|
92
|
+
file_path: Union[Text, Path],
|
|
93
|
+
encoding: Text = DEFAULT_ENCODING,
|
|
94
|
+
append: bool = False,
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Writes text to a file.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
content: The content to write.
|
|
100
|
+
file_path: The path to which the content should be written.
|
|
101
|
+
encoding: The encoding which should be used.
|
|
102
|
+
append: Whether to append to the file or to truncate the file.
|
|
103
|
+
|
|
104
|
+
"""
|
|
105
|
+
mode = "a" if append else "w"
|
|
106
|
+
with open(file_path, mode, encoding=encoding) as file:
|
|
107
|
+
file.write(content)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def read_file(filename: Union[Text, Path], encoding: Text = DEFAULT_ENCODING) -> Any:
|
|
111
|
+
"""Read text from a file."""
|
|
112
|
+
try:
|
|
113
|
+
with open(filename, encoding=encoding) as f:
|
|
114
|
+
return f.read()
|
|
115
|
+
except FileNotFoundError:
|
|
116
|
+
raise FileNotFoundException(
|
|
117
|
+
f"Failed to read file, " f"'{os.path.abspath(filename)}' does not exist."
|
|
118
|
+
)
|
|
119
|
+
except UnicodeDecodeError:
|
|
120
|
+
raise FileIOException(
|
|
121
|
+
f"Failed to read file '{os.path.abspath(filename)}', "
|
|
122
|
+
f"could not read the file using {encoding} to decode "
|
|
123
|
+
f"it. Please make sure the file is stored with this "
|
|
124
|
+
f"encoding."
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def read_json_file(filename: Union[Text, Path]) -> Any:
|
|
129
|
+
"""Read json from a file."""
|
|
130
|
+
content = read_file(filename)
|
|
131
|
+
try:
|
|
132
|
+
return json.loads(content)
|
|
133
|
+
except ValueError as e:
|
|
134
|
+
raise FileIOException(
|
|
135
|
+
f"Failed to read json from '{os.path.abspath(filename)}'. Error: {e}"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def list_directory(path: Text) -> List[Text]:
|
|
140
|
+
"""Returns all files and folders excluding hidden files.
|
|
141
|
+
|
|
142
|
+
If the path points to a file, returns the file. This is a recursive
|
|
143
|
+
implementation returning files in any depth of the path.
|
|
144
|
+
"""
|
|
145
|
+
if not isinstance(path, str):
|
|
146
|
+
raise ValueError(
|
|
147
|
+
f"`resource_name` must be a string type. " f"Got `{type(path)}` instead"
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
if os.path.isfile(path):
|
|
151
|
+
return [path]
|
|
152
|
+
elif os.path.isdir(path):
|
|
153
|
+
results: List[Text] = []
|
|
154
|
+
for base, dirs, files in os.walk(path, followlinks=True):
|
|
155
|
+
# sort files for same order across runs
|
|
156
|
+
files = sorted(files, key=_filename_without_prefix)
|
|
157
|
+
# add not hidden files
|
|
158
|
+
good_files = filter(lambda x: not x.startswith("."), files)
|
|
159
|
+
results.extend(os.path.join(base, f) for f in good_files)
|
|
160
|
+
# add not hidden directories
|
|
161
|
+
good_directories = filter(lambda x: not x.startswith("."), dirs)
|
|
162
|
+
results.extend(os.path.join(base, f) for f in good_directories)
|
|
163
|
+
return results
|
|
164
|
+
else:
|
|
165
|
+
raise ValueError(f"Could not locate the resource '{os.path.abspath(path)}'.")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def list_files(path: Text) -> List[Text]:
|
|
169
|
+
"""Returns all files excluding hidden files.
|
|
170
|
+
|
|
171
|
+
If the path points to a file, returns the file.
|
|
172
|
+
"""
|
|
173
|
+
return [fn for fn in list_directory(path) if os.path.isfile(fn)]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _filename_without_prefix(file: Text) -> Text:
|
|
177
|
+
"""Splits of a filenames prefix until after the first ``_``."""
|
|
178
|
+
return "_".join(file.split("_")[1:])
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def list_subdirectories(path: Text) -> List[Text]:
|
|
182
|
+
"""Returns all folders excluding hidden files.
|
|
183
|
+
|
|
184
|
+
If the path points to a file, returns an empty list.
|
|
185
|
+
"""
|
|
186
|
+
return [fn for fn in glob.glob(os.path.join(path, "*")) if os.path.isdir(fn)]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def deep_container_fingerprint(
|
|
190
|
+
obj: Union[List[Any], Dict[Any, Any], Any], encoding: Text = DEFAULT_ENCODING
|
|
191
|
+
) -> Text:
|
|
192
|
+
"""Calculate a hash which is stable.
|
|
193
|
+
|
|
194
|
+
Works for lists and dictionaries. For keys and values, we recursively call
|
|
195
|
+
`hash(...)` on them. In case of a dict, the hash is independent of the containers
|
|
196
|
+
key order. Keep in mind that a list with items in a different order
|
|
197
|
+
will not create the same hash!
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
obj: dictionary or list to be hashed.
|
|
201
|
+
encoding: encoding used for dumping objects as strings
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
hash of the container.
|
|
205
|
+
"""
|
|
206
|
+
if isinstance(obj, dict):
|
|
207
|
+
return get_dictionary_fingerprint(obj, encoding)
|
|
208
|
+
elif isinstance(obj, list):
|
|
209
|
+
return get_list_fingerprint(obj, encoding)
|
|
210
|
+
elif hasattr(obj, "fingerprint") and callable(obj.fingerprint):
|
|
211
|
+
return obj.fingerprint()
|
|
212
|
+
else:
|
|
213
|
+
return get_text_hash(str(obj), encoding)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_dictionary_fingerprint(
|
|
217
|
+
dictionary: Dict[Any, Any], encoding: Text = DEFAULT_ENCODING
|
|
218
|
+
) -> Text:
|
|
219
|
+
"""Calculate the fingerprint for a dictionary.
|
|
220
|
+
|
|
221
|
+
The dictionary can contain any keys and values which are either a dict,
|
|
222
|
+
a list or a elements which can be dumped as a string.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
dictionary: dictionary to be hashed
|
|
226
|
+
encoding: encoding used for dumping objects as strings
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
The hash of the dictionary
|
|
230
|
+
"""
|
|
231
|
+
stringified = json.dumps(
|
|
232
|
+
{
|
|
233
|
+
deep_container_fingerprint(k, encoding): deep_container_fingerprint(
|
|
234
|
+
v, encoding
|
|
235
|
+
)
|
|
236
|
+
for k, v in dictionary.items()
|
|
237
|
+
},
|
|
238
|
+
sort_keys=True,
|
|
239
|
+
)
|
|
240
|
+
return get_text_hash(stringified, encoding)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def get_list_fingerprint(
|
|
244
|
+
elements: List[Any], encoding: Text = DEFAULT_ENCODING
|
|
245
|
+
) -> Text:
|
|
246
|
+
"""Calculate a fingerprint for an unordered list.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
elements: unordered list
|
|
250
|
+
encoding: encoding used for dumping objects as strings
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
the fingerprint of the list
|
|
254
|
+
"""
|
|
255
|
+
stringified = json.dumps(
|
|
256
|
+
[deep_container_fingerprint(element, encoding) for element in elements]
|
|
257
|
+
)
|
|
258
|
+
return get_text_hash(stringified, encoding)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def get_text_hash(text: Text, encoding: Text = DEFAULT_ENCODING) -> Text:
|
|
262
|
+
"""Calculate the md5 hash for a text."""
|
|
263
|
+
# deepcode ignore InsecureHash: Not used for a cryptographic purpose
|
|
264
|
+
return md5(text.encode(encoding)).hexdigest() # nosec
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def json_to_string(obj: Any, **kwargs: Any) -> Text:
|
|
268
|
+
"""Dumps a JSON-serializable object to string.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
obj: JSON-serializable object.
|
|
272
|
+
kwargs: serialization options. Defaults to 2 space indentation
|
|
273
|
+
and disable escaping of non-ASCII characters.
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
The objects serialized to JSON, as a string.
|
|
277
|
+
"""
|
|
278
|
+
indent = kwargs.pop("indent", 2)
|
|
279
|
+
ensure_ascii = kwargs.pop("ensure_ascii", False)
|
|
280
|
+
return json.dumps(obj, indent=indent, ensure_ascii=ensure_ascii, **kwargs)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def convert_to_ordered_dict(obj: Any) -> Any:
|
|
284
|
+
"""Convert object to an `OrderedDict`.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
obj: Object to convert.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
An `OrderedDict` with all nested dictionaries converted if `obj` is a
|
|
291
|
+
dictionary, otherwise the object itself.
|
|
292
|
+
"""
|
|
293
|
+
if isinstance(obj, OrderedDict):
|
|
294
|
+
return obj
|
|
295
|
+
# use recursion on lists
|
|
296
|
+
if isinstance(obj, list):
|
|
297
|
+
return [convert_to_ordered_dict(element) for element in obj]
|
|
298
|
+
|
|
299
|
+
if isinstance(obj, dict):
|
|
300
|
+
out = OrderedDict()
|
|
301
|
+
# use recursion on dictionaries
|
|
302
|
+
for k, v in obj.items():
|
|
303
|
+
out[k] = convert_to_ordered_dict(v)
|
|
304
|
+
|
|
305
|
+
return out
|
|
306
|
+
|
|
307
|
+
# return all other objects
|
|
308
|
+
return obj
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def is_logging_disabled() -> bool:
|
|
312
|
+
"""Returns `True` if log level is set to WARNING or ERROR, `False` otherwise."""
|
|
313
|
+
log_level = os.environ.get(ENV_LOG_LEVEL, DEFAULT_LOG_LEVEL)
|
|
314
|
+
|
|
315
|
+
return log_level in ("ERROR", "WARNING")
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def create_directory_for_file(file_path: Union[Text, Path]) -> None:
|
|
319
|
+
"""Creates any missing parent directories of this file path."""
|
|
320
|
+
create_directory(os.path.dirname(file_path))
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def dump_obj_as_json_to_file(filename: Union[Text, Path], obj: Any) -> None:
|
|
324
|
+
"""Dump an object as a json string to a file."""
|
|
325
|
+
write_text_file(json.dumps(obj, ensure_ascii=False, indent=2), filename)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def create_directory(directory_path: Text) -> None:
|
|
329
|
+
"""Creates a directory and its super paths.
|
|
330
|
+
|
|
331
|
+
Succeeds even if the path already exists.
|
|
332
|
+
"""
|
|
333
|
+
try:
|
|
334
|
+
os.makedirs(directory_path)
|
|
335
|
+
except OSError as e:
|
|
336
|
+
# be happy if someone already created the path
|
|
337
|
+
if e.errno != errno.EEXIST:
|
|
338
|
+
raise
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def raise_deprecation_warning(
|
|
342
|
+
message: Text,
|
|
343
|
+
warn_until_version: Text = NEXT_MAJOR_VERSION_FOR_DEPRECATIONS,
|
|
344
|
+
docs: Optional[Text] = None,
|
|
345
|
+
**kwargs: Any,
|
|
346
|
+
) -> None:
|
|
347
|
+
"""Thin wrapper around `raise_warning()` to raise a deprecation warning.
|
|
348
|
+
|
|
349
|
+
It requires
|
|
350
|
+
a version until which we'll warn, and after which the support for the feature will
|
|
351
|
+
be removed.
|
|
352
|
+
"""
|
|
353
|
+
if warn_until_version not in message:
|
|
354
|
+
message = f"{message} (will be removed in {warn_until_version})"
|
|
355
|
+
|
|
356
|
+
# need the correct stacklevel now
|
|
357
|
+
kwargs.setdefault("stacklevel", 3)
|
|
358
|
+
# we're raising a `FutureWarning` instead of a `DeprecationWarning` because
|
|
359
|
+
# we want these warnings to be visible in the terminal of our users
|
|
360
|
+
# https://docs.python.org/3/library/warnings.html#warning-categories
|
|
361
|
+
raise_warning(message, FutureWarning, docs, **kwargs)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def is_subdirectory(path: Text, potential_parent_directory: Text) -> bool:
|
|
365
|
+
"""Checks if `path` is a subdirectory of `potential_parent_directory`.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
path: Path to a file or directory.
|
|
369
|
+
potential_parent_directory: Potential parent directory.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
`True` if `path` is a subdirectory of `potential_parent_directory`.
|
|
373
|
+
"""
|
|
374
|
+
if path is None or potential_parent_directory is None:
|
|
375
|
+
return False
|
|
376
|
+
|
|
377
|
+
path = os.path.abspath(path)
|
|
378
|
+
potential_parent_directory = os.path.abspath(potential_parent_directory)
|
|
379
|
+
|
|
380
|
+
return potential_parent_directory in path
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def random_string(length: int) -> Text:
|
|
384
|
+
"""Returns a random string of given length."""
|
|
385
|
+
return "".join(random.choices(string.ascii_uppercase + string.digits, k=length))
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def handle_print_blocking(output: Text) -> None:
|
|
389
|
+
"""Handle print blocking (BlockingIOError) by getting the STDOUT lock.
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
output: Text to be printed to STDOUT.
|
|
393
|
+
"""
|
|
394
|
+
# Locking again to obtain STDOUT with a lock.
|
|
395
|
+
with portalocker.Lock(sys.stdout) as lock:
|
|
396
|
+
if sys.platform == "win32":
|
|
397
|
+
# colorama is used to fix a regression where colors can not be printed on
|
|
398
|
+
# windows. https://github.com/RasaHQ/rasa/issues/7053
|
|
399
|
+
from colorama import AnsiToWin32
|
|
400
|
+
|
|
401
|
+
lock = AnsiToWin32(lock).stream
|
|
402
|
+
|
|
403
|
+
print(output, file=lock, flush=True)
|