-
Notifications
You must be signed in to change notification settings - Fork 41
Generalized functions for getting, setting, and finding environment variables #798
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
Changes from all commits
7e52698
de7ddc5
6c19042
ed387c8
2a70ff1
9a0b62d
05f04f3
c965982
14733b4
ec139c7
e48aa67
fc84498
3a1376d
7ab6dae
6b9a606
25ec9b6
a158d65
ea793df
7d0b3fd
c05f63b
c995469
f71c24f
7c2c723
7e1a67e
e5dc052
c278ba5
1c979c8
dabdc6f
33c3875
9909098
e5f442f
0233866
d2185da
ac6959d
643340b
05de2e5
0997741
e133caf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,32 @@ | ||
| (environment_variables:setting-environment-variables)= | ||
| # Setting Environment Variables | ||
|
|
||
| H2Integrate can pull weather resource datasets (e.g. data needed for wind or solar generation) automatically for a user-provided location. | ||
| To use resource datasets from the NLR developer network, you will need an NLR API key, which can be obtained from: | ||
| [https://developer.nlr.gov/signup/](https://developer.nlr.gov/signup/). | ||
|
|
||
| You will need to set the API key and the email you used to get the API key for downloading resource data from the NLR developer network. The 40 character API key is referred to in following sections as the value for the `NLR_API_KEY` environment variable. The email used to get the API key is referred to in the following sections as the value for the `NLR_API_EMAIL` environment variable. | ||
| (environment_variables:environment-variables)= | ||
| # Environment Variables | ||
| H2Integrate can pull data (such as wind and solar resource data, feedstock prices, etc) from public datasets accessible with API keys or user-specific tokens. Since API keys and tokens are unique to each user, these are accessed in H2Integrate as environment variables. These environment variables need to be set to use their corresponding functionality. Some environment variables can also be used to customize your workflow. The list of environment variables that may be used by H2Integrate are listed below: | ||
|
|
||
| - [NLR Developer Network](environment_variables:nlr_developer) | ||
| - `NLR_API_KEY` | ||
| - `NLR_API_EMAIL` | ||
| - [EIA Natural Gas Cost Data](environment_variables:eia_ng) | ||
| - `EIA_API_KEY` | ||
| - Customized Workflow | ||
| - `RESOURCE_DIR` | ||
|
|
||
| ```{note} | ||
| The old environment variable names ``NREL_API_KEY`` and ``NREL_API_EMAIL`` are still supported | ||
| for backward compatibility, but are deprecated and will be removed in a future release. | ||
| Please migrate to ``NLR_API_KEY`` and ``NLR_API_EMAIL``. | ||
| Tips on debugging environment variable related errors or issues can be found [here](#env_var_debug:intro) | ||
| ``` | ||
|
|
||
| To use models that require environment variables, [follow these instructions below](environment_variables:setting-environment-variables). | ||
|
|
||
| (environment_variables:setting-environment-variables)= | ||
| # Setting Environment Variables | ||
| We will use the environment variables needed for the NLR Developer Network (`NLR_API_KEY` and `NLR_API_EMAIL`) to showcase different methods of setting environment variables in this section. | ||
|
|
||
| In the following sections on setting these environment variables, `'api-key-value'` should be replaced with your NLR API key and `'email-for-api-key'` should be replaced with your email address. | ||
|
|
||
| An optional environment variable is `RESOURCE_DIR`. If set, this will be used as the default folder to save resource data to that is downloaded from the API. If setting this, please set its value as the full filepath to the folder you'd like to save resource files to, and ensure that the folder exists. | ||
|
|
||
| The remaining sections outline different options for setting environment variables in H2Integrate: | ||
| - [Save environment variables with conda (preferred)](#save-environment-variables-with-conda-preferred) | ||
| - [Set environment variables with a .yaml file](#set-environment-variables-with-yaml-file) | ||
| - [Set environment variables with a .yml file](#set-environment-variables-with-yaml-file) | ||
| - [Set environment variables with a .env file](#set-environment-variables-with-env-file) | ||
|
|
||
| (save-environment-variables-with-conda-preferred)= | ||
|
|
@@ -69,7 +76,7 @@ unset RESOURCE_DIR | |
| ``` | ||
|
|
||
| (set-environment-variables-with-yaml-file)= | ||
| ## Set Environment Variables with .yaml file | ||
| ## Set Environment Variables with .yml file | ||
|
|
||
| 1. In `environment.yml`, add the following lines to the bottom of the file, and replace the | ||
| environment variable values with your information. Be sure that | ||
|
|
@@ -106,3 +113,27 @@ The ".env" file will be looked for in all of the following locations: | |
| NLR_API_EMAIL='email-for-api-key' | ||
| ``` | ||
| 3. Save and close the ".env" file. | ||
|
|
||
|
|
||
| (environment_variables:nlr_developer)= | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part seems to be in python code formatting (highlighting for and in) rather than markdown formatting. I don't known if that's just a GitHub thing here?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a myst markdown thing for creating cross-referencing tags that are able to be used easily from external files. |
||
| # NLR Developer Network Environment Variables | ||
|
|
||
| H2Integrate can pull weather resource datasets (e.g. data needed for wind or solar generation) automatically for a user-provided location. | ||
| To use resource datasets from the NLR developer network, you will need an NLR API key, which can be obtained from: | ||
| [https://developer.nlr.gov/signup/](https://developer.nlr.gov/signup/). | ||
|
|
||
| You will need to set the API key and the email you used to get the API key to download resource data from the NLR developer network. The 40 character API key is referred to in following sections as the value for the `NLR_API_KEY` environment variable. The email used to get the API key is referred to in the following sections as the value for the `NLR_API_EMAIL` environment variable. | ||
|
|
||
| ```{note} | ||
| The old environment variable names ``NREL_API_KEY`` and ``NREL_API_EMAIL`` are still supported | ||
| for backward compatibility, but are deprecated and will be removed in a future release. | ||
| Please migrate to ``NLR_API_KEY`` and ``NLR_API_EMAIL``. | ||
| ``` | ||
|
|
||
| (environment_variables:eia_ng)= | ||
| # EIA Natural Gas Cost | ||
| Further documentation on the EIA natural gas cost model can be [here](#feedstocks:eia_ng_price). This requires an API key obtained from the [EIA Open Data portal](https://www.eia.gov/opendata/). This API key should be set as the value for the environment variable `EIA_API_KEY`, i.e., | ||
|
|
||
| ```bash | ||
| EIA_API_KEY='api-key-value' | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| --- | ||
| jupytext: | ||
| text_representation: | ||
| extension: .md | ||
| format_name: myst | ||
| format_version: 0.13 | ||
| jupytext_version: 1.18.1 | ||
| kernelspec: | ||
| display_name: native-ard-h2i | ||
| language: python | ||
| name: python3 | ||
| --- | ||
|
|
||
| (env_var_debug:intro)= | ||
| # Environment Variables: Non-standard Configuration and Debugging Issues | ||
|
|
||
| If you encounter errors with models that use environment variables, such as a missing API key or other credential, this may be because the environment variables were set using a non-recommended method. The different approaches to setting environment variables is documented [in the getting started guides](#environment_variables:environment-variables). If you're setting environment variables with a .env file, then errors may occur because the file is not found. | ||
|
|
||
| The following sections will demonstrate how to debug environment variable issues and alternative ways to set environment variables. | ||
|
|
||
| - [Environment File: Getting Default Supported Filepaths](env_var_debug:get_default_fpaths) | ||
| - [Environment File: Check Default Supported Filepaths](env_var_debug:is_default_fpath) | ||
| - [Environment File: Setting Environment Variables prior to H2I Simulation](env_var_debug:nonstandard_fpath) | ||
| - [Debug Missing Environment Variables](env_var_debug:debug_missing) | ||
| - [Manually Setting Environment Variables](env_var_debug:manual_setting) | ||
|
|
||
|
|
||
| ## Non-standard environment file location or name | ||
|
|
||
| If you're getting an error for a missing environment variable and your environment variables are stored in a `.env` file, then the `.env` file may not be found in the expected location. | ||
|
|
||
| (env_var_debug:get_default_fpaths)= | ||
| ### Get the supported default filepaths | ||
|
|
||
| The code below shows how to print a list of the default filepaths that H2I will look for the environment file. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, I love this!! |
||
|
|
||
|
|
||
| ```{code-cell} ipython3 | ||
| from pathlib import Path | ||
|
|
||
| from h2integrate import ROOT_DIR | ||
|
|
||
| default_directories = [ROOT_DIR, ROOT_DIR.parent, Path.cwd(), Path.home()] | ||
|
|
||
| print("Supported default environment file locations: \n") | ||
| for folder in default_directories: | ||
| print(folder/".env") | ||
| ``` | ||
|
|
||
| (env_var_debug:is_default_fpath)= | ||
| ### Determine if environment file is in supported default filepath | ||
|
|
||
| If you want to determine whether your environment file is placed in one of the valid locations, the code below will tell you if your environment file is found in any of the default directories: | ||
|
|
||
| ```python | ||
| from pathlib import Path | ||
|
|
||
| from h2integrate import ROOT_DIR | ||
|
|
||
| default_directories = [ROOT_DIR, ROOT_DIR.parent, Path.cwd(), Path.home()] | ||
|
Comment on lines
+56
to
+60
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These imports and defaults are already created in the previous cell, so are unnecessary here. Redundant definitions in cod examples is fairly uncommon unless it's putting an entire workflow in one place at the very end.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see what you're saying. The intention is that each of these blocks could be copy-pasted to a new python file for a user to run for debugging - that is why there is redundant code. I expect this page to be most useful to folks who are potentially a bit newer to python - so I'm trying to keep it very clear the exact chunk of code they can run to debug stuff. Let me know if you still think the redundant code should be avoided. I could also make this a python formatted code cell rather than an executable markdown code cell (so it doesn't actually run when the docs build) but I wanted to have it run so that if any future changes would break this code, then we remember to change it.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the cell doesn't need to run, then I'd say make it a python code block rather than executable cell like most of this documentation page, but this explanation works for me.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! pushed it up! |
||
|
|
||
| env_fpaths = [fpath for folder in default_directories if (fpath:=folder/".env").is_file()] | ||
| if not env_fpaths: | ||
| print("Environment file not found in any supported default directories") | ||
| else: | ||
| print("Environment file(s) found in the following supported default filepath(s):\n") | ||
| txt = "\n".join(str(f) for f in env_fpaths) | ||
| print(txt) | ||
| ``` | ||
|
|
||
| (env_var_debug:nonstandard_fpath)= | ||
| ### Setting environment variables with non-default environment filepath | ||
| If your environment file is not in any of the supported default locations or has a different name than ".env", then you can set the environment variables in your H2I run-script prior to running H2I. | ||
|
|
||
| If you know the filepath of your environment file, you can replace `"/path/to/environment_file/.env"` with the filepath of your environment file in the code below. Below shows an example of setting the environment variables `NLR_API_KEY` and `NLR_API_EMAIL` prior to running Example 1. | ||
|
|
||
| ```python | ||
| from h2integrate import H2IntegrateModel | ||
| from h2integrate.core.env_tools import get_environment_variables | ||
|
|
||
| environment_fpath = "/path/to/environment_file/.env" | ||
|
|
||
| # Set the environment variables prior to running H2I | ||
| env_vars = get_environment_variables("NLR_API_KEY","NLR_API_EMAIL", file_path=environment_fpath, set_variables=True) | ||
|
|
||
| model = H2IntegrateModel("01_onshore_steel_mn.yaml") | ||
| model.setup() | ||
| model.run() | ||
| ``` | ||
|
|
||
| If your environment file **is** in of the default supported directories but is named something different than `".env"`, you could instead set the environment variables prior to running H2I with the following code (replace `"myenv.env"` with the filename of your environment file in the code below): | ||
|
|
||
| ```python | ||
| from h2integrate import H2IntegrateModel | ||
| from h2integrate.core.env_tools import get_environment_variables | ||
|
|
||
| environment_fname = "myenv.env" | ||
|
|
||
| # Set the environment variables prior to running H2I | ||
| env_vars = get_environment_variables("NLR_API_KEY","NLR_API_EMAIL", file_name=environment_fname, set_variables=True) | ||
|
|
||
| model = H2IntegrateModel("01_onshore_steel_mn.yaml") | ||
| model.setup() | ||
| model.run() | ||
| ``` | ||
|
|
||
| (env_var_debug:debug_missing)= | ||
| ## Debugging a missing environment variable | ||
| For any method of setting environment variables, you can use the code below to determine if your environment variables are being loaded properly or being set. | ||
| ```{note} | ||
| If you're setting environment variables with an environment file in a non-standard location or filename, refer to the section above on how to specify the inputs to the `get_environment_variables` function. | ||
| ``` | ||
|
|
||
| Below shows an example of checking if the `NLR_API_KEY` and `NLR_API_EMAIL` environment variables are being **found** and what the values are of the variables that are found: | ||
|
|
||
| ```python | ||
| from pathlib import Path | ||
|
|
||
| from h2integrate.core.env_tools import get_environment_variables | ||
|
|
||
| # Check if environment variables are being found | ||
| env_vars = get_environment_variables("NLR_API_KEY","NLR_API_EMAIL",set_variables=False) | ||
| if not env_vars: | ||
| print("No environment variables found") | ||
| else: | ||
| print("Found environment variables with the values below:") | ||
| for key, val in env_vars.items(): | ||
| print(f"Environment variable `{key}` is set to `{val}`") | ||
|
|
||
| ``` | ||
|
|
||
|
|
||
| Below shows an example of checking if the `NLR_API_KEY` and `NLR_API_EMAIL` environment variables are being **set** and what the values are of the variables that are set: | ||
|
|
||
| ```python | ||
| import os | ||
| from pathlib import Path | ||
|
|
||
| from h2integrate.core.env_tools import get_environment_variables | ||
|
|
||
| # Check if environment variables are being set | ||
| get_environment_variables("NLR_API_KEY","NLR_API_EMAIL",set_variables=True) | ||
|
|
||
| nlr_api_key = os.environ.get("NLR_API_KEY", None) | ||
| nlr_api_email = os.environ.get("NLR_API_EMAIL", None) | ||
|
Comment on lines
+144
to
+145
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah - I suppose my justification is again that I'm trying to make this extremely user-friendly (and thinking about users who may be newer to python) so I'm trying to give them more clues about how these functions work even if it is a bit unnecessary.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My opinion is that's overkill given it's just how dictionaries operate in Python, but I'll let you decide since it's not wrong by any means.
RHammond2 marked this conversation as resolved.
|
||
|
|
||
| set_env_vars = dict(zip(["NLR_API_KEY", "NLR_API_EMAIL"], [nlr_api_key, nlr_api_email])) | ||
|
|
||
| for key,val in set_env_vars.items(): | ||
| if val is None: | ||
| print(f"Environment variable `{key}` was not set") | ||
| else: | ||
| print(f"Environment variable `{key}` is set to `{val}`") | ||
| ``` | ||
|
|
||
| (env_var_debug:manual_setting)= | ||
| ## Quick-fixes to avoid missing environment variable issues | ||
|
|
||
| If you're having issues with setting environment variables and need a quick-workaround, you can manually set environment variables in your runscript prior to running H2I. | ||
|
|
||
| ```{important} | ||
| Do not share code that includes sensitive credentials, such as API keys. The following work-around should only be used for personal code and never shared with others or pushed to a shared or public github repository. | ||
| ``` | ||
|
|
||
| The below example shows a case where the environment variables `NLR_API_KEY` and `NLR_API_EMAIL` are hard-coded prior to running Example 1 (`"nlr-api-key"` would be replaced with your API key and `"name@email.com"` would be replaced with your email) | ||
|
|
||
| ```python | ||
| import os | ||
| from h2integrate import H2IntegrateModel | ||
|
|
||
| # Hard code environment variables | ||
| os.environ["NLR_API_KEY"] = "nlr-api-key" # replace with your api key | ||
| os.environ["NLR_API_EMAIL"] = "name@email.com" # replace with your email | ||
|
|
||
| model = H2IntegrateModel("01_onshore_steel_mn.yaml") | ||
| model.setup() | ||
| model.run() | ||
| ``` | ||
|
|
||
| Another way to set environment variables is shown below: | ||
|
|
||
| ```python | ||
| from h2integrate.core.env_tools import set_env_var | ||
| from h2integrate import H2IntegrateModel | ||
|
|
||
|
|
||
| env_keys = { | ||
| "NLR_API_KEY": "nlr-api-key" # replace with your api key | ||
| "NLR_API_EMAIL": "name@email.com" # replace with your email | ||
| } | ||
|
|
||
| set_env_var(overwrite=True, **env_keys) | ||
|
|
||
| model = H2IntegrateModel("01_onshore_steel_mn.yaml") | ||
| model.setup() | ||
| model.run() | ||
| ``` | ||
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 it would be nice to add what kind of things you would need this for (i.e. wind and solar resource data)
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.
Updated first sentence to this: "H2Integrate can pull data (such as wind and solar resource data, feedstock prices, etc) from public datasets accessible with API keys or user-specific tokens"