Skip to content

Commit 2d8bc11

Browse files
feat: Adding support for Cassandra and Scylla (#167)
This add the support for those cassandra based dbs and their drivers, cassandra-driver, scylla-driver Ref: https://cassandra.apache.org/ Ref: https://www.scylladb.com/ Ref: https://pypi.org/project/cassandra-driver/ Ref: https://pypi.org/project/scylla-driver/ --------- Co-authored-by: David Ankin <[email protected]>
1 parent d5de0aa commit 2d8bc11

File tree

5 files changed

+75
-6
lines changed

5 files changed

+75
-6
lines changed

modules/scylla/README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.. autoclass:: testcontainers.scylla.ScyllaContainer
2+
.. title:: testcontainers.scylla.ScyllaContainer
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from testcontainers.core.config import MAX_TRIES
2+
from testcontainers.core.generic import DockerContainer
3+
from testcontainers.core.waiting_utils import wait_container_is_ready, wait_for_logs
4+
5+
6+
class ScyllaContainer(DockerContainer):
7+
"""
8+
Scylla database container.
9+
10+
Example
11+
-------
12+
.. doctest::
13+
14+
>>> from testcontainers.scylla import ScyllaContainer
15+
16+
>>> with ScyllaContainer() as scylla:
17+
... cluster = scylla.get_cluster()
18+
... with cluster.connect() as session:
19+
... result = session.execute(
20+
... "CREATE KEYSPACE keyspace1 WITH replication "
21+
... "= {'class': 'SimpleStrategy', 'replication_factor': '1'};")
22+
"""
23+
24+
def __init__(self, image="scylladb/scylla:latest", ports_to_expose=(9042,)):
25+
super().__init__(image)
26+
self.ports_to_expose = ports_to_expose
27+
self.with_exposed_ports(*self.ports_to_expose)
28+
self.with_command("--skip-wait-for-gossip-to-settle=0")
29+
30+
@wait_container_is_ready()
31+
def _connect(self):
32+
wait_for_logs(self, predicate="Starting listening for CQL clients", timeout=MAX_TRIES)
33+
cluster = self.get_cluster()
34+
cluster.connect()
35+
36+
def start(self):
37+
super().start()
38+
self._connect()
39+
return self
40+
41+
def get_cluster(self, **kwargs):
42+
from cassandra.cluster import Cluster
43+
44+
container = self.get_wrapped_container()
45+
container.reload()
46+
hostname = container.attrs["NetworkSettings"]["IPAddress"]
47+
return Cluster(contact_points=[hostname], **kwargs)

modules/scylla/tests/test_scylla.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from testcontainers.scylla import ScyllaContainer
2+
3+
4+
def test_docker_run_scylla():
5+
with ScyllaContainer() as scylla:
6+
cluster = scylla.get_cluster()
7+
with cluster.connect() as session:
8+
session.execute(
9+
"CREATE KEYSPACE keyspace1 WITH replication = "
10+
"{'class': 'SimpleStrategy', 'replication_factor': '1'};"
11+
)
12+
session.execute("CREATE TABLE keyspace1.table1 (key1 int, key2 int, PRIMARY KEY (key1));")
13+
session.execute("INSERT INTO keyspace1.table1 (key1,key2) values (1,2);")
14+
15+
response = session.execute("SELECT * FROM keyspace1.table1")
16+
17+
assert response.one().key1 == 1
18+
assert response.one().key2 == 2

poetry.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ packages = [
6767
{ include = "testcontainers", from = "modules/registry" },
6868
{ include = "testcontainers", from = "modules/sftp" },
6969
{ include = "testcontainers", from = "modules/selenium" },
70+
{ include = "testcontainers", from = "modules/scylla" },
7071
{ include = "testcontainers", from = "modules/trino" },
7172
{ include = "testcontainers", from = "modules/vault" },
7273
{ include = "testcontainers", from = "modules/weaviate" },
@@ -86,6 +87,7 @@ typing-extensions = "*"
8687
# community modules
8788
python-arango = { version = "^7.8", optional = true }
8889
azure-storage-blob = { version = "^12.19", optional = true }
90+
cassandra-driver = { version = "3.29.1", optional = true }
8991
clickhouse-driver = { version = "*", optional = true }
9092
google-cloud-pubsub = { version = ">=2", optional = true }
9193
google-cloud-datastore = { version = ">=2", optional = true }
@@ -156,6 +158,7 @@ rabbitmq = ["pika"]
156158
redis = ["redis"]
157159
registry = ["bcrypt"]
158160
selenium = ["selenium"]
161+
scylla = ["cassandra-driver"]
159162
sftp = ["cryptography"]
160163
vault = []
161164
weaviate = ["weaviate-client"]
@@ -175,7 +178,6 @@ psycopg2-binary = "2.9.9"
175178
pg8000 = "1.30.5"
176179
sqlalchemy = "2.0.28"
177180
psycopg = "3.1.18"
178-
cassandra-driver = "3.29.1"
179181
pytest-asyncio = "0.23.5"
180182
kafka-python-ng = "^2.2.0"
181183
hvac = "2.1.0"

0 commit comments

Comments
 (0)