diff --git a/.gitignore b/.gitignore index 9cfd57f..6b6bfb3 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ htmlcov/ nosetests.xml coverage.xml *,cover +.pytest_cache # Translations *.mo diff --git a/.travis.yml b/.travis.yml index 8a302c7..54ecab6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,12 @@ language: python python: - "2.7" -install: - - pip install tox -script: - - tox + - "3.4" + - "3.5" + - "3.6" + - "3.7-dev" +install: pip install tox-travis +script: tox branches: only: - master diff --git a/NOTICE b/NOTICE index 11ed125..38946ba 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,4 @@ grafana-dashboard-builder -Copyright 2015-2018 grafana-dashboard-builder contributors +Copyright 2015-2019 grafana-dashboard-builder contributors This product includes grafana-dashboard-builder. diff --git a/bin/grafana_dashboard_builder.py b/bin/grafana_dashboard_builder.py index 051f67c..70475f3 100755 --- a/bin/grafana_dashboard_builder.py +++ b/bin/grafana_dashboard_builder.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +13,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards import cli __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/__init__.py b/grafana_dashboards/__init__.py index 926af32..d8ceeca 100644 --- a/grafana_dashboards/__init__.py +++ b/grafana_dashboards/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,5 +12,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +from __future__ import unicode_literals __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/cli.py b/grafana_dashboards/cli.py index 0ce39f6..2cf7a80 100755 --- a/grafana_dashboards/cli.py +++ b/grafana_dashboards/cli.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +13,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function +from __future__ import unicode_literals import argparse import imp @@ -21,11 +23,11 @@ import yaml -from grafana_dashboards.client.grafana import GrafanaExporter -from grafana_dashboards.exporter import ProjectProcessor, FileExporter from grafana_dashboards.client.elastic_search import ElasticSearchExporter +from grafana_dashboards.client.grafana import GrafanaExporter from grafana_dashboards.common import get_component_type from grafana_dashboards.config import Config +from grafana_dashboards.exporter import ProjectProcessor, FileExporter from grafana_dashboards.parser import DefinitionParser __author__ = 'Jakub Plichta ' @@ -33,8 +35,8 @@ def _initialize_exporters(exporter_names, exporter_types, config): exporters = dict([(get_component_type(exporter), exporter) for exporter in exporter_types]) - exporters = dict([(name[:-9], exporter) for name, exporter in exporters.iteritems() if name[:-9] in exporter_names]) - return [exporter(**config.get_config(name)) for (name, exporter) in exporters.iteritems()] + exporters = dict([(name[:-9], exporter) for name, exporter in exporters.items() if name[:-9] in exporter_names]) + return [exporter(**config.get_config(name)) for (name, exporter) in exporters.items()] def _process_paths(paths): @@ -75,7 +77,7 @@ def main(): try: imp.load_source('grafana_dashboards.components.$loaded', plugin) except Exception as e: - print 'Cannot load plugin %s: %s' % (plugin, str(e)) + print('Cannot load plugin %s: %s' % (plugin, str(e))) if args.project: logging.warn("Using deprecated option '--project'") diff --git a/grafana_dashboards/client/__init__.py b/grafana_dashboards/client/__init__.py index 926af32..d8ceeca 100644 --- a/grafana_dashboards/client/__init__.py +++ b/grafana_dashboards/client/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,5 +12,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +from __future__ import unicode_literals __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/client/connection.py b/grafana_dashboards/client/connection.py index cab4290..1f595a8 100644 --- a/grafana_dashboards/client/connection.py +++ b/grafana_dashboards/client/connection.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,12 +12,26 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import base64 -import cookielib import json import logging -import urllib2 -from urlparse import urlparse + +try: + from cookielib import CookieJar +except ImportError: + from http.cookiejar import CookieJar +try: + from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPCookieProcessor, HTTPDefaultErrorHandler, \ + Request, BaseHandler +except ImportError: + from urllib.request import build_opener, HTTPHandler, HTTPSHandler, HTTPCookieProcessor, HTTPDefaultErrorHandler, \ + Request, BaseHandler +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse import requests from requests_kerberos import HTTPKerberosAuth @@ -37,24 +51,24 @@ def __init__(self, username, password, host, debug=0): logger.debug('Creating new connection with username=%s host=%s', username, host) self._host = host - base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') - self._headers['Authorization'] = 'Basic %s' % base64string + base64string = base64.encodestring(('%s:%s' % (username, password)).encode('utf-8')).replace(b'\n', b'') + self._headers['Authorization'] = b'Basic ' + base64string - self._opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=debug), - urllib2.HTTPSHandler(debuglevel=debug), - urllib2.HTTPCookieProcessor(cookielib.CookieJar()), - LoggingHandler(), - urllib2.HTTPDefaultErrorHandler()) + self._opener = build_opener(HTTPHandler(debuglevel=debug), + HTTPSHandler(debuglevel=debug), + HTTPCookieProcessor(CookieJar()), + LoggingHandler(), + HTTPDefaultErrorHandler()) def make_request(self, uri, body=None): - request = urllib2.Request('{0}{1}'.format(self._host, uri), - json.dumps(body) if body else None, - headers=self._headers) + request = Request('{0}{1}'.format(self._host, uri), + json.dumps(body) if body else None, + headers=self._headers) response_body = self._opener.open(request).read() return {} if (response_body is None or response_body == '') else json.loads(response_body) -class LoggingHandler(urllib2.BaseHandler): +class LoggingHandler(BaseHandler): def __init__(self): pass diff --git a/grafana_dashboards/client/elastic_search.py b/grafana_dashboards/client/elastic_search.py index eb2cabb..ffb4c58 100644 --- a/grafana_dashboards/client/elastic_search.py +++ b/grafana_dashboards/client/elastic_search.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,12 +12,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import json import logging import os -from grafana_dashboards.exporter import DashboardExporter from grafana_dashboards.client.connection import Connection, KerberosConnection +from grafana_dashboards.exporter import DashboardExporter __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/client/grafana.py b/grafana_dashboards/client/grafana.py index e3728d1..952ca7c 100644 --- a/grafana_dashboards/client/grafana.py +++ b/grafana_dashboards/client/grafana.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import logging import os diff --git a/grafana_dashboards/common.py b/grafana_dashboards/common.py index a6e6aa2..741c366 100644 --- a/grafana_dashboards/common.py +++ b/grafana_dashboards/common.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import re __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/components/__init__.py b/grafana_dashboards/components/__init__.py index c867e6e..de974dd 100644 --- a/grafana_dashboards/components/__init__.py +++ b/grafana_dashboards/components/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,12 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import base -import dashboards -import panels -import projects -import rows -import templates +from grafana_dashboards.components import base +from grafana_dashboards.components import dashboards +from grafana_dashboards.components import panels +from grafana_dashboards.components import projects +from grafana_dashboards.components import rows +from grafana_dashboards.components import templates __author__ = 'Jakub Plichta ' __all__ = [ diff --git a/grafana_dashboards/components/annotations.py b/grafana_dashboards/components/annotations.py index a8c6970..14bddc3 100644 --- a/grafana_dashboards/components/annotations.py +++ b/grafana_dashboards/components/annotations.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/components/axes.py b/grafana_dashboards/components/axes.py index 284c7f4..d87523b 100644 --- a/grafana_dashboards/components/axes.py +++ b/grafana_dashboards/components/axes.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/components/base.py b/grafana_dashboards/components/base.py index e0767b9..a7ccb68 100644 --- a/grafana_dashboards/components/base.py +++ b/grafana_dashboards/components/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import logging import string @@ -19,6 +21,11 @@ from grafana_dashboards.common import get_component_type from grafana_dashboards.context import Context +try: + basestring +except NameError: + basestring = str + __author__ = 'Jakub Plichta ' @@ -55,7 +62,7 @@ def __init__(self): self._components[clazz] = {} def _class_for_type(self, component_type): - if isinstance(component_type, str): + if isinstance(component_type, basestring): component_type = self._types.get(component_type) if self._components.get(component_type) is None: raise errors.UnregisteredComponentError("No component of type '%s' found!" % component_type) @@ -159,7 +166,7 @@ def gen_json_from_data(self, data, context): return result_list def gen_item_json(self, items, result_list): - if isinstance(items, str): + if isinstance(items, basestring): # this is component without context result_list += self.registry.get_component(type(self), items).gen_json() else: @@ -167,7 +174,7 @@ def gen_item_json(self, items, result_list): def _gen_item_json_with_context(self, items, result_list): # TODO add check for dictionary - for (item_type, item_data) in items.iteritems(): + for (item_type, item_data) in items.items(): if item_type not in self.component_item_types: # this is named component with context for context in Context.create_context(item_data, get_placeholders(item_type)): diff --git a/grafana_dashboards/components/dashboards.py b/grafana_dashboards/components/dashboards.py index d6a03b4..d6d5e9d 100644 --- a/grafana_dashboards/components/dashboards.py +++ b/grafana_dashboards/components/dashboards.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,9 +12,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + +from grafana_dashboards.common import get_component_type from grafana_dashboards.components.annotations import Annotations from grafana_dashboards.components.base import JsonGenerator -from grafana_dashboards.common import get_component_type from grafana_dashboards.components.rows import Rows from grafana_dashboards.components.templates import Templates diff --git a/grafana_dashboards/components/links.py b/grafana_dashboards/components/links.py index 7738eb8..c6dd217 100644 --- a/grafana_dashboards/components/links.py +++ b/grafana_dashboards/components/links.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,8 +12,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator +try: + basestring +except NameError: + basestring = str + __author__ = 'Jakub Plichta ' @@ -38,10 +45,10 @@ def gen_json_from_data(self, data, context): if 'params' in data and isinstance(data.get('params'), list): params = [] for param in data.get('params'): - if isinstance(param, str): + if isinstance(param, basestring): params.append((param, '$' + param)) else: - for key, value in param.iteritems(): + for key, value in param.items(): params.append((key, value)) link_json['params'] = '&'.join(map(lambda pair: 'var-%s=%s' % (pair[0], pair[1]), params)) return link_json diff --git a/grafana_dashboards/components/panels.py b/grafana_dashboards/components/panels.py index a9d8ea5..c6f7769 100644 --- a/grafana_dashboards/components/panels.py +++ b/grafana_dashboards/components/panels.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.common import get_component_type from grafana_dashboards.components.axes import Yaxes from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator @@ -80,7 +82,7 @@ def gen_json_from_data(self, data, context): if 'seriesOverrides' in self.data: overrides = [] for override in self.data['seriesOverrides']: - for alias, settings in override.iteritems(): + for alias, settings in override.items(): to_add = {'alias': alias} to_add.update(settings) overrides.append(to_add) @@ -139,7 +141,7 @@ def gen_json_from_data(self, data, context): ] if 'valueMaps' in data: panel_json['valueMaps'] = [{'value': value, 'op': '=', 'text': text} for value, text in - data['valueMaps'].iteritems()] + data['valueMaps'].items()] if get_component_type(Links) in data: panel_json['links'] = self.registry.create_component(Links, data).gen_json() return panel_json @@ -155,16 +157,16 @@ def gen_json_from_data(self, data, context): 'type': 'table', 'title': data.get('title', None), 'span': data.get('span', None), - 'targets': map(lambda v: {'target': v}, data.get('targets', [])), + 'targets': [{'target': v} for v in data.get('targets', [])], 'transform': data.get('transform', None), - 'columns': map(lambda v: {'text': v, 'value': str(v).lower()}, data.get('columns', [])) + 'columns': [{'text': v, 'value': str(v).lower()} for v in data.get('columns', [])] }) panel_json['targets'] = self.registry.create_component(Targets, data).gen_json() if 'targets' in data else [] if 'styles' in self.data: styles = [] for override in self.data['styles']: - for pattern, settings in override.iteritems(): + for pattern, settings in override.items(): to_add = {'pattern': pattern} to_add.update(settings) styles.append(to_add) diff --git a/grafana_dashboards/components/projects.py b/grafana_dashboards/components/projects.py index 9b90252..33d1aff 100644 --- a/grafana_dashboards/components/projects.py +++ b/grafana_dashboards/components/projects.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.components.base import ComponentBase, get_placeholders from grafana_dashboards.components.dashboards import Dashboard from grafana_dashboards.context import Context diff --git a/grafana_dashboards/components/rows.py b/grafana_dashboards/components/rows.py index a7a8983..a787583 100644 --- a/grafana_dashboards/components/rows.py +++ b/grafana_dashboards/components/rows.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,8 +12,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator +from __future__ import unicode_literals + from grafana_dashboards.common import get_component_type +from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator from grafana_dashboards.components.panels import Panels __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/components/targets.py b/grafana_dashboards/components/targets.py index c1ecc8c..1509419 100644 --- a/grafana_dashboards/components/targets.py +++ b/grafana_dashboards/components/targets.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,10 +12,17 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.common import get_component_type from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator from grafana_dashboards.errors import UnregisteredComponentError +try: + basestring +except NameError: + basestring = str + __author__ = 'Jakub Plichta ' @@ -40,7 +47,7 @@ class GraphiteTarget(TargetsItemBase): def gen_json_from_data(self, data, context): template_json = super(GraphiteTarget, self).gen_json_from_data(data, context) - if isinstance(data, str): + if isinstance(data, basestring): template_json['target'] = data else: template_json['target'] = data['target'] diff --git a/grafana_dashboards/components/templates.py b/grafana_dashboards/components/templates.py index b51e640..acf13fe 100644 --- a/grafana_dashboards/components/templates.py +++ b/grafana_dashboards/components/templates.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + from grafana_dashboards.components.base import JsonListGenerator, JsonGenerator __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/config.py b/grafana_dashboards/config.py index 93f8f34..9be7717 100644 --- a/grafana_dashboards/config.py +++ b/grafana_dashboards/config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import logging import os @@ -31,7 +33,7 @@ def __init__(self, config=None): logger.debug("Config file '%s' does not exist", config) self._config = {} else: - with file(config) as fp: + with open(config) as fp: self._config = yaml.load(fp) def get_config(self, section): diff --git a/grafana_dashboards/context.py b/grafana_dashboards/context.py index e591b94..f552d77 100644 --- a/grafana_dashboards/context.py +++ b/grafana_dashboards/context.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,16 +12,23 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import itertools import re import string +try: + basestring +except NameError: + basestring = str + __author__ = 'Jakub Plichta ' class Context(object): - _pattern = re.compile('\{.*\}') + _pattern = re.compile('{.*}') def __init__(self, context=None): super(Context, self).__init__() @@ -38,23 +45,23 @@ def expand_placeholders(self, to_expand): if not self._context: return to_expand - if isinstance(to_expand, str): + if isinstance(to_expand, basestring): (result, to_expand) = self._expand(to_expand) while result != to_expand: (result, to_expand) = self._expand(result) - if isinstance(result, str): + if isinstance(result, basestring): return string.Formatter().vformat(result, (), self._context) else: return result elif isinstance(to_expand, list): return [self.expand_placeholders(value) for value in to_expand] elif isinstance(to_expand, dict): - return dict([(key, self.expand_placeholders(value)) for (key, value) in to_expand.iteritems()]) + return dict([(key, self.expand_placeholders(value)) for (key, value) in to_expand.items()]) else: return to_expand def _expand(self, to_expand): - if not isinstance(to_expand, str): + if not isinstance(to_expand, basestring): return to_expand, to_expand elif self._pattern.match(to_expand) and to_expand[1:-1] in self._context: return self._context[to_expand[1:-1]], to_expand @@ -88,7 +95,7 @@ def create_context(self, key, value, parent=None): else: contexts.append(itertools.repeat({key: value}, 1)) elif isinstance(value, dict): - for (sub_key, sub_value) in value.iteritems(): + for (sub_key, sub_value) in value.items(): if parent and len(value) == 1: contexts.append(self.create_context(parent, sub_key)) contexts.append(self.create_context(sub_key, sub_value)) diff --git a/grafana_dashboards/errors.py b/grafana_dashboards/errors.py index 489d033..ffb1a14 100644 --- a/grafana_dashboards/errors.py +++ b/grafana_dashboards/errors.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +from __future__ import unicode_literals __author__ = 'Jakub Plichta ' diff --git a/grafana_dashboards/exporter.py b/grafana_dashboards/exporter.py index 0f5304c..b95968b 100644 --- a/grafana_dashboards/exporter.py +++ b/grafana_dashboards/exporter.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals +import errno import json import logging import os -import errno __author__ = 'Jakub Plichta ' @@ -77,5 +78,5 @@ def process_dashboard(self, project_name, dashboard_name, dashboard_data): dashboard_path = os.path.join(dirname, dashboard_name + '.json') logger.info("Saving dashboard '%s' to '%s'", dashboard_name, os.path.abspath(dashboard_path)) - with file(dashboard_path, 'w') as f: + with open(dashboard_path, 'w') as f: json.dump(dashboard_data, f, sort_keys=True, indent=2, separators=(',', ': ')) diff --git a/grafana_dashboards/parser.py b/grafana_dashboards/parser.py index 3fc959c..8ac36f3 100644 --- a/grafana_dashboards/parser.py +++ b/grafana_dashboards/parser.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals import yaml @@ -28,7 +29,7 @@ def __init__(self): def load_projects(self, paths): registry = ComponentRegistry() for path in paths: - with file(path, 'r') as fp: + with open(path, 'r') as fp: for component in self._iter_over_all(yaml.load_all(fp)): registry.add(component) return registry[Project] diff --git a/setup.py b/setup.py index a5a7c9b..a353460 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,6 +13,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import sys from setuptools import setup @@ -47,7 +49,7 @@ def run_tests(self): params = { 'name': 'grafana-dashboard-builder', - 'version': '0.4.0a3', + 'version': '0.5.0a1', 'packages': [ 'grafana_dashboards', 'grafana_dashboards.client', @@ -72,6 +74,11 @@ def run_tests(self): 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], 'keywords': 'grafana yaml graphite prometheus influxdb', 'cmdclass': {'test': Tox}, diff --git a/tests/grafana_dashboards/client/test_connection.py b/tests/grafana_dashboards/client/test_connection.py index 9bec2d7..6057f80 100644 --- a/tests/grafana_dashboards/client/test_connection.py +++ b/tests/grafana_dashboards/client/test_connection.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,8 +12,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import urllib2 - +from __future__ import unicode_literals +try: + from urllib2 import Request +except ImportError: + from urllib.request import Request from mock import MagicMock, patch from requests_kerberos import HTTPKerberosAuth @@ -26,6 +29,7 @@ class Capture(object): """ Class for use in method call verification that captures call argument that can be tested later on. """ + def __eq__(self, other): """ Captures argument and always returns true to make verification successful. @@ -43,20 +47,20 @@ def test_connection(): assert connection.make_request('/uri', {'it\'s': 'alive'}) == {'hello': 'world'} - request = urllib2.Request('https://host/uri', - '{"it\'s": "alive"}', - headers={ - 'Content-type': 'application/json', - 'Accept': 'application/json', - 'Authorization': 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=' - }) + request = Request('https://host/uri', + '{"it\'s": "alive"}', + headers={ + 'Content-type': 'application/json', + 'Accept': 'application/json', + 'Authorization': b'Basic dXNlcm5hbWU6cGFzc3dvcmQ=' + }) capture = Capture() # noinspection PyProtectedMember connection._opener.open.assert_called_with(capture) assert request.get_full_url() == capture.value.get_full_url() assert request.header_items() == capture.value.header_items() assert request.get_method() == capture.value.get_method() - assert request.get_data() == capture.value.get_data() + assert request.data == capture.value.data @patch('requests.post') diff --git a/tests/grafana_dashboards/client/test_elastic_search.py b/tests/grafana_dashboards/client/test_elastic_search.py index ff25ced..6e5316d 100644 --- a/tests/grafana_dashboards/client/test_elastic_search.py +++ b/tests/grafana_dashboards/client/test_elastic_search.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import json from mock import MagicMock diff --git a/tests/grafana_dashboards/client/test_grafana.py b/tests/grafana_dashboards/client/test_grafana.py index 032b019..1506cdb 100644 --- a/tests/grafana_dashboards/client/test_grafana.py +++ b/tests/grafana_dashboards/client/test_grafana.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals from mock import MagicMock diff --git a/tests/grafana_dashboards/components/test_base.py b/tests/grafana_dashboards/components/test_base.py index eccc301..9062cd4 100644 --- a/tests/grafana_dashboards/components/test_base.py +++ b/tests/grafana_dashboards/components/test_base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals import pytest -from grafana_dashboards.components.base import ComponentRegistry, ComponentBase from grafana_dashboards import errors +from grafana_dashboards.components.base import ComponentRegistry, ComponentBase __author__ = 'Jakub Plichta ' diff --git a/tests/grafana_dashboards/components/test_components.py b/tests/grafana_dashboards/components/test_components.py index bc36c15..29ce08a 100644 --- a/tests/grafana_dashboards/components/test_components.py +++ b/tests/grafana_dashboards/components/test_components.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import inspect import json import os @@ -46,9 +48,9 @@ def load_test_fixtures(): if not f.endswith('.yaml'): continue filename = f[:-5] - with file(os.path.join(dirname, '%s.yaml' % filename), 'r') as fp: + with open(os.path.join(dirname, '%s.yaml' % filename), 'r') as fp: config = yaml.load(fp) - with file(os.path.join(dirname, '%s.json' % filename), 'r') as fp: + with open(os.path.join(dirname, '%s.json' % filename), 'r') as fp: output = json.load(fp) yield component, filename, config, output diff --git a/tests/grafana_dashboards/components/test_projects.py b/tests/grafana_dashboards/components/test_projects.py index c275e9b..a8ba4cc 100644 --- a/tests/grafana_dashboards/components/test_projects.py +++ b/tests/grafana_dashboards/components/test_projects.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import mock from grafana_dashboards.components.projects import Project diff --git a/tests/grafana_dashboards/test_cli.py b/tests/grafana_dashboards/test_cli.py index 1e340fa..d640d15 100644 --- a/tests/grafana_dashboards/test_cli.py +++ b/tests/grafana_dashboards/test_cli.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import os from mock import patch diff --git a/tests/grafana_dashboards/test_config.py b/tests/grafana_dashboards/test_config.py index 7cd937f..a24ac5a 100644 --- a/tests/grafana_dashboards/test_config.py +++ b/tests/grafana_dashboards/test_config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals + import os from grafana_dashboards.config import Config diff --git a/tests/grafana_dashboards/test_context.py b/tests/grafana_dashboards/test_context.py index 82c71f8..e072f8a 100644 --- a/tests/grafana_dashboards/test_context.py +++ b/tests/grafana_dashboards/test_context.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals from grafana_dashboards.context import DictDefaultingToPlaceholder, Context diff --git a/tests/grafana_dashboards/test_exporter.py b/tests/grafana_dashboards/test_exporter.py index 38bbe0f..0a0f621 100644 --- a/tests/grafana_dashboards/test_exporter.py +++ b/tests/grafana_dashboards/test_exporter.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 grafana-dashboard-builder contributors +# Copyright 2015-2019 grafana-dashboard-builder contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,9 +12,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import unicode_literals -from mock import patch, MagicMock import pytest +from mock import patch, MagicMock from grafana_dashboards.exporter import ProjectProcessor, FileExporter @@ -41,7 +42,7 @@ def test_project_processor(): dashboard.gen_json()) -@patch('grafana_dashboards.exporter.file', create=True) +@patch('grafana_dashboards.exporter.open', create=True) @patch('json.dump') @patch('os.makedirs', return_value=True) @patch('os.path.isdir', return_value=True) diff --git a/tox.ini b/tox.ini index de68da6..949a3c4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] -envlist = pep8, py27 +envlist = pep8-py{27,36}, py{27,34,35,36,37} [testenv] passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH +skip_missing_interpreters = true deps = pytest mock @@ -12,7 +13,13 @@ commands= py.test --cov={envsitepackagesdir}/grafana_dashboards coveralls -[testenv:pep8] +[testenv:pep8-py27] +skip_missing_interpreters = true +deps = flake8 +commands = flake8 + +[testenv:pep8-py36] +skip_missing_interpreters = true deps = flake8 commands = flake8