sarvamai 0.1.13a2__tar.gz → 0.1.14__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.
Files changed (214) hide show
  1. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/PKG-INFO +1 -1
  2. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/pyproject.toml +1 -1
  3. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/client_wrapper.py +2 -2
  4. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_job/client.py +143 -0
  5. sarvamai-0.1.14/src/sarvamai/speech_to_text_job/job.py +484 -0
  6. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_job/client.py +133 -0
  7. sarvamai-0.1.14/src/sarvamai/speech_to_text_translate_job/job.py +492 -0
  8. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/README.md +0 -0
  9. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/__init__.py +0 -0
  10. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/chat/__init__.py +0 -0
  11. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/chat/client.py +0 -0
  12. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/chat/raw_client.py +0 -0
  13. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/client.py +0 -0
  14. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/__init__.py +0 -0
  15. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/api_error.py +0 -0
  16. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/datetime_utils.py +0 -0
  17. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/events.py +0 -0
  18. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/file.py +0 -0
  19. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/force_multipart.py +0 -0
  20. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/http_client.py +0 -0
  21. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/http_response.py +0 -0
  22. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/jsonable_encoder.py +0 -0
  23. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/pydantic_utilities.py +0 -0
  24. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/query_encoder.py +0 -0
  25. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/remove_none_from_dict.py +0 -0
  26. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/request_options.py +0 -0
  27. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/core/serialization.py +0 -0
  28. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/environment.py +0 -0
  29. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/__init__.py +0 -0
  30. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/bad_request_error.py +0 -0
  31. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/forbidden_error.py +0 -0
  32. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/internal_server_error.py +0 -0
  33. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/service_unavailable_error.py +0 -0
  34. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/too_many_requests_error.py +0 -0
  35. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/errors/unprocessable_entity_error.py +0 -0
  36. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/play.py +0 -0
  37. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/py.typed +0 -0
  38. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/__init__.py +0 -0
  39. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/audio_data.py +0 -0
  40. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/audio_message.py +0 -0
  41. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/audio_output.py +0 -0
  42. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/audio_output_data.py +0 -0
  43. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/base_job_parameters.py +0 -0
  44. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/bulk_job_callback.py +0 -0
  45. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/bulk_job_init_response_v_1.py +0 -0
  46. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/chat_completion_request_assistant_message.py +0 -0
  47. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/chat_completion_request_message.py +0 -0
  48. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/chat_completion_request_system_message.py +0 -0
  49. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/chat_completion_request_user_message.py +0 -0
  50. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/chat_completion_response_message.py +0 -0
  51. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/choice.py +0 -0
  52. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/completion_usage.py +0 -0
  53. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/config_message.py +0 -0
  54. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/configure_connection.py +0 -0
  55. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/configure_connection_data.py +0 -0
  56. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/create_chat_completion_response.py +0 -0
  57. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/diarized_entry.py +0 -0
  58. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/diarized_transcript.py +0 -0
  59. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/error_data.py +0 -0
  60. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/error_details.py +0 -0
  61. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/error_message.py +0 -0
  62. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/error_response.py +0 -0
  63. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/error_response_data.py +0 -0
  64. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/events_data.py +0 -0
  65. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/file_signed_url_details.py +0 -0
  66. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/files_download_response.py +0 -0
  67. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/files_request.py +0 -0
  68. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/files_upload_response.py +0 -0
  69. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/flush_signal.py +0 -0
  70. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/job_status_v_1_response.py +0 -0
  71. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/language_identification_response.py +0 -0
  72. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/ping_signal.py +0 -0
  73. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/send_text.py +0 -0
  74. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/send_text_data.py +0 -0
  75. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_job_parameters.py +0 -0
  76. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_response.py +0 -0
  77. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_response_data.py +0 -0
  78. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_streaming_response.py +0 -0
  79. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_transcription_data.py +0 -0
  80. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_translate_job_parameters.py +0 -0
  81. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_translate_response.py +0 -0
  82. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_translate_response_data.py +0 -0
  83. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_translate_streaming_response.py +0 -0
  84. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/speech_to_text_translate_transcription_data.py +0 -0
  85. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/stop_configuration.py +0 -0
  86. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/task_detail_v_1.py +0 -0
  87. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/task_file_details.py +0 -0
  88. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/text_to_speech_response.py +0 -0
  89. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/timestamps_model.py +0 -0
  90. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/transcription_metrics.py +0 -0
  91. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/translation_response.py +0 -0
  92. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/requests/transliteration_response.py +0 -0
  93. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text/__init__.py +0 -0
  94. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text/client.py +0 -0
  95. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text/raw_client.py +0 -0
  96. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_job/__init__.py +0 -0
  97. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_job/raw_client.py +0 -0
  98. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/__init__.py +0 -0
  99. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/client.py +0 -0
  100. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/raw_client.py +0 -0
  101. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/socket_client.py +0 -0
  102. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/types/__init__.py +0 -0
  103. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_high_vad_sensitivity.py +0 -0
  104. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_language_code.py +0 -0
  105. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_model.py +0 -0
  106. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_streaming/types/speech_to_text_streaming_vad_signals.py +0 -0
  107. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_job/__init__.py +0 -0
  108. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_job/raw_client.py +0 -0
  109. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/__init__.py +0 -0
  110. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/client.py +0 -0
  111. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/raw_client.py +0 -0
  112. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/socket_client.py +0 -0
  113. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/types/__init__.py +0 -0
  114. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/types/speech_to_text_translate_streaming_high_vad_sensitivity.py +0 -0
  115. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/types/speech_to_text_translate_streaming_model.py +0 -0
  116. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/speech_to_text_translate_streaming/types/speech_to_text_translate_streaming_vad_signals.py +0 -0
  117. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text/__init__.py +0 -0
  118. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text/client.py +0 -0
  119. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text/raw_client.py +0 -0
  120. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech/__init__.py +0 -0
  121. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech/client.py +0 -0
  122. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech/raw_client.py +0 -0
  123. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech_streaming/__init__.py +0 -0
  124. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech_streaming/client.py +0 -0
  125. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech_streaming/raw_client.py +0 -0
  126. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/text_to_speech_streaming/socket_client.py +0 -0
  127. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/__init__.py +0 -0
  128. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/audio_data.py +0 -0
  129. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/audio_message.py +0 -0
  130. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/audio_output.py +0 -0
  131. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/audio_output_data.py +0 -0
  132. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/base_job_parameters.py +0 -0
  133. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/bulk_job_callback.py +0 -0
  134. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/bulk_job_init_response_v_1.py +0 -0
  135. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/chat_completion_request_assistant_message.py +0 -0
  136. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/chat_completion_request_message.py +0 -0
  137. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/chat_completion_request_system_message.py +0 -0
  138. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/chat_completion_request_user_message.py +0 -0
  139. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/chat_completion_response_message.py +0 -0
  140. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/choice.py +0 -0
  141. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/completion_usage.py +0 -0
  142. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/config_message.py +0 -0
  143. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection.py +0 -0
  144. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection_data.py +0 -0
  145. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection_data_output_audio_bitrate.py +0 -0
  146. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection_data_output_audio_codec.py +0 -0
  147. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection_data_speaker.py +0 -0
  148. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/configure_connection_data_target_language_code.py +0 -0
  149. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/create_chat_completion_response.py +0 -0
  150. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/diarized_entry.py +0 -0
  151. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/diarized_transcript.py +0 -0
  152. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_code.py +0 -0
  153. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_data.py +0 -0
  154. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_details.py +0 -0
  155. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_message.py +0 -0
  156. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_response.py +0 -0
  157. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/error_response_data.py +0 -0
  158. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/events_data.py +0 -0
  159. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/file_signed_url_details.py +0 -0
  160. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/files_download_response.py +0 -0
  161. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/files_request.py +0 -0
  162. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/files_upload_response.py +0 -0
  163. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/finish_reason.py +0 -0
  164. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/flush_signal.py +0 -0
  165. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/job_state.py +0 -0
  166. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/job_status_v_1_response.py +0 -0
  167. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/language_identification_response.py +0 -0
  168. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/numerals_format.py +0 -0
  169. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/ping_signal.py +0 -0
  170. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/reasoning_effort.py +0 -0
  171. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/response_type.py +0 -0
  172. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/role.py +0 -0
  173. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/sarvam_model_ids.py +0 -0
  174. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/send_text.py +0 -0
  175. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/send_text_data.py +0 -0
  176. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_sample_rate.py +0 -0
  177. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_job_parameters.py +0 -0
  178. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_language.py +0 -0
  179. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_model.py +0 -0
  180. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_response.py +0 -0
  181. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_response_data.py +0 -0
  182. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_streaming_response.py +0 -0
  183. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_transcription_data.py +0 -0
  184. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_job_parameters.py +0 -0
  185. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_language.py +0 -0
  186. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_model.py +0 -0
  187. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_response.py +0 -0
  188. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_response_data.py +0 -0
  189. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_streaming_response.py +0 -0
  190. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/speech_to_text_translate_transcription_data.py +0 -0
  191. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/spoken_form_numerals_format.py +0 -0
  192. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/stop_configuration.py +0 -0
  193. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/storage_container_type.py +0 -0
  194. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/task_detail_v_1.py +0 -0
  195. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/task_file_details.py +0 -0
  196. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/task_state.py +0 -0
  197. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/text_to_speech_language.py +0 -0
  198. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/text_to_speech_model.py +0 -0
  199. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/text_to_speech_output_audio_codec.py +0 -0
  200. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/text_to_speech_response.py +0 -0
  201. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/text_to_speech_speaker.py +0 -0
  202. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/timestamps_model.py +0 -0
  203. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/transcription_metrics.py +0 -0
  204. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translate_mode.py +0 -0
  205. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translate_model.py +0 -0
  206. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translate_source_language.py +0 -0
  207. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translate_speaker_gender.py +0 -0
  208. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translate_target_language.py +0 -0
  209. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translation_response.py +0 -0
  210. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/translatiterate_target_language.py +0 -0
  211. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/transliterate_mode.py +0 -0
  212. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/transliterate_source_language.py +0 -0
  213. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/types/transliteration_response.py +0 -0
  214. {sarvamai-0.1.13a2 → sarvamai-0.1.14}/src/sarvamai/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sarvamai
3
- Version: 0.1.13a2
3
+ Version: 0.1.14
4
4
  Summary:
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -3,7 +3,7 @@ name = "sarvamai"
3
3
 
4
4
  [tool.poetry]
5
5
  name = "sarvamai"
6
- version = "0.1.13a2"
6
+ version = "0.1.14"
7
7
  description = ""
8
8
  readme = "README.md"
9
9
  authors = []
@@ -23,10 +23,10 @@ class BaseClientWrapper:
23
23
 
24
24
  def get_headers(self) -> typing.Dict[str, str]:
25
25
  headers: typing.Dict[str, str] = {
26
- "User-Agent": "sarvamai/0.1.13a2",
26
+ "User-Agent": "sarvamai/0.1.14",
27
27
  "X-Fern-Language": "Python",
28
28
  "X-Fern-SDK-Name": "sarvamai",
29
- "X-Fern-SDK-Version": "0.1.13a2",
29
+ "X-Fern-SDK-Version": "0.1.14",
30
30
  **(self.get_custom_headers() or {}),
31
31
  }
32
32
  headers["api-subscription-key"] = self.api_subscription_key
@@ -10,7 +10,10 @@ from ..types.bulk_job_init_response_v_1 import BulkJobInitResponseV1
10
10
  from ..types.files_download_response import FilesDownloadResponse
11
11
  from ..types.files_upload_response import FilesUploadResponse
12
12
  from ..types.job_status_v_1_response import JobStatusV1Response
13
+ from ..types.speech_to_text_model import SpeechToTextModel
14
+ from ..types.speech_to_text_language import SpeechToTextLanguage
13
15
  from .raw_client import AsyncRawSpeechToTextJobClient, RawSpeechToTextJobClient
16
+ from .job import AsyncSpeechToTextJob, SpeechToTextJob
14
17
 
15
18
  # this is used as the default value for optional parameters
16
19
  OMIT = typing.cast(typing.Any, ...)
@@ -215,6 +218,76 @@ class SpeechToTextJobClient:
215
218
  _response = self._raw_client.get_download_links(job_id=job_id, files=files, request_options=request_options)
216
219
  return _response.data
217
220
 
221
+ def create_job(
222
+ self,
223
+ model: SpeechToTextModel = "saarika:v2.5",
224
+ with_diarization: bool = False,
225
+ with_timestamps: bool = False,
226
+ language_code: typing.Optional[SpeechToTextLanguage] = None,
227
+ num_speakers: typing.Optional[int] = None,
228
+ callback: typing.Optional[BulkJobCallbackParams] = OMIT,
229
+ request_options: typing.Optional[RequestOptions] = None,
230
+ ) -> SpeechToTextJob:
231
+ """
232
+ Create a new Speech-to-Text bulk job.
233
+
234
+ Parameters
235
+ ----------
236
+ model : SpeechToTextModel, default="saarika:v2.5"
237
+ The model to use for transcription.
238
+
239
+ with_diarization : typing.Optional[bool], default=False
240
+ Whether to enable speaker diarization (distinguishing who said what).
241
+
242
+ with_timestamps : typing.Optional[bool], default=False
243
+ Whether to include word-level timestamps in the transcription output.
244
+
245
+ language_code : typing.Optional[SpeechToTextLanguage], default=None
246
+ The language code of the input audio (e.g., "hi-IN", "bn-IN").
247
+
248
+ num_speakers : typing.Optional[int], default=None
249
+ The number of distinct speakers in the audio, if known.
250
+
251
+ callback : typing.Optional[BulkJobCallbackParams], default=OMIT
252
+ Optional callback configuration to receive job completion events.
253
+
254
+ request_options : typing.Optional[RequestOptions], default=None
255
+ Request-specific configuration.
256
+
257
+ Returns
258
+ -------
259
+ SpeechToTextJob
260
+ A handle to the newly created Speech-to-Text job.
261
+ """
262
+ response = self.initialise(
263
+ job_parameters=SpeechToTextJobParametersParams(
264
+ language_code=language_code,
265
+ model=model,
266
+ num_speakers=num_speakers, # type: ignore[typeddict-item]
267
+ with_diarization=with_diarization,
268
+ with_timestamps=with_timestamps,
269
+ ),
270
+ callback=callback,
271
+ request_options=request_options,
272
+ )
273
+ return SpeechToTextJob(job_id=response.job_id, client=self)
274
+
275
+ def get_job(self, job_id: str) -> SpeechToTextJob:
276
+ """
277
+ Get an existing Speech-to-Text job handle by job ID.
278
+
279
+ Parameters
280
+ ----------
281
+ job_id : str
282
+ The job ID of the previously created Speech-to-Text job.
283
+
284
+ Returns
285
+ -------
286
+ SpeechToTextJob
287
+ A job handle which can be used to check status or retrieve results.
288
+ """
289
+ return SpeechToTextJob(job_id=job_id, client=self)
290
+
218
291
 
219
292
  class AsyncSpeechToTextJobClient:
220
293
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -456,3 +529,73 @@ class AsyncSpeechToTextJobClient:
456
529
  job_id=job_id, files=files, request_options=request_options
457
530
  )
458
531
  return _response.data
532
+
533
+ async def create_job(
534
+ self,
535
+ model: SpeechToTextModel = "saarika:v2.5",
536
+ with_diarization: bool = False,
537
+ with_timestamps: bool = False,
538
+ language_code: typing.Optional[SpeechToTextLanguage] = None,
539
+ num_speakers: typing.Optional[int] = None,
540
+ callback: typing.Optional[BulkJobCallbackParams] = OMIT,
541
+ request_options: typing.Optional[RequestOptions] = None,
542
+ ) -> "AsyncSpeechToTextJob":
543
+ """
544
+ Create a new Speech-to-Text bulk job.
545
+
546
+ Parameters
547
+ ----------
548
+ model : SpeechToTextModel, default="saarika:v2.5"
549
+ The model to use for transcription.
550
+
551
+ with_diarization : typing.Optional[bool], default=False
552
+ Whether to enable speaker diarization (distinguishing who said what).
553
+
554
+ with_timestamps : typing.Optional[bool], default=False
555
+ Whether to include word-level timestamps in the transcription output.
556
+
557
+ language_code : typing.Optional[SpeechToTextLanguage], default=None
558
+ The language code of the input audio (e.g., "hi-IN", "bn-IN").
559
+
560
+ num_speakers : typing.Optional[int], default=None
561
+ The number of distinct speakers in the audio, if known.
562
+
563
+ callback : typing.Optional[BulkJobCallbackParams], default=OMIT
564
+ Optional callback configuration to receive job completion events.
565
+
566
+ request_options : typing.Optional[RequestOptions], default=None
567
+ Request-specific configuration.
568
+
569
+ Returns
570
+ -------
571
+ AsyncSpeechToTextJob
572
+ A handle to the newly created job.
573
+ """
574
+ response = await self.initialise(
575
+ job_parameters=SpeechToTextJobParametersParams(
576
+ language_code=language_code,
577
+ model=model,
578
+ with_diarization=with_diarization,
579
+ with_timestamps=with_timestamps,
580
+ num_speakers=num_speakers, # type: ignore[typeddict-item]
581
+ ),
582
+ callback=callback,
583
+ request_options=request_options,
584
+ )
585
+ return AsyncSpeechToTextJob(job_id=response.job_id, client=self)
586
+
587
+ async def get_job(self, job_id: str) -> "AsyncSpeechToTextJob":
588
+ """
589
+ Get an existing Speech-to-Text job handle by job ID.
590
+
591
+ Parameters
592
+ ----------
593
+ job_id : str
594
+ The job ID of the previously created speech-to-text job.
595
+
596
+ Returns
597
+ -------
598
+ AsyncSpeechToTextJob
599
+ A job handle which can be used to check status or retrieve results.
600
+ """
601
+ return AsyncSpeechToTextJob(job_id=job_id, client=self)
@@ -0,0 +1,484 @@
1
+ import asyncio
2
+ import mimetypes
3
+ import os
4
+ import time
5
+ import typing
6
+ import httpx
7
+
8
+ from ..types import JobStatusV1Response
9
+
10
+ if typing.TYPE_CHECKING:
11
+ from .client import AsyncSpeechToTextJobClient, SpeechToTextJobClient
12
+
13
+
14
+ class AsyncSpeechToTextJob:
15
+ def __init__(self, job_id: str, client: "AsyncSpeechToTextJobClient"):
16
+ """
17
+ Initialize the asynchronous speech-to-text job.
18
+
19
+ Parameters
20
+ ----------
21
+ job_id : str
22
+ The unique job identifier returned from a previous job initialization.
23
+
24
+ client : AsyncSpeechToTextJobClient
25
+ The async client instance used to create the job.
26
+
27
+ !!! important
28
+ This must be the **same client instance** that was used to initialize
29
+ the job originally, as it contains the subscription key and configuration
30
+ required to authenticate and manage the job.
31
+
32
+ """
33
+ self._job_id = job_id
34
+ self._client = client
35
+
36
+ @property
37
+ def job_id(self) -> str:
38
+ """
39
+ Returns the job ID associated with this job instance.
40
+
41
+ Returns
42
+ -------
43
+ str
44
+ """
45
+ return self._job_id
46
+
47
+ async def upload_files(
48
+ self, file_paths: typing.Sequence[str], timeout: float = 60.0
49
+ ) -> bool:
50
+ """
51
+ Upload input audio files for the speech-to-text job.
52
+
53
+ Parameters
54
+ ----------
55
+ file_paths : Sequence[str]
56
+ List of full paths to local audio files.
57
+
58
+ timeout : float, optional
59
+ The maximum time to wait for the upload to complete (in seconds),
60
+ by default 60.0
61
+ Returns
62
+ -------
63
+ bool
64
+ True if all files are uploaded successfully.
65
+ """
66
+ upload_links = await self._client.get_upload_links(
67
+ job_id=self._job_id,
68
+ files=[os.path.basename(p) for p in file_paths],
69
+ )
70
+ client_timeout = httpx.Timeout(timeout=timeout)
71
+ async with httpx.AsyncClient(timeout=client_timeout) as session:
72
+ for path in file_paths:
73
+ file_name = os.path.basename(path)
74
+ url = upload_links.upload_urls[file_name].file_url
75
+ with open(path, "rb") as f:
76
+ content_type, _ = mimetypes.guess_type(path)
77
+ if content_type is None:
78
+ content_type = "audio/wav"
79
+ response = await session.put(
80
+ url,
81
+ content=f.read(),
82
+ headers={
83
+ "x-ms-blob-type": "BlockBlob",
84
+ "Content-Type": content_type,
85
+ },
86
+ )
87
+ if response.status_code != 201:
88
+ raise RuntimeError(
89
+ f"Upload failed for {file_name}: {response.status_code}"
90
+ )
91
+ return True
92
+
93
+ async def wait_until_complete(
94
+ self, poll_interval: int = 5, timeout: int = 600
95
+ ) -> JobStatusV1Response:
96
+ """
97
+ Polls job status until it completes or fails.
98
+
99
+ Parameters
100
+ ----------
101
+ poll_interval : int, optional
102
+ Time in seconds between polling attempts (default is 5).
103
+
104
+ timeout : int, optional
105
+ Maximum time to wait for completion in seconds (default is 600).
106
+
107
+ Returns
108
+ -------
109
+ JobStatusV1Response
110
+ Final job status.
111
+
112
+ Raises
113
+ ------
114
+ TimeoutError
115
+ If the job does not complete within the given timeout.
116
+ """
117
+ start = asyncio.get_event_loop().time()
118
+ while True:
119
+ status = await self.get_status()
120
+ state = status.job_state.lower()
121
+ if state in {"completed", "failed"}:
122
+ return status
123
+ if asyncio.get_event_loop().time() - start > timeout:
124
+ raise TimeoutError(
125
+ f"Job {self._job_id} did not complete within {timeout} seconds."
126
+ )
127
+ await asyncio.sleep(poll_interval)
128
+
129
+ async def get_output_mappings(self) -> typing.List[typing.Dict[str, str]]:
130
+ """
131
+ Get the mapping of input files to their corresponding output files.
132
+
133
+ Returns
134
+ -------
135
+ List[Dict[str, str]]
136
+ List of mappings with keys 'input_file' and 'output_file'.
137
+ """
138
+ job_status = await self.get_status()
139
+ return [
140
+ {
141
+ "input_file": detail.inputs[0].file_name,
142
+ "output_file": detail.outputs[0].file_name,
143
+ }
144
+ for detail in (job_status.job_details or [])
145
+ if detail.inputs and detail.outputs
146
+ ]
147
+
148
+ async def download_outputs(self, output_dir: str) -> bool:
149
+ """
150
+ Download output files to the specified directory.
151
+
152
+ Parameters
153
+ ----------
154
+ output_dir : str
155
+ Local directory where outputs will be saved.
156
+
157
+ Returns
158
+ -------
159
+ bool
160
+ True if all files downloaded successfully.
161
+
162
+ Raises
163
+ ------
164
+ RuntimeError
165
+ If a file fails to download.
166
+ """
167
+ mappings = await self.get_output_mappings()
168
+ file_names = [m["output_file"] for m in mappings]
169
+ download_links = await self._client.get_download_links(
170
+ job_id=self._job_id, files=file_names
171
+ )
172
+
173
+ os.makedirs(output_dir, exist_ok=True)
174
+ async with httpx.AsyncClient() as session:
175
+ for m in mappings:
176
+ url = download_links.download_urls[m["output_file"]].file_url
177
+ response = await session.get(url)
178
+ if response.status_code != 200:
179
+ raise RuntimeError(
180
+ f"Download failed for {m['output_file']}: {response.status_code}"
181
+ )
182
+ output_path = os.path.join(output_dir, f"{m['input_file']}.json")
183
+ with open(output_path, "wb") as f:
184
+ f.write(response.content)
185
+ return True
186
+
187
+ async def get_status(self) -> JobStatusV1Response:
188
+ """
189
+ Retrieve the current status of the job.
190
+
191
+ Returns
192
+ -------
193
+ JobStatusV1Response
194
+ """
195
+ return await self._client.get_status(self._job_id)
196
+
197
+ async def start(self) -> JobStatusV1Response:
198
+ """
199
+ Start the speech-to-text job processing.
200
+
201
+ Returns
202
+ -------
203
+ JobStatusV1Response
204
+ """
205
+ return await self._client.start(job_id=self._job_id)
206
+
207
+ async def exists(self) -> bool:
208
+ """
209
+ Check if the job exists in the system.
210
+
211
+ Returns
212
+ -------
213
+ bool
214
+ """
215
+ try:
216
+ await self.get_status()
217
+ return True
218
+ except httpx.HTTPStatusError:
219
+ return False
220
+
221
+ async def is_complete(self) -> bool:
222
+ """
223
+ Check if the job is either completed or failed.
224
+
225
+ Returns
226
+ -------
227
+ bool
228
+ """
229
+ state = (await self.get_status()).job_state.lower()
230
+ return state in {"completed", "failed"}
231
+
232
+ async def is_successful(self) -> bool:
233
+ """
234
+ Check if the job completed successfully.
235
+
236
+ Returns
237
+ -------
238
+ bool
239
+ """
240
+ return (await self.get_status()).job_state.lower() == "completed"
241
+
242
+ async def is_failed(self) -> bool:
243
+ """
244
+ Check if the job has failed.
245
+
246
+ Returns
247
+ -------
248
+ bool
249
+ """
250
+ return (await self.get_status()).job_state.lower() == "failed"
251
+
252
+
253
+ class SpeechToTextJob:
254
+ def __init__(self, job_id: str, client: "SpeechToTextJobClient"):
255
+ """
256
+ Initialize the synchronous speech-to-text job.
257
+
258
+ Parameters
259
+ ----------
260
+ job_id : str
261
+ The unique job identifier returned from a previous job initialization.
262
+
263
+ client : SpeechToTextJobClient
264
+ The client instance used to create the job.
265
+
266
+ !!! important
267
+ This must be the **same client instance** that was used to initialize
268
+ the job originally, as it contains the subscription key and configuration
269
+ required to authenticate and manage the job.
270
+
271
+ """
272
+ self._job_id = job_id
273
+ self._client = client
274
+
275
+ @property
276
+ def job_id(self) -> str:
277
+ """
278
+ Returns the job ID associated with this job instance.
279
+
280
+ Returns
281
+ -------
282
+ str
283
+ """
284
+ return self._job_id
285
+
286
+ def upload_files(
287
+ self, file_paths: typing.Sequence[str], timeout: float = 60.0
288
+ ) -> bool:
289
+ """
290
+ Upload input audio files for the speech-to-text job.
291
+
292
+ Parameters
293
+ ----------
294
+ file_paths : Sequence[str]
295
+ List of full paths to local audio files.
296
+
297
+ timeout : float, optional
298
+ The maximum time to wait for the upload to complete (in seconds),
299
+ by default 60.0
300
+ Returns
301
+ -------
302
+ bool
303
+ True if all files are uploaded successfully.
304
+ """
305
+ upload_links = self._client.get_upload_links(
306
+ job_id=self._job_id, files=[os.path.basename(p) for p in file_paths]
307
+ )
308
+ client_timeout = httpx.Timeout(timeout=timeout)
309
+ with httpx.Client(timeout=client_timeout) as client:
310
+ for path in file_paths:
311
+ file_name = os.path.basename(path)
312
+ url = upload_links.upload_urls[file_name].file_url
313
+ with open(path, "rb") as f:
314
+ response = client.put(
315
+ url,
316
+ content=f,
317
+ headers={
318
+ "x-ms-blob-type": "BlockBlob",
319
+ "Content-Type": "audio/wav",
320
+ },
321
+ )
322
+ if response.status_code != 201:
323
+ raise RuntimeError(
324
+ f"Upload failed for {file_name}: {response.status_code}"
325
+ )
326
+ return True
327
+
328
+ def wait_until_complete(
329
+ self, poll_interval: int = 5, timeout: int = 600
330
+ ) -> JobStatusV1Response:
331
+ """
332
+ Polls job status until it completes or fails.
333
+
334
+ Parameters
335
+ ----------
336
+ poll_interval : int, optional
337
+ Time in seconds between polling attempts (default is 5).
338
+
339
+ timeout : int, optional
340
+ Maximum time to wait for completion in seconds (default is 600).
341
+
342
+ Returns
343
+ -------
344
+ JobStatusV1Response
345
+ Final job status.
346
+
347
+ Raises
348
+ ------
349
+ TimeoutError
350
+ If the job does not complete within the given timeout.
351
+ """
352
+ start = time.monotonic()
353
+ while True:
354
+ status = self.get_status()
355
+ state = status.job_state.lower()
356
+ if state in {"completed", "failed"}:
357
+ return status
358
+ if time.monotonic() - start > timeout:
359
+ raise TimeoutError(
360
+ f"Job {self._job_id} did not complete within {timeout} seconds."
361
+ )
362
+ time.sleep(poll_interval)
363
+
364
+ def get_output_mappings(self) -> typing.List[typing.Dict[str, str]]:
365
+ """
366
+ Get the mapping of input files to their corresponding output files.
367
+
368
+ Returns
369
+ -------
370
+ List[Dict[str, str]]
371
+ List of mappings with keys 'input_file' and 'output_file'.
372
+ """
373
+ job_status = self.get_status()
374
+ return [
375
+ {
376
+ "input_file": detail.inputs[0].file_name,
377
+ "output_file": detail.outputs[0].file_name,
378
+ }
379
+ for detail in (job_status.job_details or [])
380
+ if detail.inputs and detail.outputs
381
+ ]
382
+
383
+ def download_outputs(self, output_dir: str) -> bool:
384
+ """
385
+ Download output files to the specified directory.
386
+
387
+ Parameters
388
+ ----------
389
+ output_dir : str
390
+ Local directory where outputs will be saved.
391
+
392
+ Returns
393
+ -------
394
+ bool
395
+ True if all files downloaded successfully.
396
+
397
+ Raises
398
+ ------
399
+ RuntimeError
400
+ If a file fails to download.
401
+ """
402
+ mappings = self.get_output_mappings()
403
+ file_names = [m["output_file"] for m in mappings]
404
+ download_links = self._client.get_download_links(
405
+ job_id=self._job_id, files=file_names
406
+ )
407
+
408
+ os.makedirs(output_dir, exist_ok=True)
409
+ with httpx.Client() as client:
410
+ for m in mappings:
411
+ url = download_links.download_urls[m["output_file"]].file_url
412
+ response = client.get(url)
413
+ if response.status_code != 200:
414
+ raise RuntimeError(
415
+ f"Download failed for {m['output_file']}: {response.status_code}"
416
+ )
417
+ output_path = os.path.join(output_dir, f"{m['input_file']}.json")
418
+ with open(output_path, "wb") as f:
419
+ f.write(response.content)
420
+ return True
421
+
422
+ def get_status(self) -> JobStatusV1Response:
423
+ """
424
+ Retrieve the current status of the job.
425
+
426
+ Returns
427
+ -------
428
+ JobStatusV1Response
429
+ """
430
+ return self._client.get_status(self._job_id)
431
+
432
+ def start(self) -> JobStatusV1Response:
433
+ """
434
+ Start the speech-to-text job processing.
435
+
436
+ Returns
437
+ -------
438
+ JobStatusV1Response
439
+ """
440
+ return self._client.start(job_id=self._job_id)
441
+
442
+ def exists(self) -> bool:
443
+ """
444
+ Check if the job exists in the system.
445
+
446
+ Returns
447
+ -------
448
+ bool
449
+ """
450
+ try:
451
+ self.get_status()
452
+ return True
453
+ except httpx.HTTPStatusError:
454
+ return False
455
+
456
+ def is_complete(self) -> bool:
457
+ """
458
+ Check if the job is either completed or failed.
459
+
460
+ Returns
461
+ -------
462
+ bool
463
+ """
464
+ return self.get_status().job_state.lower() in {"completed", "failed"}
465
+
466
+ def is_successful(self) -> bool:
467
+ """
468
+ Check if the job completed successfully.
469
+
470
+ Returns
471
+ -------
472
+ bool
473
+ """
474
+ return self.get_status().job_state.lower() == "completed"
475
+
476
+ def is_failed(self) -> bool:
477
+ """
478
+ Check if the job has failed.
479
+
480
+ Returns
481
+ -------
482
+ bool
483
+ """
484
+ return self.get_status().job_state.lower() == "failed"