PyWAsP License and User Configuration#

PyWAsP’s configuration is controlled through a configuration file, environment variables, or .env files. The configuration affects the download of the global mesoclimate files that are used for the modelling, and the license information.

A TOML (Tom’s Obvious, Minimal Language) configuration file will be sent to you with the fields filled in for your license. You can just copy this to the default location, which is system-dependent but follows standard user configuration directories:

  • Linux: ~/.config/pywasp/pywasp_config.toml

  • macOS: ~/Library/Application Support/pywasp/pywasp_config.toml

  • Windows: C:\Users\<username>\AppData\Roaming\DTU Wind Energy\pywasp\pywasp_config.toml

You can see the actual location of your configuration file by running the following command:

import pywasp as pw
print(pw.user_config.get_config_filepath())

You can manually edit this file if you need, and some options will be provided below. Additionally, you can avoid using this file and use dotenv files, or environment variables instead. More on that below.

Note

Quick-start: you can create a new configuration interactively in the shell by running:

pywasp configure

Or in Python:

import pywasp as pw
pw.user_config.create_config_interactively()

This will guide you through the process of setting up your configuration and setting up your license.

For most users, the default configuration options with "keygen_cloud" licensing is the way to go.

Configuration options#

The configuration options are organized into sections, each containing specific required and optional fields:

[download]
download_prompt = true  # Ask before downloading the global netCDF files, when a terminal is available
download_global_nc_files = true  # Allow PyWAsP to download the global netCDF files on first use

[licensing]
license_type = "keygen_cloud"  # options are "keygen_cloud" or "local"
license_id = "your_license_id"  # required for cloud licensing
activation_token = "your_activation_token"  # required for cloud licensing
redirect_host = "license.windenergy.dtu.dk"  # optional for cloud licensing, to redirect through DTU's server
root_ca_filepath = "/path/to/ca.pem"  # optional for cloud licensing, for custom CA bundle
host = "my_local_license_server.com"  # required for local licensing
port = 12345  # required for local licensing

Configuration Hierarchy#

The application loads configuration settings in a specific order of precedence, with the highest priority being listed first here.

  1. Environment Variables: System environment variables (e.g., set in your shell or Docker environment) will override settings from the TOML file and .env files.

  2. .env files: Settings defined in a .env file (e.g., .env, .env.development) will override settings from the TOML file.

  3. TOML Configuration File: The primary configuration is loaded from a TOML file named pywasp_config.toml located in your application’s configuration directory.

  4. Default Values: If a setting is not found in any of the above sources, the application will use its built-in default value.

Note

This order means that if a setting is defined in both your pywasp_config.toml file and as an environment variable, the environment variable will take precedence.

Environment Variables#

For environments like Docker containers, or for system-wide overrides, using environment variables might be more convenient than a TOML file. Environment variables will override settings found in your pywasp_config.toml or .env files.

All environment variables should be prefixed with PYWASP_. For nested settings, use double underscores (__) to separate the sections and field names.

General Format: PYWASP_<SECTION>__<FIELD_NAME>=<VALUE>

Examples:

  • download_prompt in the [download] section:

    export PYWASP_DOWNLOAD__DOWNLOAD_PROMPT=False
    
  • Local licensing in the [licensing] section:

    export PYWASP_LICENSING__HOST=127.0.0.1
    export PYWASP_LICENSING__PORT=12345
    
  • Cloud licensing in the [licensing] section:

    export PYWASP_LICENSING__LICENSE_ID=a1b2c3d4-e5f6-7890-1234-567890abcdef
    export PYWASP_LICENSING__ACTIVATION_TOKEN=your_activate_token
    

For Windows equivalents, see WindKit’s configuration page, which shows how to set environment variables in Windows Command Prompt or Windows PowerShell.

Note

The WAsP core reads its license settings from pywasp_config.toml only — it does not see the PYWASP_* environment variables. To bridge this, PyWAsP writes the effective settings (with any environment-variable overrides applied) to the configuration file at each licensed calculation, whenever they differ from what is on disk. The settings themselves are resolved once, at the first licensed calculation of a session: environment variables changed after that point are picked up in a new Python session. An environment-variable override is persisted in the file and remains in effect after the variable is unset; re-run pywasp configure (or edit the file) to change it back.

dotenv file#

You can also use a .env file to define your environment variables. This file must be in the directory that you launch your python interpreter from. The file can hold key-value pairs that are the same as the environment variables listed above.

PyWAsP licensing#

PyWAsP offers two types of licensing, local licensing and cloud licensing. Most users will be using cloud licensing.

When is the license checked?#

Importing pywasp never contacts the license server: import pywasp works offline and does not require a configuration. The configuration is read and the license is used only when you call a function that runs the WAsP model (e.g. generalize, downscale, predict_wwc, site effects, or the LINCOM functions). If no valid configuration is found at that point, you get an error explaining how to set one up.

To check your license before starting a large calculation, run:

pywasp status

For cloud licenses, the maximum number of points per run is checked before each model run, and a run with too many points raises pywasp.PointsLimitError. The limit is fetched from the license server at most once per session and cached locally for 24 hours, so repeated runs and parallel workers do not generate extra license traffic. If the license server cannot be reached, the point check is skipped with a warning and the calculation proceeds; the license itself is still enforced by the WAsP core.

Use cloud licensing server#

The cloud licensing server is used when you use a Gold, Silver or Bronze Tier license with a limit on the model runs and PyWAsP is installed in a machine with access to internet. In this case, the license type is listed as keygen_cloud, and you will have a license_id and activation_token. These values are secrets and should be treated like a password.

When you run a licensed calculation, PyWAsP reads these fields and connects to our API provider keygen at api.keygen.sh. If this is not acceptable from your IT department, you can instead contact DTU’s server by adding a redirect_host line to your configuration that points at license.windenergy.dtu.dk.

redirect_host = "license.windenergy.dtu.dk"

Another potential cause of failure is the failure of the TLS peering. In this case you should see an SSL error. By default, the TLS connection uses the system’s root certificates to validate peers. In some corporate environments, you may have a custom certificate infrastructure, that requires you to setup a custom or self-signed Certificate Authority (CA). In this case you can add a root_ca_filepath field, that points to the CA bundle that includes this additional certificate.

root_ca_filepath = "/path/to/file.pem"

Use a local licensing server#

If you are using an Enterprise license, i.e. PyWAsP is installed in on-premise servers at a research institution or a big company, your company will have a licensing server that runs on its internal network. In this case, you don’t need to worry about the license_id and activation_token, as those are part of the license server. Instead, you need to specify the host and port that are provided by your institution.

This means that you will need to edit the licensing part of your TOML file to look like below, replacing the host and port with your values.

[licensing]
license_type = "local"
host = "127.0.0.1"
port = 34523

The connection to this server is checked when you set up the configuration with pywasp configure, and used when you run licensed calculations.

The global mesoclimate#

In addition to license configuration, the configuration file controls the download of the global mesoclimate: a few NetCDF files with long-term mean atmospheric fields derived from the ERA5 and CFSR reanalyses (surface pressure, temperature, humidity and lapse rate for air density; geostrophic shear for baroclinicity; temperature and boundary-layer-height scales for stability). Please refer to the WAsP documentation for further details.

Download Options#

Nothing is downloaded when PyWAsP is imported. The files are fetched either explicitly, or on first use of a function that needs them (pywasp.get_air_density, pywasp.wasp.get_climate, …):

  • Explicitly: run pywasp mesoclimate download in a terminal (or call pywasp.download_mesoclimate()). This downloads the missing files without asking and regardless of the settings below; pywasp mesoclimate download --all re-downloads everything. Use it when preparing a container image, an HPC environment or any machine without an interactive terminal. pywasp mesoclimate status (pywasp.mesoclimate_status()) lists the files and whether each is present, and pywasp mesoclimate path (pywasp.mesoclimate_path()) prints their directory.

  • On first use: governed by the two [download] settings. download_global_nc_files says whether PyWAsP may download at all; download_prompt says whether to ask first. Both default to true when they are not set; pywasp configure suggests download_prompt = false, so accepting its suggestions means the files are downloaded without asking.

files present?

download_prompt

download_global_nc_files

behavior at first use of a function needing the files

Yes

any

any

Nothing happens (data exists)

No

True

True

In a terminal: a y/n prompt, then download. Without one (notebook, CI, container, cron/batch job, or output redirected to a file): download without asking.

No

False

True

Download without asking

No

any

False

pywasp.MesoclimateMissingError is raised; its message says how to get the files

If the download is declined at the prompt, there is no internet connection, or a download fails, MesoclimateMissingError is raised as well. Downloads try Zenodo first and fall back to the DTU Data mirror.

Headless environments (containers, CI, HPC)

Either pre-seed the files with pywasp mesoclimate download when building the image, or rely on the first-use download and make sure no prompt can block: with the default settings PyWAsP already detects that there is no terminal to prompt in and downloads without asking, but you can be explicit with

export PYWASP_DOWNLOAD__DOWNLOAD_PROMPT=False          # never ask
export PYWASP_DOWNLOAD__DOWNLOAD_GLOBAL_NC_FILES=True  # allow the download

or forbid first-use downloads altogether with PYWASP_DOWNLOAD__DOWNLOAD_GLOBAL_NC_FILES=False (you then get MesoclimateMissingError unless the files were placed manually). These [download] settings are read on their own, so they apply whether or not a licensing configuration exists. On Linux the mesoclimate directory follows XDG_DATA_HOME; on every platform pywasp mesoclimate path prints the directory in use, so files can be placed there in an image or a shared location.

Manually downloading the mesoclimate files#

If you cannot use the automatic download (e.g., no internet access during installation, corporate firewall restrictions), you can manually download the mesoclimate files and place them in the correct location.

Mesoclimate directory location

The files must be placed in PyWAsP’s user data directory:

  • Linux: ~/.local/share/pywasp/

  • macOS: ~/Library/Application Support/pywasp/

  • Windows: C:\Users\<username>\AppData\Roaming\DTU Wind Energy\pywasp\

To find the exact path on your system, run pywasp mesoclimate path in a terminal, or in Python:

import pywasp as pw
print(pw.mesoclimate_path())

pywasp mesoclimate status then confirms that every file is in place.

Required files

Download the following files and save them with the exact filenames shown below:

Required filename

Download URL (Zenodo)

Version2_202406241502_meandgdz_2010_2017_CFSRv3.nc

meandgdz_2010_2017_CFSR.nc

10yr_mean_rhoinp_ERA5v1.nc

10yr_mean_rhoinp_ERA5v1.nc

10yr_mean_rhoinp_CFSRv1.nc

10yr_mean_rhoinp_CFSRv1.nc

Version2_202406251020_ERA5-baro.nc

ERA5-baro.nc

Version2_202406251020_ERA5-meso.nc

ERA5-meso.nc

Warning

Some files have different names on Zenodo than the required local filename. You must rename the downloaded files to match the “Required filename” column exactly.

Alternative download source (DTU Data)

If Zenodo is unavailable, the files can also be downloaded from DTU Data:

  • meandgdz → rename to Version2_202406241502_meandgdz_2010_2017_CFSRv3.nc

  • rhoinp ERA5 → rename to 10yr_mean_rhoinp_ERA5v1.nc

  • rhoinp CFSR → rename to 10yr_mean_rhoinp_CFSRv1.nc

  • ERA5-baro → rename to Version2_202406251020_ERA5-baro.nc

  • ERA5-meso → rename to Version2_202406251020_ERA5-meso.nc

Configuration CLI#

PyWAsP provides a command-line interface (CLI) for managing your user configuration. You can access this CLI by running the following command in your terminal:

pywasp configure

This command will guide you through the process of setting up your configuration and license interactively.

To view your current configuration, you can run:

pywasp status

To fetch the global mesoclimate files up front, list them, or print their directory (see Download options):

pywasp mesoclimate download
pywasp mesoclimate status
pywasp mesoclimate path

Configuration API#

PyWAsP provides a few functions for viewing information about your configuration, and license. If no valid configuration exists, they raise a LicenseConfigError explaining how to set one up, so they are also useful for debugging a configuration.

These functions can be accessed via the pywasp.user_config API.

Setting up a new configuration interactively#

You can create a new configuration interactively by running the following command:

import pywasp as pw
pw.user_config.create_config_interactively()

This will guide you through the process of setting up your configuration and setting up your license.

Seeing your configuration file location and license details#

To see the location of your configuration file, you can use the following command:

import pywasp as pw
print(pw.user_config.get_config_filepath())

To view your current configuration, you can use the following command:

import pywasp as pw
pw.user_config.view()

Get remaining runs and days until expiration#

To check your remaining runs, you can use the following command:

import pywasp as pw
runs = pw.user_config.get_remaining_runs()
print(f"Remaining runs: {runs}")

This only works for cloud licensing, and will return None if you are using local licensing.

To check the days until your license expires, you can use the following command:

import pywasp as pw
days = pw.user_config.days_until_license_expiry()
print(f"Days until expiration: {days}")

This will return the number of days until your license expires, or None if you are using local licensing.