Skip to content
Open
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
42 changes: 42 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Version control
.git
.gitignore

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# VS Code
.vscode/
*.code-workspace
17 changes: 17 additions & 0 deletions Dockerfile.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Use the official Python image as base
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Copy requirements first for better caching
COPY requirements.txt .

# Install dependencies
RUN pip install -r requirements.txt

# Copy the rest of the application
COPY . .

# Run tests by default
CMD ["pytest", "-v", "--cov=app", "tests/"]
153 changes: 132 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,132 @@
# Try Out Development Containers: Python

[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-python)
[![Tests](https://github.com/microsoft/vscode-remote-try-python/actions/workflows/tests.yml/badge.svg)](https://github.com/microsoft/vscode-remote-try-python/actions/workflows/tests.yml)

A **development container** is a running container with a well-defined tool/runtime stack and its prerequisites. You can try out development containers with **[GitHub Codespaces](https://github.com/features/codespaces)** or **[Visual Studio Code Dev Containers](https://aka.ms/vscode-remote/containers)**.

This is a sample project that lets you try out either option in a few easy steps. We have a variety of other [vscode-remote-try-*](https://github.com/search?q=org%3Amicrosoft+vscode-remote-try-&type=Repositories) sample projects, too.
This is a sample project that lets you try out either option in a few easy steps. We have a variety of other [vscode-remote-try-\*](https://github.com/search?q=org%3Amicrosoft+vscode-remote-try-&type=Repositories) sample projects, too.

> **Note:** If you already have a codespace or dev container, you can jump to the [Things to try](#things-to-try) section.
## Testing

This project includes comprehensive automated tests that verify both the Flask application functionality and Docker environment configuration.

### Testing Components

The test suite consists of two main parts:

1. **Application Tests** (`tests/test_app.py`)

- Validates Flask routes and responses
- Checks static file serving
- Verifies content types and status codes

2. **Docker Environment Tests** (`tests/test_docker_environment.py`)
- Verifies Python version and dependencies
- Checks container configuration
- Tests environment variables and paths
- Validates port availability and networking

### Running Tests in Docker (Recommended)

The most reliable way to run tests is using Docker, which ensures a consistent environment:

```bash
# Build the test image
docker build -t vscode-remote-test -f Dockerfile.test .

# Run tests with coverage report
docker run vscode-remote-test

# Run specific test file
docker run vscode-remote-test pytest -v tests/test_docker_environment.py

# Run tests with detailed output
docker run vscode-remote-test pytest -v --log-cli-level=INFO tests/
```

### Running Tests Locally

Before running tests locally, set up a Python virtual environment:

```bash
# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Run all tests
python -m pytest -v tests/

# Run tests with coverage report
python -m pytest --cov=app --cov-report=html tests/

# Run specific test file
python -m pytest -v tests/test_app.py

# Run tests in watch mode (auto-rerun on file changes)
python -m pytest -f -v tests/
```

### Test Coverage

The test suite verifies:

- Index route returns correct status code and content type
- Static files are served correctly
- Docker container environment configuration
- HTML content matches expectations

> **Note:** If you already have a codespace or dev container, you can jump to the [Things to try](#things-to-try) section.

## Setting up the development container

### GitHub Codespaces

Follow these steps to open this sample in a Codespace:

1. Click the **Code** drop-down menu.
2. Click on the **Codespaces** tab.
3. Click **Create codespace on main** .

For more information on creating your codespace, visit the [GitHub documentation](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/creating-a-codespace#creating-a-codespace).

## Testing

This project includes automated tests that can be run both locally and in the container.

### Running Tests in Container

```bash
# Install dependencies
pip install -r requirements.txt

# Run tests
python -m pytest tests/

# Run tests with coverage report
python -m pytest --cov=app tests/
```

### Test Coverage

The test suite verifies:

- Index route returns correct status code and content type
- Static files are served correctly
- Docker container environment configuration
- HTML content matches expectations

### Running Tests in Development

When developing new features, you can use the following command to run tests in watch mode:

```bash
python -m pytest -v tests/
```

### VS Code Dev Containers

If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-python) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
Expand All @@ -28,9 +137,9 @@ Follow these steps to open this sample in a container using the VS Code Dev Cont

2. To use this repository, you can either open the repository in an isolated Docker volume:

- Press <kbd>F1</kbd> and select the **Dev Containers: Try a Sample...** command.
- Choose the "Python" sample, wait for the container to start, and try things out!
> **Note:** Under the hood, this will use the **Dev Containers: Clone Repository in Container Volume...** command to clone the source code in a Docker volume instead of the local filesystem. [Volumes](https://docs.docker.com/storage/volumes/) are the preferred mechanism for persisting container data.
- Press <kbd>F1</kbd> and select the **Dev Containers: Try a Sample...** command.
- Choose the "Python" sample, wait for the container to start, and try things out!
> **Note:** Under the hood, this will use the **Dev Containers: Clone Repository in Container Volume...** command to clone the source code in a Docker volume instead of the local filesystem. [Volumes](https://docs.docker.com/storage/volumes/) are the preferred mechanism for persisting container data.

Or open a locally cloned copy of the code:

Expand All @@ -45,46 +154,48 @@ Once you have this sample opened, you'll be able to work with it like you would
Some things to try:

1. **Edit:**

- Open `app.py`
- Try adding some code and check out the language features.
- Make a spelling mistake and notice it is detected. The [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) extension was automatically installed because it is referenced in `.devcontainer/devcontainer.json`.
- Also notice that utilities like `pylint` and the [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) extension are installed. Tools are installed in the `mcr.microsoft.com/devcontainers/python` image and Dev Container settings and metadata are automatically picked up from [image labels](https://containers.dev/implementors/reference/#labels).

2. **Terminal:**

2. **Terminal:**
- Press <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>\`</kbd> to open a terminal window.
- Type `python -m flask run --port 9000 --no-debugger --no-reload` to run the app.
- The terminal will say your app is `Running on http://127.0.0.1:9000/`. Click on the link in the terminal to view your app running in the browser.
- Notice that the Python extension is already installed in the container since the `.devcontainer/devcontainer.json` lists `"ms-python.python"` as an extension to install automatically when the container is created.

> **Tip:** If you use this container outside of VS Code via `docker run` with `-p 9000`, you may need to append `--host 0.0.0.0` to the command above. The `-p` option "publishes" the port rather than forwarding it. It therefore will not work if the application only listens to localhost. The `forwardPorts` property in `devcontainer.json` does not have this limitation, but you can use `appPort` property instead if you want to mirror the `docker run` behavior.
- Press <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>\`</kbd> to open a terminal window.
- Type `python -m flask run --port 9000 --no-debugger --no-reload` to run the app.
- The terminal will say your app is `Running on http://127.0.0.1:9000/`. Click on the link in the terminal to view your app running in the browser.
- Notice that the Python extension is already installed in the container since the `.devcontainer/devcontainer.json` lists `"ms-python.python"` as an extension to install automatically when the container is created.

> **Tip:** If you use this container outside of VS Code via `docker run` with `-p 9000`, you may need to append `--host 0.0.0.0` to the command above. The `-p` option "publishes" the port rather than forwarding it. It therefore will not work if the application only listens to localhost. The `forwardPorts` property in `devcontainer.json` does not have this limitation, but you can use `appPort` property instead if you want to mirror the `docker run` behavior.

3. **Build, Run, and Debug:**

- Open `app.py`
- Add a breakpoint (e.g. on line 9).
- Press <kbd>F5</kbd> to launch the app in the container.
- Once the breakpoint is hit, try hovering over variables (e.g. the app variable on line 7), examining locals, and more.
- Continue (<kbd>F5</kbd>). You can connect to the server in the container by either:
- Clicking on `Open in Browser` in the notification telling you: `Your service running on port 9000 is available`.
- Clicking the globe icon in the 'Ports' view. The 'Ports' view gives you an organized table of your forwarded ports, and you can access it with the command **Ports: Focus on Ports View**.
- Continue (<kbd>F5</kbd>). You can connect to the server in the container by either:
- Clicking on `Open in Browser` in the notification telling you: `Your service running on port 9000 is available`.
- Clicking the globe icon in the 'Ports' view. The 'Ports' view gives you an organized table of your forwarded ports, and you can access it with the command **Ports: Focus on Ports View**.
- Notice port 9000 in the 'Ports' view is labeled "Hello Remote World." In `devcontainer.json`, you can set `"portsAttributes"`, such as a label for your forwarded ports and the action to be taken when the port is autoforwarded.

> **Note:** In Dev Containers, you can access your app at `http://localhost:9000` in a local browser. But in a browser-based Codespace, you must click the link from the notification or the `Ports` view so that the service handles port forwarding in the browser and generates the correct URL.

4. **Rebuild or update your container**

You may want to make changes to your container, such as installing a different version of a software or forwarding a new port. You'll rebuild your container for your changes to take effect.
You may want to make changes to your container, such as installing a different version of a software or forwarding a new port. You'll rebuild your container for your changes to take effect.

**Open browser automatically:** As an example change, let's update the `portsAttributes` in the `.devcontainer/devcontainer.json` file to open a browser when our port is automatically forwarded.

- Open the `.devcontainer/devcontainer.json` file.
- Modify the `"onAutoForward"` attribute in your `portsAttributes` from `"notify"` to `"openBrowser"`.
- Press <kbd>F1</kbd> and select the **Dev Containers: Rebuild Container** or **Codespaces: Rebuild Container** command so the modifications are picked up.
- Press <kbd>F1</kbd> and select the **Dev Containers: Rebuild Container** or **Codespaces: Rebuild Container** command so the modifications are picked up.

5. **Install Node.js using a Dev Container Feature:**
- Press <kbd>F1</kbd> and select the **Dev Containers: Configure Container Features...** or **Codespaces: Configure Container Features...** command.
- Type "node" in the text box at the top.
- Check the check box next to "Node.js (via nvm) and yarn" (published by devcontainers)
- Check the check box next to "Node.js (via nvm) and yarn" (published by devcontainers)
- Click OK
- Press <kbd>F1</kbd> and select the **Dev Containers: Rebuild Container** or **Codespaces: Rebuild Container** command so the modifications are picked up.

Expand All @@ -94,7 +205,7 @@ Some things to try:

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.

Expand Down
18 changes: 9 additions & 9 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ If you believe you have found a security vulnerability in any Microsoft-owned re

Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).

If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).

You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).

Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:

* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly.

Expand Down
9 changes: 8 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
# Licensed under the MIT License. See LICENSE in the project root for license information.
#-----------------------------------------------------------------------------------------

# Import the Flask web framework
from flask import Flask

# Create a new Flask web application instance
app = Flask(__name__)

# Define a route for the root URL "/"
# When someone visits the homepage, this function will be called
@app.route("/")
def hello():
return app.send_static_file("index.html")
# Return the contents of index.html from the static folder
# Flask automatically looks for static files in the 'static' directory
return app.send_static_file("index.html")
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
flask
flask
pytest==7.4.0
pytest-cov==4.1.
Empty file added tests/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""Configure pytest for the project."""
import os
import sys

# Add the root directory to Python path
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
Loading