2

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.

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.

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()

Right now this second part should only send rate to the chart, but in the future i'm looking forward to have it processing a lot more data every second, and i would like to work with Pandas and Numpy to process this data.

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. Is it possible to have both running at the same time? Or should i just look for another way?

error
  • 2,356
  • 3
  • 23
  • 25
Jack022
  • 867
  • 6
  • 30
  • 91

2 Answers2

1

You may not really want to "embed" it to the first one. As far as I can tell, the second only "injects" data to the first one, so there is no logic need to have them together and from an architectural design aspect, coupling components create trouble.

I'd recommend just run two scripts from your shell. And of course, you can use a wrapper to launch both with one script, like

import subprocess

p = subprocess.Popen(['python', 'hello.py'])
p = subprocess.Popen(['python', 'wolrd.py'])

p.wait()
Siyu
  • 11,187
  • 4
  • 43
  • 55
  • Well, will using subprocess enable me to "share" data, so variables etc between the two scripts? That sounds like a good solution but would it scale well once deployed and ready to run on a website, for example? Sorry but i'm fairly new to this! Thank you! – Jack022 Nov 05 '18 at 22:45
  • 2
    no, subprocess will not allow you to share data like you would like. threads would, but neither threads nor processes should a part of your solution here. simple imports will solve your issue. if you are interesting in learning more about process spawning, check this link: https://stackoverflow.com/questions/2629680/deciding-among-subprocess-multiprocessing-and-thread-in-python. threads are also interesting, but again, not the best solution here. – Julian Nov 05 '18 at 22:52
  • Thank you! Maybe i should also look into using a DB to "share" the data – Jack022 Nov 05 '18 at 22:58
1

So there are some fundamental misunderstandings here...

First, you almost certainly do NOT want to try and write to separate scripts (running in their own process) to talk to each other. That will be a nightmare if you ever want to accomplish anything useful and is really something that should be considered after conventional methods fail to be performant. Reason being, interprocess communication is hard.

Second, you need to learn more about how importing in python works. There are quite a few issues with your imports as is, and a proper understanding of imports would basically solve your problem.

To get you started, imagine your two python files live next to one another, like so:

some_directory/
    __init__.py
    dash.py
    data.py

Since they are relative to one another, you can import one into the other to share functionality. Your code might end up looking something like this...

dash.py

from .data import XBTUSD
# other imports

app = dash.Dash(__name__)
# dash display logic, etc...

# connect your data here
XBTUSD.run_forever()

With the above, you would want to take the XBTUSD.run_forever() call out of the data.py file as it will simply define the command you want to run, allowing you to invoke it elsewhere and in different ways.

Julian
  • 1,078
  • 5
  • 17
  • So would this way make me able to have variables/data from data.py into dash.py? I tried it but i got No module named '__main__.trades', thank you for your advice! – Jack022 Nov 05 '18 at 22:57
  • That is an import error looking for a `main.trades` module. Is the code you are using up to date? I don't see an import for anything related to `trades`. – Julian Nov 05 '18 at 23:00
  • Sorry, trades is the real name for the file you called .data! – Jack022 Nov 05 '18 at 23:13
  • 1
    Ahh, then this link may help. It explains how to do relative imports in python. Read through the whole thing though, it's a great primer on the subject. https://realpython.com/absolute-vs-relative-python-imports/#relative-imports – Julian Nov 06 '18 at 01:18
  • Thanks, i'll take a look! – Jack022 Nov 06 '18 at 10:40