diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bdcbb55ac1..421ac6d58f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,7 @@ jobs: run: npm cache clean --force || true - run: npx nx affected -t install --with dev - run: npx nx affected -t lint --parallel=3 + - run: npx nx affected -t type-check --parallel=3 build-packages: name: Build Packages diff --git a/packages/traceloop-sdk/poetry.lock b/packages/traceloop-sdk/poetry.lock index e9c83c5402..e3e764fe3e 100644 --- a/packages/traceloop-sdk/poetry.lock +++ b/packages/traceloop-sdk/poetry.lock @@ -1393,13 +1393,88 @@ files = [ [package.dependencies] typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} +[[package]] +name = "mypy" +version = "1.18.2" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "mypy-1.18.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c"}, + {file = "mypy-1.18.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e"}, + {file = "mypy-1.18.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b"}, + {file = "mypy-1.18.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66"}, + {file = "mypy-1.18.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428"}, + {file = "mypy-1.18.2-cp310-cp310-win_amd64.whl", hash = "sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed"}, + {file = "mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f"}, + {file = "mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341"}, + {file = "mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d"}, + {file = "mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86"}, + {file = "mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37"}, + {file = "mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8"}, + {file = "mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34"}, + {file = "mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764"}, + {file = "mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893"}, + {file = "mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914"}, + {file = "mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8"}, + {file = "mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074"}, + {file = "mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc"}, + {file = "mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e"}, + {file = "mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986"}, + {file = "mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d"}, + {file = "mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba"}, + {file = "mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544"}, + {file = "mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce"}, + {file = "mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d"}, + {file = "mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c"}, + {file = "mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb"}, + {file = "mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075"}, + {file = "mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf"}, + {file = "mypy-1.18.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b"}, + {file = "mypy-1.18.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133"}, + {file = "mypy-1.18.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6"}, + {file = "mypy-1.18.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac"}, + {file = "mypy-1.18.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b"}, + {file = "mypy-1.18.2-cp39-cp39-win_amd64.whl", hash = "sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0"}, + {file = "mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e"}, + {file = "mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b"}, +] + +[package.dependencies] +mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing_extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + [[package]] name = "numpy" version = "1.26.4" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.9" -groups = ["test"] +groups = ["dev", "test"] markers = "platform_python_implementation == \"PyPy\"" files = [ {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, @@ -1568,7 +1643,7 @@ wrapt = ">=1.0.0,<2.0.0" [[package]] name = "opentelemetry-instrumentation-agno" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Agno instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1592,7 +1667,7 @@ url = "../opentelemetry-instrumentation-agno" [[package]] name = "opentelemetry-instrumentation-alephalpha" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Aleph Alpha instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1616,7 +1691,7 @@ url = "../opentelemetry-instrumentation-alephalpha" [[package]] name = "opentelemetry-instrumentation-anthropic" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Anthropic instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1640,7 +1715,7 @@ url = "../opentelemetry-instrumentation-anthropic" [[package]] name = "opentelemetry-instrumentation-bedrock" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Bedrock instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1663,7 +1738,7 @@ url = "../opentelemetry-instrumentation-bedrock" [[package]] name = "opentelemetry-instrumentation-chromadb" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Chroma DB instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1687,7 +1762,7 @@ url = "../opentelemetry-instrumentation-chromadb" [[package]] name = "opentelemetry-instrumentation-cohere" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Cohere instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1711,7 +1786,7 @@ url = "../opentelemetry-instrumentation-cohere" [[package]] name = "opentelemetry-instrumentation-crewai" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry crewAI instrumentation" optional = false python-versions = ">=3.10,<4" @@ -1735,7 +1810,7 @@ url = "../opentelemetry-instrumentation-crewai" [[package]] name = "opentelemetry-instrumentation-google-generativeai" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Google Generative AI instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1759,7 +1834,7 @@ url = "../opentelemetry-instrumentation-google-generativeai" [[package]] name = "opentelemetry-instrumentation-groq" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Groq instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1783,7 +1858,7 @@ url = "../opentelemetry-instrumentation-groq" [[package]] name = "opentelemetry-instrumentation-haystack" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Haystack instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1807,7 +1882,7 @@ url = "../opentelemetry-instrumentation-haystack" [[package]] name = "opentelemetry-instrumentation-lancedb" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Lancedb instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1831,7 +1906,7 @@ url = "../opentelemetry-instrumentation-lancedb" [[package]] name = "opentelemetry-instrumentation-langchain" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Langchain instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1855,7 +1930,7 @@ url = "../opentelemetry-instrumentation-langchain" [[package]] name = "opentelemetry-instrumentation-llamaindex" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry LlamaIndex instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1898,7 +1973,7 @@ opentelemetry-instrumentation = "0.59b0" [[package]] name = "opentelemetry-instrumentation-marqo" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Marqo instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1922,7 +1997,7 @@ url = "../opentelemetry-instrumentation-marqo" [[package]] name = "opentelemetry-instrumentation-mcp" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry mcp instrumentation" optional = false python-versions = ">=3.10,<4" @@ -1946,7 +2021,7 @@ url = "../opentelemetry-instrumentation-mcp" [[package]] name = "opentelemetry-instrumentation-milvus" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Milvus instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1970,7 +2045,7 @@ url = "../opentelemetry-instrumentation-milvus" [[package]] name = "opentelemetry-instrumentation-mistralai" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Mistral AI instrumentation" optional = false python-versions = ">=3.9,<4" @@ -1994,7 +2069,7 @@ url = "../opentelemetry-instrumentation-mistralai" [[package]] name = "opentelemetry-instrumentation-ollama" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Ollama instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2018,7 +2093,7 @@ url = "../opentelemetry-instrumentation-ollama" [[package]] name = "opentelemetry-instrumentation-openai" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry OpenAI instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2042,7 +2117,7 @@ url = "../opentelemetry-instrumentation-openai" [[package]] name = "opentelemetry-instrumentation-openai-agents" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry OpenAI Agents instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2066,7 +2141,7 @@ url = "../opentelemetry-instrumentation-openai-agents" [[package]] name = "opentelemetry-instrumentation-pinecone" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Pinecone instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2090,7 +2165,7 @@ url = "../opentelemetry-instrumentation-pinecone" [[package]] name = "opentelemetry-instrumentation-qdrant" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Qdrant instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2136,7 +2211,7 @@ instruments = ["redis (>=2.6)"] [[package]] name = "opentelemetry-instrumentation-replicate" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Replicate instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2182,7 +2257,7 @@ instruments = ["requests (>=2.0,<3.0)"] [[package]] name = "opentelemetry-instrumentation-sagemaker" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry SageMaker instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2244,7 +2319,7 @@ wrapt = ">=1.0.0,<2.0.0" [[package]] name = "opentelemetry-instrumentation-together" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Together AI instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2268,7 +2343,7 @@ url = "../opentelemetry-instrumentation-together" [[package]] name = "opentelemetry-instrumentation-transformers" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry transformers instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2312,7 +2387,7 @@ instruments = ["urllib3 (>=1.0.0,<3.0.0)"] [[package]] name = "opentelemetry-instrumentation-vertexai" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Vertex AI instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2336,7 +2411,7 @@ url = "../opentelemetry-instrumentation-vertexai" [[package]] name = "opentelemetry-instrumentation-watsonx" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry IBM Watsonx Instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2360,7 +2435,7 @@ url = "../opentelemetry-instrumentation-watsonx" [[package]] name = "opentelemetry-instrumentation-weaviate" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Weaviate instrumentation" optional = false python-versions = ">=3.9,<4" @@ -2384,7 +2459,7 @@ url = "../opentelemetry-instrumentation-weaviate" [[package]] name = "opentelemetry-instrumentation-writer" -version = "0.49.1" +version = "0.49.2" description = "OpenTelemetry Writer instrumentation" optional = false python-versions = ">=3.10,<4" @@ -2670,6 +2745,36 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] +[[package]] +name = "pandas-stubs" +version = "2.3.2.250926" +description = "Type annotations for pandas" +optional = false +python-versions = ">=3.10" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "pandas_stubs-2.3.2.250926-py3-none-any.whl", hash = "sha256:81121818453dcfe00f45c852f4dceee043640b813830f6e7bd084a4ef7ff7270"}, + {file = "pandas_stubs-2.3.2.250926.tar.gz", hash = "sha256:c64b9932760ceefb96a3222b953e6a251321a9832a28548be6506df473a66406"}, +] + +[package.dependencies] +numpy = ">=1.23.5" +types-pytz = ">=2022.1.1" + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + [[package]] name = "pluggy" version = "1.5.0" @@ -3592,13 +3697,84 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "types-colorama" +version = "0.4.15.20250801" +description = "Typing stubs for colorama" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "types_colorama-0.4.15.20250801-py3-none-any.whl", hash = "sha256:b6e89bd3b250fdad13a8b6a465c933f4a5afe485ea2e2f104d739be50b13eea9"}, + {file = "types_colorama-0.4.15.20250801.tar.gz", hash = "sha256:02565d13d68963d12237d3f330f5ecd622a3179f7b5b14ee7f16146270c357f5"}, +] + +[[package]] +name = "types-pytz" +version = "2025.2.0.20251108" +description = "Typing stubs for pytz" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "types_pytz-2025.2.0.20251108-py3-none-any.whl", hash = "sha256:0f1c9792cab4eb0e46c52f8845c8f77cf1e313cb3d68bf826aa867fe4717d91c"}, + {file = "types_pytz-2025.2.0.20251108.tar.gz", hash = "sha256:fca87917836ae843f07129567b74c1929f1870610681b4c92cb86a3df5817bdb"}, +] + +[[package]] +name = "types-requests" +version = "2.31.0.6" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "types-requests-2.31.0.6.tar.gz", hash = "sha256:cd74ce3b53c461f1228a9b783929ac73a666658f223e28ed29753771477b3bd0"}, + {file = "types_requests-2.31.0.6-py3-none-any.whl", hash = "sha256:a2db9cb228a81da8348b49ad6db3f5519452dd20a9c1e1a868c83c5fe88fd1a9"}, +] + +[package.dependencies] +types-urllib3 = "*" + +[[package]] +name = "types-requests" +version = "2.32.4.20250913" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_python_implementation != \"PyPy\"" +files = [ + {file = "types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1"}, + {file = "types_requests-2.32.4.20250913.tar.gz", hash = "sha256:abd6d4f9ce3a9383f269775a9835a4c24e5cd6b9f647d64f88aa4613c33def5d"}, +] + +[package.dependencies] +urllib3 = ">=2" + +[[package]] +name = "types-urllib3" +version = "1.26.25.14" +description = "Typing stubs for urllib3" +optional = false +python-versions = "*" +groups = ["dev"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"}, + {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "test"] +groups = ["main", "dev", "test"] markers = "platform_python_implementation == \"PyPy\"" files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, @@ -3642,7 +3818,7 @@ version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" -groups = ["main", "test"] +groups = ["main", "dev", "test"] markers = "platform_python_implementation != \"PyPy\"" files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, @@ -3895,4 +4071,4 @@ datasets = [] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "d8dbe03801aa910b96531b3beb5ace6d1842b51796d3952262d370656cd433d4" +content-hash = "16ac125b5109af187aa3e992c2e3b09154a6215bd9e0f202b6e687818ab964d6" diff --git a/packages/traceloop-sdk/project.json b/packages/traceloop-sdk/project.json index f9c3c9753f..2fbf34b1b1 100644 --- a/packages/traceloop-sdk/project.json +++ b/packages/traceloop-sdk/project.json @@ -50,6 +50,14 @@ "outputFile": "reports/packages/traceloop-sdk/pylint.txt" } }, + "type-check": { + "executor": "@nxlv/python:run-commands", + "outputs": [], + "options": { + "command": "poetry run mypy traceloop/sdk", + "cwd": "packages/traceloop-sdk" + } + }, "test": { "executor": "@nxlv/python:run-commands", "outputs": [ diff --git a/packages/traceloop-sdk/pyproject.toml b/packages/traceloop-sdk/pyproject.toml index 374f084076..f817c75d3f 100644 --- a/packages/traceloop-sdk/pyproject.toml +++ b/packages/traceloop-sdk/pyproject.toml @@ -79,6 +79,10 @@ autopep8 = "^2.2.0" flake8 = "7.0.0" pytest = "^8.2.2" pytest-sugar = "1.0.0" +mypy = "^1.18.2" +types-requests = "^2.31.0" +types-colorama = "^0.4.15" +pandas-stubs = "*" [tool.poetry.group.test.dependencies] openai = "^1.31.1" @@ -94,6 +98,44 @@ pandas = ">=1.0.0" [tool.poetry.extras] datasets = ["pandas"] +[tool.mypy] +python_version = "3.10" +warn_return_any = true +warn_unused_configs = true +disallow_untyped_defs = true +disallow_any_unimported = false +no_implicit_optional = true +warn_redundant_casts = true +warn_unused_ignores = true +warn_no_return = true +check_untyped_defs = true +strict_equality = true +namespace_packages = true +explicit_package_bases = true +plugins = ["pydantic.mypy"] + +# Blacklist approach - all folders checked except those excluded below +exclude = [ + "traceloop/sdk/decorators", + "traceloop/sdk/prompts", + "traceloop/sdk/tracing", + "traceloop/sdk/utils", + "traceloop/sdk/__init__.py", + "tests/", +] + +[[tool.mypy.overrides]] +module = [ + "cuid.*", + "posthog.*", +] +ignore_missing_imports = true + +[pydantic-mypy] +init_forbid_extra = true +init_typed = true +warn_required_dynamic_aliases = true + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/packages/traceloop-sdk/tests/test_user_feedback.py b/packages/traceloop-sdk/tests/test_user_feedback.py index c73a7f8acc..354d576ada 100644 --- a/packages/traceloop-sdk/tests/test_user_feedback.py +++ b/packages/traceloop-sdk/tests/test_user_feedback.py @@ -35,7 +35,7 @@ def test_user_feedback_initialization(mock_http): assert feedback._app_name == "test-app" -def test_create_basic_feedback(user_feedback, mock_http): +def test_create_basic_feedback(user_feedback: UserFeedback, mock_http: Mock): """Test creating basic user feedback""" user_feedback.create( annotation_task="task_123", entity_id="instance_456", tags={"sentiment": "positive"} @@ -56,7 +56,7 @@ def test_create_basic_feedback(user_feedback, mock_http): ) -def test_create_feedback_complex_tags(user_feedback, mock_http): +def test_create_feedback_complex_tags(user_feedback: UserFeedback, mock_http: Mock): """Test creating user feedback with complex tags""" tags = {"sentiment": "positive", "relevance": 0.95, "tones": ["happy", "nice"]} @@ -77,7 +77,7 @@ def test_create_feedback_complex_tags(user_feedback, mock_http): ) -def test_create_feedback_parameter_validation(user_feedback): +def test_create_feedback_parameter_validation(user_feedback: UserFeedback): """Test parameter validation for feedback creation""" with pytest.raises(ValueError, match="annotation_task is required"): user_feedback.create(annotation_task="", entity_id="instance_456", tags={"sentiment": "positive"}) diff --git a/packages/traceloop-sdk/traceloop/sdk/annotation/base_annotation.py b/packages/traceloop-sdk/traceloop/sdk/annotation/base_annotation.py index 34d273540e..b9e515ca0c 100644 --- a/packages/traceloop-sdk/traceloop/sdk/annotation/base_annotation.py +++ b/packages/traceloop-sdk/traceloop/sdk/annotation/base_annotation.py @@ -29,7 +29,7 @@ def create( Args: annotation_task (str): The ID/slug of the annotation task to report to. Can be found at app.traceloop.com/annotation_tasks/:annotation_task_id - entity_id (str): The ID of the specific entity instance being annotated, should be reported + entity_id (str): The ID of the specific entity being annotated, should be reported in the association properties tags (Dict[str, Any]): Dictionary containing the tags to be reported. Should match the tags defined in the annotation task @@ -39,7 +39,7 @@ def create( client = Client(api_key="your-key") client.annotation.create( annotation_task="task_123", - entity_id="instance_456", + entity_id="456", tags={ "sentiment": "positive", "relevance": 0.95, diff --git a/packages/traceloop-sdk/traceloop/sdk/annotation/user_feedback.py b/packages/traceloop-sdk/traceloop/sdk/annotation/user_feedback.py index b0ab645e00..8dba6cf07b 100644 --- a/packages/traceloop-sdk/traceloop/sdk/annotation/user_feedback.py +++ b/packages/traceloop-sdk/traceloop/sdk/annotation/user_feedback.py @@ -8,36 +8,35 @@ class UserFeedback(BaseAnnotation): def __init__(self, http: HTTPClient, app_name: str): super().__init__(http, app_name, "user_feedback") - -def create( - self, - annotation_task: str, - entity_instance_id: str, - tags: Dict[str, Any], -) -> None: - """Create an annotation for a specific task. - - Args: - annotation_task (str): The ID/slug of the annotation task to report to. - Can be found at app.traceloop.com/annotation_tasks/:annotation_task_id - entity_instance_id (str): The ID of the specific entity instance being annotated, should be reported - in the association properties - tags (Dict[str, Any]): Dictionary containing the tags to be reported. - Should match the tags defined in the annotation task - - Example: - ```python - client = Client(api_key="your-key") - client.annotation.create( - annotation_task="task_123", - entity_instance_id="instance_456", - tags={ - "sentiment": "positive", - "relevance": 0.95, - "tones": ["happy", "nice"] - }, - ) - ``` - """ - - return BaseAnnotation.create(self, annotation_task, entity_instance_id, tags) + def create( + self, + annotation_task: str, + entity_id: str, + tags: Dict[str, Any], + ) -> None: + """Create an annotation for a specific task. + + Args: + annotation_task (str): The ID/slug of the annotation task to report to. + Can be found at app.traceloop.com/annotation_tasks/:annotation_task_id + entity_id (str): The ID of the specific entity being annotated, should be reported + in the association properties + tags (Dict[str, Any]): Dictionary containing the tags to be reported. + Should match the tags defined in the annotation task + + Example: + ```python + client = Client(api_key="your-key") + client.annotation.create( + annotation_task="task_123", + entity_id="instance_456", + tags={ + "sentiment": "positive", + "relevance": 0.95, + "tones": ["happy", "nice"] + }, + ) + ``` + """ + + return BaseAnnotation.create(self, annotation_task, entity_id, tags) diff --git a/packages/traceloop-sdk/traceloop/sdk/client/client.py b/packages/traceloop-sdk/traceloop/sdk/client/client.py index a1ebc8b2e5..b3d2510f63 100644 --- a/packages/traceloop-sdk/traceloop/sdk/client/client.py +++ b/packages/traceloop-sdk/traceloop/sdk/client/client.py @@ -63,4 +63,5 @@ def __init__( self.user_feedback = UserFeedback(self._http, self.app_name) self.datasets = Datasets(self._http) experiment_slug = os.getenv("TRACELOOP_EXP_SLUG") - self.experiment = Experiment(self._http, self._async_http, experiment_slug) + # TODO: Fix type - Experiment constructor should accept Optional[str] + self.experiment = Experiment(self._http, self._async_http, experiment_slug) # type: ignore[arg-type] diff --git a/packages/traceloop-sdk/traceloop/sdk/client/http.py b/packages/traceloop-sdk/traceloop/sdk/client/http.py index 60287bf593..1e1af895f1 100644 --- a/packages/traceloop-sdk/traceloop/sdk/client/http.py +++ b/packages/traceloop-sdk/traceloop/sdk/client/http.py @@ -14,7 +14,7 @@ def __init__(self, base_url: str, api_key: str, version: str): self.api_key = api_key self.version = version - def _headers(self): + def _headers(self) -> Dict[str, str]: return { "Authorization": f"Bearer {self.api_key}", "X-Traceloop-SDK-Version": self.version, diff --git a/packages/traceloop-sdk/traceloop/sdk/dataset/dataset.py b/packages/traceloop-sdk/traceloop/sdk/dataset/dataset.py index 6f3c6a804e..1506ff0aaf 100644 --- a/packages/traceloop-sdk/traceloop/sdk/dataset/dataset.py +++ b/packages/traceloop-sdk/traceloop/sdk/dataset/dataset.py @@ -86,7 +86,7 @@ def add_column(self, slug: str, name: str, col_type: ColumnType) -> Column: self.columns.append(column) return column - def _create_columns(self, raw_columns: Dict[str, ColumnDefinition]): + def _create_columns(self, raw_columns: Dict[str, ColumnDefinition]) -> None: """Create Column objects from API response which includes column IDs""" for column_slug, column_def in raw_columns.items(): column = Column( @@ -98,7 +98,7 @@ def _create_columns(self, raw_columns: Dict[str, ColumnDefinition]): ) self.columns.append(column) - def _create_rows(self, raw_rows: List[RowObject]): + def _create_rows(self, raw_rows: List[RowObject]) -> None: for _, row_obj in enumerate(raw_rows): row = Row( http=self._http, diff --git a/packages/traceloop-sdk/traceloop/sdk/datasets/datasets.py b/packages/traceloop-sdk/traceloop/sdk/datasets/datasets.py index ded12fae2b..1d3d9ae87e 100644 --- a/packages/traceloop-sdk/traceloop/sdk/datasets/datasets.py +++ b/packages/traceloop-sdk/traceloop/sdk/datasets/datasets.py @@ -1,5 +1,5 @@ import csv -from typing import List, Optional +from typing import List, Optional, cast from pathlib import Path try: @@ -81,6 +81,10 @@ def from_csv( reader = csv.DictReader(csvfile, delimiter=delimiter) + # TODO: Handle None case for fieldnames more gracefully + if reader.fieldnames is None: + raise ValueError("CSV file has no headers") + for field_name in reader.fieldnames: columns_definition.append( ColumnDefinition( @@ -138,8 +142,9 @@ def from_dataframe( ) ) + # TODO: Pandas returns Hashable keys, should ensure they're strings rows = [ - {self._slugify(k): v for k, v in row.items()} + {self._slugify(str(k)): v for k, v in row.items()} for row in df.to_dict(orient="records") ] @@ -160,14 +165,14 @@ def get_version_csv(self, slug: str, version: str) -> str: result = self._http.get(f"datasets/{slug}/versions/{version}") if result is None: raise Exception(f"Failed to get dataset {slug} by version {version}") - return result + return cast(str, result) def get_version_jsonl(self, slug: str, version: str) -> str: """Get a specific version of a dataset as a JSONL string""" result = self._http.get(f"datasets/{slug}/versions/{version}/jsonl") if result is None: raise Exception(f"Failed to get dataset {slug} by version {version}") - return result + return cast(str, result) def _create_dataset(self, input: CreateDatasetRequest) -> CreateDatasetResponse: """Create new dataset""" diff --git a/packages/traceloop-sdk/traceloop/sdk/decorators/__init__.py b/packages/traceloop-sdk/traceloop/sdk/decorators/__init__.py index 2a7a216bcd..0036a99800 100644 --- a/packages/traceloop-sdk/traceloop/sdk/decorators/__init__.py +++ b/packages/traceloop-sdk/traceloop/sdk/decorators/__init__.py @@ -1,4 +1,4 @@ -from typing import Optional, TypeVar, Callable, Any, ParamSpec, Awaitable +from typing import Any, Optional, TypeVar, Callable import warnings from opentelemetry.semconv_ai import TraceloopSpanKindValues @@ -8,9 +8,7 @@ entity_method, ) -P = ParamSpec("P") -R = TypeVar("R") -F = TypeVar("F", bound=Callable[P, R | Awaitable[R]]) +F = TypeVar("F", bound=Callable[..., Any]) def task( diff --git a/packages/traceloop-sdk/traceloop/sdk/decorators/base.py b/packages/traceloop-sdk/traceloop/sdk/decorators/base.py index c742f2eabe..dee1e41de2 100644 --- a/packages/traceloop-sdk/traceloop/sdk/decorators/base.py +++ b/packages/traceloop-sdk/traceloop/sdk/decorators/base.py @@ -2,13 +2,11 @@ from functools import wraps import os from typing import ( - Optional, TypeVar, + Optional, Callable, Any, cast, - ParamSpec, - Awaitable, ) import inspect import warnings @@ -28,10 +26,7 @@ from traceloop.sdk.utils import camel_to_snake from traceloop.sdk.utils.json_encoder import JSONEncoder -P = ParamSpec("P") - -R = TypeVar("R") -F = TypeVar("F", bound=Callable[P, R | Awaitable[R]]) +F = TypeVar("F", bound=Callable[..., Any]) def _truncate_json_if_needed(json_str: str) -> str: diff --git a/packages/traceloop-sdk/traceloop/sdk/evaluator/stream_client.py b/packages/traceloop-sdk/traceloop/sdk/evaluator/stream_client.py index 2dfb8e37bf..af933a1563 100644 --- a/packages/traceloop-sdk/traceloop/sdk/evaluator/stream_client.py +++ b/packages/traceloop-sdk/traceloop/sdk/evaluator/stream_client.py @@ -52,13 +52,13 @@ async def wait_for_result( except Exception as e: raise Exception(f"Unexpected error in SSE stream: {e}") - async def _handle_sse_response(self, response) -> ExecutionResponse: + async def _handle_sse_response(self, response: httpx.Response) -> ExecutionResponse: """Handle SSE response: check status and parse result""" if response.status_code != 200: error_text = await response.aread() - raise Exception( - f"Failed to stream results: {response.status_code}, body: {error_text}" - ) + # TODO: Fix bytes formatting - should decode error_text or use !r + error_msg = f"Failed to stream results: {response.status_code}, body: {error_text}" # type: ignore[str-bytes-safe] # noqa: E501 + raise Exception(error_msg) response_text = await response.aread() return self._parse_sse_result(response_text.decode()) diff --git a/packages/traceloop-sdk/traceloop/sdk/experiment/experiment.py b/packages/traceloop-sdk/traceloop/sdk/experiment/experiment.py index 6f0baf70d3..9041d8ebe3 100644 --- a/packages/traceloop-sdk/traceloop/sdk/experiment/experiment.py +++ b/packages/traceloop-sdk/traceloop/sdk/experiment/experiment.py @@ -95,13 +95,15 @@ async def run( results: List[TaskResponse] = [] errors: List[str] = [] - async def run_single_row(row) -> TaskResponse: + async def run_single_row(row: Optional[Dict[str, Any]]) -> TaskResponse: try: - task_result = await task(row) + # TODO: Fix type annotation - task should return Awaitable, not dict + task_result = await task(row) # type: ignore[misc] + # TODO: Fix type - task_input should accept Optional[Dict] task_id = self._create_task( experiment_slug=experiment_slug, experiment_run_id=run_id, - task_input=row, + task_input=row, # type: ignore[arg-type] task_output=task_result, ).id @@ -132,12 +134,13 @@ async def run_single_row(row) -> TaskResponse: input=task_result, ) - eval_results[evaluator_slug] = ( - f"Triggered execution of {evaluator_slug}" - ) + # TODO: Fix type - eval_results should accept Union[Dict, str] + msg = f"Triggered execution of {evaluator_slug}" + eval_results[evaluator_slug] = msg # type: ignore[assignment] except Exception as e: - eval_results[evaluator_slug] = f"Error: {str(e)}" + # TODO: Fix type - eval_results should accept Union[Dict, str] + eval_results[evaluator_slug] = f"Error: {str(e)}" # type: ignore[assignment] return TaskResponse( task_result=task_result, @@ -151,7 +154,7 @@ async def run_single_row(row) -> TaskResponse: semaphore = asyncio.Semaphore(50) - async def run_with_semaphore(row) -> TaskResponse: + async def run_with_semaphore(row: Optional[Dict[str, Any]]) -> TaskResponse: async with semaphore: return await run_single_row(row) diff --git a/packages/traceloop-sdk/traceloop/sdk/fetcher.py b/packages/traceloop-sdk/traceloop/sdk/fetcher.py index 12ac308119..0abc413e5a 100644 --- a/packages/traceloop-sdk/traceloop/sdk/fetcher.py +++ b/packages/traceloop-sdk/traceloop/sdk/fetcher.py @@ -6,7 +6,7 @@ import requests from threading import Thread, Event -from typing import Dict +from typing import Dict, Any from tenacity import ( RetryError, retry, @@ -51,7 +51,7 @@ def __init__(self, base_url: str, api_key: str): ), ) - def run(self): + def run(self) -> None: refresh_data( self._base_url, self._api_key, @@ -61,10 +61,10 @@ def run(self): self._exit_monitor.start() self._poller_thread.start() - def post(self, api: str, body: Dict[str, str]): + def post(self, api: str, body: Dict[str, str]) -> None: post_url(f"{self._base_url}/v1/traceloop/{api}", self._api_key, body) - def api_post(self, api: str, body: Dict[str, typing.Any]): + def api_post(self, api: str, body: Dict[str, typing.Any]) -> None: try: post_url(f"{self._base_url}/v2/{api}", self._api_key, body) except Exception as e: @@ -83,7 +83,7 @@ def __init__( super().__init__(lambda e: check_http_error(e)) -def check_http_error(e): +def check_http_error(e: BaseException) -> bool: return isinstance(e, requests.exceptions.HTTPError) and ( 500 <= e.response.status_code < 600 ) @@ -94,7 +94,7 @@ def check_http_error(e): stop=stop_after_attempt(MAX_RETRIES), retry=RetryIfServerError(), ) -def fetch_url(url: str, api_key: str): +def fetch_url(url: str, api_key: str) -> Any: response = requests.get( url, headers={ @@ -114,7 +114,7 @@ def fetch_url(url: str, api_key: str): return response.json() -def post_url(url: str, api_key: str, body: Dict[str, typing.Any]): +def post_url(url: str, api_key: str, body: Dict[str, typing.Any]) -> None: response = requests.post( url, headers={ @@ -135,7 +135,7 @@ def thread_func( api_key: str, stop_polling_event: Event, seconds_interval: float = 5.0, -): +) -> None: while not stop_polling_event.is_set(): try: refresh_data(base_url, api_key, prompt_registry, content_allow_list) @@ -151,7 +151,7 @@ def refresh_data( api_key: str, prompt_registry: PromptRegistry, content_allow_list: ContentAllowList, -): +) -> None: response = fetch_url(f"{base_url}/v1/traceloop/prompts", api_key) prompt_registry.load(response) @@ -159,7 +159,7 @@ def refresh_data( content_allow_list.load(response) -def monitor_exit(exit_event: Event): +def monitor_exit(exit_event: Event) -> None: main_thread = threading.main_thread() main_thread.join() exit_event.set() diff --git a/packages/traceloop-sdk/traceloop/sdk/images/image_uploader.py b/packages/traceloop-sdk/traceloop/sdk/images/image_uploader.py index e9644dcc16..cdd47f194a 100644 --- a/packages/traceloop-sdk/traceloop/sdk/images/image_uploader.py +++ b/packages/traceloop-sdk/traceloop/sdk/images/image_uploader.py @@ -6,22 +6,26 @@ class ImageUploader: - def __init__(self, base_url, api_key): + def __init__(self, base_url: str, api_key: str) -> None: self.base_url = base_url self.api_key = api_key self.logger = logging.getLogger(__name__) - def upload_base64_image(self, trace_id, span_id, image_name, image_file): - asyncio.run(self.aupload_image_file(trace_id, span_id, image_name, image_file)) + def upload_base64_image( + self, trace_id: str, span_id: str, image_name: str, image_file: str + ) -> None: + asyncio.run(self.aupload_base64_image(trace_id, span_id, image_name, image_file)) - async def aupload_base64_image(self, trace_id, span_id, image_name, image_file): + async def aupload_base64_image( + self, trace_id: str, span_id: str, image_name: str, image_file: str + ) -> str: url = self._get_image_url(trace_id, span_id, image_name) await self._async_upload(url, image_file) return url - def _get_image_url(self, trace_id, span_id, image_name): + def _get_image_url(self, trace_id: str, span_id: str, image_name: str) -> str: response = requests.post( f"{self.base_url}/v2/traces/{trace_id}/spans/{span_id}/images", json={ @@ -33,9 +37,9 @@ def _get_image_url(self, trace_id, span_id, image_name): }, ) - return response.json()["url"] + return response.json()["url"] # type: ignore[no-any-return] - async def _async_upload(self, url, base64_image): + async def _async_upload(self, url: str, base64_image: str) -> None: headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", diff --git a/packages/traceloop-sdk/traceloop/sdk/logging/logging.py b/packages/traceloop-sdk/traceloop/sdk/logging/logging.py index 9a6f1dd193..310228a1cc 100644 --- a/packages/traceloop-sdk/traceloop/sdk/logging/logging.py +++ b/packages/traceloop-sdk/traceloop/sdk/logging/logging.py @@ -1,5 +1,5 @@ import logging -from typing import Dict +from typing import Dict, Optional, Any from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( OTLPLogExporter as GRPCExporter, @@ -15,13 +15,13 @@ class LoggerWrapper(object): - resource_attributes: dict = {} - endpoint: str = None + resource_attributes: Dict[Any, Any] = {} + endpoint: Optional[str] = None headers: Dict[str, str] = {} - __logging_exporter: LogExporter = None - __logging_provider: LoggerProvider = None + __logging_exporter: Optional[LogExporter] = None + __logging_provider: Optional[LoggerProvider] = None - def __new__(cls, exporter: LogExporter = None) -> "LoggerWrapper": + def __new__(cls, exporter: Optional[LogExporter] = None) -> "LoggerWrapper": if not hasattr(cls, "instance"): obj = cls.instance = super(LoggerWrapper, cls).__new__(cls) if not LoggerWrapper.endpoint: @@ -58,7 +58,7 @@ def init_logging_exporter(endpoint: str, headers: Dict[str, str]) -> LogExporter def init_logging_provider( - exporter: LogExporter, resource_attributes: dict = None + exporter: LogExporter, resource_attributes: Optional[Dict[Any, Any]] = None ) -> LoggerProvider: resource = ( Resource.create(resource_attributes) diff --git a/packages/traceloop-sdk/traceloop/sdk/metrics/metrics.py b/packages/traceloop-sdk/traceloop/sdk/metrics/metrics.py index 7617b3bc1f..02d74dda94 100644 --- a/packages/traceloop-sdk/traceloop/sdk/metrics/metrics.py +++ b/packages/traceloop-sdk/traceloop/sdk/metrics/metrics.py @@ -1,5 +1,5 @@ from collections.abc import Sequence -from typing import Dict +from typing import Dict, Optional, Any from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( OTLPMetricExporter as GRPCExporter, @@ -20,14 +20,14 @@ class MetricsWrapper(object): - resource_attributes: dict = {} - endpoint: str = None + resource_attributes: Dict[Any, Any] = {} + endpoint: Optional[str] = None # if it needs headers? headers: Dict[str, str] = {} - __metrics_exporter: MetricExporter = None - __metrics_provider: MeterProvider = None + __metrics_exporter: Optional[MetricExporter] = None + __metrics_provider: Optional[MeterProvider] = None - def __new__(cls, exporter: MetricExporter = None) -> "MetricsWrapper": + def __new__(cls, exporter: Optional[MetricExporter] = None) -> "MetricsWrapper": if not hasattr(cls, "instance"): obj = cls.instance = super(MetricsWrapper, cls).__new__(cls) if not MetricsWrapper.endpoint: @@ -66,7 +66,7 @@ def init_metrics_exporter(endpoint: str, headers: Dict[str, str]) -> MetricExpor def init_metrics_provider( - exporter: MetricExporter, resource_attributes: dict = None + exporter: MetricExporter, resource_attributes: Optional[Dict[Any, Any]] = None ) -> MeterProvider: resource = ( Resource.create(resource_attributes) diff --git a/packages/traceloop-sdk/traceloop/sdk/py.typed b/packages/traceloop-sdk/traceloop/sdk/py.typed new file mode 100644 index 0000000000..e69de29bb2