From 43e7b6a8d21b9ac9b7881889325ef951186b60c6 Mon Sep 17 00:00:00 2001 From: Roy Moore Date: Sun, 18 Aug 2024 06:29:26 +0000 Subject: [PATCH 1/4] docs: Add a more advance usecase documentation for ServerContainer --- modules/generic/README.rst | 34 +++++++++++++++++++ .../tests/samples/advance_1/Dockerfile | 11 ++++++ .../tests/samples/advance_1/app/__init__.py | 0 .../tests/samples/advance_1/app/main.py | 30 ++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 modules/generic/tests/samples/advance_1/Dockerfile create mode 100644 modules/generic/tests/samples/advance_1/app/__init__.py create mode 100644 modules/generic/tests/samples/advance_1/app/main.py diff --git a/modules/generic/README.rst b/modules/generic/README.rst index 7e12da700..bbcf5b473 100644 --- a/modules/generic/README.rst +++ b/modules/generic/README.rst @@ -18,3 +18,37 @@ FastAPI container that is using :code:`ServerContainer` ... response = client.get("/") ... assert response.status_code == 200 ... assert response.json() == {"Status": "Working"} + +A more advance use-case, where we are using a FastAPI container that is using Redis container: + +.. doctest:: + + >>> import httpx + >>> from testcontainers.generic import ServerContainer + >>> from testcontainers.redis import RedisContainer + >>> from testcontainers.core.waiting_utils import wait_for_logs + + >>> with RedisContainer() as redis: + ... redis_port = redis.get_exposed_port(redis.port) + ... redis_host = redis.get_container_host_ip() + + ... with DockerImage(path="./modules/generic/tests/samples/advance_1", tag="advance-1:latest") as image: + ... web_server = ServerContainer(port=80, image=image) + ... web_server.with_env(key="REDIS_HOST", value=redis_host) + ... web_server.with_env(key="REDIS_PORT", value=redis_port) + + ... with web_server: + ... web_server.get_api_url = lambda: web_server._create_connection_url() + "/api/v1/" + ... client = web_server.get_client() + + ... response = client.get("/") + ... assert response.status_code == 200, "Server request failed" + ... assert response.json() == {"Status": "ok"} + + ... test_data = {"key": "test_key", "value": "test_value"} + ... response = client.post("/set", json=test_data) + ... assert response.status_code == 200, "Failed to set data" + + ... response = client.get(f"/get/{test_data['key']}") + ... assert response.status_code == 200. "Failed to get data" + ... assert response.json() == {"key": test_data["key"], "value": test_data["value"]} diff --git a/modules/generic/tests/samples/advance_1/Dockerfile b/modules/generic/tests/samples/advance_1/Dockerfile new file mode 100644 index 000000000..2c9d9ba14 --- /dev/null +++ b/modules/generic/tests/samples/advance_1/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9 + +WORKDIR /app + +RUN pip install fastapi[standard] redis + +COPY ./app /app + +EXPOSE 80 + +CMD ["fastapi", "run", "main.py", "--port", "80"] diff --git a/modules/generic/tests/samples/advance_1/app/__init__.py b/modules/generic/tests/samples/advance_1/app/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generic/tests/samples/advance_1/app/main.py b/modules/generic/tests/samples/advance_1/app/main.py new file mode 100644 index 000000000..8fe9df5cf --- /dev/null +++ b/modules/generic/tests/samples/advance_1/app/main.py @@ -0,0 +1,30 @@ +# This app will use redis to store given key-value pairs. + +import os +import redis + +from fastapi import FastAPI + + +app = FastAPI() + +# connect to redis +redis_host = os.getenv("REDIS_HOST") +redis_port = os.getenv("REDIS_PORT") +redis_client = redis.Redis(host=redis_host, port=redis_port) + + +@app.get("/") +def health_check(): + return {"status": "ok"} + + +@app.get("/get/{key}") +def read_item(key: str): + return {key: redis_client.get(key)} + + +@app.post("/set") +def create_item(key: str, value: str): + redis_client.set(key, value) + return {key: value} From 5170c5b05e2fa1eadd628babd8874f3edbdc7e33 Mon Sep 17 00:00:00 2001 From: Roy Moore Date: Sun, 18 Aug 2024 06:44:36 +0000 Subject: [PATCH 2/4] fix order and removed unused imports --- modules/generic/README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/generic/README.rst b/modules/generic/README.rst index bbcf5b473..f9daf8410 100644 --- a/modules/generic/README.rst +++ b/modules/generic/README.rst @@ -23,10 +23,8 @@ A more advance use-case, where we are using a FastAPI container that is using Re .. doctest:: - >>> import httpx - >>> from testcontainers.generic import ServerContainer >>> from testcontainers.redis import RedisContainer - >>> from testcontainers.core.waiting_utils import wait_for_logs + >>> from testcontainers.generic import ServerContainer >>> with RedisContainer() as redis: ... redis_port = redis.get_exposed_port(redis.port) From f0a4fe9e7ff760ba38a1a88af0e87e0b76233a30 Mon Sep 17 00:00:00 2001 From: Roy Moore Date: Sun, 18 Aug 2024 06:51:11 +0000 Subject: [PATCH 3/4] added redis as dep for generic --- poetry.lock | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bf8872cb5..e0d17ea6d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4639,7 +4639,7 @@ cockroachdb = [] cosmosdb = ["azure-cosmos"] db2 = ["ibm_db_sa", "sqlalchemy"] elasticsearch = [] -generic = ["httpx"] +generic = ["httpx", "redis"] google = ["google-cloud-datastore", "google-cloud-pubsub"] influxdb = ["influxdb", "influxdb-client"] k3s = ["kubernetes", "pyyaml"] @@ -4677,4 +4677,4 @@ weaviate = ["weaviate-client"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "69d30cc8cd59a8aa0d019c42b1f171e449dabf6959828160d11f3084c5a03f7f" +content-hash = "7ffcf39257e1ac79d951b7ccb2cdb972beaaef35d0cd1f722d2964c5bdced674" diff --git a/pyproject.toml b/pyproject.toml index 435525106..fab90eb9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,7 +129,7 @@ cosmosdb = ["azure-cosmos"] cockroachdb = [] db2 = ["sqlalchemy", "ibm_db_sa"] elasticsearch = [] -generic = ["httpx"] +generic = ["httpx", "redis"] # The advance doctests for ServerContainer require redis test_module_import = ["httpx"] google = ["google-cloud-pubsub", "google-cloud-datastore"] influxdb = ["influxdb", "influxdb-client"] From f31a4a00a7fbfba0688c14275c8ddd3bf17f32e1 Mon Sep 17 00:00:00 2001 From: Roy Moore Date: Sun, 18 Aug 2024 19:43:34 +0000 Subject: [PATCH 4/4] fix --- modules/generic/README.rst | 14 +++++++------- .../generic/tests/samples/advance_1/app/main.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/generic/README.rst b/modules/generic/README.rst index f9daf8410..4497ec922 100644 --- a/modules/generic/README.rst +++ b/modules/generic/README.rst @@ -27,16 +27,16 @@ A more advance use-case, where we are using a FastAPI container that is using Re >>> from testcontainers.generic import ServerContainer >>> with RedisContainer() as redis: - ... redis_port = redis.get_exposed_port(redis.port) - ... redis_host = redis.get_container_host_ip() + ... redis_container_port = redis.port + ... redis_container_ip_address = redis.get_docker_client().bridge_ip(redis._container.id) ... with DockerImage(path="./modules/generic/tests/samples/advance_1", tag="advance-1:latest") as image: ... web_server = ServerContainer(port=80, image=image) - ... web_server.with_env(key="REDIS_HOST", value=redis_host) - ... web_server.with_env(key="REDIS_PORT", value=redis_port) + ... web_server.with_env(key="REDIS_HOST", value=redis_container_ip_address) + ... web_server.with_env(key="REDIS_PORT", value=redis_container_port) ... with web_server: - ... web_server.get_api_url = lambda: web_server._create_connection_url() + "/api/v1/" + ... web_server.get_api_url = lambda: web_server._create_connection_url() ... client = web_server.get_client() ... response = client.get("/") @@ -44,9 +44,9 @@ A more advance use-case, where we are using a FastAPI container that is using Re ... assert response.json() == {"Status": "ok"} ... test_data = {"key": "test_key", "value": "test_value"} - ... response = client.post("/set", json=test_data) + ... response = client.post("/set", params=test_data) ... assert response.status_code == 200, "Failed to set data" ... response = client.get(f"/get/{test_data['key']}") - ... assert response.status_code == 200. "Failed to get data" + ... assert response.status_code == 200, "Failed to get data" ... assert response.json() == {"key": test_data["key"], "value": test_data["value"]} diff --git a/modules/generic/tests/samples/advance_1/app/main.py b/modules/generic/tests/samples/advance_1/app/main.py index 8fe9df5cf..27cc6bbec 100644 --- a/modules/generic/tests/samples/advance_1/app/main.py +++ b/modules/generic/tests/samples/advance_1/app/main.py @@ -8,10 +8,10 @@ app = FastAPI() -# connect to redis redis_host = os.getenv("REDIS_HOST") redis_port = os.getenv("REDIS_PORT") redis_client = redis.Redis(host=redis_host, port=redis_port) +redis_client.ping() @app.get("/")