Paket Python untuk membongkar panggilan fungsi ke server HTTP yang berjalan di LocalHost secara otomatis menggunakan dekorator. Kompatibel dengan multiprosesing, acar, labu, fastapi, async dll.
Bayangkan sebuah kasus aplikasi multi -berulir atau multiprosessing di mana 1 atau beberapa fungsi adalah sumber daya yang sangat besar (CPU atau memori), tetapi fungsi lainnya dapat berjalan secara paralel.
Contoh - Panggilan API diikuti oleh tokenisasi dan klasifikasi menggunakan model DL besar diikuti oleh panggilan API lebih lanjut.
Dalam kasus seperti itu, masuk akal untuk membuat server (umumnya menggunakan Torchserve atau TFServing) untuk melayani permintaan, dan mengganti panggilan fungsi dengan permintaan POST ke server.
ServerHandler membuat server sinkron dan mengganti panggilan apa pun ke fungsi secara otomatis selama runtime.
Permintaan dibuat untuk 1 contoh proses yang menjalankan http.server.httpserver yang menjalankan fungsi di dalamnya.
AsyncServerHandler juga tersedia yang membuat permintaan secara tidak sinkron.
Bahkan panggilan yang dilakukan dari berbagai proses, utas, multiprosesing, loop flask, fastapi dan async dibuat untuk proses server yang sama.
Secara umum:
some code with a callable
dapat diganti dengan instance dari ServerHandler atau AsyncServerHandler yang menerima kode sebagai string dalam argumen pertama dan nama yang dapat dipanggil sebagai argumen kedua.
from auto_function_serving . ServerHandler import ServerHandler
callable_name = ServerHandler ( """
some independent code with a callable
""" , "callable_name" )Contoh :
import module1
import module2
def functionname ( someinput ):
a = module1 . function1 ( someinput )
return module2 . function2 ( a )bisa diganti dengan
from auto_function_serving . ServerHandler import AsyncserverHandler
functionname = AsyncServerHandler ( """
import module1
import module2
def functionname(someinput):
a = module1.function1(someinput)
return module2.function2(a)
""" , "functionname" , port = "Any" )Dekorator ( @asyncserverhandler.decorator dan @serverhandler.decorator) dan detail asyncserverhandler dalam penggunaan lebih lanjut.
from auto_function_serving . ServerHandler import ServerHandler
callable_name = ServerHandler ( """
some independent code with a callable
""" , "callable_name" , port = None , backend = 'Popen' , wait = 100 , backlog = 1024 )) menjalankan http.server.httpserver.
Objek ServerHandler dan AsyncServerHandler dapat dimuat dan diturunkan dengan acar.
Menggunakan Popen atau Multiprosessing untuk menjalankan server.
Hanya menggunakan satu ketergantungan eksternal (AIOHTTP), dan hanya untuk async.
http, bukan https.
Memilih port berdasarkan hash input. (kecuali ditentukan sebaliknya)
Perubahan kode minimal.
Harus kompatibel dengan hampir semua fungsi di hampir semua cpython envs. (Tidak yakin di mana itu bisa gagal? Silakan tambahkan masalah jika Anda menemukannya.)
Kebocoran atau kesalahan memori (dari server) sangat tidak mungkin karena minimal, berulir tunggal, proses tunggal dan komponen default Python stdlib.
Pengecualian menyebabkan kesalahan 5xx tanpa menutup server.
Bahkan proses terpisah akan membuat permintaan ke 1 instance dari server yang sama kecuali ditentukan sebaliknya. (Karena sedang mencari server di port tertentu.).
Dapat menentukan sebaliknya dengan mengatur port ke port gratis apa pun sehingga objek ServerHandler baru memulai server baru.
Permintaan HTTP POST: ringan, beberapa MS overhead, dapat diandalkan.
Async adalah fitur yang bagus.
sekarang dengan tes.
Memiliki serangkaian kode sebagai argumen untuk kelas bukanlah Pythonic, kecuali dekorator digunakan.
Mengimpor fungsi di dalam tidak ideal, bahkan ketika dekorator digunakan.
Permintaan HTTP Post: Insecure, beberapa ms overhead.
Pengecualian di dalam server tidak dikirim kembali.
Tidak ada batching.
Tidak ada logging inbuilt. (Bisa ditambahkan). Penundaan inisialisasi hingga beberapa detik untuk memulai server. Fungsi async tidak akan berfungsi di server.
Tidak ada server otomatis restart jika server ditutup.
Dapat meninggalkan beberapa sumber daya yang terkunci untuk sementara waktu (<1 menit) jika tidak ditutup dengan benar.
Masalah mungkin terjadi jika popen atau multiproses tidak tersedia.
Kemungkinan kesalahan async bersarang dengan Jupyter atau lainnya? Silakan lihat ke Nest-Asyncio dan masalahnya.
Peringatan dari solusi yang agak hacky (tapi sah dan sepenuhnya fungsional).
Penutupan proses server di del dan atexit.redister ( del ) gagal karena beberapa alasan (diuji dan tidak mungkin).
Gunakan PIP Manajer Paket untuk menginstal auto_function_serving
pip install auto_function_serving Kode untuk server disimpan di serverHandler.base_code dan beberapa pemformatan string digunakan untuk mengisi kekosongan.
Proses server dimulai dengan Popen (atau multiprosesing jika ditentukan). Hal pertama yang dilakukannya adalah mengimpor soket dan mengikat port - jika tidak tersedia kode berhenti setelah pengecualian. Oleh karena itu hanya 1 instance dari server yang berjalan pada satu waktu di mesin.
Kami tahu fungsinya siap setelah kami dapat menerima permintaan GET yang valid dari server.
Input dan output dikirim sebagai byte, dikonversi ke dan dari objek menggunakan acar.
Jika port tidak ada saat menginisialisasi (default), port dari 50000 hingga 60000 dipilih dengan hashing kode input untuk membuatnya independen dari sumber fungsi. Tabrakan fungsi yang berbeda dimungkinkan, tetapi tidak mungkin. Tabrakan fungsi yang sama dalam beberapa proses digunakan untuk memastikan hanya 1 proses server berjalan pada satu waktu. Port dapat ditentukan jika diperlukan.
Overhead untuk input dan output kecil (beberapa byte) -
~ 2ms untuk permintaan dengan urllib.request
~ 4ms untuk permintaan async dengan aioHttp.clientsession
Overhead untuk input dan output besar
~ 10ms untuk input dan output 0,5 MB (transfer total 1MB).
~ 60ms untuk input dan output 5 MB (transfer total 10 MB).
~ 600ms untuk input dan output 50 MB (transfer total 100 MB).
Ini juga dapat digunakan dengan dekorator yang disediakan untuk fungsi tanpa ketergantungan di luar fungsi.
from auto_function_serving . ServerHandler import ServerHandler
@ ServerHandler . decorator
def someheavyfunction ( args , ** kwargs ):
for i in range ( big_number )
someexpensivecomputationImpor di dalam fungsi akan berhasil
from auto_function_serving . ServerHandler import ServerHandler
@ ServerHandler . decorator
def someheavyfunction ( args , ** kwargs ):
import numpy as np from auto_function_serving . ServerHandler import ServerHandler
@ ServerHandler . decorator
def someheavyfunction ( args , ** kwargs ):
if not hasattr ( someheavyfunction , 'RunOnce' ):
global np
import numpy as np
setattr ( someheavyfunction , 'RunOnce' , None )
... etcKetika somemodule tidak memiliki pemuatan global yang mahal.
from auto_function_serving . ServerHandler import ServerHandler
from somemodule import someheavyfunction
someheavyfunction = ServerHandler . decorator ( someheavyfunction )Alamat IP dapat diubah dengan mengatur serverHandler.ip_address (default "127.0.0.1") sebelum membuat instance baru.
AsyncserverHandler juga tersedia yang menggunakan AIOHTTP untuk membuat permintaan secara tidak sinkron, untuk digunakan dengan FastAPI dan kasus penggunaan async lainnya.
AsyncServerHandler memiliki penggunaan yang sama dengan ServerHandler, kecuali panggilan perlu ditunggu atau digunakan dengan asyncio.run () atau dengan asyncio.get_event_loop (). Run_until_complete ().
Jumlah panggilan async dapat dibatasi dengan mengatur asyncserverhandler.tcpconnector_limit yang mengontrol batas tcpconnector (default 100). Menggunakan semaphore juga sesuatu yang perlu dipertimbangkan.
Perpustakaan: seledri, tfserving, oborserve, flask
Mengirim global dan penduduk setempat ke eksekutif
pohon ast
Permintaan tarik dipersilakan.
Lisensi Apache 2.0