JosephRPalmer / octopus-usage-exporter

Prometheus exporter for Octopus Energy metrics. Works best when coupled with an Octopus Home Mini.
MIT License
1 stars 1 forks source link

`Signature has expired` error #3

Closed sshaikh closed 2 weeks ago

sshaikh commented 3 weeks ago
Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 205, in <module>
    read_meters(str(os.environ.get("API_KEY")))
  File "/home/user/octopus-usage-exporter/app/app.py", line 177, in read_meters
    check_jwt(api_key)
  File "/home/user/octopus-usage-exporter/app/app.py", line 167, in check_jwt
    user_info = jwt.decode(headers["Authorization"].split(" ")[1], key=key , algorithms=["RS256"])
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 157, in decode
    _validate_claims(
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 481, in _validate_claims
    _validate_exp(claims, leeway=leeway)
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 314, in _validate_exp
    raise ExpiredSignatureError("Signature has expired.")
jose.exceptions.ExpiredSignatureError: Signature has expired.

This occurs consistently after 1 hour of running.

JosephRPalmer commented 3 weeks ago

Can you give details on how you are running the code, and what command you are using to run it directly?

Also some further logs (anonymised).

sshaikh commented 3 weeks ago

I'm not running in docker, so from the top:

$ git clone https://github.com/JosephRPalmer/octopus-usage-exporter.git
$ python3.11 -m venv octopus-usage-exporter/
$ cd octopus-usage-exporter/
$ source ./bin/activate
$ pip install --no-cache-dir -r requirements.txt
$ cd app
$ PROM_PORT=9120 INTERVAL=180 API_KEY=<key> ACCOUNT_NUMBER=<account> GAS=True ELECTRIC=True python app.py

And loglines preceeding the error are stable, although it does mention the expiry of the JWT:

2024-06-12 19:56:04,705 - INFO - JWT valid until 2024-06-12 20:01:41
2024-06-12 19:56:06,456 - INFO - Meter: 00-1C-55-00-20-05-BF-0C - Type: consumption - Reading: xxx
2024-06-12 19:56:06,456 - INFO - Meter: 00-1C-55-00-20-05-BF-0C - Type: demand - Reading: yyy
2024-06-12 19:59:06,457 - INFO - JWT valid until 2024-06-12 20:01:41
2024-06-12 19:59:07,487 - INFO - Meter: 00-1C-55-00-20-05-BF-0C - Type: consumption - Reading: xxx
2024-06-12 19:59:07,487 - INFO - Meter: 00-1C-55-00-20-05-BF-0C - Type: demand - Reading: yyy
Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 205, in <module>
    read_meters(str(os.environ.get("API_KEY")))
  File "/home/user/octopus-usage-exporter/app/app.py", line 177, in read_meters
    check_jwt(api_key)
  File "/home/user/octopus-usage-exporter/app/app.py", line 167, in check_jwt
    user_info = jwt.decode(headers["Authorization"].split(" ")[1], key=key , algorithms=["RS256"])
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 157, in decode
    _validate_claims(
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 481, in _validate_claims
    _validate_exp(claims, leeway=leeway)
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 314, in _validate_exp
    raise ExpiredSignatureError("Signature has expired.")
jose.exceptions.ExpiredSignatureError: Signature has expired.

I'm testing Cloudhunter's fork as they appear to have commits that mention JWT authorisation so there may be clues there? Alas it'll take an hour to see if it works.

JosephRPalmer commented 3 weeks ago

I have pushed a fix, I think this should resolve for you. Please reopen if it doesn't.

sshaikh commented 3 weeks ago

~Did the trick - thanks for the quick turnaround!~

sshaikh commented 3 weeks ago

I tell a lie - still expiring after an hour. Logs are the same.

JosephRPalmer commented 3 weeks ago

Can you give me the new stacktrace please? Including the logs from when it first starts running and the error itself

sshaikh commented 3 weeks ago

My mistake - was still running 0.0.16 somehow. Re-testing now (and definitely running 0.0.17). Will report back.

JosephRPalmer commented 3 weeks ago

I will leave the issue open until you confirm. Thanks.

sshaikh commented 2 weeks ago
$ python app.py
2024-06-14 17:57:25,848 - INFO - Octopus Energy Exporter by JRP - Version 0.0.17
2024-06-14 17:57:25,960 - INFO - JWT refresh success
2024-06-14 17:57:26,147 - INFO - Electricity Meter has been found - 
2024-06-14 17:57:26,289 - INFO - Gas Meter has been found - 
2024-06-14 17:57:26,289 - INFO - Starting to read electric meter every 300 seconds
2024-06-14 17:57:26,289 - INFO - Starting to read gas meter every 1800 seconds
2024-06-14 17:57:26,290 - INFO - Exporting Prometheus /metrics/ on port 9120
2024-06-14 17:57:26,290 - INFO - JWT valid until 2024-06-14 18:57:25
2024-06-14 17:57:27,896 - INFO - Meter:  - Type: consumption - Reading: 
2024-06-14 17:57:27,896 - INFO - Meter:  - Type: demand - Reading: 
...
2024-06-14 18:52:41,053 - INFO - JWT valid until 2024-06-14 18:57:25
2024-06-14 18:52:41,986 - INFO - Meter:  - Type: consumption - Reading: 
2024-06-14 18:52:41,986 - INFO - Meter:  - Type: demand - Reading: 
Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 169, in check_jwt
    user_info = jwt.decode(headers["Authorization"].split(" ")[1], key=key , algorithms=["RS256"])
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 157, in decode
    _validate_claims(
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 481, in _validate_claims
    _validate_exp(claims, leeway=leeway)
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 314, in _validate_exp
    raise ExpiredSignatureError("Signature has expired.")
jose.exceptions.ExpiredSignatureError: Signature has expired.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 209, in <module>
    read_meters(str(os.environ.get("API_KEY")))
  File "/home/user/octopus-usage-exporter/app/app.py", line 181, in read_meters
    check_jwt(api_key)
  File "/home/user/octopus-usage-exporter/app/app.py", line 174, in check_jwt
    except jwt.ExpiredSignature:
           ^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'jose.jwt' has no attribute 'ExpiredSignature'. Did you mean: 'ExpiredSignatureError'?

I've fixed the typo and am rerunning.

JosephRPalmer commented 2 weeks ago

I fixed the typo in version 0.0.18, please try that.

sshaikh commented 2 weeks ago

Neither my nor your fix worked:

2024-06-15 10:33:43,571 - INFO - Meter:  - Type: consumption - Reading: 
2024-06-15 10:33:43,571 - INFO - Meter:  - Type: demand - Reading: 
Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 169, in check_jwt
    user_info = jwt.decode(headers["Authorization"].split(" ")[1], key=key , algorithms=["RS256"])
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 157, in decode
    _validate_claims(
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 481, in _validate_claims
    _validate_exp(claims, leeway=leeway)
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 314, in _validate_exp
    raise ExpiredSignatureError("Signature has expired.")
jose.exceptions.ExpiredSignatureError: Signature has expired.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 208, in <module>
    read_meters(str(os.environ.get("API_KEY")))
  File "/home/user/octopus-usage-exporter/app/app.py", line 180, in read_meters
    check_jwt(api_key)
  File "/home/user/octopus-usage-exporter/app/app.py", line 174, in check_jwt
    except (jwt.ExpiredSignatureError, jwt.DecodeError, jwt.InvalidTokenError):
                                       ^^^^^^^^^^^^^^^
AttributeError: module 'jose.jwt' has no attribute 'DecodeError'

BTW, if I am the only one using this I'm happy to use an alternative solution?

JosephRPalmer commented 2 weeks ago

Apologies, I am pushing another fix now.

JosephRPalmer commented 2 weeks ago

Please try 0.0.20

JosephRPalmer commented 2 weeks ago

@sshaikh I am interested in what you changed and didn't work also?

sshaikh commented 2 weeks ago

I previously just changed ExpiredSignature to ExpiredSignatureError

sshaikh commented 2 weeks ago

v0.0.20

2024-06-15 19:14:20,620 - ERROR - Hit error ExpiredSignatureError - Signature has expired., refreshing JWT
Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 169, in check_jwt
    user_info = jwt.decode(headers["Authorization"].split(" ")[1], key=key , algorithms=["RS256"])
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 157, in decode
    _validate_claims(
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 481, in _validate_claims
    _validate_exp(claims, leeway=leeway)
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/jose/jwt.py", line 314, in _validate_exp
    raise ExpiredSignatureError("Signature has expired.")
jose.exceptions.ExpiredSignatureError: Signature has expired.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/octopus-usage-exporter/app/app.py", line 209, in <module>
    read_meters(str(os.environ.get("API_KEY")))
  File "/home/user/octopus-usage-exporter/app/app.py", line 181, in read_meters
    check_jwt(api_key)
  File "/home/user/octopus-usage-exporter/app/app.py", line 176, in check_jwt
    get_jwt(api_key)
  File "/home/prometheus/octopus-usage-exporter/app/app.py", line 155, in get_jwt
    jwt_query = oe_client.execute(query, variable_values={"apiKey": api_key})
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/gql/client.py", line 403, in execute
    return self.execute_sync(
           ^^^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/gql/client.py", line 221, in execute_sync
    return session.execute(
           ^^^^^^^^^^^^^^^^
  File "/home/user/octopus-usage-exporter/lib/python3.11/site-packages/gql/client.py", line 860, in execute
    raise TransportQueryError(
gql.transport.exceptions.TransportQueryError: {'message': 'Signature of the JWT has expired.', 'locations': [{'line': 2, 'column': 3}], 'path': ['obtainKrakenToken'], 'extensions': {'errorType': 'APPLICATION', 'errorCode': 'KT-CT-1124', 'errorDescription': ''}}

I've since moved to an alternative solution, but thanks for the attention here.

JosephRPalmer commented 2 weeks ago

Hi @sshaikh, thanks for trying my solution and all the data from errors. I've managed to reproduce the error locally and finally found the issue. Thanks for your help in troubleshooting this.