Skip to content

Commit

Permalink
Adding a secure RESTfull node - consumed by the dashboard charts
Browse files Browse the repository at this point in the history
  • Loading branch information
Adi Chirilov committed Jun 18, 2019
1 parent 4e50263 commit 9e07faa
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 97 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Beautiful [Argon Dashboard](https://www.creative-tim.com/product/argon-dashboard

<hr>

![Flask Dashboard](https://github.com/app-generator/flask-argon-dashboard/blob/master/screenshots/flask-argon-dashboard-intro.gif)
![Flask Dashboard Argon](https://github.com/app-generator/flask-argon-dashboard/blob/master/screenshots/flask-argon-dashboard-intro.gif)

<hr>

Expand All @@ -13,8 +13,8 @@ Features

- SQLite database
- Login, Register
- Static Build `python ./static.py`. The static build goes to `app/build` directory
- FTP Deploy script. **Info**: this `require node.js` and the edit of `deploy.js` to add FTP server credentials.
- REST API node on top of [Flask-RESTful](https://flask-restful.readthedocs.io/en/latest/)


### Screenshot - generic page

Expand All @@ -40,6 +40,13 @@ Features
$ pip install -r requirements.txt
```

4. Create the database, using Flask shell
```
$ flask shell
$ >>> from app import db
$ >>> db.create_all()
```

5. Run the development server:
```
$ flask run
Expand Down
9 changes: 9 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
from flask_login import LoginManager
from flask_bcrypt import Bcrypt

from flask_restful import Api

# Grabs the folder where the script runs.
basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)

api = Api(app) # flask_restful

app.config.from_object('app.configuration.Config')

db = SQLAlchemy (app) # flask-sqlalchemy
Expand All @@ -29,3 +33,8 @@
lm.init_app(app) # init the login manager

from app import views, models
from app.restapi.stats import ApiStats

# Inject REST api
api.add_resource(ApiStats, '/api/stats/<string:segment>')

44 changes: 43 additions & 1 deletion app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, user, email, password):
self.email = email

def __repr__(self):
return '<User %r>' % (self.id)
return '<User %r - %s>' % (self.id) % (self.email)

def save(self):

Expand All @@ -35,3 +35,45 @@ def save(self):
db.session.commit( )

return self

class Stats(db.Model):

id = db.Column(db.Integer, primary_key=True)
key = db.Column(db.String(64), unique=True)
val = db.Column(db.Integer)
val_s = db.Column(db.String(256))

def __init__(self, key):
self.key = key

db_obj = Stats.query.filter_by(key=key).first()
if db_obj:
self.id = db_obj.id
self.key = db_obj.key
self.val = db_obj.val
self.val_s = db_obj.val_s

else:

db.session.add ( self )

self.val = 0
self.val_s = ''

def __repr__(self):
return '<Stats %s / %r / %s >' % ( self.key, self.val, self.val_s )

def save(self):

db_obj = Stats.query.filter_by(key=self.key).first()

# update the existing db object
if db_obj:

db_obj.val = self.val
db_obj.val_s = self.val_s

# commit change and save the object
db.session.commit( )

return self
9 changes: 9 additions & 0 deletions app/restapi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- encoding: utf-8 -*-
"""
Argon Dashboard - coded in Flask
Author : AppSeed App Generator
Design : Creative-Tim.com
License : MIT
Support : https://appseed.us/support
"""
40 changes: 40 additions & 0 deletions app/restapi/stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- encoding: utf-8 -*-
"""
Argon Dashboard - coded in Flask
Author : AppSeed App Generator
Design : Creative-Tim.com
License : MIT
Support : https://appseed.us/support
"""

from flask_restful import Resource
from flask_login import current_user

from app.models import Stats

class ApiStats(Resource):

def get(self,segment):

if not current_user.is_authenticated:
return {'err': 'auth'}, 401

# See the model for details
val = Stats( segment ).val

if 'traffic' == segment:
return { segment : val }, 200

elif 'users' == segment:
return { segment : val }, 200

elif 'sales' == segment:
return { segment : val }, 200

elif 'perf' == segment:
return { segment : val }, 200

else:
return {'err': 'unknown'}, 404

30 changes: 30 additions & 0 deletions app/static/assets/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

'use strict';

$(function() {

// Update the Traffic cell
$.getJSON('/api/stats/traffic', function( data ) {
//console.log( ' -> ' + data['traffic'] )
$('#stats_traffic').html( data['traffic'] );
});

// Update the Users cell
$.getJSON('/api/stats/users', function( data ) {
//console.log( ' -> ' + data['traffic'] )
$('#stats_users').html( data['users'] );
});

// Update the Sales cell
$.getJSON('/api/stats/sales', function( data ) {
//console.log( ' -> ' + data['traffic'] )
$('#stats_sales').html( data['sales'] );
});

// Update the Perf cell
$.getJSON('/api/stats/perf', function( data ) {
//console.log( ' -> ' + data['traffic'] )
$('#stats_perf').html( data['perf'] );
});

});
3 changes: 3 additions & 0 deletions app/templates/includes/scripts.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
<!-- Argon JS -->
<script src="/static/assets/js/argon.js?v=1.0.0"></script>

<!-- App -->
<script src="/static/assets/js/app.js"></script>

103 changes: 103 additions & 0 deletions app/templates/includes/top-stats.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

<div class="header bg-gradient-primary pb-8 pt-5 pt-md-8">
<div class="container-fluid">
<div class="header-body">
<!-- Card stats -->
<div class="row">
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Traffic</h5>

<span id="stats_traffic" class="h2 font-weight-bold mb-0">N/A</span>

</div>
<div class="col-auto">
<div class="icon icon-shape bg-danger text-white rounded-circle shadow">
<i class="fas fa-chart-bar"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-muted text-sm">
<span class="text-success mr-2"><i class="fa fa-arrow-up"></i> 3.48%</span>
<span class="text-nowrap">Since last month</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">New users</h5>

<span id="stats_users" class="h2 font-weight-bold mb-0">N/A</span>

</div>
<div class="col-auto">
<div class="icon icon-shape bg-warning text-white rounded-circle shadow">
<i class="fas fa-chart-pie"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-muted text-sm">
<span class="text-danger mr-2"><i class="fas fa-arrow-down"></i> 3.48%</span>
<span class="text-nowrap">Since last week</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Sales</h5>

<span id="stats_sales" class="h2 font-weight-bold mb-0">N/A</span>

</div>
<div class="col-auto">
<div class="icon icon-shape bg-yellow text-white rounded-circle shadow">
<i class="fas fa-users"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-muted text-sm">
<span class="text-warning mr-2"><i class="fas fa-arrow-down"></i> 1.10%</span>
<span class="text-nowrap">Since yesterday</span>
</p>
</div>
</div>
</div>
<div class="col-xl-3 col-lg-6">
<div class="card card-stats mb-4 mb-xl-0">
<div class="card-body">
<div class="row">
<div class="col">
<h5 class="card-title text-uppercase text-muted mb-0">Performance</h5>

<span id="stats_perf" class="h2 font-weight-bold mb-0">N/A</span>

</div>
<div class="col-auto">
<div class="icon icon-shape bg-info text-white rounded-circle shadow">
<i class="fas fa-percent"></i>
</div>
</div>
</div>
<p class="mt-3 mb-0 text-muted text-sm">
<span class="text-success mr-2"><i class="fas fa-arrow-up"></i> 12%</span>
<span class="text-nowrap">Since last month</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Loading

0 comments on commit 9e07faa

Please sign in to comment.