Python Forum
Output ZMQ-content to browser - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Output ZMQ-content to browser (/thread-6289.html)



Output ZMQ-content to browser - AarClay - Nov-14-2017

I have this code in Python. (Add i'm not a great python-expert ;) )
With this I can output the content of the ZeroMQ-stream to a file. Only writing to a file every 10 seconds does not seem to be really useful and costs a lot of performance.

Now I would like to show the content in a web-page. I am not an extreme python expert, but I have learned that I can set up a web server with PyBottle.

How can I integrate PyBottle in my code, so it can output the latest message of the stream? I thought about the code of PyBottle in the **while**-loop.

But do not I ( unnecessarily ) create a new web-server instance?

How can I handle this?

Or does anyone else have a good idea how to export the content of recent data from the stream to a browser?

Sample of PyBottle:
    from bottle import route, run, template
    
    @route( '/hello/<name>' )
    def index( name ):
        return template( '<b>Hello {{name}}</b>!', name = name )
    
    run( host = 'localhost', port = 8080 )
And my Python script, so far:
    #!/usr/bin/env python2

    from gzip       import GzipFile
    from cStringIO  import StringIO
    from subprocess import call
    pass;           import zmq
    
    context = zmq.Context()
    
    subscriber = context.socket( zmq.XSUB )
    subscriber.connect( "tcp://pubsub.*******.nl:7664" )
    subscriber.send( chr( 0x01 )             # { 0x01: ZMQ_XSUB.subscribe,
                   + "/RIG/VehiclePositions" #   0x00: ZMQ_XSUB.unsubscribe
                     )                       #   }
    while   True:

            multipart =  subscriber.recv_multipart()
            address   =  multipart[0]
            contents  = ''.join(multipart[1:])
            contents  =  GzipFile( '', 'r', 0, StringIO( contents ) ).read()
            filename  = "tmp/treinpos.txt"
            file      =  open( filename, "w" )
            file.write( contents )
            file.close()
    
    subscriber.close()
    context.term()



RE: Output ZMQ-content to browser - AarClay - Nov-15-2017

Anyone an idea how i can output the content to the browser?


RE: Output ZMQ-content to browser - snippsat - Nov-15-2017

I guess you mean Bottle and not PyBottle.
Quote:But do not I ( unnecessarily ) create a new web-server instance?
Yes it's not good and unnecessarily to create a web-server instance for every update.
There are soultion for this and i would recommend Flask,
that has better support for stuff like this like Flask-SocketIO and jQuery + socket.io on the client side.
Also mention Celery that work well with Flask.

The topic of running background live update/stream tasks is complex.
If new to Python and web-develoment dos not help Wink

Can show a solution that call a Python function on server side every 10-sec.
This is using Ajax to no reload browser,and done with jQuery on client side.
To help keep it clean $.ajaxSetup({ cache: false });
Will prevent all future AJAX requests from being cached.
setTimeout( will execute a script only one time) is better setInterval().

app.py:
from flask import Flask, render_template, jsonify, request
import random

app = Flask(__name__)

@app.route("/")
def test_job():
    return render_template('index.html')

@app.route('/stuff', methods=['GET'])
def stuff():
    '''Here stuff to be send to browser'''
    val_random = random.random()   
    return jsonify(val_random=val_random)

if __name__ == "__main__":
    app.run(debug=True)
index.html:
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.css') }}" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <title>Show updated random number</title>
</head>
<body>
  <div class="table">
    <p id="rand_value">Value</p>
    <button>Push to start random update</button>
  </div>
</body>

<script> 
  $.ajaxSetup({ cache: false });
  $(document).ready(function () {
    $("button").click(function update_values() {
      $.getJSON('/stuff', function (dat) {
        $("#rand_value").text(dat['val_random']);
      });
      var interval = setTimeout(update_values, 10000);
    });
  });
</script>

</html>



RE: Output ZMQ-content to browser - AarClay - Nov-16-2017

Thank you for your extensive response. I will look at it from the weekend.
I am talking about the latest update in the stream, which must be shown in the browser.

How you can have this refreshed real-time by users, that is indeed with AJAX.
I was familiar with that point.


RE: Output ZMQ-content to browser - AarClay - Nov-24-2017

I do not understand at all?

This is what i must do first in my code, and of course make sure that flask is installed and running.
app = Flask(__name__)
And so I have to put this code in the while loop?

@app.route("/")
def index():
    return content
Is this right?


RE: Output ZMQ-content to browser - snippsat - Nov-24-2017

(Nov-24-2017, 02:26 PM)AarClay Wrote: And so I have to put this code in the while loop?
Is this right?
No i think you are confused Confused
There no while loop,the build web-server of Flask is what should be running. 
Here is the full setup,also added Bootstrap to make button and random numbers text look better.
pip install Flask
Folder setup:
rand_numbers\
  |-- app.py
  templates\
    |-- index.html
app.py:
from flask import Flask, render_template, jsonify, request
import random
 
app = Flask(__name__)
 
@app.route("/")
def test_job():
    return render_template('index.html')
 
@app.route('/stuff', methods=['GET'])
def stuff():
    '''Here stuff to be send to browser'''
    val_random = random.random()   
    return jsonify(val_random=val_random)
 
if __name__ == "__main__":
    app.run(debug=True)
index.html:
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style4.css') }}" />
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" >
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <title>Show updated random number</title>
</head>

<body style="background-color: rgb(186, 209, 231)">
  <div class="text-center" role="group" aria-label="...">
    <h1 class="text-success" id='numbers'>000000</h1>
    <a id='b1' class="btn btn-primary"><span class="glyphicon glyphicon-random"></span> Random numbers</a>
  </div>
</body>

<script> 
  $.ajaxSetup({ cache: false });
  $(document).ready(function () {
    $("#b1").click(function update_values() {
      $.getJSON('/stuff', function (dat) {
        $("#numbers").text(dat['val_random']);
      });
      var interval = setTimeout(update_values, 10000);
    });
  });
</script>
</html>
No shall start web-server bye running python app.py in rand_numbers folder(always to this from command line).
This will give you a address http://127.0.0.1:5000/.
This address do you copy and paste into browser,and push button to start random update every 10-sec.


RE: Output ZMQ-content to browser - AarClay - Nov-26-2017

But, i want to output the last message from the ZeroMQ stream. Not a random number....
Read my first post ;)
How can i integrate this, on the way that i describe?


RE: Output ZMQ-content to browser - snippsat - Nov-26-2017

(Nov-26-2017, 12:01 AM)AarClay Wrote: Read my first post ;)
ow can i integrate this, on the way that i describe?
They point is not at all that i shall write everything for for you Dodgy
Look at jsonify(),it can handle both python list and dict which will be JSON serialization automatic over the connection.
So when i do jsonify(val_random=val_random) it will send this Response JSON object in browser {"val_random: 0.55719943207732"}.
You have to look at your contents,and think of how it can be transferred based on this info.


RE: Output ZMQ-content to browser - AarClay - Nov-26-2017

The content is also a JSON-string. I will try something.... Thanks :)


RE: Output ZMQ-content to browser - YogiMike - Jun-02-2021

Smile thanks for the post snippsat. I used your example (with data changes) to use flask on my Raspberry Pi 2 with a Sense Hat to have a dynamic webpage which automatically updates Humidity, Temp, Barometric Pressure, and other data. It worked marvelously!!