abhisheksan commited on
Commit
2ce4373
·
1 Parent(s): 085eaf8

Fix: Update poetry.lock to include httpx dependency for proxy service support

Browse files
Files changed (2) hide show
  1. poetry.lock +8 -8
  2. test_endpoints.py +377 -0
poetry.lock CHANGED
@@ -18,7 +18,7 @@ version = "3.7.1"
18
  description = "High level compatibility layer for multiple asynchronous event loop implementations"
19
  optional = false
20
  python-versions = ">=3.7"
21
- groups = ["main", "dev"]
22
  files = [
23
  {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
24
  {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
@@ -156,7 +156,7 @@ version = "2025.8.3"
156
  description = "Python package for providing Mozilla's CA Bundle."
157
  optional = false
158
  python-versions = ">=3.7"
159
- groups = ["main", "dev"]
160
  files = [
161
  {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"},
162
  {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"},
@@ -630,7 +630,7 @@ version = "0.16.0"
630
  description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
631
  optional = false
632
  python-versions = ">=3.8"
633
- groups = ["main", "dev"]
634
  files = [
635
  {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
636
  {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"},
@@ -678,7 +678,7 @@ version = "1.0.9"
678
  description = "A minimal low-level HTTP client."
679
  optional = false
680
  python-versions = ">=3.8"
681
- groups = ["dev"]
682
  files = [
683
  {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
684
  {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"},
@@ -756,7 +756,7 @@ version = "0.25.2"
756
  description = "The next generation HTTP client."
757
  optional = false
758
  python-versions = ">=3.8"
759
- groups = ["dev"]
760
  files = [
761
  {file = "httpx-0.25.2-py3-none-any.whl", hash = "sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118"},
762
  {file = "httpx-0.25.2.tar.gz", hash = "sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8"},
@@ -835,7 +835,7 @@ version = "3.10"
835
  description = "Internationalized Domain Names in Applications (IDNA)"
836
  optional = false
837
  python-versions = ">=3.6"
838
- groups = ["main", "dev"]
839
  files = [
840
  {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
841
  {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
@@ -2443,7 +2443,7 @@ version = "1.3.1"
2443
  description = "Sniff out which async library your code is running under"
2444
  optional = false
2445
  python-versions = ">=3.7"
2446
- groups = ["main", "dev"]
2447
  files = [
2448
  {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
2449
  {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
@@ -3206,4 +3206,4 @@ test = ["pytest (>=8.1,<9.0)", "pytest-rerunfailures (>=14.0,<15.0)"]
3206
  [metadata]
3207
  lock-version = "2.1"
3208
  python-versions = "^3.11"
3209
- content-hash = "ebb16163670f970e4d506a8230fbb256edc8d5a749255bbbc9dc9cd17fc870eb"
 
18
  description = "High level compatibility layer for multiple asynchronous event loop implementations"
19
  optional = false
20
  python-versions = ">=3.7"
21
+ groups = ["main"]
22
  files = [
23
  {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
24
  {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
 
156
  description = "Python package for providing Mozilla's CA Bundle."
157
  optional = false
158
  python-versions = ">=3.7"
159
+ groups = ["main"]
160
  files = [
161
  {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"},
162
  {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"},
 
630
  description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
631
  optional = false
632
  python-versions = ">=3.8"
633
+ groups = ["main"]
634
  files = [
635
  {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
636
  {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"},
 
678
  description = "A minimal low-level HTTP client."
679
  optional = false
680
  python-versions = ">=3.8"
681
+ groups = ["main"]
682
  files = [
683
  {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
684
  {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"},
 
756
  description = "The next generation HTTP client."
757
  optional = false
758
  python-versions = ">=3.8"
759
+ groups = ["main"]
760
  files = [
761
  {file = "httpx-0.25.2-py3-none-any.whl", hash = "sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118"},
762
  {file = "httpx-0.25.2.tar.gz", hash = "sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8"},
 
835
  description = "Internationalized Domain Names in Applications (IDNA)"
836
  optional = false
837
  python-versions = ">=3.6"
838
+ groups = ["main"]
839
  files = [
840
  {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
841
  {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
 
2443
  description = "Sniff out which async library your code is running under"
2444
  optional = false
2445
  python-versions = ">=3.7"
2446
+ groups = ["main"]
2447
  files = [
2448
  {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
2449
  {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
 
3206
  [metadata]
3207
  lock-version = "2.1"
3208
  python-versions = "^3.11"
3209
+ content-hash = "7ca1372ab8050eedee965f5b1059f004ace52d36c44c0f6f00e042a4d5a0b35e"
test_endpoints.py ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Test file for Multi-Utility Server endpoints.
3
+ Test both Subtitles and Embeddings APIs with the deployed server.
4
+
5
+ Usage:
6
+ python test_endpoints.py
7
+
8
+ Modify the test data in the TEST_DATA section to test different inputs.
9
+ """
10
+
11
+ import json
12
+ import os
13
+ from pathlib import Path
14
+ from typing import Any, Dict, List
15
+
16
+ import requests
17
+
18
+ # ============================================================================
19
+ # CONFIGURATION
20
+ # ============================================================================
21
+
22
+ BASE_URL = "https://abhisheksan-multiutility-server.hf.space"
23
+ API_KEY = "zL6Rod5869J0" # Replace with your actual API key
24
+
25
+ # ============================================================================
26
+ # TEST DATA - MODIFY THESE TO TEST DIFFERENT INPUTS
27
+ # ============================================================================
28
+
29
+ # Test data for Subtitles API
30
+ SUBTITLE_TEST_DATA = {
31
+ "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
32
+ "lang": "en",
33
+ }
34
+
35
+ # Test data for Embeddings API
36
+ EMBEDDING_TEST_DATA = {
37
+ "texts": [
38
+ "Hello, how are you?",
39
+ "Machine learning is fascinating",
40
+ "Python is a great programming language",
41
+ ],
42
+ "normalize": True,
43
+ }
44
+
45
+ # ============================================================================
46
+ # HELPER FUNCTIONS
47
+ # ============================================================================
48
+
49
+
50
+ def print_section(title: str):
51
+ """Print a formatted section header."""
52
+ print("\n" + "=" * 80)
53
+ print(f" {title}")
54
+ print("=" * 80 + "\n")
55
+
56
+
57
+ def print_response(response: requests.Response):
58
+ """Print formatted response details."""
59
+ print(f"Status Code: {response.status_code}")
60
+ print(f"Response Time: {response.elapsed.total_seconds():.2f}s")
61
+ print("\nResponse Headers:")
62
+ for key, value in response.headers.items():
63
+ print(f" {key}: {value}")
64
+ print("\nResponse Body:")
65
+ try:
66
+ print(json.dumps(response.json(), indent=2))
67
+ except Exception:
68
+ print(response.text)
69
+
70
+
71
+ def make_request(
72
+ method: str,
73
+ endpoint: str,
74
+ data: Dict[str, Any] = None,
75
+ headers: Dict[str, str] = None,
76
+ ) -> requests.Response:
77
+ """Make HTTP request to the API."""
78
+ url = f"{BASE_URL}{endpoint}"
79
+ default_headers = {"Content-Type": "application/json", "X-API-Key": API_KEY}
80
+
81
+ if headers:
82
+ default_headers.update(headers)
83
+
84
+ try:
85
+ if method.upper() == "GET":
86
+ response = requests.get(url, headers=default_headers)
87
+ elif method.upper() == "POST":
88
+ response = requests.post(url, json=data, headers=default_headers)
89
+ else:
90
+ raise ValueError(f"Unsupported HTTP method: {method}")
91
+
92
+ return response
93
+ except requests.exceptions.RequestException as e:
94
+ print(f"❌ Request failed: {str(e)}")
95
+ raise
96
+
97
+
98
+ # ============================================================================
99
+ # TEST FUNCTIONS
100
+ # ============================================================================
101
+
102
+
103
+ def test_health_check():
104
+ """Test the main health check endpoint."""
105
+ print_section("TEST: Health Check")
106
+
107
+ try:
108
+ response = make_request("GET", "/health")
109
+ print_response(response)
110
+
111
+ if response.status_code == 200:
112
+ print("\n✅ Health check passed!")
113
+ else:
114
+ print("\n❌ Health check failed!")
115
+ except Exception as e:
116
+ print(f"\n❌ Test failed with error: {str(e)}")
117
+
118
+
119
+ def test_root_endpoint():
120
+ """Test the root endpoint."""
121
+ print_section("TEST: Root Endpoint")
122
+
123
+ try:
124
+ response = make_request("GET", "/")
125
+ print_response(response)
126
+
127
+ if response.status_code == 200:
128
+ print("\n✅ Root endpoint test passed!")
129
+ else:
130
+ print("\n❌ Root endpoint test failed!")
131
+ except Exception as e:
132
+ print(f"\n❌ Test failed with error: {str(e)}")
133
+
134
+
135
+ def test_subtitles_health():
136
+ """Test the subtitles service health check."""
137
+ print_section("TEST: Subtitles Health Check")
138
+
139
+ try:
140
+ response = make_request("GET", "/api/v1/subtitles/health")
141
+ print_response(response)
142
+
143
+ if response.status_code == 200:
144
+ print("\n✅ Subtitles health check passed!")
145
+ else:
146
+ print("\n❌ Subtitles health check failed!")
147
+ except Exception as e:
148
+ print(f"\n❌ Test failed with error: {str(e)}")
149
+
150
+
151
+ def test_audio_transcription():
152
+ """Test the audio file transcription endpoint."""
153
+ print_section("TEST: Audio File Transcription")
154
+
155
+ # Create a small test audio file (silent WAV)
156
+ # This is a minimal WAV file header for a 1-second silent audio
157
+ print("Creating test audio file...")
158
+ test_audio = b"RIFF$\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x00\x00\x00\x00"
159
+
160
+ test_file_path = "test_audio.wav"
161
+
162
+ try:
163
+ # Write test audio file
164
+ with open(test_file_path, "wb") as f:
165
+ f.write(test_audio)
166
+
167
+ print(f"Test file created: {test_file_path}")
168
+ print("Note: Using minimal WAV file for testing\n")
169
+
170
+ # Make request with file upload
171
+ url = f"{BASE_URL}/api/v1/subtitles/transcribe"
172
+ headers = {"X-API-Key": API_KEY}
173
+
174
+ with open(test_file_path, "rb") as f:
175
+ files = {"file": ("test_audio.wav", f, "audio/wav")}
176
+ data = {"lang": "en"}
177
+
178
+ response = requests.post(url, headers=headers, files=files, data=data)
179
+
180
+ print_response(response)
181
+
182
+ if response.status_code == 200:
183
+ data = response.json()
184
+ transcription_count = len(data.get("transcription", []))
185
+ print(f"\n✅ Audio transcription passed!")
186
+ print(f" - Language: {data.get('language')}")
187
+ print(f" - File name: {data.get('file_name')}")
188
+ print(f" - Number of segments: {transcription_count}")
189
+
190
+ # Print transcription segments
191
+ if transcription_count > 0:
192
+ print(f"\n Transcription segments:")
193
+ for i, line in enumerate(data.get("transcription", [])[:5]):
194
+ print(f" {i + 1}. {line}")
195
+ else:
196
+ print(" (No transcription - test audio is silent)")
197
+ else:
198
+ print("\n❌ Audio transcription failed!")
199
+ except Exception as e:
200
+ print(f"\n❌ Test failed with error: {str(e)}")
201
+ finally:
202
+ # Cleanup test file
203
+ if os.path.exists(test_file_path):
204
+ os.remove(test_file_path)
205
+ print(f"\n Cleaned up test file: {test_file_path}")
206
+
207
+
208
+ def test_subtitles_extract():
209
+ """Test the subtitles extraction endpoint."""
210
+ print_section("TEST: Extract Subtitles")
211
+
212
+ print("Test Data:")
213
+ print(json.dumps(SUBTITLE_TEST_DATA, indent=2))
214
+ print()
215
+
216
+ try:
217
+ response = make_request(
218
+ "POST", "/api/v1/subtitles/extract", data=SUBTITLE_TEST_DATA
219
+ )
220
+ print_response(response)
221
+
222
+ if response.status_code == 200:
223
+ data = response.json()
224
+ subtitle_count = len(data.get("subtitles", []))
225
+ print(f"\n✅ Subtitles extraction passed!")
226
+ print(f" - Video ID: {data.get('video_id')}")
227
+ print(f" - Language: {data.get('language')}")
228
+ print(f" - Number of subtitle lines: {subtitle_count}")
229
+
230
+ # Print first few subtitle lines
231
+ if subtitle_count > 0:
232
+ print(f"\n First 5 subtitle lines:")
233
+ for i, line in enumerate(data.get("subtitles", [])[:5]):
234
+ print(f" {i + 1}. {line}")
235
+ else:
236
+ print("\n❌ Subtitles extraction failed!")
237
+ except Exception as e:
238
+ print(f"\n❌ Test failed with error: {str(e)}")
239
+
240
+
241
+ def test_embeddings_health():
242
+ """Test the embeddings service health check."""
243
+ print_section("TEST: Embeddings Health Check")
244
+
245
+ try:
246
+ response = make_request("GET", "/api/v1/embeddings/health")
247
+ print_response(response)
248
+
249
+ if response.status_code == 200:
250
+ print("\n✅ Embeddings health check passed!")
251
+ else:
252
+ print("\n❌ Embeddings health check failed!")
253
+ except Exception as e:
254
+ print(f"\n❌ Test failed with error: {str(e)}")
255
+
256
+
257
+ def test_embeddings_generate():
258
+ """Test the embeddings generation endpoint."""
259
+ print_section("TEST: Generate Embeddings")
260
+
261
+ print("Test Data:")
262
+ print(json.dumps(EMBEDDING_TEST_DATA, indent=2))
263
+ print()
264
+
265
+ try:
266
+ response = make_request(
267
+ "POST", "/api/v1/embeddings/generate", data=EMBEDDING_TEST_DATA
268
+ )
269
+ print_response(response)
270
+
271
+ if response.status_code == 200:
272
+ data = response.json()
273
+ embeddings = data.get("embeddings", [])
274
+ print(f"\n✅ Embeddings generation passed!")
275
+ print(f" - Model: {data.get('model')}")
276
+ print(f" - Dimensions: {data.get('dimensions')}")
277
+ print(f" - Number of embeddings: {len(embeddings)}")
278
+
279
+ # Print shape of embeddings
280
+ if embeddings:
281
+ print(f"\n Embedding shapes:")
282
+ for i, emb in enumerate(embeddings):
283
+ print(f" Text {i + 1}: {len(emb)} dimensions")
284
+ print(f" First 5 values: {emb[:5]}")
285
+ else:
286
+ print("\n❌ Embeddings generation failed!")
287
+ except Exception as e:
288
+ print(f"\n❌ Test failed with error: {str(e)}")
289
+
290
+
291
+ def test_error_handling():
292
+ """Test error handling with invalid data."""
293
+ print_section("TEST: Error Handling")
294
+
295
+ print("Testing with invalid subtitle URL...")
296
+ invalid_subtitle_data = {"url": "https://invalid-url.com/video", "lang": "en"}
297
+
298
+ try:
299
+ response = make_request(
300
+ "POST", "/api/v1/subtitles/extract", data=invalid_subtitle_data
301
+ )
302
+ print_response(response)
303
+
304
+ if response.status_code >= 400:
305
+ print("\n✅ Error handling works correctly!")
306
+ else:
307
+ print("\n⚠️ Expected error response but got success!")
308
+ except Exception as e:
309
+ print(f"\n✅ Error handling works: {str(e)}")
310
+
311
+ print("\n" + "-" * 80 + "\n")
312
+ print("Testing with empty embeddings text list...")
313
+ invalid_embedding_data = {"texts": [], "normalize": True}
314
+
315
+ try:
316
+ response = make_request(
317
+ "POST", "/api/v1/embeddings/generate", data=invalid_embedding_data
318
+ )
319
+ print_response(response)
320
+
321
+ if response.status_code >= 400:
322
+ print("\n✅ Error handling works correctly!")
323
+ else:
324
+ print("\n⚠️ Expected error response but got success!")
325
+ except Exception as e:
326
+ print(f"\n✅ Error handling works: {str(e)}")
327
+
328
+
329
+ # ============================================================================
330
+ # MAIN TEST RUNNER
331
+ # ============================================================================
332
+
333
+
334
+ def run_all_tests():
335
+ """Run all test functions."""
336
+ print("\n")
337
+ print("+" + "=" * 78 + "+")
338
+ print("|" + " " * 20 + "MULTI-UTILITY SERVER API TESTS" + " " * 28 + "|")
339
+ print("+" + "=" * 78 + "+")
340
+ print(f"\nBase URL: {BASE_URL}")
341
+ print(
342
+ f"API Key: {'*' * len(API_KEY) if API_KEY != 'your-api-key-here' else 'NOT SET'}"
343
+ )
344
+
345
+ if API_KEY == "your-api-key-here":
346
+ print("\n⚠️ WARNING: Please set your API key in the API_KEY variable!")
347
+ print(" Some tests may fail without a valid API key.\n")
348
+
349
+ # Run all tests
350
+ test_health_check()
351
+ test_root_endpoint()
352
+ test_subtitles_health()
353
+ test_subtitles_extract()
354
+ test_audio_transcription()
355
+ test_embeddings_health()
356
+ test_embeddings_generate()
357
+ test_error_handling()
358
+
359
+ # Summary
360
+ print_section("TEST SUMMARY")
361
+ print("All tests completed!")
362
+ print(
363
+ "\nTo modify test inputs, edit the TEST_DATA section at the top of this file."
364
+ )
365
+ print("\nAvailable endpoints:")
366
+ print(f" - GET {BASE_URL}/health")
367
+ print(f" - GET {BASE_URL}/")
368
+ print(f" - GET {BASE_URL}/api/v1/subtitles/health")
369
+ print(f" - POST {BASE_URL}/api/v1/subtitles/extract (requires network access)")
370
+ print(f" - POST {BASE_URL}/api/v1/subtitles/transcribe (upload audio file)")
371
+ print(f" - GET {BASE_URL}/api/v1/embeddings/health")
372
+ print(f" - POST {BASE_URL}/api/v1/embeddings/generate")
373
+ print()
374
+
375
+
376
+ if __name__ == "__main__":
377
+ run_all_tests()