Separate .env for testing vs debug - python

I'm utilizing VSCode devcontainers, and I'm having difficulty trying to figure out how to run a different .env file for my pytest setup, versus when I just want to run uvicorn/debug.
I can set an envfile in settings.json, which works, but I'd have to change this path back and forth depending on whether I wanted to test or just run the server. I've read that you can change the envfile for tests in launch.json, but when discovering/running tests in no longer appears these are valid settings for launch.json, and must be baked into the vscode-python extension?
I'm really confused because I feel like this is a common use case, all I am really trying to accomplish is setting a different DB connector so that test can drop/create tables for tests, but dev would persist in a separate database.

For anyone who stumbles upon this, I found a workaround which is to specify a certain envfile for running and debugging, and then use a separate env in settings.json which will apply for the tests.
So Imagine you have
dev.env which contains
environment=dev
...
and test.env which contains
environment=test
...
Then you would include this line in your .vscode/settings.json
"python.envFile": "${workspaceFolder}/test.env"
and this is what my launch configuration looks like for bringing up fastapi with uvicorn:
{
"name": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"envFile": "${workspaceFolder}/dev.env",
"args": [
"app.main:app",
"--reload"
]
}
It's a little odd that this is how it has to be configured, but it seems to work for now.

Related

Environment variables in launch.json not recognized when running Flask application on VS Code

Shown below is the code from my launch.json file for my Flask application. I have various environment variables defined in the "env": {} portion. However, when I run my Flask application from the run.py script, it doesn't seem to recognize the variables. Although the "FLASK_DEBUG" is set to "1", the application still runs on **Debug mode: off**.
Does anyone know why?
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "run.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "1",
"EMAIL_USER": "farmgo.project.21#gmail.com",
"EMAIL_PASS": "password",
},
"args": [
"run",
//"--no-debugger"
],
"jinja": true,
}
],
}
If I set:
if __name__ == '__main__':
app.run(debug=True)
then the app does run in Debug mode. However, I still cannot get the other environment variables:
>>> import os
>>> print(os.environ.get('FLASK_DEBUG'))
None
A good way to manage environment variables in flask is by using a .flaskenv file. You will need python-dotenv to use this, and the file needs to be in the root directory of your project.
In your .flaskenv file, simply type in your variables like so:
FLASK_APP=run.py
FLASK_ENV=development
FLASK_DEBUG=1
Then you can just run flask using flask run and the envs will be loaded.
Doing it this way will mean that you keep your env settings across IDEs if you change or load the project on a different machine.
See here for more info - Flask environment variables being ignored (FLASK_ENV and FLASK_APP) WINDOWS 10
The launch.json file is only used when running your app through VS Code's debugger.
See https://code.visualstudio.com/docs/python/debugging#_initialize-configurations:
Initialize configurations
A configuration drives VS Code's behavior during a debugging session.
Configurations are defined in a launch.json file that's stored in a
.vscode folder in your workspace.
Since you mentioned
... I run my flask application from the run.py script, ...
and you are testing using the Python shell
>>> import os
>>> print(os.environ.get('FLASK_DEBUG'))
None
means you never use VS Code's debugger and thus those environment variables will never be loaded/read.
I recommend going through VS Code's tutorial on Python Debugging, especially the section on Flask Debugging. You already have the first steps done, namely adding a launch.json file with the Flask configuration. The main point here is the "module": "flask" line and adding the "--no-debugger" arg:
{
"version": "0.2.0",
"configurations": [
{
"name": "run-flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "run.py",
"FLASK_ENV": "development",
"FLASK_DEBUG": "1",
"EMAIL_USER": "farmgo.project.21#gmail.com",
"EMAIL_PASS": "password",
},
"args": [
"run",
"--no-debugger"
],
"jinja": true,
},
]
}
Then simply select that configuration from the debugger dropdown:
Testing with some quickstart Flask code:
import os
from flask import Flask
app = Flask(__name__)
#app.route("/")
def root():
env_names = [
"FLASK_APP",
"FLASK_ENV",
"FLASK_DEBUG",
"EMAIL_USER",
"EMAIL_PASS",
]
for env_name in env_names:
print(os.environ.get(env_name))
return "It works!"
...shows that the environment variables are read properly and that debug mode is now "on".
The main disadvantage of this compared to the other answer using a .flaskenv file is sharing these env vars across IDEs, with other members of your team, or with your CI/CD pipeline. You will have to define them separately.
The advantage though is allowing you to use common debugger features, such as breakpoints on code (as seen from the screenshot above where execution is stopped on the print statement), and seeing the values of your variables as your code runs.

vscode got error "timed out waiting for debug server to connect" when attaching to a running python process

We have a python app on Windows which we have packaged using pyinstaller. And now the scenario is, after running the built myapp.exe, we want to be able to attach to it and do some debugging using VS Code. This was originally working on our release version (let's say the bundle is myapp-release.exe) . However, after some modifications/upgrade, when we want to do the same thing to our latest development version (let's call it myapp-dev.exe), we got the error saying timed out waiting for debug server to connect. Basically we didn't change anything in our VS Code side (so the question title can also be like "VS Code is able to attach to one python process but fails with another one, using the same launch setting". The routine is, we start the myapp-release.exe/myapp-dev.exe outside of vs code. and launch an attach task defined in launch.json:
configurations": [
{
"name": "Python: Attach using Process Id",
"type": "python",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
I know there is not really too much information given about the myapp itself. But my question is, where I can see the error logs abou the python attach procedure, to see why it fails to attach?
Thank you very much!
You can configure logging as follow:
configurations": [
{
"name": "Python: Attach using Process Id",
"type": "python",
"request": "attach",
"processId": "${command:pickProcess}",
"logToFile": true
}
]
The log files will be available in dir:
~/.vscode-server/extensions/ms-python.python-

How to use the vscode python debugger with a project built with bazel?

I want to debug a python file which has a few dependencies that only appear in the runfiles from bazel. How can I debug a bazel build with the vscode debugger?
As someone famous said, "Yes, we can".
You would need to use the "ptvsd" python package.
One-time Setup
Add "ptvsd" as a Python dependency in Bazel
In VS Code, in your launch.json file, add the following configuration:
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"port": 5724,
"host": "localhost"
},
Debug
When you want to debug a specific file:
In the Python file you want to debug, add the following lines:
import ptvsd
ptvsd.enable_attach(address=('localhost', 5724), redirect_output=True)
print('Now is a good time to attach your debugger: Run: Python: Attach')
ptvsd.wait_for_attach()
Run Bazel on this file as you normally would (bazel run :server for instance)
Execution will stop at "Now is a good time to attach your debugger: Run: Python: Attach"
In VS Code, click on the "Python: Attach" debug option that we setup earlier:
That's it!
Feel free to change the port, 5724 in this example.
ptvsd is deprecated, replaced by debugpy.
Usage is the same as the accepted answer, except that the code snippet for the Python file has changed:
import debugpy
debugpy.listen(5678)
debugpy.wait_for_client() # blocks execution until client is attached

How to do a launch configuration where it runs a bash command in a specific folder location?

I want to configure VSCode to run all my python tests with a launch configuration (since I'm having a hard time getting it to successfully do a Test Discovery). I want to be able to just run pytest ./ in my file location.
Something like this:
{
"name": "Python: Run Tests",
"type": "python",
"request": "launch",
"program": "pytest",
"console": "integratedTerminal",
"cwd": "C:\\path\\to\\tests\\folder",
"args":["./"]
}
I've tried using the full path to the pytest.exe but it doesn't recognize my packages in my test scripts:
Any idea on how I can do this?
The error is probably because you're misusing the "program" setting.
If you're simply looking for a way to execute your tests under pytest manually, you could either do that from the terminal directly or use a task.
But test discovery should be working, so if it isn't then please file a bug at https://github.com/microsoft/vscode-python.

Setting environment variables for integrated terminal

I am seeking help figuring out how to setup environment variables for integrated terminal within Visual Studio Code. Currently I am able to do so with .env file inside my workspace folder, but I'd like to change the filename for this file and create another one or two, let's say dev.env and prod.env. Setting "python.envFile" for my workspace doesn't do the trick and from what I understand changing things in launch.json is for debugging.
The overall goal of all this (and that is important) is to run flask shell (integrated shell for flask web framework, python) with a certain set of env variables and be able to change them by swapping files. I know I could set these by introducing "terminal.integrated.env.osx" to my workspace settings, but I'd rather get these variables from a file.
Thanks a lot for your time and help.
UPD >>
I guess one way to go about it would be to create two tasks as such:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "FLASK SHELL DEV",
"type": "shell",
"command": "source ${workspaceFolder}/dev.env && ${config:python.pythonPath} -m flask shell",
"problemMatcher": []
},
{
"label": "FLASK SHELL PROD",
"type": "shell",
"command": "source ${workspaceFolder}/prod.env && ${config:python.pythonPath} -m flask shell",
"problemMatcher": []
}
]
}
but the question stands. Is there a way to do the same with integrated terminal?
Yes, you can use one of these settings (depending in your platform):
"terminal.integrated.env.linux": {},
"terminal.integrated.env.windows": {},
"terminal.integrated.env.osx": {
"PYTHONPATH": "${workspaceFolder}/src:${env:PYTHONPATH}"
},
However, they will only work for the integrated terminal, not for any other processes the vs code python extension might spawn (tests, linting, debugger). For those you need to use the .env file.
Edit:
It is worth noting that if you start VS Code from the terminal it should inherit any env variables from terminal environment (at least for all the spawned subprocesses, probably not for the integrated terminal).
If you don't want to set environment variables using the terminal you can do it using configuration files.

Categories