4

I want to create a Python app where some data is retrieved and charted on a Dash app.

This is the Dash part. This is where my whole data will be sent and shown on a webpage, since I'm starting now, this is just a basic example of a live chart.

main.py

import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly
import random
import plotly.graph_objs as go
from collections import deque

app = dash.Dash(__name__)
app.layout = html.Div(
    [
        dcc.Graph(id='live-graph', animate=True),
        dcc.Interval(
            id='graph-update',
            interval=1*1000
        ),
    ]
)

@app.callback(Output('live-graph', 'figure'),
             events=[Event('graph-update', 'interval')])
def update_graph_scatter():
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1]*random.uniform(-0.1,0.1))

    data = plotly.graph_objs.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines+markers'
            )

    return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]), yaxis=dict(range=[min(Y),max(Y)]),)}

if __name__ == '__main__':
    app.run_server(debug=True)

This is the Python part where the data is retrieved, connecting to a Websocket.
data.py

import websocket
import json
from bitmex_websocket import Instrument
from bitmex_websocket.constants import InstrumentChannels
from bitmex_websocket.constants import Channels

websocket.enableTrace(True)

channels = [
    InstrumentChannels.trade,
]

XBTUSD = Instrument(symbol='XBTUSD',
                    channels=channels)
XBTUSD.on('action', lambda msg: test(msg))

XBTUSD = Instrument(symbol='XBTUSD',                       
                channels=channels)

XBTUSD.on('action', lambda msg: rekter(msg))

def rekter(msg):

    if msg['table'] =='trade':
        Rate = msg['data'][0]['price']

        print(Rate)


XBTUSD.run_forever()

I tried to accomplish that by using imports, so I imported as a module my script, but that didn't work either:

from trades import XBTUSD
import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
import plotly
import random
import plotly.graph_objs as go
from collections import deque


X = deque(maxlen=2000)
X.append(1)
Y = deque(maxlen=2000)
Y.append(1)


app = dash.Dash(__name__)
app.layout = html.Div(
    [
        dcc.Graph(id='live-graph', animate=True),
        dcc.Interval(
            id='graph-update',
            interval=1*1000
        ),
    ]
)

@app.callback(Output('live-graph', 'figure'),
              events=[Event('graph-update', 'interval')])
def update_graph_scatter():
    X.append(X[-1]+1)
    Y.append(Y[-1]+Y[-1]*random.uniform(-0.1,0.1))

    data = plotly.graph_objs.Scatter(
            x=list(X),
            y=list(Y),
            name='Scatter',
            mode= 'lines+markers'
            )

    return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
                                                yaxis=dict(range=[min(Y),max(Y)]),)}



if __name__ == '__main__':
    app.run_server(debug=True)

XBTUSD.run_forever()

Other than that, I tried turning it into modules, but it didn't work either.

My problem is that I don't know how to "embed" my second part into the first part. I tried do that, but if I put the lineXBTUSD.run_forever()before app.run_server(debug=True) only one part of the code will be executed and my whole Dash app won't run until I stop the first part of the code. Same happens if I do the opposite.

So the problem is XBTUSD.run_forever(), but I can't just remove that line because it won't run data.py. Is there a way to solve this?

I am now thinking of running two separated scripts with one sending data to a DB and the other one should query the DB, retrieve the data and chart it, but I don't know if it's the best solution because a) I'll be handling a lot of data every minute b) I don't know if it'll work when deployed online (on heroku, for example)

1 Answer 1

2

The answer is threading or multiprocessing, which will allow both methods to run at the same time. Changes to mutable objects take place in both threads/processes, so you would be able to communicate between your two functions as such. This post provides clarity on the issue.

Sign up to request clarification or add additional context in comments.

2 Comments

Sounds like a valid solution, but would it allow me to "share" data/variable etc between the two scripts and would it work when deployed online, for example on Heroku?
As long as the data is mutable, i.e. not just a string or number, and as far as Heroku goes, a quick search looks like it's not impossible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.