How to Generate a Mock devcontainer.json Config in Python
Build a reproducible devcontainer.json file with Python, composing name, image, extensions, forwarded ports, and a post-create command as a dict.
Python code
47 linesimport json
from pathlib import Path
def create_devcontainer_config(
image: str = "mcr.microsoft.com/devcontainers/python:3.11",
name: str = "python-dev-container",
ports: list[int] | None = None,
post_create: str | None = None,
) -> dict:
config = {
"name": name,
"image": image,
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
]
}
},
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.testing.pytestEnabled": True,
},
}
if ports:
config["forwardPorts"] = ports
if post_create:
config["postCreateCommand"] = post_create
return config
if __name__ == "__main__":
config = create_devcontainer_config(
ports=[8000, 8501],
post_create="pip install -r requirements.txt",
)
output_path = Path(".devcontainer/devcontainer.json")
output_path.parent.mkdir(exist_ok=True)
output_path.write_text(json.dumps(config, indent=2))
print(f"Mock devcontainer config written to: {output_path}")
print(json.dumps(config, indent=2))
Output
Mock devcontainer config written to: .devcontainer/devcontainer.json
{
"name": "python-dev-container",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter"
]
}
},
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.testing.pytestEnabled": true
},
"forwardPorts": [
8000,
8501
],
"postCreateCommand": "pip install -r requirements.txt"
}
How it works
The function builds a plain dictionary that matches the devcontainer.json schema, with optional keys added only when values are provided. Using Path.mkdir(exist_ok=True) avoids errors when the .devcontainer directory already exists. json.dumps(config, indent=2) produces a human-readable file that tools like VS Code read on startup. Generating the config programmatically keeps the file consistent across teams and lets you branch on environment variables. Because the script only uses the standard library, it runs anywhere Python is installed.
Common mistakes
- Forgetting to create the .devcontainer directory before writing the file
- Adding empty forwardPorts lists or empty strings as postCreateCommand
- Overwriting a hand-edited devcontainer.json with a mock config
- Using single quotes in JSON strings, which breaks the format
Variations
- Read base config from a JSON file and merge overrides with dict.update
- Use Jinja2 templates to fill environment-specific values
Real-world use cases
- Auto-generating devcontainers for new microservices in a monorepo with different ports and dependencies.
- Creating identical remote development environments for a distributed team across macOS, Windows, and Linux.
- Baking a standardization config into an internal CLI tool that scaffolds Python projects.
Sponsored
More from Modern tooling
- Build a Recipe Runner Mock in Python easy
- Build a Textual TUI App Skeleton in Python easy
- Configure ruff linter rules in pyproject.toml with Python easy
- Data Conversion Helper Functions in Python easy
- How to Bind and Mock structlog Context in Python medium
- How to Build a Chainable Filter Helper in Python easy
Keep learning
Related tutorials and quizzes for this topic.