Kirim data dari server ke klien atau sebaliknya dengan SocketIO dan Flask

Artikel ini berisi cara implementasi mengirim data dari server ke klien dengan SocketIO dan Flask. Dalam hal ini “server” adalah bahasa yang digunakan untuk mengakses data server seperti PHP, Python, Java, dan lainnya. Lalu “klien” adalah lingkungan yang biasa dilihat oleh user seperti browser, aplikasi mobile android / ios. Jika berbicara browser pasti tidak lepas dari HTML dan Javascript 🙂

Artikel ini juga membahas socket.io sebagai media untuk membantu menghubungkan proses tersebut. Dalam website socket.io tertulis

“Socket.IO enables real-time bidirectional event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed.”

Socket.io membantu proses realtime komunikasi berdasarkan event secara bidireksional. Dapat digunakan di setiap platform, browser atau device dengan memfokuskan kecepatan dan reliabiliti.

Saya penasaran apakah Flask Python bisa menghandle proses ini seperti Laravel pun sudah bisa. Dan ternyata sudah ada yaitu Flask-SocketOi, https://flask-socketio.readthedocs.io/en/latest/.

Mari kita coba bermain dengan library python ini.

Langkah #1

Awalnya, buat folder dengan sembarang nama, misalnya saya ini “flask-socketio-test”.

Langkah #2

Masuk ke dalam folder “flask-socketoi-test” lalu kita buat virtualenv dengan perintah.

virtualenv venv -p python3

“venv” sebagai nama folder untuk virtual environtment python.

Langkah #3

Aktifkan virtualenv dengan perintah.

source venv/bin/activate

*perintah ini hanya dijalankan di lingkungan linux. Untuk windows, silahkan cari tahu ya di google.

Langkah #4

Instlal flask-socketio dengan perintah.

pip install flask-socketio

Setelah itu kita buat folder src lalu buat file app.py didalamnya. Lalu buat pula folder templates yang didalamnya berisi file index.html. Kosongkan saja dulu.

Setelah berhasil membuat folder dan file. Mari kita lanjutkan di proses selanjutnya.

Langkah #5

Buka file app.py, lalu code seperti dibawah ini.

from flask import Flask, render_template, request
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'THIS IS SECRETKEY 1231412'
socketio = SocketIO(app)

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

@app.route('/kirim')
def kirim_data():
	socketio.emit('my_response', {'data': 'data 1'}, namespace='/app1')
	return ('', 204)

@socketio.on('data_dari_browser', namespace='/app1')
def menerima_data(json):
    print('menerima data json: ' + str(json))

if __name__ == '__main__':
	socketio.run(app)

Jika dilihat terdapat route “/” yang mengarah ke file index.html. Isi dari file index.html adalah sebagai berikut.

<!DOCTYPE HTML>
<html>

<head>
    <title>Flask-SocketIO Test</title>
    <script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            namespace = '/app1';
            
            // initial socket object
            var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

            // sending data through socketio
            socket.on('connect', function () {

                // kirim data dari klien
                // dari klien ini bisa dari browser, atau dari mobile apps
                // biasa nya berupa form input
                socket.emit('data_dari_browser', { data: 'saya dari klien' });
            });

            socket.on('my_response', function (msg) {
                $('#log').append('<br>' + $('<div/>').text('Menerima data #' + msg.data).html());
            });
        });
    </script>
</head>

<body>
    <h1>Flask-SocketIO Test</h1>
    <div id="log"></div>
</body>

</html>

Baik, saya jelaskan per proses ya.

Mengirim data dari klien (browser) ke server

Untuk mengirim data dari klien ke server ini seperti proses ajax pada umumnya. Bedanya adalah kita tanpa jquery atau vanilla js. Kita pakai socket.io untuk mengirim data dari browser ke server.


[crp]


Pengirim dari browser itu terlihat di baris kode ini.

socket.emit('data_dari_browser', { data: 'saya dari klien' });

Pastikan sudah pasang object socket dulu diatas sebelumnya. Lalu perhatikan terdapat namespace yang mengarahkan data ini akan diterima oleh server. Jika namespace ini berbeda dengan server, maka data tidak akan diterima.

Penerimaan data di sisi server bisa dilihat di app.py di fungsi berikut.

@socketio.on('data_dari_browser', namespace='/app1')
def menerima_data(json):
    print('menerima data json: ' + str(json))

Kita coba jalankan dengan perintah

python src/app.py

Lalu server berjalan ke port 5000, *default port flask dalam membuat server. Dan kita coba akses ke port tersebut dengan Firefox maka pada terminal python kita akan terlihat bahwa data telah diterima seperti gambar dibawah ini.

menerima data socket.io flask

Sesuai ya. Dari data tersebut bisa digunakan untuk akses database atau kebutuhan lainnya.

Mengirim data dari server ke klien (browser)

Mengirim data dari klien ke server sepertinya mudah dan sudah biasa dilakukan ya oleh teman-teman. Nah sekarang bagaimana mengirim data dari server ke klien tanpa refresh/reload page? Kodenya udah ada kok di atas. Mari kita coba liat ya.

Kode dari server untuk mengirim ke klien itu kita lihat dulu kode di sisi server yaitu di file app.py. Kode pengirimannya tepat di kode ini.

@app.route('/kirim')
def kirim_data():
	socketio.emit('my_response', {'data': 'data 1'}, namespace='/app1')
	return ('', 204)

Pada kode ini saya buat route dengan “/kirim” lalu tiap ada browser yang memanggil url tersebut maka akan menjalankan kode untuk mengirim data dari server ke klien dengan perintah emit tersebut.

Pastikan flag “my_response” dan namespace itu sama dengan yang di klien (kode index.html). Karena jika tidak sama maka tidak akan diterima lho 🙂

Lalu bagaimana klien / browser menerima data dari server? mari kita lihat index.html dan terlihat kode untuk menerimanya seperti berikut.

socket.on('my_response', function (msg) {
  $('#log').append('<br>'+$('<div/>').text('Menerima data #'+msg.data).html());
});

Terima data dengan variable msg, lalu tempel ke html. Sederhana juga ya 😀

mengirim data flask-socketio

Dari sini kita sudah dapat mengirim data dari server ke klien dengan bantuan socket.io bersama flask. Kebutuhan untuk proses ini banyak sekali, salah satunya ada konsep chatting yang membutuhkan proses secara bidireksional event.

Apa saja aplikasi yang bisa memanfaatkan proses ini? coba kamu bayangkan mengirim data dari server ke klien tanpa refresh/reload dengan resources minim.

Karena kalau pakai method long polling ajax itu bikin server ngap-ngapan lho. 🙂

Ada beberapa fitur lain seperti membuat group, membuat broadcast dan lainnya, silahkan lihat referensi dibawah artikel ini.

Selamat mencoba 🙂

Referensi:

Belajar membuat Restful sederhana dengan Flask-Restful dan Flask-JWT

Kini banyak website yang menggunakan Restful untuk konektifitas dengan database. Selain lebih cepat karena data tidak dipanggil secara langsung ketika website itu muncul, dengan restful pun kita mudah untuk melebarkan performance website yang mungkin beberapa dikenal dengan microservices arsitektur. Selain itu API Restful bisa digunakan untuk Android/IOS developer untuk merangkai kode-kode indahnya. Apapun itu sebenernya adalah kemajuan yang harus programmer pelajari untuk bisa survive. Ya survive!

Enaknya, bagian Backend developer itu tidak dipusingkan dengan aturan main dari CSS atau layout. Hanya menunggu permintaan dari Frontend developer. Frontend developer biasanya menggunakan javascript framework seperti Angular, VueJS ataupun React. Ketiga pemain ini sudah begitu besar dan kencang sekali di dunia pemrograman. Luarbiasa Javascript!

Pernah menggunakan Laravel sebagai API Restful, saya penasaran dengan beberapa teknologi dari nyoba-nyoba Spring Boot, lalu sampai ke Flask Restful. Entah kenapa belum kepingin nyobain NodeJs. Lalu kenapa Flask? Ini mudah banget bikin dan implementasinya. Selain itu memang saya ada plan juga untuk putus sama PHP karena value yang makin kesini makin turun saja. (updated belum bisa move on dari PHP karena kerjaan dan butuh harian keluarga :D)

Beberapa saya coba untuk membuat Flask Restfull sederhana dengan menyimpan data pada variable python dictionary. Berikut adalah URL Githubnya: https://github.com/adiputra22/flask-rest-beginner

Setelah itu mencoba untuk menyimpan data dengan SQLite. Karena SQLite sudah bawaan Flask, jadi tinggal pakai saja. Berikut adalah URL Githubnya: https://github.com/adiputra22/flask-rest-beginner-with-sqlite

Berhasil bermain SQLite, saya coba untuk integrasi ke MySQL. Dengan MySQL ini perlu tambahan lagi yaitu PyMySQL. Berikut adalah Githubnya: https://github.com/adiputra22/flask-rest-beginner-with-mysql

Ke MySQL berhasil, lalu saya nyobain ORM yang biasa digunakan python, yap SQLAlchemy. Belajar buat model lalu cara mengakses model pada Python sampai mencoba untuk setting ke Heroku. Hasil saya simpan di github: https://github.com/adiputra22/flask-rest-sqlite-sqlalchemy. Disini juga nyobain fitur keren si heroku auto deploy dari github ke live server https://flask-rest-sqlalchemy.herokuapp.com/

Kalau udah bisa konek dan manipulasi di database. Tinggal coba-coba yang lain seperti:
– mengatur gemana restful yang baik di flask (struktur folder, file) agar manage-nya gampang jika sudah besar
– mengatur performance dari restful flask. Dihitung dari sisi flask itu sendiri ya. Belum masuk ke settingan lainnya seperti best performance untuk MySQL/Postgresql. Belum lagi kita perlu setting best performance untuk server kita, dll, dll.

Diakhir mungkin ada yang bertanya kenapa Flask/Python?
– Pertama yang saya katakan diawal adalah kode-nya simple dan gampang baca-nya.
– Performa Python itu udah terkenal handal, ada youtube, bitbucket, udemy, instagram API dan lainnya
– Project diluar negeri banyak yang nyari Python, Rails dan lainnya. PHP banyak juga tapi nilai kecil dan yang main banyak juga jadi persaingan ketat banget 😀

Cara Membuat JWT token dengan Flask

Lama tidak bermain dengan Flask mungkin kisaran 1 tahun lalu. Library python ini memang keren banget untuk belajar web dengan Python sebelum masuk ke Django. JWT sendiri biasa digunakan untuk Auth atau pembatasan penggunaan dari sisi API. Ngomong soal API, pasti ga jauh dengan development Android/IOS walaupun sekarang juga ada yang seneng buat aplikasi web dengan SPA (Single Page Application) yang membutuhkan API tentunya 🙂

Flask sendiri ada library untuk handel JWT. Ada di link ini [https://pythonhosted.org/Flask-JWT/]. Penasaran mari kita coba yuk dengan bantuan Postman untuk mengetest-nya.

Seperti biasa kita buat folder dulu, lalu pastikan kita sudah menginstall Flask dan Flask-JWT.

pip install Flask-JWT

Setelah berhasil, masuk ke folder misalnya saya buat flask-jwt, lalu buat file app.py yang isinya seperti kode dibawah ini.

from flask import Flask
from flask_jwt import JWT, jwt_required, current_identity #1
from werkzeug.security import safe_str_cmp #2

class User(object): #3
  def __init__(self, id, username, password):
    self.id = id
    self.username = username
    self.password = password

  def __str__(self):
    return "User ID: " + str(self.id) + "<br />Username: " + self.username

#4
users = [
    User(1, 'joe', 'pass'),
    User(2, 'adiputra', 'yay')
]

username_table = {u.username: u for u in users} #5
userid_table = {u.id: u for u in users} #6

#7
def authenticate(username, password):
    user = username_table.get(username, None)
    if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
        return user

#8
def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id, None)

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'xxxadiputra-flask-jwt' #9

#10
jwt = JWT(app, authenticate, identity)

@app.route('/protected')
@jwt_required() #11
def protected():
    return '%s' % current_identity #12

if __name__ == '__main__':
    app.run()

Kode ini sebenernya saya ambil dari link diatas. Ada sedikit perubahan di data saja. Penjelasan per kode:

#1: Import Flask JWT dan kawan-kawannya.
#2: safe_str_cmp itu untuk security dan membandingkan 2 variable yang akan kita gunakan saat melakukan request/login guna mendapatkan token. Penjelasan lebih lengkap ada di sini (http://werkzeug.pocoo.org/docs/0.14/utils/)
#3: Membuat class dan object User. Karena ini percobaan saja jadi mungkin buat simplenya seperti ini. Kedepan mungkin mesti dihubungkan dengan database
#4: Mengisi object dari class User. Hanya sample user saja untuk kebutuhan login nanti
#5: Dictionary user untuk mendapatkan username saat login
#6: Dictionary user untuk mendapatkan spesifik user
#7: Fungsi login untuk mendapatkan token
#8: Fungsi untuk mengetest apakah token bisa digunakan untuk mendapatkan resource/data yang diinginkan berdasarkan token tersebut.
#9: Secret Key, ini untuk mendefinisikan secretkey aplikasi kita. JWT perlu setting secretkey ini
#10: Membuat object JWT dengan fungsi callback yang sudah kita setting sebelumnya. Callback fungsi ini ada banyak tidak hanya 2, bisa dibaca di link Flask-JWTnya ya.
#11: Decorator untuk membatasi fungsi tidak bisa diakses kecuali dengan token yang valid
#12: Mereturnkan String dari Object User yang telah kita set di __str__

Penjelasannya gitu aja ya, sekarang kita coba jalankan dengan memanggil app.py tersebut di terminal kita.

python app.py

Yap, setelah itu kita coba buka Postman lalu saya akses token terlebih dahulu seperti gambar dibawah ini.

Request Token Flask-JWT
Request Token Flask-JWT

Setelah saya “Send” akan muncul “access_token”: “xxxsdsdf”. Nah token ini yang kita pakai untuk mengetest apakah token ini bisa digunakan untuk mengakses fungsi protected. Berikut saya coba dan terlihat di gambar ini.

Test Token - Flask-JWT
Test Token – Flask-JWT

Terlihat pada gambar tersebut saya sisipkan Header dengan Authorization dengan pattern: “JWT” spasi Token yang didapat.

Alhasil, token bisa digunakan dan data user bisa didapat.

Sederhana ya, mungkin dilanjut ke bagian yang lebih tapi intinya sih flask-jwt ini bisa dipakai ya 🙂

Selamat mencoba..

Belajar Flask: Looping dengan template Jinja2

Flask menggunakan jinja2 untuk template engine view nya. Seperti blade, pada jinja2 pun ada handle untuk mengatur ketika terjadi looping berjalan pada view kita. Berikut adalah beberapa catatan mengenai looping dengan template jinja2. Continue reading Belajar Flask: Looping dengan template Jinja2

Belajar Flask: Menggunakan Logging dan Flask-Debugtoolbar

flask pythonSalah satu hal penting dari pekerjaan programmer adalah teknik menemukan bug/kesalahan. Ini adalah syarat wajib karena jika bekerja di dunia game development. Anda harus tahu persis kapan game tersebut nge-hang atau force-close. Pada Flask framework, logging sudah disediakan secara otomatis.

Untuk melakukan logging terhadap aplikasi flask kita. Anda cukup menuliskan kode seperti dibawah ini.

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')

Cukup mudah kan ya 🙂

Continue reading Belajar Flask: Menggunakan Logging dan Flask-Debugtoolbar

Belajar Python: Mengenal Flask, Web Framework Python

Flask adalah salah satu framework python yang mudah dipahami. Saya personal sudah mencoba Django. Namun karena mungkin belum familiar dengan sintax Python. Saya bingung opreknya. 🙂

Saya beralih ke Flask, karena community tidak jauh dengan Django. Lalu enaknya Flask ini step by step dari awal. Jadi ga langsung jadi. Soalnya kalo langsung jadi seperti Django, ya itu…bingung opreknya dari mana hehe..
Continue reading Belajar Python: Mengenal Flask, Web Framework Python