diff --git a/.landscape.yml b/.landscape.yml index 72de64fbf2..139b3db6c2 100644 --- a/.landscape.yml +++ b/.landscape.yml @@ -8,8 +8,11 @@ autodetect: yes pylint: disable: - cyclic-import + - invalid-name options: docstring-min-length: 10 +pep8: + full: true ignore-paths: - docs - panoramix/migrations/env.py diff --git a/panoramix/__init__.py b/panoramix/__init__.py index ff9baaa61f..7e2533ca4a 100644 --- a/panoramix/__init__.py +++ b/panoramix/__init__.py @@ -1,3 +1,5 @@ +"""Package's main module!""" + import logging import os from flask import Flask, redirect diff --git a/panoramix/data/__init__.py b/panoramix/data/__init__.py index 9ba1c87556..8cd6798f34 100644 --- a/panoramix/data/__init__.py +++ b/panoramix/data/__init__.py @@ -1,3 +1,5 @@ +"""Loads datasets, dashboards and slices in a new panoramix instance""" + import gzip import json import os @@ -46,6 +48,7 @@ def get_slice_json(defaults, **kwargs): def load_world_bank_health_n_pop(): + """Loads the world bank health dataset, slices and a dashboard""" tbl_name = 'wb_health_population' with gzip.open(os.path.join(DATA_FOLDER, 'countries.json.gz')) as f: pdf = pd.read_json(f) @@ -282,6 +285,7 @@ def load_world_bank_health_n_pop(): def load_css_templates(): + """Loads 2 css templates to demonstrate the feature""" print('Creating default CSS templates') CSS = models.CssTemplate diff --git a/panoramix/forms.py b/panoramix/forms.py index e58c63ee2c..215ba5f074 100644 --- a/panoramix/forms.py +++ b/panoramix/forms.py @@ -493,6 +493,7 @@ class FormFactory(object): return [("{}".format(obj), "{}".format(obj)) for obj in l] def get_form(self): + """Returns a form object based on the viz/datasource/context""" viz = self.viz field_css_classes = {} for name, obj in self.field_dict.items(): diff --git a/panoramix/models.py b/panoramix/models.py index 7cf78042f2..d64082e1bd 100644 --- a/panoramix/models.py +++ b/panoramix/models.py @@ -1,3 +1,7 @@ +""" +A collection of ORM sqlalchemy models for Panoramix +""" + from copy import deepcopy, copy from collections import namedtuple from datetime import timedelta, datetime @@ -37,8 +41,10 @@ QueryResult = namedtuple('namedtuple', ['df', 'query', 'duration']) class AuditMixinNullable(AuditMixin): - """Altering the AuditMixin to use nullable fields, allows creating - objects programmatically outside of CRUD""" + """Altering the AuditMixin to use nullable fields + + Allows creating objects programmatically outside of CRUD + """ created_on = Column(DateTime, default=datetime.now, nullable=True) changed_on = Column( @@ -223,6 +229,7 @@ class Dashboard(Model, AuditMixinNullable): class Queryable(object): + """A common interface to objects that are queryable (tables and datasources)""" @property def column_names(self): return sorted([c.column_name for c in self.columns]) @@ -837,8 +844,7 @@ class DruidDatasource(Model, AuditMixinNullable, Queryable): @classmethod def sync_to_db(cls, name, cluster): - """Fetches the metadata for that datasource and merges it into - the Panoramix database""" + """Fetches metadata for that datasource and merges the Panoramix db""" print("Syncing Druid datasource [{}]".format(name)) session = get_session() datasource = session.query(cls).filter_by(datasource_name=name).first() @@ -884,7 +890,9 @@ class DruidDatasource(Model, AuditMixinNullable, Queryable): extras=None, # noqa select=None): """Runs a query against Druid and returns a dataframe. - This query interface is common to SqlAlchemy and Druid""" + + This query interface is common to SqlAlchemy and Druid + """ # TODO refactor into using a TBD Query object qry_start_dttm = datetime.now() diff --git a/panoramix/views.py b/panoramix/views.py index 97c2739bfe..6e62d7fca5 100644 --- a/panoramix/views.py +++ b/panoramix/views.py @@ -365,6 +365,7 @@ appbuilder.add_view_no_menu(R) class Panoramix(BaseView): + """The base views for Panoramix!""" @has_access diff --git a/panoramix/viz.py b/panoramix/viz.py index 1973aefca7..707abd18e2 100644 --- a/panoramix/viz.py +++ b/panoramix/viz.py @@ -1,3 +1,8 @@ +""" +This module contains the "Viz" objects that represent the backend of all +the visualizations that Panoramix can render +""" + from collections import OrderedDict, defaultdict from datetime import datetime, timedelta import json @@ -19,6 +24,9 @@ config = app.config class BaseViz(object): + + """All visualizations derive this base class""" + viz_type = None verbose_name = "Base Viz" is_timeseries = False @@ -110,12 +118,14 @@ class BaseViz(object): return href(d) def get_df(self, query_obj=None): + """Returns a pandas dataframe based on the query object""" if not query_obj: query_obj = self.query_obj() self.error_msg = "" self.results = None + # The datasource here can be different backend but the interface is common self.results = self.datasource.query(**query_obj) self.query = self.results.query df = self.results.df @@ -138,6 +148,7 @@ class BaseViz(object): return FormFactory(self).get_form() def query_filters(self): + """Processes the filters for the query""" form_data = self.form_data # Building filters filters = [] @@ -159,9 +170,7 @@ class BaseViz(object): return filters def query_obj(self): - """ - Building a query object - """ + """Building a query object""" form_data = self.form_data groupby = form_data.get("groupby") or [] metrics = form_data.get("metrics") or ['count'] @@ -387,10 +396,12 @@ class MarkupViz(BaseViz): class WordCloudViz(BaseViz): - """ - Integration with the nice library at: + + """Integration with the nice library at: + https://github.com/jasondavies/d3-cloud """ + viz_type = "word_cloud" verbose_name = "Word Cloud" is_timeseries = False @@ -421,12 +432,18 @@ class WordCloudViz(BaseViz): class NVD3Viz(BaseViz): + + """Base class for all nvd3 vizs""" + viz_type = None verbose_name = "Base NVD3 Viz" is_timeseries = False class BubbleViz(NVD3Viz): + + """Based on the NVD3 bubble chart""" + viz_type = "bubble" verbose_name = "Bubble Chart" is_timeseries = False