Skip to content
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

Use environment variables defined in .env file when running code in a terminal #944

Closed
DonJayamanne opened this issue Mar 5, 2018 · 61 comments
Assignees
Labels
area-environments Features relating to handling interpreter environments area-terminal feature-request Request for new features or functionality verified Verification succeeded

Comments

@DonJayamanne
Copy link

DonJayamanne commented Mar 5, 2018

@brettcannon
I've been using PYTHONPATH variable in .env for debugging using experimental debugger (without having to pip install PTVSD).
However running in terminal doesn't inherit these variables, I've had to export them manually.

What do you think about this feature?

Technical solution outlined in #4310
Need spec to provide UX (prompting users to load env, etc)

@DonJayamanne DonJayamanne added feature-request Request for new features or functionality area-terminal needs decision labels Mar 5, 2018
@dakotahawkins
Copy link

The whole "python.envFile" feature needs much better documentation/support (#544)...

I don't know if or how it works, I don't know if I can or how to refer to other variables inside .env (e.g. Does PYTHONPATH=${PYTHONPATH}:${workspaceFolder}/utility work?), etc.

From an hour of trying to use it, it appears nobody on the internet knows what's going on. It's either people who can't get it to work either or people saying it does work but not giving realistic examples... grrr!!!

@brettcannon
Copy link
Member

How hard is it to launch with these environment variables set? Does the VS Code API make it easy? If it does then doing it through Create Terminal makes sense.

@brettcannon
Copy link
Member

@dakotahawkins and yes, more docs would be good, hence why #544 exists. 😄 If you're up for helping us get that issue closed then it would be appreciated! Else we do plan on getting around to it.

@DonJayamanne
Copy link
Author

@dakotahawkins
Please could you create an issue for the following:

I don't know if or how it works, I don't know if I can or how to refer to other variables inside .env >
(e.g. Does PYTHONPATH=${PYTHONPATH}:${workspaceFolder}/utility work?), etc.

@dakotahawkins
Copy link

@DonJayamanne #955

@brettcannon I'd be happy to help out, provided I can figure out how it works or how it's intended to work for more complicated values than FOO=BAR.

Another issue I had is that "run in terminal" didn't work after setting my terminal to bash (git bash, still on windows) because it sent it windows path separators. It occurs to me that these differences might apply to environment variables as well (e.g. separating lists with : instead of ;, path separators from things like ${workspaceFolder} if that's supposed to work, etc.).

In the interim I just went back to cmd.exe. That's probably a separate feature request but I thought I'd mention in here since it could be relevant to processing .env for running in the terminal.

@brettcannon
Copy link
Member

@dakotahawkins you're right that the .env file is not terminal-agnostic; you need to write it for your terminal (and we have no explicit support for git bash or WSL at the moment).

@dakotahawkins
Copy link

dakotahawkins commented Mar 6, 2018

At any rate, and more on-topic, one of the things I tried was running a temp wat.py to print values from an environment variable set in .env. It didn't work, and while that helped me find this issue it would be an awesome way to see the effect of variables from .env.

I guess my secondary complaint, besides not knowing how to use it in the first place, is that it seems like there is no way to tell what you're actually getting out of .env.

Transparently setting them when you run in the vscode terminal would have allowed me to do that, but on the other hand I could definitely see it being a big problem for python to work fine from vscode but not anywhere else (because only vscode would be using the .env environment).

I don't know what the "most native" python solution to that would be, but whatever it is should be (imo) as helpful as possible to people who aren't going to run it from inside of vscode.

As I mentioned in #955, my use-case is that I already don't use vscode to run my code and so while that will work I want to be able to get vscode to find all the things my running code would find (without setting absolute paths, because other developers will work on this). The problematic use-case would be the opposite -- some project that starts in vscode becoming dependant on it because of features like this.

@brettcannon
Copy link
Member

Typically people use .env to set their PYTHONPATH environment variable specifically so their code will run in VS Code. Other tools also use it so a .env file isn't special to the extension (we actually didn't come up with the concept and tools like pipenv actually support .env files so it isn't unique to the Python community either).

@thebalaa

This comment has been minimized.

@DonJayamanne

This comment has been minimized.

@brettcannon
Copy link
Member

To help manage our issues and to better communicate what the team plans to work on we are closing issues that we don't plan to work on but would accept a pull request from a volunteer for. To be clear, closing this issue does not mean we won't consider a pull request for this enhancement as outlined in our contributing guide, just that the development team has no plans to work on it themselves.

@brettcannon
Copy link
Member

Apparently PyCharm supports this so might need to have a chat with @qubitron about this.

@blakeNaccarato
Copy link

blakeNaccarato commented Jun 15, 2022

A (perhaps not so awesome) workaround is to not use bash and instead use the cross-platform PowerShell as the default terminal for VSCode for Linux/MacOS, then set up your PowerShell profile to load the environment and activate the virtual environment. Now, "Run Python File" and debugging will all load the proper environment. If you have certain tasks in tasks.json specially written for bash, most of these will still work, as pwsh has access to all the system utilities including sudo. See my note at the end of this comment for more details on tasks.json.

The workaround

Install PowerShell

Install PowerShell in your distro by adding the Linux Software Repository for Microsoft Products and running sudo apt install powershell afterwards, or else follow one of these guides.

Update VSCode workspace settings

Then, e.g. for Linux in your workspace settings.json:

"terminal.integrated.defaultProfile.linux": "pwsh",

Install Set-PsEnv and modify your PowerShell profile

Then close your VSCode integrated terminal and re-open it, and it should open pwsh instead of bash. Install Set-PsEnv like Install-Module -Name Set-PsEnv. Do this in pwsh not bash.

Then run code $PROFILE which should open /home/user/.config/powershell/Microsoft.PowerShell_profile.ps1 (e.g. for a user named user), and copy/paste the following into it:

function Set-Env {

    # If there is an `.env` file in the PWD, load environment variables from it
    Set-PsEnv

    # If there is a Python virtual environment in the PWD, activate it
    $COMMON = 'bin\Activate.ps1'

    # ".venv"
    $PATH_VENV = '.venv'
    if (Test-Path $PATH_VENV) { & $PATH_VENV\$COMMON }

    # "venv" (no dot)
    $PATH_VENV = 'venv'
    if (Test-Path $PATH_VENV) { & $PATH_VENV\$COMMON }

}

Set-Env

Note: I call a function inside the profile to shield those variables from being loaded into the interactive terminal session. Note that $script:VAR or similar do not protect the scope of these variables since the profile context is the terminal context.

All done!

Now close and re-open the integrated terminal and your virtual environment should load, and your environment variables should load, and running Python files, debugging, etc. should work. Modify the profile above as necessary for your specific use-case.

Notes

Debugging and launch.json

You must debug with "console": "integratedTerminal", as opposed to internalConsole, or else your environment will not load properly.

{
  "name": "Python",
  "type": "python",
  "request": "launch",
  "program": "${file}",
  "console": "integratedTerminal",
},

Tasks and tasks.json

In order for tasks to load the proper environment variables in tasks.json, they must be formed like so:

{
  "label": "Example task",
  "type": "process",
  "command": "pwsh",
  "args": ["-Command", "python -m my_example_module"],
  "problemMatcher": []
},

This ensures that your PowerShell profile has a chance to load environment variables and such before running your Python code.

A note on (.venv) popping up twice

We are activating the environment in our PowerShell profile and via a setting in VSCode. You can disable one or the other by deleting the associated lines in the PowerShell profile above or setting the following in your workspace settings.json:

"python.terminal.activateEnvironment": false,

I prefer to do my environment activation in the PowerShell profile, but it is just a matter of preference.

A note on pwsh, environment variables, and the $DISPLAY environment variable in wsl

If you're remoting or using WSL, make sure to explicitly set your display in the PowerShell profile, like so:

$Env:DISPLAY="$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0"
$Env:LIBGL_ALWAYS_INDIRECT=1

Note that we refer to environment variables as $Env:DISPLAY, not just $DISPLAY, that is important!

@github-actions github-actions bot removed the needs PR label Aug 9, 2022
@karrtikr karrtikr added the needs PR Ready to be worked on label Aug 9, 2022
@jgrugru
Copy link

jgrugru commented Aug 18, 2022

Any updates on this?
I am able to get the .env file to load but only when I run my python file in debug mode.

The documentation is either misleading or this is a bug.

By default, the Python extension looks for and loads a file named .env in the current workspace folder, then applies those definitions. The file is identified by the default entry "python.envFile"

If the intended functionality is to have the env vars load only when debugging a file, that's fine by me; only pointing out that there is some confusion in the docs.

@jbb61
Copy link

jbb61 commented Aug 18, 2022

Ideally the functionality would work similar to Pycharm. Where variables are applied per run/debug configuration.

@HaidarZ
Copy link

HaidarZ commented Sep 16, 2022

I've created a terminal launcher that works around this issue. I didn't like the idea of declaring environment variables in multiple places. The implementation was easy, I really don't know why Microsoft didn't support this feature despite it being a trivial behavior.
Checkout my new extension:
https://marketplace.visualstudio.com/items?itemName=hzeineddine.terminal-dotenv

@dss010101
Copy link

This thread is quite long - so wondering if this is the same issue im running into - I was able to solve the problem of being able to load different env files depending on whether im running under windows or linux by adding these to my launch configurations:

            "windows": {
                "envFile": "${workspaceFolder}/.env"
            },
            "linux": {
                "envFile": "${workspaceFolder}/.env_linux"
            }

That gets me by. but when i have a file open, if dont use the debug tab to select a debug/launch profile and simply click on the 'Run Python Button'
image

It seems to default to the .env file always. Is there a way to handle that use case?

@karrtikr
Copy link

karrtikr commented Dec 14, 2022

#11039 should fix this issue, still keeping this open as it has more upvotes.

@maximecharriere
Copy link

Any updates on this?
The doc still says:

By default, the Python extension looks for and loads a file named .env in the current workspace folder, then applies those definitions.

But I need to load the .env file myself, for example by using python-dotenv or the extension presented by @HaidarZ :

# python-dotenv example
import os
from dotenv import load_dotenv
load_dotenv()

print(os.getenv("API_KEY"))

If the intended functionality is not to applies those definitions by default, that's fine by me. Only pointing out that there is some confusion in the docs.

@pama1999
Copy link

@karrtikr any update when this issue might get fixed?

@karrtikr
Copy link

There's an open PR for it right now, it's actively being worked on 🙂

@karrtikr karrtikr self-assigned this Aug 28, 2023
karrtikr pushed a commit that referenced this issue Aug 28, 2023
…ctivation` experiment (#21879)

For #944 #20822 

We only apply those env vars to terminal which are not in process env
variables, hence remove custom env vars from process variables.
@karrtikr karrtikr added this to the September 2023 milestone Sep 11, 2023
@karrtikr
Copy link

karrtikr commented Sep 11, 2023

Should be fixed with #11039, but it is currently behind an experiment. Give it a try:

  • Use latest version of VS Code and Python extension
  • Add the following to User settings and reload window:
    "python.experiments.optInto": ["pythonTerminalEnvVarActivation"]

@github-actions github-actions bot removed the needs PR Ready to be worked on label Sep 11, 2023
anthonykim1 pushed a commit to anthonykim1/vscode-python that referenced this issue Sep 12, 2023
…ctivation` experiment (microsoft#21879)

For microsoft#944 microsoft#20822 

We only apply those env vars to terminal which are not in process env
variables, hence remove custom env vars from process variables.
@starball5
Copy link

If this graduates from being experimental, docs would need to be updated.

@karrtikr
Copy link

@starball5 Thanks, I've added it to our existing issue to track this: microsoft/vscode-docs#6590

@karrtikr karrtikr added verified Verification succeeded and removed verification-needed Verification of issue is requested labels Sep 25, 2023
@GPhilo
Copy link

GPhilo commented Oct 11, 2023

The setting "python.experiments.optInto": ["pythonTerminalEnvVarActivation"] seems to only be supported in local sessions. Is there perhaps a workaround for remote sessions via SSH?

@karrtikr
Copy link

That'll be Remote settings instead of User settings for remote scenarios.

@jgrugru
Copy link

jgrugru commented Nov 1, 2023

Thank you for fixing this.

It's already been mentioned in the above comments, but for those who are trying to implement this and have not messed with experimental settings, here's how to add it:

  • Open the command palette (Ctrl+Shift+P)
  • click on Preferences: open user settings (JSON)
  • Once the JSON file opens, add the following line:
    • "python.experiments.optInto": ["pythonTerminalEnvVarActivation"]
  • save the file and reload your vscode window

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-environments Features relating to handling interpreter environments area-terminal feature-request Request for new features or functionality verified Verification succeeded
Projects
None yet
Development

No branches or pull requests