-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add support for .env
and custom env files in uv run
#8263
Add support for .env
and custom env files in uv run
#8263
Conversation
This generally looks good, but I think we should bundle it in v0.5.0, since it is a change in behavior. |
Do you mind adding a test to |
Thank you very much for your advice and input. The coding experience when writing tests is fantastic, I didn't expect it to be so good. There seems to be a problem running the tests, but it escapes my understanding. I've seen that other PRs are having the same error. |
// Initialize env file, if necessary. | ||
if !no_env_file { | ||
let env_file_path = env_file | ||
.clone() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this clone is not necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary because you then need to use env_file
to check whether it is passed as an argument or the default argument is taken.
if env_file.is_some() {
Maybe I could change it to this:
let is_env_file_present = env_file.is_some();
let env_file_path = env_file.unwrap_or_else(|| Path::new(".env").to_path_buf());
let loaded = dotenvy::from_path_override(&env_file_path);
match loaded {
Err(dotenvy::Error::Io(err)) => {
if is_env_file_present {
bail!(
"Failed to read environment file `{}`: {}",
env_file_path.display(),
err
);
}
}
to avoid the clone (but at the cost of creating a variable first).
I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to remove the clone, if you're interested in seeing how.
We're planning to do v0.5 next week (hopefully) which would include this. |
bd4dcd4
to
d3176f5
Compare
Will get this merged into the v0.5 branch tomorrow. |
19e1051
to
ac25501
Compare
b02fbdf
to
8b6bbb0
Compare
8b6bbb0
to
e5fee96
Compare
It's really common for runners to support |
I'm not a NodeJS developer, but this PR is breaking conventions and good practices. Developers always need to load the But also, the code loses the control to manage the sources, their priority and their order because the runner tool decided to load values from a configuration file by default. |
I don't understand this critique. Are you asking for
Again: I'm sorry you feel that way but you can just disable this feature if you don't want it. A more reasonable critique would be to say that this should be opt-in rather than opt-out. |
Never. Imagine this case: You have three environments (.env.Development, .env.Staging, .env.Production) and optionally localhost (.env.Local). Another example: in .NET, by default, the environment variables have priority over configuration files (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0#default-application-configuration-sources). At this point, this PR is mixing 2 sources into one, and they are different. When you develop a backend, you must read from several sources, and therefore you need So, you have to load from several sources. What's an example of a shared configuration? The number of messages to read from a queue, the server to log in against, the timeout of a webhook... And sometimes you need to override it, for example, modifying the App Service environment variable, Dockerfile, App Configuration... This PR adds the capability of, by default, reading from a source (a configuration file) and loading its values into another source (the environment variables).
I'm against adding this because instead of advantages or options, it adds a feature that I'm pretty sure how it'll be used: instead of adding a library such as But yes, my issue is |
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
This (reading If the environment is not loaded programmatically,
|
Opt-in as it's technically not backwards compatible and may be unexpected - and I'd argue the majority of users won't use this. In production my apps may need to read .env vars (though should be done by actual vars at that stage) but they are never RUN through 'uv'. So they need to include dotenv or whatever anyway. My big issue is transparency- some env vars can change the actual paths and options of that process - I don't want to run 'uv' in a repo I've just cloned and have it QUIETLY set env vars I don't know about. Opt in please. Make it a global setting that is set and forget, but please don't do it behind our backs. |
(Not disagreeing with your broader point, but I'll just note that this is already marked as a breaking change that would be included in v0.5 per our versioning policy. It's ok for it not to be backwards compatible.) |
Fair point 😃 My points still stand though. There is a reason that 'direnv' REQUIRES you to physically allow auto-reading an env file the first time - security. Maybe do this for each new project the first time? At least give the user the choice. Otherwise a global option, but please, Opt in. |
I don't know if this is a fair concern. If you clone an arbitrary repository and execute |
This is very true yes. Maybe it's just my prejudice showing, and I really have no use-case for it. In many cases my code is running uvicorn-> guniciorn -> nginx so 'uv' is not in the pipe and any .env would need to be loaded manually. If I'm using an env file, I'd make sure my code explicitly reads it, and that is really more Zen. I truly believe you may end up with new issues related to unexpected env vars being set - how many people really read the release notes or just go 'yeah yeah, upgrade'😜. I'll stand by my 'opt-in' recommendation but obv not going to stop using uv if you choose otherwise. |
One more thing - anyone who wants and uses this feature should have no problem opting in?🤷♂️ |
After the migration from Also Docker and Ansible read In my case (what our company does): The So, maybe this approach will be accepted:
@seapagan @AndreuCodina Would option 3 something you would like to see in |
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
I'd still ask kindly if you can add a setting to the uv.toml so we can disable this globally please 🙏 |
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
Suggestion here to make the |
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
I have been reading discussion #1384 about .env and how to include it in the `uv run` command. I have always wanted to include this possibility in `uv`, so I was interested in the latest changes. Following @charliermarsh's [advice ](#1384 (comment)) I have tried to respect the philosophy that `uv run` uses the default `.env` and this can be discarded or changed via terminal or environment variables. The behaviour is as follows: - `uv run file.py` executes file.py using the `.env` (if it exists). - `uv run --env-file .env.development file.py` uses the `.env.development` file to load the variables and then runs file.py. In this case the program fails if the file does not exist. - `uv run --no-env-file file.py` skips reading the `.env` file. Equivalently, I have included the `UV_ENV_FILE` and `UV_NO_ENV_FILE` environment variables. I haven't got into including automated tests, I would need help with this. I have tried the above commands, with a python script that prints environment variables. --------- Co-authored-by: Charlie Marsh <[email protected]>
## Summary This PR pulls in #8263 and #8463, which were originally merged into the v0.5 tracking branch but can now be committed separately, as we've made `.env` loading opt-in. In summary: - `.env` loading is now opt-in (`--env-file .env`). - `.env` remains supported on `uv run`, so it's meant for providing environment variables to the run command, rather than to uv itself. --------- Co-authored-by: Eduardo González Vaquero <[email protected]>
Summary
I have been reading discussion #1384 about .env and how to include it in the
uv run
command.I have always wanted to include this possibility in
uv
, so I was interested in the latest changes. Following @charliermarsh's advice I have tried to respect the philosophy thatuv run
uses the default.env
and this can be discarded or changed via terminal or environment variables.The behaviour is as follows:
uv run file.py
executes file.py using the.env
(if it exists).uv run --env-file .env.development file.py
uses the.env.development
file to load the variables and then runs file.py. In this case the program fails if the file does not exist.uv run --no-env-file file.py
skips reading the.env
file.Equivalently, I have included the
UV_ENV_FILE
andUV_NO_ENV_FILE
environment variables.Test Plan
I haven't got into including automated tests, I would need help with this.
I have tried the above commands, with a python script that prints environment variables.