go-chatgpt
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.4 KiB

  1. package gogpt
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "io"
  7. "mime/multipart"
  8. "net/http"
  9. "os"
  10. )
  11. // Whisper Defines the models provided by OpenAI to use when processing audio with OpenAI.
  12. const (
  13. Whisper1 = "whisper-1"
  14. )
  15. // AudioRequest represents a request structure for audio API.
  16. type AudioRequest struct {
  17. Model string
  18. FilePath string
  19. }
  20. // AudioResponse represents a response structure for audio API.
  21. type AudioResponse struct {
  22. Text string `json:"text"`
  23. }
  24. // CreateTranscription — API call to create a transcription. Returns transcribed text.
  25. func (c *Client) CreateTranscription(
  26. ctx context.Context,
  27. request AudioRequest,
  28. ) (response AudioResponse, err error) {
  29. response, err = c.callAudioAPI(ctx, request, "transcriptions")
  30. return
  31. }
  32. // CreateTranslation — API call to translate audio into English.
  33. func (c *Client) CreateTranslation(
  34. ctx context.Context,
  35. request AudioRequest,
  36. ) (response AudioResponse, err error) {
  37. response, err = c.callAudioAPI(ctx, request, "translations")
  38. return
  39. }
  40. // callAudioAPI — API call to an audio endpoint.
  41. func (c *Client) callAudioAPI(
  42. ctx context.Context,
  43. request AudioRequest,
  44. endpointSuffix string,
  45. ) (response AudioResponse, err error) {
  46. var formBody bytes.Buffer
  47. w := multipart.NewWriter(&formBody)
  48. if err = audioMultipartForm(request, w); err != nil {
  49. return
  50. }
  51. urlSuffix := fmt.Sprintf("/audio/%s", endpointSuffix)
  52. req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.fullURL(urlSuffix), &formBody)
  53. if err != nil {
  54. return
  55. }
  56. req.Header.Add("Content-Type", w.FormDataContentType())
  57. err = c.sendRequest(req, &response)
  58. return
  59. }
  60. // audioMultipartForm creates a form with audio file contents and the name of the model to use for
  61. // audio processing.
  62. func audioMultipartForm(request AudioRequest, w *multipart.Writer) error {
  63. f, err := os.Open(request.FilePath)
  64. if err != nil {
  65. return fmt.Errorf("opening audio file: %w", err)
  66. }
  67. fw, err := w.CreateFormFile("file", f.Name())
  68. if err != nil {
  69. return fmt.Errorf("creating form file: %w", err)
  70. }
  71. if _, err = io.Copy(fw, f); err != nil {
  72. return fmt.Errorf("reading from opened audio file: %w", err)
  73. }
  74. fw, err = w.CreateFormField("model")
  75. if err != nil {
  76. return fmt.Errorf("creating form field: %w", err)
  77. }
  78. modelName := bytes.NewReader([]byte(request.Model))
  79. if _, err = io.Copy(fw, modelName); err != nil {
  80. return fmt.Errorf("writing model name: %w", err)
  81. }
  82. w.Close()
  83. return nil
  84. }