diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8c0b9ba..b60bfa59 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,13 +48,13 @@ repos: - id: no-commit-to-branch args: [--branch, dev, --branch, int, --branch, main] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.21 + rev: v0.15.22 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --exclude, scripts] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.2.0 + rev: v2.3.0 hooks: - id: mypy args: [--no-warn-unused-ignores] diff --git a/.pyproject_generation/pyproject_custom.toml b/.pyproject_generation/pyproject_custom.toml index c8782702..c4361eb6 100644 --- a/.pyproject_generation/pyproject_custom.toml +++ b/.pyproject_generation/pyproject_custom.toml @@ -1,6 +1,6 @@ [project] name = "hexkit" -version = "8.5.0" +version = "8.6.0" description = "A Toolkit for Building Microservices using the Hexagonal Architecture" requires-python = ">=3.10" classifiers = [ @@ -16,7 +16,7 @@ classifiers = [ "Intended Audience :: Developers", ] dependencies = [ - "opentelemetry-api >=1.39, <2", + "opentelemetry-api >=1.44, <2", "pydantic >=2.12, <3", "pydantic_settings >=2.12, <3", "PyYAML >=6, <7", @@ -29,35 +29,35 @@ mongodb = ["pymongo >=4.16, <5"] redis = ["redis >=7.1, <8"] vault = ["hvac >=2.4, <3"] opentelemetry-base = [ - "opentelemetry-sdk >=1.39.1, <2", - "opentelemetry-exporter-otlp >=1.39.1, <2", - "opentelemetry-instrumentation >=0.60b1", - "opentelemetry-instrumentation-httpx >=0.60b1", - "opentelemetry-distro >=0.60b1", + "opentelemetry-sdk >=1.44, <2", + "opentelemetry-exporter-otlp >=1.44, <2", + "opentelemetry-instrumentation >=0.65b0", + "opentelemetry-instrumentation-httpx >=0.65b0", + "opentelemetry-distro >=0.65b0", ] opentelemetry-akafka = [ "hexkit[opentelemetry-base]", "hexkit[akafka]", - "opentelemetry-instrumentation-aiokafka >=0.60b1", + "opentelemetry-instrumentation-aiokafka >=0.65b0", ] opentelemetry-mongodb = [ "hexkit[opentelemetry-base]", "hexkit[mongodb]", - "opentelemetry-instrumentation-pymongo >=0.60b1", + "opentelemetry-instrumentation-pymongo >=0.65b0", ] opentelemetry-fastapi = [ "hexkit[opentelemetry-base]", - "opentelemetry-instrumentation-fastapi >=0.60b1", + "opentelemetry-instrumentation-fastapi >=0.65b0", ] opentelemetry-s3 = [ "hexkit[opentelemetry-base]", "hexkit[s3]", - "opentelemetry-instrumentation-botocore >=0.60b1", + "opentelemetry-instrumentation-botocore >=0.65b0", ] opentelemetry-redis = [ "hexkit[opentelemetry-base]", "hexkit[redis]", - "opentelemetry-instrumentation-redis >=0.60b1", + "opentelemetry-instrumentation-redis >=0.65b0", ] opentelemetry = [ "hexkit[opentelemetry-akafka]", diff --git a/lock/requirements-dev.txt b/lock/requirements-dev.txt index 5ba2a21d..5ca093b0 100644 --- a/lock/requirements-dev.txt +++ b/lock/requirements-dev.txt @@ -39,13 +39,13 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.14.1 \ - --hash=sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72 \ - --hash=sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e +anyio==4.14.2 \ + --hash=sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494 \ + --hash=sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f # via httpx -asgiref==3.11.1 \ - --hash=sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce \ - --hash=sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133 +asgiref==3.12.1 \ + --hash=sha256:59dcb51c272ad209d59bed5708a64a333083e86017d7fcdd67498eeab7784340 \ + --hash=sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094 # via opentelemetry-instrumentation-asgi ast-serialize==0.6.0 \ --hash=sha256:0067b25fce104eaae5b88383de9ab803faeb671831e14ca698b771b356e2600f \ @@ -97,13 +97,13 @@ babel==2.18.0 \ --hash=sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d \ --hash=sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # via jsonschema2md -boto3==1.43.45 \ - --hash=sha256:65e0ae541a9948ac41b706d5c7165d96ebf155812562b6518b862be027ee7347 \ - --hash=sha256:bb076647526c491ce75cab896543afcda5b81c97d3f8e8da08a033fc1ddb7429 +boto3==1.43.52 \ + --hash=sha256:1af1950c2b2400267c93d971d588367fc73554e02b4f435a50a5e930a7c93526 \ + --hash=sha256:3da09a393c050906d407023bee5fb5b5fb333378513af1a1a51159db870b572f # via hexkit (pyproject.toml) -botocore==1.43.45 \ - --hash=sha256:a04871d814124e65daf429fb99640def23b8c4d3edc6438603b31f11116d7a67 \ - --hash=sha256:a2da80ff3caa2873769b9a32ae5f1fb18b3571ab63a981896639955611ca01e6 +botocore==1.43.52 \ + --hash=sha256:3c25e11796ae6e295f1cc3a7760e808c26c432cd580d6a608f32da24715c389b \ + --hash=sha256:43715e971b306f86d5918b3b728ec62aae3f4be49e1606058ef1f0b87dcbad9e # via # hexkit (pyproject.toml) # boto3 @@ -332,98 +332,98 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via tox -coverage==7.15.0 \ - --hash=sha256:003fff99412ea848c0aaebcc78ed2b6ce7d8a1227ed17e68470672770b78a02a \ - --hash=sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796 \ - --hash=sha256:03d1f922757662eb7af586e77834792274cff776bc7b1d1a0b66a49ea9d84735 \ - --hash=sha256:08fb028000ed0aaa0a4cbdfbb98be7cb42f370db973fbbb469733505ab20e13e \ - --hash=sha256:0bf781da64326b677be344df505171435b6f58716108606621d5d27d964fff8b \ - --hash=sha256:0bfc0be1f702042207a93a00523b1065ee1fe951e96edf311581c0bbc2e34888 \ - --hash=sha256:0e4950c9d6d3e39c64c991814ff315e2d0b9cb8152363594212c9e55208c0a8f \ - --hash=sha256:106781b8482749162d0b47056937ba0933508e5d9447f65a5e7d5c422f0d6bb4 \ - --hash=sha256:110cbdf8d2e216577312cf06ccf85539c0e5a5420ef747e4a4719b5e483c88cd \ - --hash=sha256:13fb759be317fdc62e0f56bffdf61cfcb45c7761ad6b71e3e583e71a67ae753c \ - --hash=sha256:1ac2c4c27c7df851dc9a017c2d7de00b69147e84ba3d96f37a530b0b6fb51035 \ - --hash=sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5 \ - --hash=sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4 \ - --hash=sha256:276646e9481703d09f854f3b2f018f24e19fd7049ae670a92570043eb97203b1 \ - --hash=sha256:27f31ecb458da3f859aab3f15ada871eb7a7768807d88df4a9f186bb17737970 \ - --hash=sha256:2bcf9afaf064172c6ec3c58a325a9957ad1178c05dd934e25f253321776e0676 \ - --hash=sha256:2c57a275078ee3fa185f83e400f765bc764a549de66d99b47881645cbd4ea629 \ - --hash=sha256:2c5d4619214f1d9993e7b00a8600d14614b7e9d84e89507460b126aa5e6559e5 \ - --hash=sha256:2c6f0fa473003905c6d5bac328ee4eba9fbea654f15bc24b8a3274b23363fa99 \ - --hash=sha256:309990eb5fb8014b9f67cb211f7fd41876ec8a88a88d3ae76de0ed1d611e3640 \ - --hash=sha256:31e5c3e70c85307ea35a12964e2e40f56ca2ee4b1c8c721ccf4609d17071080b \ - --hash=sha256:3200b6204935f928c64b2ca1f923ab8c1acb7c9de45ec61569711b34d25cccaf \ - --hash=sha256:346771144d34f7fa84ec28386f78e0f31653f33cf35e19d253d5b35f9e8201da \ - --hash=sha256:359e141ccd33893ce3f1ad5525f8b96083003677c82182e5907d62d4ea5799fc \ - --hash=sha256:363ab38cc78b615f11c9cac3cf1d7eef950c18b9fdedfb9066f59461dcf84d68 \ - --hash=sha256:3812c61afc6685c7999b39320779ab8f43b7a3081fdb0def39976e56fbdb9a21 \ - --hash=sha256:3bb3040e9f4bbe26fcb0cd7cc85ac63e630d3f3a9c74f027abf4caa27e706663 \ - --hash=sha256:41cb79af843222e11da87127ad0ecbfa878abadd0f770a4a99391a27d3887324 \ - --hash=sha256:4de4b4d3f5545aa6c60dc4efd9c63b5b5dcc3bf00fe83146b2bdfffb8f6613bd \ - --hash=sha256:50913d4bf5ddafa6ca3693da5e4dd833dd1b772e0283c99ca7f7d287db67331a \ - --hash=sha256:51aa20f6ae2788fd197747766edf4cd8234fd9423309b934257fa6b21a592723 \ - --hash=sha256:52f9a4d2c4c56c8848bc2f524916698354b0211488b38c49ad9ae54f6cafbff6 \ - --hash=sha256:54fd9c53a5fafff509195f1b6a3f9be615d8e8362a3629ff1de23d270c03c86b \ - --hash=sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19 \ - --hash=sha256:589b54513e901739f4b4582c705ce96b80c96f57641b1464607e2367a270e540 \ - --hash=sha256:5be4caf3b28836f078abe700f8944dac4a65d78f16d6c600c89cb624e5535782 \ - --hash=sha256:5c504097b2a89b1e85bc6070d920df77daec701337e3aeef2c17775a5dd0ca90 \ - --hash=sha256:5cbd804bf2784ce7b45114516050f346ecd50f960c4bb630a7ee9e1d78fa2118 \ - --hash=sha256:5f764a3fa339bde6b3aa97657f5a6a3a9451e4a5b4ea98a2892c773a43525f77 \ - --hash=sha256:65a6b6164ee5c39e2f3803f314292d6c61a607ba7fee253d1e03c42dc3903502 \ - --hash=sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da \ - --hash=sha256:6cb3602054ccbe9f0d8c2dc04bbeba90d5719236e2cd06e042ddd6d3fc7b6e37 \ - --hash=sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382 \ - --hash=sha256:75128817f95a5c45bb01d65fd2d8b9cb54bbe03d81608fb70e3e14b437ad56c2 \ - --hash=sha256:769e8ece11a596315ebf5aa7ec383aeeed016c091d2bf6363ffb996d41529092 \ - --hash=sha256:781a704516e2d8346fbbd5be6c6f3412dd824785146528b3a01816f26c081007 \ - --hash=sha256:7d2008989ef8fe54188d3f3bfa2e3099b025af11e90a6a1b9e7dc433d04263d8 \ - --hash=sha256:821e92b3631d762a339695824cadbbc73020354eba2a23a551a99ad34938fbe6 \ - --hash=sha256:840481b12e083dbcbafab14794a8781a958edf327c8d3d70b4eee42f9b8253aa \ - --hash=sha256:8773e15c23305b58882a4611fb9b2755977eae0dc2e515366a1b6c98866cc4c2 \ - --hash=sha256:87b47553097ba185ed964866078e7e63adea9f5f51b5f39691c34f30afd21080 \ - --hash=sha256:884499f42e382675be80770391983b90e0c0c774d87dbeeebf5f991cf6612b20 \ - --hash=sha256:94c9686bfe8a9a6810297aecbd99beaa3445f9e8dc2f80b1382cca0d86b64461 \ - --hash=sha256:9887bb428fe2d4cd4bee89bac1a6c9932f484afd5b36fbd4ff6ea5f825bb1f5e \ - --hash=sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f \ - --hash=sha256:9bd671c25f9d85f09d7ec481d0e43d5139f486c06a37139847a7ce569788af72 \ - --hash=sha256:a263060f1de0b4b74b4e089c2a70b8003b3781c733329a9c8fd54995328f9950 \ - --hash=sha256:a6d6acc9a7666245e6133dd15144ca038a85a9cd5026bb06d6bbae9e77440dc9 \ - --hash=sha256:ab282853ed5fbd64bbb162f19cb8fcb7087187508a6374b4f9c34ec1577c4e8f \ - --hash=sha256:aeefb2dd178fe7eee79f0ad25d75855cb35ee9ed472db2c5ea06f5b4fd00cec5 \ - --hash=sha256:b3b3e22030f3f6f5e01a5ce69936552a5c0f6992b7698777377b99041961031f \ - --hash=sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c \ - --hash=sha256:b713aa7fcf325a01d4184d848acb46fd84f78fdb0978470c636b23a06a753d91 \ - --hash=sha256:b75ee5e8cb7575636ac598719b4307ac529ec8fcd79608a35c3cd4d4dada812d \ - --hash=sha256:b761a1d504fd4bd1f20f418753964dca9f5862a511fc854dac58296b3b223671 \ - --hash=sha256:baf06bc987115d6fb938d403f7eab684a057766c490367999a2b71a6883110c6 \ - --hash=sha256:bb25d825d885ca8036795dacfc3924d33091fc76d71ebc99420c6b79e77d96fa \ - --hash=sha256:bbcbb317c2e5ded5b21104af81c29f391be2af98d065693ffbe8d23949b948e5 \ - --hash=sha256:bd4a1b44bcb65ee29e947ac92bbee04956df3a6bfc6143641bb6cae7ede00fc9 \ - --hash=sha256:be616bf61346883b2cfdc5178669647e03531d81ab761a7e378558b7e8bcb628 \ - --hash=sha256:c48decf16e0dfd5b049c7d5e82200c23c08126719142998d4f172444e3d0529e \ - --hash=sha256:cc78d9843bd576fbe2118248258d485e968dc535f95ed504a7b0867ba9b51389 \ - --hash=sha256:cc7bafc3fe1059463a8fdd97ca79972d6e2bf819d775c7d54991b5b1971201d6 \ - --hash=sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766 \ - --hash=sha256:d34a010905fb6401324ba016b5da03d574967f7b21ce48ea41e66f0f1f95f641 \ - --hash=sha256:d5cf007add5ab4bb8fa9f4c77e3732127c9e6cad501d7db43355fbfafca0be84 \ - --hash=sha256:daf96f37f5fc3a7b6c6da862eb4aee61c426bd63da236ed4a73ef0e503b4bca5 \ - --hash=sha256:dd58ad1404704303ca8d4f4b8a1095e7cbc7040ef17a66df1e6619aa10176430 \ - --hash=sha256:e38e6fba2d56652fdfaf0231f8f78aeb805234a912de25dc291ee5cce5b8faa4 \ - --hash=sha256:e43b045e11c16e897895758ae90e4a90cf99e93d58549e2f90c0e2272e155695 \ - --hash=sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c \ - --hash=sha256:f00d5ae1dd2fe13fb8186e3e7d37bcbd8b25c0d764ff7d1b32cef9be058510a8 \ - --hash=sha256:f0405f2ff97b1c4c0e782cb32e02f32369bcf2e6b618b591d67e1ea754575dfe \ - --hash=sha256:f50e40081494c1dc4239ebb202014cbcc3306ea96fb6302a34c8cc0967fc5ae8 \ - --hash=sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4 \ - --hash=sha256:f64627d55def5a43282d70e08396672692f77e4da610a5bb8bb4060b432b6859 \ - --hash=sha256:f6e80ed91f98316e86b9c137206b04b2bcfbffccbdff49bd2eb09dddb1cf14e0 \ - --hash=sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01 \ - --hash=sha256:fb7dc0c3b7d8a1077abea0b8546ebc5e26d6ef6ecefc2f0f5ad2b8a53bdad837 \ - --hash=sha256:fe9c87ff42e5472d80d21704972e1f96e104a0a599d77c5e35db5a3c562e2571 \ - --hash=sha256:ffb31267816b93b075302248cc1737506081b4f163df4401e9df1a6424aafabe +coverage==7.15.2 \ + --hash=sha256:075560438765b7a2ef43bf7aa7758661b53d889df47f062a31bda6c1ade553a2 \ + --hash=sha256:0901cfe6c13bcd2302da4f83e884555d2a22bda6e4c476f09ef204ba20ca536e \ + --hash=sha256:094dd37f3ef7b2da8b068b583d1f4c40f91c65197e16c52a71962d5d537fc5db \ + --hash=sha256:09f5c6ec5901f667bd97dd140b5b9a2586b10efec66f46fb1e6d8135f8b95bdf \ + --hash=sha256:0e55510bc98ae943cece9e667a6c0fe94c6a92913720dea34243657a17993d0c \ + --hash=sha256:1121caa19159a38b5463eaae4b1e1fde81e525b15ecc5e000cd5b1a108f743a8 \ + --hash=sha256:1268ac8fb9ddcd783d3948dbabaf80a5d53bfdaa0575e873e2139a692f797443 \ + --hash=sha256:1473b3ba8e7ee0f076117b1a72c23f579a2b9e2bb742f48a8d86ea27ca93f91a \ + --hash=sha256:17c432b5f73ad52ef46fb06019f6fa7c66ce381961cf0f7dfd1d3a4bd3a98145 \ + --hash=sha256:1adac78e5abc7c5438f7a209c9ca69d06542f0bf481d728b6989ea80b813fdf9 \ + --hash=sha256:1cd7a5beb7af3e864a13b1f0fb26efd3695da43ef0daf71e586adfffaf34d5b2 \ + --hash=sha256:1d16e3a7104ea84f03e614611b3edbf6fb6892554b3ab0fe7fbb3f2b2ef04376 \ + --hash=sha256:25fd15dd40a0a2c51a500d664ca29053c09c3259d998407bf982b6e114696138 \ + --hash=sha256:2617f8799d268fabdeef42a7e89ac3a23e1deee9025427db2df970f99a89a578 \ + --hash=sha256:26c3b04a6377fd7c09800921fa934e3a17c0020439cd59df73e73ae1d4b6a78c \ + --hash=sha256:29c052f7c83ccfcc5c577eaae025d2e4a9bb80daf03c0ac31c996e83b000ce88 \ + --hash=sha256:2f1ec6f304b156669cfde653b4e9a953f5de87e247ea02ac599bce0ab2744036 \ + --hash=sha256:2fbeeeecea279727f8ac16c8e1133ddfeee793e985c86ae343d6a5ce744eef8c \ + --hash=sha256:2ff08701be2d1556fc78b326c80a3e8042da09352ecb3819105f8e386c8a3071 \ + --hash=sha256:38c9518b7103826c403a461544e3c2e77151e8676d06eaed85911a97e962584a \ + --hash=sha256:3df60dc267f0a2ca23cb7a9ab1109c62b9335ffbf519fcfe167157c28c09b81d \ + --hash=sha256:3ed010aa1b69cda8e827aabfca9866216c980e2dca82ab9a78c5f83689964c8b \ + --hash=sha256:40f633c5c5fc783732f6312280122e859538fa24461235597c13d803ea9a108a \ + --hash=sha256:42ec3d989421b174a2ab607c1539f24127ad362757b7f1c0c0d7a2993f7eb37b \ + --hash=sha256:434e68d531858205895eb0d74b73d20b84260de426387d53c422a5acda2cf050 \ + --hash=sha256:44826758cfe73fcd0e6af5deb4ba6d5417cc1d13df3acb35c93484a11160f846 \ + --hash=sha256:4510fb9cdf6bb02dfa6af0be4a534b8102d086e22e4a33f8836df663da3d660d \ + --hash=sha256:48ccc6395958eda89093ecdc35644c86f23a8b23a7f4d44958812b721aad67c1 \ + --hash=sha256:4d3361879d736f469f45723c11ea1a5bbdaf1f6928f0e632c940378b5aa9b660 \ + --hash=sha256:582edc45c2040543fef83341be23c43024a3ab3ae0c2d8bc498a06282905ad40 \ + --hash=sha256:63022c4c8dec1d0342f05c3ede99842fe3d007689acc45e86f123a1746e4a026 \ + --hash=sha256:67d7602480a47bdf5b675635403625553ebaa70d5a62a657c035149fd401cea0 \ + --hash=sha256:68af907f595ab01a78f794932ff3bdf929c316d3000810d38dbc247129e26f8b \ + --hash=sha256:6aa28cfb6488e5453b5b762d65f73aa586380f6693a04d58078ce228a29b06c0 \ + --hash=sha256:6c0be82b4d4aa5b2704e08518e2252f3e3d110164bcca826816801052e48a7aa \ + --hash=sha256:6f6966fc30e6f06ca8f98fb0ce51eda6b111b3ee8d066a8b1ec9e77fa06ab55d \ + --hash=sha256:6fc448c377d6eeb00a47c673494bd9bae29280ca53987e1869e67ebedfe20658 \ + --hash=sha256:728a33676d4c3f0db977990a4bd421dcaa3be3e53b5b6273036fff6666008e89 \ + --hash=sha256:7466cc7ab6dc0db871d264bf99e8779f0917ee63d40730af0552f71535a6e072 \ + --hash=sha256:77f091ea3a9cc611cd29f433565476bc1936c084ac8eee00ea0e7e70c27e4199 \ + --hash=sha256:77f0ef5011df53a4bd1b35211ab122287f8d9b8d7aa1c4553e5c2deb24b1d446 \ + --hash=sha256:7c63387e21ab21f512c69c9756a8c7dadd322c7275edb064064433c9a09c3743 \ + --hash=sha256:7d29ca7bd67af6e12e74632d65f026eabc1364da5c254494cd914446a28a3ef7 \ + --hash=sha256:7dc2950a2992cd676d35c20ae63522836deeb034f08874699d14068710af3dc1 \ + --hash=sha256:7e8f27131dc7cd53de2c137dd207b3720919320b3c20d499dc30aa9ee6173287 \ + --hash=sha256:81f382c5a94b434ec1f6da607edb904c76d7212e618cd4d1bc9f97bed4120ef5 \ + --hash=sha256:835ec4e20b45f0a7f63ed78f94065aca00de033403df8377bfe8b9c6abc0a7be \ + --hash=sha256:8bb9f4b4279187560796a4cdaca3b0a93dd97e48ee667df005f4ed9a97403688 \ + --hash=sha256:8c726b232659cbd2ae57ade46509eb068c9bd7a06df9fcbff6fe484870006934 \ + --hash=sha256:913b6c56e110da40e035bbd168353bf7aaa2544a5eaccea5d98a4629aac156c7 \ + --hash=sha256:97a5c5457a9fb1d6c4e06cfb5dc835871fbfb6a6a51addc9e925bdeff5ef7440 \ + --hash=sha256:9854ca62c152874b2060772503535be2e8f53f70b8aaa7686b094888d872f984 \ + --hash=sha256:9911f31aad8906abe337c271343485cf20df5e70df5d2f57f9f136e7b55f26bc \ + --hash=sha256:9b5bd92ff1ec22e535eab0de75fa6db021992791f461a2aceb7822c625a1187d \ + --hash=sha256:9deddf09eecb717b7f980414b43d90a5b22ff3967d2949ab29cb0aa83d9e9098 \ + --hash=sha256:9e36686f7a442185db2400b3df171aac520869faf9deb59df687d28659eda2a6 \ + --hash=sha256:9f4432898c4bf2fba0435bbe35dd4437d7264565e5a88a21f5b49d8662a6b629 \ + --hash=sha256:a0f47002c6eeb7c280228467a4cb0cc15ca2103a8421b986b2d3ec04a0f9bd8b \ + --hash=sha256:a164b50081fc7357331c4024ef4d17b78ba325f8380d05f5a69599a7e05257ee \ + --hash=sha256:a29ec5305a7335aacee2d799e3422e91e1c8a12474986e2b3b07e315c91be82f \ + --hash=sha256:a300c6934e0989c327b9e8a1e110329da4641149f872bbe9f70168be66da76c1 \ + --hash=sha256:a4c46b247b5d4b78f613bd89fea926d32b25c6cc61a50bd1e99ba310348f3dad \ + --hash=sha256:a638db90c61cd219aeee65e83a24fdaa57269a741ae0cf773309208ac862cee3 \ + --hash=sha256:a63b9e190711134d581c4d703df5df09851b1acf99792c7aacbbe9f41f0283c9 \ + --hash=sha256:aaccad4129d735a8a4d526f26929894c9a4e8ef7034566f210b176749d6906e3 \ + --hash=sha256:ae901f7e55ba405c84ee1cab3d3e962e4e871e4a2bcb9c90911adbd69b42ac5a \ + --hash=sha256:afa29e2eff3d5729267e2cb2fd4ce9d61c952932fb2694e34ccb5d9540c6a296 \ + --hash=sha256:affd532502d34c0472d0cdb181325c89f1d2c44992fef0c17e88e7b1576259a1 \ + --hash=sha256:b171bdd71cb7ff792bf32e376173b0ace7e7963e7e57c58dfc42063a6a7174cd \ + --hash=sha256:b868acc62aa5de3be7a9d05c2333bf8359ca987e43f9cb30ff8fbda6a024ab73 \ + --hash=sha256:b9a6367e4aff723e8ee8190836836124284e8fcd4265e307c844010cfa074f3f \ + --hash=sha256:bbc808daf4f5cd567af8075ecc72d21c6dfef9a254709a621a84c217c935ebc0 \ + --hash=sha256:bbf44513ceb1589e31948e20eafbde9deaface90e1a1afa5f5f77b4423d17ce6 \ + --hash=sha256:bcc0aae933921d03096f53b0b03eeb702129fd406dee59f08d2efacc68681fa5 \ + --hash=sha256:bfd341ccf78128e72c094bc70cc25b3ef309c33c7c2c66ba3ed4309549e02de1 \ + --hash=sha256:c6a98d698f9e2c8008d0370ec7fc452ebfcc530002ae2d0061170d768b992589 \ + --hash=sha256:cb0fddaa6884be6aae36ced9544b5e90f7d5f03845a2853bf47a14953a4e8688 \ + --hash=sha256:cee0f89f4767a6057c8fbf168f8135f18be651300496086bd873e3189fed0487 \ + --hash=sha256:d17d7512151fedfcc64c1821a8977fc9be0dbf495754669afcab7b57abc98ae9 \ + --hash=sha256:d46e62cb35d91e6e2589fda6d28074426b0e276422b5d2ebef2c6b11dc60dbfd \ + --hash=sha256:d50dd325e18ec25bfcc10cd7f99b04df1ab9ec76b0918c260e60817ad0643dee \ + --hash=sha256:db9c8438057e5b0f6a22a0af99c0c1d26b57fbbdbd1be5861ddb8f897fcc3a2d \ + --hash=sha256:dee88b1ed88587abd8c0269a1fc1f4cc77f7750d1dfde2869e2a123af420e67d \ + --hash=sha256:dfd3db045e95960ae3683059571e597fda7cc610106a8916f77c5839048c1deb \ + --hash=sha256:e26ff680768b8095e8874aabe0e9d3a47a2a9f176a8340d05f8604c56457c23a \ + --hash=sha256:e370c12133095ff18432de8c044962be85a5a96d90c6fcbce8e17e76236d2328 \ + --hash=sha256:e38def96ad59853824c97953fdcd2c320a84ba3ce99b417db78af8bb6c3db635 \ + --hash=sha256:e8f91bce78e32343af184c3b7fa28fcf5a9e2641f4b6623d392038f804939188 \ + --hash=sha256:eb6bcae8d1a9d305351ecb108232441d11c5cfe9de840a04388ba5d2db8d735c \ + --hash=sha256:f653e5d7248c1191ec988a85c72edeab46c3ff44f90639a4ed4874ec0be90243 \ + --hash=sha256:fe41909c9515c3bfdb5f02c4d1f857dba322d9a9a1178069b91eea77889df63a # via pytest-cov cramjam==2.11.0 \ --hash=sha256:028400d699442d40dbda02f74158c73d05cb76587a12490d0bfedd958fd49188 \ @@ -620,9 +620,9 @@ docker==7.2.0 \ --hash=sha256:a3f45fdeb9165e2d25d9a1d02ddf3bc70fb572cf5ebbf9b58558c22caf29b71f \ --hash=sha256:cebb93773d334f778e023a7ee352a8d6e13ab1bd3b863a4d4a59dec897df43ac # via testcontainers -filelock==3.29.7 \ - --hash=sha256:5b481979797ae69e72f0b389d89a80bdd585c260c5b3f1fb9c0a5ba9bb3f195d \ - --hash=sha256:987db6f789a3a2a59f55081801b2b3697cb97e2a736b5f1a9e99b559285fbc51 +filelock==3.31.2 \ + --hash=sha256:18a4179901809ad1905c6631d907f1c3a41806c0d3506f7f9862565576a81a16 \ + --hash=sha256:e6d35965c709527915a184837a8421826d18bc3f9d7e9a5a0c8114a782475d66 # via # python-discovery # tox @@ -847,52 +847,52 @@ mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -mypy==2.2.0 \ - --hash=sha256:01f24bd465a09077c8d64be8f19a6646db467a55490fd315fe7871afe6bb9645 \ - --hash=sha256:0823d7f273f3b4a49df7573eac271ddbf77a0e5f53e24d294a4f0f77ad22e1d7 \ - --hash=sha256:1f6c3d76853071409ac58fc0aadfb276a22af5f190fdaa02152a858088a39ebd \ - --hash=sha256:2529017942b951cc43db2e2712b71cc3aa7e9d90567630c03ed63d430aeec61a \ - --hash=sha256:2cdd99d48590dce6f6b7f1961eda75386364398fcdaad86923bc0f0231bf9baf \ - --hash=sha256:30a430bf26fe8cf372f3933fbd83e633d6561868803645a20e4e6d4523f52a3b \ - --hash=sha256:3df226d2a0ae2c3b03845af217800a68e2965d4b14914c99b78d3a2c8ae23299 \ - --hash=sha256:484a2be712b245ac6e89847141f1f50c612b0a924aa25917e63e6cfcf4da07cd \ - --hash=sha256:511320b17467402e2906130e185abffffa3d7648aff1444fc2abb61f4c8a087d \ - --hash=sha256:5a906bfc9c4c5de3ece6dc4726f8076d56ce9be1720baf0c6f84e926c10262a4 \ - --hash=sha256:6257bd4b4c0ae2148548b869a1ff3758e38645b92c8fe65eca401866c3c551c1 \ - --hash=sha256:68f5b7f7f755200f68c7181e3dfb28be9858162257690e539759c9f57721e388 \ - --hash=sha256:6965829a6d847a0925f51149472bbeb7a39332fb4801972fdfd9cedd9f8d43a4 \ - --hash=sha256:6968f27347ef539c443ddfd6897e79db525ddb8c856aa8fbf14c34f310ca5193 \ - --hash=sha256:6efab25fa3568569fda06928743382900860c48be9200c1758ef5ce94b532714 \ - --hash=sha256:6fc0e98b95e31755ca06d89f75fafa7820fbb3ea2caace6d83cba17625cd0acb \ - --hash=sha256:7589f370b33dcdd95708f5340f13a67c2c49140957f934b42ef63064d343cca0 \ - --hash=sha256:78d201accfafce3801d978f2b8dbbd473a9ce364cc0a0dfd9192fe47d977e129 \ - --hash=sha256:80923e6d6e7878291f537ee11052f974954c20cb569798429a5dc265eb780b47 \ - --hash=sha256:91df92625cb3452758f27f4965b000fb05ad89b00c282cc3430a7bd6b0e5389e \ - --hash=sha256:97d21f3a1582ef30d0b77f9ca3ad88b4263f3c5aea9e7380cb5d7175160aec7e \ - --hash=sha256:996abf2f0bebf572556c60720e8dc0cf5292b64060fa68d7f2bc9caa48e01b6f \ - --hash=sha256:9e0899b13da1e4ba44b880550f247402ce90ffecc71c54b220bcbe7ecb34f394 \ - --hash=sha256:b0179a3a0b833f724a65f22613607cf7ea941ab17ec34fa283f8d6dfe21d9fa9 \ - --hash=sha256:b48092132c7b0ef4322773fecae62fc5b0bc339be348badeec8af502122a4a51 \ - --hash=sha256:bc73a5b4d40e8a3e6b12ef82eb0c90430964e34016a36c2aff4e3bfe37ba41f0 \ - --hash=sha256:bdaa177e80cc3292824d4ef3670b5b58771ee8d57c290e0c9c89e7968212332c \ - --hash=sha256:c2c967a7685fa93fcf1a778b3ebe76e756b28ba14655f539d7b61ff3da69352a \ - --hash=sha256:c39bdb7ceab252d15011e26d3a254b4aaa3bbf121b551febfa301df9b0c69abe \ - --hash=sha256:d3abaeec02cdc72e30a147d99eb81852b6b745a2c8d19607e25241d79b1abbce \ - --hash=sha256:d42893d15894fd34f395090e2d78315ba7c637d5ee221683e02893f578c2f548 \ - --hash=sha256:d4452c955caf14e28bb046cbd0c3671272e6381630a8b81b0da9713558148890 \ - --hash=sha256:d58655a60e823b1a4c9ebcda072897fb0193c2f3e6f8e7c433e152aa4cb00233 \ - --hash=sha256:d59a4b80351ec92e5f7415fcdd008bd77fcbefc7adf9cbc7ffe4eb9f71617734 \ - --hash=sha256:d78a0fc90704894bc9948d78affad14b882b08183a7c30412d185748aaa9418b \ - --hash=sha256:daeaf5287091d68f674c91416cabab0f80f36e347ed17fded38d7ebde682e9d1 \ - --hash=sha256:db34595464869f474708e769413d1d739fc33a69850f253757b9a4cc20bc1fec \ - --hash=sha256:dc361340732ce7108fa0308812caf02bb6868f16112f1efd35bcad88badf3327 \ - --hash=sha256:dfa22b3ae862ac1ce76f5976ddd402651b5f090bcfd49c6d0484b8983a29eaf8 \ - --hash=sha256:ea6fe1a30f3e7dc574d641497ffead2428046b0f8bc5804d13b4e4392fdc317b \ - --hash=sha256:ec287c2381898c652bf8ff79448627fe1a9ee76d22005181fac7315a485c7108 \ - --hash=sha256:ecc138da861e932d1344214da4bae866b21900a9c2778824b51fe2fb47f5180e \ - --hash=sha256:f8d97940a0259e09c219903579720b2df12170c0c3a3b3799837c1fb63deb44e \ - --hash=sha256:fb0a020dc68480d40e484675558ed637140df1ccbf896a81ba68bca85f2b50a0 \ - --hash=sha256:fc53553996aca2094216ad9306a6f06c5265d206c1bcb54dd367560bd3557825 +mypy==2.3.0 \ + --hash=sha256:04e617030eca5221909c8b7d8d7fd1c637948199aa2100b2ad9813feb07e1491 \ + --hash=sha256:094af99f92638aa92852326188b85a89e50f4a472f44827c03362228482f0762 \ + --hash=sha256:09abd66d8685e73f8f7d17b847c3e104d9a7b164a8706ea87d6c96a3d45816d5 \ + --hash=sha256:0b025a93cffb9781d231f232be07a17912f35f10a313c24f301c81e842870654 \ + --hash=sha256:13b1b16e2fa39f3b2e33fb1c468abc7a69369fa2e886b4b87b5afc81472325cd \ + --hash=sha256:1c6c6bf687b17f90dbfcad95b960d32eaa0154c00da45f03ab50bf8952e047fe \ + --hash=sha256:1fa8d916ac3b705af733c4c1e6c9ebe38fd0d52beb15b105c3e8355b55e6ecdc \ + --hash=sha256:28e1e2af8cd8fff551fd30f2fe4b03fb76764ac8b1ba6c6a1bd00ad32b412db3 \ + --hash=sha256:2d53fc67b9d28a43c6199077f49fea0f05839e36cf6158500331c9549225e5a5 \ + --hash=sha256:3419d00717afbc5265b50dd14b1278f29ea4884dd398ab67873489ac093fd329 \ + --hash=sha256:37fa4de896a84e2dc9200d91e614c22563b43d1a266789d4bbac7b22ebe6192b \ + --hash=sha256:3961a4a34b05f7c74b0f05aa51fbfe99a2d1e126038df40318d15c8f558b7ef3 \ + --hash=sha256:3dd0bed92c4bdec57c42505b96416fb9e6a5aa7be84d2809bcd5f2ecec2860d7 \ + --hash=sha256:3e77244df3843048c3f927182916730e40c124cbaa43905c1fb86cb382aa0805 \ + --hash=sha256:4359424140d985192c778c1ce2c114a10c1ca58a381ed79cfa70d37df94b299f \ + --hash=sha256:465965d41cd9a2726694e983e8ce7113259327bec798115d1e1dfa2a52fb666e \ + --hash=sha256:56c184d2c20ca6b6378d58d1960270a767f41f5e44acbbd27f05effef4f4e1d7 \ + --hash=sha256:5e91adad1ca81742ac7ef9893959911df867752206b37135185e88dfb3c89494 \ + --hash=sha256:691fdc37132b1ae628d834f672e74de83462d9fb4aff621835767fb43a8dd373 \ + --hash=sha256:6b1cdb579446b60432432b2b2403a6201b4b475a004d7f488511c9ba177c9e88 \ + --hash=sha256:6f99ec626e3c3a2f7c0b22c5b90ddb5dabb1c18729c971e9bdaca1f1766d2cee \ + --hash=sha256:7247eb2824f996722a949530183394921ca71deb9680052a338cf53cff7925c2 \ + --hash=sha256:75b0984bb3cbd76bb5c9291a8671f7ae66ca3b51c7584c358fc2e923259f0757 \ + --hash=sha256:75cbb4b9ef04a0c84a957f07abc4504fbf64b8dcc145675101f2d3a78a4b1d6a \ + --hash=sha256:7da939dd335cfd2ad788bdfd081c9f4e47634ab995e5a45eb15fd1e5bc052f8b \ + --hash=sha256:85c5385b93012ffa3b31479ab579aef5415f4f3a32c6cf1ae07a984d2a0ff461 \ + --hash=sha256:91ad22a52ae2c7e621c2f67c94d5a17f66b3209a4cff5cf8a573579835c69e97 \ + --hash=sha256:944c665d984157cb96a679dfb7a4a81dd1d36b24b9c284b699514e6e626b82d4 \ + --hash=sha256:9559ab18a9c9957dfa3004ab57cd4bac5f26a724329a9584e583367f0c2e1117 \ + --hash=sha256:982e3d53dd23d0a4cef67dd66791fdbede0cf38f9eb617bf47663554c51e1e36 \ + --hash=sha256:99ac767cc5d3b64c8d0ae226ead10c96694f94e4e7da1668642225dcd4e75aac \ + --hash=sha256:adebc76aab4f3495a88b41d48aa4aff0c03f2822501da76625afcca5975f19e5 \ + --hash=sha256:aec15d465d477558fd842757b487849007311cf3897849cdda0e3162ac0ac556 \ + --hash=sha256:b1942b9314d4c784b8ea1dbab4972603290e5dd5630f06675f13aec97526bc4c \ + --hash=sha256:b352b7e49f5e6576009e8df730e1ff4f915cb565b851b396d2ffe2f5a6f5da88 \ + --hash=sha256:b5cd2f027a972a4a5f2278a11fac9747f5f81a53a30b714d74950b6807e55568 \ + --hash=sha256:be51653d7669d7d7955d613b8d0bb57d5b652eaf71a873ddf65ac87254dd2595 \ + --hash=sha256:cfca8ee88544090f86b6dcce05ec55d66eb48a762412ac2507810ba4bd793b6f \ + --hash=sha256:d78fcf900b59cb7e82cb7e3a235e31b462d9333d92285bd1e4952d355b8ffba1 \ + --hash=sha256:de121747278144fc9ae7caa2e978cf5df12aebc82933182f5b3b86081a30baef \ + --hash=sha256:de6d2c484742a4d7b0ed6d07b143375624d3b899c5749c7b3c947f56261f48a6 \ + --hash=sha256:ea317b060ce83e26050f8f9e4d7d6bf44ed7597c8ff9990bccffbb9d1d8522db \ + --hash=sha256:f1b3a98dfd21058bc759bb3337d5d1f61d0fdf9f3cf9c00f4291790fb5427bff \ + --hash=sha256:f4ed18f111bfe2d599bca7468e7f9251042c1c2118f762c8de2766a56d773c60 \ + --hash=sha256:fbc00cee7bdbb9291979ddc9d08034a29dfcda4932628c9bbc28c1edd589df0c # via -r lock/requirements-dev-template.in mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -904,9 +904,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -opentelemetry-api==1.43.0 \ - --hash=sha256:107d0d03857ea8fc7c5fcbbbd83f800c281f0d560553d61c1d675fccfd1761c1 \ - --hash=sha256:20acf45e9b21851926835292e4045d290acade1edd2ff3de86d2f069687ba1fd +opentelemetry-api==1.44.0 \ + --hash=sha256:67647e5e9566edcf421166fdf022b3537f818635daa852b289e34604dc6fb33a \ + --hash=sha256:94b98c893a91b88657eaac1e3ba89618cdb85be6918196705354f34728b2cdef # via # hexkit (pyproject.toml) # opentelemetry-distro @@ -923,31 +923,31 @@ opentelemetry-api==1.43.0 \ # opentelemetry-propagator-aws-xray # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-distro==0.64b0 \ - --hash=sha256:8a19716899854245b4028650ec1cca12d89f9be41571bbffe9e539cd55d2fd96 \ - --hash=sha256:ce97b6cedfcf03dc54035c422485412eda63250e094f4bd63ef57d017d823f3c +opentelemetry-distro==0.65b0 \ + --hash=sha256:0e15bb1a54c638e6c361bc66bc43e9de9ead442e1ae06f8099a2c1d27b6ef845 \ + --hash=sha256:e2fef26fdf72978ab172530c13338aff367edae41ae8d90b7f6133efedde10ab # via hexkit (pyproject.toml) -opentelemetry-exporter-otlp==1.43.0 \ - --hash=sha256:65aded6c50ee7dd2b9948c9d0e59ddb4ed4eea6e8532fba95cbe6a4a64a566ba \ - --hash=sha256:70f3fe740a64596d4157588a2ee7e4fd37d2acc0c0f522a2882b8c29316cd0f0 +opentelemetry-exporter-otlp==1.44.0 \ + --hash=sha256:4a498fa8d8fd8be9e8e2d175fe5524a3fe581ccffadd8509db86526a5fb97051 \ + --hash=sha256:af1cde7c33ea8ed624bf04ac49a885730fe44c1f1ad698656e592c38f70ce106 # via hexkit (pyproject.toml) -opentelemetry-exporter-otlp-proto-common==1.43.0 \ - --hash=sha256:123c3f9cc87218562490c63b36f497bf3a722faf174a515d1443f31ababa6264 \ - --hash=sha256:c4e32ba6d6b13bdb2b8f6764c4fd28d00192826561aa04f6d14eedfce7ac076f +opentelemetry-exporter-otlp-proto-common==1.44.0 \ + --hash=sha256:9a9fe61bba73d802904bc989f1d6b4a7b1ee40f06c40e98d6f85af65aaebb694 \ + --hash=sha256:dc87a5a5bc58f149a56d1547e4691588fa12994cdc3bc039a694ccb3375862ac # via # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-exporter-otlp-proto-grpc==1.43.0 \ - --hash=sha256:1b3e0627daa9bc21884d4a13946807c255eb558bfe5bdd543dffb6f4c9faee0d \ - --hash=sha256:6a10d1feacffffda19acacbf277b736094b1e2f4dbb98c90ccb2c6e1962e2ec6 +opentelemetry-exporter-otlp-proto-grpc==1.44.0 \ + --hash=sha256:40d1ae9e03fcc36de3cbac610cc99f35894938bff9cfd90fc4ec68bd85448463 \ + --hash=sha256:6a1a645ea182a2f59440c51fa8301d309f3324a8f9d65f8395584b064b67ee4e # via opentelemetry-exporter-otlp -opentelemetry-exporter-otlp-proto-http==1.43.0 \ - --hash=sha256:647f603aa8efdbdb4dbff842e0729d0406a6fff26b295a72d3d60e7d963b2610 \ - --hash=sha256:fa8a42bb7d00ee5391f4c0b04d8e6a46c03caa437903296ab73a81dc11ba118f +opentelemetry-exporter-otlp-proto-http==1.44.0 \ + --hash=sha256:838592fce774c1c8bb7b9a0a7facbfa82e17be5a8a4e94cef10cb84ae026bae3 \ + --hash=sha256:c633d7270ad6b57cd4cfbe8b0007a9e2e7c0cb50bd6c50fe2a7b245f721a09d8 # via opentelemetry-exporter-otlp -opentelemetry-instrumentation==0.64b0 \ - --hash=sha256:133ab7ffca796557aec059bf6be3190a34b6dea987f25be3d9409e230cbdad8b \ - --hash=sha256:b47d528dead6271d7743114417eb67fc915bd9258111c48dbf9a4951d2efa88d +opentelemetry-instrumentation==0.65b0 \ + --hash=sha256:071d9d9eced9bd6460444ec3b0c77229870ed05a881c22c84fdede58e4eed09b \ + --hash=sha256:ea967a72b9939b5fcfdad572753b4306c59dcb99e3f382d95dae04286805e137 # via # hexkit (pyproject.toml) # opentelemetry-distro @@ -958,56 +958,56 @@ opentelemetry-instrumentation==0.64b0 \ # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-pymongo # opentelemetry-instrumentation-redis -opentelemetry-instrumentation-aiokafka==0.64b0 \ - --hash=sha256:a5ca0218208f69b8c0604036e4b406cc4925e0af5f0ff4f0bfcc8bf3b23b9948 \ - --hash=sha256:e2b8154055bd7911248f495e77ce1860ca248cd117bd61080143718a5f023bf0 +opentelemetry-instrumentation-aiokafka==0.65b0 \ + --hash=sha256:5261119a9f23755b617b3998331ef1ed408f929f686b5d780431c8ec385f91ff \ + --hash=sha256:dd391f559273b5779fbaea24cd56ea256599242933c5328f152d63d3597faf24 # via hexkit (pyproject.toml) -opentelemetry-instrumentation-asgi==0.64b0 \ - --hash=sha256:4dd3eee566a4303f8e6b9b84f2a0a7abc57a6640df768926c68a3868bf5b2090 \ - --hash=sha256:e0840b66e15303a9254b0540946010bd008aa0504f4d89b8e1b7fb63490a36f0 +opentelemetry-instrumentation-asgi==0.65b0 \ + --hash=sha256:3a845a8ebd1c4ef0d8263401e6545f5b219b2feee612090d50f578a87e71fd65 \ + --hash=sha256:892bca67c56522ffa85a8a83cf934d7b50b3be2132e45cbee705825f0a5ba426 # via opentelemetry-instrumentation-fastapi -opentelemetry-instrumentation-botocore==0.64b0 \ - --hash=sha256:d55f359942021457e76a2c4d7d6dd44f6d8f9155f10c81b92922f2e364e470bc \ - --hash=sha256:e437907352a451c2b9d5b966197cf94785234ef4782ceee5b528d1f8a8875092 +opentelemetry-instrumentation-botocore==0.65b0 \ + --hash=sha256:64987326ac98a47a85821606a981f5058864de0e98b43c8de892eb0fe625b04e \ + --hash=sha256:a5e80b9423f8369c9bbc27a64b31f02cc44218633028ad8d1ace0a2a7fc8f4cd # via hexkit (pyproject.toml) -opentelemetry-instrumentation-fastapi==0.64b0 \ - --hash=sha256:05f75149929e433c1630de381688e650bf651c1e1cce7f9a7b649a807dac8a98 \ - --hash=sha256:43cbbfb2d3079dc81104478a2950ae93ac6d0e90a5020fa3987a236f8f2bdef1 +opentelemetry-instrumentation-fastapi==0.65b0 \ + --hash=sha256:10a3a95486036230413a58fe4fdf4a83fa6bba46918407e527476994bd92bd97 \ + --hash=sha256:cda2610a0ec1b22d19886f33e4d861e9f5dbb886aeaa3a1263b47aff82c36943 # via hexkit (pyproject.toml) -opentelemetry-instrumentation-httpx==0.64b0 \ - --hash=sha256:04829e5723941b5ceb0c88b44d63983e226b5c75b2b2e34a57739fdd0e060608 \ - --hash=sha256:c2cfcd03d3665762860ebd0c28038c6e47fbb48d7942dec31dd75fc634d25c92 +opentelemetry-instrumentation-httpx==0.65b0 \ + --hash=sha256:400f1b78afa4ee2332b5debe58e1ed1b317913d58812c952576be76660aeadb1 \ + --hash=sha256:4627aa9c6bb99bf4462c8b565b0ef6aeb9ffad95c6c92868be1ef7895de112ee # via hexkit (pyproject.toml) -opentelemetry-instrumentation-pymongo==0.64b0 \ - --hash=sha256:4c7a63ffea7e2ac13e83364bd4ac7216953c5f90b63942b19d5e844e35626571 \ - --hash=sha256:cb9c49963899fe3a47cba10ac054d87d3de5b180845b87c69adc689bf84c0e4f +opentelemetry-instrumentation-pymongo==0.65b0 \ + --hash=sha256:8a43f368f7dd101622d2b5929b0c12c4099a0c4a072284b86d18b75dfee10007 \ + --hash=sha256:c714006d3075b0d9cd1a5e8091dce139cb58ee1fbc5a23d5c8f8576e9ae14e53 # via hexkit (pyproject.toml) -opentelemetry-instrumentation-redis==0.64b0 \ - --hash=sha256:5458a541986f665b9d7e641421fa5d0c286f1813b452faab6f84503823719d52 \ - --hash=sha256:c37e194c1e8ff59944d5c2f18014ee18f244a103958b1f2482099525ae9099f9 +opentelemetry-instrumentation-redis==0.65b0 \ + --hash=sha256:7d135f61db9d72416e1f382012fbc13de6f5e726491bebd0344a9c42a60e6769 \ + --hash=sha256:f16409f189092984ff922f26939e7be79509365f5c9d202308c13fddf1368147 # via hexkit (pyproject.toml) opentelemetry-propagator-aws-xray==1.0.2 \ --hash=sha256:1c99181ee228e99bddb638a0c911a297fa21f1c3a0af951f841e79919b5f1934 \ --hash=sha256:6b2cee5479d2ef0172307b66ed2ed151f598a0fd29b3c01133ac87ca06326260 # via opentelemetry-instrumentation-botocore -opentelemetry-proto==1.43.0 \ - --hash=sha256:224778df17e1f3fafeaaa21d874236ca5f6ffc2f86e0899298ec7351aac27924 \ - --hash=sha256:c58f1f7ef84bc7dc2834016c0c37fe0081dde7ca9f6339be1970fbf9cdaaa90d +opentelemetry-proto==1.44.0 \ + --hash=sha256:898b155a0e1557afd867478fb6158e8122a46329ca0bb8dc53cc55e98f017f56 \ + --hash=sha256:c547a79c2f8c0c515d31509154682e5921c7cfd5ca67b70e1f9266e2c3e103f3 # via # opentelemetry-exporter-otlp-proto-common # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-sdk==1.43.0 \ - --hash=sha256:d1323a547c1ce69d6a069a17a44b7da82bb8b332051ecb074041f87642c86823 \ - --hash=sha256:d8187c81c162df9913e4003dd6485f7390d9a24fc17026ec7387b8b8218b08e9 +opentelemetry-sdk==1.44.0 \ + --hash=sha256:cebe7f65dc12f26ead75c6064de12fd2a9052e5060c0272d402cfa203aae123b \ + --hash=sha256:df081c4c6bcfdb1211e3e86140376792643128a25f8d72d1d27675936e7e96ad # via # hexkit (pyproject.toml) # opentelemetry-distro # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-semantic-conventions==0.64b0 \ - --hash=sha256:72f76fb2d1582d9d033dd1fcd84532e961e6ff3d90d24ba6fabc72975a83864c \ - --hash=sha256:ea77e85e354b8f604ddbe5f3d9135216f982fa4d77e5859ac30f6d8a50505aa6 +opentelemetry-semantic-conventions==0.65b0 \ + --hash=sha256:1cacde7b0ad306f84c5ef08c3dbe1bbaf20165bba6f8bff43b670e555a086bcb \ + --hash=sha256:f9b2b81e9d5b64f11bc952075e7e9c7fb0aab075c7fd1c46d597f1b919852d60 # via # opentelemetry-instrumentation # opentelemetry-instrumentation-aiokafka @@ -1018,9 +1018,9 @@ opentelemetry-semantic-conventions==0.64b0 \ # opentelemetry-instrumentation-pymongo # opentelemetry-instrumentation-redis # opentelemetry-sdk -opentelemetry-util-http==0.64b0 \ - --hash=sha256:8a86a220dbfc56d736f47f1e5c4e7932a21fcf69052312e1bcf166444dc79322 \ - --hash=sha256:c1e5350d25507c1afcd6076cf9ac062485a0a4f79cd9971366996fd3056bacdb +opentelemetry-util-http==0.65b0 \ + --hash=sha256:7553b606f963097cb190536dc30556cce85090692e471a422fff30ca29b04348 \ + --hash=sha256:84f82d826978bba416ab453460ff6a7391cdc3534c93a786595e4068680016b7 # via # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-fastapi @@ -1038,9 +1038,9 @@ pathspec==1.1.1 \ --hash=sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a \ --hash=sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189 # via mypy -platformdirs==4.10.0 \ - --hash=sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7 \ - --hash=sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a +platformdirs==4.10.1 \ + --hash=sha256:0e4eff26be2d75293977f7cddc153fd9b8eaa7fb0c7b64ffe4076cb443117443 \ + --hash=sha256:ceab4084426fe6319ce18e86deada8ab1b7487c7aee7040c55e277c9ae793695 # via # python-discovery # tox @@ -1547,29 +1547,29 @@ rpds-py==0.30.0 \ # -r lock/requirements-dev.in # jsonschema # referencing -ruff==0.15.21 \ - --hash=sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075 \ - --hash=sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be \ - --hash=sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd \ - --hash=sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd \ - --hash=sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86 \ - --hash=sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341 \ - --hash=sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd \ - --hash=sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67 \ - --hash=sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41 \ - --hash=sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d \ - --hash=sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d \ - --hash=sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8 \ - --hash=sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233 \ - --hash=sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8 \ - --hash=sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500 \ - --hash=sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3 \ - --hash=sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646 \ - --hash=sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f +ruff==0.15.22 \ + --hash=sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f \ + --hash=sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296 \ + --hash=sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e \ + --hash=sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c \ + --hash=sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb \ + --hash=sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809 \ + --hash=sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8 \ + --hash=sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224 \ + --hash=sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64 \ + --hash=sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178 \ + --hash=sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576 \ + --hash=sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde \ + --hash=sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262 \ + --hash=sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697 \ + --hash=sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661 \ + --hash=sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf \ + --hash=sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a \ + --hash=sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74 # via -r lock/requirements-dev-template.in -s3transfer==0.19.0 \ - --hash=sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262 \ - --hash=sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685 +s3transfer==0.19.1 \ + --hash=sha256:d3d6371dc3f1e5c5427b2b457bcf13bcf87bec334c95aed18642eae61f6926f3 \ + --hash=sha256:d5fd7005ee39307455ad5f310b5ea67f4b1960d7fed5b3671ee50c249de675de # via boto3 setuptools==83.0.0 \ --hash=sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef \ @@ -1609,13 +1609,13 @@ tornado==6.5.7 \ --hash=sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4 \ --hash=sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796 # via snakeviz -tox==4.56.4 \ - --hash=sha256:53bac88382b9638a5ce40fbaddd6076e1c8f638751af7bf8e759392c953df2f0 \ - --hash=sha256:d49e371119ebfafb15054ad7ccff3d03027ccb65195fae3ac656b431b5524055 +tox==4.57.2 \ + --hash=sha256:2c187558a0d336b5e658025649f3c0e61aad080fdc674740e213d93bd48506ee \ + --hash=sha256:d23465ed07fd743f3b20b21a4991f4932ed4edb392bf32c0b9f7ce4415d2e89d # via -r lock/requirements-dev.in -typer==0.26.8 \ - --hash=sha256:3512ca79ac5c11113414b36e80281b872884477722440691c89d1112e321a49c \ - --hash=sha256:c244a6bd558886fe3f8780efb6bdd28bb9aff005a94eedebaa5cb32926fe2f7e +typer==0.27.0 \ + --hash=sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5 \ + --hash=sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1 # via -r lock/requirements-dev-template.in typing-extensions==4.16.0 \ --hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \ @@ -1649,30 +1649,30 @@ urllib3==2.7.0 \ # docker # requests # testcontainers -uv==0.11.28 \ - --hash=sha256:041e4b80bebc58d7142ac9394370cacd73185fd8d066d6675d14707d83408f6d \ - --hash=sha256:185416a5316df8c5442b47178349f1f27fc1034468670ac1fb499eae3b25bd68 \ - --hash=sha256:2e91eb8a0b00d5f4427195fc818bcaa4d8bb4fccb79f4e973e74802419ab06ca \ - --hash=sha256:3fcfda468448093f4d5961ca8c068b0aeec2d02f7226d58ee8513321a929fe4f \ - --hash=sha256:47e3f12fe6f5c80a01639d8df36efde7bdddfc3bbc52250df623547d8d393105 \ - --hash=sha256:49fe42df9f42056037473f3876adec1615709b57d3470ed39178ff420f3afb9f \ - --hash=sha256:692edef9cf1d2dd69bb9d9fc01f281a82610547900ce227a3cb269cdf988b5ce \ - --hash=sha256:6b3d0ea11e83b373a2166b82dd0864f5677fbadf98db64541ab2e59c42968905 \ - --hash=sha256:6f7ce6f6015a3e857bc6a663514afa62856b669ee5c1bd120e4c58ac2ef5513d \ - --hash=sha256:8c60294e3be4fa203a04015fc02ac8a31d936e86fde06dcb43c7f8f22661dfff \ - --hash=sha256:a4a9fe246cb2882532277f5d5e5bd8a59462981462a2f98426f35ecfca82460e \ - --hash=sha256:ae5bbdb6150adcd625f5fa720b04abf2014247d878d1035f19751bb0e7274543 \ - --hash=sha256:bb11d94cb848ff58af79e0bb5e4037cd324d27dbe2dabb7746db698b724a9a20 \ - --hash=sha256:d01c7c665511c047f350e587b8b6557c96b61b2eddafbcd8964f0cc2f5b9afbe \ - --hash=sha256:df86cfd135542a833e9f84708b3b8dbaa987a3b9db85b267062db49ab639d242 \ - --hash=sha256:e94560995737c50525d586da553521fbafe9ef06641e7d885db4b270f53ee84d \ - --hash=sha256:e9eb317b1cdb249887df77ac232d8a9448f26858b2399f9f2949c6a7b9bedf88 \ - --hash=sha256:f4fcf2c8d9f1444b900e6b8dbbb828825fb76eca01acd18aeaa5c90240408cda \ - --hash=sha256:fab3c31007a611866475824a666f5a721bf0c9335db806355a97fcfba2a6bbb7 +uv==0.11.30 \ + --hash=sha256:06f4b824c6123df1cd00a68367f970870e7252b0b11a4d03a06b2b4b433afcda \ + --hash=sha256:08dbb7a164a335d04684973223a41b47bdc2f8828045dff5aa79d004961b24cf \ + --hash=sha256:0b39151a5873a2f0a03ff9d03eb351ad5cda14973af40da8d80e4c7c2d6369f0 \ + --hash=sha256:3a67fe9309f21c8b793f36bf15602dcd20163e11165776b3b355e520a7a2ed21 \ + --hash=sha256:3b1f0dc345a7c2101a8e5f9e36840cc40a36499644e468c59a13fd235072b457 \ + --hash=sha256:42adb04aaa0912ddafa059e641c057cafee0de0b57f6156909a00e28791c7e45 \ + --hash=sha256:520768350eadf59cb7a037eb1734bb65605e4bb7466fc57fe6357354e208b61d \ + --hash=sha256:53d83ca316a67d7442302220006ccdb4ea0e0cabaeccd9eb28430d7b62603add \ + --hash=sha256:6a29031ff95150ea6156607394db8f79dfb06d5287f46ff07e3f60b9df76121c \ + --hash=sha256:7c41e83a2811c22e04ae50d0986932318ba82e6f9e29f0fca727d855df6bd959 \ + --hash=sha256:7d9d922cfef27757156f1023eb057abab192e3e9f5436ba60eac57ffbc2b5c23 \ + --hash=sha256:9621de942431150ccfc847cd71a07b96f52ba2c072764e615cef4cb733bb5f4d \ + --hash=sha256:988133c7f44c6c64f6fef482483014995260cdb3a68270805256ddb9e6fed9e8 \ + --hash=sha256:a2aff328164d7e8fbcf6b82182cc16f7a729ec7edfce77b4d0c2908fca12bd63 \ + --hash=sha256:b99f98873c785745755cb32c165ec8e45e019b63ec71540fa0185cda9192d18d \ + --hash=sha256:cc28cb55c2b3c80a26ea374a172fec70b0561ada211e6fb23936ccea3ecb80b2 \ + --hash=sha256:d44bfd6519bedbf10bd7a4558bd281a8a5f5b72d2bb35fd831dee55cd63fc800 \ + --hash=sha256:ea5f0d4fe452dc3daf915c714504eb2f1e570f8ebac752abf51f9e6f58a1ff68 \ + --hash=sha256:fbda9d6d2921e69b157ec7642f8af478a4ac5c9f088693b3913336adaf51d0f5 # via -r lock/requirements-dev-template.in -virtualenv==21.6.0 \ - --hash=sha256:bce9d097950fef9d81129b333babfb7767072850c2f1acce0ec536708401bfd1 \ - --hash=sha256:e18a4d750f2b64dea73e72ffde3922f3c52365fabdc8157ebd3da20d031c4734 +virtualenv==21.6.1 \ + --hash=sha256:15f978b7cd329f24855ff4a0c4b4899cc7678589f49adbdcbbb4d3232e641128 \ + --hash=sha256:afe991df855715a2b2f60edfcc0107ef95a79fdfd8cb4cdaa71603d1c12e463b # via # pre-commit # tox diff --git a/lock/requirements.txt b/lock/requirements.txt index 699d0c36..4c9d14b7 100644 --- a/lock/requirements.txt +++ b/lock/requirements.txt @@ -39,9 +39,9 @@ annotated-types==0.7.0 \ # via # -c lock/requirements-dev.txt # pydantic -asgiref==3.11.1 \ - --hash=sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce \ - --hash=sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133 +asgiref==3.12.1 \ + --hash=sha256:59dcb51c272ad209d59bed5708a64a333083e86017d7fcdd67498eeab7784340 \ + --hash=sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094 # via # -c lock/requirements-dev.txt # opentelemetry-instrumentation-asgi @@ -58,15 +58,15 @@ attrs==26.1.0 \ # -c lock/requirements-dev.txt # jsonschema # referencing -boto3==1.43.45 \ - --hash=sha256:65e0ae541a9948ac41b706d5c7165d96ebf155812562b6518b862be027ee7347 \ - --hash=sha256:bb076647526c491ce75cab896543afcda5b81c97d3f8e8da08a033fc1ddb7429 +boto3==1.43.52 \ + --hash=sha256:1af1950c2b2400267c93d971d588367fc73554e02b4f435a50a5e930a7c93526 \ + --hash=sha256:3da09a393c050906d407023bee5fb5b5fb333378513af1a1a51159db870b572f # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -botocore==1.43.45 \ - --hash=sha256:a04871d814124e65daf429fb99640def23b8c4d3edc6438603b31f11116d7a67 \ - --hash=sha256:a2da80ff3caa2873769b9a32ae5f1fb18b3571ab63a981896639955611ca01e6 +botocore==1.43.52 \ + --hash=sha256:3c25e11796ae6e295f1cc3a7760e808c26c432cd580d6a608f32da24715c389b \ + --hash=sha256:43715e971b306f86d5918b3b728ec62aae3f4be49e1606058ef1f0b87dcbad9e # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) @@ -417,9 +417,9 @@ jsonschema-specifications==2025.9.1 \ # via # -c lock/requirements-dev.txt # jsonschema -opentelemetry-api==1.43.0 \ - --hash=sha256:107d0d03857ea8fc7c5fcbbbd83f800c281f0d560553d61c1d675fccfd1761c1 \ - --hash=sha256:20acf45e9b21851926835292e4045d290acade1edd2ff3de86d2f069687ba1fd +opentelemetry-api==1.44.0 \ + --hash=sha256:67647e5e9566edcf421166fdf022b3537f818635daa852b289e34604dc6fb33a \ + --hash=sha256:94b98c893a91b88657eaac1e3ba89618cdb85be6918196705354f34728b2cdef # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) @@ -437,40 +437,40 @@ opentelemetry-api==1.43.0 \ # opentelemetry-propagator-aws-xray # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-distro==0.64b0 \ - --hash=sha256:8a19716899854245b4028650ec1cca12d89f9be41571bbffe9e539cd55d2fd96 \ - --hash=sha256:ce97b6cedfcf03dc54035c422485412eda63250e094f4bd63ef57d017d823f3c +opentelemetry-distro==0.65b0 \ + --hash=sha256:0e15bb1a54c638e6c361bc66bc43e9de9ead442e1ae06f8099a2c1d27b6ef845 \ + --hash=sha256:e2fef26fdf72978ab172530c13338aff367edae41ae8d90b7f6133efedde10ab # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-exporter-otlp==1.43.0 \ - --hash=sha256:65aded6c50ee7dd2b9948c9d0e59ddb4ed4eea6e8532fba95cbe6a4a64a566ba \ - --hash=sha256:70f3fe740a64596d4157588a2ee7e4fd37d2acc0c0f522a2882b8c29316cd0f0 +opentelemetry-exporter-otlp==1.44.0 \ + --hash=sha256:4a498fa8d8fd8be9e8e2d175fe5524a3fe581ccffadd8509db86526a5fb97051 \ + --hash=sha256:af1cde7c33ea8ed624bf04ac49a885730fe44c1f1ad698656e592c38f70ce106 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-exporter-otlp-proto-common==1.43.0 \ - --hash=sha256:123c3f9cc87218562490c63b36f497bf3a722faf174a515d1443f31ababa6264 \ - --hash=sha256:c4e32ba6d6b13bdb2b8f6764c4fd28d00192826561aa04f6d14eedfce7ac076f +opentelemetry-exporter-otlp-proto-common==1.44.0 \ + --hash=sha256:9a9fe61bba73d802904bc989f1d6b4a7b1ee40f06c40e98d6f85af65aaebb694 \ + --hash=sha256:dc87a5a5bc58f149a56d1547e4691588fa12994cdc3bc039a694ccb3375862ac # via # -c lock/requirements-dev.txt # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-exporter-otlp-proto-grpc==1.43.0 \ - --hash=sha256:1b3e0627daa9bc21884d4a13946807c255eb558bfe5bdd543dffb6f4c9faee0d \ - --hash=sha256:6a10d1feacffffda19acacbf277b736094b1e2f4dbb98c90ccb2c6e1962e2ec6 +opentelemetry-exporter-otlp-proto-grpc==1.44.0 \ + --hash=sha256:40d1ae9e03fcc36de3cbac610cc99f35894938bff9cfd90fc4ec68bd85448463 \ + --hash=sha256:6a1a645ea182a2f59440c51fa8301d309f3324a8f9d65f8395584b064b67ee4e # via # -c lock/requirements-dev.txt # opentelemetry-exporter-otlp -opentelemetry-exporter-otlp-proto-http==1.43.0 \ - --hash=sha256:647f603aa8efdbdb4dbff842e0729d0406a6fff26b295a72d3d60e7d963b2610 \ - --hash=sha256:fa8a42bb7d00ee5391f4c0b04d8e6a46c03caa437903296ab73a81dc11ba118f +opentelemetry-exporter-otlp-proto-http==1.44.0 \ + --hash=sha256:838592fce774c1c8bb7b9a0a7facbfa82e17be5a8a4e94cef10cb84ae026bae3 \ + --hash=sha256:c633d7270ad6b57cd4cfbe8b0007a9e2e7c0cb50bd6c50fe2a7b245f721a09d8 # via # -c lock/requirements-dev.txt # opentelemetry-exporter-otlp -opentelemetry-instrumentation==0.64b0 \ - --hash=sha256:133ab7ffca796557aec059bf6be3190a34b6dea987f25be3d9409e230cbdad8b \ - --hash=sha256:b47d528dead6271d7743114417eb67fc915bd9258111c48dbf9a4951d2efa88d +opentelemetry-instrumentation==0.65b0 \ + --hash=sha256:071d9d9eced9bd6460444ec3b0c77229870ed05a881c22c84fdede58e4eed09b \ + --hash=sha256:ea967a72b9939b5fcfdad572753b4306c59dcb99e3f382d95dae04286805e137 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) @@ -482,45 +482,45 @@ opentelemetry-instrumentation==0.64b0 \ # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-pymongo # opentelemetry-instrumentation-redis -opentelemetry-instrumentation-aiokafka==0.64b0 \ - --hash=sha256:a5ca0218208f69b8c0604036e4b406cc4925e0af5f0ff4f0bfcc8bf3b23b9948 \ - --hash=sha256:e2b8154055bd7911248f495e77ce1860ca248cd117bd61080143718a5f023bf0 +opentelemetry-instrumentation-aiokafka==0.65b0 \ + --hash=sha256:5261119a9f23755b617b3998331ef1ed408f929f686b5d780431c8ec385f91ff \ + --hash=sha256:dd391f559273b5779fbaea24cd56ea256599242933c5328f152d63d3597faf24 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-instrumentation-asgi==0.64b0 \ - --hash=sha256:4dd3eee566a4303f8e6b9b84f2a0a7abc57a6640df768926c68a3868bf5b2090 \ - --hash=sha256:e0840b66e15303a9254b0540946010bd008aa0504f4d89b8e1b7fb63490a36f0 +opentelemetry-instrumentation-asgi==0.65b0 \ + --hash=sha256:3a845a8ebd1c4ef0d8263401e6545f5b219b2feee612090d50f578a87e71fd65 \ + --hash=sha256:892bca67c56522ffa85a8a83cf934d7b50b3be2132e45cbee705825f0a5ba426 # via # -c lock/requirements-dev.txt # opentelemetry-instrumentation-fastapi -opentelemetry-instrumentation-botocore==0.64b0 \ - --hash=sha256:d55f359942021457e76a2c4d7d6dd44f6d8f9155f10c81b92922f2e364e470bc \ - --hash=sha256:e437907352a451c2b9d5b966197cf94785234ef4782ceee5b528d1f8a8875092 +opentelemetry-instrumentation-botocore==0.65b0 \ + --hash=sha256:64987326ac98a47a85821606a981f5058864de0e98b43c8de892eb0fe625b04e \ + --hash=sha256:a5e80b9423f8369c9bbc27a64b31f02cc44218633028ad8d1ace0a2a7fc8f4cd # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-instrumentation-fastapi==0.64b0 \ - --hash=sha256:05f75149929e433c1630de381688e650bf651c1e1cce7f9a7b649a807dac8a98 \ - --hash=sha256:43cbbfb2d3079dc81104478a2950ae93ac6d0e90a5020fa3987a236f8f2bdef1 +opentelemetry-instrumentation-fastapi==0.65b0 \ + --hash=sha256:10a3a95486036230413a58fe4fdf4a83fa6bba46918407e527476994bd92bd97 \ + --hash=sha256:cda2610a0ec1b22d19886f33e4d861e9f5dbb886aeaa3a1263b47aff82c36943 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-instrumentation-httpx==0.64b0 \ - --hash=sha256:04829e5723941b5ceb0c88b44d63983e226b5c75b2b2e34a57739fdd0e060608 \ - --hash=sha256:c2cfcd03d3665762860ebd0c28038c6e47fbb48d7942dec31dd75fc634d25c92 +opentelemetry-instrumentation-httpx==0.65b0 \ + --hash=sha256:400f1b78afa4ee2332b5debe58e1ed1b317913d58812c952576be76660aeadb1 \ + --hash=sha256:4627aa9c6bb99bf4462c8b565b0ef6aeb9ffad95c6c92868be1ef7895de112ee # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-instrumentation-pymongo==0.64b0 \ - --hash=sha256:4c7a63ffea7e2ac13e83364bd4ac7216953c5f90b63942b19d5e844e35626571 \ - --hash=sha256:cb9c49963899fe3a47cba10ac054d87d3de5b180845b87c69adc689bf84c0e4f +opentelemetry-instrumentation-pymongo==0.65b0 \ + --hash=sha256:8a43f368f7dd101622d2b5929b0c12c4099a0c4a072284b86d18b75dfee10007 \ + --hash=sha256:c714006d3075b0d9cd1a5e8091dce139cb58ee1fbc5a23d5c8f8576e9ae14e53 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) -opentelemetry-instrumentation-redis==0.64b0 \ - --hash=sha256:5458a541986f665b9d7e641421fa5d0c286f1813b452faab6f84503823719d52 \ - --hash=sha256:c37e194c1e8ff59944d5c2f18014ee18f244a103958b1f2482099525ae9099f9 +opentelemetry-instrumentation-redis==0.65b0 \ + --hash=sha256:7d135f61db9d72416e1f382012fbc13de6f5e726491bebd0344a9c42a60e6769 \ + --hash=sha256:f16409f189092984ff922f26939e7be79509365f5c9d202308c13fddf1368147 # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) @@ -530,26 +530,26 @@ opentelemetry-propagator-aws-xray==1.0.2 \ # via # -c lock/requirements-dev.txt # opentelemetry-instrumentation-botocore -opentelemetry-proto==1.43.0 \ - --hash=sha256:224778df17e1f3fafeaaa21d874236ca5f6ffc2f86e0899298ec7351aac27924 \ - --hash=sha256:c58f1f7ef84bc7dc2834016c0c37fe0081dde7ca9f6339be1970fbf9cdaaa90d +opentelemetry-proto==1.44.0 \ + --hash=sha256:898b155a0e1557afd867478fb6158e8122a46329ca0bb8dc53cc55e98f017f56 \ + --hash=sha256:c547a79c2f8c0c515d31509154682e5921c7cfd5ca67b70e1f9266e2c3e103f3 # via # -c lock/requirements-dev.txt # opentelemetry-exporter-otlp-proto-common # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-sdk==1.43.0 \ - --hash=sha256:d1323a547c1ce69d6a069a17a44b7da82bb8b332051ecb074041f87642c86823 \ - --hash=sha256:d8187c81c162df9913e4003dd6485f7390d9a24fc17026ec7387b8b8218b08e9 +opentelemetry-sdk==1.44.0 \ + --hash=sha256:cebe7f65dc12f26ead75c6064de12fd2a9052e5060c0272d402cfa203aae123b \ + --hash=sha256:df081c4c6bcfdb1211e3e86140376792643128a25f8d72d1d27675936e7e96ad # via # -c lock/requirements-dev.txt # hexkit (pyproject.toml) # opentelemetry-distro # opentelemetry-exporter-otlp-proto-grpc # opentelemetry-exporter-otlp-proto-http -opentelemetry-semantic-conventions==0.64b0 \ - --hash=sha256:72f76fb2d1582d9d033dd1fcd84532e961e6ff3d90d24ba6fabc72975a83864c \ - --hash=sha256:ea77e85e354b8f604ddbe5f3d9135216f982fa4d77e5859ac30f6d8a50505aa6 +opentelemetry-semantic-conventions==0.65b0 \ + --hash=sha256:1cacde7b0ad306f84c5ef08c3dbe1bbaf20165bba6f8bff43b670e555a086bcb \ + --hash=sha256:f9b2b81e9d5b64f11bc952075e7e9c7fb0aab075c7fd1c46d597f1b919852d60 # via # -c lock/requirements-dev.txt # opentelemetry-instrumentation @@ -561,9 +561,9 @@ opentelemetry-semantic-conventions==0.64b0 \ # opentelemetry-instrumentation-pymongo # opentelemetry-instrumentation-redis # opentelemetry-sdk -opentelemetry-util-http==0.64b0 \ - --hash=sha256:8a86a220dbfc56d736f47f1e5c4e7932a21fcf69052312e1bcf166444dc79322 \ - --hash=sha256:c1e5350d25507c1afcd6076cf9ac062485a0a4f79cd9971366996fd3056bacdb +opentelemetry-util-http==0.65b0 \ + --hash=sha256:7553b606f963097cb190536dc30556cce85090692e471a422fff30ca29b04348 \ + --hash=sha256:84f82d826978bba416ab453460ff6a7391cdc3534c93a786595e4068680016b7 # via # -c lock/requirements-dev.txt # opentelemetry-instrumentation-asgi @@ -1033,9 +1033,9 @@ rpds-py==0.30.0 \ # -c lock/requirements-dev.txt # jsonschema # referencing -s3transfer==0.19.0 \ - --hash=sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262 \ - --hash=sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685 +s3transfer==0.19.1 \ + --hash=sha256:d3d6371dc3f1e5c5427b2b457bcf13bcf87bec334c95aed18642eae61f6926f3 \ + --hash=sha256:d5fd7005ee39307455ad5f310b5ea67f4b1960d7fed5b3671ee50c249de675de # via # -c lock/requirements-dev.txt # boto3 diff --git a/pyproject.toml b/pyproject.toml index a7cdc2eb..ad54d001 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,10 +23,10 @@ classifiers = [ "Intended Audience :: Developers", ] name = "hexkit" -version = "8.5.0" +version = "8.6.0" description = "A Toolkit for Building Microservices using the Hexagonal Architecture" dependencies = [ - "opentelemetry-api >=1.39, <2", + "opentelemetry-api >=1.44, <2", "pydantic >=2.12, <3", "pydantic_settings >=2.12, <3", "PyYAML >=6, <7", @@ -54,35 +54,35 @@ vault = [ "hvac >=2.4, <3", ] opentelemetry-base = [ - "opentelemetry-sdk >=1.39.1, <2", - "opentelemetry-exporter-otlp >=1.39.1, <2", - "opentelemetry-instrumentation >=0.60b1", - "opentelemetry-instrumentation-httpx >=0.60b1", - "opentelemetry-distro >=0.60b1", + "opentelemetry-sdk >=1.44, <2", + "opentelemetry-exporter-otlp >=1.44, <2", + "opentelemetry-instrumentation >=0.65b0", + "opentelemetry-instrumentation-httpx >=0.65b0", + "opentelemetry-distro >=0.65b0", ] opentelemetry-akafka = [ "hexkit[opentelemetry-base]", "hexkit[akafka]", - "opentelemetry-instrumentation-aiokafka >=0.60b1", + "opentelemetry-instrumentation-aiokafka >=0.65b0", ] opentelemetry-mongodb = [ "hexkit[opentelemetry-base]", "hexkit[mongodb]", - "opentelemetry-instrumentation-pymongo >=0.60b1", + "opentelemetry-instrumentation-pymongo >=0.65b0", ] opentelemetry-fastapi = [ "hexkit[opentelemetry-base]", - "opentelemetry-instrumentation-fastapi >=0.60b1", + "opentelemetry-instrumentation-fastapi >=0.65b0", ] opentelemetry-s3 = [ "hexkit[opentelemetry-base]", "hexkit[s3]", - "opentelemetry-instrumentation-botocore >=0.60b1", + "opentelemetry-instrumentation-botocore >=0.65b0", ] opentelemetry-redis = [ "hexkit[opentelemetry-base]", "hexkit[redis]", - "opentelemetry-instrumentation-redis >=0.60b1", + "opentelemetry-instrumentation-redis >=0.65b0", ] opentelemetry = [ "hexkit[opentelemetry-akafka]", diff --git a/src/hexkit/opentelemetry.py b/src/hexkit/opentelemetry.py deleted file mode 100644 index 31cd9350..00000000 --- a/src/hexkit/opentelemetry.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln -# for the German Human Genome-Phenome Archive (GHGA) -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""OpenTelemetry specific configuration code. This is gated behind the opentelemetry extra.""" - -import logging -import os -from typing import Annotated - -from opentelemetry import trace -from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter -from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED -from opentelemetry.sdk.resources import SERVICE_NAME, Resource -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import BatchSpanProcessor -from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio -from pydantic import Field -from pydantic_settings import BaseSettings - -logger = logging.getLogger(__name__) - - -class OpenTelemetryConfig(BaseSettings): - """OpenTelemetry specific configuration options""" - - enable_opentelemetry: bool = Field( - default=False, - description="If set to true, this will run necessary setup code." - "If set to false, environment variables are set that should also effectively " - "disable autoinstrumentation.", - ) - otel_trace_sampling_rate: Annotated[float, Field(strict=True, ge=0, le=1)] = Field( - default=1.0, - description="Determines which proportion of spans should be sampled. " - "A value of 1.0 means all and is equivalent to the previous behaviour. " - "Setting this to 0 will result in no spans being sampled, but this does not " - "automatically set `enable_opentelemetry` to False.", - ) - - -def configure_opentelemetry(*, service_name: str, config: OpenTelemetryConfig): - """Configure all needed parts of OpenTelemetry. - - Setup of the TracerProvider is done programmatically, while disabling OpenTelemetry - sets the corresponding environment variable. - """ - if config.enable_opentelemetry: - resource = Resource(attributes={SERVICE_NAME: service_name}) - # Replace the default static sampler with a probabilistic one that honors parent - # span sampling decisions - # This should consistently yield full traces within a service but not necessarily - # across service boundaries - # With the default sampling rate, behaviour does not change, but this allows to - # introduce head sampling by adjusting a config option on the service side later on - sampler = ParentBasedTraceIdRatio(rate=config.otel_trace_sampling_rate) - - # Initialize service specific TracerProvider - trace_provider = TracerProvider(resource=resource, sampler=sampler) - processor = BatchSpanProcessor(OTLPSpanExporter()) - trace_provider.add_span_processor(processor) - trace.set_tracer_provider(trace_provider) - else: - # Currently OTEL_SDK_DISABLED doesn't seem to be honored by all implementations yet - # It seems to be working well enough for the Python implementation. - os.environ[OTEL_SDK_DISABLED] = "true" diff --git a/src/hexkit/opentelemetry/__init__.py b/src/hexkit/opentelemetry/__init__.py new file mode 100644 index 00000000..246e01cd --- /dev/null +++ b/src/hexkit/opentelemetry/__init__.py @@ -0,0 +1,29 @@ +# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""Subpackage containing OpenTelemetry instrumentation and related utilities.""" + +from .instrumentation import ( + OpenTelemetryConfig, + configure_opentelemetry, + instrument_installed_libraries, +) + +__all__ = [ + "OpenTelemetryConfig", + "configure_opentelemetry", + "instrument_installed_libraries", +] diff --git a/src/hexkit/opentelemetry/instrumentation.py b/src/hexkit/opentelemetry/instrumentation.py new file mode 100644 index 00000000..a3aa61ea --- /dev/null +++ b/src/hexkit/opentelemetry/instrumentation.py @@ -0,0 +1,122 @@ +# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""OpenTelemetry specific configuration code. This is gated behind the opentelemetry extra.""" + +import importlib +import logging +from typing import Annotated + +from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.resources import SERVICE_NAME, Resource +from opentelemetry.sdk.trace import SpanProcessor, TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor +from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio +from pydantic import Field +from pydantic_settings import BaseSettings + +__all__ = [ + "OpenTelemetryConfig", + "configure_opentelemetry", + "instrument_installed_libraries", +] + +logger = logging.getLogger(__name__) + +# Instrumentation modules corresponding to the `opentelemetry-*` optional extras. +# Each entry is only instrumented if its module is installed. +_INSTRUMENTOR_MODULES: tuple[tuple[str, str], ...] = ( + ("opentelemetry.instrumentation.httpx", "HTTPXClientInstrumentor"), + ("opentelemetry.instrumentation.aiokafka", "AIOKafkaInstrumentor"), + ("opentelemetry.instrumentation.pymongo", "PymongoInstrumentor"), + ("opentelemetry.instrumentation.fastapi", "FastAPIInstrumentor"), + ("opentelemetry.instrumentation.botocore", "BotocoreInstrumentor"), + ("opentelemetry.instrumentation.redis", "RedisInstrumentor"), +) + + +def instrument_installed_libraries() -> None: + """Run `.instrument()` for every instrumentation library that is installed.""" + for module_name, class_name in _INSTRUMENTOR_MODULES: + try: + module = importlib.import_module(module_name) + except ImportError: + logger.debug("'%s' not installed, skipping instrumentation.", module_name) + continue + try: + instrumentor_class = getattr(module, class_name) + except AttributeError: + logger.warning( + "Could not instrument '%s' for '%s'.", class_name, module_name + ) + instrumentor_class().instrument() + logger.info("Instrumented '%s' for '%s'.", class_name, module_name) + + +class OpenTelemetryConfig(BaseSettings): + """OpenTelemetry specific configuration options""" + + enable_opentelemetry: bool = Field( + default=False, + description="If set to true, this will run necessary setup code." + "If set to false, no setup code is run, which leaves tracing disabled.", + ) + otel_trace_sampling_rate: Annotated[float, Field(strict=True, ge=0, le=1)] = Field( + default=1.0, + description="Determines which proportion of spans should be sampled. " + "A value of 1.0 means all and is equivalent to the previous behaviour. " + "Setting this to 0 will result in no spans being sampled, but this does not " + "automatically set `enable_opentelemetry` to False.", + ) + + +def configure_opentelemetry( + *, + service_name: str, + config: OpenTelemetryConfig, + span_processor: SpanProcessor | None = None, +): + """Configure all needed parts of OpenTelemetry. + + This needs to be called before constructing any objects that are instrumented, e.g. + construction a FastAPI app before running this, will result in missing instrumentation. + + Setup of the TracerProvider is done programmatically. If disabled, this is a no-op, + leaving the default no-op TracerProvider from the OpenTelemetry API in place. + + By default, spans are exported via OTLP over HTTP using a `BatchSpanProcessor`. + """ + if not config.enable_opentelemetry: + logger.info("OpenTelemetry disabled via config.") + return + + resource = Resource(attributes={SERVICE_NAME: service_name}) + # Replace the default static sampler with a probabilistic one that honors parent + # span sampling decisions + # This should consistently yield full traces within a service but not necessarily + # across service boundaries + # With the default sampling rate, behaviour does not change, but this allows to + # introduce head sampling by adjusting a config option on the service side later on + sampler = ParentBasedTraceIdRatio(rate=config.otel_trace_sampling_rate) + + # Initialize service specific TracerProvider + trace_provider = TracerProvider(resource=resource, sampler=sampler) + trace_provider.add_span_processor( + span_processor or BatchSpanProcessor(OTLPSpanExporter()) + ) + trace.set_tracer_provider(trace_provider) + + instrument_installed_libraries() diff --git a/src/hexkit/opentelemetry/testutils.py b/src/hexkit/opentelemetry/testutils.py new file mode 100644 index 00000000..2a46db50 --- /dev/null +++ b/src/hexkit/opentelemetry/testutils.py @@ -0,0 +1,141 @@ +# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""Utilities for testing code that relies on OpenTelemetry instrumentation. + +Please note, only use for testing purposes. +""" + +from collections.abc import Generator +from dataclasses import dataclass + +import pytest +from opentelemetry import trace +from opentelemetry.sdk.trace import ReadableSpan, TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + +from hexkit.custom_types import PytestScope +from hexkit.opentelemetry import OpenTelemetryConfig, configure_opentelemetry + +__all__ = [ + "OpenTelemetryFixture", + "get_otel_fixture", + "get_otel_provider_fixture", + "otel_fixture", + "otel_provider_fixture", +] + + +@dataclass(frozen=True) +class OpenTelemetryFixture: + """A fixture with utility methods for tests that verify emitted spans.""" + + exporter: InMemorySpanExporter + + def reset(self) -> None: + """Clear all previously captured spans.""" + self.exporter.clear() + + def get_finished_spans(self) -> tuple[ReadableSpan, ...]: + """Return all spans finished so far, in the order they completed.""" + return tuple(self.exporter.get_finished_spans()) + + def get_span_names(self) -> list[str]: + """Return the names of all finished spans, in the order they completed.""" + return [span.name for span in self.get_finished_spans()] + + def assert_has_span(self, name: str) -> ReadableSpan: + """Assert that a finished span with the given name exists and return it.""" + for span in self.get_finished_spans(): + if span.name == name: + return span + raise AssertionError( + f"No span named {name!r} found. Captured spans: {self.get_span_names()}" + ) + + +def _otel_provider_fixture( + service_name: str = "test", +) -> Generator[OpenTelemetryFixture, None, None]: + """Fixture function attaching an in-memory span exporter for the test session. + + If OpenTelemetry has already been configured (e.g. because the app under test + calls `configure_opentelemetry()` on startup), this attaches to the resulting + TracerProvider so the exact same setup (sampler, resource, instrumented + libraries) is exercised. Otherwise, it configures one itself via + `configure_opentelemetry()` so the fixture also works standalone. + + A `SimpleSpanProcessor` is used instead of the `BatchSpanProcessor` used for real + exports, so spans show up as soon as they end instead of on a batching interval. + """ + provider = trace.get_tracer_provider() + exporter = InMemorySpanExporter() + + if not isinstance(provider, TracerProvider): + # No app under test has configured OpenTelemetry yet, so do it here, wiring + # up the in-memory exporter directly instead of the default OTLP exporter - + # this avoids pointless connection attempts against a collector in tests. + configure_opentelemetry( + service_name=service_name, + config=OpenTelemetryConfig(enable_opentelemetry=True), + span_processor=SimpleSpanProcessor(exporter), + ) + else: + # OpenTelemetry has already been configured (e.g. by the app under test), + # so attach to its existing TracerProvider instead of replacing it - + # OpenTelemetry only allows the global TracerProvider to be set once. + # Detaching after the test is not possible, as there's no stable public API for that + provider.add_span_processor(SimpleSpanProcessor(exporter)) + + yield OpenTelemetryFixture(exporter=exporter) + + +def get_otel_provider_fixture( + scope: PytestScope = "session", name: str = "otel_provider" +): + """Get a fixture with desired scope and name that sets up span capturing. + + By default, the session scope is used since only one `TracerProvider` can be + configured per process. + """ + return pytest.fixture(_otel_provider_fixture, scope=scope, name=name) + + +otel_provider_fixture = get_otel_provider_fixture() + + +def _otel_fixture( + otel_provider: OpenTelemetryFixture, +) -> Generator[OpenTelemetryFixture, None, None]: + """Fixture function that gets a clean slate of captured spans for a single test.""" + otel_provider.reset() + yield otel_provider + otel_provider.reset() + + +def get_otel_fixture(scope: PytestScope = "function", name: str = "otel"): + """Get a fixture with desired scope and name for asserting on emitted spans. + + By default, the function scope is used so captured spans don't leak between + tests, while the session scope is used for the underlying span capturing setup. + """ + return pytest.fixture(_otel_fixture, scope=scope, name=name) + + +otel_fixture = get_otel_fixture() diff --git a/tests/unit/test_opentelemetry_testutils.py b/tests/unit/test_opentelemetry_testutils.py new file mode 100644 index 00000000..5cf60888 --- /dev/null +++ b/tests/unit/test_opentelemetry_testutils.py @@ -0,0 +1,169 @@ +# Copyright 2021 - 2026 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""Tests for the in-memory span capturing test harness from `hexkit.opentelemetry.testutils`.""" + +import pytest +from opentelemetry import trace +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter +from opentelemetry.util._once import Once + +from hexkit.opentelemetry import OpenTelemetryConfig, configure_opentelemetry +from hexkit.opentelemetry.testutils import ( + _otel_fixture, + _otel_provider_fixture, + otel_fixture, # noqa: F401 + otel_provider_fixture, # noqa: F401 +) + +SERVICE_NAME = "test-service" + + +@pytest.fixture +def reset_global_tracer_provider(monkeypatch: pytest.MonkeyPatch): + """Give a test a clean slate to configure its own global TracerProvider. + + OpenTelemetry only allows `set_tracer_provider()` to succeed once per process (an + internal `Once` guards it), so tests that configure a TracerProvider themselves + need to reset that guard first, and restore it afterward, to stay isolated from + each other and from the session-scoped `otel_provider` fixture. + """ + monkeypatch.setattr(trace, "_TRACER_PROVIDER", None) + monkeypatch.setattr(trace, "_TRACER_PROVIDER_SET_ONCE", Once()) + + +def emit_span(name: str) -> None: + """Start and immediately end a span with the given name on the global tracer.""" + tracer = trace.get_tracer(__name__) + with tracer.start_as_current_span(name): + pass + + +def test_captures_emitted_spans(otel): + """Ensure spans emitted while the fixture is active show up immediately. + + Also implicitly checks that no span leaked in from a previous test. + """ + assert otel.get_span_names() == [] + + emit_span("do-thing") + + otel.assert_has_span("do-thing") + assert otel.get_span_names() == ["do-thing"] + + +def test_span_order_is_preserved(otel): + """Ensure spans are returned in the order they finished, not just any order.""" + assert otel.get_span_names() == [] + + emit_span("first") + emit_span("second") + emit_span("third") + + assert otel.get_span_names() == ["first", "second", "third"] + + +def test_assert_has_span_raises_with_useful_message(otel): + """Ensure a missing span fails with an assertion listing what was captured.""" + emit_span("known-span") + + with pytest.raises(AssertionError) as exc_info: + otel.assert_has_span("unknown-span") + + assert "unknown-span" in str(exc_info.value) + assert "known-span" in str(exc_info.value) + + +def test_reset_clears_captured_spans(otel): + """Ensure `reset()` drops all previously captured spans.""" + emit_span("to-be-cleared") + assert otel.get_span_names() == ["to-be-cleared"] + + otel.reset() + + assert otel.get_span_names() == [] + + +def test_standalone_provider_uses_in_memory_exporter(reset_global_tracer_provider): + """Ensure that, when nothing has configured OpenTelemetry yet, the fixture + configures its own TracerProvider wired to the in-memory exporter, never the real + OTLP exporter. + """ + assert not isinstance(trace.get_tracer_provider(), TracerProvider) + + provider_gen = _otel_provider_fixture(service_name=SERVICE_NAME) + fixture = next(provider_gen) + + assert isinstance(trace.get_tracer_provider(), TracerProvider) + + emit_span("standalone-span") + fixture.assert_has_span("standalone-span") + + provider_gen.close() + + +def test_attaches_to_already_configured_provider(reset_global_tracer_provider): + """Ensure that, if OpenTelemetry has already been configured, the fixture attaches + an in-memory exporter to that existing TracerProvider instead of replacing it - + OpenTelemetry only allows the global TracerProvider to be set once. + """ + own_exporter = InMemorySpanExporter() + configure_opentelemetry( + service_name=SERVICE_NAME, + config=OpenTelemetryConfig(enable_opentelemetry=True), + span_processor=SimpleSpanProcessor(own_exporter), + ) + existing_provider = trace.get_tracer_provider() + + provider_gen = _otel_provider_fixture(service_name=SERVICE_NAME) + fixture = next(provider_gen) + + # the provider was attached to, not replaced + assert trace.get_tracer_provider() is existing_provider + + emit_span("shared-span") + + # both the app's own exporter and the fixture's in-memory exporter see the span + fixture.assert_has_span("shared-span") + assert [span.name for span in own_exporter.get_finished_spans()] == ["shared-span"] + + provider_gen.close() + + +def test_function_scoped_fixture_resets_before_and_after(reset_global_tracer_provider): + """Ensure the function-scoped fixture hands back a clean slate on entry and cleans + up the spans captured during the test on exit. + """ + provider_gen = _otel_provider_fixture(service_name=SERVICE_NAME) + provider_fixture = next(provider_gen) + + emit_span("leftover-from-before") + assert provider_fixture.get_span_names() == ["leftover-from-before"] + + test_gen = _otel_fixture(provider_fixture) + fixture = next(test_gen) + assert fixture.get_span_names() == [] # reset on entry + + emit_span("during-test") + assert fixture.get_span_names() == ["during-test"] + + with pytest.raises(StopIteration): + next(test_gen) # drive the generator past its final `reset()` on exit + assert provider_fixture.get_span_names() == [] # reset on exit + + provider_gen.close()