gRPC — это мощная и высокопроизводительная среда удаленного вызова процедур (RPC), которая, несмотря на то, что используется реже, чем REST, предлагает значительные преимущества в определенных сценариях.
Кроме того, он не зависит от языка и может работать в любой среде, что делает его идеальным выбором для межсерверной связи.
Я не буду вдаваться в полное объяснение, но вот общая ссылка на gRPC. Я предоставлю практическое руководство
Давайте представим, что наш Go является клиентом, но является сервером для внешнего приложения React, Svelte и т. д.
func getFirstArg() (string, error) { if len(os.Args)В качестве примера интерфейс React загружает файл, Go обрабатывает его, но нам нужны ответы из Excel, мы будем использовать GPT API. Хотя это можно сделать с помощью Go, Python, с другой стороны, имеет больше пакетов, которые могут облегчить нашу жизнь, например langchan_openai, pandas for excel и т. д.
Давайте начнем с установки gRPC, желательно в вашей виртуальной среде .venv
$ 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"Далее вам следует установить буфер протокола в вашу ОС, это можно сделать здесь.
Давайте создадим каталог прототипа, в котором вы будете хранить файл буфера протокола. Я назову его excel.proto и вставлю это: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; }Эта служба gRPC ExcelService позволяет клиентам загружать файл, отправляя его имя и содержимое. Сервер отвечает тем же содержимым файла.
Для Go важно передать go_package в Python, эта строка не требуется.
vscode-proto3 — хорошее расширение для загрузки, если вы используете VSCode.
После всего этого вы можете создавать файлы прототипов. Я предпочитаю, чтобы они были на том же уровне, что и prot dir, для этого выполните следующую команду:
протокол --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/excel.proto
Если должны быть успешно сгенерированы два файла, при необходимости, если будет много настроек, добавьте Makefile и определите его как прото-верхнюю команду.
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 }Мы устанавливаем соединение для прослушивания 50051, который будет нашим сервером Python, &pb.FileRequest был сгенерирован ранее с помощью команды proto, и теперь мы импортируем методы. Если вы запустите, вы получите? из-за того, что сервер Python еще не установлен.
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"Сервер Python gRPC
Поскольку Python будет действовать как сервер, подход будет немного другим, но, по сути, отделение того же прото-файла из поля пакета не требуется. Давайте начнем с создания базового main.py без gRPC, просто чтобы дать представление о том, как GPT будет заполнять вопросы в 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Это простой скрипт, который будет отвечать на вопросы, которые Go пришлет нам, но LOC меньше из-за специальной библиотеки openai, которая упрощает его.
Мы также начинаем с добавления каталога прототипа с тем же файлом, что и выше, раздел опций можно удалить, как обсуждалось. Желательно установить gRPC в свою виртуальную среду и следовать инструкциям по установке для генерации прототипа, которую я запускал"
python3 -m grpc_tools.protoc --proto_path=proto --python_out=proto --grpc_python_out=proto proto/excel.protoЧтобы быть на том же уровне, что и мой каталог прототипа, не забудьте добавить __init.py!
Если файлы созданы, продолжим.
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]Мы определяем сервер и добавляем класс ExcelService, который содержит методы, сгенерированные файлом прототипа. Поскольку мы получаем файл побайтно, необходимо использовать программу чтения байтов io, начать дальнейшую обработку файла и заполнить второй столбец.
response = excel_pb2.FileResponse(file_content=output.read())В конце мы возвращаем ☝️ нашему клиенту Go.
Однако, чтобы найти файлы прототипов в Python, вам необходимо определить путь экспорта
export 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И вы должны получить обновленный файл .xlsx на стороне клиента Go.
Заключение
В этой статье мы рассмотрели основы настройки связи gRPC между сервером Python и клиентом Go. Используя gRPC, мы разработали простой способ отправки файла Excel из приложения Go на сервер Python, обработки файла с помощью API GPT OpenAI и возврата измененного файла обратно клиенту Go.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3