Cloudflare Workers Kini Bisa Ditulis dengan Python
(blog.cloudflare.com)- Cloudflare Workers mendukung penulisan dengan Python dalam open beta, memperluas model yang berpusat pada JavaScript dengan mengintegrasikan Pyodide langsung ke workerd, runtime Workers open source
- Python Workers mendukung binding yang sudah ada seperti Vectorize, Workers AI, R2, dan Durable Objects sejak hari pertama, serta dapat mengimpor beberapa paket Python seperti FastAPI, Langchain, dan Numpy
- Implementasinya berbasis Pyodide, port WebAssembly dari CPython, dan menggunakan FFI antara JavaScript dan Python untuk menangani Request, Response, Fetch API, serta binding resource Cloudflare dari kode Python
- Cloudflare menjalankan import saat deployment dan membuat snapshot memori linear WebAssembly untuk mengurangi biaya inisialisasi Pyodide dan paket, sehingga cold start Python Worker dasar turun menjadi kurang dari 1 detik
- Versi Python serta pembaruan Pyodide dan paket dikelola dengan Compatibility Dates dan Compatibility Flags; Worker yang tetap berada pada rilis Python setelah masa dukungan 5 tahun berakhir akan otomatis dipindahkan ke rilis Python tertua berikutnya
Open Beta Python Workers
- Python Workers kini tersedia dalam open beta di Cloudflare Workers
- Berbeda dari dukungan bahasa selain JavaScript sebelumnya, implementasi Python diintegrasikan langsung ke runtime workerd
- Binding Cloudflare yang didukung sejak hari pertama mencakup:
- Python Workers dapat mengimpor beberapa paket Python populer seperti FastAPI, Langchain, dan Numpy
- Tidak memerlukan tahap build terpisah atau toolchain eksternal
Mengapa Kompilasi WebAssembly Saja Belum Cukup
- Workers telah mendukung WebAssembly sejak 2018, dan setiap Worker berjalan di V8 isolate, yaitu engine JavaScript yang sama seperti Chrome
- Pada prinsipnya, berbagai bahasa termasuk Python dapat dijalankan di Workers jika terlebih dahulu dikompilasi ke WebAssembly atau JavaScript
- Aplikasi nyata membutuhkan lebih dari sekadar menjalankan “hello world”; dukungan terhadap ekosistem paket yang familiar bagi developer sangat penting
- Python Workers adalah bentuk awal dari upaya menjadikan bahasa selain JavaScript sebagai warga kelas satu di Workers
Alur Eksekusi Python Worker
- Dengan Pyodide yang ditanamkan di workerd, Python Worker dapat menangani request melalui handler
on_fetch - Di
wrangler.toml, file.pyditetapkan sebagaimain, dancompatibility_flags = ["python_workers"]dikonfigurasi - Saat menjalankan
npx wrangler@latest dev, runtime Workers menangani hal berikut:- Menentukan versi Pyodide yang diperlukan berdasarkan compatibility date
- Membuat isolate untuk Worker dan menyuntikkan Pyodide secara otomatis
- Menyediakan kode Python ke Pyodide
- Lingkungan eksekusi Python ditangani secara internal dan disediakan oleh platform, mirip dengan JavaScript Workers
Mengapa Pyodide Cocok untuk Workers
- Pyodide adalah implementasi CPython yang di-port ke WebAssembly, dan menafsirkan kode Python tanpa prakompilasi ke format lain
- Pyodide menyediakan sebagian besar standard library Python serta foreign function interface (FFI) yang memungkinkan API JavaScript dipanggil dari Python
- Dirancang untuk membangun interpreter inti dan setiap modul Python native sebagai modul WebAssembly terpisah, lalu melakukan dynamic linking saat runtime
- Beberapa Workers yang berjalan di mesin yang sama dapat berbagi code footprint modul, hal yang penting bagi lingkungan Cloudflare yang menjalankan ribuan Workers per mesin
- Sebagian besar bahasa target WebAssembly belum mendukung dynamic linking, sehingga setiap aplikasi sering kali menyertakan salinan runtime bahasanya sendiri
Pyodide dan Dynamic Linking WebAssembly
- Karena WebAssembly adalah lingkungan sandbox yang terpisah dari runtime host, pekerjaan selain komputasi murni seperti membaca file harus disediakan oleh lingkungan runtime dan diimpor oleh modul
- Target WebAssembly LLVM terbagi menjadi tiga:
wasm32-unknown-unknown: Tidak menyediakan C standard library atau antarmuka system callwasm32-wasi: Menggunakan antarmuka sistem standar yang diimplementasikan oleh runtime WASIwasm32-unknown-emscripten: Mendefinisikan import yang diperlukan dan sekaligus menghasilkan library JavaScript yang mengimplementasikannya
- Pyodide menggunakan Emscripten untuk menyediakan interpreter CPython, FFI Python-JavaScript, dan paket Python pihak ketiga yang dikompilasi ke WebAssembly
- Di antara target ini, hanya Emscripten yang saat ini mendukung dynamic linking
- WASI belum mendukung abstraksi dynamic linking
dlopen/dlsymyang digunakan CPython
FFI yang Menghubungkan Python dan JavaScript
- Contoh Python Worker mengambil
ResponseJavaScript denganfrom js import Response - FFI Pyodide memungkinkan akses ke semua fitur JavaScript dari Python, sehingga mengurangi risiko Python Workers tertinggal secara fungsi dibanding JavaScript Workers
- Tipe immutable seperti string dan angka dikonversi secara transparan di antara kedua bahasa, sementara objek yang dapat diubah dibungkus dengan proxy yang sesuai
- Saat objek JavaScript diteruskan ke Python, Pyodide memeriksa protokol JavaScript yang didukung objek tersebut, lalu secara dinamis menyusun class yang mengimplementasikan protokol Python yang sesuai
- Jika mendukung protokol iterasi JavaScript, objek tersebut juga mendukung protokol iterasi Python
- Jika berupa Promise atau thenable, di Python objek tersebut menjadi awaitable
- Dalam alur pemrosesan request, objek JavaScript
Requestyang masuk dibungkus sebagaiJsProxyyang dapat diakses dari kode Python, dan nilai kembalian handler Python dikonversi menjadi objek JavaScriptResponse
Dynamic Linking dan Paket Python
- Banyak paket Python membawa library native melalui C FFI, dan agar berjalan di runtime Workers, library tersebut harus dikompilasi ke WebAssembly
- Pyodide dibangun dengan Emscripten untuk meng-override C FFI Python, dan ketika sebuah paket mencoba memuat library native, runtime Workers memuat modul WebAssembly yang disediakannya
- Dynamic linking memungkinkan Pyodide mendukung berbagai paket Python yang memiliki dependensi library native
- Static linking harus memuat semua kode yang diperlukan sebelum binary dijalankan, sedangkan dynamic linking membayar biaya hanya saat dibutuhkan
- Workers membuat filesystem yang tampak seperti distribusi Python untuk setiap Worker pada runtime, tetapi file dasarnya dibagikan antar-Workers
- Saat ini file dibagikan antar-Workers tetapi disalin untuk setiap isolate baru; ke depannya, lebih banyak underlying resource diperkirakan dapat dibagikan dengan teknik copy-on-write
Dukungan pustaka klien dan server HTTP
- Python memiliki banyak pustaka klien HTTP seperti httpx, urllib3, dan requests, tetapi tidak berjalan secara default di Pyodide
- Pustaka-pustaka ini menggunakan socket mentah, sementara model keamanan browser dan CORS tidak mengizinkannya, sehingga runtime Workers memerlukan pendekatan berbeda
-
Klien asinkron
- Pustaka yang mendukung permintaan asinkron seperti aiohttp dan httpx dapat menggunakan Fetch API milik Workers
- Cloudflare menambal pustaka melalui Pyodide FFI agar menggunakan Fetch API JavaScript
- Patch httpx terdiri dari kurang dari 100 baris kode
-
Klien sinkron dan batasannya
- Banyak API Python bersifat sinkron, dan dalam kasus ini Fetch API yang asinkron tidak dapat digunakan secara langsung
- urllib3 menerima kontribusi untuk dukungan browser Pyodide yang menggunakan
Atomics.wait()dan fetch worker thread, atau XMLHttpRequest sinkron - Cloudflare Workers saat ini tidak mendukung worker threads maupun
XMLHttpRequestsinkron, sehingga kedua pendekatan tersebut tidak berjalan di Python Workers - Saat ini permintaan sinkron belum didukung
-
WebAssembly Stack Switching
- WebAssembly memiliki proposal stage 3 untuk menambahkan stack switching, dan V8 sudah memiliki implementasinya
- Para kontributor Pyodide telah menambahkan dukungan stack switching sejak September 2022 dan hampir siap
- Jika dukungan ini masuk,
run_syncdi Pyodide dapat memblokir hingga awaitable selesai, sehingga membuka jalur untuk dukungan permintaan sinkron
FastAPI dan ASGI
- FastAPI adalah pustaka yang banyak digunakan untuk mendefinisikan server Python, dan menggunakan protokol ASGI
- Aplikasi FastAPI tidak membaca atau menulis socket secara langsung; biasanya server ASGI seperti uvicorn yang menangani socket mentah
- Berkat struktur ini, FastAPI dapat berjalan di Cloudflare Workers tanpa perlu menambal atau mengganti FastAPI itu sendiri
- Cukup mengganti uvicorn dengan server ASGI yang dapat berjalan di dalam Workers
- Implementasi awal ada di asgi.py milik workerd, dan disertakan dalam fork Pyodide yang dikelola Cloudflare
- Cloudflare berencana melakukan upstream ke Pyodide setelah fiturnya lebih lengkap dan cakupan pengujian ditambahkan
Mengimpor paket Python
- Python Workers mendukung sebagian paket Python yang disediakan langsung oleh Pyodide
- Paket yang didukung mencakup numpy, httpx, FastAPI, Langchain, dan lainnya
- Untuk mengimpor paket, tambahkan nama paket tanpa nomor versi ke
requirements.txt - Versi paket tertentu disediakan langsung oleh Pyodide
- Saat ini paket dapat digunakan dalam pengembangan lokal, dan dalam beberapa minggu mendatang deployment Workers dengan dependensi yang didefinisikan di
requirements.txtakan dimungkinkan - Cloudflare mengatakan akan mempertahankan fork Pyodide sendiri untuk menyediakan patch khusus runtime Workers, serta mengirimkan perubahan tersebut ke upstream Pyodide
Cold start dan snapshot memori
- Ukuran Pyodide sendiri adalah 6,4MB, dan paket Python juga bisa berukuran besar
- Jika Pyodide dimasukkan begitu saja ke Worker lalu diunggah ke Cloudflare, biaya pemuatan isolate baru menjadi besar sehingga cold start melambat
- Pada komputer cepat dan jaringan yang baik, Pyodide membutuhkan sekitar 2 detik untuk inisialisasi di browser, terdiri dari 1 detik jaringan dan 1 detik CPU
- Saat menjalankan
npx wrangler@latest deploy, proses deployment berjalan seperti berikut- Wrangler mengunggah kode Python dan
requirements.txtke Workers API - Runtime Workers memverifikasi kode Python dan dependensinya
- Membuat isolate baru lalu menyuntikkan Pyodide dan paket yang ditentukan secara otomatis
- Memindai dan menjalankan pernyataan import dalam kode Worker, lalu membuat snapshot memori linear WebAssembly milik Worker
- Men-deploy snapshot ini dan kode Python ke jaringan Cloudflare
- Menjalankan top-level scope seperti pada JavaScript Worker
- Wrangler mengunggah kode Python dan
- Saat permintaan masuk, snapshot ini dimuat untuk melakukan bootstrap Worker di isolate, sehingga biaya inisialisasi yang mahal dapat dihindari
- Cold start Python Worker dasar turun menjadi kurang dari 1 detik
-
Penggunaan ulang snapshot
- Saat ini snapshot memori yang dibuat ketika mengunggah Python Worker bersifat khusus untuk Worker tersebut, dan tidak dapat dibagikan meskipun sebagian besarnya sama dengan Python Workers lain
- Cloudflare menilai mereka dapat membuat satu snapshot bersama sebelumnya dan memuatnya terlebih dahulu ke kumpulan pre-warmed isolate yang runtime Pyodide-nya sudah dimuat
- Dengan cara ini, Python Worker juga akan semakin mendekati model di mana runtime disediakan secara on-demand seperti JavaScript Worker
- Cloudflare melihat penggunaan ulang snapshot sebagai cara terbesar untuk makin menurunkan cold start sepanjang sisa tahun 2024
Mengelola versi Python dengan Compatibility Dates
- Cloudflare Workers memiliki model yang mengharapkan Worker yang sudah di-deploy terus berjalan tanpa perlu pembaruan
- Stabilitas ini disediakan melalui Compatibility Dates dan Compatibility Flags
- Dalam Python, Pyodide dan CPython masing-masing memiliki versi, dan versi baru dapat menyertakan breaking change
- Versi Python baru dirilis setiap Agustus, dan versi Pyodide baru dirilis 6 bulan setelahnya
- Ketika versi Pyodide baru ditambahkan ke Workers, versi tersebut ditempatkan di balik Compatibility Flag dan hanya diaktifkan setelah Compatibility Date yang ditentukan
- Rilis Python memiliki masa dukungan 5 tahun, dan versi Python yang masa dukungannya telah berakhir tidak menerima patch keamanan
- Python Worker yang tetap berada pada rilis Python lama setelah 5 tahun akan otomatis dipindahkan ke rilis Python tertua berikutnya
- Cloudflare memperkirakan dalam sebagian besar kasus Python Worker akan terus berjalan tanpa masalah, tetapi menyarankan untuk memperbarui compatibility date secara berkala agar tetap berada dalam masa dukungan
- Di antara rilis Python, paket juga akan diperbarui dan ditambahkan dengan cara opt-in yang sama, dengan contoh flag berbentuk
python_3.17_packages_2025_03_01
Binding di Python Workers
- Berkat Pyodide FFI, objek, metode, dan fungsi JavaScript dapat diakses langsung dari Python
- Dengan struktur ini, semua binding API untuk resource Cloudflare didukung di Python Workers sejak hari pertama
- Objek
envpada handler Python adalah objek JavaScript, dan Pyodide menyediakan API proxy yang menangani konversi tipe antarbahasa - Untuk KV namespace,
env.FOO.put()danenv.FOO.get()dapat di-awaitdi Python untuk menulis dan membaca nilai - Web API juga dapat digunakan dengan cara yang sama, dan JavaScript global seperti
Responsedapat diimpor dari moduljs
Rencana API yang lebih Pythonic
- Cloudflare menyadari bahwa bentuk seperti
from js import Responsetidak terasa Pythonic, dan berencana menyediakan API yang lebih idiomatis untuk Python Workers - workers-rs, yang dirilis pada 2021, menyediakan binding bergaya Rust untuk setiap JavaScript API Workers
- Cloudflare merencanakan arah yang sama untuk Python Workers, dimulai dari binding Workers AI dan Vectorize
- workers-rs di Rust menggunakan dependensi eksternal dan perlu diperbarui, tetapi API Python Workers rencananya akan dibangun langsung ke dalam runtime Workers
- Dengan memperbarui compatibility date, API bergaya Python terbaru dapat digunakan
- Ada kemungkinan menyediakan sebagian raw socket API dari standard library Python berdasarkan JavaScript API
connect()milik Workers - Cloudflare berharap dapat memulai upaya membangun API serverless terstandardisasi yang mudah digunakan developer Python, sambil menyediakan fitur yang sama seperti JavaScript
Arah ke depan
- Untuk mendukung bahasa pemrograman baru dengan benar, diperlukan investasi besar yang melampaui “hello world”
- Berdasarkan survei Stack Overflow 2023, Python tercatat sebagai bahasa yang paling banyak digunakan setelah JavaScript
- Cloudflare menyatakan akan terus meningkatkan performa Python Workers dan memperluas cakupan dukungan paket Python
- Kanal umpan baliknya adalah kanal Python Workers di Cloudflare Developers Discord dan diskusi GitHub workerd
1 komentar
Opini Hacker News
Senang melihat Cloudflare lebih memperhatikan menjalankan Python sebagai WebAssembly di Edge
Dari sudut pandang kami di Wasmer yang telah menangani eksekusi Python berbasis WebAssembly di Edge, Cloudflare Workers mengaktifkan Python di Edge dengan menggunakan Pyodide, yaitu Python yang dikompilasi ke WebAssembly dengan Emscripten
Strukturnya mengikat Pyodide ke Workerd dan mencoba mengurangi waktu mulai dengan snapshot V8; dalam skenario terbaik, cold start Python sekitar 1 detik
Namun, pendekatan saat ini terikat pada versi Python/Pyodide yang tertanam di Workerd, dan resolusi paket juga sangat terkopel dengan Workerd, sehingga kemungkinan besar saat runtime hanya paket native yang sudah dikompilasi sebelumnya yang diizinkan. Misalnya, menggunakan versi numpy tertentu bisa menjadi rumit
Secara arsitektural, ini terikat pada dunia JS/V8, jadi dengan arsitektur saat ini tampaknya sulit mencapai waktu mulai di bawah 100ms
Meski begitu, rilis ini patut disambut, dan saya berharap orang-orang membuat aplikasi yang keren
https://pyodide.org/
https://github.com/cloudflare/workerd/blob/main/docs/pyodide...
https://github.com/cloudflare/workerd/pull/1875
Edit: Mengubah “bukti konsep” menjadi “rilis” untuk mencerminkan penjelasan dari tim Cloudflare
Kami berencana memperbarui paket seperti langchain atau numpy yang disebutkan tadi dengan cukup sering
Akan menarik jika Anda bisa menjelaskan lebih lanjut mengapa V8 dianggap sebagai faktor pembatas. V8 adalah runtime WebAssembly yang kuat, dan sebagian besar optimasi yang direncanakan tidak terlalu bergantung pada engine di bawahnya
Selain itu, ini bukan bukti konsep, melainkan beta yang akan terus ditingkatkan hingga GA
https://wasmer.io/templates?language=python
Cloudflare punya banyak hal bagus di sisi hosting dan database, tetapi sebagai platform developer tampaknya pemasarannya kurang baik, sehingga Vercel atau Netlify mengambil porsi awareness yang cukup besar
Terpisah dari itu, saya penasaran apakah Cloudflare menyediakan layanan hosting container yang agnostik bahasa seperti Google Cloud Run
Harga dan produknya sangat bagus
Beberapa fitur sama sekali tidak berjalan, dan beberapa fitur hanya didukung sebagian
Jika waktu developer yang berharga harus dihabiskan untuk menyelesaikan masalah seperti ini, platform alternatif seperti Vercel, Netlify, dan Deno Deploy terasa lebih mulus untuk kebutuhan tim, dan lebih mudah berfokus pada pengembangan daripada masalah infrastruktur
Biaya bandwidth di Vercel dan Netlify 40–50 kali lebih mahal daripada sebagian besar penyedia cloud, sementara di Cloudflare bandwidth nyaris tidak menjadi biaya
Pemanggilan Edge function juga 6 kali lebih mahal di Vercel dan Netlify dibanding Cloudflare. Itu belum termasuk biaya waktu komputasi, yang gratis di Cloudflare
Hampir satu-satunya alasan Vercel populer adalah karena itu tempat terbaik untuk meng-host NextJS, dan mungkin karena itu mereka membuat NextJS sulit di-deploy ke tempat lain
Saya sudah memakai Workers di produksi sekitar 4 tahun dan menyukainya, tetapi sebagian besar aplikasi saya masih berjalan di container
Saya pernah memakai JS Workers di situs yang berada di depan Cloudflare; mudah digunakan dan sangat cepat. Saya ingin memindahkan seluruh aplikasi Django di belakang situs itu, bahkan sampai memakai database D1
Karena traffic-nya rendah, saya masih berada di tier gratis, tetapi karena begitu mudah dibuat, saya juga bersedia membayar
Akan membantu jika ada perbandingan performa dengan JS Worker. Ini menarik, tetapi karena ada beberapa lapisan yang saling terkait, tampaknya berpotensi lebih lambat
Bukan berarti saya mengharapkan performa yang setara, tetapi akan bagus jika bisa mengetahui gambaran kasar trade-off-nya
Saat ini cold start Python lebih lambat daripada JavaScript Worker dengan ukuran yang sama. Worker “Hello World” dasar yang ditulis dengan JavaScript punya waktu cold start yang hampir mendekati 0, sedangkan Python Worker di bawah 1 detik
Ini karena Pyodide harus dimuat ke Worker secara on-demand saat request masuk, dan artikel blog menjelaskan pekerjaan untuk mengurangi hal ini dengan membuat Pyodide tersedia lebih awal
Namun setelah Python Worker selesai cold start, perbedaannya menjadi nyaris di pinggiran, dan bisa hanya beberapa milidetik tergantung apa yang terjadi selama request
Saat melintasi “bridge” antara JavaScript dan WebAssembly, misalnya ketika melakukan input/output atau pekerjaan asinkron, ada sedikit biaya. Namun anggap saja di level mikrodetik, bukan milidetik, dan umumnya sangat kecil
Orang-orang yang memakai Worker yang sensitif terhadap performa sudah ada yang menulisnya dengan Rust: https://github.com/cloudflare/workers-rs Ini juga bergantung pada bridge antara JavaScript dan WebAssembly
Interpreter Python berbasis WebAssembly yang disediakan Pyodide tidak secepat optimisasi bertahun-tahun yang telah dibangun untuk membuat JavaScript cepat di V8. Meski begitu, Pyodide masih berada di tahap awal dibandingkan mesin JS V8, dan ada bagian yang tampaknya memungkinkan peningkatan performa besar. Mereka ingin mengirimkan perbaikan performa ke upstream, dan ada juga beberapa proposal WebAssembly yang membantu
Saya penasaran apakah pemilihan lzma untuk menunjukkan isolasi itu disengaja, atau kebetulan karena berita teknologi minggu lalu
https://news.ycombinator.com/item?id=39865810
Sepertinya ini akan cukup menjadi game changer untuk menjalankan pekerjaan terkait AI di Cloudflare. Sudah cukup lama saya menantikannya
Kalau belum melihatnya, dua pengumuman lain yang keluar hari ini juga layak dicek
“Leveling up Workers AI: General Availability and more new capabilities”
https://blog.cloudflare.com/workers-ai-ga-huggingface-loras-...
“Running fine-tuned models on Workers AI with LoRAs”
https://blog.cloudflare.com/fine-tuned-inference-with-loras
Saya mencobanya hari ini dan bagus, bisa sampai berjalan dengan sangat cepat
Namun saya penasaran bagaimana membuat lingkungan pengembangan lokal memahami library yang tertanam dalam implementasi Python CFW
Misalnya ada library
asgi, dan saya ingin linter tidak menandainya sebagai tidak dikenal. Tetapi library ini hanya ada pada runtime handleron_fetchdan tidak benar-benar ada di mesin pengembangan lokal, jadi saya belum menemukan solusinyaSaya mendapatkan hasil bagus memakai CF Pages untuk situs statis, dan produk Cloudflare yang menyediakan LLM open-source seperti layanan juga menarik
Alasan utama yang menghambat saya membuat lebih banyak hal di Cloudflare adalah kurangnya dukungan Python, dan saya menantikan untuk mencoba fitur ini
Mudah menjalankan sesuatu dengan cepat, dan tidak perlu terlalu memikirkan infrastruktur
Penambahan Python sangat saya sambut, dan saya berharap Go juga mendapat dukungan kelas satu
Saya penasaran bagaimana batasan bahwa kita harus hanya memakai paket Pyodide akan bekerja pada build yang tidak sederhana
Ada banyak kode yang bukan Python murni, dan untuk mendukung aplikasi produksi yang nyata sepertinya akan ada banyak hal yang harus dibangun ulang secara manual
Adopsi Cloudflare mungkin membantu menarik lebih banyak paket, dan jika aturan 80/20 berlaku di sini, itu bisa saja sudah cukup baik
Seperti disebutkan juga di artikel blog, masalah terbesar adalah dukungan untuk paket terkait server dan request. Ini jelas berguna di Cloudflare Workers, tetapi sulit dipindahkan karena sering memakai raw socket dan suatu bentuk konkurensi
Akan bagus jika CloudFlare mengimplementasikan Workers yang menjadikan WASM target kelas satu, bersama API umum yang tidak terikat pada JS Workers
Sekarang pun kita bisa men-deploy kode WASM sehingga secara praktis bisa memakai bahasa apa pun, tetapi itu bukan native karena berjalan di dalam konteks JS
Ada sedikit overhead dan kejanggalan dalam deployment
Pada akhirnya saya pikir semua layanan akan di-deploy langsung ke runtime WASM yang diamankan, bukan ke container. Mirip dengan pergeseran dari image ke container
Saat ini manfaat memakai sesuatu seperti Rust di Cloudflare Edge tidak besar. Sebagian besar keuntungan performanya tertutupi oleh overhead dan waktu start
Contoh: https://github.com/WasmEdge/WasmEdge