dwani 0.1.19__tar.gz → 0.1.21__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dwani
3
- Version: 0.1.19
3
+ Version: 0.1.21
4
4
  Summary: Multimodal API for Indian + European languages (Chat, Vision, TTS, ASR, Translate, Docs)
5
5
  Author-email: sachin <python@dwani.ai>
6
6
  License: MIT License
@@ -78,7 +78,7 @@ dwani.api_base = os.getenv("DWANI_API_BASE_URL")
78
78
 
79
79
  #### Document - OCR
80
80
  ```python
81
- result = dwani.Documents.run_ocr_number(file_path="dwani-workshop.pdf", page_number=1, model="gemma3")
81
+ result = dwani.Documents.run_ocr_page(file_path="dwani-workshop.pdf", page_number=1, model="gemma3")
82
82
  print(result)
83
83
  ```
84
84
  ```json
@@ -86,6 +86,17 @@ print(result)
86
86
  ```
87
87
 
88
88
 
89
+ #### Document - Summary
90
+
91
+ ```python
92
+ result = dwani.Documents.summarize_all(
93
+ file_path="dwani-workshop.pdf", model="gemma3" , tgt_lang="english"
94
+ )
95
+
96
+ print("Document Query Response: gemma3- ", result["summary"])
97
+ ```
98
+
99
+
89
100
  ### Text Query
90
101
  ---
91
102
  - gemma3 (default)
@@ -168,4 +179,16 @@ python -m build
168
179
 
169
180
  python -m twine upload dist/*
170
181
 
182
+ -->
183
+
184
+ <!--
185
+ Without Batch
186
+ 2025-07-14 13:39:50,330 - dwani_api - INFO - Request to /indic-summarize-pdf-all took 245.381 seconds
187
+ INFO:dwani_api:Request to /indic-summarize-pdf-all took 245.381 seconds
188
+
189
+ With Batch
190
+
191
+ vllm serve google/gemma-3-4b-it --served-model-name gemma3 --host 0.0.0.0 --port 9000 --gpu-memory-utilization 0.8 --tensor-parallel-size 1 --max-model-len 65536 --dtype bfloat16
192
+
193
+
171
194
  -->
@@ -41,7 +41,7 @@ dwani.api_base = os.getenv("DWANI_API_BASE_URL")
41
41
 
42
42
  #### Document - OCR
43
43
  ```python
44
- result = dwani.Documents.run_ocr_number(file_path="dwani-workshop.pdf", page_number=1, model="gemma3")
44
+ result = dwani.Documents.run_ocr_page(file_path="dwani-workshop.pdf", page_number=1, model="gemma3")
45
45
  print(result)
46
46
  ```
47
47
  ```json
@@ -49,6 +49,17 @@ print(result)
49
49
  ```
50
50
 
51
51
 
52
+ #### Document - Summary
53
+
54
+ ```python
55
+ result = dwani.Documents.summarize_all(
56
+ file_path="dwani-workshop.pdf", model="gemma3" , tgt_lang="english"
57
+ )
58
+
59
+ print("Document Query Response: gemma3- ", result["summary"])
60
+ ```
61
+
62
+
52
63
  ### Text Query
53
64
  ---
54
65
  - gemma3 (default)
@@ -131,4 +142,16 @@ python -m build
131
142
 
132
143
  python -m twine upload dist/*
133
144
 
145
+ -->
146
+
147
+ <!--
148
+ Without Batch
149
+ 2025-07-14 13:39:50,330 - dwani_api - INFO - Request to /indic-summarize-pdf-all took 245.381 seconds
150
+ INFO:dwani_api:Request to /indic-summarize-pdf-all took 245.381 seconds
151
+
152
+ With Batch
153
+
154
+ vllm serve google/gemma-3-4b-it --served-model-name gemma3 --host 0.0.0.0 --port 9000 --gpu-memory-utilization 0.8 --tensor-parallel-size 1 --max-model-len 65536 --dtype bfloat16
155
+
156
+
134
157
  -->
@@ -53,25 +53,36 @@ class translate:
53
53
 
54
54
  class document:
55
55
  @staticmethod
56
- def run_ocr_number(file_path, page_number=1, model="gemma3"):
57
- return _get_client().document_ocr_number(file_path, page_number, model)
56
+ def run_ocr_page(file_path, page_number=1, model="gemma3"):
57
+ return _get_client().document_ocr_page(file_path, page_number, model)
58
58
 
59
59
  @staticmethod
60
60
  def run_ocr_all(file_path, model="gemma3"):
61
61
  return _get_client().document_ocr_all(file_path, model)
62
62
 
63
63
  @staticmethod
64
- def run_summarize(file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
65
- return _get_client().document_summarize(file_path, page_number, src_lang, tgt_lang, model)
64
+ def run_summarize_page(file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
65
+ return _get_client().document_summarize_page(file_path, page_number, tgt_lang, model)
66
+
67
+
68
+ @staticmethod
69
+ def run_summarize_all(file_path, tgt_lang="kan_Knda", model="gemma3"):
70
+ return _get_client().document_summarize_all(file_path, tgt_lang, model)
66
71
 
67
72
  @staticmethod
68
- def run_extract(file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
69
- return _get_client().extract(file_path, page_number, src_lang, tgt_lang, model)
73
+ def run_extract(file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
74
+ return _get_client().extract(file_path, page_number, tgt_lang, model)
75
+
70
76
 
71
77
  @staticmethod
72
- def run_doc_query(file_path, page_number=1, prompt="list the key points", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
73
- return _get_client().doc_query(file_path, page_number, prompt, src_lang, tgt_lang, model)
78
+ def query_page(file_path, page_number=1,prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
79
+ return _get_client().query_page(file_path, page_number, prompt, query_lang, tgt_lang, model)
80
+
81
+
82
+ @staticmethod
83
+ def query_all(file_path, prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
84
+ return _get_client().query_all(file_path, prompt, query_lang, tgt_lang, model)
74
85
 
75
86
  @staticmethod
76
- def run_doc_query_kannada(file_path, page_number=1, prompt="list key points", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
87
+ def run_doc_query_kannada(file_path, page_number=1, prompt="list key points", src_lang="kan_Latn", tgt_lang="kan_Knda", model="gemma3"):
77
88
  return _get_client().doc_query_kannada(file_path, page_number, prompt, src_lang, tgt_lang, model)
@@ -51,17 +51,22 @@ class DwaniClient:
51
51
  from .docs import document_ocr_all
52
52
  return document_ocr_all(self, file_path=file_path, model=model)
53
53
 
54
- def document_summarize(self, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
54
+ def document_summarize(self, file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
55
55
  from .docs import document_summarize
56
- return document_summarize(self, file_path, page_number, src_lang, tgt_lang, model)
56
+ return document_summarize(self, file_path, page_number, tgt_lang, model)
57
57
 
58
- def extract(self, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
58
+ def extract(self, file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
59
59
  from .docs import extract
60
- return extract(self, file_path=file_path, page_number=page_number, src_lang=src_lang, tgt_lang=tgt_lang, model=model)
60
+ return extract(self, file_path=file_path, page_number=page_number, tgt_lang=tgt_lang, model=model)
61
+
62
+ def query_page(self, file_path, page_number=1, prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
63
+ from .docs import query_page
64
+ return query_page(self, file_path, page_number=page_number, prompt=prompt, query_lang=query_lang, tgt_lang=tgt_lang, model=model)
65
+
66
+ def query_all(self, file_path, prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
67
+ from .docs import query_all
68
+ return query_all(self, file_path, prompt=prompt, query_lang=query_lang, tgt_lang=tgt_lang, model=model)
61
69
 
62
- def doc_query(self, file_path, page_number=1, prompt="list the key points", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
63
- from .docs import doc_query
64
- return doc_query(self, file_path, page_number=page_number, prompt=prompt, src_lang=src_lang, tgt_lang=tgt_lang, model=model)
65
70
 
66
71
  def doc_query_kannada(self, file_path, page_number=1, prompt="list key points", src_lang="eng_Latn", language="kan_Knda", model="gemma3"):
67
72
  from .docs import doc_query_kannada
@@ -67,7 +67,7 @@ def document_ocr_all(client, file_path, model="gemma3"):
67
67
  return resp.json()
68
68
 
69
69
 
70
- def document_ocr_number(client, file_path, page_number, model="gemma3"):
70
+ def document_ocr_page(client, file_path, page_number, model="gemma3"):
71
71
  """OCR a document (image/PDF) and return extracted text."""
72
72
  logger.debug(f"Calling document_ocr: file_path={file_path}, model={model}")
73
73
  validate_model(model)
@@ -94,9 +94,10 @@ def document_ocr_number(client, file_path, page_number, model="gemma3"):
94
94
 
95
95
  logger.debug(f"OCR response: {resp.status_code}")
96
96
  return resp.json()
97
- def document_summarize(client, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
97
+
98
+ def document_summarize_page(client, file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
98
99
  """Summarize a PDF document with language and page number options."""
99
- logger.debug(f"Calling document_summarize: file_path={file_path}, page_number={page_number}, src_lang={src_lang}, tgt_lang={tgt_lang}, model={model}")
100
+ logger.debug(f"Calling document_summarize: file_path={file_path}, page_number={page_number}, tgt_lang={tgt_lang}, model={model}")
100
101
  validate_model(model)
101
102
 
102
103
  if not file_path.lower().endswith('.pdf'):
@@ -104,7 +105,6 @@ def document_summarize(client, file_path, page_number=1, src_lang="eng_Latn", tg
104
105
  if page_number < 1:
105
106
  raise ValueError("Page number must be at least 1")
106
107
 
107
- src_lang_code = normalize_language(src_lang)
108
108
  tgt_lang_code = normalize_language(tgt_lang)
109
109
 
110
110
  url = f"{client.api_base}/v1/indic-summarize-pdf"
@@ -113,7 +113,6 @@ def document_summarize(client, file_path, page_number=1, src_lang="eng_Latn", tg
113
113
  files = {"file": (file_path, f, "application/pdf")}
114
114
  data = {
115
115
  "page_number": str(page_number),
116
- "src_lang": src_lang_code,
117
116
  "tgt_lang": tgt_lang_code,
118
117
  "model": model
119
118
  }
@@ -135,9 +134,47 @@ def document_summarize(client, file_path, page_number=1, src_lang="eng_Latn", tg
135
134
 
136
135
  return resp.json()
137
136
 
138
- def extract(client, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
137
+
138
+ def document_summarize_all(client, file_path, tgt_lang="kan_Knda", model="gemma3"):
139
+ """Summarize a PDF document with language """
140
+ logger.debug(f"Calling document_summarize: file_path={file_path}, tgt_lang={tgt_lang}, model={model}")
141
+ validate_model(model)
142
+
143
+ if not file_path.lower().endswith('.pdf'):
144
+ raise ValueError("File must be a PDF")
145
+
146
+ tgt_lang_code = normalize_language(tgt_lang)
147
+
148
+ url = f"{client.api_base}/v1/indic-summarize-pdf-all"
149
+ headers = client._headers()
150
+ with open(file_path, "rb") as f:
151
+ files = {"file": (file_path, f, "application/pdf")}
152
+ data = {
153
+ "tgt_lang": tgt_lang_code,
154
+ "model": model
155
+ }
156
+
157
+ try:
158
+ resp = requests.post(
159
+ url,
160
+ headers=headers,
161
+ files=files,
162
+ data=data,
163
+ timeout=90
164
+ )
165
+ resp.raise_for_status()
166
+ except requests.RequestException as e:
167
+ logger.error(f"Summarize request failed: {str(e)}")
168
+ raise DwaniAPIError(resp) if 'resp' in locals() else DwaniAPIError.from_exception(e)
169
+
170
+ logger.debug(f"Summarize response: {resp.status_code}")
171
+
172
+ return resp.json()
173
+
174
+
175
+ def extract(client, file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
139
176
  """Extract and translate text from a PDF document using form data."""
140
- logger.debug(f"Calling extract: file_path={file_path}, page_number={page_number}, src_lang={src_lang}, tgt_lang={tgt_lang}, model={model}")
177
+ logger.debug(f"Calling extract: file_path={file_path}, page_number={page_number}, tgt_lang={tgt_lang}, model={model}")
141
178
  validate_model(model)
142
179
 
143
180
  if not file_path.lower().endswith('.pdf'):
@@ -145,7 +182,6 @@ def extract(client, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan
145
182
  if page_number < 1:
146
183
  raise ValueError("Page number must be at least 1")
147
184
 
148
- src_lang_code = normalize_language(src_lang)
149
185
  tgt_lang_code = normalize_language(tgt_lang)
150
186
 
151
187
  url = f"{client.api_base}/v1/indic-extract-text/"
@@ -155,7 +191,6 @@ def extract(client, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan
155
191
 
156
192
  data = {
157
193
  "page_number": str(page_number),
158
- "src_lang": src_lang_code,
159
194
  "tgt_lang": tgt_lang_code,
160
195
  "model": model
161
196
  }
@@ -176,17 +211,17 @@ def extract(client, file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan
176
211
 
177
212
  return resp.json()
178
213
 
179
- def doc_query(
214
+ def query_page(
180
215
  client,
181
216
  file_path,
182
217
  page_number=1,
183
218
  prompt="list the key points",
184
- src_lang="eng_Latn",
185
219
  tgt_lang="kan_Knda",
220
+ query_lang="eng_Latn",
186
221
  model="gemma3"
187
222
  ):
188
223
  """Query a document with a custom prompt and language options."""
189
- logger.debug(f"Calling doc_query: file_path={file_path}, page_number={page_number}, prompt={prompt}, src_lang={src_lang}, tgt_lang={tgt_lang}, model={model}")
224
+ logger.debug(f"Calling doc_query: file_path={file_path}, page_number={page_number}, prompt={prompt}, tgt_lang={tgt_lang}, model={model}")
190
225
  validate_model(model)
191
226
 
192
227
  if not file_path.lower().endswith('.pdf'):
@@ -196,9 +231,11 @@ def doc_query(
196
231
  if not prompt.strip():
197
232
  raise ValueError("Prompt cannot be empty")
198
233
 
199
- src_lang_code = normalize_language(src_lang)
200
234
  tgt_lang_code = normalize_language(tgt_lang)
201
235
 
236
+ query_lang_code = normalize_language(query_lang)
237
+
238
+
202
239
  url = f"{client.api_base}/v1/indic-custom-prompt-pdf"
203
240
  headers = client._headers()
204
241
  with open(file_path, "rb") as f:
@@ -206,8 +243,58 @@ def doc_query(
206
243
  data = {
207
244
  "page_number": str(page_number),
208
245
  "prompt": prompt,
209
- "src_lang": src_lang_code,
210
246
  "tgt_lang": tgt_lang_code,
247
+ "query_lang": query_lang_code,
248
+ "model": model
249
+ }
250
+
251
+ try:
252
+ resp = requests.post(
253
+ url,
254
+ headers=headers,
255
+ files=files,
256
+ data=data,
257
+ #params=params,
258
+ timeout=90
259
+ )
260
+ resp.raise_for_status()
261
+ except requests.RequestException as e:
262
+ logger.error(f"Doc query request failed: {str(e)}")
263
+ raise DwaniAPIError(resp) if 'resp' in locals() else DwaniAPIError.from_exception(e)
264
+
265
+ logger.debug(f"Doc query response: {resp.status_code}")
266
+
267
+ return resp.json()
268
+
269
+ def query_all(
270
+ client,
271
+ file_path,
272
+ prompt="list the key points",
273
+ tgt_lang="kan_Knda",
274
+ query_lang="eng_Latn",
275
+ model="gemma3"
276
+ ):
277
+ """Query a document with a custom prompt and language options."""
278
+ logger.debug(f"Calling doc_query: file_path={file_path}, prompt={prompt}, tgt_lang={tgt_lang}, model={model}")
279
+ validate_model(model)
280
+
281
+ if not file_path.lower().endswith('.pdf'):
282
+ raise ValueError("File must be a PDF")
283
+ if not prompt.strip():
284
+ raise ValueError("Prompt cannot be empty")
285
+
286
+ tgt_lang_code = normalize_language(tgt_lang)
287
+
288
+ query_lang_code = normalize_language(query_lang)
289
+
290
+ url = f"{client.api_base}/v1/indic-custom-prompt-pdf-all"
291
+ headers = client._headers()
292
+ with open(file_path, "rb") as f:
293
+ files = {"file": (file_path, f, "application/pdf")}
294
+ data = {
295
+ "prompt": prompt,
296
+ "tgt_lang": tgt_lang_code,
297
+ "query_lang": query_lang_code,
211
298
  "model": model
212
299
  }
213
300
 
@@ -228,17 +315,18 @@ def doc_query(
228
315
 
229
316
  return resp.json()
230
317
 
318
+
231
319
  def doc_query_kannada(
232
320
  client,
233
321
  file_path,
234
322
  page_number=1,
235
323
  prompt="list key points",
236
- src_lang="eng_Latn",
237
324
  tgt_lang="kan_Knda",
325
+ src_lang="kan_Knda",
238
326
  model="gemma3"
239
327
  ):
240
328
  """Query a document with a custom prompt, outputting in Kannada."""
241
- logger.debug(f"Calling doc_query_kannada: file_path={file_path}, page_number={page_number}, prompt={prompt}, src_lang={src_lang}, tgt_lang={tgt_lang}, model={model}")
329
+ logger.debug(f"Calling doc_query_kannada: file_path={file_path}, page_number={page_number}, prompt={prompt}, tgt_lang={tgt_lang}, model={model}")
242
330
  validate_model(model)
243
331
 
244
332
  if not file_path.lower().endswith('.pdf'):
@@ -248,8 +336,10 @@ def doc_query_kannada(
248
336
  if not prompt.strip():
249
337
  raise ValueError("Prompt cannot be empty")
250
338
 
251
- src_lang_code = normalize_language(src_lang)
252
339
  tgt_lang_code = normalize_language(tgt_lang) if tgt_lang else "kan_Knda"
340
+
341
+ src_lang_code = normalize_language(src_lang)
342
+
253
343
 
254
344
  url = f"{client.api_base}/v1/indic-custom-prompt-pdf"
255
345
  headers = client._headers()
@@ -259,8 +349,8 @@ def doc_query_kannada(
259
349
  data = {
260
350
  "page_number": str(page_number),
261
351
  "prompt": prompt,
262
- "src_lang": src_lang_code,
263
352
  "tgt_lang": tgt_lang_code,
353
+ "src_lang": src_lang_code,
264
354
  "model": model
265
355
  }
266
356
  try:
@@ -282,36 +372,50 @@ def doc_query_kannada(
282
372
 
283
373
  class Documents:
284
374
  @staticmethod
285
- def run_ocr_number(file_path, page_number=2,model="gemma3"):
375
+ def run_ocr_number(file_path, page_number=1,model="gemma3"):
286
376
  from .client import DwaniClient
287
377
  client = DwaniClient()
288
- return document_ocr_number(client, file_path, page_number, model)
378
+ return document_ocr_page(client, file_path=file_path, page_number=page_number, model=model)
289
379
  @staticmethod
290
380
  def run_ocr_all(file_path, model="gemma3"):
291
381
  from .client import DwaniClient
292
382
  client = DwaniClient()
293
- return document_ocr_all(client, file_path, model)
383
+ return document_ocr_all(client, file_path=file_path, model=model)
294
384
 
295
385
  @staticmethod
296
- def summarize(file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
386
+ def summarize_page(file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
387
+ from .client import DwaniClient
388
+ client = DwaniClient()
389
+ return document_summarize_page(client, file_path=file_path, page_number=page_number, tgt_lang=tgt_lang, model=model)
390
+
391
+
392
+ @staticmethod
393
+ def summarize_all(file_path, tgt_lang="kan_Knda", model="gemma3"):
394
+ from .client import DwaniClient
395
+ client = DwaniClient()
396
+ return document_summarize_all(client, file_path=file_path, tgt_lang=tgt_lang, model=model)
397
+
398
+ @staticmethod
399
+ def run_extract(file_path, page_number=1, tgt_lang="kan_Knda", model="gemma3"):
297
400
  from .client import DwaniClient
298
401
  client = DwaniClient()
299
- return document_summarize(client, file_path, page_number, src_lang, tgt_lang, model)
402
+ return extract(client, file_path=file_path, page_number=page_number, tgt_lang=tgt_lang, model=model)
300
403
 
301
404
  @staticmethod
302
- def run_extract(file_path, page_number=1, src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
405
+ def query_page(file_path, page_number=1, prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
303
406
  from .client import DwaniClient
304
407
  client = DwaniClient()
305
- return extract(client, file_path, page_number, src_lang, tgt_lang, model)
408
+ return query_page(client, file_path=file_path, page_number=page_number, prompt=prompt, query_lang=query_lang, tgt_lang=tgt_lang, model=model)
306
409
 
307
410
  @staticmethod
308
- def run_doc_query(file_path, page_number=1, prompt="list the key points", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
411
+ def query_all(file_path, prompt="list the key points", query_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
309
412
  from .client import DwaniClient
310
413
  client = DwaniClient()
311
- return doc_query(client, file_path, page_number, prompt, src_lang, tgt_lang, model)
414
+ return query_all(client, file_path=file_path, prompt=prompt, query_lang=query_lang, tgt_lang=tgt_lang, model=model)
312
415
 
416
+
313
417
  @staticmethod
314
- def run_doc_query_kannada(file_path, page_number=1, prompt="list key points", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
418
+ def run_doc_query_kannada(file_path, page_number=1, prompt="list key points", tgt_lang="kan_Knda", model="gemma3"):
315
419
  from .client import DwaniClient
316
420
  client = DwaniClient()
317
- return doc_query_kannada(client, file_path, page_number, prompt, src_lang, tgt_lang, model)
421
+ return doc_query_kannada(client, file_path=file_path, page_number=page_number, prompt=prompt, tgt_lang=tgt_lang, model=model)
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "dwani"
7
7
 
8
- version = "0.1.19"
8
+ version = "0.1.21"
9
9
  description = "Multimodal API for Indian + European languages (Chat, Vision, TTS, ASR, Translate, Docs)"
10
10
  authors = [
11
11
  { name="sachin", email="python@dwani.ai" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes