Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@ on:
branches: [ master ]

jobs:
sphinx:
strategy:
fail-fast: false
matrix:
python-version:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
runs-on: ubuntu-latest
Comment thread
pffijt marked this conversation as resolved.
steps:
- uses: actions/checkout@v2
- name: Setup python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Cache Python dependencies
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles(format('requirements/{0}.txt', matrix.python-version)) }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install wheel
pip install -r requirements/${{ matrix.python-version }}.txt
- name: Build documentation
run: sphinx-build -nW docs docs/_build/html
- name: Run doctests
run: sphinx-build -b doctest docs docs/_build/html

build:
strategy:
fail-fast: false
Expand Down Expand Up @@ -62,10 +96,6 @@ jobs:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock --network=bridge testcontainers-python python diagnostics.py
echo "Container diagnostics with host network"
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock --network=host testcontainers-python python diagnostics.py
- name: Build documentation
run: sphinx-build -nW docs docs/_build/html
- name: Run doctests
run: sphinx-build -b doctest docs docs/_build/html
- name: Lint the code
run: flake8
- name: Run tests
Expand Down
6 changes: 6 additions & 0 deletions docs/aws.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
AWS Emulators
===================

Allows to spin up AWS emulators, such as the LocalStackContainer.

.. autoclass:: testcontainers.localstack.LocalStackContainer
6 changes: 6 additions & 0 deletions docs/azure.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Azure Emulators
===================

Allows to spin up Azure emulators, such as the Azurite emulator.

.. autoclass:: testcontainers.azurite.AzuriteContainer
1 change: 0 additions & 1 deletion docs/database.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Allows to spin up database images such as MySQL, PostgreSQL, MariaDB, Oracle XE,
.. autoclass:: testcontainers.mysql.MariaDbContainer
.. autoclass:: testcontainers.postgres.PostgresContainer
.. autoclass:: testcontainers.oracle.OracleDbContainer
.. autoclass:: testcontainers.elasticsearch.ElasticSearchContainer
.. autoclass:: testcontainers.mongodb.MongoDbContainer
.. autoclass:: testcontainers.mssql.SqlServerContainer
.. autoclass:: testcontainers.clickhouse.ClickHouseContainer
Expand Down
6 changes: 6 additions & 0 deletions docs/elasticsearch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Elastic Search Container
===========================

Allows to spin up Elastic Search Container.

.. autoclass:: testcontainers.elasticsearch.ElasticSearchContainer
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ Usage modes
Selenium containers <selenium>
Docker Compose <compose>
Google Cloud Emulators <google-cloud-emulators>
Azure Emulators <azure>
AWS Emulators <aws>
Elastic Search <elasticsearch>
Kafka container <kafka>
Keycloak container <keycloak>
RabbitMQ container <rabbitmq>
Redis container <redis>

6 changes: 6 additions & 0 deletions docs/kafka.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Kafka Container
===================

Allows to spin up Kafka Container.

.. autoclass:: testcontainers.kafka.KafkaContainer
6 changes: 6 additions & 0 deletions docs/keycloak.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Keycloak Container
===================

Allows to spin up Keycloak container.

.. autoclass:: testcontainers.keycloak.KeycloakContainer
6 changes: 6 additions & 0 deletions docs/rabbitmq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RabbitMQ Container
===================

Allows to spin up RabbitMQ container.

.. autoclass:: testcontainers.rabbitmq.RabbitMqContainer
6 changes: 6 additions & 0 deletions docs/redis.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Redis Container
===================

Allows to spin up Redis container.

.. autoclass:: testcontainers.redis.RedisContainer
19 changes: 12 additions & 7 deletions testcontainers/arangodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,21 @@ class ArangoDbContainer(DbContainer):
The example will spin up a ArangoDB container.
You may use the :code:`get_connection_url()` method which returns a arangoclient-compatible url
in format :code:`scheme://host:port`. As of now, only a single host is supported (over HTTP).
::

with ArangoContainer("arangodb:3.9.1") as arango:
client = ArangoClient(hosts=arango.get_connection_url())
.. doctest::

# Connect
sys_db = arango_client.db(username="root", password="")
>>> from testcontainers.arangodb import ArangoDbContainer
>>> from arango import ArangoClient

# Create a new database named "test".
sys_db.create_database("test")
>>> with ArangoDbContainer("arangodb:3.9.1") as arango:
... client = ArangoClient(hosts=arango.get_connection_url())
...
... # Connect
... sys_db = client.db(username="root", password="passwd")
...
... # Create a new database named "test".
... sys_db.create_database("test")
True
"""

def __init__(self,
Expand Down
24 changes: 15 additions & 9 deletions testcontainers/azurite.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,24 @@

class AzuriteContainer(DockerContainer):
"""
Azurite container.
The example below spins up an Azurite container and
shows an example to create a Blob service client with the container. The method
:code:`get_connection_string` can be used to create a client for Blob service, Queue service
and Table service.

Example
-------
::

with AzuriteContainer() as azurite:
connection_string = azurite.get_connection_string()
BlobServiceClient.from_connection_string(
connection_string,
api_version="2019-12-12"
)
.. doctest::

>>> from testcontainers.azurite import AzuriteContainer
>>> from azure.storage.blob import BlobServiceClient

>>> with AzuriteContainer() as azurite_container:
... connection_string = azurite_container.get_connection_string()
... client = BlobServiceClient.from_connection_string(
... connection_string,
... api_version="2019-12-12"
... )
"""

_AZURITE_ACCOUNT_NAME = os.environ.get("AZURITE_ACCOUNT_NAME", "devstoreaccount1")
Expand Down
13 changes: 9 additions & 4 deletions testcontainers/clickhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,16 @@ class ClickHouseContainer(DbContainer):
-------
The example spins up a ClickHouse database and connects to it
using the :code:`clickhouse-driver`.
::

with ClickHouseContainer("clickhouse/clickhouse-server:21.8") as clickhouse:
with clickhouse_driver.Client.from_url(self.get_connection_url()) as client:
result = client.execute("SELECT version()")
.. doctest::

>>> import clickhouse_driver
>>> from testcontainers.clickhouse import ClickHouseContainer

>>> with ClickHouseContainer("clickhouse/clickhouse-server:21.8") as clickhouse:
... client = clickhouse_driver.Client.from_url(clickhouse.get_connection_url())
... client.execute("select 'working'")
[('working',)]
"""

CLICKHOUSE_USER = os.environ.get("CLICKHOUSE_USER", "test")
Expand Down
12 changes: 9 additions & 3 deletions testcontainers/elasticsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,16 @@ class ElasticSearchContainer(DockerContainer):

Example
-------
::
.. doctest::

with ElasticSearchContainer() as es:
connection_url = es.get_url()
>>> import json
>>> import urllib
>>> from testcontainers.elasticsearch import ElasticSearchContainer

>>> with ElasticSearchContainer(f'elasticsearch:8.3.3') as es:
... resp = urllib.request.urlopen(es.get_url())
... json.loads(resp.read().decode())['version']['number']
'8.3.3'
"""

def __init__(self, image="elasticsearch", port_to_expose=9200, **kwargs):
Expand Down
12 changes: 12 additions & 0 deletions testcontainers/kafka.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@


class KafkaContainer(DockerContainer):
"""
Kafka container.

Example
-------
.. doctest::

>>> from testcontainers.kafka import KafkaContainer

>>> with KafkaContainer() as kafka:
... connection = kafka.get_bootstrap_server()
"""
KAFKA_PORT = 9093
TC_START_SCRIPT = '/tc-start.sh'

Expand Down
8 changes: 5 additions & 3 deletions testcontainers/keycloak.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ class KeycloakContainer(DockerContainer):

Example
-------
::
.. doctest::

with KeycloakContainer() as kc:
keycloak: KeycloakAdmin = kc.get_client()
>>> from testcontainers.keycloak import KeycloakContainer

>>> with KeycloakContainer() as kc:
... keycloak = kc.get_client()
"""
KEYCLOAK_USER = os.environ.get("KEYCLOAK_USER", "test")
KEYCLOAK_PASSWORD = os.environ.get("KEYCLOAK_PASSWORD", "test")
Expand Down
15 changes: 11 additions & 4 deletions testcontainers/localstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ class LocalStackContainer(DockerContainer):

Example
-------
.. doctest::

>>> from testcontainers.localstack import LocalStackContainer

>>> with LocalStackContainer(image="localstack/localstack:0.11.4") as localstack:
... localstack.with_services("dynamodb", "lambda")
... dynamo_endpoint = localstack.get_url()
<testcontainers.localstack.LocalStackContainer object at 0x...>

The endpoint can be used to create a client with the boto3 library:
::
localstack = LocalStackContainer(image="localstack/localstack:0.11.4")
localstack.with_services("dynamodb", "lambda")
localstack.start()
dynamo_endpoint = localstack.get_url()

dynamo_client = boto3.client("dynamodb", endpoint_url=dynamo_endpoint)
scan_result = dynamo_client.scan(TableName='foo')
# Do something with the scan result
Expand Down
44 changes: 22 additions & 22 deletions testcontainers/mongodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,29 @@ class MongoDbContainer(DbContainer):

Example
-------
::
.. doctest::

with MongoDbContainer("mongo:latest") as mongo:
db = mongo.get_connection_client().test
# Insert a database entry
result = db.restaurants.insert_one(
{
"address": {
"street": "2 Avenue",
"zipcode": "10075",
"building": "1480",
"coord": [-73.9557413, 40.7720266]
},
"borough": "Manhattan",
"cuisine": "Italian",
"name": "Vella",
"restaurant_id": "41704620"
}
)
# Find the restaurant document
cursor = db.restaurants.find({"borough": "Manhattan"})
for document in cursor:
# Do something interesting with the document
>>> from testcontainers.mongodb import MongoDbContainer

>>> with MongoDbContainer("mongo:latest") as mongo:
... db = mongo.get_connection_client().test
... # Insert a database entry
... result = db.restaurants.insert_one(
... {
... "address": {
... "street": "2 Avenue",
... "zipcode": "10075",
... "building": "1480",
... "coord": [-73.9557413, 40.7720266]
... },
... "borough": "Manhattan",
... "cuisine": "Italian",
... "name": "Vella",
... "restaurant_id": "41704620"
... }
... )
... # Find the restaurant document
... cursor = db.restaurants.find({"borough": "Manhattan"})
"""
MONGO_INITDB_ROOT_USERNAME = os.environ.get("MONGO_INITDB_ROOT_USERNAME", "test")
MONGO_INITDB_ROOT_PASSWORD = os.environ.get("MONGO_INITDB_ROOT_PASSWORD", "test")
Expand Down
11 changes: 7 additions & 4 deletions testcontainers/mssql.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ class SqlServerContainer(DbContainer):

Example
-------
::
.. doctest::

with SqlServerContainer() as mssql:
e = sqlalchemy.create_engine(mssql.get_connection_url())
result = e.execute("select @@VERSION")
>>> import sqlalchemy
>>> from testcontainers.mssql import SqlServerContainer

>>> with SqlServerContainer() as mssql:
... e = sqlalchemy.create_engine(mssql.get_connection_url())
... result = e.execute("select @@VERSION")

Notes
-----
Expand Down
13 changes: 8 additions & 5 deletions testcontainers/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ class MySqlContainer(DbContainer):
in the constructor. Alternatively, you may use the :code:`get_connection_url()` method which
returns a sqlalchemy-compatible url in format
:code:`dialect+driver://username:password@host:port/database`.
::
.. doctest::

with MySqlContainer('mysql:5.7.17') as mysql:
e = sqlalchemy.create_engine(mysql.get_connection_url())
result = e.execute("select version()")
version, = result.fetchone()
>>> import sqlalchemy
>>> from testcontainers.mysql import MySqlContainer

>>> with MySqlContainer('mysql:5.7.17') as mysql:
... e = sqlalchemy.create_engine(mysql.get_connection_url())
... result = e.execute("select version()")
... version, = result.fetchone()
"""

def __init__(self,
Expand Down
14 changes: 8 additions & 6 deletions testcontainers/neo4j.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ class Neo4jContainer(DbContainer):

Example
-------
::
with Neo4jContainer() as neo4j:
with neo4j.get_driver() as driver:
with driver.session() as session:
result = session.run("MATCH (n) RETURN n LIMIT 1")
record = result.single()
.. doctest::

>>> from testcontainers.neo4j import Neo4jContainer

>>> with Neo4jContainer() as neo4j, \
neo4j.get_driver() as driver, \
driver.session() as session:
... result = session.run("MATCH (n) RETURN n LIMIT 1")
... record = result.single()
"""

# The official image requires a change of password on startup.
Expand Down
Loading