I need to build a dashboard for a website. Could you please give me some suggestion. I want to use python. Thanks in advance.
I would look into the Flask framework.
Per their website:
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.
The documentation is really good and I've used it at work for several dashboard style projects.
Here is something I have drawn up amending the resources I have around the internet.
This app creates a simple sidebar layout using inline style arguments and the
dbc.Nav component.
dcc.Location is used to track the current location, and a callback uses the
current location to render the appropriate page content.
Each page should have a different chart layout as its content.
The active prop of each NavLink is set automatically according to the current
pathname. To use this feature you must install dash-bootstrap-components >= 0.11.0.
For more details on building multi-page Dash applications, check out the Dash
documentation: https://dash.plot.ly/urls
import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output #for the callbacks
app = dash.Dash(external_stylesheets=[dbc.themes.DARKLY])
# the style arguments for the sidebar. We use position:fixed and a fixed width
SIDEBAR_STYLE = {
"position": "fixed",
"top": 0,
"left": 0,
"bottom": 0,
"width": "16rem",
"padding": "2rem 1rem",
"background-color": "black",
}
# the styles for the main content position it to the right of the sidebar and
# add some padding.
CONTENT_STYLE = {
"margin-left": "18rem",
"margin-right": "2rem",
"padding": "2rem 1rem",
}
sidebar = html.Div(
[
html.H2("Sidebar", className="display-4"),
html.Hr(),
html.P(
"A simple sidebar layout with navigation links", className="lead"
),
dbc.Nav(
[
dbc.NavLink("Home", href="/", active="exact"),
dbc.NavLink("Page 1", href="/page-1", active="exact"),
dbc.NavLink("Page 2", href="/page-2", active="exact"),
dbc.NavLink("Page 3", href="/page-3", active="exact"),
],
vertical=True,
pills=True,
),
],
style=SIDEBAR_STYLE,
)
content = html.Div(id="page-content", style=CONTENT_STYLE)
header = html.H4(
"Side Example.py", className="bg-primary text-white p-2 mb-2 text-center"
)
app.layout = html.Div([dcc.Location(id="url"),sidebar,header,content])
#app.callback(Output("page-content", "children"),[Input("url", "pathname")])
#Output("line-chart", "figure"),
def render_page_content(pathname):
if pathname == "/":
return dbc.NavbarSimple(children=[html.H2('Particular info for HOMEPAGE')],color="grey",dark=True,)
elif pathname == "/page-1":
return dbc.NavbarSimple(children=[html.H2('Particular info for PAGE1')],color="grey",dark=True,)
elif pathname == "/page-2":
return dbc.NavbarSimple(children=[html.H2('Particular info for PAGE2')],color="grey",dark=True,)
# If the user tries to reach a different page, return a 404 message
return dbc.Jumbotron(
[
html.H1("404: Not found", className="text-danger"),
html.Hr(),
html.P(f"The pathname {pathname} was not recognised..."),
]
)
if __name__ == "__main__":
app.run_server(port=8001)
Related
I'm using the SublimeREPL package. The title in the tab where the code is running is very long and makes navigating the tabs a hassle:
Can the title shown in the REPL tab be modified and/or suppressed all together?
In the answer you linked, one of the steps was to create a custom plugin to run your virtualenv REPL. You can customize the tab's title by changing the repl_open method to pass an "external_id" key and value. Here is the modified plugin code:
import sublime_plugin
class ProjectVenvReplCommand(sublime_plugin.TextCommand):
"""
Starts a SublimeREPL, attempting to use project's specified
python interpreter.
"""
def run(self, edit, open_file='$file', name='Python'):
"""Called on project_venv_repl command"""
cmd_list = [self.get_project_interpreter(), '-i', '-u']
if open_file:
cmd_list.append(open_file)
self.repl_open(cmd_list=cmd_list, name=name)
def get_project_interpreter(self):
"""Return the project's specified python interpreter, if any"""
settings = self.view.settings()
return settings.get('python_interpreter', '/usr/bin/python')
def repl_open(self, cmd_list, name):
"""Open a SublimeREPL using provided commands"""
self.view.window().run_command(
'repl_open', {
'encoding': 'utf8',
'type': 'subprocess',
'cmd': cmd_list,
'cwd': '$file_path',
'syntax': 'Packages/Python/Python.sublime-syntax',
'external_id': name
}
)
And here you can modify the arguments you send to the plugin to define the tab's name (the default being Python):
{
"keys": ["f6"],
"command": "project_venv_repl",
"args": {
"open_file": null,
"name": "My Project Name" // insert name of choice here.
}
},
I am making a chatbot through Chatterbot. I am facing the problems as follow:
when I run the code, it shows error, but the ChatBot is imported from chatterbot at the beginning?
File ".../SquirralBot.py", line 5,
in
class SquirralBot: File "...SquirralBot.py", line 6, in
SquirralBot
bot = Chatbot("SquirralBot", NameError: name 'Chatbot' is not defined
I want to make the chatbot to distinguish specific texts then to trigger specific corpus, how can I make it? Is the "chatterbot.conversation.Response(text, **kwargs)" class for this purpose? e.g. when the user types "I am leaving", then it will trigger to call the training set "chatterbot.corpus.chinese.squirral_bye_conversation"?
Is it possible if I can store the reply specifically to the database e.g. MongoDB for different users? e.g. when user A replies "I am sick. I got fever and running nose", then the system store "sick" into "status" and "fever" and "running nose" into "symptoms" in the user A's data so that inside the database it would be like JSON:
{
"user A",
"gender": "male",
"record": [
{
"date": "25-12-2018",
"status": "fine",
"symptoms": "",
},
{
"date": "26-12-2018",
"status": "sick",
"symptoms": "fever", "running nose"
}
}
Is it possible to make the chatbot can text the user in specific time range?
The code for the above mentioned is as following. I am very new in programming so the code may be a bit messy. Please feel free to correct. Many thanks.
import sys
from chatterbot import ChatBot
from chatterbot.trainers import ChatterBotCorpusTrainer
class SquirralBot:
chatbot = Chatbot("SquirralBot",
logic_adapters=[
{
"import_path": "chatterbot.logic.BestMatch",
"statement_comparison_function": "chatterbot.comparisons.levenshtein_distance",
"response_selection_method": "chatterbot.response_selection.get_first_response"
}
],storage_adapter = "chatterbot.storage.JsonFileStorageAdapter",database = "./SquirralBot_DB.json")
def __init__(self):
self.chatbot.set_trainer(ChatterBotCorpusTrainer)
self.chatbot.train("chatterbot.corpus.chinese.squirral_greeting", "chatterbot.corpus.chinese.squirral_bye_conversation", "chatterbot.corpus.chinese.squirral_normal_conversation", "chatterbot.corpus.chinese.squirral_rabbit_bye_conversation", "chatterbot.corpus.chinese.squirral_rabbit_conversation")
def getResponse(self, message=""):
return self.chatbot.get_response(message)
if __name__ == "__main__":
bot = SquirralBot()
print(bot.getResponse(sys.argv[1]))
Your import statements hint a ChatBot class with a capitalized B:
from chatterbot import ChatBot
Change
chatbot = Chatbot("SquirralBot",...)
to
chatbot = ChatBot("SquirralBot",...)
Note the capitalize B in ChatBot.
All of the documentation I've found on ScriptRunner and creating pages in Confluence assumes you are doing it from Jira, so it adds unnecessary steps to authenticate. I want to run the script in Confluence with no input from Jira or outside system.
Here is the code I had so far that gets hung up on the authenticatedRequestFactory:
import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Request
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import com.atlassian.sal.api.net.ResponseHandler
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def confluenceLink = getPrimaryConfluenceLink()
assert confluenceLink // must have a working app link set up
def authenticatedRequestFactory = confluenceLink.createImpersonatingAuthenticatedRequestFactory()
// set the page title - this should be unique in the space or page creation will fail
def pageTitle = "Teset Discussion"
def pageBody = """h3. Test
{quote}This is a quote{quote}
Yada yada, use this page to discuss the above...
"""
def params = [
type: "page",
title: pageTitle,
space: [
key: "COM" // set the space key - or calculate it from the project or something
],
/* // if you want to specify create the page under another, do it like this:
ancestors: [
[
type: "page",
id: "14123220",
]
],*/
body: [
storage: [
value: pageBody,
representation: "wiki"
],
],
]
authenticatedRequestFactory
.createRequest(Request.MethodType.POST, "rest/api/content")
.addHeader("Content-Type", "application/json")
.setRequestBody(new JsonBuilder(params).toString())
.execute(new ResponseHandler<Response>() {
#Override
void handle(Response response) throws ResponseException {
if(response.statusCode != HttpURLConnection.HTTP_OK) {
throw new Exception(response.getResponseBodyAsString())
}
else {
def webUrl = new JsonSlurper().parseText(response.responseBodyAsString)["_links"]["webui"]
}
}
})
The above sample is a trimmed down version from this documentation: https://scriptrunner.adaptavist.com/latest/jira/interacting-with-confluence-from-jira.html Appreciate any direction on how to just create a page.
Example code was shared on the following Atlassian thread: https://community.developer.atlassian.com/t/how-to-create-a-confluence-page-with-scriptrunner-via-rest-api/23695 It reviews how to create a page in Confluence without having to be connected to Jira.
I'm trying to build a website that allows people to access different kinds of graphs in a dash app. I want the users to log in with a username and a password before they can access the dashboard. This is what I have thus far
from flask import Flask, flash, render_template, request, session
import os, dash
import dash_html_components as html
import dash_core_components as dcc
import flask
app = Flask(__name__)
dash_app = dash.Dash(__name__, server=app, url_base_pathname='/dash_app')
dash_app.config['suppress_callback_exceptions']=True
def index_page():
index = html.Div([
dcc.Link('Page 1', href='/page1'),
html.Br(),
dcc.Link('Page 2', href='/page2'),
html.Br(),
dcc.Link('Page 3', href='/page3'),
html.Br()
])
return index
dash_app.layout = html.Div(children=[
dcc.Location(id='url', refresh=False),
html.Div(id = 'page-content')
])
page_1 = html.Div([
html.H1('Welcome to page 1'),
index_page()
])
page_2 = html.Div([
html.H1('Welcome to page 2'),
index_page()
])
page_3 = html.Div([
html.H1('Welcome to page 3'),
index_page()
])
#dash_app.callback(
dash.dependencies.Output('page-content','children'),
[dash.dependencies.Input('url','pathname')]
)
def display_page(pathname):
if pathname == '/page1':
return page_1
if pathname == '/page2':
return page_2
if pathname == '/page3':
return page_3
else:
return index_page()
#app.route('/')
def home():
if not session.get('logged_in'):
return render_template('login.html')
else:
return flask.redirect('/dash_app')
#app.route('/login', methods=['POST'])
def do_admin_login():
if request.form['password'] == 'password' and request.form['username'] == 'admin':
session['logged_in'] = True
else:
flash('wrong password!')
return home()
if __name__ == "__main__":
app.secret_key = os.urandom(12)
app.run(debug=True, port=5000)
There are two problems that I want to solve:
With this setup, you don't have to login to access the dashboard. If, instead of entering the username and password, you go directly to http://localhost:5000/dash_app you get to see the dashboard immediately. I only want to give access to people that are logged in.
If I refresh my browser page, after clicking on one of the three page links, I get a message saying "Not Found":I don't understand why this is happening and it feels to me like this has something to with the structure of the app.
Question: How do I solve these two issues? And, more generally; does this structure fit the goal I am trying to achieve? Is this the correct way to setup a dashboard inside a flask app? (I know that this login setup is not safe)
Edit: Regarding the refresh problem, I am sure that it has something to do with the dash app being run inside the flask app, because when I run the dash app by itself I can refresh http://localhost:5000/page1 and it renders successfully.
You should use flask-security instead of building your own login mechanism it solve lot of issue like Registration, Login, Logout, Forgot Password etc.
Instagram recently started showing view counts on videos. Is there a way to pull this data from the API?
I read through the documentation but I could not find anything about "Views" only "Likes".
Not available via public API yet.
Yes you can get it, if you have your facebook and instagram accounts linked and your instagram account has a business profile, make following GET request:
https://graph.facebook.com/v3.0/instagram_video_id/insights/video_views
you will get response in this format:
{
"data": [
{
"name": "video_views",
"period": "lifetime",
"values": [
{
"value": 123
}
],
"title": "Video Views",
"description": "Total number of times the video has been seen",
"id": "instagram_video_id/insights/video_views/lifetime"
}
]
}
The only way I've found is to systematically scrape posts' permalinks using browser automation like Seleniuim (with some logic handling the formatting e.g. 5.6k views vs 1,046 views) and picking out the appropriate element. A simple GET request doesn't yield the desired DOM due to the lack of javascript detected.
In python:
from bs4 import BeautifulSoup
from selenium import webdriver
def insertViews(posts):
driver = webdriver.PhantomJS('<path-to-phantomjs-driver-ignoring-escapes>')
views_span_dom_path = '._9jphp > span'
for post in posts:
post_type = post.get('Type')
link = post.get('Link')
views = post.get('Views')
if post_type == 'video':
driver.get(link)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
views_string_results = soup.select(views_span_dom_path)
if len(views_string_results) > 0:
views_string = views_string_results[0].get_text()
if 'k' in views_string:
views = float(views_string.replace('k', '')) * 1000
elif ',' in views_string:
views = float(views_string.replace(',', ''))
elif 'k' not in views_string and ',' not in views_string:
views = float(views_string)
else:
views = None
post['Views'] = views
driver.quit()
return posts
The PhantomJS driver can be downloaded here.