diff --git a/modules/trino/README.rst b/modules/trino/README.rst new file mode 100644 index 000000000..95b4be930 --- /dev/null +++ b/modules/trino/README.rst @@ -0,0 +1,2 @@ +.. autoclass:: testcontainers.trino.TrinoContainer +.. title:: testcontainers.trino.TrinoContainer diff --git a/modules/trino/testcontainers/trino/__init__.py b/modules/trino/testcontainers/trino/__init__.py new file mode 100644 index 000000000..97e3f9de4 --- /dev/null +++ b/modules/trino/testcontainers/trino/__init__.py @@ -0,0 +1,56 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import re + +from testcontainers.core.config import testcontainers_config as c +from testcontainers.core.generic import DbContainer +from testcontainers.core.waiting_utils import wait_container_is_ready, wait_for_logs +from trino.dbapi import connect + + +class TrinoContainer(DbContainer): + def __init__( + self, + image="trinodb/trino:latest", + user: str = "test", + port: int = 8080, + **kwargs, + ): + super().__init__(image=image, **kwargs) + self.user = user + self.port = port + self.with_exposed_ports(self.port) + + @wait_container_is_ready() + def _connect(self) -> None: + wait_for_logs( + self, + re.compile(".*======== SERVER STARTED ========.*", re.MULTILINE).search, + c.max_tries, + c.sleep_time, + ) + conn = connect( + host=self.get_container_host_ip(), + port=self.get_exposed_port(self.port), + user=self.user, + ) + cur = conn.cursor() + cur.execute("SELECT 1") + cur.fetchall() + conn.close() + + def get_connection_url(self): + return f"trino://{self.user}@{self.get_container_host_ip()}:{self.port}" + + def _configure(self): + pass diff --git a/modules/trino/tests/test_trino.py b/modules/trino/tests/test_trino.py new file mode 100644 index 000000000..c1a70230b --- /dev/null +++ b/modules/trino/tests/test_trino.py @@ -0,0 +1,17 @@ +from testcontainers.trino import TrinoContainer +from trino.dbapi import connect + + +def test_docker_run_trino(): + container = TrinoContainer("trinodb/trino:451") + with container as trino: + conn = connect( + host=trino.get_container_host_ip(), + port=trino.get_exposed_port(trino.port), + user="test", + ) + cur = conn.cursor() + cur.execute("SELECT version()") + rows = cur.fetchall() + assert rows[0][0] == "451" + conn.close() diff --git a/poetry.lock b/poetry.lock index 596444b7d..56f42ea3b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1913,7 +1913,6 @@ python-versions = ">=3.7" files = [ {file = "milvus_lite-2.4.7-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:c828190118b104b05b8c8e0b5a4147811c86b54b8fb67bc2e726ad10fc0b544e"}, {file = "milvus_lite-2.4.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e1537633c39879714fb15082be56a4b97f74c905a6e98e302ec01320561081af"}, - {file = "milvus_lite-2.4.7-py3-none-manylinux2014_aarch64.whl", hash = "sha256:fcb909d38c83f21478ca9cb500c84264f988c69f62715ae9462e966767fb76dd"}, {file = "milvus_lite-2.4.7-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f016474d663045787dddf1c3aad13b7d8b61fd329220318f858184918143dcbf"}, ] @@ -4108,6 +4107,31 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "trino" +version = "0.329.0" +description = "Client for the Trino distributed SQL Engine" +optional = true +python-versions = ">=3.8" +files = [ + {file = "trino-0.329.0-py3-none-any.whl", hash = "sha256:74b82a38f16193ad869e63fb837d651e66c044f19a817232787e27c5d44b671f"}, + {file = "trino-0.329.0.tar.gz", hash = "sha256:1d976467726ec3d0fa120a64e61fdb8caf13295db207051e2cc267a952af989b"}, +] + +[package.dependencies] +python-dateutil = "*" +pytz = "*" +requests = ">=2.31.0" +tzlocal = "*" + +[package.extras] +all = ["requests-kerberos", "sqlalchemy (>=1.3)"] +external-authentication-token-cache = ["keyring"] +gssapi = ["requests-gssapi"] +kerberos = ["requests-kerberos"] +sqlalchemy = ["sqlalchemy (>=1.3)"] +tests = ["black", "httpretty (<1.1)", "isort", "pre-commit", "pytest", "pytest-runner", "requests-gssapi", "requests-kerberos", "sqlalchemy (>=1.3)"] + [[package]] name = "trio" version = "0.24.0" @@ -4571,10 +4595,11 @@ registry = ["bcrypt"] selenium = ["selenium"] sftp = ["cryptography"] test-module-import = ["httpx"] +trino = ["trino"] vault = [] weaviate = ["weaviate-client"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "4694e6bedeb7263ba9b7de579b81913f285161d5d27d453bd36a616e9ce3eade" +content-hash = "ef48ca48ddc2bc6ac68487e1674d1e6973c3a14b2b5c41235262af20695fe432" diff --git a/pyproject.toml b/pyproject.toml index 58814ace1..ac59f12ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ packages = [ { include = "testcontainers", from = "modules/registry" }, { include = "testcontainers", from = "modules/sftp" }, { include = "testcontainers", from = "modules/selenium" }, + { include = "testcontainers", from = "modules/trino" }, { include = "testcontainers", from = "modules/vault" }, { include = "testcontainers", from = "modules/weaviate" }, ] @@ -111,6 +112,7 @@ bcrypt = { version = "*", optional = true } httpx = { version = "*", optional = true } azure-cosmos = { version = "*", optional = true } cryptography = { version = "*", optional = true } +trino = { version = "*", optional = true } [tool.poetry.extras] arangodb = ["python-arango"] @@ -153,6 +155,7 @@ sftp = ["cryptography"] vault = [] weaviate = ["weaviate-client"] chroma = ["chromadb-client"] +trino = ["trino"] [tool.poetry.group.dev.dependencies] mypy = "1.7.1"