Skip to content

Commit

Permalink
Accept datasource attribute on DatasourceItem, but don't process it
Browse files Browse the repository at this point in the history
> When I try to explore datasources it always fail with a TypeError.
> No idea why this happens.

Exception:

  TypeError: DatasourceItem.__init__() got an unexpected keyword
  argument 'datasource'
  • Loading branch information
amotl committed Sep 28, 2024
1 parent d29da52 commit d65ef27
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
6 changes: 4 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ grafana-wtf changelog
in progress
===========
- CI: Verify support for Grafana 11
- AMG compatibility: Fetch Grafana version from `/api/frontend/settings`
instead of `/api/health`. Thanks, @squadgazzz.
- AMG compatibility: Fetch Grafana version from ``/api/frontend/settings``
instead of ``/api/health``. Thanks, @squadgazzz.
- Accept ``datasource`` attribute on ``DatasourceItem``, but
ignore it for the time being. Thanks, @apepojken.

2024-04-20 0.19.1
=================
Expand Down
27 changes: 26 additions & 1 deletion grafana_wtf/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
# License: GNU Affero General Public License, Version 3
import dataclasses
import logging
import warnings
from collections import OrderedDict
from typing import Dict, List, Optional
from typing import Any, Dict, List, Optional
from urllib.parse import urljoin

from munch import Munch
Expand Down Expand Up @@ -158,6 +159,10 @@ def transform(section):

@dataclasses.dataclass
class DatasourceItem:
"""
Represent a datasource reference within a panel, annotation, or templating (variable).
"""

uid: Optional[str] = None
name: Optional[str] = None
type: Optional[str] = None
Expand All @@ -168,11 +173,31 @@ def from_payload(cls, payload: any):
if isinstance(payload, Munch):
payload = dict(payload)
if isinstance(payload, dict):
cls.validate(payload)
return cls(**payload)
if isinstance(payload, str):
return cls(name=payload)
raise TypeError(f"Unknown payload type for DatasourceItem: {type(payload)}")

@classmethod
def validate(cls, data: dict):
if "datasource" in data:
warnings.warn(
f"""
The `datasource` attribute is ignored for the time being.
See also: https://github.com/panodata/grafana-wtf/issues/110
Please report back this occurrence to the grafana-wtf issue tracker,
so the maintainers can improve the situation.
The context of this error is in `DatasourceItem`, using this ingress data:
{data}
""".strip(),
UserWarning,
)
del data["datasource"]


@dataclasses.dataclass
class DatasourceExplorationItem:
Expand Down
57 changes: 57 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import re

import pytest
from munch import Munch

from grafana_wtf.model import DatasourceItem

DATA = dict(uid="foo", name="bar", type="baz", url="qux")


def test_datasource_item_basic():
item = DatasourceItem(**DATA)
assert item.uid == "foo"


def test_datasource_item_dict_success():
item = DatasourceItem.from_payload(DATA)
assert item.uid == "foo"


def test_datasource_item_munch():
item = DatasourceItem.from_payload(Munch(**DATA))
assert item.uid == "foo"


def test_datasource_item_str():
item = DatasourceItem.from_payload("Hotzenplotz")
assert item.uid is None
assert item.name == "Hotzenplotz"


def test_datasource_item_dict_unknown_attribute():
mydata = DATA.copy()
mydata.update({"more": "data"})
with pytest.raises(TypeError) as ex:
DatasourceItem.from_payload(mydata)
assert ex.match(re.escape("__init__() got an unexpected keyword argument 'more'"))


def test_datasource_item_dict_compensate_datasource():
"""
Validate that the `datasource` attribute is ignored.
TypeError: DatasourceItem.__init__() got an unexpected keyword argument 'datasource'
https://github.com/panodata/grafana-wtf/issues/110
"""
mydata = DATA.copy()
mydata.update({"datasource": "unknown"})
with pytest.warns(UserWarning) as record:
item = DatasourceItem.from_payload(mydata)
assert item.uid == "foo"

# Check that only one warning was raised.
assert len(record) == 1

# Check that the message matches.
assert "The `datasource` attribute is ignored for the time being" in record[0].message.args[0]

0 comments on commit d65ef27

Please sign in to comment.