diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e41d1..6be70f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,20 @@ ## [Unreleased] +### Chore +- **changelog:** 0.7.4 + + + +## [0.7.4] - 2019-06-05 ### Chore - **changelog:** 0.7.3 +- **codestyle:** reformat +- **dep:** update +- **deps:** bump requests from 2.21.0 to 2.22.0 + +### Fix +- **api:** python2 Teams support, fix [#24](https://github.com/m0nhawk/grafana_api/issues/24) @@ -137,7 +149,8 @@ - always deploy -[Unreleased]: https://github.com/m0nhawk/grafana_api/compare/0.7.3...HEAD +[Unreleased]: https://github.com/m0nhawk/grafana_api/compare/0.7.4...HEAD +[0.7.4]: https://github.com/m0nhawk/grafana_api/compare/0.7.3...0.7.4 [0.7.3]: https://github.com/m0nhawk/grafana_api/compare/0.7.2...0.7.3 [0.7.2]: https://github.com/m0nhawk/grafana_api/compare/0.7.1...0.7.2 [0.7.1]: https://github.com/m0nhawk/grafana_api/compare/0.7.0...0.7.1 diff --git a/Pipfile b/Pipfile index 51bea03..43af684 100644 --- a/Pipfile +++ b/Pipfile @@ -11,4 +11,4 @@ requests = "~=2.22" codecov = "~=2.0" coverage = "~=4.5" unittest-xml-reporting = "~=2.5" -requests-mock = "~=1.5" +requests-mock = "~=1.6" diff --git a/Pipfile.lock b/Pipfile.lock index 839b6c8..849a0ad 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "bbff82609a9f6d127285c63a96537b29ffa8d5f00055a19c1d0e0370793d260a" + "sha256": "952fbc3fe44dfaf0eb08b13580760229791decbcf4783882a6811538e5cd3120" }, "pipfile-spec": 6, "requires": {}, diff --git a/grafana_api/api/admin.py b/grafana_api/api/admin.py index 695816a..9324511 100644 --- a/grafana_api/api/admin.py +++ b/grafana_api/api/admin.py @@ -11,7 +11,7 @@ def settings(self): :return: """ - path = '/admin/settings' + path = "/admin/settings" r = self.api.GET(path) return r @@ -20,7 +20,7 @@ def stats(self): :return: """ - path = '/admin/stats' + path = "/admin/stats" r = self.api.GET(path) return r @@ -30,7 +30,7 @@ def create_user(self, user): :param user: :return: """ - create_user_path = '/admin/users' + create_user_path = "/admin/users" r = self.api.POST(create_user_path, json=user) return r @@ -41,8 +41,8 @@ def change_user_password(self, user_id, password): :param password: :return: """ - change_user_password_path = '/admin/users/%s/password' % user_id - r = self.api.PUT(change_user_password_path, json={'password': password}) + change_user_password_path = "/admin/users/%s/password" % user_id + r = self.api.PUT(change_user_password_path, json={"password": password}) return r def change_user_permissions(self, user_id, is_grafana_admin): @@ -52,8 +52,10 @@ def change_user_permissions(self, user_id, is_grafana_admin): :param is_grafana_admin: :return: """ - change_user_permissions = '/admin/users/%s/permissions' % user_id - r = self.api.PUT(change_user_permissions, json={'isGrafanaAdmin': is_grafana_admin}) + change_user_permissions = "/admin/users/%s/permissions" % user_id + r = self.api.PUT( + change_user_permissions, json={"isGrafanaAdmin": is_grafana_admin} + ) return r def delete_user(self, user_id): @@ -62,7 +64,7 @@ def delete_user(self, user_id): :param user_id: :return: """ - delete_user_path = '/admin/users/%s' % user_id + delete_user_path = "/admin/users/%s" % user_id r = self.api.DELETE(delete_user_path) return r @@ -72,6 +74,6 @@ def pause_all_alerts(self, pause): :param pause: :return: """ - change_user_permissions = self.path + '/pause-all-alerts' - r = self.api.POST(change_user_permissions, json={'paused': pause}) + change_user_permissions = self.path + "/pause-all-alerts" + r = self.api.POST(change_user_permissions, json={"paused": pause}) return r diff --git a/grafana_api/api/dashboard.py b/grafana_api/api/dashboard.py index 40b8646..2380c23 100644 --- a/grafana_api/api/dashboard.py +++ b/grafana_api/api/dashboard.py @@ -3,7 +3,7 @@ class Dashboard(Base): def __init__(self, api): - super(Dashboard,self).__init__(api) + super(Dashboard, self).__init__(api) self.api = api def get_dashboard(self, dashboard_uid): @@ -12,7 +12,7 @@ def get_dashboard(self, dashboard_uid): :param dashboard_uid: :return: """ - get_dashboard_path = '/dashboards/uid/%s' % dashboard_uid + get_dashboard_path = "/dashboards/uid/%s" % dashboard_uid r = self.api.GET(get_dashboard_path) return r @@ -22,7 +22,7 @@ def update_dashboard(self, dashboard): :param dashboard: :return: """ - put_dashboard_path = '/dashboards/db' + put_dashboard_path = "/dashboards/db" r = self.api.POST(put_dashboard_path, json=dashboard) return r @@ -32,7 +32,7 @@ def delete_dashboard(self, dashboard_uid): :param dashboard_uid: :return: """ - delete_dashboard_path = '/dashboards/uid/%s' % dashboard_uid + delete_dashboard_path = "/dashboards/uid/%s" % dashboard_uid r = self.api.DELETE(delete_dashboard_path) return r @@ -41,7 +41,7 @@ def get_home_dashboard(self): :return: """ - get_home_dashboard_path = '/dashboards/home' + get_home_dashboard_path = "/dashboards/home" r = self.api.GET(get_home_dashboard_path) return r @@ -50,7 +50,7 @@ def get_dashboards_tags(self): :return: """ - get_dashboards_tags_path = '/dashboards/tags' + get_dashboards_tags_path = "/dashboards/tags" r = self.api.GET(get_dashboards_tags_path) return r @@ -60,7 +60,7 @@ def get_dashboard_permissions(self, dashboard_id): :param dashboard_id: :return: """ - get_dashboard_permissions_path = '/dashboards/id/%s/permissions' % dashboard_id + get_dashboard_permissions_path = "/dashboards/id/%s/permissions" % dashboard_id r = self.api.GET(get_dashboard_permissions_path) return r @@ -71,6 +71,8 @@ def update_dashboard_permissions(self, dashboard_id, items): :param items: :return: """ - update_dashboard_permissions_path = '/dashboards/id/%s/permissions' % dashboard_id + update_dashboard_permissions_path = ( + "/dashboards/id/%s/permissions" % dashboard_id + ) r = self.api.POST(update_dashboard_permissions_path, json=items) return r diff --git a/grafana_api/api/datasource.py b/grafana_api/api/datasource.py index bc6e21c..a96549a 100644 --- a/grafana_api/api/datasource.py +++ b/grafana_api/api/datasource.py @@ -3,7 +3,7 @@ class Datasource(Base): def __init__(self, api): - super(Datasource,self).__init__(api) + super(Datasource, self).__init__(api) self.api = api def find_datasource(self, datasource_name): @@ -12,7 +12,7 @@ def find_datasource(self, datasource_name): :param datasource_name: :return: """ - get_datasource_path = '/datasources/name/%s' % datasource_name + get_datasource_path = "/datasources/name/%s" % datasource_name r = self.api.GET(get_datasource_path) return r @@ -22,7 +22,7 @@ def get_datasource_by_id(self, datasource_id): :param datasource_id: :return: """ - get_datasource_path = '/datasources/%s' % datasource_id + get_datasource_path = "/datasources/%s" % datasource_id r = self.api.GET(get_datasource_path) return r @@ -32,7 +32,7 @@ def get_datasource_by_name(self, datasource_name): :param datasource_name: :return: """ - get_datasource_path = '/datasources/name/%s' % datasource_name + get_datasource_path = "/datasources/name/%s" % datasource_name r = self.api.GET(get_datasource_path) return r @@ -42,7 +42,7 @@ def get_datasource_id_by_name(self, datasource_name): :param datasource_name: :return: """ - get_datasource_path = '/datasources/id/%s' % datasource_name + get_datasource_path = "/datasources/id/%s" % datasource_name r = self.api.GET(get_datasource_path) return r @@ -52,7 +52,7 @@ def create_datasource(self, datasource): :param datasource: :return: """ - create_datasources_path = '/datasources' + create_datasources_path = "/datasources" r = self.api.POST(create_datasources_path, json=datasource) return r @@ -63,7 +63,7 @@ def update_datasource(self, datasource_id, datasource): :param datasource: :return: """ - update_datasource = '/datasources/%s' % datasource_id + update_datasource = "/datasources/%s" % datasource_id r = self.api.PUT(update_datasource, json=datasource) return r @@ -72,7 +72,7 @@ def list_datasources(self): :return: """ - list_datasources_path = '/datasources' + list_datasources_path = "/datasources" r = self.api.GET(list_datasources_path) return r @@ -82,7 +82,7 @@ def delete_datasource_by_id(self, datasource_id): :param datasource_id: :return: """ - delete_datasource = '/datasources/%s' % datasource_id + delete_datasource = "/datasources/%s" % datasource_id r = self.api.DELETE(delete_datasource) return r @@ -92,6 +92,6 @@ def delete_datasource_by_name(self, datasource_name): :param datasource_name: :return: """ - delete_datasource = '/datasources/name/%s' % datasource_name + delete_datasource = "/datasources/name/%s" % datasource_name r = self.api.DELETE(delete_datasource) return r diff --git a/grafana_api/api/folder.py b/grafana_api/api/folder.py index 3ab66f1..9781512 100644 --- a/grafana_api/api/folder.py +++ b/grafana_api/api/folder.py @@ -3,7 +3,7 @@ class Folder(Base): def __init__(self, api): - super(Folder,self).__init__(api) + super(Folder, self).__init__(api) self.api = api def get_all_folders(self): @@ -11,7 +11,7 @@ def get_all_folders(self): :return: """ - path = '/folders' + path = "/folders" r = self.api.GET(path) return r @@ -21,7 +21,7 @@ def get_folder(self, uid): :param uid: :return: """ - path = '/folders/%s' % uid + path = "/folders/%s" % uid r = self.api.GET(path) return r @@ -34,8 +34,8 @@ def create_folder(self, title, uid=None): """ json_data = dict(title=title) if uid is not None: - json_data['uid'] = uid - return self.api.POST('/folders', json=json_data) + json_data["uid"] = uid + return self.api.POST("/folders", json=json_data) def update_folder(self, uid, title): """ @@ -44,10 +44,8 @@ def update_folder(self, uid, title): :param title: :return: """ - path = '/folders' % uid - r = self.api.PUT(path, json={ - "title": title - }) + path = "/folders/%s" % uid + r = self.api.PUT(path, json={"title": title}) return r def delete_folder(self, uid): @@ -56,7 +54,7 @@ def delete_folder(self, uid): :param uid: :return: """ - path = '/folders/%s' % uid + path = "/folders/%s" % uid r = self.api.DELETE(path) return r @@ -66,7 +64,7 @@ def get_folder_by_id(self, folder_id): :param folder_id: :return: """ - path = '/folders/id/%s' % folder_id + path = "/folders/id/%s" % folder_id r = self.api.GET(path) return r @@ -75,7 +73,7 @@ def get_folder_permissions(self): :return: """ - path = '/folders/%s/permissions' + path = "/folders/%s/permissions" r = self.api.GET(path) return r @@ -86,6 +84,6 @@ def update_folder_permissions(self, uid, items): :param items: :return: """ - update_folder_permissions_path = '/folders/%s/permissions' % uid + update_folder_permissions_path = "/folders/%s/permissions" % uid r = self.api.POST(update_folder_permissions_path, json=items) return r diff --git a/grafana_api/api/organization.py b/grafana_api/api/organization.py index f2a7c21..6843b0a 100644 --- a/grafana_api/api/organization.py +++ b/grafana_api/api/organization.py @@ -3,7 +3,7 @@ class Organization(Base): def __init__(self, api): - super(Organization,self).__init__(api) + super(Organization, self).__init__(api) self.api = api def find_organization(self, org_name): @@ -12,7 +12,7 @@ def find_organization(self, org_name): :param org_name: :return: """ - get_org_path = '/orgs/name/%s' % org_name + get_org_path = "/orgs/name/%s" % org_name r = self.api.GET(get_org_path) return r @@ -21,7 +21,7 @@ def get_current_organization(self): :return: """ - get_current_organization_path = '/org' + get_current_organization_path = "/org" r = self.api.GET(get_current_organization_path) return r @@ -31,8 +31,8 @@ def create_organization(self, organization): :param organization: :return: """ - create_orgs_path = '/orgs' - r = self.api.POST(create_orgs_path, json={'name': organization['name']}) + create_orgs_path = "/orgs" + r = self.api.POST(create_orgs_path, json={"name": organization["name"]}) return r def update_current_organization(self, organization): @@ -41,7 +41,7 @@ def update_current_organization(self, organization): :param organization: :return: """ - update_current_organization_path = '/org' + update_current_organization_path = "/org" r = self.api.PUT(update_current_organization_path, json=organization) return r @@ -50,7 +50,7 @@ def get_current_organization_users(self): :return: """ - get_current_organization_users_path = '/org/users' + get_current_organization_users_path = "/org/users" r = self.api.GET(get_current_organization_users_path) return r @@ -60,7 +60,7 @@ def add_user_current_organization(self, user): :param user: :return: """ - add_user_current_organization_path = '/org/users' + add_user_current_organization_path = "/org/users" r = self.api.POST(add_user_current_organization_path, json=user) return r @@ -71,7 +71,7 @@ def update_user_current_organization(self, user_id, user): :param user: :return: """ - update_user_current_organization_path = '/org/users/%s' % user_id + update_user_current_organization_path = "/org/users/%s" % user_id r = self.api.PATCH(update_user_current_organization_path, json=user) return r @@ -81,16 +81,16 @@ def delete_user_current_organization(self, user_id): :param user_id: :return: """ - delete_user_current_organization_path = '/org/users/%s' % user_id + delete_user_current_organization_path = "/org/users/%s" % user_id r = self.api.DELETE(delete_user_current_organization_path) return r class Organizations(Base): def __init__(self, api): - super(Organizations,self).__init__(api) + super(Organizations, self).__init__(api) self.api = api - self.path = '/users' + self.path = "/users" def update_organization(self, organization_id, organization): """ @@ -99,7 +99,7 @@ def update_organization(self, organization_id, organization): :param organization: :return: """ - update_org_path = '/orgs/%s' % organization_id + update_org_path = "/orgs/%s" % organization_id r = self.api.PUT(update_org_path, json=organization) return r @@ -109,7 +109,7 @@ def delete_organization(self, organization_id): :param organization_id: :return: """ - delete_org_path = '/orgs/%s' % organization_id + delete_org_path = "/orgs/%s" % organization_id r = self.api.DELETE(delete_org_path) return r @@ -118,7 +118,7 @@ def list_organization(self): :return: """ - search_org_path = '/orgs' + search_org_path = "/orgs" r = self.api.GET(search_org_path) return r @@ -128,7 +128,7 @@ def switch_organization(self, organization_id): :param organization_id: :return: """ - switch_user_organization = '/user/using/%s' % organization_id + switch_user_organization = "/user/using/%s" % organization_id r = self.api.POST(switch_user_organization) return r @@ -138,7 +138,7 @@ def organization_user_list(self, organization_id): :param organization_id: :return: """ - users_in_org = '/orgs/%s/users' % organization_id + users_in_org = "/orgs/%s/users" % organization_id r = self.api.GET(users_in_org) return r @@ -149,7 +149,7 @@ def organization_user_add(self, organization_id, user): :param user: :return: """ - add_user_path = '/orgs/%s/users' % organization_id + add_user_path = "/orgs/%s/users" % organization_id r = self.api.POST(add_user_path, json=user) return r @@ -161,8 +161,8 @@ def organization_user_update(self, organization_id, user_id, user_role): :param user_role: :return: """ - patch_user = '/orgs/%s/users/%s' % (organization_id, user_id) - r = self.api.PATCH(patch_user, json={'role': user_role}) + patch_user = "/orgs/%s/users/%s" % (organization_id, user_id) + r = self.api.PATCH(patch_user, json={"role": user_role}) return r def organization_user_delete(self, organization_id, user_id): @@ -172,7 +172,7 @@ def organization_user_delete(self, organization_id, user_id): :param user_id: :return: """ - delete_user = '/orgs/%s/users/%s' % (organization_id, user_id) + delete_user = "/orgs/%s/users/%s" % (organization_id, user_id) r = self.api.DELETE(delete_user) return r @@ -180,11 +180,13 @@ def organization_preference_get(self): """ :return: """ - update_preference = '/org/preferences' + update_preference = "/org/preferences" r = self.api.GET(update_preference) return r - def organization_preference_update(self, theme='', home_dashboard_id=0, timezone='utc'): + def organization_preference_update( + self, theme="", home_dashboard_id=0, timezone="utc" + ): """ :param theme: @@ -192,10 +194,13 @@ def organization_preference_update(self, theme='', home_dashboard_id=0, timezone :param timezone: :return: """ - update_preference = '/org/preferences' - r = self.api.PUT(update_preference, json={ - "theme": theme, - "homeDashboardId": home_dashboard_id, - "timezone": timezone - }) + update_preference = "/org/preferences" + r = self.api.PUT( + update_preference, + json={ + "theme": theme, + "homeDashboardId": home_dashboard_id, + "timezone": timezone, + }, + ) return r diff --git a/grafana_api/api/search.py b/grafana_api/api/search.py index ac3519a..abdca61 100644 --- a/grafana_api/api/search.py +++ b/grafana_api/api/search.py @@ -3,11 +3,19 @@ class Search(Base): def __init__(self, api): - super(Search,self).__init__(api) + super(Search, self).__init__(api) self.api = api - def search_dashboards(self, query=None, tag=None, type_=None, dashboard_ids=None, folder_ids=None, starred=None, - limit=None): + def search_dashboards( + self, + query=None, + tag=None, + type_=None, + dashboard_ids=None, + folder_ids=None, + starred=None, + limit=None, + ): """ :param query: @@ -19,32 +27,32 @@ def search_dashboards(self, query=None, tag=None, type_=None, dashboard_ids=None :param limit: :return: """ - list_dashboard_path = '/search' + list_dashboard_path = "/search" params = [] if query: - params.append('query=%s' % query) + params.append("query=%s" % query) if tag: - params.append('tag=%s' % tag) + params.append("tag=%s" % tag) if type_: - params.append('type=%s' % type_) + params.append("type=%s" % type_) if dashboard_ids: - params.append('dashboardIds=%s' % dashboard_ids) + params.append("dashboardIds=%s" % dashboard_ids) if folder_ids: - params.append('folderIds=%s' % folder_ids) + params.append("folderIds=%s" % folder_ids) if starred: - params.append('starred=%s' % starred) + params.append("starred=%s" % starred) if limit: - params.append('limit=%s' % limit) + params.append("limit=%s" % limit) - list_dashboard_path += '?' - list_dashboard_path += '&'.join(params) + list_dashboard_path += "?" + list_dashboard_path += "&".join(params) r = self.api.GET(list_dashboard_path) return r diff --git a/grafana_api/api/team.py b/grafana_api/api/team.py index b5b36a1..56eac41 100644 --- a/grafana_api/api/team.py +++ b/grafana_api/api/team.py @@ -3,7 +3,7 @@ class Teams(Base): def __init__(self, api): - super().__init__(api) + super(Teams, self).__init__(api) self.api = api def search_teams(self, query=None, page=None, perpage=None): @@ -12,26 +12,25 @@ def search_teams(self, query=None, page=None, perpage=None): :return: """ list_of_teams = [] - teams_on_page = None - search_teams_path = '/teams/search' + search_teams_path = "/teams/search" params = [] if query: - params.append('query=%s' % query) + params.append("query=%s" % query) if page: iterate = False - params.append('page=%s' % page) + params.append("page=%s" % page) else: iterate = True - params.append('page=%s') + params.append("page=%s") page = 1 if perpage: - params.append('perpage=%s' % perpage) + params.append("perpage=%s" % perpage) - search_teams_path += '?' - search_teams_path += '&'.join(params) + search_teams_path += "?" + search_teams_path += "&".join(params) if iterate: while True: @@ -52,9 +51,9 @@ def get_team_by_name(self, team_name): :param team_name: :return: """ - search_teams_path = '/teams/search' + search_teams_path = "/teams/search" - search_teams_path += '?name=%s' % team_name + search_teams_path += "?name=%s" % team_name teams_on_page = self.api.GET(search_teams_path) return teams_on_page["teams"] @@ -65,7 +64,7 @@ def get_team(self, team_id): :param team_id: :return: """ - get_team_path = '/teams/%s' % team_id + get_team_path = "/teams/%s" % team_id r = self.api.GET(get_team_path) return r @@ -75,7 +74,7 @@ def add_team(self, team): :param team: :return: """ - add_team_path = '/teams' + add_team_path = "/teams" r = self.api.POST(add_team_path, json=team) return r @@ -86,7 +85,7 @@ def update_team(self, team_id, team): :param team: :return: """ - update_team_path = '/teams/%s' % team_id + update_team_path = "/teams/%s" % team_id r = self.api.PUT(update_team_path, json=team) return r @@ -96,7 +95,7 @@ def delete_team(self, team_id): :param team_id: :return: """ - delete_team_path = '/teams/%s' % team_id + delete_team_path = "/teams/%s" % team_id r = self.api.DELETE(delete_team_path) return True @@ -106,7 +105,7 @@ def get_team_members(self, team_id): :param team_id: :return: """ - get_team_members_path = '/teams/%s/members' % team_id + get_team_members_path = "/teams/%s/members" % team_id r = self.api.GET(get_team_members_path) return r @@ -117,10 +116,8 @@ def add_team_member(self, team_id, user_id): :param user_id: :return: """ - add_team_member_path = '/teams/%s/members' % team_id - payload = { - "userId": user_id - } + add_team_member_path = "/teams/%s/members" % team_id + payload = {"userId": user_id} r = self.api.POST(add_team_member_path, json=payload) return r @@ -131,7 +128,7 @@ def remove_team_member(self, team_id, user_id): :param user_id: :return: """ - remove_team_member_path = '/teams/%s/members/%s' % (team_id, user_id) + remove_team_member_path = "/teams/%s/members/%s" % (team_id, user_id) r = self.api.DELETE(remove_team_member_path) return r @@ -141,7 +138,7 @@ def get_team_preferences(self, team_id): :param team_id: :return: """ - get_team_preferences_path = '/teams/%s/preferences' % team_id + get_team_preferences_path = "/teams/%s/preferences" % team_id r = self.api.GET(get_team_preferences_path) return r @@ -152,6 +149,6 @@ def update_team_preferences(self, team_id, preferences): :param preferences: :return: """ - update_team_preferences_path = '/teams/%s/preferences' % team_id + update_team_preferences_path = "/teams/%s/preferences" % team_id r = self.api.PUT(update_team_preferences_path, json=preferences) return r diff --git a/grafana_api/api/user.py b/grafana_api/api/user.py index bb87fe5..45460d1 100644 --- a/grafana_api/api/user.py +++ b/grafana_api/api/user.py @@ -3,7 +3,7 @@ class Users(Base): def __init__(self, api): - super(Users,self).__init__(api) + super(Users, self).__init__(api) self.api = api def search_users(self, query=None, page=None, perpage=None): @@ -13,28 +13,28 @@ def search_users(self, query=None, page=None, perpage=None): """ list_of_users = [] users_on_page = None - show_users_path = '/users' + show_users_path = "/users" params = [] if query: - params.append('query=%s' % query) + params.append("query=%s" % query) if page: iterate = False - params.append('page=%s' % page) + params.append("page=%s" % page) else: iterate = True - params.append('page=%s') + params.append("page=%s") page = 1 if perpage: - params.append('perpage=%s' % perpage) + params.append("perpage=%s" % perpage) - show_users_path += '?' - show_users_path += '&'.join(params) + show_users_path += "?" + show_users_path += "&".join(params) if iterate: - while users_on_page != []: + while users_on_page is not []: users_on_page = self.api.GET(show_users_path % page) list_of_users += users_on_page page += 1 @@ -50,7 +50,7 @@ def get_user(self, user_id): :param user_id: :return: """ - get_user_path = '/users/%s' % user_id + get_user_path = "/users/%s" % user_id r = self.api.GET(get_user_path) return r @@ -60,7 +60,7 @@ def find_user(self, login_or_email): :param login_or_email: :return: """ - search_user_path = '/users/lookup?loginOrEmail=%s' % login_or_email + search_user_path = "/users/lookup?loginOrEmail=%s" % login_or_email r = self.api.GET(search_user_path) return r @@ -71,7 +71,7 @@ def update_user(self, user_id, user): :param user: :return: """ - update_user_path = '/users/%s' % user_id + update_user_path = "/users/%s" % user_id r = self.api.PUT(update_user_path, json=user) return r @@ -81,23 +81,23 @@ def get_user_organisations(self, user_id): :param user_id: :return: """ - get_user_organisations_path = '/users/%s/orgs' % user_id + get_user_organisations_path = "/users/%s/orgs" % user_id r = self.api.GET(get_user_organisations_path) return r class User(Base): def __init__(self, api): - super(User,self).__init__(api) + super(User, self).__init__(api) self.api = api - self.path = '/user' + self.path = "/user" def get_actual_user(self): """ :return: """ - get_actual_user_path = '/user' + get_actual_user_path = "/user" r = self.api.GET(get_actual_user_path) return r @@ -108,13 +108,15 @@ def change_actual_user_password(self, old_password, new_password): :param new_password: :return: """ - change_actual_user_password_path = '/user/password' + change_actual_user_password_path = "/user/password" change_actual_user_password_json = { "oldPassword": old_password, "newPassword": new_password, - "confirmNew": new_password + "confirmNew": new_password, } - r = self.api.PUT(change_actual_user_password_path, json=change_actual_user_password_json) + r = self.api.PUT( + change_actual_user_password_path, json=change_actual_user_password_json + ) return r def switch_user_organisation(self, user_id, organisation_id): @@ -124,7 +126,10 @@ def switch_user_organisation(self, user_id, organisation_id): :param organisation_id: :return: """ - switch_user_organisation_path = '/users/%s/using/%s' % (user_id, organisation_id) + switch_user_organisation_path = "/users/%s/using/%s" % ( + user_id, + organisation_id, + ) r = self.api.POST(switch_user_organisation_path) return r @@ -134,7 +139,7 @@ def switch_actual_user_organisation(self, organisation_id): :param organisation_id: :return: """ - switch_actual_user_organisation_path = '/user/using/%s' % organisation_id + switch_actual_user_organisation_path = "/user/using/%s" % organisation_id r = self.api.POST(switch_actual_user_organisation_path) return r @@ -143,7 +148,7 @@ def get_actual_user_organisations(self): :return: """ - get_actual_user_organisations_path = '/user/orgs' + get_actual_user_organisations_path = "/user/orgs" r = self.api.GET(get_actual_user_organisations_path) return r @@ -153,7 +158,7 @@ def star_actual_user_dashboard(self, dashboard_id): :param dashboard_id: :return: """ - star_dashboard = '/user/stars/dashboard/%s' % dashboard_id + star_dashboard = "/user/stars/dashboard/%s" % dashboard_id r = self.api.POST(star_dashboard) return r @@ -163,6 +168,6 @@ def unstar_actual_user_dashboard(self, dashboard_id): :param dashboard_id: :return: """ - unstar_dashboard = '/user/stars/dashboard/%s' % dashboard_id + unstar_dashboard = "/user/stars/dashboard/%s" % dashboard_id r = self.api.DELETE(unstar_dashboard) return r diff --git a/grafana_api/grafana_api.py b/grafana_api/grafana_api.py index 2b1fe97..81a9b5c 100644 --- a/grafana_api/grafana_api.py +++ b/grafana_api/grafana_api.py @@ -10,6 +10,7 @@ class GrafanaServerError(Exception): """ 5xx """ + pass @@ -17,6 +18,7 @@ class GrafanaClientError(Exception): """ Invalid input (4xx errors) """ + pass @@ -24,6 +26,7 @@ class GrafanaBadInputError(GrafanaClientError): """ 400 """ + pass @@ -31,6 +34,7 @@ class GrafanaUnauthorizedError(GrafanaClientError): """ 401 """ + pass @@ -39,14 +43,20 @@ def __init__(self, token): self.token = token def __call__(self, request): - request.headers.update({ - "Authorization": "Bearer {0}".format(self.token) - }) + request.headers.update({"Authorization": "Bearer {0}".format(self.token)}) return request class GrafanaAPI: - def __init__(self, auth, host='localhost', port=None, url_path_prefix='', protocol='http', verify=True): + def __init__( + self, + auth, + host="localhost", + port=None, + url_path_prefix="", + protocol="http", + verify=True, + ): self.auth = auth self.verify = verify self.url_host = host @@ -56,16 +66,16 @@ def __init__(self, auth, host='localhost', port=None, url_path_prefix='', protoc def construct_api_url(): params = { - 'protocol': self.url_protocol, - 'host': self.url_host, - 'url_path_prefix': self.url_path_prefix, + "protocol": self.url_protocol, + "host": self.url_host, + "url_path_prefix": self.url_path_prefix, } if self.url_port is None: - url_pattern = '{protocol}://{host}/{url_path_prefix}api' + url_pattern = "{protocol}://{host}/{url_path_prefix}api" else: - params['port'] = self.url_port - url_pattern = '{protocol}://{host}:{port}/{url_path_prefix}api' + params["port"] = self.url_port + url_pattern = "{protocol}://{host}:{port}/{url_path_prefix}api" return url_pattern.format(**params) @@ -79,19 +89,26 @@ def construct_api_url(): def __getattr__(self, item): def __request_runnner(url, json=None, headers=None): - __url = '%s%s' % (self.url, url) + __url = "%s%s" % (self.url, url) runner = getattr(self.s, item.lower()) - r = runner(__url, json=json, headers=headers, auth=self.auth, verify=self.verify) + r = runner( + __url, json=json, headers=headers, auth=self.auth, verify=self.verify + ) if 500 <= r.status_code < 600: - raise GrafanaServerError("Server Error {0}: {1}".format(r.status_code, - r.content.decode("ascii", "replace"))) + raise GrafanaServerError( + "Server Error {0}: {1}".format( + r.status_code, r.content.decode("ascii", "replace") + ) + ) elif r.status_code == 400: raise GrafanaBadInputError("Bad Input: `{0}`".format(r.text)) elif r.status_code == 401: - raise GrafanaUnauthorizedError('Unauthorized') + raise GrafanaUnauthorizedError("Unauthorized") elif 400 <= r.status_code < 500: - raise GrafanaClientError("Client Error {0}: {1}".format(r.status_code, r.text)) + raise GrafanaClientError( + "Client Error {0}: {1}".format(r.status_code, r.text) + ) return r.json() return __request_runnner diff --git a/grafana_api/grafana_face.py b/grafana_api/grafana_face.py index 86df65e..36ce24e 100644 --- a/grafana_api/grafana_face.py +++ b/grafana_api/grafana_face.py @@ -1,10 +1,36 @@ from .grafana_api import GrafanaAPI -from .api import (Admin, Dashboard, Datasource, Folder, Organization, Organizations, Search, User, Users, Teams) +from .api import ( + Admin, + Dashboard, + Datasource, + Folder, + Organization, + Organizations, + Search, + User, + Users, + Teams, +) class GrafanaFace: - def __init__(self, auth, host="localhost", port=None, url_path_prefix="", protocol="http", verify=True): - self.api = GrafanaAPI(auth, host=host, port=port, url_path_prefix=url_path_prefix, protocol=protocol, verify=verify) + def __init__( + self, + auth, + host="localhost", + port=None, + url_path_prefix="", + protocol="http", + verify=True, + ): + self.api = GrafanaAPI( + auth, + host=host, + port=port, + url_path_prefix=url_path_prefix, + protocol=protocol, + verify=verify, + ) self.admin = Admin(self.api) self.dashboard = Dashboard(self.api) self.datasource = Datasource(self.api) diff --git a/setup.py b/setup.py index b66a41d..f3b1999 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ def get_version(): tag = check_output( ["git", "describe", "--tags", "--abbrev=0", "--match=[0-9]*"] ) - return tag.decode('utf-8').strip("\n") + return tag.decode("utf-8").strip("\n") except Exception: raise RuntimeError( "The version number cannot be extracted from git tag in this source " @@ -16,38 +16,35 @@ def get_version(): ) -with open('README.md') as file: +with open("README.md") as file: long_description = file.read() -setup(name='grafana_api', - version=get_version(), - description='Yet another Python library for Grafana API', - long_description=long_description, - long_description_content_type='text/markdown', - url='https://github.com/m0nhawk/grafana_api', - author='Andrew Prokhorenkov', - author_email='andrew.prokhorenkov@gmail.com', - license='MIT', - packages=find_packages(), - install_requires=[ - 'requests', - 'pyyaml', - ], - tests_require=[ - 'requests-mock', - ], - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'Topic :: Internet', - 'Topic :: Software Development :: Libraries', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Operating System :: OS Independent', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - ], - zip_safe=False) +setup( + name="grafana_api", + version=get_version(), + description="Yet another Python library for Grafana API", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/m0nhawk/grafana_api", + author="Andrew Prokhorenkov", + author_email="andrew.prokhorenkov@gmail.com", + license="MIT", + packages=find_packages(), + install_requires=["requests", "pyyaml"], + tests_require=["requests-mock"], + classifiers=[ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Topic :: Internet", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", + "Operating System :: OS Independent", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + ], + zip_safe=False, +) diff --git a/test/api/test_team.py b/test/api/test_team.py index a32fd24..acf61ae 100644 --- a/test/api/test_team.py +++ b/test/api/test_team.py @@ -1,221 +1,227 @@ import unittest + import requests_mock + from grafana_api.grafana_face import GrafanaFace -class TeamsTestCase(unittest.TestCase): +class TeamsTestCase(unittest.TestCase): def setUp(self): - self.cli = GrafanaFace(('admin', 'admin'), host='localhost', - url_path_prefix='', protocol='http') + self.cli = GrafanaFace( + ("admin", "admin"), host="localhost", url_path_prefix="", protocol="http" + ) @requests_mock.Mocker() def test_search_teams_url_encodes_query(self, m): - m.get('http://localhost/api/teams/search?query=my%20team&page=1', json= - {"totalCount": 1, + m.get( + "http://localhost/api/teams/search?query=my%20team&page=1", + json={ + "totalCount": 1, "teams": [ { "id": 1, "orgId": 1, "name": "MyTestTeam", "email": "", - "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", - "memberCount": 1 - } - ], + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1, + } + ], "page": 1, - "perPage": 1000 - }) - teams = self.cli.teams.search_teams('my team') + "perPage": 1000, + }, + ) + teams = self.cli.teams.search_teams("my team") self.assertEqual(teams[0]["name"], "MyTestTeam") self.assertEqual(len(teams), 1) @requests_mock.Mocker() def test_search_teams_loads_all_pages(self, m): - m.get('http://localhost/api/teams/search?query=team&page=1', json= - {"totalCount": 2, + m.get( + "http://localhost/api/teams/search?query=team&page=1", + json={ + "totalCount": 2, "teams": [ { "id": 1, "orgId": 1, "name": "MyTestTeam", "email": "", - "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", - "memberCount": 1 - } - ], + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1, + } + ], "page": 1, - "perPage": 1 - }) - - m.get('http://localhost/api/teams/search?query=team&page=2', json= - {"totalCount": 2, + "perPage": 1, + }, + ) + + m.get( + "http://localhost/api/teams/search?query=team&page=2", + json={ + "totalCount": 2, "teams": [ { "id": 2, "orgId": 1, "name": "SecondTeam", "email": "", - "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", - "memberCount": 23 - } - ], + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 23, + } + ], "page": 2, - "perPage": 1 - }) - teams = self.cli.teams.search_teams('team') + "perPage": 1, + }, + ) + teams = self.cli.teams.search_teams("team") self.assertEqual(teams[0]["name"], "MyTestTeam") self.assertEqual(teams[1]["name"], "SecondTeam") self.assertEqual(len(teams), 2) @requests_mock.Mocker() def test_search_teams_only_loads_requested_page(self, m): - m.get('http://localhost/api/teams/search?query=my%20team&page=2', json= - {"totalCount": 10, + m.get( + "http://localhost/api/teams/search?query=my%20team&page=2", + json={ + "totalCount": 10, "teams": [ { "id": 2, "orgId": 1, "name": "MyTestTeam", "email": "", - "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", - "memberCount": 1 - } - ], + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1, + } + ], "page": 1, - "perPage": 1 - }) - teams = self.cli.teams.search_teams('my team', 2) + "perPage": 1, + }, + ) + teams = self.cli.teams.search_teams("my team", 2) self.assertEqual(teams[0]["name"], "MyTestTeam") self.assertEqual(len(teams), 1) @requests_mock.Mocker() def test_get_team_by_name(self, m): - m.get('http://localhost/api/teams/search?name=my%20team', json= - {"totalCount": 1, + m.get( + "http://localhost/api/teams/search?name=my%20team", + json={ + "totalCount": 1, "teams": [ { "id": 2, "orgId": 1, "name": "my team", "email": "", - "avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398", - "memberCount": 1 - } - ], + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1, + } + ], "page": 1, - "perPage": 1000 - }) - teams = self.cli.teams.get_team_by_name('my team') + "perPage": 1000, + }, + ) + teams = self.cli.teams.get_team_by_name("my team") self.assertEqual(teams[0]["name"], "my team") self.assertEqual(len(teams), 1) @requests_mock.Mocker() def test_get_team(self, m): - m.get('http://localhost/api/teams/1', json= - {"id": 1, - "orgId": 1, - "name": "MyTestTeam", - "email": "", - "created": "2017-12-15T10:40:45+01:00", - "updated": "2017-12-15T10:40:45+01:00" - }) - team = self.cli.teams.get_team('1') + m.get( + "http://localhost/api/teams/1", + json={ + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "created": "2017-12-15T10:40:45+01:00", + "updated": "2017-12-15T10:40:45+01:00", + }, + ) + team = self.cli.teams.get_team("1") self.assertEqual(team["name"], "MyTestTeam") @requests_mock.Mocker() def test_add_team(self, m): - m.post('http://localhost/api/teams', json= - { - "message":"Team created","teamId":2 - }) - team = { - "name": "MySecondTestTeam", - "email": "email@test.com" - } + m.post( + "http://localhost/api/teams", json={"message": "Team created", "teamId": 2} + ) + team = {"name": "MySecondTestTeam", "email": "email@test.com"} new_team = self.cli.teams.add_team(team) self.assertEqual(new_team["teamId"], 2) @requests_mock.Mocker() def test_update_team(self, m): - m.put('http://localhost/api/teams/3', json= - { - "message":"Team updated" - }) - team = { - "name": "MyThirdTestTeam", - "email": "email@test.com" - } + m.put("http://localhost/api/teams/3", json={"message": "Team updated"}) + team = {"name": "MyThirdTestTeam", "email": "email@test.com"} response = self.cli.teams.update_team(3, team) self.assertEqual(response["message"], "Team updated") @requests_mock.Mocker() def test_delete_team(self, m): - m.delete('http://localhost/api/teams/3', json= - { - "message":"Team deleted" - }) + m.delete("http://localhost/api/teams/3", json={"message": "Team deleted"}) response = self.cli.teams.delete_team(3) self.assertEqual(response, True) @requests_mock.Mocker() def test_get_team_members(self, m): - m.get('http://localhost/api/teams/1/members', json= - [{ - "orgId": 1, - "teamId": 1, - "userId": 3, - "email": "user1@email.com", - "login": "user1", - "avatarUrl": "\/avatar\/1b3c32f6386b0185c40d359cdc733a79" - }]) - members = self.cli.teams.get_team_members('1') + m.get( + "http://localhost/api/teams/1/members", + json=[ + { + "orgId": 1, + "teamId": 1, + "userId": 3, + "email": "user1@email.com", + "login": "user1", + "avatarUrl": "/avatar/1b3c32f6386b0185c40d359cdc733a79", + } + ], + ) + members = self.cli.teams.get_team_members("1") self.assertEqual(members[0]["login"], "user1") @requests_mock.Mocker() def test_add_team_member(self, m): - m.post('http://localhost/api/teams/1/members', json= - { - "message":"Member added to Team" - }) + m.post( + "http://localhost/api/teams/1/members", + json={"message": "Member added to Team"}, + ) history = m.request_history - add_res = self.cli.teams.add_team_member('1', '3') - self.assertEqual(history[0].json()["userId"], '3') + add_res = self.cli.teams.add_team_member("1", "3") + self.assertEqual(history[0].json()["userId"], "3") self.assertEqual(add_res["message"], "Member added to Team") @requests_mock.Mocker() def test_remove_team_member(self, m): - m.delete('http://localhost/api/teams/13/members/2', json= - { - "message":"Team member removed" - }) - remove_res = self.cli.teams.remove_team_member('13', '2') + m.delete( + "http://localhost/api/teams/13/members/2", + json={"message": "Team member removed"}, + ) + remove_res = self.cli.teams.remove_team_member("13", "2") self.assertEqual(remove_res["message"], "Team member removed") @requests_mock.Mocker() def test_get_team_preferences(self, m): - m.get('http://localhost/api/teams/1/preferences', json= - { - "theme": "", - "homeDashboardId": 0, - "timezone": "" - }) - prefs = self.cli.teams.get_team_preferences('1') + m.get( + "http://localhost/api/teams/1/preferences", + json={"theme": "", "homeDashboardId": 0, "timezone": ""}, + ) + prefs = self.cli.teams.get_team_preferences("1") self.assertEqual(prefs["homeDashboardId"], 0) @requests_mock.Mocker() def test_update_team_preferences(self, m): - m.put('http://localhost/api/teams/1/preferences', json= - { - "message":"Preferences updated" - }) - prefs = { - "theme": "light", - "homeDashboardId": 0, - "timezone": "" - } - - updates = self.cli.teams.update_team_preferences('1', prefs) + m.put( + "http://localhost/api/teams/1/preferences", + json={"message": "Preferences updated"}, + ) + prefs = {"theme": "light", "homeDashboardId": 0, "timezone": ""} + + updates = self.cli.teams.update_team_preferences("1", prefs) history = m.request_history json_payload = history[0].json() - self.assertEqual(json_payload["theme"], 'light') - self.assertEqual(updates["message"], 'Preferences updated') + self.assertEqual(json_payload["theme"], "light") + self.assertEqual(updates["message"], "Preferences updated") diff --git a/test/test_grafana.py b/test/test_grafana.py index da3f77a..86c6089 100644 --- a/test/test_grafana.py +++ b/test/test_grafana.py @@ -1,7 +1,7 @@ import unittest import sys -if (sys.version_info > (3, 0)): +if sys.version_info > (3, 0): from unittest.mock import patch, Mock else: from mock import patch, Mock @@ -22,7 +22,7 @@ def json(self): class TestGrafanaAPI(unittest.TestCase): - @patch('grafana_api.grafana_api.GrafanaAPI.__getattr__') + @patch("grafana_api.grafana_api.GrafanaAPI.__getattr__") def test_grafana_api(self, mock_get): mock_get.return_value = Mock() mock_get.return_value.return_value = """{ @@ -33,37 +33,59 @@ def test_grafana_api(self, mock_get): "orgId": 1, "isGrafanaAdmin": true }""" - cli = GrafanaFace(('admin', 'admin'), host='localhost', - url_path_prefix='', protocol='https') - cli.users.find_user('test@test.com') + cli = GrafanaFace( + ("admin", "admin"), host="localhost", url_path_prefix="", protocol="https" + ) + cli.users.find_user("test@test.com") def test_grafana_api_no_verify(self): - cli = GrafanaFace(('admin', 'admin'), host='localhost', - url_path_prefix='', protocol='https', verify=False) - cli.api.s.get = Mock(name='get') - cli.api.s.get.return_value = MockResponse({ - "email": "user@mygraf.com", - "name": "admin", - "login": "admin", - "theme": "light", - "orgId": 1, - "isGrafanaAdmin": True}, 200) + cli = GrafanaFace( + ("admin", "admin"), + host="localhost", + url_path_prefix="", + protocol="https", + verify=False, + ) + cli.api.s.get = Mock(name="get") + cli.api.s.get.return_value = MockResponse( + { + "email": "user@mygraf.com", + "name": "admin", + "login": "admin", + "theme": "light", + "orgId": 1, + "isGrafanaAdmin": True, + }, + 200, + ) - basicAuth = requests.auth.HTTPBasicAuth('admin', 'admin') - cli.users.find_user('test@test.com') - cli.api.s.get.assert_called_once_with('https://localhost/api/users/lookup?loginOrEmail=test@test.com', auth=basicAuth, headers=None, json=None, verify=False) + basic_auth = requests.auth.HTTPBasicAuth("admin", "admin") + cli.users.find_user("test@test.com") + cli.api.s.get.assert_called_once_with( + "https://localhost/api/users/lookup?loginOrEmail=test@test.com", + auth=basic_auth, + headers=None, + json=None, + verify=False, + ) def test_grafana_api_basic_auth(self): - cli = GrafanaFace(('admin', 'admin'), host='localhost', - url_path_prefix='', protocol='https') + cli = GrafanaFace( + ("admin", "admin"), host="localhost", url_path_prefix="", protocol="https" + ) self.assertTrue(isinstance(cli.api.auth, requests.auth.HTTPBasicAuth)) def test_grafana_api_token_auth(self): - cli = GrafanaFace('alongtoken012345etc', host='localhost', - url_path_prefix='', protocol='https') + cli = GrafanaFace( + "alongtoken012345etc", + host="localhost", + url_path_prefix="", + protocol="https", + ) self.assertTrue(isinstance(cli.api.auth, TokenAuth)) -if __name__ == '__main__': +if __name__ == "__main__": import xmlrunner - unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports')) + + unittest.main(testRunner=xmlrunner.XMLTestRunner(output="test-reports"))