clarifai 11.3.0rc2__py3-none-any.whl → 11.4.0__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.
Files changed (300) hide show
  1. clarifai/__init__.py +1 -1
  2. clarifai/cli/__main__.py +1 -1
  3. clarifai/cli/base.py +144 -136
  4. clarifai/cli/compute_cluster.py +45 -31
  5. clarifai/cli/deployment.py +93 -76
  6. clarifai/cli/model.py +578 -180
  7. clarifai/cli/nodepool.py +100 -82
  8. clarifai/client/__init__.py +12 -2
  9. clarifai/client/app.py +973 -911
  10. clarifai/client/auth/helper.py +345 -342
  11. clarifai/client/auth/register.py +7 -7
  12. clarifai/client/auth/stub.py +107 -106
  13. clarifai/client/base.py +185 -178
  14. clarifai/client/compute_cluster.py +214 -180
  15. clarifai/client/dataset.py +793 -698
  16. clarifai/client/deployment.py +55 -50
  17. clarifai/client/input.py +1223 -1088
  18. clarifai/client/lister.py +47 -45
  19. clarifai/client/model.py +1939 -1717
  20. clarifai/client/model_client.py +525 -502
  21. clarifai/client/module.py +82 -73
  22. clarifai/client/nodepool.py +358 -213
  23. clarifai/client/runner.py +58 -0
  24. clarifai/client/search.py +342 -309
  25. clarifai/client/user.py +419 -414
  26. clarifai/client/workflow.py +294 -274
  27. clarifai/constants/dataset.py +11 -17
  28. clarifai/constants/model.py +8 -2
  29. clarifai/datasets/export/inputs_annotations.py +233 -217
  30. clarifai/datasets/upload/base.py +63 -51
  31. clarifai/datasets/upload/features.py +43 -38
  32. clarifai/datasets/upload/image.py +237 -207
  33. clarifai/datasets/upload/loaders/coco_captions.py +34 -32
  34. clarifai/datasets/upload/loaders/coco_detection.py +72 -65
  35. clarifai/datasets/upload/loaders/imagenet_classification.py +57 -53
  36. clarifai/datasets/upload/loaders/xview_detection.py +274 -132
  37. clarifai/datasets/upload/multimodal.py +55 -46
  38. clarifai/datasets/upload/text.py +55 -47
  39. clarifai/datasets/upload/utils.py +250 -234
  40. clarifai/errors.py +51 -50
  41. clarifai/models/api.py +260 -238
  42. clarifai/modules/css.py +50 -50
  43. clarifai/modules/pages.py +33 -33
  44. clarifai/rag/rag.py +312 -288
  45. clarifai/rag/utils.py +91 -84
  46. clarifai/runners/models/model_builder.py +906 -802
  47. clarifai/runners/models/model_class.py +370 -331
  48. clarifai/runners/models/model_run_locally.py +459 -419
  49. clarifai/runners/models/model_runner.py +170 -162
  50. clarifai/runners/models/model_servicer.py +78 -70
  51. clarifai/runners/server.py +111 -101
  52. clarifai/runners/utils/code_script.py +225 -187
  53. clarifai/runners/utils/const.py +4 -1
  54. clarifai/runners/utils/data_types/__init__.py +12 -0
  55. clarifai/runners/utils/data_types/data_types.py +598 -0
  56. clarifai/runners/utils/data_utils.py +387 -440
  57. clarifai/runners/utils/loader.py +247 -227
  58. clarifai/runners/utils/method_signatures.py +411 -386
  59. clarifai/runners/utils/openai_convertor.py +108 -109
  60. clarifai/runners/utils/serializers.py +175 -179
  61. clarifai/runners/utils/url_fetcher.py +35 -35
  62. clarifai/schema/search.py +56 -63
  63. clarifai/urls/helper.py +125 -102
  64. clarifai/utils/cli.py +129 -123
  65. clarifai/utils/config.py +127 -87
  66. clarifai/utils/constants.py +49 -0
  67. clarifai/utils/evaluation/helpers.py +503 -466
  68. clarifai/utils/evaluation/main.py +431 -393
  69. clarifai/utils/evaluation/testset_annotation_parser.py +154 -144
  70. clarifai/utils/logging.py +324 -306
  71. clarifai/utils/misc.py +60 -56
  72. clarifai/utils/model_train.py +165 -146
  73. clarifai/utils/protobuf.py +126 -103
  74. clarifai/versions.py +3 -1
  75. clarifai/workflows/export.py +48 -50
  76. clarifai/workflows/utils.py +39 -36
  77. clarifai/workflows/validate.py +55 -43
  78. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/METADATA +16 -6
  79. clarifai-11.4.0.dist-info/RECORD +109 -0
  80. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/WHEEL +1 -1
  81. clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
  82. clarifai/__pycache__/__init__.cpython-311.pyc +0 -0
  83. clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
  84. clarifai/__pycache__/errors.cpython-310.pyc +0 -0
  85. clarifai/__pycache__/errors.cpython-311.pyc +0 -0
  86. clarifai/__pycache__/versions.cpython-310.pyc +0 -0
  87. clarifai/__pycache__/versions.cpython-311.pyc +0 -0
  88. clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  89. clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  90. clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
  91. clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
  92. clarifai/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  93. clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  94. clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  95. clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
  96. clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
  97. clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
  98. clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
  99. clarifai/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  100. clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
  101. clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
  102. clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
  103. clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
  104. clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
  105. clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
  106. clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
  107. clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
  108. clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
  109. clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
  110. clarifai/client/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  111. clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  112. clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
  113. clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
  114. clarifai/client/__pycache__/deployment.cpython-310.pyc +0 -0
  115. clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
  116. clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
  117. clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
  118. clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
  119. clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
  120. clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
  121. clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
  122. clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
  123. clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
  124. clarifai/client/__pycache__/nodepool.cpython-310.pyc +0 -0
  125. clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
  126. clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
  127. clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
  128. clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
  129. clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
  130. clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
  131. clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
  132. clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
  133. clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
  134. clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
  135. clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
  136. clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
  137. clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
  138. clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
  139. clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
  140. clarifai/client/cli/__init__.py +0 -0
  141. clarifai/client/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  142. clarifai/client/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  143. clarifai/client/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  144. clarifai/client/cli/base_cli.py +0 -88
  145. clarifai/client/cli/model_cli.py +0 -29
  146. clarifai/constants/__pycache__/base.cpython-310.pyc +0 -0
  147. clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
  148. clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
  149. clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
  150. clarifai/constants/__pycache__/input.cpython-310.pyc +0 -0
  151. clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
  152. clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
  153. clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
  154. clarifai/constants/__pycache__/rag.cpython-310.pyc +0 -0
  155. clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
  156. clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
  157. clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
  158. clarifai/constants/__pycache__/workflow.cpython-310.pyc +0 -0
  159. clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
  160. clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
  161. clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
  162. clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
  163. clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
  164. clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
  165. clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
  166. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
  167. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
  168. clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
  169. clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
  170. clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
  171. clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
  172. clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
  173. clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
  174. clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
  175. clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
  176. clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
  177. clarifai/datasets/upload/__pycache__/multimodal.cpython-310.pyc +0 -0
  178. clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
  179. clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
  180. clarifai/datasets/upload/__pycache__/text.cpython-311.pyc +0 -0
  181. clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
  182. clarifai/datasets/upload/__pycache__/utils.cpython-311.pyc +0 -0
  183. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-311.pyc +0 -0
  184. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-39.pyc +0 -0
  185. clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-311.pyc +0 -0
  186. clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
  187. clarifai/models/__pycache__/__init__.cpython-39.pyc +0 -0
  188. clarifai/modules/__pycache__/__init__.cpython-39.pyc +0 -0
  189. clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
  190. clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
  191. clarifai/rag/__pycache__/__init__.cpython-39.pyc +0 -0
  192. clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
  193. clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
  194. clarifai/rag/__pycache__/rag.cpython-39.pyc +0 -0
  195. clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
  196. clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
  197. clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
  198. clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
  199. clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
  200. clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
  201. clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -42
  202. clarifai/runners/dockerfile_template/Dockerfile.nim +0 -71
  203. clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
  204. clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
  205. clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
  206. clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
  207. clarifai/runners/models/__pycache__/base_typed_model.cpython-311.pyc +0 -0
  208. clarifai/runners/models/__pycache__/base_typed_model.cpython-39.pyc +0 -0
  209. clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
  210. clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
  211. clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
  212. clarifai/runners/models/__pycache__/model_run_locally.cpython-310-pytest-7.1.2.pyc +0 -0
  213. clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
  214. clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
  215. clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
  216. clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
  217. clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
  218. clarifai/runners/models/base_typed_model.py +0 -238
  219. clarifai/runners/models/model_class_refract.py +0 -80
  220. clarifai/runners/models/model_upload.py +0 -607
  221. clarifai/runners/models/temp.py +0 -25
  222. clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  223. clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  224. clarifai/runners/utils/__pycache__/__init__.cpython-38.pyc +0 -0
  225. clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  226. clarifai/runners/utils/__pycache__/buffered_stream.cpython-310.pyc +0 -0
  227. clarifai/runners/utils/__pycache__/buffered_stream.cpython-38.pyc +0 -0
  228. clarifai/runners/utils/__pycache__/buffered_stream.cpython-39.pyc +0 -0
  229. clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
  230. clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
  231. clarifai/runners/utils/__pycache__/constants.cpython-310.pyc +0 -0
  232. clarifai/runners/utils/__pycache__/constants.cpython-38.pyc +0 -0
  233. clarifai/runners/utils/__pycache__/constants.cpython-39.pyc +0 -0
  234. clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
  235. clarifai/runners/utils/__pycache__/data_handler.cpython-311.pyc +0 -0
  236. clarifai/runners/utils/__pycache__/data_handler.cpython-38.pyc +0 -0
  237. clarifai/runners/utils/__pycache__/data_handler.cpython-39.pyc +0 -0
  238. clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
  239. clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
  240. clarifai/runners/utils/__pycache__/data_utils.cpython-38.pyc +0 -0
  241. clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
  242. clarifai/runners/utils/__pycache__/grpc_server.cpython-310.pyc +0 -0
  243. clarifai/runners/utils/__pycache__/grpc_server.cpython-38.pyc +0 -0
  244. clarifai/runners/utils/__pycache__/grpc_server.cpython-39.pyc +0 -0
  245. clarifai/runners/utils/__pycache__/health.cpython-310.pyc +0 -0
  246. clarifai/runners/utils/__pycache__/health.cpython-38.pyc +0 -0
  247. clarifai/runners/utils/__pycache__/health.cpython-39.pyc +0 -0
  248. clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
  249. clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
  250. clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
  251. clarifai/runners/utils/__pycache__/logging.cpython-38.pyc +0 -0
  252. clarifai/runners/utils/__pycache__/logging.cpython-39.pyc +0 -0
  253. clarifai/runners/utils/__pycache__/stream_source.cpython-310.pyc +0 -0
  254. clarifai/runners/utils/__pycache__/stream_source.cpython-39.pyc +0 -0
  255. clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
  256. clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
  257. clarifai/runners/utils/__pycache__/url_fetcher.cpython-38.pyc +0 -0
  258. clarifai/runners/utils/__pycache__/url_fetcher.cpython-39.pyc +0 -0
  259. clarifai/runners/utils/data_handler.py +0 -231
  260. clarifai/runners/utils/data_handler_refract.py +0 -213
  261. clarifai/runners/utils/data_types.py +0 -469
  262. clarifai/runners/utils/logger.py +0 -0
  263. clarifai/runners/utils/openai_format.py +0 -87
  264. clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
  265. clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
  266. clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
  267. clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
  268. clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  269. clarifai/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  270. clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  271. clarifai/utils/__pycache__/cli.cpython-310.pyc +0 -0
  272. clarifai/utils/__pycache__/cli.cpython-311.pyc +0 -0
  273. clarifai/utils/__pycache__/config.cpython-311.pyc +0 -0
  274. clarifai/utils/__pycache__/constants.cpython-310.pyc +0 -0
  275. clarifai/utils/__pycache__/constants.cpython-311.pyc +0 -0
  276. clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
  277. clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
  278. clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
  279. clarifai/utils/__pycache__/misc.cpython-311.pyc +0 -0
  280. clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
  281. clarifai/utils/__pycache__/model_train.cpython-311.pyc +0 -0
  282. clarifai/utils/__pycache__/protobuf.cpython-311.pyc +0 -0
  283. clarifai/utils/evaluation/__pycache__/__init__.cpython-311.pyc +0 -0
  284. clarifai/utils/evaluation/__pycache__/__init__.cpython-39.pyc +0 -0
  285. clarifai/utils/evaluation/__pycache__/helpers.cpython-311.pyc +0 -0
  286. clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
  287. clarifai/utils/evaluation/__pycache__/main.cpython-39.pyc +0 -0
  288. clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
  289. clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
  290. clarifai/workflows/__pycache__/__init__.cpython-39.pyc +0 -0
  291. clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
  292. clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
  293. clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
  294. clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
  295. clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
  296. clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
  297. clarifai-11.3.0rc2.dist-info/RECORD +0 -322
  298. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/entry_points.txt +0 -0
  299. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info/licenses}/LICENSE +0 -0
  300. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,598 @@
1
+ import io
2
+ import json
3
+ import re
4
+ import uuid
5
+ from typing import Iterable, List, Tuple, Union, get_args, get_origin
6
+
7
+ import numpy as np
8
+ from clarifai_grpc.grpc.api.resources_pb2 import Audio as AudioProto
9
+ from clarifai_grpc.grpc.api.resources_pb2 import Concept as ConceptProto
10
+ from clarifai_grpc.grpc.api.resources_pb2 import Frame as FrameProto
11
+ from clarifai_grpc.grpc.api.resources_pb2 import Image as ImageProto
12
+ from clarifai_grpc.grpc.api.resources_pb2 import Mask as MaskProto
13
+ from clarifai_grpc.grpc.api.resources_pb2 import Point as PointProto
14
+ from clarifai_grpc.grpc.api.resources_pb2 import Region as RegionProto
15
+ from clarifai_grpc.grpc.api.resources_pb2 import Text as TextProto
16
+ from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
17
+ from PIL import Image as PILImage
18
+
19
+ __all__ = [
20
+ "Audio",
21
+ "Concept",
22
+ "Frame",
23
+ "Image",
24
+ "Region",
25
+ "Text",
26
+ "Video",
27
+ "MessageData",
28
+ "NamedFieldsMeta",
29
+ "NamedFields",
30
+ "JSON",
31
+ ]
32
+
33
+
34
+ class MessageData:
35
+ def to_proto(self):
36
+ raise NotImplementedError
37
+
38
+ @classmethod
39
+ def from_proto(cls, proto):
40
+ raise NotImplementedError
41
+
42
+ @classmethod
43
+ def from_value(cls, value):
44
+ if isinstance(value, cls):
45
+ return value
46
+ return cls(value)
47
+
48
+ def cast(self, python_type):
49
+ if python_type is self.__class__:
50
+ return self
51
+ raise TypeError(f'Incompatible type for {self.__class__.__name__}: {python_type}')
52
+
53
+
54
+ class NamedFieldsMeta(type):
55
+ """Metaclass to create NamedFields subclasses with __annotations__ when fields are specified."""
56
+
57
+ def __call__(cls, *args, **kwargs):
58
+ # Check if keyword arguments are types (used in type annotations)
59
+ if kwargs and all(isinstance(v, type) for v in kwargs.values()):
60
+ # Dynamically create a subclass with __annotations__
61
+ name = f"NamedFields({', '.join(f'{k}:{v.__name__}' for k, v in kwargs.items())})"
62
+ return type(name, (cls,), {'__annotations__': kwargs})
63
+ else:
64
+ # Create a normal instance for runtime data
65
+ return super().__call__(*args, **kwargs)
66
+
67
+
68
+ class NamedFields(metaclass=NamedFieldsMeta):
69
+ """A class that can be used to store named fields with values."""
70
+
71
+ def __init__(self, **kwargs):
72
+ for key, value in kwargs.items():
73
+ setattr(self, key, value)
74
+
75
+ def items(self):
76
+ return self.__dict__.items()
77
+
78
+ def keys(self):
79
+ return self.__dict__.keys()
80
+
81
+ def values(self):
82
+ return self.__dict__.values()
83
+
84
+ def __contains__(self, key):
85
+ return key in self.__dict__
86
+
87
+ def __getitem__(self, key):
88
+ return getattr(self, key)
89
+
90
+ def __setitem__(self, key, value):
91
+ setattr(self, key, value)
92
+
93
+ def __repr__(self):
94
+ return f"{self.__class__.__name__}({', '.join(f'{key}={value!r}' for key, value in self.__dict__.items())})"
95
+
96
+ def __origin__(self):
97
+ return self
98
+
99
+ def __args__(self):
100
+ return list(self.keys())
101
+
102
+
103
+ class JSON:
104
+ def __init__(self, value):
105
+ self.value = value
106
+
107
+ def __eq__(self, other):
108
+ return self.value == other
109
+
110
+ def __bool__(self):
111
+ return bool(self.value)
112
+
113
+ def __repr__(self):
114
+ return f"JSON({self.value})"
115
+
116
+ def to_json(self):
117
+ return json.dumps(self.value)
118
+
119
+ @classmethod
120
+ def from_json(cls, json_str):
121
+ return cls(json.loads(json_str))
122
+
123
+ @classmethod
124
+ def from_value(cls, value):
125
+ return cls(value)
126
+
127
+ def cast(self, python_type):
128
+ if not isinstance(self.value, python_type):
129
+ raise TypeError(f'Incompatible type {type(self.value)} for {python_type}')
130
+ return self.value
131
+
132
+
133
+ class Text(MessageData):
134
+ def __init__(self, text: str, url: str = None):
135
+ self.text = text
136
+ self.url = url
137
+
138
+ def __eq__(self, other):
139
+ if isinstance(other, Text):
140
+ return self.text == other.text and self.url == other.url
141
+ if isinstance(other, str):
142
+ return self.text == other
143
+ return False
144
+
145
+ def __bool__(self):
146
+ return bool(self.text) or bool(self.url)
147
+
148
+ def __repr__(self) -> str:
149
+ return f"Text(text={self.text!r}, url={self.url!r})"
150
+
151
+ def to_proto(self) -> TextProto:
152
+ return TextProto(raw=self.text or '', url=self.url or '')
153
+
154
+ @classmethod
155
+ def from_proto(cls, proto: TextProto) -> "Text":
156
+ return cls(proto.raw, proto.url or None)
157
+
158
+ @classmethod
159
+ def from_value(cls, value):
160
+ if isinstance(value, str):
161
+ return cls(value)
162
+ if isinstance(value, Text):
163
+ return value
164
+ if isinstance(value, dict):
165
+ return cls(value.get('text'), value.get('url'))
166
+ raise TypeError(f'Incompatible type for Text: {type(value)}')
167
+
168
+ def cast(self, python_type):
169
+ if python_type is str:
170
+ return self.text
171
+ if python_type is Text:
172
+ return self
173
+ raise TypeError(f'Incompatible type for Text: {python_type}')
174
+
175
+
176
+ class Concept(MessageData):
177
+ def __init__(self, name: str, value: float = 1.0, id: str = None):
178
+ self.name = name
179
+ self.value = value
180
+ self.id = id or Concept._concept_name_to_id(name)
181
+
182
+ @staticmethod
183
+ def _concept_name_to_id(name: str):
184
+ _name = re.sub(r'[^a-zA-Z0-9\s]', '', name)
185
+ _name = _name.replace(' ', '-')
186
+ return _name
187
+
188
+ def __repr__(self) -> str:
189
+ return f"Concept(id={self.id!r}, name={self.name!r}, value={self.value})"
190
+
191
+ def to_proto(self):
192
+ return ConceptProto(id=self.id, name=self.name, value=self.value)
193
+
194
+ @classmethod
195
+ def from_proto(cls, proto: ConceptProto) -> "Concept":
196
+ return cls(id=proto.id, name=proto.name, value=proto.value)
197
+
198
+
199
+ class Region(MessageData):
200
+ def __init__(
201
+ self,
202
+ proto_region: RegionProto = None,
203
+ box: List[float] = None,
204
+ concepts: List[Concept] = None,
205
+ mask: Union['Image', PILImage.Image, np.ndarray] = None,
206
+ point: Tuple[float, float, float] = None,
207
+ track_id: str = None,
208
+ text: str = None,
209
+ id: str = None,
210
+ ):
211
+ if proto_region is None:
212
+ self.proto = RegionProto()
213
+ # use setters for init vals
214
+ if box:
215
+ self.box = box
216
+ if concepts:
217
+ self.concepts = concepts
218
+ if mask:
219
+ self.mask = mask
220
+ if point:
221
+ self.point = point
222
+ if track_id:
223
+ self.track_id = track_id
224
+ if text:
225
+ self.text = text
226
+ self.id = id if id is not None else uuid.uuid4().hex
227
+ elif isinstance(proto_region, RegionProto):
228
+ self.proto = proto_region
229
+ else:
230
+ raise TypeError(
231
+ f"Expected type {RegionProto.__name__}, but got type {type(proto_region).__name__}"
232
+ )
233
+
234
+ @property
235
+ def id(self):
236
+ return self.proto.id
237
+
238
+ @id.setter
239
+ def id(self, value: str):
240
+ self.proto.id = value
241
+
242
+ @property
243
+ def text(self):
244
+ return self.proto.data.text.raw
245
+
246
+ @text.setter
247
+ def text(self, value: str):
248
+ self.proto.data.text.raw = value
249
+
250
+ @property
251
+ def box(self) -> List[float]:
252
+ """[xmin, ymin, xmax, ymax]"""
253
+ bbox = self.proto.region_info.bounding_box
254
+ # x1, y1, x2, y2
255
+ return [bbox.left_col, bbox.top_row, bbox.right_col, bbox.bottom_row]
256
+
257
+ @box.setter
258
+ def box(self, value: List[float]):
259
+ if (
260
+ isinstance(value, list)
261
+ and len(value) == 4
262
+ and all(isinstance(val, (int, float)) for val in value)
263
+ ):
264
+ bbox = self.proto.region_info.bounding_box
265
+ bbox.left_col, bbox.top_row, bbox.right_col, bbox.bottom_row = value
266
+ else:
267
+ raise TypeError(f"Expected a list of 4 float values for 'box', but got: {value}")
268
+
269
+ @property
270
+ def concepts(self) -> List[Concept]:
271
+ return [Concept.from_proto(proto) for proto in self.proto.data.concepts]
272
+
273
+ @concepts.setter
274
+ def concepts(self, value: List[Concept]):
275
+ if isinstance(value, list) and all(isinstance(concept, Concept) for concept in value):
276
+ self.proto.data.concepts.extend([concept.to_proto() for concept in value])
277
+ else:
278
+ raise TypeError(f"Expected a list of 'Concept' for 'concepts', but got: {value}")
279
+
280
+ @property
281
+ def mask(self) -> 'Image':
282
+ return Image.from_proto(self.proto.region_info.mask.image)
283
+
284
+ @mask.setter
285
+ def mask(self, value: Union['Image', PILImage.Image, np.ndarray]):
286
+ if isinstance(value, PILImage.Image):
287
+ value = Image.from_pil(value)
288
+ elif isinstance(value, np.ndarray):
289
+ value = Image.from_numpy(value)
290
+ elif not isinstance(value, Image):
291
+ raise TypeError(
292
+ f"Expected one of types ['Image', PIL.Image.Image, numpy.ndarray] got '{type(value).__name__}'"
293
+ )
294
+ self.proto.region_info.mask.CopyFrom(MaskProto(image=value.to_proto()))
295
+
296
+ @property
297
+ def track_id(self) -> str:
298
+ return self.proto.track_id
299
+
300
+ @track_id.setter
301
+ def track_id(self, value: str):
302
+ if not isinstance(value, str):
303
+ raise TypeError(f"Expected str for track_id, got {type(value).__name__}")
304
+ self.proto.track_id = value
305
+
306
+ @property
307
+ def point(self) -> Tuple[float, float, float]:
308
+ """[x,y,z]"""
309
+ point = self.proto.region_info.point
310
+ return point.col, point.row, point.z
311
+
312
+ @point.setter
313
+ def point(self, value: Tuple[float, float, float]):
314
+ if not isinstance(value, Iterable):
315
+ raise TypeError(f"Expected a tuple of floats, got {type(value).__name__}")
316
+ value = tuple(value)
317
+ if len(value) != 3:
318
+ raise ValueError(f"Expected 3 elements, got {len(value)}")
319
+ if not all(isinstance(v, float) for v in value):
320
+ raise TypeError("All elements must be floats")
321
+ x, y, z = value
322
+ point_proto = PointProto(col=x, row=y, z=z)
323
+ self.proto.region_info.point.CopyFrom(point_proto)
324
+
325
+ def __repr__(self) -> str:
326
+ return f"Region(id={self.id},box={self.box or []}, concepts={self.concepts or None}, point={self.point or None}, mask={self.mask or None}, track_id={self.track_id or None})"
327
+
328
+ def to_proto(self) -> RegionProto:
329
+ return self.proto
330
+
331
+ @classmethod
332
+ def from_proto(cls, proto: RegionProto) -> "Region":
333
+ return cls(proto)
334
+
335
+
336
+ class Image(MessageData):
337
+ def __init__(self, proto_image: ImageProto = None, url: str = None, bytes: bytes = None):
338
+ if proto_image is None:
339
+ proto_image = ImageProto()
340
+ self.proto = proto_image
341
+ # use setters for init vals
342
+ if url:
343
+ self.url = url
344
+ if bytes:
345
+ self.bytes = bytes
346
+
347
+ @property
348
+ def url(self) -> str:
349
+ return self.proto.url
350
+
351
+ @url.setter
352
+ def url(self, value: str):
353
+ self.proto.url = value
354
+
355
+ @property
356
+ def bytes(self) -> bytes:
357
+ return self.proto.base64
358
+
359
+ @bytes.setter
360
+ def bytes(self, value: bytes):
361
+ self.proto.base64 = value
362
+
363
+ def __repr__(self) -> str:
364
+ attrs = []
365
+ if self.url:
366
+ attrs.append(f"url={self.url!r}")
367
+ if self.bytes:
368
+ attrs.append(f"bytes=<{len(self.bytes)} bytes>")
369
+ return f"Image({', '.join(attrs)})"
370
+
371
+ @classmethod
372
+ def from_url(cls, url: str) -> "Image":
373
+ proto_image = ImageProto(url=url)
374
+ return cls(proto_image)
375
+
376
+ @classmethod
377
+ def from_pil(cls, pil_image: PILImage.Image, img_format="PNG") -> "Image":
378
+ with io.BytesIO() as output:
379
+ pil_image.save(output, format=img_format)
380
+ image_bytes = output.getvalue()
381
+ proto_image = ImageProto(base64=image_bytes)
382
+ return cls(proto_image)
383
+
384
+ @classmethod
385
+ def from_numpy(cls, numpy_image: np.ndarray, img_format="PNG") -> "Image":
386
+ pil_image = PILImage.fromarray(numpy_image)
387
+ with io.BytesIO() as output:
388
+ pil_image.save(output, format=img_format)
389
+ image_bytes = output.getvalue()
390
+ proto_image = ImageProto(base64=image_bytes)
391
+ return cls(proto_image)
392
+
393
+ def to_pil(self) -> PILImage.Image:
394
+ if not self.proto.base64:
395
+ raise ValueError("Image has no bytes")
396
+ return PILImage.open(io.BytesIO(self.proto.base64))
397
+
398
+ def to_numpy(self) -> np.ndarray:
399
+ return np.asarray(self.to_pil())
400
+
401
+ def to_proto(self) -> ImageProto:
402
+ return self.proto
403
+
404
+ @classmethod
405
+ def from_proto(cls, proto: ImageProto) -> "Image":
406
+ return cls(proto)
407
+
408
+ @classmethod
409
+ def from_value(cls, value):
410
+ if isinstance(value, PILImage.Image):
411
+ return cls.from_pil(value)
412
+ if isinstance(value, Image):
413
+ return value
414
+ raise TypeError(f'Incompatible type for Image: {type(value)}')
415
+
416
+ def cast(self, python_type):
417
+ if python_type is Image:
418
+ return self
419
+ if python_type is PILImage.Image or python_type is PILImage:
420
+ return self.to_pil()
421
+ if python_type is np.ndarray or get_origin(python_type) is np.ndarray:
422
+ return self.to_numpy()
423
+ raise TypeError(f'Incompatible type for Image: {python_type}')
424
+
425
+
426
+ class Audio(MessageData):
427
+ def __init__(self, proto_audio: AudioProto = None, url: str = None, bytes: bytes = None):
428
+ if proto_audio is None:
429
+ proto_audio = AudioProto()
430
+ self.proto = proto_audio
431
+
432
+ if url:
433
+ self.url = url
434
+ if bytes:
435
+ self.bytes = bytes
436
+
437
+ @property
438
+ def url(self) -> str:
439
+ return self.proto.url
440
+
441
+ @url.setter
442
+ def url(self, value: str):
443
+ self.proto.url = value
444
+
445
+ @property
446
+ def bytes(self) -> bytes:
447
+ return self.proto.base64
448
+
449
+ @bytes.setter
450
+ def bytes(self, value: bytes):
451
+ self.proto.base64 = value
452
+
453
+ @classmethod
454
+ def from_url(cls, url: str) -> "Audio":
455
+ proto_audio = AudioProto(url=url)
456
+ return cls(proto_audio)
457
+
458
+ def __repr__(self) -> str:
459
+ attrs = []
460
+ if self.url:
461
+ attrs.append(f"url={self.url!r}")
462
+ if self.bytes:
463
+ attrs.append(f"bytes=<{len(self.bytes)} bytes>")
464
+ return f"Audio({', '.join(attrs)})"
465
+
466
+ def to_proto(self) -> AudioProto:
467
+ return self.proto
468
+
469
+ @classmethod
470
+ def from_proto(cls, proto: AudioProto) -> "Audio":
471
+ return cls(proto)
472
+
473
+
474
+ class Frame(MessageData):
475
+ def __init__(
476
+ self,
477
+ proto_frame: FrameProto = None,
478
+ image: Image = None,
479
+ regions: List[Region] = None,
480
+ time: float = None,
481
+ index: int = None,
482
+ ):
483
+ if proto_frame is None:
484
+ proto_frame = FrameProto()
485
+ self.proto = proto_frame
486
+ # use setters for init vals
487
+ if image:
488
+ self.image = image
489
+ if regions:
490
+ self.regions = regions
491
+ if time:
492
+ self.time = time
493
+ if index:
494
+ self.index = index
495
+
496
+ @property
497
+ def time(self) -> float:
498
+ # TODO: time is a uint32, so this will overflow at 49.7 days
499
+ # we should be using double or uint64 in the proto instead
500
+ return self.proto.frame_info.time / 1000.0
501
+
502
+ @time.setter
503
+ def time(self, value: float):
504
+ self.proto.frame_info.time = int(value * 1000)
505
+
506
+ @property
507
+ def index(self) -> int:
508
+ return self.proto.frame_info.index
509
+
510
+ @index.setter
511
+ def index(self, value: int):
512
+ self.proto.frame_info.index = value
513
+
514
+ @property
515
+ def image(self) -> Image:
516
+ return Image.from_proto(self.proto.data.image)
517
+
518
+ @image.setter
519
+ def image(self, value: Image):
520
+ self.proto.data.image.CopyFrom(value.to_proto())
521
+
522
+ @property
523
+ def regions(self) -> List[Region]:
524
+ return [Region(region) for region in self.proto.data.regions]
525
+
526
+ @regions.setter
527
+ def regions(self, value: List[Region]):
528
+ self.proto.data.regions.extend([region.proto for region in value])
529
+
530
+ def to_proto(self) -> FrameProto:
531
+ return self.proto
532
+
533
+ @classmethod
534
+ def from_proto(cls, proto: FrameProto) -> "Frame":
535
+ return cls(proto)
536
+
537
+
538
+ class Video(MessageData):
539
+ def __init__(self, proto_video: VideoProto = None, url: str = None, bytes: bytes = None):
540
+ if proto_video is None:
541
+ proto_video = VideoProto()
542
+ self.proto = proto_video
543
+
544
+ if url:
545
+ self.url = url
546
+ if bytes:
547
+ self.bytes = bytes
548
+
549
+ @property
550
+ def url(self) -> str:
551
+ return self.proto.url
552
+
553
+ @url.setter
554
+ def url(self, value: str):
555
+ self.proto.url = value
556
+
557
+ @property
558
+ def bytes(self) -> bytes:
559
+ return self.proto.base64
560
+
561
+ @bytes.setter
562
+ def bytes(self, value: bytes):
563
+ self.proto.base64 = value
564
+
565
+ @classmethod
566
+ def from_url(cls, url: str) -> "Video":
567
+ proto_video = VideoProto(url=url)
568
+ return cls(proto_video)
569
+
570
+ def __repr__(self) -> str:
571
+ attrs = []
572
+ if self.url:
573
+ attrs.append(f"url={self.url!r}")
574
+ if self.bytes:
575
+ attrs.append(f"bytes=<{len(self.bytes)} bytes>")
576
+ return f"Video({', '.join(attrs)})"
577
+
578
+ def to_proto(self) -> VideoProto:
579
+ return self.proto
580
+
581
+ @classmethod
582
+ def from_proto(cls, proto: VideoProto) -> "Video":
583
+ return cls(proto)
584
+
585
+
586
+ def cast(value, python_type):
587
+ list_type = get_origin(python_type) is list
588
+ if isinstance(value, MessageData):
589
+ return value.cast(python_type)
590
+ if list_type and isinstance(value, np.ndarray):
591
+ return value.tolist()
592
+ if list_type and isinstance(value, list):
593
+ if get_args(python_type):
594
+ inner_type = get_args(python_type)[0]
595
+ return [cast(item, inner_type) for item in value]
596
+ if not isinstance(value, Iterable):
597
+ raise TypeError(f'Expected list, got {type(value)}')
598
+ return value