Skip to content

Commit a6bdf0e

Browse files
feat(main): New Testcontainers Python Docs Site (#822)
# Hello all! I've been working on getting a new and improved docs site for Testcontainers Python. This docs site aligns it with Testcontainers Java/Go/.NET/Node which will hopefully help users onboard and adopt Testcontainers more easily. ![Screenshot 2025-06-04 at 5 03 17 PM](https://github.com/user-attachments/assets/a1ce37a2-dfd7-40f8-8a62-7d169a22a069) Testing fork deploys can be seen here, I'm also lining up the official builds to live on the python.testcontainers.org name space! 👀 https://exquisite-dusk-036c28.netlify.app/ ## Why? We (Docker) want to support the Python community! A big improvement opportunity I saw was the current docs site compared to some of the other languages. Adopting the same template and builds will help keep use inline with the other and hopefully make Testcontainers Python easier to adopt by providing a starting point with more guide style content. ## Usage and Details The old Sphinx site has been left untouched for now (TBD by the community if it's provided value imo). This is a large change for writing documentation on the lib. There is now a `/docs` folder filler with markdown files rather then being powered only by code comments. The left hand navigation is controlled by a new yml file on the root of the project called `mkdocs.yml`. Rather then using Sphinx to parse code comments, with mkdocs you can include example python files to go with the documentation. I've created community module usage examples beside their implementation called `example_basic.py` but people can make other example files in the source as well. The linter is ignoring files with `example_` in them to ease builds for the docs purposes (and missing dependencies that may not matter). In the documentation site you can them import your examples via ```text # MinIO ........ ## Usage example <!--codeinclude--> [Creating a MinIO container](../../modules/minio/example_basic.py) <!--/codeinclude--> ``` Content was largely generated by reading the source code with an editing pass from one of Docker's technical writers. ## Running / Editing the Docs Site Locally A new Testcontainer python docs Dockerfile lives in the root of the project which handles the docssite specific dependencies. The container will build and serve the site for you. `make serve-docs` ## How Documentation Will Deploy It's Netlify powered. We can configure it to do preview deploys per PR and deploy a new site on merge to main. Unfortunately Netlify doesn't support Poetry so to keep the builds simple there is a requirements.txt for explicitly the docs site dependency. ## The Contents of the New Documentation As mentioned briefly in the opening we used AI to help generate the content of the site by reading the source code, myself and Arthur also did some human passes to ensure things read well, but clearly more help from people ensuring the accuracy will come over time. Once the new docs site is merged into main and hosting is fully working **I think we should post in the community slack and ask for feedback**, the two docs sites will run concurrently before officially launching (replacing) the current docs site. --------- Co-authored-by: ArthurFlag <[email protected]>
1 parent 632e5f4 commit a6bdf0e

File tree

142 files changed

+10730
-48
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+10730
-48
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,6 @@ venv
7272
.python-version
7373
.env
7474
.github-token
75+
76+
# docs build
77+
site/

Dockerfile.docs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM python:3.11-slim
2+
3+
RUN pip install poetry
4+
5+
WORKDIR /docs

Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,39 @@ clean-all: clean ## Remove all generated files and reset the local virtual envir
6868
.PHONY: help
6969
help: ## Display command usage
7070
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
71+
72+
## --------------------------------------
73+
74+
DOCS_CONTAINER=mkdocs-container
75+
DOCS_IMAGE=mkdocs-poetry
76+
DOCS_DOCKERFILE := Dockerfile.docs
77+
78+
.PHONY: clean-docs
79+
clean-docs:
80+
@echo "Destroying docs"
81+
@if docker ps -a --format '{{.Names}}' | grep -q '^$(DOCS_CONTAINER)$$'; then \
82+
docker rm -f $(DOCS_CONTAINER); \
83+
fi
84+
@if docker images -q $(DOCS_IMAGE) | grep -q .; then \
85+
docker rmi $(DOCS_IMAGE); \
86+
fi
87+
88+
.PHONY: docs-ensure-image
89+
docs-ensure-image:
90+
@if [ -z "$$(docker images -q $(DOCS_IMAGE))" ]; then \
91+
docker build -f $(DOCS_DOCKERFILE) -t $(DOCS_IMAGE) . ; \
92+
fi
93+
94+
.PHONY: serve-docs
95+
serve-docs: docs-ensure-image
96+
docker run --rm --name $(DOCS_CONTAINER) -it -p 8000:8000 \
97+
-v $(PWD):/testcontainers-go \
98+
-w /testcontainers-go \
99+
$(DOCS_IMAGE) bash -c "\
100+
cd docs && poetry install --no-root && \
101+
poetry run mkdocs serve -f ../mkdocs.yml -a 0.0.0.0:8000"
102+
103+
# Needed if dependencies are added to the docs site
104+
.PHONY: export-docs-deps
105+
export-docs-deps:
106+
cd docs && poetry export --without-hashes --output requirements.txt

docs/_headers

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/search/search_index.json
2+
Access-Control-Allow-Origin: *

docs/_redirects

Whitespace-only changes.

docs/contributing.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Contributing to `testcontainers-python`
2+
3+
Welcome to the `testcontainers-python` community!
4+
This should give you an idea about how we build, test and release `testcontainers-python`!
5+
6+
Highly recommended to read this document thoroughly to understand what we're working on right now
7+
and what our priorities are before you are trying to contribute something.
8+
9+
This will greatly increase your chances of getting prompt replies as the maintainers are volunteers themselves.
10+
11+
## Before you begin
12+
13+
We recommend following these steps:
14+
15+
1. Finish reading this document.
16+
2. Read the [recently updated issues](https://github.com/testcontainers/testcontainers-python/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc){:target="\_blank"}
17+
3. Look for existing issues on the subject you are interested in - we do our best to label everything correctly
18+
19+
## Local development
20+
21+
### Pre-Requisites
22+
23+
You need to have the following tools available to you:
24+
25+
- `make` - You'll need a GNU Make for common developer activities
26+
- `poetry` - This is the primary package manager for the project
27+
- `pyenv` **Recommended**: For installing python versions for your system.
28+
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`.
29+
30+
### Build and test
31+
32+
- Run `make install` to get `poetry` to install all dependencies and set up `pre-commit`
33+
- **Recommended**: Run `make` or `make help` to see other commands available to you.
34+
- After this, you should have a working virtual environment and proceed with writing code with your favorite IDE
35+
- **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
36+
- You can also run `make lint` to run the `pre-commit` for the entire codebase.
37+
38+
## Adding new modules
39+
40+
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.
41+
Once you've talked to the maintainers (we do our best to reply!) then you can proceed with contributing the new container.
42+
43+
!!!WARNING
44+
45+
Please raise an issue before you try to contribute a new container! It helps maintainersunderstand your use-case and motivation.
46+
This way we can keep pull requests forced on the "how", not the "why"! :pray:
47+
It also gives maintainers a chance to give you last-minute guidance on caveats orexpectations, particularly with
48+
new extra dependencies and how to manage them.
49+
50+
### Module documentation
51+
52+
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.
53+
54+
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"}.
55+
56+
!!! important
57+
58+
Make sure to add your new module to the sidebar nav in the `mkdocs.yml`
59+
60+
## Raising issues
61+
62+
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.
63+
Try to look through the existing issues before you raise a new one.
64+
65+
## Releasing versions
66+
67+
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"}.
68+
This takes care of:
69+
70+
- Detecting the next version, based on the commits that landed on `main`
71+
- When a Release PR has been merged
72+
- Create a GitHub Release with the CHANGELOG included
73+
- Update the [CHANGELOG](https://github.com/testcontainers/testcontainers-python/blob/main/CHANGELOG.md){:target="\_blank"}, similar to the GitHub Release
74+
- Release to PyPI via a [trusted publisher](https://docs.pypi.org/trusted-publishers/using-a-publisher/){:target="\_blank"}
75+
- Automatically script updates in files where it's needed instead of hand-crafting it (i.e. in `pyproject.toml`)
76+
77+
!!!DANGER
78+
79+
Community modules are supported on a best-effort basis and for maintenance reasons, any change to them
80+
is only covered under minor and patch changes.
81+
Community modules changes DO NOT contribute to major version changes!
82+
If your community module container was broken by a minor or patch version change, check out the change logs!
83+
84+
## Documentation contributions
85+
86+
The _Testcontainers for Go_ documentation is a static site built with [MkDocs](https://www.mkdocs.org/){:target="\_blank"}.
87+
We use the [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/){:target="\_blank"} theme, which offers a number of useful extensions to MkDocs.
88+
89+
We publish our documentation using Netlify.
90+
91+
### Adding code snippets
92+
93+
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:
94+
95+
> &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/>
96+
97+
Where each title snippet in the same `codeinclude` block would represent a new tab
98+
in the snippet, and each `targeting_expression` would be:
99+
100+
- `block:someString` or
101+
- `inside_block:someString`
102+
103+
Please refer to the [codeinclude plugin documentation](https://github.com/rnorth/mkdocs-codeinclude-plugin){:target="\_blank"} for more information.
104+
105+
### Previewing rendered content
106+
107+
From the root directory of the repository, you can use the following command to build and serve the documentation locally:
108+
109+
```shell
110+
make serve-docs
111+
```
112+
113+
It will use a Docker container to install the required dependencies and start a local server at `http://localhost:8000`.
114+
115+
Once finished, you can destroy the container with the following command:
116+
117+
```shell
118+
make clean-docs
119+
```
120+
121+
### PR preview deployments
122+
123+
Note that documentation for pull requests will automatically be published by Netlify as 'deploy previews'.
124+
These deployment previews can be accessed via the `deploy/netlify` check that appears for each pull request.
125+
126+
Please check the GitHub comment Netlify posts on the PR for the URL to the deployment preview.

docs/css/extra.css

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
h1, h2, h3, h4, h5, h6 {
2+
font-family: 'Rubik', sans-serif;
3+
}
4+
5+
[data-md-color-scheme="testcontainers"] {
6+
--md-primary-fg-color: #00bac2;
7+
--md-accent-fg-color: #361E5B;
8+
--md-typeset-a-color: #0C94AA;
9+
--md-primary-fg-color--dark: #291A3F;
10+
--md-default-fg-color--lightest: #F2F4FE;
11+
--md-footer-fg-color: #361E5B;
12+
--md-footer-fg-color--light: #746C8F;
13+
--md-footer-fg-color--lighter: #C3BEDE;
14+
--md-footer-bg-color: #F7F9FD;
15+
--md-footer-bg-color--dark: #F7F9FD;
16+
}
17+
18+
.card-grid {
19+
display: grid;
20+
gap: 10px;
21+
}
22+
23+
.tc-version {
24+
font-size: 1.1em;
25+
text-align: center;
26+
margin: 0;
27+
}
28+
29+
@media (min-width: 680px) {
30+
.card-grid {
31+
grid-template-columns: repeat(3, 1fr);
32+
}
33+
}
34+
35+
body .card-grid-item {
36+
display: flex;
37+
align-items: center;
38+
gap: 20px;
39+
border: 1px solid #C3BEDE;
40+
border-radius: 6px;
41+
padding: 16px;
42+
font-weight: 600;
43+
color: #9991B5;
44+
background: #F2F4FE;
45+
}
46+
47+
body .card-grid-item:hover,
48+
body .card-grid-item:focus {
49+
color: #9991B5;
50+
}
51+
52+
.card-grid-item[href] {
53+
color: var(--md-primary-fg-color--dark);
54+
background: transparent;
55+
}
56+
57+
.card-grid-item[href]:hover,
58+
.card-grid-item[href]:focus {
59+
background: #F2F4FE;
60+
color: var(--md-primary-fg-color--dark);
61+
}
62+
63+
.community-callout-wrapper {
64+
padding: 30px 10px 0 10px;
65+
}
66+
67+
.community-callout {
68+
color: #F2F4FE;
69+
background: linear-gradient(10.88deg, rgba(102, 56, 242, 0.4) 9.56%, #6638F2 100%), #291A3F;
70+
box-shadow: 0px 20px 45px rgba(#9991B5, 0.75);
71+
border-radius: 10px;
72+
padding: 20px;
73+
}
74+
75+
.community-callout h2 {
76+
font-size: 1.15em;
77+
margin: 0 0 20px 0;
78+
color: #F2F4FE;
79+
text-align: center;
80+
}
81+
82+
.community-callout ul {
83+
list-style: none;
84+
padding: 0;
85+
display: flex;
86+
justify-content: space-between;
87+
gap: 10px;
88+
margin-top: 20px;
89+
margin-bottom: 0;
90+
}
91+
92+
.community-callout a {
93+
transition: opacity 0.2s ease;
94+
}
95+
96+
.community-callout a:hover {
97+
opacity: 0.5;
98+
}
99+
100+
.community-callout a img {
101+
height: 1.75em;
102+
width: auto;
103+
aspect-ratio: 1;
104+
}
105+
106+
@media (min-width: 1220px) {
107+
.community-callout-wrapper {
108+
padding: 40px 0 0;
109+
}
110+
111+
.community-callout h2 {
112+
font-size: 1.25em;
113+
}
114+
115+
.community-callout a img {
116+
height: 2em;
117+
}
118+
}
119+
120+
@media (min-width: 1600px) {
121+
.community-callout h2 {
122+
font-size: 1.15em;
123+
}
124+
125+
.community-callout a img {
126+
height: 1.75em;
127+
}
128+
}
129+
130+
.md-typeset__table {
131+
min-width: 100%;
132+
}
133+
134+
.md-typeset table:not([class]) {
135+
display: table;
136+
}

0 commit comments

Comments
 (0)