Pos Tagger dan Dependency Parser dengan StanfordNLP Python

Sebelumnya saya sudah buat tulisan tentang pos tagger & dependency parser Bahasa Indonesia dengan lib CRFTagger, UUParser dan Syntaxnet.  Hanya Syntaxnet yang menyediakan pretrained model. Saat ini ada satu lagi library yang menyediakan pretrained model untuk Bahasa Indonesia: StanfordNLP (https://github.com/stanfordnlp/stanfordnlp).

StanfordNLP sudah ada cukup lama, tapi awalnya menggunakan Java dan lisensinya GPL (kita perlu bayar lisensi terpisah jika buat sistem yang tidak open source).  Sejalan dengan dominasi Python dan lisensi yang lebih longgar seperti MIT dan Apache, maka dikembangkan lib baru, dan StanfordNLP yang lama diubah namanya menjadi CoreNLP.

StanfordNLP  ini sudah native python (bisa diinstall dengan pip install stanfordnlp),  menggunakan deep learning (pytorch) dan sudah menyediakan pretrained model untuk bahasa Indonesia.

Saat saya coba, ternyata lib ini memerlukan Python 3.6 dan 3.7.   Saya install saja versi yang terakhir, yaitu versi  3.7.2, sayangnya untuk versi ini Python harus dicompile manual. Langkah-langkahnya saya tiru dari: https://tecadmin.net/install-python-3-7-on-ubuntu-linuxmint/  tapi dengan modifikasi sedikit karena di artikel itu kurang dua library yaitu libffi dan liblzma (saya menggunakan Ubuntu 16).

sudo apt-get install build-essential checkinstall
sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
    libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev liblzma-dev
cd /usr/src
sudo wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
sudo tar xzf Python-3.7.2.tgz
cd Python-3.7.2
sudo ./configure --enable-optimizations
sudo make altinstall

Catatan: interpreter hasil compile  disimpan di /usr/local/bin/python3.7

Update Juni 19: Untuk Windows dengan Anaconda, masalahnya ada di instalasi torch (saya menggunakan PyCharm). Buka conda prompt, aktifkan virtual env target, pergi  ke website  Pytorch untuk dapat instruksi instalasi.

Setelah pip install stanfordnlp, kode berikut adalah contoh penggunaannya. HATI-HATI, perlu satu jam untuk menjalankan kode ini, entah karena harus menggunakan GPU atau ada optimasi yang belum saya lakukan. Update: running berikutnya hanya perlu 1-2 menit, tetap lebih lama dibandingkan lib lain.

import stanfordnlp
stanfordnlp.download('id')   # download 1.4GB model
nlp = stanfordnlp.Pipeline(lang="id",use_gpu=False)
doc = nlp("Budi makan nasi enak sekali.")
print("token:")
doc.sentences[0].print_tokens()
print("dependency parse:")
doc.sentences[0].print_dependencies()

Hasilnya adalah sebagai berikut:


token:
Token index=1;words=[Word index=1;text=budi;lemma=budi;upos=NOUN;xpos=NSD;feats=Number=Sing;governor=2;dependency_relation=nsubj]
Token index=2;words=[Word index=2;text=makan;lemma=makan;upos=VERB;xpos=VSA;feats=Number=Sing|Voice=Act;governor=0;dependency_relation=root]
Token index=3;words=[Word index=3;text=nasi;lemma=nasi;upos=NOUN;xpos=NSD;feats=Number=Sing;governor=2;dependency_relation=obj]
Token index=4;words=[Word index=4;text=enak;lemma=enak;upos=ADJ;xpos=ASP;feats=Degree=Pos|Number=Sing;governor=3;dependency_relation=amod]
Token index=5;words=[Word index=5;text=sekali;lemma=sekali;upos=ADV;xpos=D--;feats=_;governor=2;dependency_relation=punct]

dependency parse:
('Budi', '2', 'nsubj')
('makan', '0', 'root')
('nasi', '2', 'obj')
('enak', '3', 'amod')
('sekali', '4','advmod')
('.', '2', 'punct') 

Iklan

Belajar Investasi Saham

Update Feb 2019:
Tiga bulan saya sudah mulai masuk pasar saham. Saya menggunakan dollar cost averaging, jadi tiap awal bulan ada jumlah fix yang bisa digunakan untuk membeli saham. Tapi saya belanjakannya tidak dipaksakan satu hari tertentu, bisa 1-2 minggu menunggu saat yang tepat. Sangat bagus mulai dari jumlah kecil untuk belajar,  karena ternyata lumayan tegang saat harga saham naik turun. Padahal idealnya kinerja itu diukur 1-2 tahun setelah saham dibeli, tidak perlu cek harga tiap hari.  Lalu saat salah analisis (karena belum tahu) dan keburu beli, ada keinginan kuat untuk menjual. Jumlah investasi kecil membantu untuk lebih menenangkan hati. Nanti saat sudah terbiasa, jumlahnya bisa dinaikkan.

Saya bergabung dengan beberapa group telegram untuk mengetahui dinamika para pemain pasar saham.  Rekomendasi saham dari group justru saya jauhi. Logikanya kalau saya jadi admin group itu, urutan aksi saya adalah: saya beli saat murah,   umumkan di group berbayar baru terakhir umumkan di group gratis. Ini akan berakibat saham naik.  Lalu admin akan jual untuk ambil keuntungan.   Jadi sudah terlambat kalau kita ikuti rekomendasi group. Lagipula umumnya  fundamental saham yang direkomendasi memang tidak terlalu bagus. Sama dengan rekomendasi para “analis” di media , banyak rekomendasi ajaib, sudah jelek fundamentalnya, mahal pula.

Saham yang saya hindari (masalah personal saja, tiap orang punya selera dan prinsip berbeda):

  1. BUMN. Walaupun sering mendapat perlakuan khusus dari pemerintah sehingga bisa menguasai pasar, tapi akibatnya sering tidak efisien, beresiko korupsi, dan tidak berhati-hati (misal urusan hutang). Masalah lain: pemerintah juga dapat ikut campur urusan internal perusahaan dan eksekutif sulit ambil resiko bisnis karena takut dipidana.
  2. Finansial, selain riba, saya juga tidak paham proses bisnisnya. Jadi walaupun bank syariah tetap saya hindari.
  3. Rumah sakit, rokok dan minuman keras.

END update

—-

Update Jan 2019:
Perlu berhati-hati, terlepas sentimen negatif dan prediksi kuat terjadinya resesi 2019-2020, pasar saham Indonesia sepertinya tidak terpengaruh. Investor (retail) kita sepertinya masih bersemangat sekali. Ini justru yang buat saya khawatir.  Sekarang sulit cari saham yang  bagus (bagi saya) tapi dengan harga yang murah. Lebih baik jangan dipaksakan beli.
–end update–

———

Posting yang agak berbeda dengan biasa 🙂  tapi sebenarnya nanti berhubungan juga dengan NLP dan  machine learning.  Posting ini akan diupdate sejalan dengan perjalanan saya belajar tentang investasi di pasar saham, jadi mungkin posting ini nantinya akan sangat panjang.  Posting ini adalah sudut pandang saya yang awam.

Saya sudah lama tertarik untuk berinvestasi di pasar saham, tapi baru bisa mulai sekarang. Masalahnya, investasi saham walaupun dapat menghasilkan return tinggi, tetapi resikonya juga tinggi. Dalam kasus terburuk uang bisa berkurang atau bahkan hilang.  Itu sebabnya uang untuk investasi saham menunggu  antrian yang urutannya sebagai berikut: tabungan, dana pendidikan anak, deposito syariah, dana pensiun (diluar taspen PNS), investasi yang relatif aman baru terakhir saham. Ini yang saya lihat sering dilupakan orang, saya pernah baca pertanyaan  “Saya punya banyak hutang, saya tertarik bermain saham, bagaimana caranya?”, gawat kalau seperti itu.

Tadinya saya berminat untuk memulai dari reksadana dulu, tetapi melihat fee yang lumayan lalu banyak analis  yang rekomendasinya aneh, sepertinya lebih baik saya pilih sendiri saham yang mau saya koleksi. Rugi atau untung semua tanggung jawab saya 🙂

Banyak yang bingung mulai dari mana? untuk langkah pertama menurut saya adalah membaca sebanyak mungkin informasi. Hati-hati banyak informasi di internet, khususnya video Youtube yang hanya menyampaikan bahwa   investasi saham itu bisa untung besar tapi tidak  membahas kemungkinan rugi (yang bisa besar juga) dan tidak membahas bahwa tingkat kesulitannya cukup tinggi.  Banyak yang terlalu menyederhanakan seperti “Beli saham bluechip saja!”.

Mendapatkan keuntungan dari saham itu  bisa dengan dua cara: harga sahamnya naik (contoh beli 100/share lalu sebulan kemudian menjadi 300/share) dan melalui dividen (bagi hasil keuntungan perusahaan). Masalah utamanya adalah memilih saham yang mana dan kapan.

Saya lihat ada dua pendekatan: pendekatan pertama adalah berdagang saham jangka pendek.   Saat melihat potensi harga  naik, maka saham akan dibeli dan pada saat titik yang dianggap menguntungkan maka saham tersebut dijual, untung dapat diperoleh dari selisihnya. Ini bisa berlangsung dalam hitungan jam atau hari. Pendekatan ini mirip berselancar (mengikuti harga yang naik). Masalahnya sama dengan berselancar, salah pemilihan waktu sedikit saja, maka akan kehilangan ombak. Informasi yang digunakan umumnya hanya sejarah harga saham dan volume penjualan. Teknik yang perlu dipelajari untuk pendekatan ini disebut analisis teknikal.

Pendekatan kedua adalah jangka panjang (6 bulan sampai tahunan).  Pada pendekatan ini perlu dicari perusahaan yang bagus tapi sahamnya relatif dihargai murah. Saham milik perusahaan yang fundamentalnya bagus, walaupun saat ini dihargai murah,  nantinya akan naik juga dan kenaikannya bisa besar (berkali-kali lipat) sejalan dengan semakin besarnya perusahaan. Keuntungan juga bisa didapat dari dividen.  Masalahnya bagaimana menentukan perusahaan ini bagus? jangan-jangan murah karena memang mau bangkrut.  Informasi yang digunakan mulai dari laporan keuangan (tahunan, triwulan), analisis kemampuan manajemen, analisis sektor yang terkait dan sebagainya.  Pendekatan ini disebut value investing dan teknik yang perlu dipelajari adalah analisis fundamental.

Di Indonesia, yang saya lihat mayoritas yang digunakan adalah pendekatan pertama (trading).  Menurut saya karena alasan berikut:  1) lebih sederhana karena variabel yang digunakan lebih sedikit dan kuantitatif.  2) Perusahaan sekuritas mendapat fee jika ada transaksi, jadi mereka mendorong pelanggan melakukan transaksi sebanyak-banyaknya 3) lebih seru, seperti menonton film aksi atau balapan, ada keasyikan sendiri menyaksikan harga naik (atau turun) menit demi menit sebelum memutuskan beli atau jual. Walaupun saat ini sudah ada  mekanisme otomatis beli dan jual berdasarkan kriteria tertentu, tetapi tetap saja seru.

Saya pribadi lebih suka pendekatan kedua (value investing), karena tujuannya memang untuk jangka panjang (20 tahunan). Saya suka membaca, mencari dan menganalisis data dan  informasi. Wajar karena berkecimpung di bidang machine learning dan datamining 🙂 Membaca laporan tahunan adalah kegiatan menarik bagi saya. Saya juga tidak terlalu suka lagi nonton pertandingan dan bermain game (mungkin faktor umur?) jadi memonitor pergerakan harga saham jam demi jam (apalagi menit demi menit) bukan lagi hal yang terlalu menyenangkan. Lebih baik waktunya digunakan untuk hal yang lain. Sebagai bonus, biaya transaksi untuk sekuritas juga akan lebih murah.

Menurut saya memilih pendekatan trading atau value investing (atau gabungan) tergantung dengan minat, bakat dan tujuan tiap individunya. Yang penting bekali diri dengan ilmu sebelum masuk.  Tanpa ilmu,  sama saja dengan judi.  Banyak yang malas belajar dan ingin jalan pintas: “Udah, pokoknya apa saham yang harus saya beli besok?”, “Saham X bagus nggak gan?”.  Kadang bergidik,   mau beli barang 500 ribu saja kita  harus pikir-pikir dan banding-bandingkan dulu,  ini  jutaan rupiah dipertaruhkan  seperti dengan lempar dadu saja.

Karena saya memilih value investing, tentu saya lebih mendalami materi-materi yang terkait analisis fundamental. Video tutorial yang bagus adalah: https://www.youtube.com/watch?v=KfDB9e_cO4k&list=PLECECA66C0CE68B1E

Untuk buku:

  1. “Stock Market Investing for Beginner”, Tycho Press.
  2.  Peter Lynch (ada tiga buku, dengan urutan baca “One Up On Wall Street”, “Learn to Earn”,  “Beating the Street”).  Kalau tidak sempat cukup baca yang “One Up On Wall Street” saja, dua yang lain hanya pelengkap. Peter Lynch ini menarik karena dia termasuk fund manager yang fokus pada pemilihan saham dan sukses (rata-rata return 29.2% per tahun selama 13 tahun). Tapi perlu hati-hati untuk mengikuti petunjuk dia. Gaya investasinya  lebih agresif dan dia kerja gila-gilaan (mulai dari jam 6 pagi sampai malam termasuk sabtu). Aktivitasnya termasuk mendatangi secara langsung atau menelepon calon emiten yang dia incar, jadi salah satu kunci keberhasilannya adalah punya informasi yang mendalam. Mungkin aktivitas seperti ini yang bisa diganti dengan datamining? Saya paling hanya googling saja untuk informasi, tapi untuk sampai menelepon apalagi mendatangi perusahaan ya berat.
  3. “The Intelligent Investor”, Graham. Ini yang paling berat, sebaiknya dibaca terakhir.
  4. Update Jan 2019. Karena tertarik dengan video Youtubenya, saya beli buku Phil Town (Rule #1). Buku ini lebih pragmatis dengan aturan yang lebih jelas. Tapi perlu hati-hati karena  Phill Town sendiri tidak memperlihatkan kinerja portofolionya. Saya lebih cocok dengan Lynch yang lebih fleksibel, tapi ada beberapa hal yang bermanfaat juga. Intinya aturan dari buku ini: hanya beli saham dengan kondisi: 1) ROIC >10% (kenapa bukan ROE ya?)  2) Equity growth >10%  3) EPS growth >10%   4) Sales growth >10%   5) Free cashflow >10%.  Setelah itu hitung nilai intrinsik saham dengan cara hitung nilai 10 tahun ke depan berdasarkan PER, EPS growth, mundurkan ke harga saat ini berdasarkan target pertumbuhan 15% (Indonesia mungkin  harus lebih tinggi),  ini yang jadi harga intrinsik.  Lalu hanya beli yang harganya 50% dari harga intrinsik (margin of safety).

Perlu juga baca yang terkait pasar Indonesia, sayang judulnya agak  berlebihan:

  1. “Value Investing beat the market in 5 minutes”, Teguh Hidayat.  Lebih untuk pengantar, menggunakan bahasa non formal, cocok untuk orang muda.
  2. “Investasi Saham ala Fundamentalis Dunia”, Ryan Filbert, William Prasetya. Sisi dasar-dasar akuntasi, untuk membaca laporan keuangan.

Lumayan capek ya 🙂  Tapi saat investasi kita bisa hilang jadi nol rupiah menurut saya wajar perlu persiapan ekstra, itupun tetap tidak menjamin, tapi setidaknya jauh mengurangi resiko.

Selanjutnya bisa dimulai melihat-lihat laporan keuangan perusahaan incaran. Semua laporan emiten bisa dilihat di: https://www.idx.co.id/perusahaan-tercatat/laporan-keuangan-dan-tahunan/   Bisa juga mencari saham yang sesuai kritera yang diinginkan melalui stock screener: https://www.indopremier.com/ipotgo/marketanalysis.php?page=stockscreener

Untuk informasi tentang saham, berikut dua situs bagus dan ada app Android-nya juga:

  1. www.indopremier.com/ipotgo   Tapi hati-hati, tidak memperhitungkan stock split (contoh EPS ULTJ yang terlihat jadi drop drastis dari 16-17).
  2. rti.co.id (klik free trial)

Setelah punya gambaran saham yang mau dibeli, pilihan ini dapat diujicoba (disimulasikan) secara virtual pada situs stockbit.com sekalian belajar mekanisme beli-jual. Selanjutnya kita sudah siap untuk terjun membeli saham sesungguhnya.

Memilih dan Mendaftar pada Perusahaan Sekuritas

Transaksi saham harus dilakukan melalui perusahaan sekuritas sebagai perantara.  Mereka mendapat fee setiap transaksi  (untuk BNI sekuritas, fee-nya adalah 0.15% untuk beli dan 0.25% untuk jual). Ada banyak perusahaan sekuritas, tapi karena saya sudah punya rekening BNI dan ingin perusahaan sekuritas yang masih ada sampai 20 tahun lagi maka saya memilih BNI Sekuritas. Saya tanya-tanya via Twitter cepat dijawab (marketing), tapi untuk yang teknis, harus tanya via WA, dan responnya lambat (bisa 1jam) plus kurang ramah. Tapi yang penting dijawab sih bagi saya.

Saya buka rekening syariah, proses pendaftarannya: kita ke situs BNI sekuritas, isi berbagai formulir,  download formulir, print, beri paraf, beri materai, tandatangan lalu kirimkan via pos. Tunggu sampai 5 hari kerja. Total waktu yang diperlukan kira-kira 2 minggu. Nanti otomatis akan dibuatkan dua  RDI (Rekening Dana Investasi),  satu untuk syariah, satunya untuk yang biasa. Rekening ini yang digunakan untuk menampung dana untuk membeli, menjual atau dividen saham. Tidak ada info rekening syariah yang mana, tapi saran saya isi saja dua rekening itu masing-masing dengan 1 jt (nilai minimum). Walaupun punya dana banyak, sebaiknya mulai dari kecil dulu.

Ternyata yang disebut rekening syariah itu hanya sekedar membatasi saham apa yang bisa dibeli (misal saham bank, saham minuman keras tidak boleh dibeli). Jadi rekening yang non syariah saya gunakan juga,  yang penting jangan beli saham non syariah.  Bisa saja satu rekening untuk investasi jangka pendek satunya untuk jangka panjang. Setelah digunakan tidak perlu ada uang mengendap pada  rekening itu (semuanya bisa dibelikan saham). Saat membeli, nanti akan ada isian rekening mana yang akan digunakan, yang syariah ujungnya ada “S”.  Nanti akan dapat email dari sekuritas dan kita bisa tahu rekening syariah yang mana.

Kita juga akan diberikan user dan password untuk masuk ke aplikasi trading milik BNI (esmart) dan pin untuk bertransaksi. Saya tidak terlalu peduli dengan fitur-fitur trading, biasanya saya hanya buka sebentar dan langsung beli dengan harga yang ada.  Setelah transaksi, tidak otomatis uang di rekening didebet, ini dilakukan dua hari kemudian. Santai saja, BNI sekuritas akan mengirimkan email tentang transaksi, dividen dsb.

Selanjutnya tinggal memonitor fundamental emiten yang sahamnya kita miliki atau calon yang menarik untuk dikoleksi. Selama fundamentalnya bagus, saham jangan dijual. Perlu pembahasan terpisah untuk itu, dan saya masih belajar 🙂

Mengenai penerapan machine learning khususnya NLP pada pasar saham: saya belum mendalami, tapi umumnya ditujukan untuk fast trading (misalnya saat ada berita negatif tentang sektor X, maka semua saham terkait X dijual dalam waktu sekian milidetik). Istilah yang digunakan adalah algorithmic trading dan orang yang membuat algo-nya disebut  quant.  Salah satu tutorial  tentang algo trading ini dapat dilihat di https://www.youtube.com/watch?v=GlV_QO5B2eU  Sayangnya untuk pasar saham Indonesia sepertinya belum ada platform untuk backtest.

Pemanfaatan NLP untuk analisis fundamental sudah ada, tapi sepertinya tidak terlalu banyak.  Saya pernah baca paper yang memproses  laporan tahunan untuk memprediksi kinerja emiten. Menarik, karena memang setelah saya baca laporan tahunan,  dapat dilihat dirut yang isi tulisannya hanya normatif biasa-biasa saja, tapi ada juga yang kelihatan menguasai bidangnya dan bersemangat.  Bagusnya semua laporan tahunan ada versi bahasa Inggris-nya, jadi kita bisa menggunakan resources bahasa Inggris.  Mungkin ini yang paling dekat yang akan saya coba.

Memberikan Pelatihan Machine Learning & NLP

Dalam 4 bulan terakhir ini kami (saya dan istri) memberikan pelatihan machine learning untuk calon data analisis PT Pos dan NLP+Deep learning untuk sebuah perusahaan software.  Saya suka karena hal ini menjadi kesempatan untuk berdiskusi dengan pihak industri tentang apa yang mereka perlukan dari lulusan, dan bisa digunakan untuk memperbaiki proses pendidikan di kampus.

Di kampus saya mengajar kuliah pilihan datamining dan NLP sedangkan Lia mengajar machine learning, jadi dari sisi materi sebenarnya tidak terlalu masalah. Masalah utama adalah bagaimana memadatkan materi yang belasan SKS menjadi hanya beberapa hari saja.

Selection_181

Berdasarkan evaluasi saat pelatihan, menurut saya bentuk pelatihan ideal untuk machine learning  adalah:

  • Perlu profil rinci peserta pelatihan. Latar belakang peserta akan sangat berpengaruh, misalnya banyak calon data analis latar belakangnya adalah dari prodi Matematika atau Statistika.
  • Secara rinci perlu dibuat dan disepakati kompetensi yang ingin didapat, seperti “Peserta memahami X”, “Peserta dapat melakukan Y” dst.  Perlu disesuakan dengan jumlah jam pelatihan. Jangan terlalu memaksakan terlalu banyak materi jika waktunya terbatas.
  • Proporsi teori dan praktek sekitar 40:60 atau 50:50.  Mengapa teori mendapat porsi yang cukup besar? karena  saat ini sudah banyak tutorial dan lib untuk machine learning tetapi tanpa pembahasan konsep yang cukup, misalnya seputar rancangan eksperimen, evaluasi model.
  • Pretest – Posttest. Mengukur sejauh mana peningkatkan pengetahuan peserta.
  • Tugas berbentuk kasus yang dikerjakan berkelompok. Idealnya minimal ada dua sesi pelatihan dengan waktu yang terpisah sekitar 1-2 minggu. Di akhir sesi  ada   PR berbentuk analisis kasus yang setelah diolah harus dipresentasikan pada sesi berikutnya.
  • Evaluasi berbentuk ujian teori dan praktek dalam bentuk kasus.

Memang tahapan seperti test dan presentasi akan memerlukan waktu lama,  padahal seringkali  pelatihan  dirancang memberikan materi sebanyak-banyaknya dalam  waktu sesingkat-singkatnya. Tapi menurut saya kalau mau hasil optimal memang perlu  waktu yang cukup.

Web App (frontend) dengan Python

Saya membantu penelitian dosen prodi lain dan karena programmernya menghilang, saya diminta untuk jadi programmer pengganti. Aplikasi yang dibuat adalah aplikasi web tetapi banyak menggunakan javascript untuk user interfacenya.

Posting ini untuk catatan pribadi  sebagai template pengembangan web app (karena saya gampang lupa). Setiap orang punya preferensi masing-masing dan perlu disesuaikan dengan kondisi yang ada. Saya pilih Python+Flask karena hanya saya programmernya dan bisa memilih tools dengan bebas 🙂  Sempat lihat-lihat framework  seperti react, vue, angular tapi saya sendiri tidak terlalu suka dengan bahasa Javascript. Saya tetap gunakan Javascript, tetapi hanya untuk user interface saja.  Ada juga framework seperti Django, tetapi menurut saya terlalu berlebihan untuk proyek kecil yang  dikerjakan satu orang.   Sebelumnya saya sudah membahas tentang Flask, tapi dengan docker bisa dipermudah.

Saya menggunakan PyCharm Profesional karena Pycharm Community tidak dapat mengedit css dan javascript (dianggap sebagai teks biasa). Untungnya ada versi pro gratis untuk dosen yang punya email .edu.

Pertama yang perlu dilakukan adalah install Flask.  Siapkan struktur direktori: /app, /app/static/img, app/static/node_modules, /app/templates. Buat program utama di: /app/main.py

Template dasarnya seperti ini:

import requests
from flask import Flask, session
from flask import render_template
from flask import request

app = Flask(__name__)
app.secret_key = "x"

@app.route("/", methods=['GET', 'POST'])
def beranda():
    return render_template('index.html')

if __name__ == "__main__":
    # Only for debugging while developing
    # operasional
    app.run(host='0.0.0.0', debug=False, port=80)

    # debug
    #app.run(host='0.0.0.0', debug=True, port=8080)

Untuk mengelola lib javascript, gunakan NPM.  Masuk ke directory app/static, gunakan npm init  lalu npm install lib yang diperlukan. Tadinya saya kira NPM itu seperti pip-nya Python, defaultnya global, ternyata lokal.

Di html, untuk memanggil javascript gunakan url_for seperti ini (ganti img dengan script, karena WordPress ternyata memblok tag script):

//ganti dengan img dengan script karena wordpress tdk mengijinkan
<img src="{{ url_for('static', filename='node_modules/file-js-nya')}}" /> 

Demikian juga dengan image dan css :

<img src="{{ url_for('static', filename='img/gambar.png')}}" />

Untuk deploy, buat Dockerfile yang sejajar dengan /app (bukan di dalam).

FROM tiangolo/uwsgi-nginx-flask:python3.6
RUN pip install requests
COPY ./app /app
EXPOSE 80

Coba dulu di lokal (jangan lupa titik saat docker build):

docker build -t nama-app .
docker run -p 80:80 nama-app

Untuk stop bisa dengan ctrl-c, atau:

docker ps
docker stop container [id-container]

Untuk deploy, push ke gitlab (di Pycharm gunakan plugin gitlab project, posting saya tentang ini).

Di server, jika pertama kali, gunakan git clone  (siapkan sebelumnya ssh key untuk gitlab). Selanjutnya untuk update gunakan git pull. Lakukan docker build dan docker run.

Untuk koneksi ke database, saya belum memutuskan apakah digabung saja dengan frontend ini, atau dipisahkan jadi web service. Tapi mungkin akan saya pisahkan untuk jaga-jaga jika mau dibuat versi mobile app-nya, sekalian lebih mendalami model web API.

 

Chrome Remote Desktop di Ubuntu 16

Ini berawal dari account TeamViewer saya yang diblokir karena dianggap untuk komersial. Sebenarnya untuk riset, tapi memang saya gunakan untuk mengendalikan sampai 4 PC, jadi ya wajar juga jika dicurigai 🙂

Beberapa alternatif opensource sulit untuk digunakan karena PC harus bisa diakses langsung atau harus memodifikasi router, padahal PC di kampus ditutup akses portnya.  Saya lihat Chrome Remote Dekstop (CRD) jadi alternatif yang menarik. Untuk me-remote Windows dengan CRD  lancar.  Masalah muncul saat saya gunakan pada Ubuntu 16. Layar memang muncul tapi hanya wallpaper saja.  Terminal masih bisa diakses melalui menu klik kanan. Tapi semua window tidak bisa digeser dan diresize! Ternyata berbeda dengan TeamViewer yang prinsipnya screen mirroring, di Ubuntu, CRD menggunakan virtual session. Dari yang saya baca, ada bug untuk session Unity yang diakses secara remote karena masalah 3D accelerator(?).

Googling, dapat solusi dari https://productforums.google.com/forum/#!msg/chrome/LJgIh-IJ9Lk/tj-SBgEd85wJ   Prinsipnya CRD dimodifikasi agar tidak membuat session baru, tetapi menggunakan session yang sudah ada. Solusi ini berhasil, dan saat dijalankan, maka layar host jadi gelap saat PC diakses remote.   Masalahnya, saat koneksi terputus, maka layar host akan tetap gelap dan reconnect pun gagal 😦  Googling tapi tidak menemukan solusi lain. Aneh ya, itu sebabnya saya buat posting blog ini.

Setelah saya lihat-lihat code di /opt/google/chrome-remote-desktop/chrome-remote-desktop (jangan lupa backup), di Ubuntu, desktop display manager yang digunakan adalah  /usr/sbin/lightdm-session. Secara default Ubuntu 16 menjalankan gnome-session –session=ubuntu dan ini yang menjadi sumber masalah. Sebenarnya ada code yang akan memilih gnome-session –session=ubuntu-2d jika tersedia di OS untuk menghindari bug akibat 3D accelerator. Masalahnya di Ubuntu 16, sudah tidak ada lagi gnome ubuntu-2d (hanya ada di Ubuntu 12). Saat saya coba install, sudah tidak ada dan tidak disupport.  Solusinya saya install gnome-session-flashback:

sudo apt-get update
sudo apt-get install gnome-session-flashback

Stop dulu service chrome desktop:

/opt/google/chrome-remote-desktop/chrome-remote-desktop --stop

Lalu  sudo edit (jangan lupa  backup): /opt/google/chrome-remote-desktop/chrome-remote-desktop . Saya akan update bagian yang tadinya menggunakan ubuntu-2D. Edit  bagian ini  (cari dengan kata kunci “2d”):

  SESSION_WRAPPERS = [
    "/usr/sbin/lightdm-session",
    "/etc/gdm/Xsession",
    "/etc/X11/Xsession" ]
  for session_wrapper in SESSION_WRAPPERS:
    if os.path.exists(session_wrapper):
      #yw edit
      #if os.path.exists("/usr/bin/unity-2d-panel"):
        # On Ubuntu 12.04, the default session relies on 3D-accelerated
        # hardware. Trying to run this with a virtual X display produces
        # weird results on some systems (for example, upside-down and
        # corrupt displays).  So if the ubuntu-2d session is available,
        # choose it explicitly.
        return [session_wrapper, "/usr/lib/gnome-flashback/gnome-flashback-metacity"]
      #else:
        # Use the session wrapper by itself, and let the system choose a
        # session.
        #return [session_wrapper]
  return None

Intinya code akan menjalankan /usr/lib/gnome-flashback/gnome-flashback-metacity bukan gnome-session –session=ubuntu . Gunakan gnome metacity, bukan compiz karena metacity tidak menggunakan 3D accelerator.

Update Juli 2019: kalau ini diedit efeknya akan terjadi error. Biarkan saja seperti aslinya.

Lalu dibagian lain edit juga:

x_session = choose_x_session()
#  yw ganti
if (len(x_session) == 2 and
   x_session[1] == "/usr/lib/gnome-flashback/gnome-flashback-metacity"):
       extra_x_args.extend(["-extension", "Composite"])

Katanya ini untuk mengatasi bug di Ubuntu 2D metacity, jadi saya juga tambahkan untuk gnome-flashback-metacity ini (entah valid atau tidak hehe).

restart ulang:

 /opt/google/chrome-remote-desktop/chrome-remote-desktop --start

Coba jalankan secara remote dan semua bisa berjalan dengan baik, walaupun user interfacenya agak berbeda dengan Ubuntu standard 🙂 CRD bahkan lebih cepat daripada TeamViewer.

Catatan: jangan lupa catat pin, Google Remote Desktop tetap membutuhkan pin walaupun kita sudah login.

Eksplorasi Front-End

Setelah membuat model untuk task named entity, membuat model server, membuat web service maka selanjutnya adalah membuat web untuk mendemokan API yang dibuat.

Saya terakhir mengurusi front-end hampir 10 thn yang lalu untuk penelitian bersama pembimbing S2 saya. Waktu itu saya jadi belajar CSS dan Javascript. Saat lihat-lihat kondisi sekarang, wah sudah jauh berbeda. Ada berbagai macam framework: React, Angular, Vue.

Setelah saya eksplorasi, ternyata jauh berbeda dengan pendekatan lama.  Perlu belajar banyak. Masalahnya, framework juga bergeser dengan cepat. Bahkan untuk framework yang sama bisa mengalami perubahan besar (seperti Angular).  Kombinasi yang buruk terutama bagi saya yang punya waktu terbatas: perlu sumberdaya besar untuk belajar + gampang kadaluarsa ilmunya.

Akhirnya saya buat dengan cara lama saja, Python+Flask+Jinja2 +JQueryUI dan Bootstrap. Mungkin kalau benar-benar perlu serius, kami akan sewa orang lain saja 🙂

 

Web App dengan Python Flask, Nginx dan uwsgi.

Update April 2018:

Dengan Docker, proses persiapan dan deploy jauh lebih gampang. Tutorial/repo yang dapat digunakan: https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/

Walapun sempat mengerjakan beberapa proyek dengan PHP, pengalaman saya membuat web app dengan PHP ternyata tidak menyenangkan. Pernah coba menggunakan Java, tapi menurut saya terlalu rumit untuk web app. Sejalan dengan eksplorasi saya belajar Python untuk keperluan datamining, maka sekalian saja menggunakan Python untuk membuat applikasi web, baik frontend maupun untuk RestFul-API.

Di posting sebelumnya saya mencoba membuat sendiri dari nol, tapi ternyata rawan kesalahan. Setelah lihat-lihat beberapa framework, menurut saya yang paling menarik adalah Flask (http://flask.pocoo.org/).  Seperti biasa, saya share di blog ini untuk catatan pribadi dan mudah-mudahan bermanfaat bagi pemula seperti saya.

Saya menggunakan instance Ubuntu AWS  dengan client Windows+Putty.  Pertama siapkan port forwarding agar kita bisa mencoba app dengan aman via SSH.  Di Putty, pilih settings->connection-SSH-tunnels. Saya forward port 5000, jangan lupa klik add (gambar bawah). Simpan session supaya tidak perlu mengeset berulangkali.

tunnel

Pertamakali yang perlu dilakukan adalah install pip, tools untuk menginstall lib python.

sudo apt-get update
sudo apt-get install python-pip

Kemudian install nginx sebagai webserver

sudo apt-get install nginx

Pastikan port 80 sudah dibuka (kalau digital ocean dibuka, tapi kalau AWS defaultnya ditutup),  dan buka alamat server kita di browser, harusnya pesan bahwa nginx sudah terinstall akan keluar.

Selanjutnya kita akan menginstall virtual environment (virtualenv). Ini penting dan wajib karena memungkinkan kita menginstall lib Python untuk suatu proyek  yang terisolasi dengan proyek lainnya. Tanpa virtualenv, install lib bisa membuat proyek lain jadi tidak jalan (pengalaman pahit pribadi hehe).

sudo pip install virtualenv 

Selanjutnya buat directory project dan masuk.

mkdir myproject
cd myproject

Dalam direktori ini set virtual env dengan:

 virtualenv myproject-env 

untuk mengaktivasi virtual env ini, gunakan

source myproject-env/bin/activate 

perhatikan prompt akan berubah. Sekarang kalau kita jalankan pip, maka lib tersebut akan terinstall di virt env ini saja (myproject/myproject-env).  Tapi kalau installnya lewat apt-get tetap berlaku untuk semua.

Untuk mengetest, coba jalankan

 which python 

maka yang muncul adalah lokasi Python di myproject. Untuk menonaktifkan virt env ini,  ketik  deactivate (tapi jangan lakukan dulu sekarang).

Selanjutnya install Flask dan uwsgi. Flask untuk framework, sedangkan uwsgi untuk koneksi dengan nginx.

 pip install uwsgi flask 

Selanjutnya kita akan membuat code sederhana hello world.

from flask import Flask
from werkzeug.serving import run_simple
app = Flask(__name__)

@app.route("/")
def beranda():
     return "Hello World"

if __name__ == '__main__':
     run_simple('0.0.0.0', 5000, app, use_reloader=True, use_debugger=True, use_evalex=True)

Jalankan

 python myapp.py 

dan buka browser dengan alamat  http://localhost:5000/  maka di browser akan muncul “Hello World” (jika menggunakan putty, pastikan tunneling sudah benar).  Jika code diupdate maka otomatis akan dilakukan reload. Gampang kan 🙂

Inilah kelebihan Flask, sangat mudah untuk dijalankan dan didebug.  Tapi tentu jika sudah operasional cara seperti ini tidak cocok. Sekarang kita akan menghubungkan app ini dengan web server nginx melalui uwsgi.

Pertama buat konfigurasi wsgi dulu, buat file uwsgi-myproject.ini dengan isi sebagai berikut:

Catatan: Sesuaikan path lokasi project di variabel home. Pastikan nama directory virtenv sudah cocok.

[uwsgi]
home = /home/ubuntu/myproject
wsgi-file = %(home)/myapp.py
socket = 127.0.0.1:3033
callable = app
module = app
daemonize = %(home)/app.log
pidfile = %(home)/app.pid
virtualenv= %(home)/myproject-env

Sekarang kita perlu update nginx agar mendengarkan socket uwsgi.  Buka /etc/nginx/nginx.conf   (mungkin perlu sudo) lalu pada bagian  ” http { ” tambahkan konfigurasi server berikut:

http {
  ##
  # Basic Settings
  ##
  ...
  server {
    listen 80;
    location / { include uwsgi_params; uwsgi_pass 127.0.0.1:3033; }
  }
}

Selanjutnya hapus page default nginx dan restart nginx.

sudo rm -v /etc/nginx/sites-enabled/default
sudo service nginx restart

Sekarang jalankan uwsgi project kita dengan cara

 uwsgi uwsgi-myproject.ini 

Sekarang buka di browser alamat server anda (bukan localhost:5000), yang tadinya ucapan default dari nginx harusnya akan berubah menjadi “Hello world” . Jika tidak, coba lihat catatan error di di file app.log (tail -10 app.log)

Untuk men-stop uwsgi, lakukan dengan (hati-hati, parameternya adalah app.pid bukan file uwsgi.ini):

 uwsgi --stop app.pid 

Tips: jika di-log keluar pesan seperti ini: “probably another instance of uWSGI is running on the same address”. Reset port dengan

 sudo fuser -k 3033/tcp 

Untuk mengaktifkan autoreload gunakan:

 uwsgi --py-autoreload 1