สรุปสั้น ๆ
จากตอนที่แล้วเราได้ทำการลองสร้างเว็บ Image Gallery ด้วย Flask ขึ้นมาแล้ว ในตอนนี้เรามาดูวิธีทำให้มันพร้อมใช้งานบน Production แบบไว ๆ กัน !!!
เขียนโดย
Sirasit Boonklang (Aeff)
Tech and Coding Consultant
บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 19 เมษายน 2566
สิ่งที่เราจะทำกันในบทความนี้
- สร้าง Azure Blob Storage account
- แก้ไขโค้ดสำหรับบันทึก / อ่านไฟล์จาก Azure Blob Storage
- สร้าง Azure App Service
- การตั้งค่า Environment Variables ใน Azure App Service
- การ Deploy เว็บแอปพลิเคชัน Flask ไปยัง Azure App Service
ขั้นตอนการทำเว็บ Image Gallery ด้วย Flask แบบง่าย ๆ : borntodev.com/2023/04/12/มาลองสร้างเว็บ-image-gallery
1. สร้าง Azure Blob Storage account
สำหรับเว็บของเราจะมีการเก็บไฟล์ที่เป็นรูปภาพด้วยนะครับดังนั้นตอนที่เว็บของเราออนไลน์ก็จะต้องมีพื้นที่เก็บไฟล์ที่เป็นออนไลน์ด้วย โดยเราจะใช้บริการ Azure Blob Storage ที่เป็นบริการสำหรับเก็บข้อมูลที่เป็น Unstructured data สามารถใช้เก็บไฟล์ต่าง ๆ ได้ไม่ว่าจะเป็นไฟล์รูป ไฟล์เสียง หรือไฟล์อื่น ๆ
1. สำหรับใครที่ต้องการลองทำตามโดยใช้ Subscription แบบทดลองฟรีก่อนสามารถใช้เป็น Microsoft Sandbox ก่อนได้นะครับ โดยไปที่ https://learn.microsoft.com/en-us/training/modules/host-a-web-app-with-azure-app-service/3-exercise-create-a-web-app-in-the-azure-portal?pivots=csharp (หากใช้ Subscription อื่นอยู่แล้วสามารถข้ามขั้นตอนนี้ไปได้เลยครับ)
2. หลังจากนั้นทำการกด Sign in to activate sanbox แล้วทำการ Login Azure Account แล้วตัว Sandbox จะถูก Activate โดยสามารถใช้ได้ครั้งละ 4 ชั่วโมง
4. แล้วมาที่ Resource groups ที่เรามีอยู่จะพบกับส่วนของ Storage account
5. เลือก Stroge browser > Blob containers ทำการกด + Add container โดย Blob containers จะเป็นเหมือนโฟลเดอร์หรือ Directory ใน file system โดยเราจะทำการตั้งชื่อ
6. โดยในโปรเจกต์นี้ผมจะตั้งชื่อว่า imagegallery และ Public access level จะเลือกเป็น Private (no anonymous access)
7. หลังจากนั้นเราก็จะได้ Blob containers ของเรามา
2. แก้ไขโค้ดสำหรับบันทึก / อ่านไฟล์จาก Azure Blob Storage
จากเดิมที่โค้ดของเรามีการอ่านและบันทึกไฟล์ลงใน Path ที่อยู่ในเครื่องของเรา เราต้องแก้ไขโค้ดให้สามารถอ่านและบันทึกไฟล์ไปยัง Azure Blob Storage ได้ โดยใช้ library ของ azure-storage-blob ซึ่งสามารถติดตั้งได้โดยใช้คำสั่ง
pip install azure-storage-blob
เพื่อเข้าถึงบริการ Azure Blob Storage ให้เราทำการสร้าง Connection String จาก Azure Portal โดยทำได้ตามขั้นตอนดังนี้
- เข้าไปที่ Storage account ที่เราได้สร้างไว้
- เลือก Access keys แล้วทำการคัดลอก Connection String ที่ต้องการใช้
โดยการไปเอา Connection String ของ Azure Blob Storage มีวิธีดังนี้
โดยการไปที่ Resource groups > Storage account > Access keys แล้วทำการคัดลอก Connection String ที่ต้องการใช้
เมื่อได้ Connection String แล้ว ให้เรานำมาใช้ในการเชื่อมต่อกับ Azure Blob Storage และแก้ไขโค้ดดังนี้
from flask import Flask, render_template, url_for
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
import os
from wtforms.validators import InputRequired
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET_KEY'
# Azure Blob Storage configuration
CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName={your_account_name};AccountKey={your_account_key};EndpointSuffix=core.windows.net"
CONTAINER_NAME = "imagegallery"
class UploadFileForm(FlaskForm):
file = FileField("File", validators=[InputRequired()])
submit = SubmitField("Upload File")
@app.route('/', methods=['GET', 'POST'])
def UploadFile2Web():
form = UploadFileForm()
if form.validate_on_submit():
# Save file to Azure Blob Storage
file = form.file.data
filename = secure_filename(file.filename)
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
blob_client = container_client.get_blob_client(filename)
blob_client.upload_blob(file)
# List files in Azure Blob Storage
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
image_files = [blob.name for blob in container_client.list_blobs()]
return render_template('index.html', form=form, image_files=image_files)
if __name__ == '__main__':
app.run(debug=True)
โดยโค้ดแต่ละส่วนมีการทำงานดังนี้
ส่วนการเรียกใช้งาน Lib ที่เกี่ยวข้อง
from flask import Flask, render_template, url_for
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
import os
from wtforms.validators import InputRequired
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
- from flask import Flask, render_template, url_for: เรียกใช้งาน Flask โมดูลสำหรับสร้างเว็บแอปพลิเคชัน Flask, render_template และ url_for เพื่อแสดงเทมเพลต HTML และสร้าง URL ตามลำดับ
- from flask_wtf import FlaskForm: เรียกใช้งานโมดูล FlaskForm เพื่อสร้างฟอร์มพร้อมฟิลด์สำหรับการเลือกไฟล์และการส่ง
- from wtforms import FileField, SubmitField: โมดูล FileField สร้างฟิลด์ที่อนุญาตให้ผู้ใช้เลือกไฟล์ ในขณะที่ SubmitField สร้างปุ่มเพื่อส่งแบบฟอร์ม
- from werkzeug.utils import secure_filename: ฟังก์ชัน secure_filename จากโมดูล werkzeug.utils ใช้เพื่อรับรองว่าชื่อไฟล์ของไฟล์ที่อัปโหลดนั้นปลอดภัยและไม่มีโค้ดที่เป็นอันตรายใดๆ
- import os: โมดูล os ใช้เพื่อตั้งค่าตัวแปรสภาพแวดล้อม
- from wtforms.validators import InputRequired: ตัวตรวจสอบความถูกต้อง InputRequired จากโมดูล wtforms.validators ใช้เพื่อให้แน่ใจว่าผู้ใช้อัปโหลดไฟล์ก่อนที่จะส่งแบบฟอร์ม
- from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient: โมดูล Azure.storage.blob ใช้เพื่อสร้างการเชื่อมต่อกับ Azure Blob Storage และอัปโหลดไฟล์ไปยังคอนเทนเนอร์ที่ระบุ โดยเฉพาะอย่างยิ่ง BlobServiceClient ใช้เพื่อสร้าง Client Object สำหรับบัญชี Blob Storage, BlobClient ใช้เพื่อสร้าง Client Object สำหรับ blob โดยเฉพาะ และ ContainerClient ใช้เพื่อสร้าง Client Object สำหรับคอนเทนเนอร์ที่จะจัดเก็บใน blob
app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET_KEY'
# Azure Blob Storage configuration
CONNECTION_STRING = "DefaultEndpointsProtocol=https;AccountName={your_account_name};AccountKey={your_account_key};EndpointSuffix=core.windows.net"
CONTAINER_NAME = "imagegallery"
- app = Flask(name): ที่ ส่วนในการสร้าง Flask Instance เริ่มต้น
- app.config[‘SECRET_KEY’] = ‘SECRET_KEY’ : แอตทริบิวต์ app.config เป็น dict ในการเก็บการ config ต่าง ๆ ของแอป จะตั้งค่าของตัวแปร config โดยใช้ SECRET_KEY เป็นสตริง ใช้เป็นคีย์ลับเพื่อเข้ารหัสคุกกี้และป้องกันการโจมตีต่างๆ เช่น การโจมตี CSRF
- CONNECTION_STRING = “” : ตัวแปร CONNECTION_STRING คือ Connection String ที่ใช้เชื่อมต่อกับบัญชี Azure Blob Storage ค่าของสตริงนี้รวมถึง AccountName, AccountKey, และ EndpointSuffix
- CONTAINER_NAME =””: คือ ชื่อคอนเทนเนอร์ในบัญชี Blob Storage ที่จะจัดเก็บไฟล์
@app.route('/', methods=['GET', 'POST'])
def UploadFile2Web():
form = UploadFileForm()
if form.validate_on_submit():
# Save file to Azure Blob Storage
file = form.file.data
filename = secure_filename(file.filename)
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
blob_client = container_client.get_blob_client(filename)
blob_client.upload_blob(file)
# List files in Azure Blob Storage
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
image_files = [blob.name for blob in container_client.list_blobs()]
return render_template('index.html', form=form, image_files=image_files)
- @app.route(‘/’, methods=[‘GET’, ‘POST’]): กำหนดให้เมื่อมี Request เข้ามาที่ Path Root ด้วย Methods GET กับ POST
- def UploadFile2Web(): ประกาศฟังก์ชันสำหรับอัปโหลดภาพไปยังเว็บโดยมีการทำงานดังนี้
- if form.validate_on_submit(): หากข้อมูลจากฟอร์มถูกส่งและผ่านการตรวจสอบโดยใช้ form.validate_on_submit() ฟังก์ชันจะดำเนินการอัปโหลดไฟล์ไปยังบัญชี Azure Blob Storage ที่ระบุในตัวแปร CONNECTION_STRING และ CONTAINER_NAME
- file = form.file.data: ขั้นแรกจะแตกไฟล์จากแบบฟอร์มโดยใช้ form.file.data
- filename = secure_filename(file.filename): จากนั้นสร้างชื่อไฟล์ที่ปลอดภัยโดยใช้ฟังก์ชัน secure_filename() จากโมดูล werkzeug.utils
- blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING): สร้าง BlobServiceClient โดยใช้เมธอด from_connection_string() และตัวแปร CONNECTION_STRING
- container_client = blob_service_client.get_container_client(CONTAINER_NAME): ตามด้วย ContainerClient โดยใช้เมธอด get_container_client() และตัวแปร CONTAINER_NAME
- image_files = [blob.name for blob in container_client.list_blobs()]: หลังจากอัปโหลดไฟล์หรือหากได้รับ GET Request แล้วฟังก์ชันจะแสดงรายการไฟล์ในคอนเทนเนอร์ใน Azure Blob Storage โดยใช้เมธอด list_blobs() ของ ContainerClient
- return render_template(‘index.html’, form=form, image_files=image_files): จากนั้นจะ return ฟอร์มและรายการไฟล์รูปภาพไปยังเทมเพลต HTML ที่ชื่อ index.html โดยใช้ฟังก์ชัน และ index.html จะแสดงรายการไฟล์รูปภาพและผู้ใช้สามารถอัปโหลดไฟล์เพิ่มเติมได้นั่นเอง
หลังจากนั้นถ้าเราเอา Connection String ไปใส่ตัวเว็บแอปของเราก็จะทำงานได้แล้ว และได้รู้ว่าโค้ดแต่ละส่วนทำงานอย่างไรแล้ว แต่โค้ดของเรายังเป็นแบบ Hardcode เราจะมีการแก้ไขและปรับปรุงโค้ดดังนี้ จัดการกับข้อมูลที่มีความ Sensitive เช่น Connection String เก็บไว้ใน Environment Variables
from flask import Flask, render_template, url_for
from flask_wtf import FlaskForm
from wtforms import FileField, SubmitField
from werkzeug.utils import secure_filename
import os
from wtforms.validators import InputRequired
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
app = Flask(__name__)
app.config['SECRET_KEY'] = 'SECRET_KEY'
# Azure Blob Storage configuration
CONNECTION_STRING = os.environ.get('CONNECTION_STRING')
CONTAINER_NAME = os.environ.get('CONTAINER_NAME')
class UploadFileForm(FlaskForm):
file = FileField("File", validators=[InputRequired()])
submit = SubmitField("Upload File")
@app.route('/', methods=['GET', 'POST'])
def UploadFile2Web():
form = UploadFileForm()
if form.validate_on_submit():
# Save file to Azure Blob Storage
file = form.file.data
filename = secure_filename(file.filename)
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
blob_client = container_client.get_blob_client(filename)
blob_client.upload_blob(file)
# List files in Azure Blob Storage
blob_service_client = BlobServiceClient.from_connection_string(CONNECTION_STRING)
container_client = blob_service_client.get_container_client(CONTAINER_NAME)
image_files = [blob.name for blob in container_client.list_blobs()]
return render_template('index.html', form=form, image_files=image_files)
if __name__ == '__main__':
app.run(debug=True)
3. สร้าง Azure App Service
แต่ก่อนที่เราจะ Deploy แอปพลิเคชันของเราไปยัง Azure App Service นั้น เราต้องเข้าไปทำการสร้าง Azure App Service ของเราขั้นตอนในการสร้างมีดังนี้
1. ไปที่ Azure Portal เลือก Azure App Service กด Create
2.กำหนดค่าต่าง ๆ ในการสร้าง App Service
-
- กำหนดชื่อและแพลตฟอร์มที่ต้องการสร้าง App Service
- เลือก Subscription และ Resource group ที่ต้องการใช้งาน
- เลือก Runtime stack ที่ต้องการใช้งานในตัวอย่างนี้เลือกเป็น Python
ส่วนของ Pricing plan เนื่องจากตอนนี้เราใช้เป็น Subscription ของ Microsoft Sandbox เราจะเลือกเป็น Free F1 หลังจากสร้าง App Service เสร็จเรียบร้อยแล้ว เราจะได้ Azure App Service URL มา ซึ่งในที่นี้คือ http://<app_name>.azurewebsites.net โดยเปลี่ยน <app_name> เป็นชื่อของ App Service ที่เราตั้งไว้นั่นเอง
4. การตั้งค่า Environment Variables ใน Azure App Service
หลังจากนั้นทำการกำหนดค่าในตัวแปร Environtment Variable ใน Azure App Service โดยเข้าไปที่ Configuration
แล้วทำการเพิ่ม Environment Variables ของเรา ซึ่งในที่นี้จะเก็บ Connection String และ Container Name ของ Azure Blob Storage
5. การ Deploy เว็บแอปพลิเคชัน Flask ไปยัง Azure App Service
สำหรับการ Deploy เว็บของเราจะทำการ Deploy ผ่าน Visual Studio Code Extension ของ Azure App Service โดยเราจะมีขั้นตอนการ Deploy ดังนี้
1. ติดตั้ง Azure App Service Extension ใน Visual Studio Code
2. เปิดโฟลเดอร์ของโปรเจกต์ที่ต้องการเลือก App Service ที่เราต้องการ Deploy และคลิกขวาเพื่อเลือก “Deploy to Web App”
3. เลือกโฟลเดอร์ของโปรเจกต์ที่ต้องการ Deploy หลังจากนั้นรอระบบ Deploy สักครู่
3. เลือกโฟลเดอร์ของโปรเจกต์ที่ต้องการ Deploy หลังจากนั้นรอระบบ Deploy สักครู่
4. หลังจากการ Deploy เสร็จสิ้นแล้ว เราสามารถเข้าถึงเว็บแอปพลิเคชันของเราได้ผ่าน URL ของ Azure App Service ที่เราได้สร้างไว้แล้วนั่นเอง
ระบบฝึกทักษะ การเขียนโปรแกรม
ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง
- โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
- รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
- ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!