|
| 1 | +# Making and Managing Python Projects |
| 2 | + |
| 3 | +This guide explains how to set up and manage Python projects in VS Code using the Python Environments extension. By the end, you'll understand what a "project" is, how to create and configure them, and how to assign the right environments and package managers to each one. |
| 4 | + |
| 5 | +## What is a Python Project? |
| 6 | + |
| 7 | +A **Python Project** is any file or folder that contains runnable Python code and needs its own environment. Think of it as a way to tell VS Code: "This folder (or file) is a distinct Python codebase that should use a specific Python interpreter and package manager." |
| 8 | + |
| 9 | +By default, every workspace folder you open in VS Code is automatically treated as a project. However, you can also: |
| 10 | + |
| 11 | +- Add subfolders as separate projects (useful for mono-repos) |
| 12 | +- Add individual Python files as projects (great for standalone scripts) |
| 13 | +- Create brand new projects from templates |
| 14 | + |
| 15 | +### Why use projects? |
| 16 | + |
| 17 | +Projects solve a common challenge: **different parts of your workspace need different Python environments**. |
| 18 | + |
| 19 | +| Scenario | Without Projects | With Projects | |
| 20 | +|----------|-----------------|---------------| |
| 21 | +| Mono-repo with multiple services | All services share one environment | Each service gets its own environment | |
| 22 | +| Testing different Python versions | Manual interpreter switching | Assign Python 3.10 to one folder, 3.12 to another | |
| 23 | +| Shared workspace with scripts and packages | Confusing environment management | Clear separation of concerns | |
| 24 | + |
| 25 | +## The Python Environments Panel |
| 26 | + |
| 27 | +The Python Environments extension adds a dedicated view to VS Code's Activity Bar. This panel has two main sections: |
| 28 | + |
| 29 | +1. **Python Projects**: Shows all projects in your workspace and their selected environments |
| 30 | +2. **Environment Managers**: Shows available environment managers (venv, conda, etc.) with their environments |
| 31 | + |
| 32 | +<!-- INSERT IMAGE: Screenshot of the Python Environments panel showing both sections |
| 33 | + Alt text: VS Code sidebar showing Python Projects section with project list and Environment Managers section below |
| 34 | + Caption: The Python Environments panel with Python Projects and Environment Managers sections --> |
| 35 | + |
| 36 | +## Adding Projects to Your Workspace |
| 37 | + |
| 38 | +There are several ways to add Python projects: |
| 39 | + |
| 40 | +### Method 1: Add existing files or folders |
| 41 | + |
| 42 | +Use this when you have existing Python code that should be treated as a separate project. |
| 43 | + |
| 44 | +1. Open the Python Environments panel in the Activity Bar. |
| 45 | +2. In the **Python Projects** section, click the **+** button. |
| 46 | +3. Select **Add Existing**. |
| 47 | +4. Browse to and select the folder(s) or file(s) you want to add. |
| 48 | +5. Select **Open** to add them as projects. |
| 49 | + |
| 50 | +Alternatively, right-click any folder or Python file in the Explorer and select **Add as Python Project**. |
| 51 | + |
| 52 | +<!-- INSERT IMAGE: Context menu in Explorer showing "Add as Python Project" option |
| 53 | + Alt text: VS Code Explorer context menu with "Add as Python Project" highlighted |
| 54 | + Caption: Right-click any folder or file to add it as a Python project --> |
| 55 | + |
| 56 | +### Method 2: Auto-find projects |
| 57 | + |
| 58 | +Use this to quickly discover all Python projects in your workspace based on common project markers. |
| 59 | + |
| 60 | +1. Open the Python Environments panel. |
| 61 | +2. Click the **+** button in the Python Projects section. |
| 62 | +3. Select **Auto Find**. |
| 63 | +4. The extension searches for folders containing `pyproject.toml` or `setup.py` files. |
| 64 | +5. Select which discovered projects to add from the list. |
| 65 | + |
| 66 | +> **Tip**: Auto-find is especially useful when you clone a mono-repo and want to quickly identify all its Python projects. |
| 67 | +
|
| 68 | +### Method 3: Create a new project from a template |
| 69 | + |
| 70 | +Use this to scaffold a brand new Python project with the correct structure and files. |
| 71 | + |
| 72 | +1. Open the Command Palette (`Cmd+Shift+P` on macOS, `Ctrl+Shift+P` on Windows/Linux). |
| 73 | +2. Run **Python Envs: Create New Project from Template**. |
| 74 | +3. Choose a template type: |
| 75 | + - **Package**: A structured Python package with `pyproject.toml`, tests folder, and package directory |
| 76 | + - **Script**: A simple standalone Python file using PEP 723 inline metadata |
| 77 | +4. Enter a name for your project. |
| 78 | +5. Choose whether to create a virtual environment. |
| 79 | + |
| 80 | +The extension creates the project structure, adds it to your workspace, and optionally creates a virtual environment. |
| 81 | + |
| 82 | +#### Package template structure |
| 83 | + |
| 84 | +When you create a package named `my_package`, the extension generates: |
| 85 | + |
| 86 | +``` |
| 87 | +my_package_project/ |
| 88 | +├── pyproject.toml # Project metadata and dependencies |
| 89 | +├── dev-requirements.txt # Development dependencies |
| 90 | +├── my_package/ # Your package source code |
| 91 | +│ └── __init__.py |
| 92 | +└── tests/ # Test directory |
| 93 | + └── __init__.py |
| 94 | +``` |
| 95 | + |
| 96 | +#### Script template |
| 97 | + |
| 98 | +When you create a script, the extension generates a single `.py` file with PEP 723 inline script metadata, which allows you to specify dependencies directly in the file. |
| 99 | + |
| 100 | +## Assigning Environments to Projects |
| 101 | + |
| 102 | +Each project can have its own Python environment. This is the core benefit of project management. |
| 103 | + |
| 104 | +### Set an environment for a project |
| 105 | + |
| 106 | +1. In the **Python Projects** section, find your project. |
| 107 | +2. Click on the environment path shown beneath the project name (or "No environment" if none is set). |
| 108 | +3. Select an environment from the list of available environments. |
| 109 | + |
| 110 | +You can also: |
| 111 | + |
| 112 | +- Click the environment icon next to a project |
| 113 | +- Right-click the project and select **Set Project Environment** |
| 114 | + |
| 115 | +<!-- INSERT IMAGE: Python Projects section showing a project with environment selection dropdown |
| 116 | + Alt text: Project item in Python Environments panel with environment selector expanded |
| 117 | + Caption: Click the environment path to change a project's Python interpreter --> |
| 118 | + |
| 119 | +### Use an environment from the Environment Managers section |
| 120 | + |
| 121 | +1. In the **Environment Managers** section, expand a manager (e.g., venv, conda). |
| 122 | +2. Find the environment you want to use. |
| 123 | +3. Right-click it and select **Set As Project Environment**. |
| 124 | +4. Choose which project should use this environment. |
| 125 | + |
| 126 | +## Setting Environment and Package Managers |
| 127 | + |
| 128 | +Beyond selecting which Python interpreter a project uses, you can also specify which **environment manager** and **package manager** the project should use. This affects how environments are created and how packages are installed. |
| 129 | + |
| 130 | +### Environment managers |
| 131 | + |
| 132 | +Environment managers control how Python environments are created and discovered: |
| 133 | + |
| 134 | +| Manager | Description | |
| 135 | +|---------|-------------| |
| 136 | +| `venv` | Built-in Python virtual environments (default) | |
| 137 | +| `conda` | Conda environments from Anaconda or Miniconda | |
| 138 | +| `pyenv` | Multiple Python versions via pyenv | |
| 139 | +| `poetry` | Poetry-managed environments | |
| 140 | +| `pipenv` | Pipenv-managed environments | |
| 141 | +| `system` | System-installed Python interpreters | |
| 142 | + |
| 143 | +### Package managers |
| 144 | + |
| 145 | +Package managers control how packages are installed in environments: |
| 146 | + |
| 147 | +| Manager | Description | |
| 148 | +|---------|-------------| |
| 149 | +| `pip` | Standard Python package installer (default) | |
| 150 | +| `conda` | Conda package manager for conda environments | |
| 151 | + |
| 152 | +### Set managers for a project |
| 153 | + |
| 154 | +1. Right-click a project in the Python Projects section. |
| 155 | +2. Select **Set Environment Manager** to change how environments are created. |
| 156 | +3. Select **Set Package Manager** to change how packages are installed. |
| 157 | + |
| 158 | +> **Note**: The default package manager is typically determined by the environment manager. For example, venv environments use pip by default, while conda environments use the conda package manager. |
| 159 | +
|
| 160 | +## Where Settings Are Stored |
| 161 | + |
| 162 | +The extension stores project configurations in your VS Code settings. Understanding this helps you manage settings across different scopes. |
| 163 | + |
| 164 | +### Settings location |
| 165 | + |
| 166 | +Project settings are stored in the `python-envs.pythonProjects` setting. Depending on your workspace setup: |
| 167 | + |
| 168 | +| Workspace Type | Settings Location | |
| 169 | +|----------------|-------------------| |
| 170 | +| Single folder | `.vscode/settings.json` in your workspace | |
| 171 | +| Multi-root workspace | `.code-workspace` file | |
| 172 | + |
| 173 | +### Settings structure |
| 174 | + |
| 175 | +The `pythonProjects` setting is an array of project configurations: |
| 176 | + |
| 177 | +```json |
| 178 | +{ |
| 179 | + "python-envs.pythonProjects": [ |
| 180 | + { |
| 181 | + "path": "backend", |
| 182 | + "envManager": "ms-python.python:venv", |
| 183 | + "packageManager": "ms-python.python:pip" |
| 184 | + }, |
| 185 | + { |
| 186 | + "path": "ml-service", |
| 187 | + "envManager": "ms-python.python:conda", |
| 188 | + "packageManager": "ms-python.python:conda" |
| 189 | + } |
| 190 | + ] |
| 191 | +} |
| 192 | +``` |
| 193 | + |
| 194 | +Each project entry contains: |
| 195 | + |
| 196 | +| Property | Description | |
| 197 | +|----------|-------------| |
| 198 | +| `path` | Relative path from workspace root to the project | |
| 199 | +| `envManager` | ID of the environment manager (e.g., `ms-python.python:venv`) | |
| 200 | +| `packageManager` | ID of the package manager (e.g., `ms-python.python:pip`) | |
| 201 | +| `workspace` | (Multi-root only) Name of the workspace folder containing the project | |
| 202 | + |
| 203 | +### Default managers |
| 204 | + |
| 205 | +You can set default managers that apply to all projects without explicit overrides: |
| 206 | + |
| 207 | +```json |
| 208 | +{ |
| 209 | + "python-envs.defaultEnvManager": "ms-python.python:venv", |
| 210 | + "python-envs.defaultPackageManager": "ms-python.python:pip" |
| 211 | +} |
| 212 | +``` |
| 213 | + |
| 214 | +## Working with Multi-Root Workspaces |
| 215 | + |
| 216 | +Multi-root workspaces contain multiple top-level folders. The extension handles these seamlessly: |
| 217 | + |
| 218 | +1. Each workspace folder is automatically treated as a project. |
| 219 | +2. You can add sub-projects within any workspace folder. |
| 220 | +3. Project settings include a `workspace` property to identify which folder they belong to. |
| 221 | +4. When creating a new project from a template, you're prompted to select which workspace folder to use. |
| 222 | + |
| 223 | +### Example: Multi-root mono-repo |
| 224 | + |
| 225 | +``` |
| 226 | +my-workspace.code-workspace |
| 227 | +├── frontend/ → Project with Python 3.12 |
| 228 | +│ └── scripts/ → Sub-project with same environment |
| 229 | +├── backend/ → Project with Python 3.10, venv |
| 230 | +│ ├── api/ → Sub-project with its own venv |
| 231 | +│ └── workers/ → Sub-project with its own venv |
| 232 | +└── ml-pipeline/ → Project with conda environment |
| 233 | +``` |
| 234 | + |
| 235 | +## Removing Projects |
| 236 | + |
| 237 | +To remove a project (this does not delete any files): |
| 238 | + |
| 239 | +1. Right-click the project in the Python Projects section. |
| 240 | +2. Select **Remove Python Project**. |
| 241 | + |
| 242 | +The project is removed from the extension's tracking. Its files remain untouched, and you can always add it back later. |
| 243 | + |
| 244 | +## Quick Reference: Commands |
| 245 | + |
| 246 | +Access these via the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`): |
| 247 | + |
| 248 | +| Command | Description | |
| 249 | +|---------|-------------| |
| 250 | +| **Python Envs: Create New Project from Template** | Create a new package or script from a template | |
| 251 | +| **Python Envs: Add Python Project** | Add existing files/folders as projects | |
| 252 | +| **Python Envs: Set Project Environment** | Change the Python interpreter for a project | |
| 253 | +| **Python Envs: Set Environment Manager** | Change how environments are created | |
| 254 | +| **Python Envs: Set Package Manager** | Change how packages are installed | |
| 255 | +| **Python Envs: Create Environment** | Create a new environment for a project | |
| 256 | +| **Python Envs: Manage Packages** | Install or uninstall packages | |
| 257 | + |
| 258 | +## Quick Reference: Settings |
| 259 | + |
| 260 | +| Setting | Default | Description | |
| 261 | +|---------|---------|-------------| |
| 262 | +| `python-envs.defaultEnvManager` | `"ms-python.python:venv"` | Default environment manager for new projects | |
| 263 | +| `python-envs.defaultPackageManager` | `"ms-python.python:pip"` | Default package manager for new projects | |
| 264 | +| `python-envs.pythonProjects` | `[]` | List of project configurations | |
| 265 | + |
| 266 | +## Common Scenarios |
| 267 | + |
| 268 | +### Scenario 1: Mono-repo with microservices |
| 269 | + |
| 270 | +You have a repository with multiple Python services, each needing isolated dependencies. |
| 271 | + |
| 272 | +1. Open the root folder in VS Code. |
| 273 | +2. Click **+** in Python Projects and select **Auto Find** to discover all services with `pyproject.toml`. |
| 274 | +3. Select the services you want to track. |
| 275 | +4. For each service, create a virtual environment by right-clicking and selecting **Create Environment**. |
| 276 | +5. Each service now runs with its own isolated environment. |
| 277 | + |
| 278 | +### Scenario 2: Switching a project from venv to conda |
| 279 | + |
| 280 | +Your data science project needs packages that install more reliably with conda. |
| 281 | + |
| 282 | +1. Right-click the project in Python Projects. |
| 283 | +2. Select **Set Environment Manager** → **conda**. |
| 284 | +3. Select **Set Package Manager** → **conda**. |
| 285 | +4. Right-click the project again and select **Create Environment** to create a new conda environment. |
| 286 | + |
| 287 | +### Scenario 3: Adding a standalone script |
| 288 | + |
| 289 | +You have a utility script that needs specific packages without affecting your main project. |
| 290 | + |
| 291 | +1. Right-click the `.py` file in Explorer. |
| 292 | +2. Select **Add as Python Project**. |
| 293 | +3. The script is now a separate project that can have its own environment. |
| 294 | + |
| 295 | +## Troubleshooting |
| 296 | + |
| 297 | +### Project not appearing in the panel |
| 298 | + |
| 299 | +- Verify the file or folder is inside your workspace |
| 300 | +- Check if it was already added (duplicates are prevented) |
| 301 | +- Try using **Add Existing** and manually selecting it |
| 302 | + |
| 303 | +### Environment changes not taking effect |
| 304 | + |
| 305 | +- Restart any open terminals to use the new environment |
| 306 | +- Check that the environment actually exists and is valid |
| 307 | +- Verify the `pythonProjects` setting in `.vscode/settings.json` |
| 308 | + |
| 309 | +### Settings not persisting |
| 310 | + |
| 311 | +- Ensure you have write access to the workspace folder |
| 312 | +- Check if settings are being overridden at a higher scope (User vs. Workspace) |
| 313 | +- For multi-root workspaces, verify the `.code-workspace` file is being saved |
| 314 | + |
| 315 | +## Related Resources |
| 316 | + |
| 317 | +- [Environment Management](../README.md#environment-management): Learn about creating and managing Python environments |
| 318 | +- [Package Management](../README.md#package-management): Learn how to install and manage packages |
| 319 | +- [Projects API Reference](projects-api-reference.md): Technical reference for extension authors |
| 320 | + |
| 321 | + |
| 322 | + |
| 323 | + |
| 324 | +RawEventsVSCodeExt |
| 325 | +| where EventName == "ms-python.vscode-python-envs/project_structure" |
| 326 | +| extend ProjectCount = toint(Properties["totalprojectcount"]) |
| 327 | +| extend Bucket = case( |
| 328 | + ProjectCount == 0, "0", |
| 329 | + ProjectCount == 1, "1", |
| 330 | + ProjectCount == 2, "2", |
| 331 | + ProjectCount == 3, "3", |
| 332 | + ProjectCount >= 4, "4+", |
| 333 | + "unknown") |
| 334 | +| summarize Count = count() by Bucket |
| 335 | +| order by Bucket asc |
| 336 | + |
| 337 | +0 4,231 |
| 338 | +1 38,743 93.6% |
| 339 | +2 1,163 2.8% |
| 340 | +3 429 1% |
| 341 | +4+ 1,051 2.5% |
| 342 | + |
| 343 | +1-4 == 41,386 |
| 344 | + |
| 345 | +RawEventsVSCodeExt |
| 346 | +| where EventName == "ms-python.vscode-python-envs/project_structure" |
| 347 | +| extend ProjectCount = toint(Properties["uniqueinterpretercount"]) |
| 348 | +| extend Bucket = case( |
| 349 | + ProjectCount == 0, "0", |
| 350 | + ProjectCount == 1, "1", |
| 351 | + ProjectCount == 2, "2", |
| 352 | + ProjectCount == 3, "3", |
| 353 | + ProjectCount >= 4, "4+", |
| 354 | + "unknown") |
| 355 | +| summarize Count = count() by Bucket |
| 356 | +| order by Bucket asc |
| 357 | + |
| 358 | +0 4,934 10.9% |
| 359 | +1 39,054 86.6% |
| 360 | +2 820 1.8% |
| 361 | +3 138 0.3% |
| 362 | +4+ 160 0.35 |
| 363 | + |
| 364 | +0-4+ = 45,106 |
| 365 | + |
| 366 | + |
| 367 | +RawEventsVSCodeExt |
| 368 | +| where EventName == "ms-python.vscode-python-envs/project_structure" |
| 369 | +| extend ProjectCount = toint(Properties["projectunderroot"]) |
| 370 | +| extend Bucket = case( |
| 371 | + ProjectCount == 0, "0", |
| 372 | + ProjectCount == 1, "1", |
| 373 | + ProjectCount == 2, "2", |
| 374 | + ProjectCount == 3, "3", |
| 375 | + ProjectCount >= 4, "4+", |
| 376 | + "unknown") |
| 377 | +| summarize Count = count() by Bucket |
| 378 | +| order by Bucket asc |
| 379 | + |
| 380 | + |
| 381 | +0 45,293 98.2% |
| 382 | +1 445 1% |
| 383 | +2 119 0.25% |
| 384 | +3 29 |
| 385 | +4+ 194 0.4% |
| 386 | + |
| 387 | +0-4+: 46,080 |
0 commit comments