rasa-sdk 3.19.0.dev1__tar.gz → 3.19.0.dev2__tar.gz

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.
Files changed (36) hide show
  1. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/PKG-INFO +23 -4
  2. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/README.md +19 -0
  3. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/pyproject.toml +13 -7
  4. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/endpoint.py +50 -32
  5. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/executor.py +6 -0
  6. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_server.py +1 -1
  7. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/version.py +1 -1
  8. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/LICENSE.txt +0 -0
  9. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/__init__.py +0 -0
  10. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/__main__.py +0 -0
  11. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/cli/__init__.py +0 -0
  12. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/cli/arguments.py +0 -0
  13. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/constants.py +0 -0
  14. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/events.py +0 -0
  15. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/exceptions.py +0 -0
  16. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/forms.py +0 -0
  17. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_errors.py +0 -0
  18. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_py/__init__.py +0 -0
  19. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_py/action_webhook_pb2.py +0 -0
  20. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_py/action_webhook_pb2.pyi +0 -0
  21. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/grpc_py/action_webhook_pb2_grpc.py +0 -0
  22. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/interfaces.py +0 -0
  23. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/knowledge_base/__init__.py +0 -0
  24. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/knowledge_base/actions.py +0 -0
  25. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/knowledge_base/storage.py +0 -0
  26. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/knowledge_base/utils.py +0 -0
  27. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/plugin.py +0 -0
  28. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/slots.py +0 -0
  29. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/config.py +0 -0
  30. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/endpoints.py +0 -0
  31. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/instrumentation/attribute_extractors.py +0 -0
  32. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/instrumentation/instrumentation.py +0 -0
  33. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/tracer_register.py +0 -0
  34. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/tracing/utils.py +0 -0
  35. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/types.py +0 -0
  36. {rasa_sdk-3.19.0.dev1 → rasa_sdk-3.19.0.dev2}/rasa_sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rasa-sdk
3
- Version: 3.19.0.dev1
3
+ Version: 3.19.0.dev2
4
4
  Summary: Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants
5
5
  License: Apache-2.0
6
6
  Keywords: nlp,machine-learning,machine-learning-library,bot,bots,botkit,rasa conversational-agents,conversational-ai,chatbot,chatbot-framework,bot-framework
@@ -8,7 +8,7 @@ Author: Rasa Technologies GmbH
8
8
  Author-email: hi@rasa.com
9
9
  Maintainer: Tom Bocklisch
10
10
  Maintainer-email: tom@rasa.com
11
- Requires-Python: >=3.10,<3.14
11
+ Requires-Python: >=3.10,<3.15
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: Apache Software License
@@ -22,7 +22,7 @@ Requires-Dist: Sanic-Cors (>=2.0.0,<3.0.0)
22
22
  Requires-Dist: coloredlogs (>=10,<16)
23
23
  Requires-Dist: grpcio (>=1.80.0,<1.81.0)
24
24
  Requires-Dist: grpcio-health-checking (>=1.66.2,<1.67.0)
25
- Requires-Dist: grpcio-tools (>=1.66.2,<1.67.0)
25
+ Requires-Dist: grpcio-tools (>=1.66.2,<1.67.0) ; python_version < "3.14"
26
26
  Requires-Dist: opentelemetry-api (>=1.33.0,<1.34.0)
27
27
  Requires-Dist: opentelemetry-exporter-otlp (>=1.33.0,<1.34.0)
28
28
  Requires-Dist: opentelemetry-sdk (>=1.33.0,<1.34.0)
@@ -30,7 +30,7 @@ Requires-Dist: pluggy (>=1.0.0,<2.0.0)
30
30
  Requires-Dist: protobuf (>=5.29.5,<5.30.0)
31
31
  Requires-Dist: pydantic (>=2.13.4,<2.14.0)
32
32
  Requires-Dist: ruamel.yaml (>=0.19.1,<0.20.0)
33
- Requires-Dist: sanic (>=22.12,<23.0)
33
+ Requires-Dist: sanic (>=25.12,<25.13)
34
34
  Requires-Dist: typing-extensions (>=4.15.0,<4.16.0)
35
35
  Requires-Dist: websockets (>=10.0,<16)
36
36
  Project-URL: Documentation, https://rasa.com/docs
@@ -177,6 +177,25 @@ by GitHub Actions.
177
177
  git push origin 1.2.x
178
178
  ```
179
179
 
180
+ ### Auto patch after Renovate (supported `3.N.x` lines)
181
+
182
+ When a Renovate dependency PR is merged into a supported SDK release line (`3.N.x`, never `main`),
183
+ [Auto Release Renovate](.github/workflows/auto_release_renovate.yml) prepares the next micro/patch
184
+ (via `scripts/release.py`) and opens a `prepare-release-<version>` PR against that same line.
185
+
186
+ **Operator steps:**
187
+
188
+ 1. Confirm the prepare PR appeared (Actions also supports manual `workflow_dispatch` with
189
+ `base_branch` like `3.16.x` if you need to re-run).
190
+ 2. Review CI, changelog, and version on the prepare PR.
191
+ 3. Approve and merge it yourself.
192
+ 4. Existing [Release workflow](.github/workflows/release.yml) tags on `prepare-release-*` merge; publish
193
+ continues as usual.
194
+
195
+ If an open `prepare-release-*` already targets that `3.N.x`, further Renovate merges on the same line
196
+ do not open another competing prepare PR. Manual `make release` / Release workflow dispatch remains
197
+ available. Merges to `main` and non-Renovate merges on `3.N.x` do not start this path.
198
+
180
199
  ## License
181
200
  Licensed under the Apache License, Version 2.0. Copyright 2021 Rasa
182
201
  Technologies GmbH. [Copy of the license](LICENSE.txt).
@@ -137,6 +137,25 @@ by GitHub Actions.
137
137
  git push origin 1.2.x
138
138
  ```
139
139
 
140
+ ### Auto patch after Renovate (supported `3.N.x` lines)
141
+
142
+ When a Renovate dependency PR is merged into a supported SDK release line (`3.N.x`, never `main`),
143
+ [Auto Release Renovate](.github/workflows/auto_release_renovate.yml) prepares the next micro/patch
144
+ (via `scripts/release.py`) and opens a `prepare-release-<version>` PR against that same line.
145
+
146
+ **Operator steps:**
147
+
148
+ 1. Confirm the prepare PR appeared (Actions also supports manual `workflow_dispatch` with
149
+ `base_branch` like `3.16.x` if you need to re-run).
150
+ 2. Review CI, changelog, and version on the prepare PR.
151
+ 3. Approve and merge it yourself.
152
+ 4. Existing [Release workflow](.github/workflows/release.yml) tags on `prepare-release-*` merge; publish
153
+ continues as usual.
154
+
155
+ If an open `prepare-release-*` already targets that `3.N.x`, further Renovate merges on the same line
156
+ do not open another competing prepare PR. Manual `make release` / Release workflow dispatch remains
157
+ available. Merges to `main` and non-Renovate merges on `3.N.x` do not start this path.
158
+
140
159
  ## License
141
160
  Licensed under the Apache License, Version 2.0. Copyright 2021 Rasa
142
161
  Technologies GmbH. [Copy of the license](LICENSE.txt).
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "rasa-sdk"
7
- version = "3.19.0.dev1"
7
+ version = "3.19.0.dev2"
8
8
  description = "Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants"
9
9
  authors = [ "Rasa Technologies GmbH <hi@rasa.com>",]
10
10
  maintainers = [ "Tom Bocklisch <tom@rasa.com>",]
@@ -66,13 +66,13 @@ exclude = "rasa_sdk/grpc_py"
66
66
 
67
67
  [tool.ruff]
68
68
  line-length = 88
69
- target-version = "py38"
69
+ target-version = "py310"
70
70
  exclude = [ "rasa_sdk/grpc_py", "eggs", ".git", ".pytest_cache", "build", "dist", ".DS_Store",]
71
71
 
72
72
  [tool.poetry.dependencies]
73
- python = ">=3.10,<3.14"
73
+ python = ">=3.10,<3.15"
74
74
  coloredlogs = ">=10,<16"
75
- sanic = "^22.12"
75
+ sanic = "~25.12"
76
76
  typing-extensions = "~4.15.0"
77
77
  Sanic-Cors = "^2.0.0"
78
78
  "ruamel.yaml" = "~0.19.1"
@@ -85,7 +85,6 @@ opentelemetry-exporter-otlp = "~1.33.0"
85
85
  opentelemetry-api = "~1.33.0"
86
86
  grpcio = "~1.80.0"
87
87
  protobuf = "~5.29.5"
88
- grpcio-tools = "~1.66.2"
89
88
 
90
89
  [tool.poetry.requires-plugins]
91
90
  poetry-plugin-export = ">=1.8"
@@ -98,6 +97,10 @@ select = [ "D", "E", "F", "W", "RUF",]
98
97
  python_functions = "test_"
99
98
  asyncio_mode = "auto"
100
99
 
100
+ [tool.poetry.dependencies.grpcio-tools]
101
+ version = "~1.66.2"
102
+ python = "<3.14"
103
+
101
104
  [tool.ruff.lint.pydocstyle]
102
105
  convention = "google"
103
106
 
@@ -108,10 +111,13 @@ pytest = "^7.4.0"
108
111
  questionary = ">=1.5.1,<2.1.0"
109
112
  towncrier = "~25.8.0"
110
113
  toml = "^0.10.0"
111
- pep440-version-utils = "~1.2.0"
112
114
  semantic_version = "^2.8.5"
113
115
  mypy = "~2.1.0"
114
- sanic-testing = "~23.6.0"
116
+ sanic-testing = "~24.6.0"
115
117
  ruff = "~0.15.14"
116
118
  pytest-asyncio = "^0.23.6"
117
119
  types-protobuf = "4.25.0.20240417"
120
+
121
+ [tool.poetry.group.dev.dependencies.pep440-version-utils]
122
+ version = "~1.2.0"
123
+ python = "<3.14"
@@ -5,8 +5,7 @@ import warnings
5
5
  import zlib
6
6
  import json
7
7
  from functools import partial
8
- from typing import List, Text, Union, Optional, Any
9
- from ssl import SSLContext
8
+ from typing import Dict, List, Text, Union, Optional, Any
10
9
 
11
10
  from multidict import MultiDict
12
11
  from sanic import Sanic, response
@@ -62,23 +61,21 @@ def configure_cors(
62
61
  )
63
62
 
64
63
 
65
- def create_ssl_context(
64
+ def create_ssl_config(
66
65
  ssl_certificate: Optional[Text],
67
66
  ssl_keyfile: Optional[Text],
68
67
  ssl_password: Optional[Text] = None,
69
- ) -> Optional[SSLContext]:
70
- """Create a SSL context if a certificate is passed."""
71
- if ssl_certificate:
72
- import ssl
73
-
74
- ssl_context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
75
- ssl_context.load_cert_chain(
76
- ssl_certificate, keyfile=ssl_keyfile, password=ssl_password
77
- )
78
- return ssl_context
79
- else:
68
+ ) -> Optional[Dict[Text, Optional[Text]]]:
69
+ """Create a Sanic SSL config if a certificate is passed.
70
+
71
+ Returns cert and key paths rather than an ``ssl.SSLContext`` so each spawned
72
+ worker can rebuild the context; ``SSLContext`` objects are not picklable.
73
+ """
74
+ if not ssl_certificate:
80
75
  return None
81
76
 
77
+ return {"cert": ssl_certificate, "key": ssl_keyfile, "password": ssl_password}
78
+
82
79
 
83
80
  def create_argument_parser():
84
81
  """Parse all the command line arguments for the run script."""
@@ -212,6 +209,32 @@ def create_app(
212
209
  return app
213
210
 
214
211
 
212
+ def create_app_for_serve(
213
+ action_executor: ActionExecutor,
214
+ cors_origins: Union[Text, List[Text], None] = "*",
215
+ auto_reload: bool = False,
216
+ endpoints: str = DEFAULT_ENDPOINTS_PATH,
217
+ keep_alive_timeout: int = DEFAULT_KEEP_ALIVE_TIMEOUT,
218
+ ) -> Sanic:
219
+ """Build a Sanic app for the primary process and each worker.
220
+
221
+ Must be module-level so ``Sanic.serve`` can pickle it via ``AppLoader``.
222
+ """
223
+ app = create_app(
224
+ action_executor,
225
+ cors_origins=cors_origins,
226
+ auto_reload=auto_reload,
227
+ )
228
+ app.config.KEEP_ALIVE_TIMEOUT = keep_alive_timeout
229
+ app.register_listener(
230
+ partial(load_tracer_provider, endpoints),
231
+ "before_server_start",
232
+ )
233
+ logger.info("Starting plugins...")
234
+ plugin_manager().hook.attach_sanic_app_extensions(app=app)
235
+ return app
236
+
237
+
215
238
  def run(
216
239
  action_executor: ActionExecutor,
217
240
  port: int = DEFAULT_SERVER_PORT,
@@ -225,39 +248,34 @@ def run(
225
248
  ) -> None:
226
249
  """Starts the action endpoint server with given config values."""
227
250
  logger.info("Starting action endpoint server...")
251
+
228
252
  loader = AppLoader(
229
253
  factory=partial(
230
- create_app,
254
+ create_app_for_serve,
231
255
  action_executor,
232
256
  cors_origins=cors_origins,
233
257
  auto_reload=auto_reload,
234
- ),
258
+ endpoints=endpoints,
259
+ keep_alive_timeout=keep_alive_timeout,
260
+ )
235
261
  )
236
262
  app = loader.load()
237
263
 
238
- app.config.KEEP_ALIVE_TIMEOUT = keep_alive_timeout
239
-
240
- app.register_listener(
241
- partial(load_tracer_provider, endpoints),
242
- "before_server_start",
243
- )
244
-
245
- # Attach additional sanic extensions: listeners, middleware and routing
246
- logger.info("Starting plugins...")
247
- plugin_manager().hook.attach_sanic_app_extensions(app=app)
248
-
249
- ssl_context = create_ssl_context(ssl_certificate, ssl_keyfile, ssl_password)
250
- protocol = "https" if ssl_context else "http"
264
+ ssl_config = create_ssl_config(ssl_certificate, ssl_keyfile, ssl_password)
265
+ protocol = "https" if ssl_config else "http"
251
266
  host = os.environ.get("SANIC_HOST", "0.0.0.0")
252
267
 
253
268
  logger.info(f"Action endpoint is up and running on {protocol}://{host}:{port}")
254
- app.run(
269
+
270
+ # Sanic 25 removed ``legacy=True`` from ``app.run``. Use prepare + serve so
271
+ # AppLoader recreates the app (listeners, plugins, config) in each worker.
272
+ app.prepare(
255
273
  host=host,
256
274
  port=port,
257
- ssl=ssl_context,
275
+ ssl=ssl_config,
258
276
  workers=utils.number_of_sanic_workers(),
259
- legacy=True,
260
277
  )
278
+ Sanic.serve(primary=app, app_loader=loader)
261
279
 
262
280
 
263
281
  def set_http_span_attributes(
@@ -432,6 +432,12 @@ class ActionExecutor:
432
432
  self.domain: Optional[Dict[Text, Any]] = None
433
433
  self.domain_digest: Optional[Text] = None
434
434
 
435
+ def __getstate__(self) -> Dict[Text, Any]:
436
+ """Drop unpicklable module objects so Sanic can spawn workers."""
437
+ state = self.__dict__.copy()
438
+ state["_modules"] = {}
439
+ return state
440
+
435
441
  def register_action(self, action: Union[Type[Action], Action]) -> None:
436
442
  """Register an action with the executor.
437
443
 
@@ -700,7 +700,7 @@ def _initialise_interrupts(server: grpc.Server) -> None:
700
700
  await server.stop(NO_GRACE_PERIOD)
701
701
  logger.info("gRPC server stopped.")
702
702
 
703
- loop = asyncio.get_event_loop()
703
+ loop = asyncio.get_running_loop()
704
704
  loop.add_signal_handler(
705
705
  signal.SIGINT, lambda: asyncio.create_task(handle_sigint(signal.SIGINT))
706
706
  )
@@ -1,3 +1,3 @@
1
1
  # this file will automatically be changed,
2
2
  # do not add anything but the version number here!
3
- __version__ = "3.19.0.dev1"
3
+ __version__ = "3.19.0.dev2"