blog ที่แล้ว เราคุยกันถึง data contract กับ NodeJS รอบนี้ เรามาใช้ Python กันบ้างฮะ

สำหรับ NodeJS กดที่ลิงก์ข้างล่างได้เลย

สัญญา(ไม่)ปากเปล่า - data contracts in action (NodeJS)
Data contract เป็นส่วนนึงของ data integration โดยตัวมันเองทำหน้าที่เป็นเหมือน “contract” หรือสัญญา ว่าเราจะรับส่งข้อมูลกันระหว่างต้นทางและปลายทางยังไงบ้าง เพื่อสร้าง pipeline ได้อย่างถูกต้อง และโปร่งใส

ย้อนความนิดนึง

ใน ETL มันมี extract ถูกมั้ยฮะ ซึ่งในขั้น extract ก็ควร validate ค่าที่เข้ามาด้วย ตรง validate นี่แหละ ที่เราสนใจ เพื่อให้ข้อมูลมีคุณภาพเพียงพอที่เราจะเอาไปใส่ใน database ได้

และเราก็จะสร้าง API มารับข้อมูลและ validate โดยใช้ OpenAPI กับ Python library ตัวนึงที่เอาไว้ทำ validation นั่นคือ jsonschema ฮะ


API Swagger

ขอ recycle ของเก่า  API definition file people ฮะ

อ้อ pets ด้วย


เขียน app พร้อม validation

เรามารู้จัก jsonschema กัน เจ้า library ตัวนี้ใช้ validate object โดยอ้างอิงกับ schema ที่เราต้องการ คือหลักการเหมือนกับ AJV ใน NodeJS เลยฮะ

jsonschema
PyPI version Supported Python versions Build status ReadTheDocs status pre-commit.ci status Zenodo DOI jsonschema is an implementation of the JSON Schema specification for Python. It can also be us…

1. สร้าง python app

เริ่มจาก sample Flask app

แล้วติดตั้ง requirements

แค่นี้ เราก็จะได้ API app มาแล้วฮะ

2. อ่าน contract

เราจะเริ่มจากหนึ่ง contract ก็คือ people ก่อนนะฮะ

ตรงบรรทัดที่ 6-7 นั่นคือเราไปอ่าน contract file เก็บไว้ในตัวแปรcontract

3. Validate

  • บรรทัด 9: รับ payload ด้วย request.get_json()
  • บรรทัด 10: อ้างอิงค่า schema ของ contract จาก /components/schemas/people
  • บรรทัด 11: validate payload และ contract ด้วย jsonschema.validate()
  • บรรทัด 12: return 200 คือ "OK" ถ้า validate ถูกต้อง แต่ถ้าไม่ เราจะได้ "500 Internal Server Error" แทน แบบข้างล่างนี้ฮะ

4. Handling errors

ตรง error ตะกี้ มันไม่สื่อเท่าไหร่ เรามาลองปรับให้มันดูดีขึ้นกัน

  • ถ้า validate ถูกต้อง ให้ return 200 ใน try block
  • ถ้าเกิด validation error ให้ return 400 พร้อม message จาก jsonschema.ValidationError.message ใน except block อันแรก
  • แต่ถ้า error อย่างอื่น ก็ return 400 เหมือนกันแต่ print log แทน

5. Complete API

6. Test

กรณี payload ถูกต้อง

กรณี payload มีบาง field ระบุ type ไม่ถูกต้อง

กรณี payload ไม่มี required field


ถ้ามีหลาย contract ?

ตอนนี้เราสามารถ validate people contract ได้แล้ว ละถ้าเรามี pets และต้องการ validate ทั้งคู่พร้อมกันล่ะ

เราควรจะต้องมี generic function ประมาณนี้ฮะ

  • บรรทัด 8-13: อ่าน contract files เก็บไว้ใน dict ให้ key เป็นชื่อ file
  • บรรทัด 16-30: refactor ตรงส่วน validation ให้อยู่ใน generic function โดยรับค่า parameter เป็น contract key (อ้างอิงใน dict) และ payload

เวลาเรียก ก็เรียกจาก endpoint แต่ละอันฮะ

นี่คือ code ตัวเต็ม

ลองเรียก API ด้วย payload ที่ไม่ถูกต้อง จะได้ผลลัพท์แนวๆ นี้

เอาล่ะ แค่นี้ก็ได้ API ง่ายๆ พร้อม contract validation ด้วย python แล้วฮะ


Repo

สามารถดู source code ทั้งหมดใน repo ด้านล่างนี้ฮะ

GitHub - bluebirz/sample-data-contracts-py: Sample data contracts for data integration with Python
Sample data contracts for data integration with Python - bluebirz/sample-data-contracts-py