Code Monkey home page Code Monkey logo

grafana-client's People

Contributors

amotl avatar asalkeld avatar beeradb avatar beingnikhilarora avatar bhks avatar changdingfang avatar chintal avatar dependabot-preview[bot] avatar dependabot[bot] avatar eric-fontana-bose avatar hamelg avatar harish422 avatar larsderidder avatar lilatomic avatar luixx avatar m0nhawk avatar maharacha avatar mbovo avatar mottish avatar ohmrefresh avatar panchorn avatar patsevanton avatar peekjef72 avatar ralfherzog avatar sedan07 avatar storg2001 avatar sytten avatar szuro avatar tescalada avatar tharvik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

grafana-client's Issues

Feature: Organisation-awareness

Grafana can support multiple organisations within a single instance. The organisation that requests are made to is stateful; that is, a request is made to change the user's context to an organisation, and all requests are then made against that organisation. This statefulness can lead to trouble if the org context is not changed at the beginning of the execution or if it is changed during execution.

Including the orgId query parameter will cause grafana to automatically change the user's context and returns a 302 Found for the same URL. This results in a retry of the request in the correct org.

Proposal: add an org_id parameter to GrafanaApi, which is passed to GrafanaClient, which adds it to self.s.params. If you'd like this, I can contribute the MR.

Improve test suite by adding integration tests with Grafana

Hi there,

currently, grafana-client employs testing solely by mocking HTTP conversations. Because this does not cover real integration tests with Grafana, it is easy to miss regressions, like those which recently happened here.

On the other hand, both grafana-wtf, and Kotori, already feature such an integration test suite with Grafana. In this manner, the grafana-wtf test harness was able to catch this issue.

So, grafana-client will need to adopt that test suite soon, in order to improve compatibility and QA on different versions of Grafana, by adding them to a test matrix.

grafana-wtf/tests can be an inspiration for this. While being at it, we may split this off into a generic pytest-grafana package, in the same spirit like the recently conceived pytest-mqtt package.

With kind regards,
Andreas.

Alternative way of creating alert rules?

Hi there,

coming from #30, I am wondering if grafana-client could also provide an alternative way of creating alert rules.

@Maharacha asked at #30 (comment):

Is it possible to use /api/ruler/grafana/api/v1/rules/<rule_group> instead? That is what the UI is using. When using that endpoint instead of the provisioning API endpoints supported with #30, it is possible to edit and delete corresponding entities from the Grafana UI.

With kind regards,
Andreas.

Unable to create team

Describe the bug
When using grafana_api.teams.add_team(), I am observing errors.

To Reproduce
Steps to reproduce the behavior:

  1. Create Grafana Api client
  2. Search team (not found)
  3. Create team
  4. Call add_team method
  5. See error - grafana_client.client.GrafanaClientError: Client Error 404: Not found
    grafana_api = GrafanaApi(auth=GRAFANA_API_KEY, host=GRAFANA_URL)
    grafana_teams = grafana_api.teams.search_teams(perpage=100, page=1, query=team_name)
    
    grafana_team = next((team for team in grafana_teams if team["name"] == team_name), None)
    
    if grafana_team is None:
      team = {
          "name": team_name
          }
      new_team = grafana_api.teams.add_team(json.dumps(team))

Expected behavior
We should be able to create a team in grafana.

Versions

  • Grafana: [ 8.4.5]
  • grafana-client: [ 2.3.0]
  • Authentication: Token

Additional context
If I call the same endpoint using postman I'm able to create the team

Regression with `delete_folder` in Grafana 9.3.0

What API call do you use?

grafana.folder.delete_folder(uid=folder_uid) 1

What is the actual output?

requests.exceptions.JSONDecodeError: [Errno Expecting value] : 0 2

What is the expected output?

It worked before on Grafana 9.2.4.

References

Footnotes

  1. https://github.com/panodata/grafana-wtf/actions/runs/3582719496/jobs/6027277338#step:5:1888

  2. https://github.com/panodata/grafana-wtf/actions/runs/3582719496/jobs/6027277338#step:5:1935

Add converter for dashboard JSON in "export format" representation

Hi there,

@jeremybz / @jeremybanzhaf asked at 1:

My goal is to use the API to get the JSON representation of a dashboard, including __inputs and named datasources.

@jangaraj answered:

HTTP API for dashboard export for external use doesn’t exist. This export feature is implemented in the UI (frontend). I would say the only option is to use standard dashboard API and make that output transformed into “dashboard format for external use”. Unfortunately, that format is not documented, so you have to use reverse engineering.

Torkel Ödegaard said at 2:

This is not possible, the data is captured by the frontend so you would have to replicate what all the panel & data sources do (issue metric queries etc).

In order to implement this transformation, I would be happy to provide a place within this package, if possible. Would that make any sense / be helpful in any way?

The implementation should adhere to the specifications defined by the corresponding TypeScript code.

With kind regards,
Andreas.

/cc @jangaraj

Footnotes

  1. https://community.grafana.com/t/export-dashboard-for-external-use-via-http-api/50716

  2. https://community.grafana.com/t/snapshot-api-how-to-get-the-data/2424

Grafana Smart Query Prometheus missing key

Describe the bug

result = grafana.datasource.smartquery(datasource=datasource, expression='openstack_nova_total_vms')

I have called smartquery for the type=prometheus.

This function doesn't take from and to keys which is required to call grafana for the prometheus query, otherwise it is giving 200 ok but the output doesn't contain any data. But if provided with timestamp in from and to it gives the data.

This is the result:

{'results': {'A': {'status': 200, 'frames': []}}}

Setting timeout explicitly

As of now timeout is set to 5 seconds and there is no way to change it. Please add this option to from_url method.

Thanks and regards, Mikhail

Cannot find `from_url` function in GrafanaApi class in api.py module

Describe the bug
A clear and concise description of what the bug is.
I see this
AttributeError: type object 'GrafanaApi' has no attribute 'from_url'

To Reproduce
Steps to reproduce the behavior:

  1. Install latest grafana-client using pip install grafana-client==2.3.0

  2. Run with valid key

from grafana_client import GrafanaApi

# Use Grafana API token.
grafana = GrafanaApi.from_url(
    url="https://grafana.example.org/grafana",
    auth="eyJrIjoiWHg...dGJpZCI6MX0=",
)

Expected behavior
I see the method in the repo code but not in my site packages when I do pip install.
Expecting this to run error free.

Versions

  • Grafana: [ 8.5.2]
  • grafana-client: [ 2.3.0]
  • Authentication: [Token]

Additional context
Add any other context about the problem here.

grafana_client.client.GrafanaClientError: Client Error 404: Not found

Describe the bug

I have started looking at the Grafana Client python library. Whatever the method I try from Grafana Client, I get the 404 error.

Error

Traceback (most recent call last):
  File "D:\Nandan\PythonScripts\Grafana API Calls.py", line 19, in <module>
    print(grafana.datasource.list_datasources())
  File "D:\Python\Python39\lib\site-packages\grafana_client\elements\datasource.py", line 144, in list_datasources
    r = self.client.GET(list_datasources_path)
  File "D:\Python\Python39\lib\site-packages\grafana_client\client.py", line 156, in __request_runner
    raise GrafanaClientError(
grafana_client.client.GrafanaClientError: Client Error 404: Not found

Expected behavior
I am able to make these calls from Postman Web Agent and I am successful in getting the response back.

Versions

  • Grafana: [V9.2.4]
  • grafana-client: [API]
  • Authentication: [Token]

Additional context
print(grafana.datasource.list_datasources())

Above is the simple method I am using the get the response.

Introducing the data source health check subsystem

Dear @chenlujjj and @jangaraj,

Originally coming from How to find out unused datasources?, based on our discussion at Finding unhealthy data sources, we finally made a start to lay out the foundation with #19. Health checks for a few data source types will be supported already 1, but we will have to complete the list diligently, which requires dedicated work.

Corresponding documentation how to work with the health check subsystem on behalf of an example program examples/datasource-health.py can be inspected at examples/datasource-health.rst. The program is intended to evaluate the new subsystem with different databases, in order to gradually improve the implementation. We tried to make it easily usable for others to run in order to support this endeavor.

When the feature is reasonably ready over here, we will return to grafana-toolbox/grafana-wtf#19 in order to continue the discussion how to use it within grafana-wtf appropriately.

If this resonates with you, you might want to lend a hand? All kinds of feedback, both in terms of testing and further contributions will be greatly appreciated. Thank you very much in advance.

With kind regards,
Andreas.


Usage

The documentation at examples/datasource-health.rst will guide you through a full development sandbox installation, including running Grafana and some database services as Docker containers, and setting up the working tree from the Git repository.

In this section, we outline an alternative approach how to work with the feature using the example program examples/datasource-health.py. It might save a few keystrokes, specifically when aiming to work on an existing infrastructure.

# Setup
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade git+https://github.com/panodata/grafana-client
wget https://raw.githubusercontent.com/panodata/grafana-client/main/examples/datasource-health.py

# Run
export GRAFANA_URL=http://daq.example.org:3000
export GRAFANA_TOKEN=eyJrIjoiUWVrYXJh....aWQiOjJ9
python datasource-health.py --type=influxdb --url=http://daq.example.org:8086

Details

The example program will create a data source item named probe-{dstype}, with the designated database target URL. Then, it will run a data source health check on it and report about its outcome.

This will work well in situations when running the database services as Docker containers, as outlined in the reference documentation at examples/datasource-health.rst. It might not work well in other situations, where the data source configuration might need further adjustments.

In this case, don't hesitate to adjust the datasource_factory() code correspondingly to match your setup.

References

Footnotes

  1. CrateDB, Elasticsearch, InfluxDB, PostgreSQL, Prometheus, Testdata

feature request: async api

Hi there,

are there any plans to support/switch to an async client like httpx in place of requests?

It would be useful for using it within web services without blocking concurrency.

Grafana 10.2.3: breaking changes

Describe the bug

Grafana-client is no longer compatible with the data source permissions APIs of grafana Enterprise 10.2.3.

https://grafana.com/blog/2024/01/08/grafana-10.2.3-release-new-features-and-breaking-changes

The following data source permission endpoints have been removed:

  • GET /datasources/:datasourceId/permissions
  • POST /api/datasources/:datasourceId/permissions
  • DELETE /datasources/:datasourceId/permissions
  • POST /datasources/:datasourceId/enable-permissions
  • POST /datasources/:datasourceId/disable-permissions

replaced by:

  • GET /api/access-control/datasources/:uid for listing data source permissions
  • POST /api/access-control/datasources/:uid/users/:id, POST /api/access-control/datasources/:uid/teams/:id
  • POST /api/access-control/datasources/:uid/buildInRoles/:id for adding or removing data source permissions

Versions

  • Grafana: 10.2.3
  • grafana-client: 3.11.0

Cannot update datasource key with newlines, e.g. GCP Monitoring

Describe the bug
Hello team,

I am trying to rotate a service account key for a GCP Monitoring data source in Grafana. I generate the new key in GCP, I save it in the Secrets manager, but when I update the datasource with the proper key, it simply stops working. I believe it's because the \n newline characters are escaped to \\n and the data source is saved with the wrong key.

To Reproduce
Please review the code snippet below. The key I get from GCP is already a JWT key with newline characters in place, e.g. -----BEGIN PRIVATE KEY-----\nReStOfThEkEy\n.

decoded_key = base64.b64decode(key).decode("utf-8")
key_dict = json.loads(decoded_key)
try:
    datasource_object = self.client.datasource.find_datasource('my-test-data-source')
except GrafanaClientError as exception:
    logging.error(exception)
    sys.exit(1)

datasource_uid = datasource_object["uid"]

datasource_object["jsonData"]["authenticationType"] = "jwt"
datasource_object["jsonData"]["clientEmail"] = key_dict["client_email"]
datasource_object["jsonData"]["defaultProject"] = key_dict["project_id"]
datasource_object["jsonData"]["tokenUri"] = key_dict["token_uri"]
datasource_object["secureJsonFields"]["privateKey"] = key_dict["private_key"]

result = self.client.datasource.update_datasource_by_uid(
    datasource_uid, datasource_object
)
logging.info(f"{result['message']}, uid: {datasource_uid}")

Expected behavior
I can update the JWT keys for my GCP integrations.

Versions

  • Grafana: v10.1
  • grafana-client: 9.3.1
  • Authentication: Token

Add x-disable-provenance header to allow alert rules to be edited from the UI

What API call you use?

  • Based on this PR grafana/grafana#58410 which was merged in the new version 9.3.0, we can the header x-disable-provenance to allow the alert rules created under the alert provisioning API to be modifiable via UI.

This can only be added on the POST request, if we try to update with the PUT operation an alert has already been created we got the following error:

{
    "message": "cannot changed provenance from 'api' to ''",
    "traceID": ""
}

What is the actual output?

  • Without the header when the rule is created we cannot edit the alert rules via UI, we got the label "provisioned".

What is the expected output?
And what output is expected.

  • Alerts created with the header can be edited via UI like in the s screenshot below
    image

Missing update datasource by UID.

What Grafana API endpoint the library is missing?

There is no update_datasource_by_uid function, only update_datasource, which takes the ID rather than UID. Using the ID is deprecated.

See Update an existing data source Grafana API documentation.

Quick work-around until implemented:

  update_datasource = f"/datasources/uid/{uid}"
  grafana.client.PUT(update_datasource, json=datasource)

Dashboard.get_dashboard_by_name seems broken

Describe the bug

I might be totaly wrong by it seems this path this method tries to access does not exist.
At least not in the grafana docs..

  10  -> grafana.search.search_dashboards(tag="fake")                                                                                                                                                                                         
(Pdb++) grafana.search.search_dashboards(tag="fake")
[{'id': 1, 'uid': 'b071f222-28cf-4025-a13c-14b4adde3071', 'title': 'Palette-Fake', 'uri': 'db/palette-fake', 'url': '/d/b071f222-28cf-4025-a13c-14b4adde3071/palette-fake', 'slug': '', 'type': 'dash-db', 'tags': ['fake'], 'isStarred': False, 'sortMeta': 0}]
(Pdb++) grafana.dashboard.
client                        get_dashboard                 get_dashboard_permissions     get_home_dashboard            update_dashboard_permissions  
delete_dashboard              get_dashboard_by_name         get_dashboards_tags           update_dashboard              
(Pdb++) grafana.dashboard.get_dashboard_by_name("palette-fake")
*** grafana_client.client.GrafanaClientError: Client Error 404: Not found
Traceback (most recent call last):
  File "/home/oznt/.local/share/virtualenvs/reporting-JW0JCX-S/lib/python3.11/site-packages/grafana_client/elements/dashboard.py", line 26, in get_dashboard_by_name
    r = self.client.GET(get_dashboard_path)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/oznt/.local/share/virtualenvs/reporting-JW0JCX-S/lib/python3.11/site-packages/grafana_client/client.py", line 156, in __request_runner
    raise GrafanaClientError(

Versions

  • Grafana: 9.1.0
  • grafana-client: 3.5.0
  • Authentication: Token.

distutils.version.LooseVersion is deprecated

Describe the bug
Got an error

File /home/ffy/workspace/PyProjects/venv/lib/python3.12/site-packages/grafana_client/elements/dashboard.py:1
----> 1 from distutils.version import LooseVersion
      3 from .base import Base
      6 class Dashboard(Base):

ModuleNotFoundError: No module named 'distutils'

while import grafana_client in python 3.12.
Based on PEP386, distutils is deprecated and we may have some alternatives.

To Reproduce
Steps to reproduce the behavior:

  1. python 3.12
  2. import grafana_client

Expected behavior
ModuleNotFoundError: No module named 'distutils'

Versions

Additional context

Get all folders endpoint is incorrect

Describe the bug
The folders.get_all_folders endpoint provides the parent_uid, if set, in data. This puts it in the body of the resulting API request. This needs to be a query parameter, however.

https://grafana.com/docs/grafana/latest/developers/http_api/folder/#get-all-folders

To Reproduce
Steps to reproduce the behavior:

  1. Create a Folder in grafana. Create a subfolder folder within it. Note that nested folders needs to be enabled on the Grafana instance
  2. Run client.folders.get_all_folders(parent_uid=<uid of created parent>)
  3. You'll get the contents of the root folder

Expected behavior
Folders contained within the provided parent_uid should be returned.

Versions

  • Grafana: v10.4.1 (d3ce857c0e)
  • grafana-client: git main head
  • Authentication: Token

Additional context
I've quickly tested that the problem is resolved if I change data=data to params=data in the __request_runner call to s.request() in client.py. Obviously, this is not a viable solution.

The infrastructure needs to be modified to allow params to be passed through to the final request call, the same way data presently is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.