Skip to content

feat(main): New Testcontainers Python Docs Site #822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,6 @@ venv
.python-version
.env
.github-token

# docs build
site/
5 changes: 5 additions & 0 deletions Dockerfile.docs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.11-slim

RUN pip install poetry

WORKDIR /docs
36 changes: 36 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,39 @@ clean-all: clean ## Remove all generated files and reset the local virtual envir
.PHONY: help
help: ## Display command usage
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

## --------------------------------------

DOCS_CONTAINER=mkdocs-container
DOCS_IMAGE=mkdocs-poetry
DOCS_DOCKERFILE := Dockerfile.docs

.PHONY: clean-docs
clean-docs:
@echo "Destroying docs"
@if docker ps -a --format '{{.Names}}' | grep -q '^$(DOCS_CONTAINER)$$'; then \
docker rm -f $(DOCS_CONTAINER); \
fi
@if docker images -q $(DOCS_IMAGE) | grep -q .; then \
docker rmi $(DOCS_IMAGE); \
fi

.PHONY: docs-ensure-image
docs-ensure-image:
@if [ -z "$$(docker images -q $(DOCS_IMAGE))" ]; then \
docker build -f $(DOCS_DOCKERFILE) -t $(DOCS_IMAGE) . ; \
fi

.PHONY: serve-docs
serve-docs: docs-ensure-image
docker run --rm --name $(DOCS_CONTAINER) -it -p 8000:8000 \
-v $(PWD):/testcontainers-go \
-w /testcontainers-go \
$(DOCS_IMAGE) bash -c "\
cd docs && poetry install --no-root && \
poetry run mkdocs serve -f ../mkdocs.yml -a 0.0.0.0:8000"

# Needed if dependencies are added to the docs site
.PHONY: export-docs-deps
export-docs-deps:
cd docs && poetry export --without-hashes --output requirements.txt
9 changes: 9 additions & 0 deletions core/tests/test_core_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@
from testcontainers.core.waiting_utils import wait_container_is_ready

from testcontainers.registry import DockerRegistryContainer
from testcontainers.core.utils import is_mac


@pytest.mark.skipif(
is_mac(),
reason="Docker Desktop on macOS does not support insecure private registries without daemon reconfiguration",
)
def test_missing_on_private_registry(monkeypatch):
username = "user"
password = "pass"
Expand All @@ -41,6 +46,10 @@ def test_missing_on_private_registry(monkeypatch):
wait_container_is_ready(test_container)


@pytest.mark.skipif(
is_mac(),
reason="Docker Desktop on macOS does not support local insecure registries over HTTP without modifying daemon settings",
)
@pytest.mark.parametrize(
"image,tag,username,password",
[
Expand Down
8 changes: 8 additions & 0 deletions core/tests/test_docker_in_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from testcontainers.core.container import DockerContainer
from testcontainers.core.docker_client import DockerClient, LOGGER
from testcontainers.core.utils import inside_container
from testcontainers.core.utils import is_mac
from testcontainers.core.waiting_utils import wait_for_logs


Expand All @@ -36,6 +37,7 @@ def _wait_for_dind_return_ip(client, dind):
return docker_host_ip


@pytest.mark.skipif(is_mac(), reason="Docker socket forwarding (socat) is unsupported on Docker Desktop for macOS")
def test_wait_for_logs_docker_in_docker():
# real dind isn't possible (AFAIK) in CI
# forwarding the socket to a container port is at least somewhat the same
Expand Down Expand Up @@ -64,6 +66,9 @@ def test_wait_for_logs_docker_in_docker():
not_really_dind.remove()


@pytest.mark.skipif(
is_mac(), reason="Bridge networking and Docker socket forwarding are not supported on Docker Desktop for macOS"
)
def test_dind_inherits_network():
client = DockerClient()
try:
Expand Down Expand Up @@ -158,6 +163,9 @@ def test_find_host_network_in_dood() -> None:
assert DockerClient().find_host_network() == os.environ[EXPECTED_NETWORK_VAR]


@pytest.mark.skipif(
is_mac(), reason="Docker socket mounting and container networking do not work reliably on Docker Desktop for macOS"
)
@pytest.mark.skipif(not Path(tcc.ryuk_docker_socket).exists(), reason="No docker socket available")
def test_dood(python_testcontainer_image: str) -> None:
"""
Expand Down
8 changes: 8 additions & 0 deletions core/tests/test_ryuk.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@
from testcontainers.core.config import testcontainers_config
from testcontainers.core.container import Reaper
from testcontainers.core.container import DockerContainer
from testcontainers.core.utils import is_mac
from testcontainers.core.waiting_utils import wait_for_logs


@pytest.mark.skipif(
is_mac(),
reason="Ryuk container reaping is unreliable on Docker Desktop for macOS due to VM-based container lifecycle handling",
)
@pytest.mark.inside_docker_check
def test_wait_for_reaper(monkeypatch: MonkeyPatch):
Reaper.delete_instance()
Expand Down Expand Up @@ -41,6 +46,9 @@ def test_wait_for_reaper(monkeypatch: MonkeyPatch):
Reaper.delete_instance()


@pytest.mark.skipif(
is_mac(), reason="Ryuk disabling behavior is unreliable on Docker Desktop for macOS due to Docker socket emulation"
)
@pytest.mark.inside_docker_check
def test_container_without_ryuk(monkeypatch: MonkeyPatch):
Reaper.delete_instance()
Expand Down
2 changes: 2 additions & 0 deletions docs/_headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/search/search_index.json
Access-Control-Allow-Origin: *
Empty file added docs/_redirects
Empty file.
126 changes: 126 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Contributing to `testcontainers-python`

Welcome to the `testcontainers-python` community!
This should give you an idea about how we build, test and release `testcontainers-python`!

Highly recommended to read this document thoroughly to understand what we're working on right now
and what our priorities are before you are trying to contribute something.

This will greatly increase your chances of getting prompt replies as the maintainers are volunteers themselves.

## Before you begin

We recommend following these steps:

1. Finish reading this document.
2. Read the [recently updated issues](https://github.com/testcontainers/testcontainers-python/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc){:target="\_blank"}
3. Look for existing issues on the subject you are interested in - we do our best to label everything correctly

## Local development

### Pre-Requisites

You need to have the following tools available to you:

- `make` - You'll need a GNU Make for common developer activities
- `poetry` - This is the primary package manager for the project
- `pyenv` **Recommended**: For installing python versions for your system.
Poetry infers the current latest version from what it can find on the `PATH` so you are still fine if you don't use `pyenv`.

### Build and test

- Run `make install` to get `poetry` to install all dependencies and set up `pre-commit`
- **Recommended**: Run `make` or `make help` to see other commands available to you.
- After this, you should have a working virtual environment and proceed with writing code with your favorite IDE
- **TIP**: You can run `make core/tests` or `make modules/<my-module>/tests` to run the tests specifically for that to speed up feedback cycles
- You can also run `make lint` to run the `pre-commit` for the entire codebase.

## Adding new modules

We have an [issue template](https://github.com/testcontainers/testcontainers-python/blob/main/.github/ISSUE_TEMPLATE/new-container.md){:target="\_blank"} for adding new module containers, please refer to that for more information.
Once you've talked to the maintainers (we do our best to reply!) then you can proceed with contributing the new container.

!!!WARNING

Please raise an issue before you try to contribute a new container! It helps maintainersunderstand your use-case and motivation.
This way we can keep pull requests forced on the "how", not the "why"! :pray:
It also gives maintainers a chance to give you last-minute guidance on caveats orexpectations, particularly with
new extra dependencies and how to manage them.

### Module documentation

Leave examples for others with your mew module such as `modules/<new_module>/basic_example.py`. You can create as many examples as you want.

Create a new `docs/modules/<new_module>.md` describing the basic use of the new container. There is a [starter template provided here](https://raw.githubusercontent.com/testcontainers/testcontainers-python/blob/main/docs/modules/template.md){:target="\_blank"}.

!!! important

Make sure to add your new module to the sidebar nav in the `mkdocs.yml`

## Raising issues

We have [Issue Templates](https://raw.githubusercontent.com/testcontainers/testcontainers-python/refs/heads/main/.github/ISSUE_TEMPLATE/new-container.md){:target="\_blank"} to cover most cases, please try to adhere to them, they will guide you through the process.
Try to look through the existing issues before you raise a new one.

## Releasing versions

We have automated Semantic Versioning and release via [release-please](https://github.com/testcontainers/testcontainers-python/blob/main/.github/workflows/release-please.yml){:target="\_blank"}.
This takes care of:

- Detecting the next version, based on the commits that landed on `main`
- When a Release PR has been merged
- Create a GitHub Release with the CHANGELOG included
- Update the [CHANGELOG](https://github.com/testcontainers/testcontainers-python/blob/main/CHANGELOG.md){:target="\_blank"}, similar to the GitHub Release
- Release to PyPI via a [trusted publisher](https://docs.pypi.org/trusted-publishers/using-a-publisher/){:target="\_blank"}
- Automatically script updates in files where it's needed instead of hand-crafting it (i.e. in `pyproject.toml`)

!!!DANGER

Community modules are supported on a best-effort basis and for maintenance reasons, any change to them
is only covered under minor and patch changes.
Community modules changes DO NOT contribute to major version changes!
If your community module container was broken by a minor or patch version change, check out the change logs!

## Documentation contributions

The _Testcontainers for Go_ documentation is a static site built with [MkDocs](https://www.mkdocs.org/){:target="\_blank"}.
We use the [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/){:target="\_blank"} theme, which offers a number of useful extensions to MkDocs.

We publish our documentation using Netlify.

### Adding code snippets

To include code snippets in the documentation, we use the [codeinclude plugin](https://github.com/rnorth/mkdocs-codeinclude-plugin){:target="\_blank"}, which uses the following syntax:

> &lt;!--codeinclude--&gt;<br/> > &#91;Human readable title for snippet&#93;(./relative_path_to_example_code.go) targeting_expression<br/> > &#91;Human readable title for snippet&#93;(./relative_path_to_example_code.go) targeting_expression<br/> > &lt;!--/codeinclude--&gt;<br/>

Where each title snippet in the same `codeinclude` block would represent a new tab
in the snippet, and each `targeting_expression` would be:

- `block:someString` or
- `inside_block:someString`

Please refer to the [codeinclude plugin documentation](https://github.com/rnorth/mkdocs-codeinclude-plugin){:target="\_blank"} for more information.

### Previewing rendered content

From the root directory of the repository, you can use the following command to build and serve the documentation locally:

```shell
make serve-docs
```

It will use a Docker container to install the required dependencies and start a local server at `http://localhost:8000`.

Once finished, you can destroy the container with the following command:

```shell
make clean-docs
```

### PR preview deployments

Note that documentation for pull requests will automatically be published by Netlify as 'deploy previews'.
These deployment previews can be accessed via the `deploy/netlify` check that appears for each pull request.

Please check the GitHub comment Netlify posts on the PR for the URL to the deployment preview.
Loading
Loading