Enviable (Enviable v1.6.0)

View Source

Enviable is a small collection of functions to improve Elixir project configuration via environment variables as proposed under the 12-factor application model. It works well with configuration environment loaders like Dotenvy or Nvir and provides robust value conversion like jetenv.

Usage

Enviable will typically be imported in config/runtime.exs after Config, but may be used anywhere that environment variables are read.

# config/runtime.exs
import Config
import Enviable

client = fetch_env!("CLIENT")
Dotenvy.source([".env", ".env.#{client}", get_env()], side_effect: &put_env/1)

# Before
#
# config :my_app,
#   key: System.fetch_env!("SECRET_KEY"),
#   port: System.fetch_env!("PORT") |> String.to_integer(),
#   ssl: System.get_env("SSL_ENABLED") in ~w[1 true]

# After
config :my_app,
  key: fetch_env!("SECRET_KEY"),
  port: fetch_env_as_integer!("PORT"),
  ssl: get_env_as_boolean("SSL_ENABLED")

Info

When using Dotenvy, the use of a side_effect that calls System.put_env/1 is required, as Enviable works with the system environment variable table. Future versions of Enviable may offer ways to work with the default Dotenvy side effect.

Configuration

Envible has two compile-time options.

  • :boolean_downcase: Sets the default value for case-folding boolean conversions. Can be set to :default, :ascii, :greek, or :turkic. The boolean value true will be treated as :default.

    config :enviable, :boolean_downcase, true
    config :enviable, :boolean_downcase, :default
    config :enviable, :boolean_downcase, :ascii

    If unspecified, defaults to false.

    The next major version of Enviable will change this to :default, as it should not matter whether the matched value is true, TRUE, or True for boolean tests.

  • :json_engine: The default JSON engine to use for JSON conversions. This may be provided as a module/0 (which must export decode/1) or a mfa/0 tuple. When provided with a mfa/0, the variable value will be passed as the first parameter.

    If the engine produces {:ok, json_value} or an expected JSON type result, it will be considered successful. Any other result will be treated as failure.

    The default JSON engine is :json if the Erlang/OTP :json module is available (Erlang/OTP 27+) or provided by json_polyfill. Otherwise, Jason is the default engine.

    config :enviable, :json_engine, :thoas
    config :enviable, :json_engine, {Jason, :decode, [[floats: :decimals]]}

Summary

Functions

Set an environment variable value only if it is not yet set. This is a convenience wrapper around System.put_env/2 and System.get_env/2.

Functions: Conversion

Returns the value of an environment variable converted to the target type as {:ok, term()} or :error if the variable is unset.

Returns the value of an environment variable converted to the target type or raises an exception if the variable is unset.

Returns the value of an environment variable converted to atom/0 as {:ok, atom()} or :error if the variable is unset.

Returns the value of an environment variable converted to atom/0 or raises an exception if the variable is unset.

Returns the value of an environment variable decoded as a base 16 string.

Returns the value of an environment variable decoded as a base 16 string.

Returns the value of an environment variable decoded as a base 32 string.

Returns the value of an environment variable decoded as a base 32 string.

Returns the value of an environment variable decoded as a base 64 string.

Returns the value of an environment variable decoded as a base 64 string.

Returns the value of an environment variable converted to a boolean/0 value as {:ok, boolean()} or :error if the variable is unset.

Returns the value of an environment variable converted to a boolean/0 value or raises an exception if the variable is unset.

Returns the value of an environment variable converted to a charlist/0 as {:ok, charlist()} or :error if the variable is unset.

Returns the value of an environment variable converted to a charlist/0 or raises an exception if the variable is unset.

Returns the value of an environment variable converted to a Decimal.t/0 value as {:ok, Decimal.t()} or :error if the variable is unset.

Returns the value of an environment variable converted to a Decimal.t/0 value or :error if the variable is unset.

Returns the value of an environment variable parsed and evaluated as Elixir code with the result as {:ok, term()}, or :error if the environment variable is not set.

Returns the value of an environment variable parsed and evaluated as Elixir code with the result , or raises an exception if the environment variable is not set.

Returns the value of an environment variable parsed and evaluated as Erlang code with the result as {:ok, term()}, or :error if the environment variable is not set.

Returns the value of an environment variable parsed and evaluated as Erlang code with the result , or raises an exception if the environment variable is not set.

Returns the value of an environment variable converted to a float/0 value as {:ok, float()} or :error if the variable is unset.

Returns the value of an environment variable converted to a float/0 value or :error if the variable is unset.

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Returns the value of an environment variable converted to a integer/0 value as {:ok, integer()} or :error if the variable is unset.

Returns the value of an environment variable converted to a integer/0 value or raises an exception if the variable is unset.

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value as {:ok, Conversion.json()} or :error if the variable is unset.

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value or raises an exception if the variable is unset.

Returns the value of an environment variable parsed as a delimiter-separated list.

Returns the value of an environment variable parsed as a delimiter-separated list.

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 as {:ok, atom()} or :error if the variable is unset.

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 or raises an exception if the variable is unset.

Returns the value of an environment variable converted to module/0 as {:ok, module()} or :error if the variable is unset.

Returns the value of an environment variable converted to module/0 or raises an exception if the variable is unset.

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 as {:ok, value} or :error if the variable is unset.

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 or raises an exception if the variable is unset.

Returns the value of an environment variable converted to an existing atom/0 as {:ok, atom()} or :error if the variable is unset.

Returns the value of an environment variable converted to an existing atom/0 or raises an exception if the variable is unset.

Returns the value of an environment variable converted to module/0 as {:ok, module()} or :error if the variable is unset. The resulting module/0 must already exist.

Returns the value of an environment variable converted to module/0 or raises an exception if the variable is unset. The resulting module/0 must already exist.

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Returns the value of an environment variable as {:ok, t:boolean/0} value or :error if the variable is unset. See fetch_env_as_boolean/2 or more details.

Returns the value of an environment variable converted to a boolean/0 value or raises an exception if the variable is unset. See fetch_env_as_boolean!/2 for details.

Returns the value of an environment variable as {:ok, t:integer/0} or :error if the variable is unset. See fetch_env_as_integer/2 for details.

Returns the value of an environment variable converted to a integer/0 value raises an exception if the variable is unset. See fetch_env_as_integer!/2 for details.

Returns the value of an environment variable converted to the target type or a default value if the variable is unset. If no default is provided, nil is returned (unless converting to :boolean, which will return false).

Returns the value of an environment variable converted to atom/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Returns the value of an environment variable decoded as a base 16 string.

Returns the value of an environment variable decoded as a base 32 string.

Returns the value of an environment variable decoded as a base 64 string.

Returns the value of an environment variable converted to a boolean/0 value, or a default value if the variable is unset. If no default is provided, false will be returned.

Returns the value of an environment variable converted to a charlist/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Returns the value of an environment variable converted to a Decimal.t/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Returns the value of an environment variable parsed and evaluated as Elixir code, or nil if the environment variable is not set.

Returns the value of an environment variable parsed and evaluated as Erlang code, or nil if the environment variable is not set.

Returns the value of an environment variable converted to a float/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Returns the value of an environment variable converted to a integer/0 value or a default value if the variable is unset. If no default is provided, nil is returned.

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Returns the value of an environment variable parsed as a delimiter-separated list.

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 or a default value if the variable is unset. If no default is provided, nil will be returned.

Returns the value of an environment variable converted to module/0 or a default value if the variable is unset. If no default is provided, nil will be returned.

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 or nil if the variable is unset.

Returns the value of an environment variable converted to an existing atom/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Returns the value of an environment variable converted to module/0 or a default value if the variable is unset. If no default is provided, nil will be returned. The resulting module/0 must already exist.

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Returns the value of an environment variable converted to a boolean/0 value. See get_env_as_boolean/2 for more details.

Returns the value of an environment variable converted to a integer/0 value or nil if the variable is not set and a default is not provided. See get_env_as_integer/2 for details.

Functions: Delegates

Deletes an environment variable, removing varname from the environment.

Returns the value of the given environment variable or :error if not found.

Returns the value of the given environment variable or raises if not found.

Returns all system environment variables.

Returns the value of the given environment variable.

Sets multiple environment variables.

Sets an environment variable value.

Functions

put_env_new(varname, value)

@spec put_env_new(String.t(), String.t()) :: :ok

Set an environment variable value only if it is not yet set. This is a convenience wrapper around System.put_env/2 and System.get_env/2.

Examples

iex> Enviable.put_env_new("PORT", "3000")
:ok
iex> Enviable.get_env("PORT")
"3000"
iex> Enviable.put_env_new("PORT", "5000")
:ok
iex> Enviable.get_env("PORT")
"3000"

Functions: Conversion

fetch_env_as(varname, type, opts \\ [])

(since 1.1.0)
@spec fetch_env_as(String.t(), Enviable.Conversion.conversion(), keyword()) ::
  {:ok, term()} | :error

Returns the value of an environment variable converted to the target type as {:ok, term()} or :error if the variable is unset.

Supported primitive conversions are:

Supported encoded conversions are:

See Enviable.Conversion for supported type conversions and options, but note that any default values are ignored for fetch_env_as/3 and related fetch_env_as_* functions.

Examples

iex> Enviable.fetch_env_as("UNSET", :atom)
:error

iex> Enviable.fetch_env_as("UNSET", :float)
:error

iex> Enviable.fetch_env_as("UNSET", :base16)
:error

iex> Enviable.put_env("NAME", "fetch_env_as")
iex> Enviable.fetch_env_as("NAME", :atom)
{:ok, :fetch_env_as}

iex> Enviable.put_env("NAME", "FETCH_ENV_AS")
iex> Enviable.fetch_env_as("NAME", :safe_atom, downcase: true)
{:ok, :fetch_env_as}

iex> Enviable.fetch_env_as("UNSET", :float, default: "3.5")
:error

iex> Enviable.fetch_env_as("UNSET", :float, default: 3.5)
:error

iex> Enviable.put_env("FLOAT", "3")
iex> Enviable.fetch_env_as("FLOAT", :float)
{:ok, 3.0}

iex> Enviable.put_env("FLOAT", "3.1")
iex> Enviable.fetch_env_as("FLOAT", :float)
{:ok, 3.1}

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as("NAME", :base16, case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as("NAME", {:base16, :string}, case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as("NAME", {:base16, :atom}, case: :lower, downcase: true)
{:ok, :red}

fetch_env_as!(varname, type, opts \\ [])

(since 1.1.0)
@spec fetch_env_as!(String.t(), Enviable.Conversion.conversion(), keyword()) :: term()

Returns the value of an environment variable converted to the target type or raises an exception if the variable is unset.

Supported primitive conversions are:

Supported encoded conversions are:

See Enviable.Conversion for supported type conversions and options, but note that any documented default values are ignored for fetch_env_as!/3 and related fetch_env_as_*! functions.

Examples

iex> Enviable.fetch_env_as!("UNSET", :atom)
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.fetch_env_as!("UNSET", :float)
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.fetch_env_as!("UNSET", :base16)
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "fetch_env_as!")
iex> Enviable.fetch_env_as!("NAME", :atom)
:fetch_env_as!

iex> Enviable.put_env("NAME", "FETCH_ENV_AS!")
iex> Enviable.fetch_env_as!("NAME", :safe_atom, downcase: true)
:fetch_env_as!

iex> Enviable.fetch_env_as!("UNSET", :float, default: "3.5")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.fetch_env_as!("UNSET", :float, default: 3.5)
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("FLOAT", "3")
iex> Enviable.fetch_env_as!("FLOAT", :float)
3.0

iex> Enviable.put_env("FLOAT", "3.1")
iex> Enviable.fetch_env_as!("FLOAT", :float)
3.1

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as!("NAME", :base16, case: :lower)
"RED"
iex> Enviable.fetch_env_as!("NAME", {:base16, :string}, case: :lower)
"RED"
iex> Enviable.fetch_env_as!("NAME", {:base16, :atom}, case: :lower, downcase: true)
:red

fetch_env_as_atom(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_atom(String.t(), [
  {:allowed, [atom()]} | Enviable.Conversion.opt_downcase()
]) ::
  {:ok, atom()} | :error

Returns the value of an environment variable converted to atom/0 as {:ok, atom()} or :error if the variable is unset.

Untrusted Input

This conversion routine uses String.to_atom/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

Examples

iex> Enviable.fetch_env_as_atom("UNSET")
:error

iex> Enviable.put_env("NAME", "fetch_env_as_atom")
iex> Enviable.fetch_env_as_atom("NAME")
{:ok,  :fetch_env_as_atom}

fetch_env_as_atom!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_atom!(String.t(), [
  {:allowed, [atom()]} | Enviable.Conversion.opt_downcase()
]) ::
  atom()

Returns the value of an environment variable converted to atom/0 or raises an exception if the variable is unset.

Untrusted Input

This conversion routine uses String.to_atom/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

Examples

iex> Enviable.fetch_env_as_atom!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "fetch_env_as_atom!")
iex> Enviable.fetch_env_as_atom!("NAME")
:fetch_env_as_atom!

fetch_env_as_base16(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base16(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed
) :: :error | {:ok, term()}

Returns the value of an environment variable decoded as a base 16 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode16/2, which must be :upper, :lower, or :mixed.

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base16("NAME", case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base16("NAME", as: :string, case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base16("NAME", as: :atom, case: :lower, downcase: true)
{:ok, :red}

fetch_env_as_base16!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base16!(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed
) :: term()

Returns the value of an environment variable decoded as a base 16 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode16/2, which must be :upper, :lower, or :mixed.

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base16!("NAME", case: :lower)
"RED"
iex> Enviable.fetch_env_as_base16!("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.fetch_env_as_base16!("NAME", as: :atom, case: :lower, downcase: true)
:red

fetch_env_as_base32(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base32(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: :error | {:ok, term()}

Returns the value of an environment variable decoded as a base 32 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to Base.decode32/2. The default is false (the opposite of Base.decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base32("NAME", case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base32("NAME", as: :string, case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base32("NAME", as: :atom, case: :lower, downcase: true)
{:ok, :red}

fetch_env_as_base32!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base32!(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: term()

Returns the value of an environment variable decoded as a base 32 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to Base.decode32/2. The default is false (the opposite of Base.decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base32!("NAME", case: :lower)
"RED"
iex> Enviable.fetch_env_as_base32!("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.fetch_env_as_base32!("NAME", as: :atom, case: :lower, downcase: true)
:red

fetch_env_as_base64(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base64(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: :error | {:ok, term()}

Returns the value of an environment variable decoded as a base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base64("NAME", padding: false)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base64("NAME", as: :string, padding: true)
{:ok, "RED"}
iex> Enviable.fetch_env_as_base64("NAME", as: :atom, downcase: true, padding: false)
{:ok, :red}

fetch_env_as_base64!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_base64!(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: term()

Returns the value of an environment variable decoded as a base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_base64!("NAME", padding: false)
"RED"
iex> Enviable.fetch_env_as_base64!("NAME", as: :string, padding: true)
"RED"
iex> Enviable.fetch_env_as_base64!("NAME", as: :atom, downcase: true, padding: false)
:red

fetch_env_as_boolean(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_boolean(String.t(), [
  Enviable.Conversion.opt_downcase() | {:truthy | :falsy, [binary()]}
]) :: {:ok, boolean()} | :error

Returns the value of an environment variable converted to a boolean/0 value as {:ok, boolean()} or :error if the variable is unset.

This function will always result in a boolean/0 value. Unless configured with truthy or falsy, only the values "1" and "true" will be converted to true and any other value will result in false.

Options

  • :truthy: a list of string values to be compared for truth values. If the value of the environment variable matches these values, true will be returned; other values will result in false. Mutually exclusive with falsy.

  • :falsy: a list of string values to be compared for false values. If the value of the environment variable matches these values, false will be returned; other values will result in true. Mutually exclusive with truthy.

  • :downcase: either false (the default), true, or the mode parameter for String.downcase/2 (:default, :ascii, :greek, or :turkic).

    The default :downcase value for boolean conversions can be changed at compile time through application configuration:

    config :enviable, :boolean_downcase, true
    config :enviable, :boolean_downcase, :default
    config :enviable, :boolean_downcase, :ascii

    In the next major version of Enviable, the default :downcase value will be changing to :default.

Examples

iex> Enviable.fetch_env_as_boolean("UNSET")
:error

iex> Enviable.put_env("FLAG", "1")
iex> Enviable.fetch_env_as_boolean("FLAG")
{:ok, true}

iex> Enviable.put_env("FLAG", "something")
iex> Enviable.fetch_env_as_boolean("FLAG")
{:ok, false}

iex> Enviable.put_env("FLAG", "oui")
iex> Enviable.fetch_env_as_boolean("FLAG", truthy: ["oui"])
{:ok, true}

iex> Enviable.put_env("FLAG", "OUI")
iex> Enviable.fetch_env_as_boolean("FLAG", truthy: ["oui"])
{:ok, false}

iex> Enviable.put_env("FLAG", "OUI")
iex> Enviable.fetch_env_as_boolean("FLAG", truthy: ["oui"], downcase: true)
{:ok, true}

iex> Enviable.put_env("FLAG", "NON")
iex> Enviable.fetch_env_as_boolean("FLAG", falsy: ["non"])
{:ok, true}

iex> Enviable.put_env("FLAG", "NON")
iex> Enviable.fetch_env_as_boolean("FLAG", falsy: ["non"], downcase: true)
{:ok, false}

fetch_env_as_boolean!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_boolean!(String.t(), [
  Enviable.Conversion.opt_downcase() | {:truthy | :falsy, [binary()]}
]) :: boolean()

Returns the value of an environment variable converted to a boolean/0 value or raises an exception if the variable is unset.

This function will always result in a boolean/0 value. Unless configured with truthy or falsy, only the values "1" and "true" will be converted to true and any other value will result in false.

Options

  • :truthy: a list of string values to be compared for truth values. If the value of the environment variable matches these values, true will be returned; other values will result in false. Mutually exclusive with falsy.

  • :falsy: a list of string values to be compared for false values. If the value of the environment variable matches these values, false will be returned; other values will result in true. Mutually exclusive with truthy.

  • :downcase: either false (the default), true, or the mode parameter for String.downcase/2 (:default, :ascii, :greek, or :turkic).

    The default :downcase value for boolean conversions can be changed at compile time through application configuration:

    config :enviable, :boolean_downcase, true
    config :enviable, :boolean_downcase, :default
    config :enviable, :boolean_downcase, :ascii

    In the next major version of Enviable, the default :downcase value will be changing to :default.

Examples

iex> Enviable.fetch_env_as_boolean!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("FLAG", "1")
iex> Enviable.fetch_env_as_boolean!("FLAG")
true

iex> Enviable.put_env("FLAG", "something")
iex> Enviable.fetch_env_as_boolean!("FLAG")
false

iex> Enviable.put_env("FLAG", "oui")
iex> Enviable.fetch_env_as_boolean!("FLAG", truthy: ["oui"])
true

iex> Enviable.put_env("FLAG", "OUI")
iex> Enviable.fetch_env_as_boolean!("FLAG", truthy: ["oui"])
false

iex> Enviable.put_env("FLAG", "OUI")
iex> Enviable.fetch_env_as_boolean!("FLAG", truthy: ["oui"], downcase: true)
true

iex> Enviable.put_env("FLAG", "NON")
iex> Enviable.fetch_env_as_boolean!("FLAG", falsy: ["non"])
true

iex> Enviable.put_env("FLAG", "NON")
iex> Enviable.fetch_env_as_boolean!("FLAG", falsy: ["non"], downcase: true)
false

fetch_env_as_charlist(varname)

(since 1.3.0)
@spec fetch_env_as_charlist(String.t()) :: {:ok, charlist()} | :error

Returns the value of an environment variable converted to a charlist/0 as {:ok, charlist()} or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_charlist("UNSET")
:error

iex> Enviable.put_env("NAME", "fetch_env_as")
iex> Enviable.fetch_env_as_charlist("NAME")
{:ok, ~c"fetch_env_as"}

fetch_env_as_charlist!(varname)

(since 1.3.0)
@spec fetch_env_as_charlist!(String.t()) :: charlist()

Returns the value of an environment variable converted to a charlist/0 or raises an exception if the variable is unset.

Examples

iex> Enviable.fetch_env_as_charlist!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "fetch_env_as")
iex> Enviable.fetch_env_as_charlist!("NAME")
~c"fetch_env_as"

fetch_env_as_decimal(varname)

(since 1.6.0)
@spec fetch_env_as_decimal(String.t()) :: {:ok, Decimal.t()} | :error

Returns the value of an environment variable converted to a Decimal.t/0 value as {:ok, Decimal.t()} or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_decimal("UNSET")
:error

iex> Enviable.put_env("DECIMAL", "1")
iex> Enviable.fetch_env_as_decimal("DECIMAL")
{:ok, Decimal.new("1")}

iex> Enviable.put_env("DECIMAL", "ff")
iex> Enviable.fetch_env_as_decimal("DECIMAL")
** (Enviable.ConversionError) could not convert environment variable "DECIMAL" to type decimal

fetch_env_as_decimal!(varname)

(since 1.6.0)
@spec fetch_env_as_decimal!(String.t()) :: Decimal.t()

Returns the value of an environment variable converted to a Decimal.t/0 value or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_decimal!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("DECIMAL", "1")
iex> Enviable.fetch_env_as_decimal!("DECIMAL")
Decimal.new("1")

iex> Enviable.put_env("DECIMAL", "ff")
iex> Enviable.fetch_env_as_decimal!("DECIMAL")
** (Enviable.ConversionError) could not convert environment variable "DECIMAL" to type decimal

fetch_env_as_elixir(varname)

(since 1.3.0)
@spec fetch_env_as_elixir(String.t()) :: {:ok, term()} | :error

Returns the value of an environment variable parsed and evaluated as Elixir code with the result as {:ok, term()}, or :error if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :elixir}.

Untrusted Input

This function parses (with Code.string_to_quoted/1) and evaluates (with Code.eval_quoted/1) elixir code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.fetch_env_as_elixir("UNSET")
:error

iex> Enviable.put_env("TERM", "11000..11100//3")
iex> Enviable.fetch_env_as_elixir("TERM")
{:ok, 11000..11100//3}

fetch_env_as_elixir!(varname)

(since 1.3.0)
@spec fetch_env_as_elixir!(String.t()) :: term()

Returns the value of an environment variable parsed and evaluated as Elixir code with the result , or raises an exception if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :elixir}.

Untrusted Input

This function parses (with Code.string_to_quoted/1) and evaluates (with Code.eval_quoted/1) elixir code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.fetch_env_as_elixir!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("TERM", "11000..11100//3")
iex> Enviable.fetch_env_as_elixir!("TERM")
11000..11100//3

fetch_env_as_erlang(varname)

(since 1.3.0)
@spec fetch_env_as_erlang(String.t()) :: {:ok, term()} | :error

Returns the value of an environment variable parsed and evaluated as Erlang code with the result as {:ok, term()}, or :error if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :erlang}.

Untrusted Input

This function parses (with :erl_scan.string/1) and evaluates (with :erl_parse.parse_term/1) Erlang code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.fetch_env_as_erlang("UNSET")
:error

iex> Enviable.put_env("TERM", "{ok, true}.")
iex> Enviable.fetch_env_as_erlang("TERM")
{:ok, {:ok, true}}

fetch_env_as_erlang!(varname)

(since 1.3.0)
@spec fetch_env_as_erlang!(String.t()) :: term()

Returns the value of an environment variable parsed and evaluated as Erlang code with the result , or raises an exception if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :erlang}.

Untrusted Input

This function parses (with :erl_scan.string/1) and evaluates (with :erl_parse.parse_term/1) Erlang code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.fetch_env_as_erlang!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("TERM", "{ok, true}.")
iex> Enviable.fetch_env_as_erlang!("TERM")
{:ok, true}

fetch_env_as_float(varname)

(since 1.3.0)
@spec fetch_env_as_float(String.t()) :: {:ok, float()} | :error

Returns the value of an environment variable converted to a float/0 value as {:ok, float()} or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_float("UNSET")
:error

iex> Enviable.put_env("FLOAT", "1")
iex> Enviable.fetch_env_as_float("FLOAT")
{:ok, 1.0}

iex> Enviable.put_env("FLOAT", "ff")
iex> Enviable.fetch_env_as_float("FLOAT")
** (Enviable.ConversionError) could not convert environment variable "FLOAT" to type float

fetch_env_as_float!(varname)

(since 1.3.0)
@spec fetch_env_as_float!(String.t()) :: float()

Returns the value of an environment variable converted to a float/0 value or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_float!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("FLOAT", "1")
iex> Enviable.fetch_env_as_float!("FLOAT")
1.0

iex> Enviable.put_env("FLOAT", "ff")
iex> Enviable.fetch_env_as_float!("FLOAT")
** (Enviable.ConversionError) could not convert environment variable "FLOAT" to type float

fetch_env_as_hex32(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_hex32(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: :error | {:ok, term()}

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.hex_decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to hex.decode32/2. The default is false (the opposite of Base.hex_decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.hex_encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_hex32("NAME", case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_hex32("NAME", as: :string, case: :lower)
{:ok, "RED"}
iex> Enviable.fetch_env_as_hex32("NAME", as: :atom, case: :lower, downcase: true)
{:ok, :red}

fetch_env_as_hex32!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_hex32!(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: term()

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.hex_decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to hex.decode32/2. The default is false (the opposite of Base.hex_decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.hex_encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_hex32!("NAME", case: :lower)
"RED"
iex> Enviable.fetch_env_as_hex32!("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.fetch_env_as_hex32!("NAME", as: :atom, case: :lower, downcase: true)
:red

fetch_env_as_integer(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_integer(String.t(), [{:base, 2..36}]) :: {:ok, integer()} | :error

Returns the value of an environment variable converted to a integer/0 value as {:ok, integer()} or :error if the variable is unset.

Options

Failure to parse the value of the environment variable will result in an exception.

Examples

iex> Enviable.fetch_env_as_integer("UNSET")
:error

iex> Enviable.put_env("PORT", "5432")
iex> Enviable.fetch_env_as_integer("PORT")
{:ok, 5432}

iex> Enviable.put_env("PORT", "18eb")
iex> Enviable.fetch_env_as_integer("PORT")
** (Enviable.ConversionError) could not convert environment variable "PORT" to type integer

iex> Enviable.put_env("PORT", "18EB")
iex> Enviable.fetch_env_as_integer("PORT", base: 16)
{:ok, 6379}

fetch_env_as_integer!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_integer!(String.t(), [{:base, 2..36}]) :: integer()

Returns the value of an environment variable converted to a integer/0 value or raises an exception if the variable is unset.

Options

Failure to parse the value of the environment variable will result in an exception.

Examples

iex> Enviable.fetch_env_as_integer!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("PORT", "5432")
iex> Enviable.fetch_env_as_integer!("PORT")
5432

iex> Enviable.put_env("PORT", "18eb")
iex> Enviable.fetch_env_as_integer!("PORT")
** (Enviable.ConversionError) could not convert environment variable "PORT" to type integer

iex> Enviable.put_env("PORT", "18EB")
iex> Enviable.fetch_env_as_integer!("PORT", base: 16)
6379

fetch_env_as_json(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_json(String.t(), [
  {:engine, module() | (String.t() -> Enviable.Conversion.json())}
]) ::
  {:ok, Enviable.Conversion.json()} | :error

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value as {:ok, Conversion.json()} or :error if the variable is unset.

Options

  • :engine: The JSON engine to use. May be provided as a module/0 (which must export decode/1), an arity 1 function, or a mfa/0 tuple. When provided with a mfa/0, the variable value will be passed as the first parameter.

    If the engine produces {:ok, json_value} or an expected JSON type result, it will be considered successful. Any other result will be treated as failure.

    The default JSON engine is :json if the Erlang/OTP :json module is available (Erlang/OTP 27+) or provided by json_polyfill. Otherwise, Jason is the default engine. This choice may be overridden with application configuration, as this example shows using Thoas.

    import Config
    
    config :enviable, :json_engine, :thoas

Examples

iex> Enviable.fetch_env_as_json("UNSET")
:error

iex> Enviable.put_env("JSON", ~S|[{"foo":"bar"}]|)
iex> Enviable.fetch_env_as_json("JSON")
{:ok, [%{"foo" => "bar"}]}

iex> Enviable.put_env("JSON", "ff")
iex> Enviable.fetch_env_as_json("JSON")
** (Enviable.ConversionError) could not convert environment variable "JSON" to type json

fetch_env_as_json!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_json!(String.t(), [
  {:engine, module() | (String.t() -> Enviable.Conversion.json())}
]) ::
  Enviable.Conversion.json()

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value or raises an exception if the variable is unset.

Options

  • :engine: The JSON engine to use. May be provided as a module/0 (which must export decode/1), an arity 1 function, or a mfa/0 tuple. When provided with a mfa/0, the variable value will be passed as the first parameter.

    If the engine produces {:ok, json_value} or an expected JSON type result, it will be considered successful. Any other result will be treated as failure.

    The default JSON engine is :json if the Erlang/OTP :json module is available (Erlang/OTP 27+) or provided by json_polyfill. Otherwise, Jason is the default engine. This choice may be overridden with application configuration, as this example shows using Thoas.

    import Config
    
    config :enviable, :json_engine, :thoas

Examples

iex> Enviable.fetch_env_as_json!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("JSON", ~S|[{"foo":"bar"}]|)
iex> Enviable.fetch_env_as_json!("JSON")
[%{"foo" => "bar"}]

iex> Enviable.put_env("JSON", "ff")
iex> Enviable.fetch_env_as_json!("JSON")
** (Enviable.ConversionError) could not convert environment variable "JSON" to type json

fetch_env_as_list(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_list(String.t(), [
  {:default, term()}
  | {:as, :string | Enviable.Conversion.primitive()}
  | {:delimiter, String.t(), [String.t()], Regex.t(), :binary.cp()}
  | {:parts, pos_integer() | :infinity}
  | {:trim, boolean()}
  | {:on,
     :all | :first | :all_but_first | :none | :all_names | [binary() | atom()]}
  | {:include_captures, boolean()}
]) :: :error | {:ok, list()}

Returns the value of an environment variable parsed as a delimiter-separated list.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Each entry must conform to the permitted type provided in :as.
  • :delimiter: The delimiter used to separate the list. This must be a pattern accepted by String.split/3 (a string, a list of strings, a compiled binary pattern, or a regular expression). Defaults to ",".
  • :parts: The maximum number of parts to split into (pos_integer/0 or :infinity). Passed to String.split/3.
  • :trim: A boolean option whether empty entries should be omitted.

When the pattern is a regular expression, Regex.split/3 options are also supported:

  • :on: specifies which captures to split the string on, and in what order. Defaults to :first which means captures inside the regex do not affect the splitting process.
  • :include_captures: when true, includes in the result the matches of the regular expression. The matches are not counted towards the maximum number of parts if combined with the :parts option. Defaults to false.

If :as is provided, the options for that type may also be provided.

Examples

iex> Enviable.put_env("LIST", "1,2,3")
iex> Enviable.fetch_env_as_list("LIST")
{:ok, ["1", "2", "3"]}
iex> Enviable.fetch_env_as_list("LIST", as: :integer)
{:ok, [1, 2, 3]}

iex> Enviable.put_env("LIST", "1;2;3")
iex> Enviable.fetch_env_as_list("LIST", delimiter: ";")
{:ok, ["1", "2", "3"]}
iex> Enviable.fetch_env_as_list("LIST", as: :integer, delimiter: ";")
{:ok, [1, 2, 3]}

fetch_env_as_list!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_list!(String.t(), [
  {:default, term()}
  | {:as, :string | Enviable.Conversion.primitive()}
  | {:delimiter, String.t(), [String.t()], Regex.t(), :binary.cp()}
  | {:parts, pos_integer() | :infinity}
  | {:trim, boolean()}
  | {:on,
     :all | :first | :all_but_first | :none | :all_names | [binary() | atom()]}
  | {:include_captures, boolean()}
]) :: list()

Returns the value of an environment variable parsed as a delimiter-separated list.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Each entry must conform to the permitted type provided in :as.
  • :delimiter: The delimiter used to separate the list. This must be a pattern accepted by String.split/3 (a string, a list of strings, a compiled binary pattern, or a regular expression). Defaults to ",".
  • :parts: The maximum number of parts to split into (pos_integer/0 or :infinity). Passed to String.split/3.
  • :trim: A boolean option whether empty entries should be omitted.

When the pattern is a regular expression, Regex.split/3 options are also supported:

  • :on: specifies which captures to split the string on, and in what order. Defaults to :first which means captures inside the regex do not affect the splitting process.
  • :include_captures: when true, includes in the result the matches of the regular expression. The matches are not counted towards the maximum number of parts if combined with the :parts option. Defaults to false.

If :as is provided, the options for that type may also be provided.

Examples

iex> Enviable.put_env("LIST", "1,2,3")
iex> Enviable.fetch_env_as_list!("LIST")
["1", "2", "3"]
iex> Enviable.fetch_env_as_list!("LIST", as: :integer)
[1, 2, 3]

iex> Enviable.put_env("LIST", "1;2;3")
iex> Enviable.fetch_env_as_list!("LIST", delimiter: ";")
["1", "2", "3"]
iex> Enviable.fetch_env_as_list!("LIST", as: :integer, delimiter: ";")
[1, 2, 3]

fetch_env_as_log_level(varname)

(since 1.3.0)
@spec fetch_env_as_log_level(String.t()) ::
  {:ok, Enviable.Conversion.log_level()} | :error

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 as {:ok, atom()} or :error if the variable is unset.

Examples

iex> Enviable.fetch_env_as_log_level("UNSET")
:error

iex> Enviable.put_env("LOG_LEVEL", "critical")
iex> Enviable.fetch_env_as_log_level("LOG_LEVEL")
{:ok, :critical}

fetch_env_as_log_level!(varname)

(since 1.3.0)
@spec fetch_env_as_log_level!(String.t()) :: Enviable.Conversion.log_level()

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 or raises an exception if the variable is unset.

Examples

iex> Enviable.fetch_env_as_log_level!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("LOG_LEVEL", "critical")
iex> Enviable.fetch_env_as_log_level!("LOG_LEVEL")
:critical

fetch_env_as_module(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_module(String.t(), [{:allowed, [module()]}]) ::
  {:ok, module()} | :error

Returns the value of an environment variable converted to module/0 as {:ok, module()} or :error if the variable is unset.

Untrusted Input

This conversion routine uses Module.concat/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.

Examples

iex> Enviable.fetch_env_as_module("UNSET")
:error

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.fetch_env_as_module("NAME")
{:ok, Elixir.Enviable}

fetch_env_as_module!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_module!(String.t(), [{:allowed, [module()]}]) :: module()

Returns the value of an environment variable converted to module/0 or raises an exception if the variable is unset.

Untrusted Input

This conversion routine uses Module.concat/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.

Examples

iex> Enviable.fetch_env_as_module!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.fetch_env_as_module!("NAME")
Elixir.Enviable

fetch_env_as_pem(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_pem(String.t(), [{:filter, boolean() | :cert | :key}]) ::
  {:ok, Enviable.Conversion.pem()} | :error

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 as {:ok, value} or :error if the variable is unset.

Options

  • :filter: Filters the output of :public_key.pem_decode/1. Permitted values are false, true, :cert, or :key. The default is true.
    • false: the list is returned without processing, suitable for further processing with :public_key.pem_entry_decode/2.
    • true: returns the first unencrypted :PrivateKeyInfo found, a list of unencrypted :Certificate records, or an empty list.
    • :cert: returns a list of unencrypted :Certificate records or raises an exception if none are found.
    • :key: returns the first unencrypted :PrivateKeyIinfo record or raises an exception if one is not found.

Examples

iex> Enviable.fetch_env_as_pem("UNSET")
:error

iex> Enviable.put_env("PEM", "")
iex> Enviable.fetch_env_as_pem("PEM")
{:ok, []}

fetch_env_as_pem!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_pem!(String.t(), [{:filter, boolean() | :cert | :key}]) ::
  Enviable.Conversion.pem()

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 or raises an exception if the variable is unset.

Options

  • :filter: Filters the output of :public_key.pem_decode/1. Permitted values are false, true, :cert, or :key. The default is true.
    • false: the list is returned without processing, suitable for further processing with :public_key.pem_entry_decode/2.
    • true: returns the first unencrypted :PrivateKeyInfo found, a list of unencrypted :Certificate records, or an empty list.
    • :cert: returns a list of unencrypted :Certificate records or raises an exception if none are found.
    • :key: returns the first unencrypted :PrivateKeyIinfo record or raises an exception if one is not found.

Examples

iex> Enviable.fetch_env_as_pem!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("PEM", "")
iex> Enviable.fetch_env_as_pem!("PEM")
[]

fetch_env_as_safe_atom(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_safe_atom(String.t(), [
  {:allowed, [atom()]} | Enviable.Conversion.opt_downcase()
]) ::
  {:ok, atom()} | :error

Returns the value of an environment variable converted to an existing atom/0 as {:ok, atom()} or :error if the variable is unset.

Untrusted Input

This conversion routine uses String.to_existing_atom/1 which will result in an exception if the resulting atom is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

Examples

iex> Enviable.fetch_env_as_safe_atom("UNSET")
:error

iex> Enviable.put_env("NAME", "FETCH_ENV_AS_SAFE_ATOM")
iex> Enviable.fetch_env_as_safe_atom("NAME", downcase: true)
{:ok, :fetch_env_as_safe_atom}

fetch_env_as_safe_atom!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_safe_atom!(String.t(), [
  {:allowed, [atom()]} | Enviable.Conversion.opt_downcase()
]) ::
  atom()

Returns the value of an environment variable converted to an existing atom/0 or raises an exception if the variable is unset.

Untrusted Input

This conversion routine uses String.to_existing_atom/1 which will result in an exception if the resulting atom is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

Examples

iex> Enviable.fetch_env_as_safe_atom!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "FETCH_ENV_AS_SAFE_ATOM!")
iex> Enviable.fetch_env_as_safe_atom!("NAME", downcase: true)
:fetch_env_as_safe_atom!

fetch_env_as_safe_module(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_safe_module(String.t(), [{:allowed, [module()]}]) ::
  {:ok, module()} | :error

Returns the value of an environment variable converted to module/0 as {:ok, module()} or :error if the variable is unset. The resulting module/0 must already exist.

Untrusted Input

This conversion routine uses Module.safe_concat/1 which will result in an exception if the resulting module is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.

Examples

iex> Enviable.fetch_env_as_safe_module("UNSET")
:error

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.fetch_env_as_safe_module("NAME")
{:ok, Elixir.Enviable}

fetch_env_as_safe_module!(varname, opts \\ [])

(since 1.3.0)
@spec fetch_env_as_safe_module!(String.t(), [{:allowed, [module()]}]) :: module()

Returns the value of an environment variable converted to module/0 or raises an exception if the variable is unset. The resulting module/0 must already exist.

Untrusted Input

This conversion routine uses Module.safe_concat/1 which will result in an exception if the resulting module is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.

Examples

iex> Enviable.fetch_env_as_safe_module!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.fetch_env_as_safe_module!("NAME")
Elixir.Enviable

fetch_env_as_url_base64(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_url_base64(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: :error | {:ok, term()}

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.url_encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_url_base64("NAME", padding: false)
{:ok, "RED"}
iex> Enviable.fetch_env_as_url_base64("NAME", as: :string, padding: true)
{:ok, "RED"}
iex> Enviable.fetch_env_as_url_base64("NAME", as: :atom, downcase: true, padding: false)
{:ok, :red}

fetch_env_as_url_base64!(varname, opts \\ [])

(since 1.4.0)
@spec fetch_env_as_url_base64!(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: term()

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.url_encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.fetch_env_as_url_base64!("NAME", padding: false)
"RED"
iex> Enviable.fetch_env_as_url_base64!("NAME", as: :string, padding: true)
"RED"
iex> Enviable.fetch_env_as_url_base64!("NAME", as: :atom, downcase: true, padding: false)
:red

fetch_env_boolean(varname, opts \\ [])

This function is deprecated. Use fetch_env_as_boolean/2 or fetch_env_as/3 instead.
@spec fetch_env_boolean(
  String.t(),
  keyword()
) :: {:ok, boolean()} | :error

Returns the value of an environment variable as {:ok, t:boolean/0} value or :error if the variable is unset. See fetch_env_as_boolean/2 or more details.

Examples

iex> Enviable.fetch_env_boolean("UNSET")
:error

iex> Enviable.put_env("FLAG", "1")
iex> Enviable.fetch_env_boolean("FLAG")
{:ok, true}

fetch_env_boolean!(varname, opts \\ [])

This function is deprecated. Use fetch_env_as_boolean!/2 or fetch_env_as!/3 instead.
@spec fetch_env_boolean!(
  String.t(),
  keyword()
) :: boolean()

Returns the value of an environment variable converted to a boolean/0 value or raises an exception if the variable is unset. See fetch_env_as_boolean!/2 for details.

iex> Enviable.fetch_env_boolean!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("FLAG", "1")
iex> Enviable.fetch_env_boolean!("FLAG")
true

fetch_env_integer(varname, opts \\ [])

This function is deprecated. Use fetch_env_as_integer/2 or fetch_env_as/3 instead.
@spec fetch_env_integer(
  String.t(),
  keyword()
) :: {:ok, integer()} | :error

Returns the value of an environment variable as {:ok, t:integer/0} or :error if the variable is unset. See fetch_env_as_integer/2 for details.

Examples

iex> Enviable.fetch_env_integer("UNSET")
:error

iex> Enviable.put_env("PORT", "1")
iex> Enviable.fetch_env_integer("PORT")
{:ok, 1}

fetch_env_integer!(varname, opts \\ [])

This function is deprecated. Use fetch_env_as_integer!/2 or fetch_env_as!/3 instead.
@spec fetch_env_integer!(
  String.t(),
  keyword()
) :: integer()

Returns the value of an environment variable converted to a integer/0 value raises an exception if the variable is unset. See fetch_env_as_integer!/2 for details.

Examples

iex> Enviable.fetch_env_integer!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("PORT", "1")
iex> Enviable.fetch_env_integer!("PORT")
1

get_env_as(varname, type, opts \\ [])

(since 1.1.0)
@spec get_env_as(String.t(), Enviable.Conversion.conversion(), keyword()) ::
  nil | term()

Returns the value of an environment variable converted to the target type or a default value if the variable is unset. If no default is provided, nil is returned (unless converting to :boolean, which will return false).

Supported primitive conversions are:

Supported encoded conversions are:

See Enviable.Conversion for supported type conversions and options.

Value Conversion and Default Values

Value conversion will be applied only to values contained in the requested environment variable. Default values are used only when the environment variable is unset. There is a meaningful difference between an unset environment variable (where System.get_env/1 will return nil) and an empty environment variable (where System.get_env/1 returns "").

$ FOO= elixir -e 'IO.inspect([foo: System.get_env("FOO"), bar: System.get_env("BAR")])'
[foo: "", bar: nil]

Examples

iex> Enviable.get_env_as("UNSET", :atom)
nil

iex> Enviable.get_env_as("UNSET", :float)
nil

iex> Enviable.get_env_as("UNSET", :base16)
nil

iex> Enviable.put_env("NAME", "get_env_as")
iex> Enviable.get_env_as("NAME", :atom)
:get_env_as

iex> Enviable.put_env("NAME", "GET_ENV_AS")
iex> Enviable.get_env_as("NAME", :safe_atom, downcase: true)
:get_env_as

iex> Enviable.get_env_as("FLOAT", :float, default: "3.5")
3.5

iex> Enviable.get_env_as("FLOAT", :float, default: 3.5)
3.5

iex> Enviable.put_env("FLOAT", "3")
iex> Enviable.get_env_as("FLOAT", :float)
3.0

iex> Enviable.put_env("FLOAT", "3.1")
iex> Enviable.get_env_as("FLOAT", :float)
3.1

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as("NAME", :base16, case: :lower)
"RED"
iex> Enviable.get_env_as("NAME", {:base16, :string}, case: :lower)
"RED"
iex> Enviable.get_env_as("NAME", {:base16, :atom}, case: :lower, downcase: true)
:red

iex> Enviable.put_env("LIST", "1,2,3")
iex> Enviable.get_env_as("LIST", :list)
["1", "2", "3"]
iex> Enviable.get_env_as("LIST", {:list, :integer})
[1, 2, 3]

iex> Enviable.put_env("LIST", "1;2;3")
iex> Enviable.get_env_as("LIST", :list, delimiter: ";")
["1", "2", "3"]
iex> Enviable.get_env_as("LIST", {:list, :integer}, delimiter: ";")
[1, 2, 3]

get_env_as_atom(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_atom(
  String.t(),
  atom()
  | binary()
  | [
      {:allowed, [atom()]}
      | {:default, atom() | binary()}
      | Enviable.Conversion.opt_downcase()
    ]
) :: nil | atom()

Returns the value of an environment variable converted to atom/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Untrusted Input

This conversion routine uses String.to_atom/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of atom/0 values indicating permitted atoms and used as a lookup table, if present. Any value not found will result in an exception.
  • :default: The atom/0 or binary/0 value representing the atom value to use if the environment variable is unset (nil). If the :allowed option is present, the default value must be one of the permitted values.
  • :downcase: See Enviable.Conversion.opt_downcase/0.
  • :upcase: See Enviable.Conversion.opt_upcase/0.

A shorthand for the default option may be provided as a atom/0 value.

Examples

iex> Enviable.get_env_as_atom("UNSET")
nil

iex> Enviable.get_env_as_atom("UNSET", :default)
:default

iex> Enviable.get_env_as_atom("UNSET", default: :default)
:default

iex> Enviable.put_env("NAME", "get_env_as_atom")
iex> Enviable.get_env_as_atom("NAME")
:get_env_as_atom

get_env_as_base16(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_base16(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed
) :: nil | term()

Returns the value of an environment variable decoded as a base 16 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode16/2, which must be :upper, :lower, or :mixed.

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode16("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as_base16("NAME", case: :lower)
"RED"
iex> Enviable.get_env_as_base16("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.get_env_as_base16("NAME", as: :atom, case: :lower, downcase: true)
:red

get_env_as_base32(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_base32(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: nil | term()

Returns the value of an environment variable decoded as a base 32 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to Base.decode32/2. The default is false (the opposite of Base.decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as_base32("NAME", case: :lower)
"RED"
iex> Enviable.get_env_as_base32("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.get_env_as_base32("NAME", as: :atom, case: :lower, downcase: true)
:red

get_env_as_base64(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_base64(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: nil | term()

Returns the value of an environment variable decoded as a base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as_base64("NAME", padding: false)
"RED"
iex> Enviable.get_env_as_base64("NAME", as: :string, padding: true)
"RED"
iex> Enviable.get_env_as_base64("NAME", as: :atom, downcase: true, padding: false)
:red

get_env_as_boolean(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_boolean(
  String.t(),
  boolean()
  | [
      {:default, boolean()}
      | Enviable.Conversion.opt_downcase()
      | {:truthy | :falsy, [binary()]}
    ]
) :: boolean()

Returns the value of an environment variable converted to a boolean/0 value, or a default value if the variable is unset. If no default is provided, false will be returned.

This function will always result in a boolean/0 value. Unless configured with truthy or falsy, only the values "1" and "true" will be converted to true and any other value will result in false.

Options

  • :default: the default value (which must be true or false) if the variable is unset. In most cases, when falsy is provided, default: true should also be provided.

  • :truthy: a list of string values to be compared for truth values. If the value of the environment variable matches these values, true will be returned; other values will result in false. Mutually exclusive with falsy.

  • :falsy: a list of string values to be compared for false values. If the value of the environment variable matches these values, false will be returned; other values will result in true. Mutually exclusive with truthy.

  • :downcase: either false (the default), true, or the mode parameter for String.downcase/2 (:default, :ascii, :greek, or :turkic).

    The default :downcase value for boolean conversions can be changed at compile time through application configuration:

    config :enviable, :boolean_downcase, true
    config :enviable, :boolean_downcase, :default
    config :enviable, :boolean_downcase, :ascii

    In the next major version of Enviable, the default :downcase value will be changing to :default.

A shorthand value for the default option may be provided as a boolean/0 value.

Examples

iex> Enviable.get_env_as_boolean("FLAG")
false

iex> Enviable.get_env_as_boolean("FLAG", true)
true

iex> Enviable.get_env_as_boolean("FLAG", default: true)
true

iex> Enviable.put_env("FLAG", "1")
iex> Enviable.get_env_as_boolean("FLAG")
true

iex> Enviable.put_env("FLAG", "something")
iex> Enviable.get_env_as_boolean("FLAG")
false

iex> Enviable.put_env("FLAG", "oui")
iex> Enviable.get_env_as_boolean("FLAG", truthy: ["oui"])
true

iex> Enviable.put_env("FLAG", "OUI")
iex> Enviable.get_env_as_boolean("FLAG", truthy: ["oui"])
false
iex> Enviable.get_env_as_boolean("FLAG", truthy: ["oui"], downcase: true)
true

iex> Enviable.put_env("FLAG", "NON")
iex> Enviable.get_env_as_boolean("FLAG", falsy: ["non"])
true
iex> Enviable.get_env_as_boolean("FLAG", falsy: ["non"], downcase: true)
false

iex> Enviable.get_env_as_boolean("FLAG", default: nil)
** (ArgumentError) could not convert environment variable "FLAG" to type boolean: non-boolean `default` value

iex> Enviable.get_env_as_boolean("FLAG", downcase: nil)
** (ArgumentError) could not convert environment variable "FLAG" to type boolean: invalid `downcase` value

iex> Enviable.get_env_as_boolean("FLAG", truthy: ["oui"], falsy: ["non"])
** (ArgumentError) could not convert environment variable "FLAG" to type boolean: `truthy` and `falsy` options both provided

get_env_as_charlist(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_charlist(String.t(), binary() | [{:default, charlist() | binary()}]) ::
  nil | charlist()

Returns the value of an environment variable converted to a charlist/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Options

A shorthand for the default value may be provided as a binary/0 (there is no guard for charlist/0).

Examples

iex> Enviable.get_env_as_charlist("UNDEFINED")
nil

iex> Enviable.get_env_as_charlist("UNDEFINED", "default")
~c"default"

iex> Enviable.get_env_as_charlist("UNDEFINED", default: "default")
~c"default"

iex> Enviable.get_env_as_charlist("UNDEFINED", default: ~c"default")
~c"default"

iex> Enviable.put_env("NAME", "get_env_as")
iex> Enviable.get_env_as_charlist("NAME")
~c"get_env_as"

get_env_as_decimal(varname, opts \\ [])

(since 1.6.0)
@spec get_env_as_decimal(
  String.t(),
  Decimal.t()
  | float()
  | integer()
  | binary()
  | [{:default, Decimal.t() | binary() | float() | integer()}]
) :: Decimal.t() | nil

Returns the value of an environment variable converted to a Decimal.t/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Options

A shorthand for the default value may be provided as a Decimal.t/0, float/0, integer/0, or binary/0 value.

Examples

iex> Enviable.get_env_as_decimal("DECIMAL")
nil

iex> Enviable.get_env_as_decimal("DECIMAL", Decimal.new("3.14"))
Decimal.new("3.14")

iex> Enviable.get_env_as_decimal("DECIMAL", 25.5)
Decimal.new("25.5")

iex> Enviable.get_env_as_decimal("DECIMAL", 25)
Decimal.new("25")

iex> Enviable.get_env_as_decimal("DECIMAL", "255")
Decimal.new("255")

iex> Enviable.get_env_as_decimal("DECIMAL", default: Decimal.new("3.14"))
Decimal.new("3.14")

iex> Enviable.get_env_as_decimal("DECIMAL", default: 25.5)
Decimal.new("25.5")

iex> Enviable.get_env_as_decimal("DECIMAL", default: 25)
Decimal.new("25")

iex> Enviable.get_env_as_decimal("DECIMAL", default: "255")
Decimal.new("255")

iex> Enviable.get_env_as_decimal("DECIMAL", default: "3.5R")
** (ArgumentError) could not convert environment variable "DECIMAL" to type decimal: invalid decimal `default` value

iex> Enviable.get_env_as_decimal("DECIMAL", default: %{})
** (ArgumentError) could not convert environment variable "DECIMAL" to type decimal: invalid decimal `default` value

iex> Enviable.put_env("DECIMAL", "1")
iex> Enviable.get_env_as_decimal("DECIMAL")
Decimal.new("1")

iex> Enviable.put_env("DECIMAL", "ff")
iex> Enviable.get_env_as_decimal("DECIMAL")
** (Enviable.ConversionError) could not convert environment variable "DECIMAL" to type decimal

get_env_as_elixir(varname)

(since 1.3.0)
@spec get_env_as_elixir(String.t()) :: nil | term()

Returns the value of an environment variable parsed and evaluated as Elixir code, or nil if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :elixir}.

Untrusted Input

This function parses (with Code.string_to_quoted/1) and evaluates (with Code.eval_quoted/1) elixir code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.get_env_as_elixir("TERM")
nil

iex> Enviable.put_env("TERM", "11000..11100//3")
iex> Enviable.get_env_as_elixir("TERM")
11000..11100//3

get_env_as_erlang(varname)

(since 1.3.0)
@spec get_env_as_erlang(String.t()) :: nil | term()

Returns the value of an environment variable parsed and evaluated as Erlang code, or nil if the environment variable is not set.

This can be used for tuples, complex map declarations, or other expressions difficult to represent with other types. Longer code blocks should be encoded as base 64 text and decoded as {:base64, :erlang}.

Untrusted Input

This function parses (with :erl_scan.string/1) and evaluates (with :erl_parse.parse_term/1) Erlang code from environment variables in the context of your application. Do not use this with untrusted input.

Examples

iex> Enviable.get_env_as_erlang("TERM")
nil

iex> Enviable.put_env("TERM", "{ok, true}.")
iex> Enviable.get_env_as_erlang("TERM")
{:ok, true}

get_env_as_float(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_float(
  String.t(),
  float() | integer() | binary() | [{:default, binary() | float() | integer()}]
) :: float() | nil

Returns the value of an environment variable converted to a float/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Options

  • :default: The default value, either as float/0, integer/0 (which will be converted to float), or binary/0 (which must parse cleanly as float).

A shorthand for the default value may be provided as a float/0, integer/0, or binary/0 value.

Examples

iex> Enviable.get_env_as_float("FLOAT")
nil

iex> Enviable.get_env_as_float("FLOAT", 25.5)
25.5

iex> Enviable.get_env_as_float("FLOAT", 25)
25.0

iex> Enviable.get_env_as_float("FLOAT", "255")
255.0

iex> Enviable.get_env_as_float("FLOAT", default: 25.5)
25.5

iex> Enviable.get_env_as_float("FLOAT", default: 25)
25.0

iex> Enviable.get_env_as_float("FLOAT", default: "255")
255.0

iex> Enviable.get_env_as_float("FLOAT", default: "3.5R")
** (ArgumentError) could not convert environment variable "FLOAT" to type float: non-float `default` value

iex> Enviable.put_env("FLOAT", "1")
iex> Enviable.get_env_as_float("FLOAT")
1.0

iex> Enviable.put_env("FLOAT", "ff")
iex> Enviable.get_env_as_float("FLOAT")
** (Enviable.ConversionError) could not convert environment variable "FLOAT" to type float

get_env_as_hex32(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_hex32(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: nil | term()

Returns the value of an environment variable decoded as a base 32 hex encoded string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :case: The value of :case passed to Base.hex_decode32/2, which must be :upper, :lower, or :mixed.
  • :padding: The boolean value of :padding passed to hex.decode32/2. The default is false (the opposite of Base.hex_decode32/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.hex_encode32("RED", case: :lower)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as_hex32("NAME", case: :lower)
"RED"
iex> Enviable.get_env_as_hex32("NAME", as: :string, case: :lower)
"RED"
iex> Enviable.get_env_as_hex32("NAME", as: :atom, case: :lower, downcase: true)
:red

get_env_as_integer(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_integer(
  String.t(),
  integer() | binary() | [base: 2..36, default: binary() | integer()]
) :: integer() | nil

Returns the value of an environment variable converted to a integer/0 value or a default value if the variable is unset. If no default is provided, nil is returned.

Options

  • :base: The base (2..36) for integer conversion. Defaults to base 10 like String.to_integer/2.
  • :default: the default value, which must be either a binary string value or an integer. If provided as a binary, this will be interpreted according to the base option provided.

A shorthand for the default value may be provided as a integer/0 or binary/0 value.

Failure to parse a binary string default or the value of the environment variable will result in an exception.

Examples

iex> Enviable.get_env_as_integer("PORT")
nil

iex> Enviable.get_env_as_integer("PORT", 5432)
5432

iex> Enviable.get_env_as_integer("PORT", "5432")
5432

iex> Enviable.get_env_as_integer("PORT", default: 5432)
5432

iex> Enviable.get_env_as_integer("PORT", default: "5432")
5432

iex> Enviable.get_env_as_integer("PORT", default: 3.5)
** (ArgumentError) could not convert environment variable "PORT" to type integer: non-integer `default` value

iex> Enviable.put_env("PORT", "5432")
iex> Enviable.get_env_as_integer("PORT")
5432

iex> Enviable.put_env("PORT", "18eb")
iex> Enviable.get_env_as_integer("PORT")
** (Enviable.ConversionError) could not convert environment variable "PORT" to type integer

iex> Enviable.put_env("PORT", "18EB")
iex> Enviable.get_env_as_integer("PORT", base: 16)
6379

get_env_as_json(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_json(String.t(),
  default: Enviable.Conversion.json(),
  engine: module() | (String.t() -> Enviable.Conversion.json())
) :: Enviable.Conversion.json() | nil

Returns the value of an environment variable converted to a Enviable.Conversion.json/0 value or a default value if the variable is unset. If no default is provided, nil will be returned.

Options

  • :default: The default value, which may be any valid JSON type.

  • :engine: The JSON engine to use. May be provided as a module/0 (which must export decode/1), an arity 1 function, or a mfa/0 tuple. When provided with a mfa/0, the variable value will be passed as the first parameter.

    If the engine produces {:ok, json_value} or an expected JSON type result, it will be considered successful. Any other result will be treated as failure.

    The default JSON engine is :json if the Erlang/OTP :json module is available (Erlang/OTP 27+) or provided by json_polyfill. Otherwise, Jason is the default engine. This choice may be overridden with application configuration, as this example shows using Thoas.

    import Config
    
    config :enviable, :json_engine, :thoas

Examples

iex> Enviable.get_env_as_json("JSON")
nil

iex> Enviable.get_env_as_json("JSON", default: "3.5R")
"3.5R"

iex> Enviable.put_env("JSON", ~S|[{"foo":"bar"}]|)
iex> Enviable.get_env_as_json("JSON", engine: &Jason.decode!/1)
[%{"foo" => "bar"}]

iex> Enviable.put_env("JSON", ~S|[{"foo":"bar"}]|)
iex> Enviable.get_env_as_json("JSON")
[%{"foo" => "bar"}]

iex> Enviable.put_env("JSON", "ff")
iex> Enviable.get_env_as_json("JSON")
** (Enviable.ConversionError) could not convert environment variable "JSON" to type json

iex> Enviable.put_env("JSON", "ff")
iex> Enviable.get_env_as_json("JSON", engine: &Jason.decode!/1)
** (Enviable.ConversionError) could not convert environment variable "JSON" to type json

get_env_as_list(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_list(String.t(), [
  {:default, term()}
  | {:as, :string | Enviable.Conversion.primitive()}
  | {:delimiter, String.t(), [String.t()], Regex.t(), :binary.cp()}
  | {:parts, pos_integer() | :infinity}
  | {:trim, boolean()}
  | {:on,
     :all | :first | :all_but_first | :none | :all_names | [binary() | atom()]}
  | {:include_captures, boolean()}
]) :: nil | list()

Returns the value of an environment variable parsed as a delimiter-separated list.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Each entry must conform to the permitted type provided in :as.
  • :delimiter: The delimiter used to separate the list. This must be a pattern accepted by String.split/3 (a string, a list of strings, a compiled binary pattern, or a regular expression). Defaults to ",".
  • :parts: The maximum number of parts to split into (pos_integer/0 or :infinity). Passed to String.split/3.
  • :trim: A boolean option whether empty entries should be omitted.

When the pattern is a regular expression, Regex.split/3 options are also supported:

  • :on: specifies which captures to split the string on, and in what order. Defaults to :first which means captures inside the regex do not affect the splitting process.
  • :include_captures: when true, includes in the result the matches of the regular expression. The matches are not counted towards the maximum number of parts if combined with the :parts option. Defaults to false.

If :as is provided, the options for that type may also be provided.

Examples

iex> Enviable.put_env("LIST", "1,2,3")
iex> Enviable.get_env_as_list("LIST")
["1", "2", "3"]
iex> Enviable.get_env_as_list("LIST", as: :integer)
[1, 2, 3]

iex> Enviable.put_env("LIST", "1;2;3")
iex> Enviable.get_env_as_list("LIST", delimiter: ";")
["1", "2", "3"]
iex> Enviable.get_env_as_list("LIST", as: :integer, delimiter: ";")
[1, 2, 3]

get_env_as_log_level(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_log_level(String.t(), [{:default, Enviable.Conversion.log_level()}]) ::
  nil | Enviable.Conversion.log_level()

Returns the value of an environment variable converted to a log level atom/0 for Logger.configure/1 or a default value if the variable is unset. If no default is provided, nil will be returned.

Options

  • :default: The default value. Must be a valid value.

A shorthand for the default option may be provided as a atom/0 or binary/0 value.

Examples

iex> Enviable.get_env_as_log_level("LOG_LEVEL")
nil

iex> Enviable.get_env_as_log_level("LOG_LEVEL", :error)
:error

iex> Enviable.get_env_as_log_level("LOG_LEVEL", "info")
:info

iex> Enviable.get_env_as_log_level("LOG_LEVEL", default: :error)
:error

iex> Enviable.get_env_as_log_level("LOG_LEVEL", default: "info")
:info

iex> Enviable.put_env("LOG_LEVEL", "critical")
iex> Enviable.get_env_as_log_level("LOG_LEVEL")
:critical

get_env_as_module(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_module(
  String.t(),
  module() | binary() | [allowed: [module()], default: module() | binary()]
) :: nil | module()

Returns the value of an environment variable converted to module/0 or a default value if the variable is unset. If no default is provided, nil will be returned.

Untrusted Input

This conversion routine uses Module.concat/1 and may result in atom exhaustion if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.
  • :default: The module/0 or binary/0 value representing the atom value to use if the environment variable is unset (nil). If the :allowed option is present, the default value must be one of the permitted values.

A shorthand for the default option may be provided as a atom/0 or binary/0 value.

Examples

iex> Enviable.get_env_as_module("UNSET")
nil

iex> Enviable.get_env_as_module("UNSET", Enviable)
Elixir.Enviable

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.get_env_as_module("NAME")
Elixir.Enviable

get_env_as_pem(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_pem(String.t(), [{:filter, boolean() | :cert | :key}]) ::
  nil | Enviable.Conversion.pem()

Returns the value of an environment variable converted from a PEM string through :public_key.pem_decode/1 or nil if the variable is unset.

Options

  • :filter: Filters the output of :public_key.pem_decode/1. Permitted values are false, true, :cert, or :key. The default is true.
    • false: the list is returned without processing, suitable for further processing with :public_key.pem_entry_decode/2.
    • true: returns the first unencrypted :PrivateKeyInfo found, a list of unencrypted :Certificate records, or an empty list.
    • :cert: returns a list of unencrypted :Certificate records or raises an exception if none are found.
    • :key: returns the first unencrypted :PrivateKeyIinfo record or raises an exception if one is not found.

Examples

iex> Enviable.get_env_as_pem("PEM")
nil

iex> Enviable.put_env("PEM", "")
iex> Enviable.get_env_as_pem("PEM")
[]

get_env_as_safe_atom(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_safe_atom(
  String.t(),
  atom()
  | binary()
  | [
      {:allowed, [atom()]}
      | {:default, atom() | binary()}
      | Enviable.Conversion.opt_downcase()
    ]
) :: nil | atom()

Returns the value of an environment variable converted to an existing atom/0 or a default value if the variable is unset. If no default is provided, nil is returned.

Untrusted Input

This conversion routine uses String.to_existing_atom/1 which will result in an exception if the resulting atom is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of atom/0 values indicating permitted atoms and used as a lookup table, if present. Any value not found will result in an exception.
  • :default: The atom/0 or binary/0 value representing the atom value to use if the environment variable is unset (nil). If the :allowed option is present, the default value must be one of the permitted values.
  • :downcase: See Enviable.Conversion.opt_downcase/0.
  • :upcase: See Enviable.Conversion.opt_upcase/0.

A shorthand for the default option may be provided as a atom/0 value.

Examples

iex> Enviable.get_env_as_safe_atom("UNSET")
nil

iex> Enviable.get_env_as_safe_atom("UNSET", :default)
:default

iex> Enviable.get_env_as_safe_atom("UNSET", default: :default)
:default

iex> Enviable.put_env("NAME", "GET_ENV_AS_SAFE_ATOM")
iex> Enviable.get_env_as_safe_atom("NAME", downcase: true)
:get_env_as_safe_atom

get_env_as_safe_module(varname, opts \\ [])

(since 1.3.0)
@spec get_env_as_safe_module(
  String.t(),
  binary() | module() | [allowed: [module()], default: module() | binary()]
) :: nil | module()

Returns the value of an environment variable converted to module/0 or a default value if the variable is unset. If no default is provided, nil will be returned. The resulting module/0 must already exist.

Untrusted Input

This conversion routine uses Module.safe_concat/1 which will result in an exception if the resulting module is not already known and if used without the :allowed option. See Preventing atom exhaustion from the Security Working Group of the Erlang Ecosystem Foundation.

Options

  • :allowed: A list of module/0 values indicating permitted module and used as a lookup table, if present. Any value not found will result in an exception.
  • :default: The module/0 or binary/0 value representing the atom value to use if the environment variable is unset (nil). If the :allowed option is present, the default value must be one of the permitted values.

A shorthand for the default option may be provided as a atom/0 or binary/0 value.

Examples

iex> Enviable.get_env_as_safe_module("UNSET")
nil

iex> Enviable.get_env_as_safe_module("UNSET", Enviable)
Elixir.Enviable

iex> Enviable.put_env("NAME", "Enviable")
iex> Enviable.get_env_as_safe_module("NAME")
Elixir.Enviable

get_env_as_url_base64(varname, opts \\ [])

(since 1.4.0)
@spec get_env_as_url_base64(String.t(),
  default: term(),
  as: :string | Enviable.Conversion.primitive(),
  case: :upper | :lower | :mixed,
  padding: boolean()
) :: nil | term()

Returns the value of an environment variable decoded as a URL-safe base 64 string.

Options

  • :as: The type of value that the encoded string is to be parsed as once decoded. Must be either :string (the same as not providing as: :string) or a t:Conversion.primit/0 value.
  • :default: The default value to be used. Must conform to the permitted type provided in :as.
  • :ignore_whitespace: Whether to ignore whitespace values. The default is true, the opposite default for both Base.decode64/2 and Base.url_decode64/2.
  • :padding: The boolean value of :padding passed to Base.decode64/2. The default is false (the opposite of Base.decode64/2).

If :as is provided, the options for that type may also be provided.

Examples

iex> red = Base.url_encode64("RED", padding: true)
iex> Enviable.put_env("NAME", red)
iex> Enviable.get_env_as_url_base64("NAME", padding: false)
"RED"
iex> Enviable.get_env_as_url_base64("NAME", as: :string, padding: true)
"RED"
iex> Enviable.get_env_as_url_base64("NAME", as: :atom, downcase: true, padding: false)
:red

get_env_boolean(varname, opts \\ [])

This function is deprecated. Use get_env_as_boolean/2 or get_env_as/3 instead.
@spec get_env_boolean(
  String.t(),
  keyword()
) :: boolean()

Returns the value of an environment variable converted to a boolean/0 value. See get_env_as_boolean/2 for more details.

Examples

iex> Enviable.get_env_boolean("UNSET")
false

get_env_integer(varname, opts \\ [])

This function is deprecated. Use get_env_as_integer/2 or get_env_as/3 instead.
@spec get_env_integer(
  String.t(),
  keyword()
) :: integer() | nil

Returns the value of an environment variable converted to a integer/0 value or nil if the variable is not set and a default is not provided. See get_env_as_integer/2 for details.

Examples

iex> Enviable.get_env_integer("UNSET")
nil

iex> Enviable.get_env_integer("PORT", default: 255)
255

Functions: Delegates

delete_env(varname)

@spec delete_env(String.t()) :: :ok

Deletes an environment variable, removing varname from the environment.

fetch_env(varname)

@spec fetch_env(String.t()) :: {:ok, String.t()} | :error

Returns the value of the given environment variable or :error if not found.

If the environment variable varname is set, then {:ok, value} is returned where value is a string. If varname is not set, :error is returned.

Examples

iex> Enviable.fetch_env("PORT")
:error

iex> Enviable.put_env("PORT", "4000")
iex> Enviable.fetch_env("PORT")
{:ok, "4000"}

fetch_env!(varname)

@spec fetch_env!(String.t()) :: String.t()

Returns the value of the given environment variable or raises if not found.

Same as get_env/1 but raises instead of returning nil when the variable is not set.

Examples

iex> Enviable.fetch_env!("UNSET")
** (System.EnvError) could not fetch environment variable "UNSET" because it is not set

iex> Enviable.put_env("PORT", "4000")
iex> Enviable.fetch_env!("PORT")
"4000"

get_env()

@spec get_env() :: %{optional(String.t()) => String.t()}

Returns all system environment variables.

The returned value is a map containing name-value pairs. Variable names and their values are strings.

get_env(varname, default \\ nil)

@spec get_env(String.t(), default) :: String.t() | default
when default: String.t() | nil

Returns the value of the given environment variable.

The returned value of the environment variable varname is a string. If the environment variable is not set, returns the string specified in default or nil if none is specified.

Examples

iex> Enviable.get_env("PORT")
nil

iex> Enviable.get_env("PORT", "4001")
"4001"

iex> Enviable.put_env("PORT", "4000")
iex> Enviable.get_env("PORT")
"4000"
iex> Enviable.get_env("PORT", "4001")
"4000"

put_env(var_map)

@spec put_env(Enumerable.t()) :: :ok

Sets multiple environment variables.

Sets a new value for each environment variable corresponding to each {key, value} pair in enum. Keys and non-nil values are automatically converted to charlists. nil values erase the given keys.

Overall, this is a convenience wrapper around put_env/2 and delete_env/2 with support for different key and value formats.

put_env(varname, value)

@spec put_env(String.t(), String.t()) :: :ok

Sets an environment variable value.

Sets a new value for the environment variable varname.