Skip to content

Commit

Permalink
update rasa-sdk to support python 3.11, 3.12 (#1145)
Browse files Browse the repository at this point in the history
* update rasa-sdk to support python 3.11, 3.12 and 3.13

* update test test_cli_non_existent_handler_id_in_config

* fix lint errors

* Remove black and prompt-toolkit as they are not used anymore

Updated the constraint for grpcio-tools. It is listed in the extras package for grpcio which specifies the same constraint. I had trouble installing earlier versions on Python 3.12

* handle diff in grpc code

* update grpcio constraint

* update pydantic constraint

* update typing extensions and grpcio-tools

* remove python 3.13 support as grpcio-tools fails to install

* update grpc code

* update poetry.lock

* drop python 3.8 support

* add changelog for 1145

* remove unused import

* remove stale test
  • Loading branch information
vcidst authored Oct 23, 2024
1 parent 3ae845c commit a34edd8
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 390 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: [3.8, 3.9, '3.10']
python-version: [3.9, '3.10', '3.11', '3.12']

steps:
- name: Checkout git repository 🕝
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,5 @@ tests/executor_test_packages

grpc-standalone-server-integration-test-results.xml
grpc-server-docker-integration-test-results.xml

.vscode/
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ generate-grpc: ## generate grpc code
--pyi_out=. \
proto/action_webhook.proto

check-generate-grpc-code-in-sync: generate-grpc
check-generate-grpc-code-in-sync: ## check if the generated code is in sync with the proto files
# this is a helper to check if the generated code is in sync with the proto files
check-generate-grpc-code-in-sync: generate-grpc ## check if the generated code is in sync with the proto files, it uses a helper to check if the generated code is in sync with the proto files
git diff --exit-code rasa_sdk/grpc_py | if [ "$$(wc -c)" -eq 0 ]; then echo "Generated code is in sync with proto files"; else echo "Generated code is not in sync with proto files"; exit 1; fi

GRPC_STANDALONE_SERVER_INTEGRATION_TEST_RESULTS_FILE = grpc-standalone-server-integration-test-results.xml
Expand Down
1 change: 1 addition & 0 deletions changelog/1145.improvement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adds support for Python 3.11 and 3.12, drops Python 3.8 support
639 changes: 301 additions & 338 deletions poetry.lock

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,28 @@ target-version = "py38"
exclude = [ "rasa_sdk/grpc_py", "eggs", ".git", ".pytest_cache", "build", "dist", ".DS_Store",]

[tool.poetry.dependencies]
python = ">=3.8,<3.11"
python = ">3.8,<3.13"
coloredlogs = ">=10,<16"
sanic = "^22.12"
typing-extensions = ">=4.1.1,<5.0.0"
Sanic-Cors = "^2.0.0"
prompt-toolkit = "^3.0,<3.0.29"
"ruamel.yaml" = ">=0.16.5,<0.18.0"
websockets = ">=10.0,<12.0"
pluggy = "^1.0.0"
opentelemetry-api = "~1.16.0"
opentelemetry-sdk = "~1.16.0"
opentelemetry-exporter-jaeger = "~1.16.0"
opentelemetry-exporter-otlp = "~1.16.0"
grpcio = "1.59.3"
protobuf = "4.25.3"
grpcio-tools = "1.56.2"
pydantic = "2.6.4"
grpcio-health-checking = "1.59.3"
grpcio = "^1.59.3"
protobuf = "~4.25.3"
pydantic = "^2.6.4"
grpcio-health-checking = "~1.59.3"
grpcio-tools = ">=1.59.3"

[tool.poetry.dev-dependencies]
pytest-cov = "^4.1.0"
coveralls = "^3.0.1"
pytest = "^7.4.0"
black = "22.12.0"
questionary = ">=1.5.1,<2.1.0"
towncrier = "^23.6.0"
toml = "^0.10.0"
Expand Down
6 changes: 3 additions & 3 deletions rasa_sdk/grpc_py/action_webhook_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions rasa_sdk/grpc_py/action_webhook_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map
DESCRIPTOR: _descriptor.FileDescriptor

class ActionsRequest(_message.Message):
__slots__ = []
__slots__ = ()
def __init__(self) -> None: ...

class ActionsResponse(_message.Message):
__slots__ = ["actions"]
__slots__ = ("actions",)
ACTIONS_FIELD_NUMBER: _ClassVar[int]
actions: _containers.RepeatedCompositeFieldContainer[_struct_pb2.Struct]
def __init__(self, actions: _Optional[_Iterable[_Union[_struct_pb2.Struct, _Mapping]]] = ...) -> None: ...

class Tracker(_message.Message):
__slots__ = ["sender_id", "slots", "latest_message", "events", "paused", "followup_action", "active_loop", "latest_action_name", "stack"]
__slots__ = ("sender_id", "slots", "latest_message", "events", "paused", "followup_action", "active_loop", "latest_action_name", "stack")
class ActiveLoopEntry(_message.Message):
__slots__ = ["key", "value"]
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
Expand All @@ -46,31 +46,31 @@ class Tracker(_message.Message):
def __init__(self, sender_id: _Optional[str] = ..., slots: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., latest_message: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., events: _Optional[_Iterable[_Union[_struct_pb2.Struct, _Mapping]]] = ..., paused: bool = ..., followup_action: _Optional[str] = ..., active_loop: _Optional[_Mapping[str, str]] = ..., latest_action_name: _Optional[str] = ..., stack: _Optional[_Iterable[_Union[_struct_pb2.Struct, _Mapping]]] = ...) -> None: ...

class Intent(_message.Message):
__slots__ = ["string_value", "dict_value"]
__slots__ = ("string_value", "dict_value")
STRING_VALUE_FIELD_NUMBER: _ClassVar[int]
DICT_VALUE_FIELD_NUMBER: _ClassVar[int]
string_value: str
dict_value: _struct_pb2.Struct
def __init__(self, string_value: _Optional[str] = ..., dict_value: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...

class Entity(_message.Message):
__slots__ = ["string_value", "dict_value"]
__slots__ = ("string_value", "dict_value")
STRING_VALUE_FIELD_NUMBER: _ClassVar[int]
DICT_VALUE_FIELD_NUMBER: _ClassVar[int]
string_value: str
dict_value: _struct_pb2.Struct
def __init__(self, string_value: _Optional[str] = ..., dict_value: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...

class Action(_message.Message):
__slots__ = ["string_value", "dict_value"]
__slots__ = ("string_value", "dict_value")
STRING_VALUE_FIELD_NUMBER: _ClassVar[int]
DICT_VALUE_FIELD_NUMBER: _ClassVar[int]
string_value: str
dict_value: _struct_pb2.Struct
def __init__(self, string_value: _Optional[str] = ..., dict_value: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...

class Domain(_message.Message):
__slots__ = ["config", "session_config", "intents", "entities", "slots", "responses", "actions", "forms", "e2e_actions"]
__slots__ = ("config", "session_config", "intents", "entities", "slots", "responses", "actions", "forms", "e2e_actions")
CONFIG_FIELD_NUMBER: _ClassVar[int]
SESSION_CONFIG_FIELD_NUMBER: _ClassVar[int]
INTENTS_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -92,7 +92,7 @@ class Domain(_message.Message):
def __init__(self, config: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., session_config: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., intents: _Optional[_Iterable[_Union[Intent, _Mapping]]] = ..., entities: _Optional[_Iterable[_Union[Entity, _Mapping]]] = ..., slots: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., responses: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., actions: _Optional[_Iterable[_Union[Action, _Mapping]]] = ..., forms: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., e2e_actions: _Optional[_Iterable[_Union[_struct_pb2.Struct, _Mapping]]] = ...) -> None: ...

class WebhookRequest(_message.Message):
__slots__ = ["next_action", "sender_id", "tracker", "domain", "version", "domain_digest"]
__slots__ = ("next_action", "sender_id", "tracker", "domain", "version", "domain_digest")
NEXT_ACTION_FIELD_NUMBER: _ClassVar[int]
SENDER_ID_FIELD_NUMBER: _ClassVar[int]
TRACKER_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -108,7 +108,7 @@ class WebhookRequest(_message.Message):
def __init__(self, next_action: _Optional[str] = ..., sender_id: _Optional[str] = ..., tracker: _Optional[_Union[Tracker, _Mapping]] = ..., domain: _Optional[_Union[Domain, _Mapping]] = ..., version: _Optional[str] = ..., domain_digest: _Optional[str] = ...) -> None: ...

class WebhookResponse(_message.Message):
__slots__ = ["events", "responses"]
__slots__ = ("events", "responses")
EVENTS_FIELD_NUMBER: _ClassVar[int]
RESPONSES_FIELD_NUMBER: _ClassVar[int]
events: _containers.RepeatedCompositeFieldContainer[_struct_pb2.Struct]
Expand Down
1 change: 0 additions & 1 deletion tests/test_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def test_server_list_actions_returns_200(
sanic_app: Sanic,
):
"""Test that the server returns a list of actions."""

# When we request the list of actions
request, response = sanic_app.test_client.get("/actions")

Expand Down
26 changes: 0 additions & 26 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
import logging
import os
import sys
from pathlib import Path
from typing import Any, Text

Expand Down Expand Up @@ -189,9 +188,6 @@ def test_cli_invalid_logging_configuration(
)


@pytest.mark.skipif(
sys.version_info.minor == 7, reason="no error is raised with python 3.7"
)
def test_cli_invalid_format_value_in_config(caplog: LogCaptureFixture) -> None:
root_dir = Path(__file__).resolve().parents[1]
logging_config_file = (
Expand All @@ -211,28 +207,6 @@ def test_cli_invalid_format_value_in_config(caplog: LogCaptureFixture) -> None:
)


@pytest.mark.skipif(
sys.version_info.minor in [9, 10],
reason="no error is raised with python 3.9 or 3.10",
)
def test_cli_non_existent_handler_id_in_config(caplog: LogCaptureFixture) -> None:
root_dir = Path(__file__).resolve().parents[1]
logging_config_file = (
root_dir / "data/test_logging_config_files/test_non_existent_handler_id.yml"
)

with caplog.at_level(logging.DEBUG):
rasa_sdk.utils.configure_logging_from_input_file(
logging_config_file=logging_config_file
)

assert (
f"The logging config file {logging_config_file} could not be applied "
f"because it failed validation against the built-in Python "
f"logging schema." in caplog.text
)


def test_configure_default_logging():
output_file = "test_default_logging.log"
rasa_sdk.utils.configure_file_logging(
Expand Down

0 comments on commit a34edd8

Please sign in to comment.