gRPC ialah rangka kerja Panggilan Prosedur Jauh (RPC) yang berkuasa dan berprestasi tinggi yang, walaupun kurang biasa digunakan berbanding REST, menawarkan kelebihan ketara dalam senario tertentu.
Selain itu ia adalah bahasa agnostik dan boleh dijalankan dalam mana-mana persekitaran, menjadikannya pilihan ideal untuk komunikasi pelayan-ke-pelayan.
Saya tidak akan menyelidiki secara keseluruhannya tetapi berikut ialah pautan umum gRPC. Saya akan berikan tutorial
Mari gambarkan Go kami adalah pelanggan tetapi merupakan pelayan untuk apl frontend React, Svelte dsb.
func getFirstArg() (string, error) { if len(os.Args) < 2 { return "", fmt.Errorf("expected 1 argument, but got none") } return os.Args[1], nil } func main() { filePath, err := getFirstArg() if err != nil { log.Fatalf("Failed to get file path from arguments: %v", err) } fileData, err := ioutil.ReadFile(filePath) if err != nil { log.Fatalf("Failed to read file: %v", err) } ... }
Sebagai contoh React frontend memuat naik fail, Pergi proseskannya tetapi kami memerlukan jawapan daripada excel kami akan menggunakan API GPT. Walaupun ia boleh dilakukan dengan Go, Python sebaliknya mempunyai lebih banyak pakej yang boleh memudahkan kehidupan kita seperti langchan_openai, panda untuk excel dan sebagainya.
Mari mulakan dengan pemasangan gRPC sebaik-baiknya dalam virtualenv .venv anda
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest $ export PATH="$PATH:$(go env GOPATH)/bin"
Seterusnya anda harus memasang penimbal protokol dalam OS anda boleh mengikutinya di sini.
Mari buat dir proto di mana anda akan menyimpan fail penimbal protokol anda. Saya akan namakannya sebagai excel.proto dan tampal ini:
syntax = "proto3"; option go_package = "client-gRPC/proto"; service ExcelService { rpc UploadFile(FileRequest) returns (FileResponse); } message FileRequest { string file_name = 1; bytes file_content = 2; } message FileResponse { bytes file_content = 1; }
Perkhidmatan gRPC ini, ExcelService, membenarkan pelanggan memuat naik fail dengan menghantar nama dan kandungannya. Pelayan bertindak balas dengan kandungan fail yang sama.
Untuk Go adalah penting untuk memasukkan go_package dalam Python baris tidak diperlukan.
vscode-proto3 ialah sambungan yang baik untuk dimuat turun jika anda menggunakan VSCode.
Selepas semua ini, anda boleh menjana fail proto anda, saya lebih sukakannya dalam tahap yang sama seperti prot dir, untuk itu jalankan arahan ini:
protokok --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/excel.proto
Jika dua fail yang berjaya harus dijana, secara pilihan jika terdapat banyak pelarasan tambahkan Makefile dan takrifkannya sebagai proto + arahan atas.
import ( .... "google.golang.org/grpc" pb "client-gRPC/proto" "github.com/xuri/excelize/v2" ) func main() { .... conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("Failed to connect to gRPC server: %v", err) } defer conn.Close() client := pb.NewExcelServiceClient(conn) req := &pb.FileRequest{ FileName: filePath, FileContent: fileData, } res, err := client.UploadFile(context.Background(), req) if err != nil { log.Fatalf("Failed to upload file: %v", err) } outputFile := "output.xlsx" err = saveBytesAsExcel(outputFile, res.FileContent) if err != nil { log.Fatalf("Failed to save bytes as Excel file: %v", err) } fmt.Printf("Excel file saved as: %s\n", outputFile) } func saveBytesAsExcel(filePath string, fileContent []byte) error { f, err := excelize.OpenReader(bytes.NewReader(fileContent)) if err != nil { return fmt.Errorf("failed to open Excel file: %v", err) } if err := f.SaveAs(filePath); err != nil { return fmt.Errorf("failed to save Excel file: %v", err) } return nil }
Kami membuat sambungan untuk mendengar 50051 yang akan menjadi pelayan Python kami, &pb.FileRequest telah dijana sebelum ini dengan menggunakan arahan proto dan kini kami mengimport kaedah tersebut. Jika anda berlari anda akan menerima? disebabkan pelayan Python belum ditubuhkan lagi.
Failed to upload file: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:50051: connect: connection refused"
Oleh kerana python akan bertindak sebagai pelayan pendekatan akan berbeza sedikit tetapi pada dasarnya fail proto yang sama selain daripada medan pakej tidak diperlukan. Mari mulakan dengan mencipta asas main.py tanpa gRPC hanya untuk memberi pandangan tentang cara GPT akan mengisi soalan dalam excel.
import os import openai import pandas as pd from dotenv import load_dotenv def get_answer_from_gpt(apikey: str, question: str): openai.api_key = apikey response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": question} ] ) return response['choices'][0]['message']['content'].strip() def answer_questions_df(df: pd.DataFrame, apikey: str): answers = [] for question in df.iloc[:, 0]: answer = get_answer_from_gpt(apikey, question) answers.append(answer) return answers if __name__ == "__main__": load_dotenv() openai_api_key = os.getenv("OPENAI_API_KEY", "OpenAI API key hasn't been set.") df = pd.read_excel('Book1.xlsx') df['Answer'] = answer_questions_df(df, openai_api_key
Skrip ringkas yang akan menjawab soalan yang akan dihantar oleh Go kepada kami tetapi LOC kurang disebabkan perpustakaan openai khusus yang memudahkannya.
Kami bermula dengan menambah dir proto dengan fail yang sama seperti di atas bahagian pilihan boleh dialih keluar seperti yang dibincangkan. Pasang gRPC dalam virtualenv anda sebaik-baiknya dan ikuti di sini pemasangan untuk generasi proto yang saya jalankan"
python3 -m grpc_tools.protoc --proto_path=proto --python_out=proto --grpc_python_out=proto proto/excel.proto
Untuk berada dalam lvl yang sama dengan direktori proto saya ingat untuk menambah __init.py!
Satu fail telah dijana mari teruskan.
import io import grpc from proto import excel_pb2_grpc as excel_grpc from proto import excel_pb2 class ExcelService(excel_grpc.ExcelServiceServicer): def UploadFile(self, request, context): try: # Convert bytes to a file-like object file_like_object = io.BytesIO(request.file_content) # Load the workbook from the file-like object workbook = openpyxl.load_workbook(file_like_object) # Access the first sheet (or use appropriate logic to get the sheet you need) sheet = workbook.active # Convert the sheet to a DataFrame data = sheet.values columns = next(data) # Get the header row df = pd.DataFrame(data, columns=columns) print("Loaded DataFrame:") print(df.head()) # Ensure that the DataFrame is not empty and has questions if df.empty or df.shape[1] < 1: print("DataFrame is empty or does not have the expected columns.") return excel_pb2.FileResponse(file_content=b'') # Get answers and add them to the DataFrame answers = answer_questions_df(df, openai_api_key) df['Answer'] = answers # Write the updated DataFrame back to a BytesIO object output = io.BytesIO() with pd.ExcelWriter(output, engine='openpyxl') as writer: df.to_excel(writer, index=False, sheet_name='Sheet1') # Reset the buffer's position to the beginning output.seek(0) # Return the modified file content response = excel_pb2.FileResponse(file_content=output.read()) return response except Exception as e: print(f"Error processing file: {e}") return excel_pb2.FileResponse(file_content=b'') def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) excel_grpc.add_ExcelServiceServicer_to_server(ExcelService(), server) server.add_insecure_port('[::]:50051') server.start() print("Server running on port 50051.") server.wait_for_termination() if __name__ == "__main__": load_dotenv() openai_api_key = os.getenv("OPENAI_API_KEY", "OpenAI API key hasn't been set.") serve()
Kami mentakrifkan pelayan dan menambah kelas ExcelService yang mengandungi kaedah yang dijana oleh fail proto. Kerana kami menerima fail mengikut bait perlu menggunakan pembaca bait io dan memulakan pemprosesan selanjutnya bagi fail dan populasi lajur kedua.
response = excel_pb2.FileResponse(file_content=output.read())
Pada akhirnya kami akan kembali ☝️ untuk pelanggan Go kami untuk menerima.
Untuk dapat mencari fail proto dalam python bagaimanapun anda harus menentukan laluan eksport
eksport PYTHONPATH=$PYTHONPATH:mnt/c/own_dev/gRPC/server/proto
If all is good you can run #First comes server python3 -m main #Then client go run client.go Book1.xlsx
Dan anda harus mendapatkan fail .xlsx yang dikemas kini dalam bahagian klien Go.
Dalam artikel ini kami meneroka asas-asas menyediakan komunikasi gRPC antara pelayan Python dan klien Go. Dengan memanfaatkan gRPC, kami mewujudkan cara yang lancar untuk menghantar fail Excel daripada aplikasi Go ke pelayan Python, memproses fail menggunakan API GPT OpenAI dan mengembalikan fail yang diubah suai kembali kepada klien Go.
Atas ialah kandungan terperinci Komunikasi gRPC Antara Go dan Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!