github.com/weaviate/weaviate@v1.24.6/modules/multi2vec-clip/clients/vectorizer.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package clients 13 14 import ( 15 "bytes" 16 "context" 17 "encoding/json" 18 "fmt" 19 "io" 20 "net/http" 21 "time" 22 23 "github.com/pkg/errors" 24 "github.com/sirupsen/logrus" 25 "github.com/weaviate/weaviate/modules/multi2vec-clip/ent" 26 ) 27 28 type vectorizer struct { 29 origin string 30 httpClient *http.Client 31 logger logrus.FieldLogger 32 } 33 34 func New(origin string, timeout time.Duration, logger logrus.FieldLogger) *vectorizer { 35 return &vectorizer{ 36 origin: origin, 37 httpClient: &http.Client{ 38 Timeout: timeout, 39 }, 40 logger: logger, 41 } 42 } 43 44 func (v *vectorizer) Vectorize(ctx context.Context, 45 texts, images []string, config ent.VectorizationConfig, 46 ) (*ent.VectorizationResult, error) { 47 body, err := json.Marshal(vecRequest{ 48 Texts: texts, 49 Images: images, 50 }) 51 if err != nil { 52 return nil, errors.Wrapf(err, "marshal body") 53 } 54 55 req, err := http.NewRequestWithContext(ctx, "POST", v.url("/vectorize", config.InferenceURL), 56 bytes.NewReader(body)) 57 if err != nil { 58 return nil, errors.Wrap(err, "create POST request") 59 } 60 61 res, err := v.httpClient.Do(req) 62 if err != nil { 63 return nil, errors.Wrap(err, "send POST request") 64 } 65 defer res.Body.Close() 66 67 bodyBytes, err := io.ReadAll(res.Body) 68 if err != nil { 69 return nil, errors.Wrap(err, "read response body") 70 } 71 72 var resBody vecResponse 73 if err := json.Unmarshal(bodyBytes, &resBody); err != nil { 74 return nil, errors.Wrap(err, "unmarshal response body") 75 } 76 77 if res.StatusCode > 399 { 78 return nil, errors.Errorf("fail with status %d: %s", res.StatusCode, 79 resBody.Error) 80 } 81 82 return &ent.VectorizationResult{ 83 TextVectors: resBody.TextVectors, 84 ImageVectors: resBody.ImageVectors, 85 }, nil 86 } 87 88 func (v *vectorizer) url(path string, inferenceURL string) string { 89 if inferenceURL != "" { 90 return fmt.Sprintf("%s%s", inferenceURL, path) 91 } 92 return fmt.Sprintf("%s%s", v.origin, path) 93 } 94 95 type vecRequest struct { 96 Texts []string `json:"texts"` 97 Images []string `json:"images"` 98 } 99 100 type vecResponse struct { 101 TextVectors [][]float32 `json:"textVectors"` 102 ImageVectors [][]float32 `json:"imageVectors"` 103 Error string `json:"error"` 104 }