From efc54e0f65f7c9df18b2a15d230350fd19f51426 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Sat, 5 Sep 2015 09:23:46 -0700 Subject: [PATCH] Preparing pypi package --- .gitignore | 2 + README.md | 68 +++++++++++------- alembic.ini | 67 +++++++++++++++++ {app => panoramix}/__init__.py | 4 +- panoramix/bin/panoramix | 19 +++++ config.py => panoramix/config.py | 2 +- {app => panoramix}/highchart.py | 0 {app => panoramix}/models.py | 2 +- {app => panoramix}/static/bootstrap-theme.css | 0 {app => panoramix}/static/chaudron.png | Bin {app => panoramix}/static/chaudron_white.png | Bin {app => panoramix}/static/d3.min.js | 0 .../static/dataTables.bootstrap.css | 0 .../static/dataTables.bootstrap.js | 0 {app => panoramix}/static/favicon.png | Bin {app => panoramix}/static/highcharts-more.js | 0 {app => panoramix}/static/highcharts.js | 0 {app => panoramix}/static/highstock.js | 0 .../static/jquery.dataTables.min.css | 0 .../static/jquery.dataTables.min.js | 0 {app => panoramix}/static/main.css | 0 {app => panoramix}/static/panoramix.jpg | Bin {app => panoramix}/static/panoramix.png | Bin .../static/panoramix_screenshot.png | Bin .../static/select2-bootstrap.css | 0 {app => panoramix}/static/select2.min.css | 0 {app => panoramix}/static/select2.min.js | 0 {app => panoramix}/static/serpe.jpg | Bin {app => panoramix}/static/tux_panoramix.png | Bin .../templates/appbuilder/baselayout.html | 0 .../templates/appbuilder/navbar.html | 0 {app => panoramix}/templates/index.html | 0 .../templates/panoramix/base.html | 0 .../templates/panoramix/datasource.html | 0 .../templates/panoramix/no_data.html | 0 .../templates/panoramix/viz_highcharts.html | 0 .../templates/panoramix/viz_table.html | 0 {app => panoramix}/utils.py | 4 -- {app => panoramix}/views.py | 7 +- {app => panoramix}/viz.py | 5 +- run.py | 19 ----- setup.py | 32 +++++++++ 42 files changed, 172 insertions(+), 59 deletions(-) create mode 100644 alembic.ini rename {app => panoramix}/__init__.py (87%) create mode 100755 panoramix/bin/panoramix rename config.py => panoramix/config.py (99%) rename {app => panoramix}/highchart.py (100%) rename {app => panoramix}/models.py (99%) rename {app => panoramix}/static/bootstrap-theme.css (100%) rename {app => panoramix}/static/chaudron.png (100%) rename {app => panoramix}/static/chaudron_white.png (100%) rename {app => panoramix}/static/d3.min.js (100%) rename {app => panoramix}/static/dataTables.bootstrap.css (100%) rename {app => panoramix}/static/dataTables.bootstrap.js (100%) rename {app => panoramix}/static/favicon.png (100%) rename {app => panoramix}/static/highcharts-more.js (100%) rename {app => panoramix}/static/highcharts.js (100%) rename {app => panoramix}/static/highstock.js (100%) rename {app => panoramix}/static/jquery.dataTables.min.css (100%) rename {app => panoramix}/static/jquery.dataTables.min.js (100%) rename {app => panoramix}/static/main.css (100%) rename {app => panoramix}/static/panoramix.jpg (100%) rename {app => panoramix}/static/panoramix.png (100%) rename {app => panoramix}/static/panoramix_screenshot.png (100%) rename {app => panoramix}/static/select2-bootstrap.css (100%) rename {app => panoramix}/static/select2.min.css (100%) rename {app => panoramix}/static/select2.min.js (100%) rename {app => panoramix}/static/serpe.jpg (100%) rename {app => panoramix}/static/tux_panoramix.png (100%) rename {app => panoramix}/templates/appbuilder/baselayout.html (100%) rename {app => panoramix}/templates/appbuilder/navbar.html (100%) rename {app => panoramix}/templates/index.html (100%) rename {app => panoramix}/templates/panoramix/base.html (100%) rename {app => panoramix}/templates/panoramix/datasource.html (100%) rename {app => panoramix}/templates/panoramix/no_data.html (100%) rename {app => panoramix}/templates/panoramix/viz_highcharts.html (100%) rename {app => panoramix}/templates/panoramix/viz_table.html (100%) rename {app => panoramix}/utils.py (96%) rename {app => panoramix}/views.py (98%) rename {app => panoramix}/viz.py (99%) delete mode 100644 run.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index 6e2668ab781cb..9fc9e4a01dcca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ *.pyc *.db tmp +panoramix_config.py local_config.py +env app.db diff --git a/README.md b/README.md index 33c3344c34508..808a59cbe5eb0 100644 --- a/README.md +++ b/README.md @@ -61,35 +61,17 @@ Installation Follow these few simple steps to install Panoramix ``` -# Clone the github repo -git clone https://github.com/mistercrunch/panoramix.git - -# Get in that fresh new folder -cd panoramix - -# You may want to create a python virtualenv -# virtualenv env -# source env/bin/activate -# pip install -r requirements.txt - -# If you don't use a virtualenv, you'll have to sudo to install the reqs -sudo pip install -r requirements.txt +# Install panoramix +pip install panoramix -# Edit config.py, and read through the settings -# Note that alternatively, you can create a ``local_config.py`` and put it -# somewhere in your PYTHONPATH. The variables declared local_config.py -# will override the ones in ``config.py``, and won't create issues when -# you need to ``git pull`` the latest version of panoramix -vim config.py +# Create an admin user +fabmanager create-admin --app panoramix -# Create an admin account, the app will ask for username/password, ... -# This feature is out of Flask App Builder, the framework I used to build -# Panoramix -fabmanager create-admin +# Clone the github repo +git clone https://github.com/mistercrunch/panoramix.git # Start the web server -python run.py - +panoramix ``` After installation, you should be able to point your browser to the right @@ -101,6 +83,42 @@ your datasources for Panoramix to be aware of, and they should show up in Configuration ------------- + +To configure your application, you need to create a file (module) +`panoramix_config.py` and make sure it is in your PYTHONPATH. Here are some +of the parameters you can copy / paste in that configuration module: + +``` +#--------------------------------------------------------- +# Panoramix specifix config +#--------------------------------------------------------- +ROW_LIMIT = 5000 +WEBSERVER_THREADS = 8 + +PANORAMIX_WEBSERVER_PORT = 8088 +#--------------------------------------------------------- + +#--------------------------------------------------------- +# Flask App Builder configuration +#--------------------------------------------------------- +# Your App secret key +SECRET_KEY = '\2\1thisismyscretkey\1\2\e\y\y\h' + +# The SQLAlchemy connection string. +SQLALCHEMY_DATABASE_URI = 'sqlite:///tmp/panoramix.db' + +# Flask-WTF flag for CSRF +CSRF_ENABLED = True + +# Whether to run the web server in debug mode or not +DEBUG = True +``` + +This file also allows you to define configuration parameters used by +Flask App Builder, the web framework used by Panoramix. Please consult +the [Flask App Builder Documentation](http://flask-appbuilder.readthedocs.org/en/latest/config.html) for more information on how to configure Panoramix. + + * From the UI, enter the information about your clusters in the ``Admin->Clusters`` menu by hitting the + sign. diff --git a/alembic.ini b/alembic.ini new file mode 100644 index 0000000000000..24ddf3adb8115 --- /dev/null +++ b/alembic.ini @@ -0,0 +1,67 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +script_location = migrations + +# template used to generate migration files +# file_template = %%(rev)s_%%(slug)s + +# max length of characters to apply to the +# "slug" field +#truncate_slug_length = 40 + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +# set to 'true' to allow .pyc and .pyo files without +# a source .py file to be detected as revisions in the +# versions/ directory +# sourceless = false + +# version location specification; this defaults +# to help/versions. When using multiple version +# directories, initial revisions must be specified with --version-path +# version_locations = %(here)s/bar %(here)s/bat help/versions + +# the output encoding used when revision files +# are written from script.py.mako +# output_encoding = utf-8 + +sqlalchemy.url = scheme://localhost/panoramix + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/app/__init__.py b/panoramix/__init__.py similarity index 87% rename from app/__init__.py rename to panoramix/__init__.py index 97c83055919c3..c245baa58e0ad 100644 --- a/app/__init__.py +++ b/panoramix/__init__.py @@ -10,7 +10,7 @@ logging.getLogger().setLevel(logging.DEBUG) app = Flask(__name__) -app.config.from_object('config') +app.config.from_object('panoramix.config') db = SQLA(app) class MyIndexView(IndexView): @@ -22,4 +22,4 @@ class MyIndexView(IndexView): get_session = appbuilder.get_session -from app import views +from panoramix import views diff --git a/panoramix/bin/panoramix b/panoramix/bin/panoramix new file mode 100755 index 0000000000000..1ceb1b2d029ea --- /dev/null +++ b/panoramix/bin/panoramix @@ -0,0 +1,19 @@ +#!/usr/bin/env python +from panoramix import app, config +from subprocess import Popen + + +if __name__ == "__main__": + if config.DEBUG: + app.run( + host='0.0.0.0', + port=int(config.PANORAMIX_WEBSERVER_PORT), + debug=True) + else: + cmd = ( + "gunicorn " + "-w 8 " + "-b 0.0.0.0:{config.PANORAMIX_WEBSERVER_PORT} " + "panoramix:app").format(**locals()) + print("Starting server with command: " + cmd) + Popen(cmd, shell=True).wait() diff --git a/config.py b/panoramix/config.py similarity index 99% rename from config.py rename to panoramix/config.py index 093f5cf4d10c7..cb4bf8cff58fe 100644 --- a/config.py +++ b/panoramix/config.py @@ -124,6 +124,6 @@ #APP_THEME = "yeti.css" try: - from local_config import * + from panoramix_config import * except: pass diff --git a/app/highchart.py b/panoramix/highchart.py similarity index 100% rename from app/highchart.py rename to panoramix/highchart.py diff --git a/app/models.py b/panoramix/models.py similarity index 99% rename from app/models.py rename to panoramix/models.py index 40cbc231567ea..4f785cb36a65c 100644 --- a/app/models.py +++ b/panoramix/models.py @@ -22,7 +22,7 @@ import requests import textwrap -from app import db, get_session, utils +from panoramix import db, get_session QueryResult = namedtuple('namedtuple', ['df', 'query', 'duration']) diff --git a/app/static/bootstrap-theme.css b/panoramix/static/bootstrap-theme.css similarity index 100% rename from app/static/bootstrap-theme.css rename to panoramix/static/bootstrap-theme.css diff --git a/app/static/chaudron.png b/panoramix/static/chaudron.png similarity index 100% rename from app/static/chaudron.png rename to panoramix/static/chaudron.png diff --git a/app/static/chaudron_white.png b/panoramix/static/chaudron_white.png similarity index 100% rename from app/static/chaudron_white.png rename to panoramix/static/chaudron_white.png diff --git a/app/static/d3.min.js b/panoramix/static/d3.min.js similarity index 100% rename from app/static/d3.min.js rename to panoramix/static/d3.min.js diff --git a/app/static/dataTables.bootstrap.css b/panoramix/static/dataTables.bootstrap.css similarity index 100% rename from app/static/dataTables.bootstrap.css rename to panoramix/static/dataTables.bootstrap.css diff --git a/app/static/dataTables.bootstrap.js b/panoramix/static/dataTables.bootstrap.js similarity index 100% rename from app/static/dataTables.bootstrap.js rename to panoramix/static/dataTables.bootstrap.js diff --git a/app/static/favicon.png b/panoramix/static/favicon.png similarity index 100% rename from app/static/favicon.png rename to panoramix/static/favicon.png diff --git a/app/static/highcharts-more.js b/panoramix/static/highcharts-more.js similarity index 100% rename from app/static/highcharts-more.js rename to panoramix/static/highcharts-more.js diff --git a/app/static/highcharts.js b/panoramix/static/highcharts.js similarity index 100% rename from app/static/highcharts.js rename to panoramix/static/highcharts.js diff --git a/app/static/highstock.js b/panoramix/static/highstock.js similarity index 100% rename from app/static/highstock.js rename to panoramix/static/highstock.js diff --git a/app/static/jquery.dataTables.min.css b/panoramix/static/jquery.dataTables.min.css similarity index 100% rename from app/static/jquery.dataTables.min.css rename to panoramix/static/jquery.dataTables.min.css diff --git a/app/static/jquery.dataTables.min.js b/panoramix/static/jquery.dataTables.min.js similarity index 100% rename from app/static/jquery.dataTables.min.js rename to panoramix/static/jquery.dataTables.min.js diff --git a/app/static/main.css b/panoramix/static/main.css similarity index 100% rename from app/static/main.css rename to panoramix/static/main.css diff --git a/app/static/panoramix.jpg b/panoramix/static/panoramix.jpg similarity index 100% rename from app/static/panoramix.jpg rename to panoramix/static/panoramix.jpg diff --git a/app/static/panoramix.png b/panoramix/static/panoramix.png similarity index 100% rename from app/static/panoramix.png rename to panoramix/static/panoramix.png diff --git a/app/static/panoramix_screenshot.png b/panoramix/static/panoramix_screenshot.png similarity index 100% rename from app/static/panoramix_screenshot.png rename to panoramix/static/panoramix_screenshot.png diff --git a/app/static/select2-bootstrap.css b/panoramix/static/select2-bootstrap.css similarity index 100% rename from app/static/select2-bootstrap.css rename to panoramix/static/select2-bootstrap.css diff --git a/app/static/select2.min.css b/panoramix/static/select2.min.css similarity index 100% rename from app/static/select2.min.css rename to panoramix/static/select2.min.css diff --git a/app/static/select2.min.js b/panoramix/static/select2.min.js similarity index 100% rename from app/static/select2.min.js rename to panoramix/static/select2.min.js diff --git a/app/static/serpe.jpg b/panoramix/static/serpe.jpg similarity index 100% rename from app/static/serpe.jpg rename to panoramix/static/serpe.jpg diff --git a/app/static/tux_panoramix.png b/panoramix/static/tux_panoramix.png similarity index 100% rename from app/static/tux_panoramix.png rename to panoramix/static/tux_panoramix.png diff --git a/app/templates/appbuilder/baselayout.html b/panoramix/templates/appbuilder/baselayout.html similarity index 100% rename from app/templates/appbuilder/baselayout.html rename to panoramix/templates/appbuilder/baselayout.html diff --git a/app/templates/appbuilder/navbar.html b/panoramix/templates/appbuilder/navbar.html similarity index 100% rename from app/templates/appbuilder/navbar.html rename to panoramix/templates/appbuilder/navbar.html diff --git a/app/templates/index.html b/panoramix/templates/index.html similarity index 100% rename from app/templates/index.html rename to panoramix/templates/index.html diff --git a/app/templates/panoramix/base.html b/panoramix/templates/panoramix/base.html similarity index 100% rename from app/templates/panoramix/base.html rename to panoramix/templates/panoramix/base.html diff --git a/app/templates/panoramix/datasource.html b/panoramix/templates/panoramix/datasource.html similarity index 100% rename from app/templates/panoramix/datasource.html rename to panoramix/templates/panoramix/datasource.html diff --git a/app/templates/panoramix/no_data.html b/panoramix/templates/panoramix/no_data.html similarity index 100% rename from app/templates/panoramix/no_data.html rename to panoramix/templates/panoramix/no_data.html diff --git a/app/templates/panoramix/viz_highcharts.html b/panoramix/templates/panoramix/viz_highcharts.html similarity index 100% rename from app/templates/panoramix/viz_highcharts.html rename to panoramix/templates/panoramix/viz_highcharts.html diff --git a/app/templates/panoramix/viz_table.html b/panoramix/templates/panoramix/viz_table.html similarity index 100% rename from app/templates/panoramix/viz_table.html rename to panoramix/templates/panoramix/viz_table.html diff --git a/app/utils.py b/panoramix/utils.py similarity index 96% rename from app/utils.py rename to panoramix/utils.py index 6276b002ee5b2..bc83ddd292d5e 100644 --- a/app/utils.py +++ b/panoramix/utils.py @@ -1,9 +1,5 @@ -import config from datetime import datetime import parsedatetime -from app import db - - def parse_human_datetime(s): diff --git a/app/views.py b/panoramix/views.py similarity index 98% rename from app/views.py rename to panoramix/views.py index a2af4240770dd..be55baa87809c 100644 --- a/app/views.py +++ b/panoramix/views.py @@ -1,17 +1,16 @@ from datetime import datetime -import logging import json +import logging from flask import request, redirect, flash, Response from flask.ext.appbuilder.models.sqla.interface import SQLAInterface from flask.ext.appbuilder import ModelView, CompactCRUDMixin, BaseView, expose -from app import appbuilder, db, models, viz, utils, app, get_session -from flask.ext.appbuilder.security.decorators import has_access, permission_name -import config +from flask.ext.appbuilder.security.decorators import has_access from pydruid.client import doublesum from wtforms.validators import ValidationError from flask.ext.appbuilder.actions import action +from panoramix import appbuilder, db, models, viz, utils, app def validate_json(form, field): try: diff --git a/app/viz.py b/panoramix/viz.py similarity index 99% rename from app/viz.py rename to panoramix/viz.py index f5da848ce75af..dace3ebe2b1b9 100644 --- a/app/viz.py +++ b/panoramix/viz.py @@ -2,12 +2,11 @@ from flask import flash, request import pandas as pd from collections import OrderedDict -from app import utils -from app.highchart import Highchart, HighchartBubble +from panoramix import utils +from panoramix.highchart import Highchart, HighchartBubble from wtforms import Form, SelectMultipleField, SelectField, TextField import config import logging -from pydruid.utils.filters import Dimension, Filter CHART_ARGS = { diff --git a/run.py b/run.py deleted file mode 100644 index 8cc161e387d83..0000000000000 --- a/run.py +++ /dev/null @@ -1,19 +0,0 @@ -from app import app -import config -from subprocess import Popen - -if config.DEBUG: - app.run( - host='0.0.0.0', - port=int(config.PANORAMIX_WEBSERVER_PORT), - debug=True) -else: - cmd = ( - "gunicorn " - "-w 8 " - "-b 0.0.0.0:{config.PANORAMIX_WEBSERVER_PORT} " - "app:app").format(**locals()) - print("Starting server with command: " + cmd) - Popen(cmd, shell=True).wait() - - diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000000..c31e0afe9b675 --- /dev/null +++ b/setup.py @@ -0,0 +1,32 @@ +from setuptools import setup, find_packages + +version = '0.2' + +setup( + name='panoramix', + description=( + "A interactive data visualization platform build on SqlAlchemy " + "and druid.io"), + version=version, + packages=find_packages(), + package_data={'': ['panoramix/alembic.ini']}, + include_package_data=True, + zip_safe=False, + scripts=['panoramix/bin/panoramix'], + install_requires=[ + 'flask-appbuilder>=1.4.5', + 'flask-alembic>=1.2.1', + 'gunicorn>=19.3.0', + 'pandas>=0.16.2', + 'pydruid>=0.2.2', + 'parsedatetime>=1.5', + 'python-dateutil>=2.4.2', + 'requests>=2.7.0', + 'sqlparse>=0.1.16', + ], + author='Maxime Beauchemin', + author_email='maximebeauchemin@gmail.com', + url='https://github.com/mistercrunch/panoramix', + download_url=( + 'https://github.com/mistercrunch/panoramix/tarball/' + version), +)