Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7e52698
added draft of generalizing api key tools
elenya-grant May 26, 2026
de7ddc5
generalized api methods properly
elenya-grant Jul 2, 2026
6c19042
moved base environment var functions to core
elenya-grant Jul 2, 2026
ed387c8
removed old work
elenya-grant Jul 2, 2026
2a70ff1
Merge remote-tracking branch 'h2i_upstream/develop' into generalize_api
elenya-grant Jul 2, 2026
9a0b62d
minor clean-ups to generalized stuff
elenya-grant Jul 2, 2026
05f04f3
removed commented out code
elenya-grant Jul 2, 2026
c965982
removed usage of globals()
elenya-grant Jul 2, 2026
14733b4
started adding in test file
elenya-grant Jul 2, 2026
ec139c7
Merge branch 'develop' into generalize_api
johnjasa Jul 6, 2026
e48aa67
added another test and bugfix in loading environment variable from file
elenya-grant Jul 8, 2026
fc84498
removed commented out code and added todos
elenya-grant Jul 8, 2026
3a1376d
updated so that setter method is called after _get_env_with_fallback
elenya-grant Jul 8, 2026
7ab6dae
Merge remote-tracking branch 'origin/generalize_api' into generalize_api
elenya-grant Jul 8, 2026
6b9a606
added doc strings to setter methods in nlr_developer_api_keys.py
elenya-grant Jul 9, 2026
25ec9b6
Merge remote-tracking branch 'h2i_upstream/develop' into generalize_api
elenya-grant Jul 13, 2026
a158d65
refactored environment tools with help from Rob
elenya-grant Jul 14, 2026
ea793df
minor changes to nlr_developer_api_keys
elenya-grant Jul 14, 2026
7d0b3fd
updated tests for env_tools
elenya-grant Jul 14, 2026
c05f63b
updated conftest.py files
elenya-grant Jul 14, 2026
c995469
updated doc page
elenya-grant Jul 14, 2026
f71c24f
updated conftest.py files and get_environment_variables
elenya-grant Jul 15, 2026
7c2c723
added doc page for debugging environment variable problems
elenya-grant Jul 15, 2026
7e1a67e
updated doc page so formatting is nice
elenya-grant Jul 15, 2026
e5dc052
typo fix in model_overview.md
elenya-grant Jul 15, 2026
c278ba5
Merge remote-tracking branch 'h2i_upstream/develop' into generalize_api
elenya-grant Jul 20, 2026
1c979c8
updates to doc pages
elenya-grant Jul 20, 2026
dabdc6f
added set_vars as input to get_nlr_developer_api_credential and updat…
elenya-grant Jul 20, 2026
33c3875
Merge branch 'develop' into generalize_api
johnjasa Jul 21, 2026
9909098
updated debugging environment variables doc page
elenya-grant Jul 22, 2026
e5f442f
cleaned up some of test_env_tools.py
elenya-grant Jul 22, 2026
0233866
finished cleanups to test_env_tools.py
elenya-grant Jul 22, 2026
d2185da
updated conftest.py files
elenya-grant Jul 22, 2026
ac6959d
Merge branch 'generalize_api' of github.com:elenya-grant/GreenHEART i…
elenya-grant Jul 22, 2026
643340b
updated changelog
elenya-grant Jul 22, 2026
05de2e5
Added new method to check for duplicate defined environment variables…
elenya-grant Jul 22, 2026
0997741
changed executable code cell to python code block in doc page
elenya-grant Jul 23, 2026
e133caf
commiting johns doc changes
elenya-grant Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
- Added infrastructure for running models with non-hourly time steps via a class attribute `_time_step_bounds` and sets new time step bounds of 5-minutes to 1-hour for the grid components. [PR 653](https://github.com/NatLabRockies/H2Integrate/pull/653) and [PR 671](https://github.com/NatLabRockies/H2Integrate/pull/671)
- Remove demand-related outputs from storage performance models and replace usage with demand components [PR 666](https://github.com/NatLabRockies/H2Integrate/pull/666)
- Added a compressed gas hydrogen storage model [PR 680](https://github.com/NatLabRockies/H2Integrate/pull/680)
- Generalized functions for retrieving and setting environment variables in `h2integrate/core/test/test_env_tools.py`. The main function used to get and/or set environment variables is `get_environment_variables`, which is now used by the `get_nlr_developer_api_key` and `get_nlr_developer_api_email` functions [PR 798](https://github.com/NatLabRockies/H2Integrate/pull/798)

## 0.7.2 [April 9, 2026]

Expand Down
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ parts:
- file: misc_resources/glossary
- file: misc_resources/defining_filepaths
- file: misc_resources/turbine_models_library_preprocessing
- file: misc_resources/debugging_environment_variables
- caption: API Reference
maxdepth: 3
chapters:
Expand Down
57 changes: 44 additions & 13 deletions docs/getting_started/environment_variables.md
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)

Copy link
Copy Markdown
Collaborator

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)

Copy link
Copy Markdown
Collaborator Author

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"

- `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)=
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)=

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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'
```
197 changes: 197 additions & 0 deletions docs/misc_resources/debugging_environment_variables.md
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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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.

@elenya-grant elenya-grant Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None is the default value for .get() when there isn't a match, so it's not really needed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The 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.

Comment thread
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()
```
2 changes: 2 additions & 0 deletions docs/technology_models/feedstocks.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
(feedstocks:intro)=
# Feedstock Models

Feedstock models in H2Integrate represent any resource input that is consumed by technologies in your plant that comes from outside your designed system boundary (and not generated internally), such as natural gas, water, electricity from the grid, or any other material input.
Expand Down Expand Up @@ -94,6 +95,7 @@ The feedstock model outputs cost and performance information about the consumed
- `rated_{commodity}_production`: this is equal to the the `rated_capacity` of the feedstock model (in `commodity_rate_units`)
- `capacity_factor`: ratio of the feedstock consumed to the maximum feedstock available

(feedstocks:eia_ng_price)=
## EIA Natural Gas Pricing

A special case of the feedstock cost model `EIANaturalGasFeedstockCostModel` exists to enable users
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/model_overview.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

(model-overview)=
# Model Overview
Currently, H2I recognizes four types of models:
Currently, H2I recognizes five types of models:

- [Resource](#resource)
- [Converter](#converters)
Expand Down
Loading
Loading