การสร้าง RESTful API สำหรับใช้งานจริง ง่าย ๆ ด้วย Flask และ Waitress

จาก From LAB to Production – จาก Machine Learning Model สู่ Flask RESTful ซึ่งได้นำ Machine Learning แบบ Statistical Approach อย่าง Logistic Regression ที่สร้างโมเดล และ Train กับข้อมูลเรียบร้อยแล้ว (บนเครื่อง Development) จากนั้น ได้นำโมเดลออกมาใช้งาน โดยใช้ วิธีการ Serialization ด้วย joblib ในภาษา Python ได้เป็นไฟล์ออกมา แล้วจึงนำไปใช้เพื่อใช้ในการทำนาย (predict) ชนิดของดอก Iris บนเครื่อง Production โดยรับ Input จากผู้ใช้ผ่าน HTTP Protocol ทั้ง GET/POST ที่ TCP/5000 ตัวอย่างดังกล่าว ยังเป็นเพียงการ “ทดสอบ” แต่ในบทความนี้ จะเป็นวิธีการ ซึ่งนำไปสู่การใช้งานจริง ๆ ซึ่ง Flask แนะนำให้ใช้งานกับ “waitress” (น่าจะเลียนแบบจาก Server) ซึ่งเป็น WSGI (Web Server Gateway Interface) อีกตัวหนึ่ง ใช้งานง่าย เพราะไม่ต้องติดตั้ง Apache/Nginx เลย ติดตั้ง waitress predict.py from flask import Flask, request, jsonify from flask_restful import Resource, Api, reqparse from flask_cors import CORS app = Flask(__name__) # Enable CORS CORS(app) @app.route(“/predict”, methods=[“POST”]) def predict(): result = 0 if request.method == “POST”: input_value = request.form[“input_value”] # ประมวลผล # … # ตัวอย่างเช่น รับค่ามา แล้ว คูณ 2 result=input_value * 2 # ### return jsonify( prediction=result ),201 ไฟล์ predict.py เป็นตัวอย่าง python ซึ่งรับค่า input_value จาก HTML form ผ่าน POST method เข้ามา ที่ /predict ซึ่งเขียนด้วย Flask ที่จะไปเรียกใช้ฟังก์ชั่น prediction() แล้วก็ทำการคำนวณที่ต้องการ จากนั้น ตอบค่ากลับไปเป็น JSON ด้วยฟังก์ชั่น jsonify โดยสามารถกำหนด key ชื่อ prediction และ value เป็น result ที่คำนวณได้ และแจ้ง Response Code เป็น 201 waitress_server.py from waitress import serve import predict serve(predict.app, host=’0.0.0.0′, port=8080) ไฟล์ waitress_server.py ก็เพียงแค่ import serve จาก waitress ที่ติดตั้งไป และ import predict ซึ่งก็คือไฟล์ predict.py ข้างต้น (อยู่ในไดเรคทอรีเดียวกัน)

Read More »

Stencil : Styling

Shadow DOM Shadow DOM เป็น API ที่อยู่ใน browser ที่ให้ความสามารถในทำ DOM encapsulation และ style encapsulation โดย Shadow DOM จะแยก component ออกจากภายนอก ทำให้ไม่ต้องกังวลกับ scope ของ css หรือผลกระทบกับ component ภายนอก หรือ component ภายนอกจะกระทบกับ component ภายใน ใน Stencil ค่า default การใช้งาน Shadow DOM ใน web component ที่สร้างด้วย Stencil จะถูกปิดอยู่  หากต้องการเปิดใช้งาน Shadow DOM ใน web component ต้องกำหนดค่า shadow param ใน component decorator ดังตัวอย่างด้านล่างนี้ @Component({ tag: ‘shadow-component’, styleUrl: ‘shadow-component.scss’, shadow: true }) export class ShadowComponent { } สิ่งจำเป็นเมื่อเปิดใช้งาน Shadow DOM QuerySelector เมื่อต้องการ query element ที่อยู่ภายใน web component จะต้องใช้ this.el.shadowRoot.querySelector() เนื่องจาก DOM ภายใน web component อยู่ภายใน shadowRoot Global Styles จะต้องใช้ CSS custom properties css selector สำหรับ web component element คือ “:host”  selector โดยทั่วไป จะเก็บ styles ไว้ภายไต้ ชื่อ tag ของ component นั้น my-element { div { background: blue; } } ในกรณีของ Shadow DOM  อยู่ภายใต้ tag :host :host { div { background: blue; } } Scoped CSS สำหรับ browser ที่ไม่สนับสนุน Shadow DOM, web component ที่สร้างโดย Stencil จะกลับไปใช้ scoped CSS แทนที่จะ load Shadow DOM polyfill ที่มีขนาดใหญ่  Scoped CSS จะทำการกำหนดขอบเขต CSS ให้กับ element โดยอัตโนมัตตอน runtime CSS Variables CSS Variables เหมือนกับ Sass Variables แต่ต่างกันตรงที่ CSS Variables รวมอยู่ใน browser โดยที่ CSS Variables ให้ความสามารถในการกำหนด CSS properties ที่ใช้ได้ภายใน app  ตัวอย่างการใช้งานที่พบบ่อยคือ การกำหนดสี (color) ถ้ามีสีหลักที่ต้องการใช้ร่วมกันทั้ง app แทนที่จะกำหนดสีนั้นๆในแต่ละที่ที่ใช้งาน ก็จะสร้าง variable ขึ้นมาและใช้ variable นั้นในทุกๆที่ที่ต้องการ ซึ่งถ้าต้องการเปลี่ยนสี ก็สามารถเปลี่ยนที่ variable ที่เดียว การใช้งาน CSS Variables ใน Stencil สร้าง

Read More »

python #02 – ติดตั้ง Tensorflow และ Keras

ต่อจาก python #01 – ติดตั้ง jupyter notebook บน Windows ต่อไปเราจะใช้ Machine Learning Library “Tensorflow” และใช้ “Keras” ซึ่งเป็น High-level Neuron Network API ซึ่งจะไปเรียกใช้ Backend คือ Tensorflow อีกชั้นหนึ่ง จาก jupyter notebook ทำตามขั้นตอนต่อไปนี 1.  คำสั่งต่อไปนี้ เพื่อติดตั้ง Tensorflow 2.  คำสั่งต่อไปนี้ เพื่อติดตั้ง Keras จะได้ผลประมาณนี้ สร้าง Neural Network ด้วย Keras เริ่มจาก import ส่วนต่าง ๆ ได้แก่ Models และ Layers สมมุติเราจะสร้าง Model แบบนี้ เสร็จแล้วก็ต้อง compile ตั้งค่า Hyperparameters ต่าง ๆ ดู Summary ได้ผลประมาณนี้

Read More »

python #01 – ติดตั้ง jupyter notebook บน Windows

jupyter Notebook เป็น Open Source Web Application ให้เราสามารถเขียนภาษา python ได้ง่ายขึ้น สามารถ Share ได้ด้วย และยังสามารถใส่คำอธิบาย (Markdown) ได้ด้วย ติดตั้งลงในเครื่องส่วนตัวได้ ในบทความนี้ แสดงวิธีติดตั้งและใช้งานบน Microsoft Windows ดังนี้ 1. ขั้นแรก ต้องมี Python ก่อน (หมายเหตุ: ณ เวลานี้ 27/11/61 รุ่นล่าสุดคือ 3.7.1 แต่เนื่องจากจะแนะนำการใช้งาน Tensorflow, Keras จึงยังต้องเลือกใช้ Python 3.6.7) https://www.python.org/ftp/python/3.6.7/python-3.6.7.exe เมื่อติดตั้งแล้ว ควร Restart เครื่องสักหนึ่งครั้ง 2. ติดตั้ง pip ซึ่งใช้ในการติดตั้งเครื่องมือต่าง ๆเปิด Windows Console (กดปุ่ม Win + R) แล้วพิมพ์คำสั่ง cmdจากนั้น ใช้คำสั่งต่อไปนี้ 3. (Optional) ติดตั้ง virtualenv เพื่อให้สามารถจัดการ Virtual Environment ได้ง่ายขึ้น เพราะอาจจะต้องทำหลาย Project ซึ่งใช้รุ่นของ Package/Module ที่แตกต่างกันบนเครื่องเดียวกัน 4. ติดตั้ง jupyter notebook 5. เมื่อติดตั้งเสร็จแล้ว ก็ใช้คำสั่งต่อไปนี้ ระบบจะเปิด Web Browser มายัง http://localhost:8888 จากนั้น คลิกที่ปุ่ม New > Python3 จากนั้น เราก็จะสามารถใช้คำสั่ง Python ทั่ว ๆ ไปได้ นอกจากนี้ ยัง Save ได้ และสามารถส่งต่อให้ผู้อื่นใช้ได้ด้วย

Read More »

Stencil : JSX

Stencil component ใช้ JSX template syntax ในการกำหนดรูปแบบการแสดงผลที่จะถูก render ของ component  ซึ่งแต่ละ component จะมี render function ที่จะทำหน้าที่ return โครงสร้างของ component ที่จะเปลี่ยนเป็น DOM ตอน runtime เพื่อแสดงผลบนหน้าจอ class MyComponent { render() { return ( <div> <h1>Hello World</h1> <p>This is JSX!</p> </div> ); } } จาก class Mycomponent ด้านบน render function จะ return div element ที่ภายในประกอบไปด้วย h1 และ p Data Binding เมื่อ component ต้องการที่จะ render ข้อมูลที่มีการเปลี่ยนแปลง dynamic data ทำได้โดยการ bindind ข้อมูลนั้นๆ โดยใช้ {variable}  (ซึ่งจะใกล้เคียงกับ ES6 template ที่ใช้ ${variable}) render() { return ( <div>Hello {this.name}</div> ) } Conditionals เมื่อ component มีการแสดงผลที่ขึ้นอยู่กับเงื่อนไข สามารถใช้ JavaScript if/else statements ใน render function ดังเช่นตัวอย่างด้านล่างนี้ ถ้า this.name ไม่มีการกำหนดค่า จะแสดงผล “Hello, World” render() { if (this.name) { return ( <div>Hello {this.name}</div> ) } else { return ( <div>Hello, World</div> ) } } หรือ จะเขียนในรูปแบบ inline conditionals ก็ได้เช่นกัน render() { return ( <div> {this.name ? <p>Hello {this.name}</p> : <p>Hello World</p> } </div> ); } Loops ใน JSX สามารถใช้ array operators : map ในการทำงานแบบ loop  จากตัวอย่างด้านล่าง มี lists ของ todo object ใน this.Objects ซึ่ง map function ทำหน้าที่ loop ในแต่ละ todo object ใน this.Objects แล้วสร้าง new JSX sub tree และ add เข้าไปใน array ที่จะ return ออกจาก map function ซึ่งจะเพิ่มเข้าไปใน JSX tree ด้านนอกนั่นคือ div element render() { return ( <div> {this.todos.map((todo) => <div> <div>{todo.taskName}</div> <div>{todo.isCompleted}</div> </div> )}

Read More »