Skip to content

ValidationError when importing library #21

@mdavis-xyz

Description

@mdavis-xyz

It seems that something is checking for the presence of the API in the environment vars when I import the library, and is throwing an exception when not found.

Steps to reproduce

  • Install openelectricity == 0.9.2
  • Do not set API key in the env vars
  • Run this line of python: from openelectricity import OEClient

Expected Result

The import returns a client constructor.
No exception is thrown.

Then I can subsequently pass the key as an explicit argument


with open(api_key_path, 'r') as f:
    key = f.read().strip()
 
client = OEClient(api_key=key)

The documentation says I can pass a key either as an env var, or as an argument. So I think this behavior does not match the intended behavior.

Actual Result

s> python
Python 3.14.2 | packaged by conda-forge | (main, Dec  6 2025, 11:17:27) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from openelectricity import OEClient
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    from openelectricity import OEClient
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\openelectricity\__init__.py", line 7, in <module>
    from openelectricity.client import AsyncOEClient, OEClient
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\openelectricity\client.py", line 13, in <module>
    from openelectricity.logging import get_logger
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\openelectricity\logging.py", line 12, in <module>
    from openelectricity.settings_schema import settings
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\openelectricity\settings_schema.py", line 24, in <module>
    settings = Settings()
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\pydantic_settings\main.py", line 194, in __init__
    super().__init__(
    ~~~~~~~~~~~~~~~~^
        **__pydantic_self__._settings_build_values(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<27 lines>...
        )
        ^
    )
    ^
  File "C:\Users\DAVIS_M\AppData\Local\anaconda3\envs\ausbids\Lib\site-packages\pydantic\main.py", line 250, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 1 validation error for Settings
OPENELECTRICITY_API_KEY
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.12/v/missing

Discussion

I prefer to use the explicit approach, because I'm in a new company where the actual environment variables are unclear. (Conda, pip, proxies, antivirus. Argh, it's hard. If I can the key explicitly in python, that's one less thing to go wrong.)

Even if I choose to pass the key as an env var, I don't think it should be checked when the library is imported. What if I do:

import os
from openelectricity import OEClient

# get secret from disk, or AWS secrets manager etc
with open(api_key_path, 'r') as f:
    os.environ["OPENELECTRICITY_API_KEY"] = f.read().strip()

client = OEClient()

Also, what if I change the API key while the script is running? Or what if I want two keys at once for different queries? I don't have those use cases, but I would expect to be able to have two different clients to manage that kind of difference.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions