scale-gp-beta 0.1.0a19__tar.gz → 0.1.0a21__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 (177) hide show
  1. scale_gp_beta-0.1.0a21/.release-please-manifest.json +3 -0
  2. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/CHANGELOG.md +26 -0
  3. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/PKG-INFO +1 -1
  4. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/examples/tracing/1_explicit_use_case.py +3 -3
  5. scale_gp_beta-0.1.0a21/examples/tracing/2_direct_upload.py +49 -0
  6. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/pyproject.toml +3 -2
  7. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/requirements-dev.lock +4 -0
  8. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_base_client.py +16 -2
  9. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_version.py +1 -1
  10. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/span.py +60 -17
  11. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/trace.py +68 -9
  12. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/trace_exporter.py +25 -4
  13. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/trace_queue_manager.py +12 -8
  14. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/tracing.py +99 -48
  15. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/types.py +7 -2
  16. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/lib/test_span.py +3 -3
  17. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/lib/test_trace.py +7 -7
  18. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/lib/test_trace_exporter.py +61 -4
  19. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/lib/test_tracing.py +48 -11
  20. scale_gp_beta-0.1.0a19/.release-please-manifest.json +0 -3
  21. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/.gitignore +0 -0
  22. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/CONTRIBUTING.md +0 -0
  23. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/LICENSE +0 -0
  24. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/README.md +0 -0
  25. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/SECURITY.md +0 -0
  26. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/api.md +0 -0
  27. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/bin/check-release-environment +0 -0
  28. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/bin/publish-pypi +0 -0
  29. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/examples/.keep +0 -0
  30. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/examples/tracing/0_primitives_fibonacci.py +0 -0
  31. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/mypy.ini +0 -0
  32. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/noxfile.py +0 -0
  33. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/release-please-config.json +0 -0
  34. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/requirements.lock +0 -0
  35. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp/lib/.keep +0 -0
  36. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/__init__.py +0 -0
  37. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_client.py +0 -0
  38. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_compat.py +0 -0
  39. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_constants.py +0 -0
  40. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_exceptions.py +0 -0
  41. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_files.py +0 -0
  42. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_models.py +0 -0
  43. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_qs.py +0 -0
  44. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_resource.py +0 -0
  45. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_response.py +0 -0
  46. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_streaming.py +0 -0
  47. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_types.py +0 -0
  48. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/__init__.py +0 -0
  49. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_logs.py +0 -0
  50. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_proxy.py +0 -0
  51. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_reflection.py +0 -0
  52. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_resources_proxy.py +0 -0
  53. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_streams.py +0 -0
  54. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_sync.py +0 -0
  55. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_transform.py +0 -0
  56. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_typing.py +0 -0
  57. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/_utils/_utils.py +0 -0
  58. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/.keep +0 -0
  59. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/__init__.py +0 -0
  60. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/exceptions.py +0 -0
  61. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/scope.py +0 -0
  62. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/lib/tracing/util.py +0 -0
  63. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/pagination.py +0 -0
  64. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/py.typed +0 -0
  65. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/__init__.py +0 -0
  66. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/chat/__init__.py +0 -0
  67. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/chat/chat.py +0 -0
  68. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/chat/completions.py +0 -0
  69. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/completions.py +0 -0
  70. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/dataset_items.py +0 -0
  71. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/datasets.py +0 -0
  72. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/evaluation_items.py +0 -0
  73. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/evaluations.py +0 -0
  74. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/files/__init__.py +0 -0
  75. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/files/content.py +0 -0
  76. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/files/files.py +0 -0
  77. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/inference.py +0 -0
  78. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/models.py +0 -0
  79. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/resources/spans.py +0 -0
  80. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/__init__.py +0 -0
  81. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/__init__.py +0 -0
  82. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/chat_completion.py +0 -0
  83. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/chat_completion_chunk.py +0 -0
  84. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/completion_create_params.py +0 -0
  85. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/completion_create_response.py +0 -0
  86. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/completion_models_params.py +0 -0
  87. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/completion_models_response.py +0 -0
  88. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/chat/model_definition.py +0 -0
  89. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/completion.py +0 -0
  90. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/completion_create_params.py +0 -0
  91. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/component.py +0 -0
  92. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/component_param.py +0 -0
  93. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/container.py +0 -0
  94. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/container_param.py +0 -0
  95. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset.py +0 -0
  96. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_create_params.py +0 -0
  97. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_delete_response.py +0 -0
  98. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item.py +0 -0
  99. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_batch_create_params.py +0 -0
  100. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_batch_create_response.py +0 -0
  101. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_delete_response.py +0 -0
  102. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_list_params.py +0 -0
  103. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_retrieve_params.py +0 -0
  104. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_item_update_params.py +0 -0
  105. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_list_params.py +0 -0
  106. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_retrieve_params.py +0 -0
  107. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/dataset_update_params.py +0 -0
  108. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation.py +0 -0
  109. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_create_params.py +0 -0
  110. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_delete_response.py +0 -0
  111. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_item.py +0 -0
  112. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_item_list_params.py +0 -0
  113. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_item_retrieve_params.py +0 -0
  114. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_list_params.py +0 -0
  115. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_retrieve_params.py +0 -0
  116. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_task.py +0 -0
  117. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_task_param.py +0 -0
  118. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/evaluation_update_params.py +0 -0
  119. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file.py +0 -0
  120. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file_create_params.py +0 -0
  121. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file_delete_response.py +0 -0
  122. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file_list.py +0 -0
  123. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file_list_params.py +0 -0
  124. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/file_update_params.py +0 -0
  125. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/files/__init__.py +0 -0
  126. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_create_params.py +0 -0
  127. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_create_response.py +0 -0
  128. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_model.py +0 -0
  129. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_model_list.py +0 -0
  130. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_response.py +0 -0
  131. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/inference_response_chunk.py +0 -0
  132. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/item_locator.py +0 -0
  133. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/item_locator_template.py +0 -0
  134. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/model_create_params.py +0 -0
  135. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/model_delete_response.py +0 -0
  136. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/model_list_params.py +0 -0
  137. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/model_update_params.py +0 -0
  138. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span.py +0 -0
  139. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_batch_params.py +0 -0
  140. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_batch_response.py +0 -0
  141. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_create_params.py +0 -0
  142. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_search_params.py +0 -0
  143. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_search_response.py +0 -0
  144. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_update_params.py +0 -0
  145. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_upsert_batch_params.py +0 -0
  146. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/scale_gp_beta/types/span_upsert_batch_response.py +0 -0
  147. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/src/sgp_dev/lib/.keep +0 -0
  148. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/__init__.py +0 -0
  149. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/__init__.py +0 -0
  150. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/chat/__init__.py +0 -0
  151. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/chat/test_completions.py +0 -0
  152. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/files/__init__.py +0 -0
  153. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/files/test_content.py +0 -0
  154. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_completions.py +0 -0
  155. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_dataset_items.py +0 -0
  156. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_datasets.py +0 -0
  157. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_evaluation_items.py +0 -0
  158. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_evaluations.py +0 -0
  159. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_files.py +0 -0
  160. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_inference.py +0 -0
  161. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_models.py +0 -0
  162. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/api_resources/test_spans.py +0 -0
  163. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/conftest.py +0 -0
  164. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/sample_file.txt +0 -0
  165. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_client.py +0 -0
  166. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_deepcopy.py +0 -0
  167. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_extract_files.py +0 -0
  168. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_files.py +0 -0
  169. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_models.py +0 -0
  170. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_qs.py +0 -0
  171. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_required_args.py +0 -0
  172. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_response.py +0 -0
  173. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_streaming.py +0 -0
  174. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_transform.py +0 -0
  175. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_utils/test_proxy.py +0 -0
  176. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/test_utils/test_typing.py +0 -0
  177. {scale_gp_beta-0.1.0a19 → scale_gp_beta-0.1.0a21}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0-alpha.21"
3
+ }
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.21 (2025-06-13)
4
+
5
+ Full Changelog: [v0.1.0-alpha.20...v0.1.0-alpha.21](https://github.com/scaleapi/sgp-python-beta/compare/v0.1.0-alpha.20...v0.1.0-alpha.21)
6
+
7
+ ### Features
8
+
9
+ * Group id support ([#110](https://github.com/scaleapi/sgp-python-beta/issues/110)) ([d934d91](https://github.com/scaleapi/sgp-python-beta/commit/d934d9136db1210e934e2c34b754200678ea60ca))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **client:** correctly parse binary response | stream ([f802181](https://github.com/scaleapi/sgp-python-beta/commit/f80218120e7f6780461ee0eac836139241532421))
15
+
16
+ ## 0.1.0-alpha.20 (2025-06-12)
17
+
18
+ Full Changelog: [v0.1.0-alpha.19...v0.1.0-alpha.20](https://github.com/scaleapi/sgp-python-beta/compare/v0.1.0-alpha.19...v0.1.0-alpha.20)
19
+
20
+ ### Features
21
+
22
+ * Added flush() to Span ([#108](https://github.com/scaleapi/sgp-python-beta/issues/108)) ([5caf42f](https://github.com/scaleapi/sgp-python-beta/commit/5caf42f047f7ff0e4fbc9cb04835e9b9e13d65dc))
23
+
24
+
25
+ ### Chores
26
+
27
+ * **tests:** run tests in parallel ([b707f08](https://github.com/scaleapi/sgp-python-beta/commit/b707f08569ff81e9ed21d010d80de65013f8db67))
28
+
3
29
  ## 0.1.0-alpha.19 (2025-06-11)
4
30
 
5
31
  Full Changelog: [v0.1.0-alpha.18...v0.1.0-alpha.19](https://github.com/scaleapi/sgp-python-beta/compare/v0.1.0-alpha.18...v0.1.0-alpha.19)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: scale-gp-beta
3
- Version: 0.1.0a19
3
+ Version: 0.1.0a21
4
4
  Summary: The official Python library for the Scale GP API
5
5
  Project-URL: Homepage, https://github.com/scaleapi/sgp-python-beta
6
6
  Project-URL: Repository, https://github.com/scaleapi/sgp-python-beta
@@ -21,7 +21,7 @@ class MockDatabase:
21
21
  }
22
22
 
23
23
  def execute_query(self, query: str, trace_id: str) -> Dict[str, Any]:
24
- with tracing.create_span("db_query", input={"query": query}, trace=trace_id) as span:
24
+ with tracing.create_span("db_query", input={"query": query}, trace_id=trace_id) as span:
25
25
  # simulate delay
26
26
  time.sleep(random.uniform(0.1, 0.3))
27
27
 
@@ -30,7 +30,7 @@ class MockDatabase:
30
30
  return result
31
31
 
32
32
  def get_user_from_db(db: MockDatabase, user_id: int, trace_id: str) -> Dict[str, Any]:
33
- with tracing.create_span("get_user_from_db", input={"user_id": user_id}, trace=trace_id):
33
+ with tracing.create_span("get_user_from_db", input={"user_id": user_id}, trace_id=trace_id):
34
34
  query = f"SELECT * FROM users WHERE id = {user_id};"
35
35
 
36
36
  return db.execute_query(query, trace_id)
@@ -38,7 +38,7 @@ def get_user_from_db(db: MockDatabase, user_id: int, trace_id: str) -> Dict[str,
38
38
  def main() -> None:
39
39
  db = MockDatabase()
40
40
  trace_id = str(uuid.uuid4())
41
- with tracing.create_span("main", metadata={"env": "local"}, trace=trace_id):
41
+ with tracing.create_span("main", metadata={"env": "local"}, trace_id=trace_id):
42
42
  user = get_user_from_db(db, 1, trace_id)
43
43
  print(f"Retrieved user: {user.get('name')}")
44
44
 
@@ -0,0 +1,49 @@
1
+ import uuid
2
+ from datetime import datetime, timezone, timedelta
3
+
4
+ import scale_gp_beta.lib.tracing as tracing
5
+ from scale_gp_beta import SGPClient
6
+
7
+
8
+ def main() -> None:
9
+ parent_span_id = str(uuid.uuid4())
10
+ trace_id = str(uuid.uuid4())
11
+ child_span_id = str(uuid.uuid4())
12
+
13
+ now = datetime.now(timezone.utc)
14
+
15
+ start_time = (now - timedelta(minutes=10)).isoformat()
16
+ end_time = now.isoformat()
17
+ parent_span = tracing.create_span(
18
+ "my_parent_span_name",
19
+ input={"test": "input"},
20
+ output={"test": "output"},
21
+ metadata={"test": "metadata"},
22
+ span_id=parent_span_id,
23
+ trace_id=trace_id,
24
+ )
25
+ parent_span.start_time = start_time
26
+ parent_span.end_time = end_time
27
+ parent_span.flush()
28
+
29
+ start_time = (now - timedelta(minutes=6)).isoformat()
30
+ end_time = (now - timedelta(minutes=2)).isoformat()
31
+ child_span = tracing.create_span(
32
+ "my_child_span_name",
33
+ input={"test": "another input"},
34
+ output={"test": "another output"},
35
+ metadata={"test": "another metadata"},
36
+ span_id=child_span_id,
37
+ trace_id=trace_id,
38
+ parent_id=parent_span_id,
39
+ )
40
+ child_span.start_time = start_time
41
+ child_span.end_time = end_time
42
+ child_span.flush()
43
+
44
+
45
+ if __name__ == "__main__":
46
+ api_key = "xxx"
47
+ account_id = "xxx"
48
+ tracing.init(SGPClient(api_key=api_key, account_id=account_id), disabled=False)
49
+ main()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "scale-gp-beta"
3
- version = "0.1.0-alpha.19"
3
+ version = "0.1.0-alpha.21"
4
4
  description = "The official Python library for the Scale GP API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -54,6 +54,7 @@ dev-dependencies = [
54
54
  "importlib-metadata>=6.7.0",
55
55
  "rich>=13.7.1",
56
56
  "nest_asyncio==1.6.0",
57
+ "pytest-xdist>=3.6.1",
57
58
  ]
58
59
 
59
60
  [tool.rye.scripts]
@@ -125,7 +126,7 @@ replacement = '[\1](https://github.com/scaleapi/sgp-python-beta/tree/main/\g<2>)
125
126
 
126
127
  [tool.pytest.ini_options]
127
128
  testpaths = ["tests"]
128
- addopts = "--tb=short"
129
+ addopts = "--tb=short -n auto"
129
130
  xfail_strict = true
130
131
  asyncio_mode = "auto"
131
132
  asyncio_default_fixture_loop_scope = "session"
@@ -30,6 +30,8 @@ distro==1.8.0
30
30
  exceptiongroup==1.2.2
31
31
  # via anyio
32
32
  # via pytest
33
+ execnet==2.1.1
34
+ # via pytest-xdist
33
35
  filelock==3.12.4
34
36
  # via virtualenv
35
37
  h11==0.14.0
@@ -72,7 +74,9 @@ pygments==2.18.0
72
74
  pyright==1.1.399
73
75
  pytest==8.3.3
74
76
  # via pytest-asyncio
77
+ # via pytest-xdist
75
78
  pytest-asyncio==0.24.0
79
+ pytest-xdist==3.7.0
76
80
  python-dateutil==2.8.2
77
81
  # via time-machine
78
82
  pytz==2023.3.post1
@@ -1071,7 +1071,14 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1071
1071
  ) -> ResponseT:
1072
1072
  origin = get_origin(cast_to) or cast_to
1073
1073
 
1074
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
1074
+ if (
1075
+ inspect.isclass(origin)
1076
+ and issubclass(origin, BaseAPIResponse)
1077
+ # we only want to actually return the custom BaseAPIResponse class if we're
1078
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
1079
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
1080
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
1081
+ ):
1075
1082
  if not issubclass(origin, APIResponse):
1076
1083
  raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}")
1077
1084
 
@@ -1574,7 +1581,14 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1574
1581
  ) -> ResponseT:
1575
1582
  origin = get_origin(cast_to) or cast_to
1576
1583
 
1577
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
1584
+ if (
1585
+ inspect.isclass(origin)
1586
+ and issubclass(origin, BaseAPIResponse)
1587
+ # we only want to actually return the custom BaseAPIResponse class if we're
1588
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
1589
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
1590
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
1591
+ ):
1578
1592
  if not issubclass(origin, AsyncAPIResponse):
1579
1593
  raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}")
1580
1594
 
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "scale_gp_beta"
4
- __version__ = "0.1.0-alpha.19" # x-release-please-version
4
+ __version__ = "0.1.0-alpha.21" # x-release-please-version
@@ -1,14 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import TYPE_CHECKING, Any, Type, Optional
4
+ from typing import TYPE_CHECKING, Type, Optional
5
5
  from typing_extensions import override
6
6
 
7
7
  from scale_gp_beta.types.span_upsert_batch_params import Item as SpanCreateRequest
8
8
 
9
9
  from .util import iso_timestamp, generate_span_id
10
10
  from .scope import Scope
11
- from .types import SpanTypeLiterals, SpanStatusLiterals
11
+ from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam, SpanStatusLiterals
12
12
  from .exceptions import ParamsCreationError
13
13
 
14
14
  if TYPE_CHECKING:
@@ -53,20 +53,22 @@ class BaseSpan:
53
53
  queue_manager: Optional[TraceQueueManager] = None,
54
54
  span_id: Optional[str] = None,
55
55
  parent_span_id: Optional[str] = None,
56
- input: Optional[dict[str, Any]] = None,
57
- output: Optional[dict[str, Any]] = None,
58
- metadata: Optional[dict[str, Any]] = None,
56
+ group_id: Optional[str] = None,
57
+ input: Optional[SpanInputParam] = None,
58
+ output: Optional[SpanOutputParam] = None,
59
+ metadata: Optional[SpanMetadataParam] = None,
59
60
  span_type: SpanTypeLiterals = "STANDALONE"
60
61
  ):
61
62
  self.name = name
62
63
  self.trace_id = trace_id or "no_trace_id"
64
+ self.group_id = group_id
63
65
  self.span_id: str = span_id or generate_span_id()
64
66
  self.parent_span_id = parent_span_id
65
67
  self.start_time: Optional[str] = None
66
68
  self.end_time: Optional[str] = None
67
- self.input = input
68
- self.output = output
69
- self.metadata = metadata
69
+ self.input: SpanInputParam = input or {}
70
+ self.output: SpanOutputParam = output or {}
71
+ self.metadata: SpanMetadataParam = metadata or {}
70
72
  self.span_type: SpanTypeLiterals = span_type
71
73
  self.status: SpanStatusLiterals = "SUCCESS"
72
74
  self._queue_manager = queue_manager
@@ -79,6 +81,9 @@ class BaseSpan:
79
81
  def end(self) -> None:
80
82
  pass
81
83
 
84
+ def flush(self, blocking: bool = True) -> None:
85
+ pass
86
+
82
87
  def __enter__(self) -> BaseSpan:
83
88
  self.start()
84
89
  return self
@@ -92,8 +97,6 @@ class BaseSpan:
92
97
  # Naively record details in metadata for now, note that error capture only supported in context manager
93
98
  # TODO: support error observations when using direct span.start() and span.end()
94
99
  if exc_type is not None:
95
- if self.metadata is None:
96
- self.metadata = {}
97
100
  self.metadata["error"] = True
98
101
  self.metadata["error.type"] = exc_type.__name__
99
102
  self.metadata["error.message"] = str(exc_val)
@@ -109,9 +112,9 @@ class BaseSpan:
109
112
  id=self.span_id,
110
113
  trace_id=self.trace_id,
111
114
  start_timestamp=self.start_time,
112
- input=self.input or {},
113
- output=self.output or {},
114
- metadata=self.metadata or {},
115
+ input=self.input,
116
+ output=self.output,
117
+ metadata=self.metadata,
115
118
  status=self.status,
116
119
  type=self.span_type
117
120
  )
@@ -123,8 +126,34 @@ class BaseSpan:
123
126
  if self.parent_span_id is not None:
124
127
  request_data["parent_id"] = self.parent_span_id
125
128
 
129
+ if self.group_id is not None:
130
+ request_data["group_id"] = self.group_id
131
+
126
132
  return request_data
127
133
 
134
+ @override
135
+ def __repr__(self) -> str:
136
+ return (
137
+ f"{self.__class__.__name__}("
138
+ f"name='{self.name}', "
139
+ f"span_id='{self.span_id}', "
140
+ f"trace_id='{self.trace_id}', "
141
+ f"parent_span_id='{self.parent_span_id}', "
142
+ f"group_id='{self.group_id}', "
143
+ f"start_time='{self.start_time}', "
144
+ f"end_time='{self.end_time}', "
145
+ f"input='{self.input}', "
146
+ f"output='{self.output}', "
147
+ f"metadata='{self.metadata}', "
148
+ f"span_type='{self.span_type}', "
149
+ f"status='{self.status}'"
150
+ ")"
151
+ )
152
+
153
+ @override
154
+ def __str__(self) -> str:
155
+ return self.__repr__()
156
+
128
157
 
129
158
  class NoOpSpan(BaseSpan):
130
159
  @override
@@ -166,15 +195,29 @@ class Span(BaseSpan):
166
195
  queue_manager: TraceQueueManager,
167
196
  span_id: Optional[str] = None,
168
197
  parent_span_id: Optional[str] = None,
169
- input: Optional[dict[str, Any]] = None,
170
- output: Optional[dict[str, Any]] = None,
171
- metadata: Optional[dict[str, Any]] = None,
198
+ group_id: Optional[str] = None,
199
+ input: Optional[SpanInputParam] = None,
200
+ output: Optional[SpanOutputParam] = None,
201
+ metadata: Optional[SpanMetadataParam] = None,
172
202
  span_type: SpanTypeLiterals = "STANDALONE",
173
203
  ):
174
- super().__init__(name, trace_id, queue_manager, span_id, parent_span_id, input, output, metadata, span_type)
204
+ super().__init__(name, trace_id, queue_manager, span_id, parent_span_id, group_id, input, output, metadata, span_type)
175
205
  self._queue_manager: TraceQueueManager = queue_manager
176
206
  self.trace_id: str = trace_id
177
207
 
208
+ @override
209
+ def flush(self, blocking: bool = True) -> None:
210
+ """Export span. Defaults to in-thread and will block until the request is complete.
211
+
212
+ With `blocking=False`, this method will enqueue the request for the background worker.
213
+ The background worker batches and sends asynchronously.
214
+ :param blocking:
215
+ """
216
+ if blocking:
217
+ self._queue_manager.export_now(self)
218
+ else:
219
+ self._queue_manager.enqueue(self)
220
+
178
221
  @override
179
222
  def start(self) -> None:
180
223
  """Starts the operational Span.
@@ -1,12 +1,13 @@
1
1
  import logging
2
2
  import contextvars
3
3
  from types import TracebackType
4
- from typing import Dict, Type, Optional
4
+ from typing import Type, Optional
5
5
  from typing_extensions import override
6
6
 
7
7
  from .span import Span, NoOpSpan
8
8
  from .util import generate_trace_id
9
9
  from .scope import Scope
10
+ from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam
10
11
  from .trace_queue_manager import TraceQueueManager
11
12
 
12
13
  log: logging.Logger = logging.getLogger(__name__)
@@ -26,6 +27,12 @@ class BaseTrace:
26
27
  def end(self) -> None:
27
28
  pass
28
29
 
30
+ def flush(self, blocking: bool = True) -> None:
31
+ pass
32
+
33
+ def group_id(self) -> Optional[str]:
34
+ return None
35
+
29
36
  def __enter__(self) -> "BaseTrace":
30
37
  self.start()
31
38
  return self
@@ -38,6 +45,14 @@ class BaseTrace:
38
45
  ) -> None:
39
46
  self.end()
40
47
 
48
+ @override
49
+ def __repr__(self) -> str:
50
+ return f"{self.__class__.__name__}(trace_id='{self.trace_id})"
51
+
52
+ @override
53
+ def __str__(self) -> str:
54
+ return self.__repr__()
55
+
41
56
 
42
57
  class NoOpTrace(BaseTrace):
43
58
  def __init__(
@@ -45,18 +60,34 @@ class NoOpTrace(BaseTrace):
45
60
  name: str,
46
61
  queue_manager: Optional[TraceQueueManager] = None,
47
62
  trace_id: Optional[str] = None,
48
- root_span_id: Optional[str] = None,
49
- metadata: Optional[Dict[str, Optional[str]]] = None,
63
+ span_id: Optional[str] = None,
64
+ group_id: Optional[str] = None,
65
+ span_type: SpanTypeLiterals = "TRACER",
66
+ input: Optional[SpanInputParam] = None,
67
+ output: Optional[SpanOutputParam] = None,
68
+ metadata: Optional[SpanMetadataParam] = None,
50
69
  ):
51
70
  super().__init__(queue_manager, trace_id)
52
71
 
53
72
  self.root_span = NoOpSpan(
54
73
  name=name,
55
- span_id=root_span_id,
74
+ span_id=span_id,
56
75
  trace_id=self.trace_id,
76
+ group_id=group_id,
57
77
  queue_manager=queue_manager,
58
78
  metadata=metadata,
59
- span_type="TRACER"
79
+ span_type=span_type,
80
+ input=input,
81
+ output=output,
82
+ )
83
+
84
+ @override
85
+ def __repr__(self) -> str:
86
+ return (
87
+ f"{self.__class__.__name__}("
88
+ f"trace_id='{self.trace_id}', "
89
+ f"root_span='{repr(self.root_span)}', "
90
+ ")"
60
91
  )
61
92
 
62
93
  @override
@@ -67,6 +98,10 @@ class NoOpTrace(BaseTrace):
67
98
  def end(self) -> None:
68
99
  self.root_span.end()
69
100
 
101
+ @override
102
+ def group_id(self) -> Optional[str]:
103
+ return self.root_span.group_id
104
+
70
105
 
71
106
  class Trace(BaseTrace):
72
107
  def __init__(
@@ -74,19 +109,26 @@ class Trace(BaseTrace):
74
109
  name: str,
75
110
  queue_manager: TraceQueueManager,
76
111
  trace_id: Optional[str] = None,
77
- root_span_id: Optional[str] = None,
78
- metadata: Optional[Dict[str, Optional[str]]] = None,
112
+ span_id: Optional[str] = None,
113
+ group_id: Optional[str] = None,
114
+ span_type: SpanTypeLiterals = "TRACER",
115
+ input: Optional[SpanInputParam] = None,
116
+ output: Optional[SpanOutputParam] = None,
117
+ metadata: Optional[SpanMetadataParam] = None,
79
118
  ):
80
119
  super().__init__(queue_manager, trace_id)
81
120
  self.queue_manager: TraceQueueManager = queue_manager
82
121
 
83
122
  self.root_span = Span(
84
123
  name=name,
85
- span_id=root_span_id,
124
+ span_id=span_id,
86
125
  trace_id=self.trace_id,
126
+ group_id=group_id,
87
127
  queue_manager=queue_manager,
88
128
  metadata=metadata,
89
- span_type="TRACER"
129
+ span_type=span_type,
130
+ input=input,
131
+ output=output,
90
132
  )
91
133
 
92
134
  @override
@@ -116,3 +158,20 @@ class Trace(BaseTrace):
116
158
  self._contextvar_token = None
117
159
 
118
160
  self.root_span.end()
161
+
162
+ @override
163
+ def flush(self, blocking: bool = True) -> None:
164
+ self.root_span.flush(blocking=blocking)
165
+
166
+ @override
167
+ def group_id(self) -> Optional[str]:
168
+ return self.root_span.group_id
169
+
170
+ @override
171
+ def __repr__(self) -> str:
172
+ return (
173
+ f"{self.__class__.__name__}("
174
+ f"trace_id='{self.trace_id}', "
175
+ f"root_span='{repr(self.root_span)}', "
176
+ ")"
177
+ )
@@ -34,11 +34,22 @@ class TraceExporter:
34
34
  self.backoff = backoff
35
35
  self.max_backoff = max_backoff
36
36
 
37
+ def export_span(self, client: SGPClient, span: "Span") -> None:
38
+ # only upsert endpoint is batch upsert, so we work in batches
39
+ batch: SpanRequestBatch = self._create_one_span_batch(span)
40
+
41
+ log.info(f"Exporting single span with id {span.span_id}")
42
+ self._export_batch(batch, client)
43
+
37
44
  def export(self, client: SGPClient, queue: "Queue[Span]") -> None:
38
45
  # this is also thread safe, two threads can call this method with the same queue at once
39
46
  # the ordering of the requests might be randomly split between the two threads, but they should all be picked up
40
47
  batches: list[SpanRequestBatch] = self._create_batches(queue)
41
48
 
49
+ if not batches:
50
+ log.debug("No new span batches to export")
51
+ return
52
+
42
53
  log.info(f"Exporting {len(batches)} span batches")
43
54
 
44
55
  for batch in batches:
@@ -73,15 +84,25 @@ class TraceExporter:
73
84
  while len(span_batch) < self.max_batch_size and queue.qsize() > 0:
74
85
  try:
75
86
  span: "Span" = queue.get_nowait()
76
- span_request = span.to_request_params()
77
- span_batch.append(span_request)
87
+ self._add_span_to_batch(span, span_batch)
78
88
  except Empty:
79
89
  break
80
- except ParamsCreationError as e:
81
- log.warning(f"ParamsCreationError: {e}\ndropping...")
82
90
 
83
91
  if not span_batch:
84
92
  break
85
93
  batches.append(span_batch)
86
94
 
87
95
  return batches
96
+
97
+ def _create_one_span_batch(self, span: "Span") -> SpanRequestBatch:
98
+ span_batch: SpanRequestBatch = []
99
+ self._add_span_to_batch(span, span_batch)
100
+
101
+ return span_batch
102
+
103
+ def _add_span_to_batch(self, span: "Span", span_batch: SpanRequestBatch) -> None:
104
+ try:
105
+ span_request = span.to_request_params()
106
+ span_batch.append(span_request)
107
+ except ParamsCreationError as e:
108
+ log.warning(f"ParamsCreationError: dropping span: {span}\n{e}")
@@ -76,16 +76,10 @@ class TraceQueueManager:
76
76
 
77
77
  def report_span_start(self, span: "Span") -> None:
78
78
  # TODO: support making this optional. Current backend requires us to send span starts
79
- try:
80
- self._queue.put_nowait(span)
81
- except queue.Full:
82
- log.warning(f"Queue full, ignoring span {span.span_id}")
79
+ self.enqueue(span)
83
80
 
84
81
  def report_span_end(self, span: "Span") -> None:
85
- try:
86
- self._queue.put_nowait(span)
87
- except queue.Full:
88
- log.warning(f"Queue full, ignoring span {span.span_id}")
82
+ self.enqueue(span)
89
83
 
90
84
  def report_trace_start(self, trace: "Trace") -> None:
91
85
  pass
@@ -96,6 +90,16 @@ class TraceQueueManager:
96
90
  def flush_queue(self) -> None:
97
91
  self._export()
98
92
 
93
+ def enqueue(self, span: "Span") -> None:
94
+ try:
95
+ self._queue.put_nowait(span)
96
+ except queue.Full:
97
+ log.warning(f"Queue full, ignoring span {span.span_id}")
98
+
99
+ def export_now(self, span: "Span") -> None:
100
+ if self.client:
101
+ self._exporter.export_span(self.client, span)
102
+
99
103
  @property
100
104
  def client(self) -> Optional[SGPClient]:
101
105
  """