dwani 0.1.10__py3-none-any.whl → 0.1.12__py3-none-any.whl

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.
dwani/__init__.py CHANGED
@@ -24,6 +24,9 @@ class chat:
24
24
  @staticmethod
25
25
  def create(prompt, src_lang, tgt_lang, model="gemma3"):
26
26
  return _get_client().chat(prompt, src_lang, tgt_lang, model)
27
+ @staticmethod
28
+ def direct(prompt, model="gemma3", system_prompt =""):
29
+ return _get_client().chat_direct(prompt, model, system_prompt)
27
30
 
28
31
  class audio:
29
32
  @staticmethod
@@ -34,6 +37,9 @@ class vision:
34
37
  @staticmethod
35
38
  def caption(file_path, query="describe the image", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
36
39
  return _get_client().caption(file_path, query, src_lang, tgt_lang, model)
40
+ @staticmethod
41
+ def caption_direct(file_path, query="describe the image", model="gemma3", system_prompt=""):
42
+ return _get_client().caption_direct(file_path, query, model, system_prompt)
37
43
 
38
44
  class asr:
39
45
  @staticmethod
dwani/chat.py CHANGED
@@ -36,9 +36,25 @@ def normalize_language(lang):
36
36
  supported_langs = list(lang_name_to_code.keys()) + list(lang_code_to_code.keys())
37
37
  raise ValueError(f"Unsupported language: {lang}. Supported languages: {supported_langs}")
38
38
 
39
+ def chat_direct(client, prompt, model="gemma3", system_prompt=""):
40
+ url = f"{client.api_base}/v1/chat_direct"
41
+ payload = {
42
+ "prompt": prompt,
43
+ "model": model,
44
+ "system_prompt":system_prompt
45
+ }
46
+ resp = requests.post(
47
+ url,
48
+ headers={**client._headers(), "Content-Type": "application/json"},
49
+ json=payload
50
+ )
51
+ if resp.status_code != 200:
52
+ raise DwaniAPIError(resp)
53
+ return resp.json()
54
+
39
55
  def chat_create(client, prompt, src_lang, tgt_lang, model="gemma3"):
40
56
  # Validate model
41
- valid_models = ["gemma3", "qwen3", "deepseek-r1"]
57
+ valid_models = ["gemma3", "qwen3", "deepseek-r1", "sarvam-m"]
42
58
  if model not in valid_models:
43
59
  raise ValueError(f"Unsupported model: {model}. Supported models: {valid_models}")
44
60
 
@@ -66,4 +82,8 @@ class Chat:
66
82
  @staticmethod
67
83
  def create(prompt, src_lang, tgt_lang, model="gemma3"):
68
84
  from . import _get_client
69
- return _get_client().chat(prompt, src_lang, tgt_lang, model)
85
+ return _get_client().chat(prompt, src_lang, tgt_lang, model)
86
+ @staticmethod
87
+ def direct(prompt, model="gemma3", system_prompt=""):
88
+ from . import _get_client
89
+ return _get_client().chat_direct(prompt, model, system_prompt)
dwani/client.py CHANGED
@@ -22,7 +22,12 @@ class DwaniClient:
22
22
  def chat(self, prompt, src_lang, tgt_lang, model="gemma3"):
23
23
  from .chat import chat_create
24
24
  return chat_create(self, prompt=prompt, src_lang=src_lang, tgt_lang=tgt_lang, model=model)
25
-
25
+
26
+
27
+ def chat_direct(self, prompt, model="gemma3", system_prompt=""):
28
+ from .chat import chat_direct
29
+ return chat_direct(self, prompt=prompt, model=model, system_prompt=system_prompt)
30
+
26
31
  def speech(self, input, response_format="mp3"):
27
32
  from .audio import audio_speech
28
33
  return audio_speech(self, input=input, response_format=response_format)
@@ -31,6 +36,10 @@ class DwaniClient:
31
36
  from .vision import vision_caption
32
37
  return vision_caption(self, file_path=file_path, query=query, src_lang=src_lang, tgt_lang=tgt_lang, model=model)
33
38
 
39
+ def caption_direct(self, file_path, query="describe the image", model="gemma3", system_prompt=""):
40
+ from .vision import vision_direct
41
+ return vision_direct(self, file_path=file_path, query=query, model=model, system_prompt=system_prompt)
42
+
34
43
  def transcribe(self, file_path, language=None):
35
44
  from .asr import asr_transcribe
36
45
  return asr_transcribe(self, file_path=file_path, language=language)
dwani/translate.py CHANGED
@@ -25,21 +25,27 @@ lang_code_to_code = {code: code for _, code in language_options}
25
25
  def normalize_language(lang):
26
26
  """Convert language input (name or code) to language code."""
27
27
  lang = lang.strip()
28
- # Check if input is a language name (case-insensitive)
29
28
  lang_lower = lang.lower()
30
29
  if lang_lower in lang_name_to_code:
31
30
  return lang_name_to_code[lang_lower]
32
- # Check if input is a language code
33
31
  if lang in lang_code_to_code:
34
32
  return lang_code_to_code[lang]
35
- # Raise error if language is not supported
36
33
  supported_langs = list(lang_name_to_code.keys()) + list(lang_code_to_code.keys())
37
34
  raise ValueError(f"Unsupported language: {lang}. Supported languages: {supported_langs}")
38
35
 
36
+ def split_into_sentences(text):
37
+ """Split a string into sentences based on full stops."""
38
+ if not text.strip():
39
+ return []
40
+ # Split on full stops, preserving non-empty sentences
41
+ sentences = [s.strip() for s in text.split('.') if s.strip()]
42
+ return sentences
43
+
39
44
  def run_translate(client, sentences, src_lang, tgt_lang):
40
- # Convert single string to list if necessary
45
+ """Translate sentences in a single API call."""
46
+ # Convert single string to list of sentences if necessary
41
47
  if isinstance(sentences, str):
42
- sentences = [sentences]
48
+ sentences = split_into_sentences(sentences)
43
49
  elif not isinstance(sentences, list):
44
50
  raise ValueError("sentences must be a string or a list of strings")
45
51
 
@@ -70,4 +76,4 @@ class Translate:
70
76
  @staticmethod
71
77
  def run_translate(sentences, src_lang, tgt_lang):
72
78
  from . import _get_client
73
- return _get_client().translate(sentences, src_lang, tgt_lang)
79
+ return run_translate(_get_client(), sentences, src_lang, tgt_lang)
dwani/vision.py CHANGED
@@ -36,9 +36,32 @@ def normalize_language(lang):
36
36
  supported_langs = list(lang_name_to_code.keys()) + list(lang_code_to_code.keys())
37
37
  raise ValueError(f"Unsupported language: {lang}. Supported languages: {supported_langs}")
38
38
 
39
+ def vision_direct(client, file_path, query="describe this image", model="gemma3", system_prompt=""):
40
+ url = (
41
+ f"{client.api_base}/v1/visual_query_direct"
42
+ f"?model={model}"
43
+ )
44
+ headers = {
45
+ **client._headers(),
46
+ "accept": "application/json"
47
+ }
48
+ with open(file_path, "rb") as f:
49
+ files = {"file": (file_path, f, "image/png")}
50
+ data = {"query": query, "system_prompt": system_prompt}
51
+ resp = requests.post(
52
+ url,
53
+ headers=headers,
54
+ files=files,
55
+ data=data
56
+ )
57
+ if resp.status_code != 200:
58
+ raise DwaniAPIError(resp)
59
+ return resp.json()
60
+
61
+
39
62
  def vision_caption(client, file_path, query="describe the image", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
40
63
  # Validate model
41
- valid_models = ["gemma3", "qwen2.5vl", "moondream"]
64
+ valid_models = ["gemma3", "qwen2.5vl", "moondream", "smolvla"]
42
65
  if model not in valid_models:
43
66
  raise ValueError(f"Unsupported model: {model}. Supported models: {valid_models}")
44
67
 
@@ -72,4 +95,8 @@ class Vision:
72
95
  @staticmethod
73
96
  def caption(file_path, query="describe the image", src_lang="eng_Latn", tgt_lang="kan_Knda", model="gemma3"):
74
97
  from . import _get_client
75
- return _get_client().caption(file_path, query, src_lang, tgt_lang, model)
98
+ return _get_client().caption(file_path, query, src_lang, tgt_lang, model)
99
+ @staticmethod
100
+ def caption_direct(file_path, query="describe the image", model="gemma3", system_prompt=""):
101
+ from . import _get_client
102
+ return _get_client().caption_direct(file_path, query, model, system_prompt)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dwani
3
- Version: 0.1.10
3
+ Version: 0.1.12
4
4
  Summary: Multimodal API for Indian languages (Chat, Vision, TTS, ASR, Translate, Docs)
5
5
  Author-email: sachin <python@dwani.ai>
6
6
  License: MIT License
@@ -39,7 +39,7 @@ Dynamic: license-file
39
39
 
40
40
  ### Install the library
41
41
  ```bash
42
- pip install dwani
42
+ pip install --upgrade dwani
43
43
  ```
44
44
 
45
45
  ### Languages supported
@@ -59,10 +59,10 @@ dwani.api_base = os.getenv("DWANI_API_BASE_URL")
59
59
  ### Text Query
60
60
  ---
61
61
  - With model selection
62
- - Supported models : gemma3 (default), qwen3, deepseek-r1-8b, sarvam-m
62
+ - gemma3 (default), qwen3, sarvam-m
63
63
 
64
64
  ---
65
- - gemma3
65
+ - gemma3 - with translation
66
66
  ```python
67
67
  resp = dwani.Chat.create(prompt="Hello!", src_lang="english", tgt_lang="kannada", model="gemma3")
68
68
  print(resp)
@@ -70,13 +70,23 @@ print(resp)
70
70
  ```json
71
71
  {'response': 'ನಮಸ್ತೆ! ಭಾರತ ಮತ್ತು ಕರ್ನಾಟಕವನ್ನು ಗಮನದಲ್ಲಿಟ್ಟುಕೊಂಡು ಇಂದು ನಿಮ್ಮ ಪ್ರಶ್ನೆಗಳಿಗೆ ನಾನು ನಿಮಗೆ ಹೇಗೆ ಸಹಾಯ ಮಾಡಲಿ?'}
72
72
  ```
73
+
74
+ - gemma3 - without translation
75
+ ```python
76
+ resp = dwani.Chat.direct(prompt="Hello!", model="gemma3")
77
+ print(resp)
78
+ ```
79
+ ```json
80
+ {'response': 'Hello! I am Dwani, ready to assist you with information pertaining to India, specifically Karnataka. '}
81
+ ```
82
+
73
83
  ---
74
84
  ### Vision Query
75
85
  ---
76
86
  - With model selection
77
- - Supported models : gemma3 (default), moondream
78
- - gemma3
87
+ - gemma3 (default), moondream, smolvla
79
88
 
89
+ - gemma3 - with translation
80
90
  ```python
81
91
  result = dwani.Vision.caption(
82
92
  file_path="image.png",
@@ -90,6 +100,19 @@ print(result)
90
100
  ```json
91
101
  {'answer': 'ಒಂದು ವಾಕ್ಯದಲ್ಲಿ ಚಿತ್ರದ ಸಾರಾಂಶವನ್ನು ಇಲ್ಲಿ ನೀಡಲಾಗಿದೆಃ ಪ್ರಕಟಣೆಯ ಅವಲೋಕನವು ಪ್ರಸ್ತುತ ಅರವತ್ತನಾಲ್ಕು ದೇಶಗಳು/ಪ್ರದೇಶಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ ಮತ್ತು ಇನ್ನೂ ಹದಿನಾರು ಪ್ರದೇಶಗಳನ್ನು ಸೇರಿಸಬೇಕಾಗಿದೆ. ಒದಗಿಸಲಾದ ಚಿತ್ರದಲ್ಲಿ ಲಾಂಛನವು ಕಾಣಿಸುವುದಿಲ್ಲ.'}
92
102
  ```
103
+ - gemma3 - without translation
104
+ ```python
105
+ result = dwani.Vision.caption_direct(
106
+ file_path="image.png",
107
+ query="Describe this logo",
108
+ model="gemma3"
109
+ )
110
+ print(result)
111
+ ```
112
+ ```json
113
+ {'answer': 'The logo displays a publishing overview stating that changes are under review, with a production rollout initiated at version sixty-four point one point one, expanding to sixteen countries/regions including Australia and Bangladesh.'}
114
+ ```
115
+
93
116
  ---
94
117
  ### Speech to Text - Automatic Speech Recognition (ASR)
95
118
  ---
@@ -108,13 +131,13 @@ resp = dwani.Translate.run_translate(sentences="hi, i am gaganyatri", src_lang="
108
131
  print(resp)
109
132
  ```
110
133
  ```json
111
- {'translations': ['ಹಾಯ್']}
134
+ {'translations': ['ಹಾಯ್, ನಾನು ಗಗನಯಾತ್ರಿ']}
112
135
  ```
113
136
  ---
114
137
  ### Text to Speech - Speech Synthesis
115
138
  ---
116
139
  ```python
117
- response = dwani.Audio.speech(input="ಕರ್ನಾಟಕ ರಾಜಧಾನಿ ಯಾವುದು", response_format="wav")
140
+ response = dwani.Audio.speech(input="ಕರ್ನಾಟಕದ ರಾಜಧಾನಿ ಯಾವುದು", response_format="wav")
118
141
  with open("output.wav", "wb") as f:
119
142
  f.write(response)
120
143
  ```
@@ -0,0 +1,14 @@
1
+ dwani/__init__.py,sha256=8Q1qdF0g6xWEy1_PK6qxG-EeZUp_QOwYBqNv_y6EyHI,3010
2
+ dwani/asr.py,sha256=BAdqivQd57NJZX1dSY-J6EFi8TDdyuhf_AyCPcQ0M7w,1719
3
+ dwani/audio.py,sha256=MWsIZazL91c2wa5AE1YY78l9RKaJwNFFHIajuwl43Jg,886
4
+ dwani/chat.py,sha256=Tui52XBhUyDyN2rOFoLme4oB0Q8fkD9_0tFDAnRzoaU,2979
5
+ dwani/client.py,sha256=VG7MFCF4yLAWyD037YcI3QTUMxRfJZrWTDK-JAurTnY,3356
6
+ dwani/docs.py,sha256=Cp0Gtudug79GH25toB-Npl35ZFA0TM32oZF2xH1VmNY,10598
7
+ dwani/exceptions.py,sha256=n06dPmR20rS4T3sJBWHQhGxzg4SJKzird9Hx0YTwwo0,226
8
+ dwani/translate.py,sha256=c03N8-tN49IBcTA6GMOkrJ3MaVzZ12RnYdLQwRbEeoQ,2794
9
+ dwani/vision.py,sha256=sjkudW2Jb_PEbRcoZy_S1Wno6K5icZz42pHcpD1FMGs,3607
10
+ dwani-0.1.12.dist-info/licenses/LICENSE,sha256=IAD8tbwWZbPWHXgYjabHoMv0aaUzZUYzYiEbfhTCisY,1070
11
+ dwani-0.1.12.dist-info/METADATA,sha256=aj_vKOlWgfznm_c_RqT82VYKl8FBia0CDQLbf40ZoJU,5791
12
+ dwani-0.1.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ dwani-0.1.12.dist-info/top_level.txt,sha256=AM5EhkyuO_EXQFR9JIxEV6tAYMCCyc-a1dLifpCGBUk,6
14
+ dwani-0.1.12.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- dwani/__init__.py,sha256=k1fWBnAp5zHQaYnOpUwzPIngqzVO4wIQr1wp5kPyzfE,2663
2
- dwani/asr.py,sha256=BAdqivQd57NJZX1dSY-J6EFi8TDdyuhf_AyCPcQ0M7w,1719
3
- dwani/audio.py,sha256=MWsIZazL91c2wa5AE1YY78l9RKaJwNFFHIajuwl43Jg,886
4
- dwani/chat.py,sha256=K3OJHQcRhU0aVmWBqajZqbfZg_Q5Dfm6Es3YMSpkxGY,2332
5
- dwani/client.py,sha256=UsRLoYZgj25F-qCGlATvElG6r3EWxqndeMv696cBk1w,2904
6
- dwani/docs.py,sha256=Cp0Gtudug79GH25toB-Npl35ZFA0TM32oZF2xH1VmNY,10598
7
- dwani/exceptions.py,sha256=n06dPmR20rS4T3sJBWHQhGxzg4SJKzird9Hx0YTwwo0,226
8
- dwani/translate.py,sha256=-6UHV5hu1oBxuDlGlGYp13bFDayKWwo1rBkJhE-LRMs,2568
9
- dwani/vision.py,sha256=9tRPhEXFQ3n-80XxVCs1qrEKqvzsoxGQTOKs2fTwQTI,2699
10
- dwani-0.1.10.dist-info/licenses/LICENSE,sha256=IAD8tbwWZbPWHXgYjabHoMv0aaUzZUYzYiEbfhTCisY,1070
11
- dwani-0.1.10.dist-info/METADATA,sha256=YUBayRe_IiFtbeJhr3Wu9trPBRGykVDngdzZGD8_2pk,5062
12
- dwani-0.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- dwani-0.1.10.dist-info/top_level.txt,sha256=AM5EhkyuO_EXQFR9JIxEV6tAYMCCyc-a1dLifpCGBUk,6
14
- dwani-0.1.10.dist-info/RECORD,,
File without changes