diff --git a/jetstream/cli.py b/jetstream/cli.py index 6e5225d7..9a937f3a 100644 --- a/jetstream/cli.py +++ b/jetstream/cli.py @@ -1121,6 +1121,44 @@ def export_statistics_to_json(project_id, dataset_id, bucket, experiment_slug): export_statistics_tables(project_id, dataset_id, bucket, slug) +@cli.command() +@project_id_option() +@dataset_id_option() +@bucket_option +@experiment_slug_option +@config_repos_option +@private_config_repos_option +def export_metadata_to_json( + project_id, dataset_id, bucket, experiment_slug, config_repos, private_config_repos +): + """Export all tables as JSON (optionally to a GCS bucket).""" + config_getter = ConfigLoader.with_configs_from(config_repos).with_configs_from( + private_config_repos, is_private=True + ) + for slug in experiment_slug: + experiments = ExperimentCollection.from_experimenter(slug=slug).experiments + if experiments == []: + print(f"No experiment with slug {slug} in Experimenter.") + continue + + # run_configs = self._experiments_to_configs(experiment_slug, config_getter) + experiment = experiments[0] + + client = BigQueryClient(project_id, dataset_id) + first_updated = client.experiment_table_first_updated(experiment.normandy_slug) + + # get the configs that were the most recent when the experiment was last updated + config_collection = config_getter.configs.as_of(first_updated) + spec = AnalysisSpec.default_for_experiment(experiment, config_collection) + + if external_spec := config_collection.spec_for_experiment(experiment.normandy_slug): + spec.merge(external_spec) + + config = spec.resolve(experiment, config_collection) + + export_metadata(config, bucket, project_id, None) + + @cli.command() @log_project_id_option @log_dataset_id_option diff --git a/jetstream/metadata.py b/jetstream/metadata.py index e680deed..bb25cab3 100644 --- a/jetstream/metadata.py +++ b/jetstream/metadata.py @@ -126,15 +126,20 @@ def export_metadata( metadata = ExperimentMetadata.from_config(config, analysis_start_time) - storage_client = storage.Client(project_id) - bucket = storage_client.get_bucket(bucket_name) - target_file = f"metadata_{bq_normalize_name(config.experiment.normandy_slug)}" - target_path = "metadata" - blob = bucket.blob(f"{target_path}/{target_file}.json") - - logger.info(f"Uploading {target_file} to {bucket_name}/{target_path}.") - - blob.upload_from_string( - data=metadata.model_dump_json(), - content_type="application/json", - ) + logger.info(metadata.model_dump_json()) + + if bucket_name: + storage_client = storage.Client(project_id) + bucket = storage_client.get_bucket(bucket_name) + target_file = f"metadata_{bq_normalize_name(config.experiment.normandy_slug)}" + target_path = "metadata" + blob = bucket.blob(f"{target_path}/{target_file}.json") + + logger.info(f"Uploading {target_file} to {bucket_name}/{target_path}.") + + blob.upload_from_string( + data=metadata.model_dump_json(), + content_type="application/json", + ) + else: + logger.info("No bucket_name provided, skipping upload...") diff --git a/pyproject.toml b/pyproject.toml index b15b366e..fbc5dd7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "mozilla-jetstream" # This project does not issue regular releases, only when there # are changes that would be meaningful to our (few) dependents. -version = "2026.1.1" +version = "2026.3.1" authors = [{ name = "Mozilla Corporation", email = "fx-data-dev@mozilla.org" }] description = "Runs a thing that analyzes experiments" readme = "README.md" diff --git a/requirements.in b/requirements.in index 42db8533..e9181c89 100644 --- a/requirements.in +++ b/requirements.in @@ -14,18 +14,16 @@ attrs==25.4.0 # mozilla-jetstream # mozilla-metric-config-parser # referencing -cachetools==7.0.1 +cachetools==7.0.2 # via tox -cattrs==25.3.0 +cattrs==26.1.0 # via # mozilla-jetstream # mozilla-metric-config-parser -certifi==2026.1.4 +certifi==2026.2.25 # via requests cffi==2.0.0 # via cryptography -chardet==5.2.0 - # via tox charset-normalizer==3.4.4 # via requests click==8.3.1 @@ -64,10 +62,11 @@ distributed==2026.1.2 # via dask execnet==2.1.2 # via pytest-xdist -faker==40.4.0 +faker==40.5.1 # via polyfactory -filelock==3.24.2 +filelock==3.25.0 # via + # python-discovery # tox # virtualenv fonttools==4.61.1 @@ -84,7 +83,7 @@ gitpython==3.1.46 # via # mozilla-jetstream # mozilla-metric-config-parser -google-api-core[grpc]==2.29.0 +google-api-core[grpc]==2.30.0 # via # google-cloud-artifact-registry # google-cloud-bigquery @@ -107,7 +106,7 @@ google-cloud-bigquery==3.40.1 # via # mozanalysis # mozilla-jetstream -google-cloud-bigquery-storage==2.36.1 +google-cloud-bigquery-storage==2.36.2 # via # mozanalysis # mozilla-jetstream @@ -205,7 +204,7 @@ mypy==1.19.1 # via mozilla-jetstream mypy-extensions==1.1.0 # via mypy -narwhals==2.16.0 +narwhals==2.17.0 # via # formulaic # marginaleffects @@ -255,6 +254,7 @@ pillow==12.1.1 # via matplotlib platformdirs==4.9.2 # via + # python-discovery # tox # virtualenv plotnine==0.15.3 @@ -331,7 +331,9 @@ python-dateutil==2.9.0.post0 # google-cloud-bigquery # matplotlib # pandas -pytz==2025.2 +python-discovery==1.1.0 + # via virtualenv +pytz==2026.1.post1 # via # mozilla-jetstream # mozilla-metric-config-parser @@ -358,13 +360,13 @@ rpds-py==0.30.0 # referencing rsa==4.9.1 # via google-auth -ruff==0.15.1 +ruff==0.15.4 # via # mozilla-jetstream # pytest-ruff scikit-learn==1.8.0 # via mozilla-jetstream -scipy==1.17.0 +scipy==1.17.1 # via # formulaic # marginaleffects @@ -377,7 +379,7 @@ secretstorage==3.5.0 # via mozanalysis six==1.17.0 # via python-dateutil -smart-open[gcs]==7.5.0 +smart-open[gcs]==7.5.1 # via mozilla-jetstream smmap==5.0.2 # via gitdb @@ -403,11 +405,11 @@ toolz==1.1.0 # partd tornado==6.5.4 # via distributed -tox==4.36.1 +tox==4.47.1 # via mozilla-jetstream types-futures==3.3.8 # via mozilla-jetstream -types-protobuf==6.32.1.20251210 +types-protobuf==6.32.1.20260221 # via mozilla-jetstream types-pytz==2025.2.0.20251108 # via mozilla-jetstream @@ -442,7 +444,7 @@ urllib3==2.6.3 # distributed # requests # types-requests -virtualenv==20.37.0 +virtualenv==21.1.0 # via tox wrapt==2.1.1 # via diff --git a/requirements.txt b/requirements.txt index a6ca63cd..108c434c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,21 +20,21 @@ attrs==25.4.0 \ # mozanalysis # mozilla-metric-config-parser # referencing -cachetools==7.0.1 \ - --hash=sha256:8f086515c254d5664ae2146d14fc7f65c9a4bce75152eb247e5a9c5e6d7b2ecf \ - --hash=sha256:e31e579d2c5b6e2944177a0397150d312888ddf4e16e12f1016068f0c03b8341 +cachetools==7.0.2 \ + --hash=sha256:7e7f09a4ca8b791d8bb4864afc71e9c17e607a28e6839ca1a644253c97dbeae0 \ + --hash=sha256:938dcad184827c5e94928c4fd5526e2b46692b7fb1ae94472da9131d0299343c # via # -r requirements.in # tox -cattrs==25.3.0 \ - --hash=sha256:1ac88d9e5eda10436c4517e390a4142d88638fe682c436c93db7ce4a277b884a \ - --hash=sha256:9896e84e0a5bf723bc7b4b68f4481785367ce07a8a02e7e9ee6eb2819bc306ff +cattrs==26.1.0 \ + --hash=sha256:d1e0804c42639494d469d08d4f26d6b9de9b8ab26b446db7b5f8c2e97f7c3096 \ + --hash=sha256:fa239e0f0ec0715ba34852ce813986dfed1e12117e209b816ab87401271cdd40 # via # -r requirements.in # mozilla-metric-config-parser -certifi==2026.1.4 \ - --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ - --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 +certifi==2026.2.25 \ + --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ + --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 # via # -r requirements.in # requests @@ -126,12 +126,6 @@ cffi==2.0.0 \ # via # -r requirements.in # cryptography -chardet==5.2.0 \ - --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ - --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 - # via - # -r requirements.in - # tox charset-normalizer==3.4.4 \ --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ @@ -544,17 +538,18 @@ execnet==2.1.2 \ # via # -r requirements.in # pytest-xdist -faker==40.4.0 \ - --hash=sha256:486d43c67ebbb136bc932406418744f9a0bdf2c07f77703ea78b58b77e9aa443 \ - --hash=sha256:76f8e74a3df28c3e2ec2caafa956e19e37a132fdc7ea067bc41783affcfee364 +faker==40.5.1 \ + --hash=sha256:70222361cd82aa10cb86066d1a4e8f47f2bcdc919615c412045a69c4e6da0cd3 \ + --hash=sha256:c69640c1e13bad49b4bcebcbf1b52f9f1a872b6ea186c248ada34d798f1661bf # via # -r requirements.in # polyfactory -filelock==3.24.2 \ - --hash=sha256:667d7dc0b7d1e1064dd5f8f8e80bdac157a6482e8d2e02cd16fd3b6b33bd6556 \ - --hash=sha256:c22803117490f156e59fafce621f0550a7a853e2bbf4f87f112b11d469b6c81b +filelock==3.25.0 \ + --hash=sha256:5ccf8069f7948f494968fc0713c10e5c182a9c9d9eef3a636307a20c2490f047 \ + --hash=sha256:8f00faf3abf9dc730a1ffe9c354ae5c04e079ab7d3a683b7c32da5dd05f26af3 # via # -r requirements.in + # python-discovery # tox # virtualenv fonttools==4.61.1 \ @@ -636,9 +631,9 @@ gitpython==3.1.46 \ # via # -r requirements.in # mozilla-metric-config-parser -google-api-core[grpc]==2.29.0 \ - --hash=sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7 \ - --hash=sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9 +google-api-core[grpc]==2.30.0 \ + --hash=sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b \ + --hash=sha256:80be49ee937ff9aba0fd79a6eddfde35fe658b9953ab9b79c57dd7061afa8df5 # via # -r requirements.in # google-cloud-artifact-registry @@ -669,9 +664,9 @@ google-cloud-bigquery==3.40.1 \ # via # -r requirements.in # mozanalysis -google-cloud-bigquery-storage==2.36.1 \ - --hash=sha256:99ad6b8810d028f0cf368ea0cc54b3cda20e856f05eb4cda51f1db2a70692286 \ - --hash=sha256:fd3917584a41f7a9d9c633b31ff43103869b108224e8a4b765537eb1ea83148c +google-cloud-bigquery-storage==2.36.2 \ + --hash=sha256:823a73db0c4564e8ad3eedcfd5049f3d5aa41775267863b5627211ec36be2dbf \ + --hash=sha256:ad49d8c09ad6cd82da4efe596fcfcdbc1458bf05b93915e3c5c00f1e700ae128 # via # -r requirements.in # mozanalysis @@ -1380,9 +1375,9 @@ mypy-extensions==1.1.0 \ # via # -r requirements.in # mypy -narwhals==2.16.0 \ - --hash=sha256:155bb45132b370941ba0396d123cf9ed192bf25f39c4cea726f2da422ca4e145 \ - --hash=sha256:846f1fd7093ac69d63526e50732033e86c30ea0026a44d9b23991010c7d1485d +narwhals==2.17.0 \ + --hash=sha256:2ac5307b7c2b275a7d66eeda906b8605e3d7a760951e188dcfff86e8ebe083dd \ + --hash=sha256:ebd5bc95bcfa2f8e89a8ac09e2765a63055162837208e67b42d6eeb6651d5e67 # via # -r requirements.in # formulaic @@ -1672,6 +1667,7 @@ platformdirs==4.9.2 \ --hash=sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291 # via # -r requirements.in + # python-discovery # tox # virtualenv plotnine==0.15.3 \ @@ -2021,9 +2017,15 @@ python-dateutil==2.9.0.post0 \ # google-cloud-bigquery # matplotlib # pandas -pytz==2025.2 \ - --hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 \ - --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 +python-discovery==1.1.0 \ + --hash=sha256:447941ba1aed8cc2ab7ee3cb91be5fc137c5bdbb05b7e6ea62fbdcb66e50b268 \ + --hash=sha256:a162893b8809727f54594a99ad2179d2ede4bf953e12d4c7abc3cc9cdbd1437b + # via + # -r requirements.in + # virtualenv +pytz==2026.1.post1 \ + --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ + --hash=sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a # via # -r requirements.in # mozilla-metric-config-parser @@ -2248,25 +2250,25 @@ rsa==4.9.1 \ # via # -r requirements.in # google-auth -ruff==0.15.1 \ - --hash=sha256:1d83466455fdefe60b8d9c8df81d3c1bbb2115cede53549d3b522ce2bc703899 \ - --hash=sha256:1fe5c41ab43e3a06778844c586251eb5a510f67125427625f9eb2b9526535779 \ - --hash=sha256:3dd86dccb83cd7d4dcfac303ffc277e6048600dfc22e38158afa208e8bf94a1f \ - --hash=sha256:4ab064052c31dddada35079901592dfba2e05f5b1e43af3954aafcbc1096a5b2 \ - --hash=sha256:518f9af03bfc33c03bdb4cb63fabc935341bb7f54af500f92ac309ecfbba6330 \ - --hash=sha256:5631c940fe9fe91f817a4c2ea4e81f47bee3ca4aa646134a24374f3c19ad9454 \ - --hash=sha256:5ff7d5f0f88567850f45081fac8f4ec212be8d0b963e385c3f7d0d2eb4899416 \ - --hash=sha256:660975d9cb49b5d5278b12b03bb9951d554543a90b74ed5d366b20e2c57c2098 \ - --hash=sha256:66a6dd6df4d80dc382c6484f8ce1bcceb55c32e9f27a8b94c32f6c7331bf14fb \ - --hash=sha256:68138a4ba184b4691ccdc39f7795c66b3c68160c586519e7e8444cf5a53e1b4c \ - --hash=sha256:6a4a42cbb8af0bda9bcd7606b064d7c0bc311a88d141d02f78920be6acb5aa83 \ - --hash=sha256:92c92b003e9d4f7fbd33b1867bb15a1b785b1735069108dfc23821ba045b29bc \ - --hash=sha256:939c995e9277e63ea632cc8d3fae17aa758526f49a9a850d2e7e758bfef46602 \ - --hash=sha256:a9457e3c3291024866222b96108ab2d8265b477e5b1534c7ddb1810904858d16 \ - --hash=sha256:b101ed7cf4615bda6ffe65bdb59f964e9f4a0d3f85cbf0e54f0ab76d7b90228a \ - --hash=sha256:c590fe13fb57c97141ae975c03a1aedb3d3156030cabd740d6ff0b0d601e203f \ - --hash=sha256:c820fef9dd5d4172a6570e5721704a96c6679b80cf7be41659ed439653f62336 \ - --hash=sha256:da79f4d6a826caaea95de0237a67e33b81e6ec2e25fc7e1993a4015dffca7c61 +ruff==0.15.4 \ + --hash=sha256:04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f \ + --hash=sha256:291258c917539e18f6ba40482fe31d6f5ac023994ee11d7bdafd716f2aab8a68 \ + --hash=sha256:3412195319e42d634470cc97aa9803d07e9d5c9223b99bcb1518f0c725f26ae1 \ + --hash=sha256:3f1c4893841ff2d54cbda1b2860fa3260173df5ddd7b95d370186f8a5e66a4ac \ + --hash=sha256:3f83c45911da6f2cd5936c436cf86b9f09f09165f033a99dcf7477e34041cbc3 \ + --hash=sha256:451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec \ + --hash=sha256:5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992 \ + --hash=sha256:60d5177e8cfc70e51b9c5fad936c634872a74209f934c1e79107d11787ad5453 \ + --hash=sha256:65594a2d557d4ee9f02834fcdf0a28daa8b3b9f6cb2cb93846025a36db47ef22 \ + --hash=sha256:820b8766bd65503b6c30aaa6331e8ef3a6e564f7999c844e9a547c40179e440a \ + --hash=sha256:917cc68503357021f541e69b35361c99387cdbbf99bd0ea4aa6f28ca99ff5338 \ + --hash=sha256:a1810931c41606c686bae8b5b9a8072adac2f611bb433c0ba476acba17a332e0 \ + --hash=sha256:a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba \ + --hash=sha256:a8f157f2e583c513c4f5f896163a93198297371f34c04220daf40d133fdd4f7f \ + --hash=sha256:b2496488bdfd3732747558b6f95ae427ff066d1fcd054daf75f5a50674411e75 \ + --hash=sha256:c9fb74bab47139c1751f900f857fa503987253c3ef89129b24ed375e72873e85 \ + --hash=sha256:e9737c8161da79fd7cfec19f1e35620375bd8b2a50c3e77fa3d2c16f574105cc \ + --hash=sha256:f80c98765949c518142b3a50a5db89343aa90f2c2bf7799de9986498ae6176db # via # -r requirements.in # pytest-ruff @@ -2309,68 +2311,68 @@ scikit-learn==1.8.0 \ --hash=sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4 \ --hash=sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd # via -r requirements.in -scipy==1.17.0 \ - --hash=sha256:00fb5f8ec8398ad90215008d8b6009c9db9fa924fd4c7d6be307c6f945f9cd73 \ - --hash=sha256:031121914e295d9791319a1875444d55079885bbae5bdc9c5e0f2ee5f09d34ff \ - --hash=sha256:0937a0b0d8d593a198cededd4c439a0ea216a3f36653901ea1f3e4be949056f8 \ - --hash=sha256:0cf46c8013fec9d3694dc572f0b54100c28405d55d3e2cb15e2895b25057996e \ - --hash=sha256:0d5018a57c24cb1dd828bcf51d7b10e65986d549f52ef5adb6b4d1ded3e32a57 \ - --hash=sha256:130d12926ae34399d157de777472bf82e9061c60cc081372b3118edacafe1d00 \ - --hash=sha256:13c4096ac6bc31d706018f06a49abe0485f96499deb82066b94d19b02f664209 \ - --hash=sha256:13e861634a2c480bd237deb69333ac79ea1941b94568d4b0efa5db5e263d4fd1 \ - --hash=sha256:1f9586a58039d7229ce77b52f8472c972448cded5736eaf102d5658bbac4c269 \ - --hash=sha256:1ff269abf702f6c7e67a4b7aad981d42871a11b9dd83c58d2d2ea624efbd1088 \ - --hash=sha256:255c0da161bd7b32a6c898e7891509e8a9289f0b1c6c7d96142ee0d2b114c2ea \ - --hash=sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e \ - --hash=sha256:272a9f16d6bb4667e8b50d25d71eddcc2158a214df1b566319298de0939d2ab7 \ - --hash=sha256:2abd71643797bd8a106dff97894ff7869eeeb0af0f7a5ce02e4227c6a2e9d6fd \ - --hash=sha256:2b531f57e09c946f56ad0b4a3b2abee778789097871fc541e267d2eca081cff1 \ - --hash=sha256:30509da9dbec1c2ed8f168b8d8aa853bc6723fede1dbc23c7d43a56f5ab72a67 \ - --hash=sha256:33af70d040e8af9d5e7a38b5ed3b772adddd281e3062ff23fec49e49681c38cf \ - --hash=sha256:357ca001c6e37601066092e7c89cca2f1ce74e2a520ca78d063a6d2201101df2 \ - --hash=sha256:3625c631a7acd7cfd929e4e31d2582cf00f42fcf06011f59281271746d77e061 \ - --hash=sha256:363ad4ae2853d88ebcde3ae6ec46ccca903ea9835ee8ba543f12f575e7b07e4e \ - --hash=sha256:40052543f7bbe921df4408f46003d6f01c6af109b9e2c8a66dd1cf6cf57f7d5d \ - --hash=sha256:423ca1f6584fc03936972b5f7c06961670dbba9f234e71676a7c7ccf938a0d61 \ - --hash=sha256:474da16199f6af66601a01546144922ce402cb17362e07d82f5a6cf8f963e449 \ - --hash=sha256:4e00562e519c09da34c31685f6acc3aa384d4d50604db0f245c14e1b4488bfa2 \ - --hash=sha256:5194c445d0a1c7a6c1a4a4681b6b7c71baad98ff66d96b949097e7513c9d6742 \ - --hash=sha256:5fb10d17e649e1446410895639f3385fd2bf4c3c7dfc9bea937bddcbc3d7b9ba \ - --hash=sha256:65ec32f3d32dfc48c72df4291345dae4f048749bc8d5203ee0a3f347f96c5ce6 \ - --hash=sha256:6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 \ - --hash=sha256:6e886000eb4919eae3a44f035e63f0fd8b651234117e8f6f29bad1cd26e7bc45 \ - --hash=sha256:7204fddcbec2fe6598f1c5fdf027e9f259106d05202a959a9f1aecf036adc9f6 \ - --hash=sha256:819fc26862b4b3c73a60d486dbb919202f3d6d98c87cf20c223511429f2d1a97 \ - --hash=sha256:8547e7c57f932e7354a2319fab613981cde910631979f74c9b542bb167a8b9db \ - --hash=sha256:85b0ac3ad17fa3be50abd7e69d583d98792d7edc08367e01445a1e2076005379 \ - --hash=sha256:87b411e42b425b84777718cc41516b8a7e0795abfa8e8e1d573bf0ef014f0812 \ - --hash=sha256:88c22af9e5d5a4f9e027e26772cc7b5922fab8bcc839edb3ae33de404feebd9e \ - --hash=sha256:9244608d27eafe02b20558523ba57f15c689357c85bdcfe920b1828750aa26eb \ - --hash=sha256:979c3a0ff8e5ba254d45d59ebd38cde48fce4f10b5125c680c7a4bfe177aab07 \ - --hash=sha256:9eeb9b5f5997f75507814ed9d298ab23f62cf79f5a3ef90031b1ee2506abdb5b \ - --hash=sha256:9fad7d3578c877d606b1150135c2639e9de9cecd3705caa37b66862977cc3e72 \ - --hash=sha256:a38c3337e00be6fd8a95b4ed66b5d988bac4ec888fd922c2ea9fe5fb1603dd67 \ - --hash=sha256:aabf057c632798832f071a8dde013c2e26284043934f53b00489f1773b33527e \ - --hash=sha256:c17514d11b78be8f7e6331b983a65a7f5ca1fd037b95e27b280921fe5606286a \ - --hash=sha256:c5e8647f60679790c2f5c76be17e2e9247dc6b98ad0d3b065861e082c56e078d \ - --hash=sha256:cacbaddd91fcffde703934897c5cd2c7cb0371fac195d383f4e1f1c5d3f3bd04 \ - --hash=sha256:d7425fcafbc09a03731e1bc05581f5fad988e48c6a861f441b7ab729a49a55ea \ - --hash=sha256:dac97a27520d66c12a34fd90a4fe65f43766c18c0d6e1c0a80f114d2260080e4 \ - --hash=sha256:dbf133ced83889583156566d2bdf7a07ff89228fe0c0cb727f777de92092ec6b \ - --hash=sha256:e8c0b331c2c1f531eb51f1b4fc9ba709521a712cce58f1aa627bc007421a5306 \ - --hash=sha256:eb2651271135154aa24f6481cbae5cc8af1f0dd46e6533fb7b56aa9727b6a232 \ - --hash=sha256:ebb7446a39b3ae0fe8f416a9a3fdc6fba3f11c634f680f16a239c5187bc487c0 \ - --hash=sha256:ec0827aa4d36cb79ff1b81de898e948a51ac0b9b1c43e4a372c0508c38c0f9a3 \ - --hash=sha256:edce1a1cf66298cccdc48a1bdf8fb10a3bf58e8b58d6c3883dd1530e103f87c0 \ - --hash=sha256:eec3842ec9ac9de5917899b277428886042a93db0b227ebbe3a333b64ec7643d \ - --hash=sha256:ef28d815f4d2686503e5f4f00edc387ae58dfd7a2f42e348bb53359538f01558 \ - --hash=sha256:f2a4942b0f5f7c23c7cd641a0ca1955e2ae83dedcff537e3a0259096635e186b \ - --hash=sha256:f3cd947f20fe17013d401b64e857c6b2da83cae567adbb75b9dcba865abc66d8 \ - --hash=sha256:f603d8a5518c7426414d1d8f82e253e454471de682ce5e39c29adb0df1efb86b \ - --hash=sha256:f7df7941d71314e60a481e02d5ebcb3f0185b8d799c70d03d8258f6c80f3d467 \ - --hash=sha256:f9eb55bb97d00f8b7ab95cb64f873eb0bf54d9446264d9f3609130381233483f \ - --hash=sha256:fc02c37a5639ee67d8fb646ffded6d793c06c5622d36b35cfa8fe5ececb8f042 \ - --hash=sha256:fe508b5690e9eaaa9467fc047f833af58f1152ae51a0d0aed67aa5801f4dd7d6 +scipy==1.17.1 \ + --hash=sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0 \ + --hash=sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458 \ + --hash=sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118 \ + --hash=sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39 \ + --hash=sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e \ + --hash=sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6 \ + --hash=sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec \ + --hash=sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21 \ + --hash=sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1 \ + --hash=sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6 \ + --hash=sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce \ + --hash=sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8 \ + --hash=sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448 \ + --hash=sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19 \ + --hash=sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b \ + --hash=sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87 \ + --hash=sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4 \ + --hash=sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9 \ + --hash=sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b \ + --hash=sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082 \ + --hash=sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 \ + --hash=sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87 \ + --hash=sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c \ + --hash=sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369 \ + --hash=sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad \ + --hash=sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f \ + --hash=sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c \ + --hash=sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475 \ + --hash=sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd \ + --hash=sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866 \ + --hash=sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d \ + --hash=sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6 \ + --hash=sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb \ + --hash=sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca \ + --hash=sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0 \ + --hash=sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca \ + --hash=sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d \ + --hash=sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee \ + --hash=sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4 \ + --hash=sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717 \ + --hash=sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49 \ + --hash=sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2 \ + --hash=sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a \ + --hash=sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350 \ + --hash=sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950 \ + --hash=sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b \ + --hash=sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086 \ + --hash=sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444 \ + --hash=sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068 \ + --hash=sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff \ + --hash=sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a \ + --hash=sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50 \ + --hash=sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696 \ + --hash=sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21 \ + --hash=sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c \ + --hash=sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484 \ + --hash=sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118 \ + --hash=sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3 \ + --hash=sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea \ + --hash=sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293 \ + --hash=sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76 # via # -r requirements.in # formulaic @@ -2392,9 +2394,9 @@ six==1.17.0 \ # via # -r requirements.in # python-dateutil -smart-open[gcs]==7.5.0 \ - --hash=sha256:87e695c5148bbb988f15cec00971602765874163be85acb1c9fb8abc012e6599 \ - --hash=sha256:f394b143851d8091011832ac8113ea4aba6b92e6c35f6e677ddaaccb169d7cb9 +smart-open[gcs]==7.5.1 \ + --hash=sha256:3e07cbbd9c8a908bcb8e25d48becf1a5cbb4886fa975e9f34c672ed171df2318 \ + --hash=sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7 # via -r requirements.in smmap==5.0.2 \ --hash=sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5 \ @@ -2491,17 +2493,17 @@ tornado==6.5.4 \ # via # -r requirements.in # distributed -tox==4.36.1 \ - --hash=sha256:085ddf2e6ebd2a5be04ae8f4a2c6422a7994a4702b3c187edc4e99f1e7ccdc2a \ - --hash=sha256:1a26afa08ff0a527e2055959c99907058328aaa5134fcea07ad2ae1dbce1a09a +tox==4.47.1 \ + --hash=sha256:80b3d9157cff65b6b514b01840d33cf72de0fc9117cf18ef86531407d11d24d8 \ + --hash=sha256:b2de8fc90157f357754082784c2457c542d797d93b3e8889682d7406db98afc4 # via -r requirements.in types-futures==3.3.8 \ --hash=sha256:6fe8ccc2c2af7ef2fdd9bf73eab6d617074f09f30ad7d373510b4043d39c42de \ --hash=sha256:d6e97ec51d56b96debfbf1dea32ebec22c1687f16d2547ea0a34b48db45df205 # via -r requirements.in -types-protobuf==6.32.1.20251210 \ - --hash=sha256:2641f78f3696822a048cfb8d0ff42ccd85c25f12f871fbebe86da63793692140 \ - --hash=sha256:c698bb3f020274b1a2798ae09dc773728ce3f75209a35187bd11916ebfde6763 +types-protobuf==6.32.1.20260221 \ + --hash=sha256:6d5fb060a616bfb076cbb61b4b3c3969f5fc8bec5810f9a2f7e648ee5cbcbf6e \ + --hash=sha256:da7cdd947975964a93c30bfbcc2c6841ee646b318d3816b033adc2c4eb6448e4 # via -r requirements.in types-pytz==2025.2.0.20251108 \ --hash=sha256:0f1c9792cab4eb0e46c52f8845c8f77cf1e313cb3d68bf826aa867fe4717d91c \ @@ -2562,9 +2564,9 @@ urllib3==2.6.3 \ # distributed # requests # types-requests -virtualenv==20.37.0 \ - --hash=sha256:5d3951c32d57232ae3569d4de4cc256c439e045135ebf43518131175d9be435d \ - --hash=sha256:6f7e2064ed470aa7418874e70b6369d53b66bcd9e9fd5389763e96b6c94ccb7c +virtualenv==21.1.0 \ + --hash=sha256:164f5e14c5587d170cf98e60378eb91ea35bf037be313811905d3a24ea33cc07 \ + --hash=sha256:1990a0188c8f16b6b9cf65c9183049007375b26aad415514d377ccacf1e4fb44 # via # -r requirements.in # tox