From 0fff232b963f48b2edb33654d318b4ae0e861b73 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 20 May 2025 08:31:18 -0400 Subject: [PATCH 01/20] Add support for IHGIS extract submission --- src/ipumspy/api/extract.py | 125 ++++++++++++++++++++++++++++++------- tests/test_api.py | 43 ++++++++++--- 2 files changed, 137 insertions(+), 31 deletions(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index 013da4a..5f3aa3e 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -148,6 +148,26 @@ class Dataset(IpumsObject): """ IPUMS dataset object to include in an ``AggregateDataExtract`` object. + Args: + name: IPUMS dataset name + """ + + name: str + """IPUMS dataset name""" + + def build(self): + """Format dataset information for API Extract submission""" + built_dataset = self.__dict__.copy() + # don't repeat the dataset name + built_dataset.pop("name") + + return built_dataset + +@dataclass +class NhgisDataset(Dataset): + """ + IPUMS dataset object to include in an ``AggregateDataExtract`` object. + Args: name: IPUMS dataset name data_tables: IPUMS data tables to extract from this dataset @@ -182,7 +202,35 @@ def build(self): built_dataset["breakdownValues"] = built_dataset.pop("breakdown_values") return built_dataset + +@dataclass +class IhgisDataset(Dataset): + """ + IPUMS dataset object to include in an ``AggregateDataExtract`` object. + Args: + name: IPUMS dataset name + data_tables: IPUMS data tables to extract from this dataset + tabulation_geographies: Geographic level(s) at which to obtain data for this dataset + """ + + name: str + """IPUMS dataset name""" + data_tables: List[str] + """IPUMS data tables to extract from this dataset""" + tabulation_geographies: List[str] + """Geographic level(s) at which to obtain data for this dataset""" + + def build(self): + """Format dataset information for API Extract submission""" + built_dataset = self.__dict__.copy() + # don't repeat the dataset name + built_dataset.pop("name") + # adhere to API schema camelCase convention + built_dataset["dataTables"] = built_dataset.pop("data_tables") + built_dataset["tabulationGeographies"] = built_dataset.pop("tabulation_geographies") + + return built_dataset @dataclass class TimeSeriesTable(IpumsObject): @@ -269,10 +317,10 @@ def _unpack_tuv_dict(dct: dict) -> List[TimeUseVariable]: return tuvs -def _unpack_dataset_dict(dct: dict) -> List[Dataset]: +def _unpack_nhgis_dataset_dict(dct: dict) -> List[NhgisDataset]: datasets = [] for dataset in dct.keys(): - dataset_obj = Dataset( + dataset_obj = NhgisDataset( name=dataset, data_tables=dct[dataset]["dataTables"], geog_levels=dct[dataset]["geogLevels"], @@ -284,6 +332,25 @@ def _unpack_dataset_dict(dct: dict) -> List[Dataset]: datasets.append(dataset_obj) return datasets +def _unpack_ihgis_dataset_dict(dct: dict) -> List[IhgisDataset]: + datasets = [] + for dataset in dct.keys(): + dataset_obj = IhgisDataset( + name=dataset, + data_tables=dct[dataset]["dataTables"], + tabulation_geographies=dct[dataset]["tabulationGeographies"], + ) + datasets.append(dataset_obj) + return datasets + +def _unpack_dataset_dict(dct: dict) -> List[Dataset]: + datasets = [] + for dataset in dct.keys(): + dataset_obj = Dataset( + name=dataset, + ) + datasets.append(dataset_obj) + return datasets def _unpack_tst_dict(dct: dict) -> List[TimeSeriesTable]: time_series_tables = [] @@ -313,6 +380,7 @@ def _get_collection_type(collection: str) -> str: "nhis": "microdata", "meps": "microdata", "nhgis": "aggregate_data", + "ihgis": "aggregate_data" } return collection_types[collection] @@ -436,6 +504,12 @@ def _validate_list_args(self, list_arg, arg_obj): elif isinstance(list_arg, dict) and arg_obj is TimeUseVariable: args = _unpack_tuv_dict(list_arg) return args + elif isinstance(list_arg, dict) and arg_obj is NhgisDataset: + args = _unpack_nhgis_dataset_dict(list_arg) + return args + elif isinstance(list_arg, dict) and arg_obj is IhgisDataset: + args = _unpack_ihgis_dataset_dict(list_arg) + return args elif isinstance(list_arg, dict) and arg_obj is Dataset: args = _unpack_dataset_dict(list_arg) return args @@ -726,26 +800,27 @@ def __init__( self.collection_type = self.collection_type """IPUMS collection type""" - self.datasets = self._validate_list_args(datasets, Dataset) + if collection == "nhgis": + self.datasets = self._validate_list_args(datasets, NhgisDataset) + self.data_format = data_format + self.geographic_extents = geographic_extents + self.breakdown_and_data_type_layout = breakdown_and_data_type_layout + self.tst_layout = tst_layout + elif collection == "ihgis": + self.datasets = self._validate_list_args(datasets, IhgisDataset) + else: + self.datasets = self._validate_list_args(datasets, Dataset) + self.data_format = data_format + self.geographic_extents = geographic_extents + self.breakdown_and_data_type_layout = breakdown_and_data_type_layout + self.tst_layout = tst_layout + self.time_series_tables = self._validate_list_args( time_series_tables, TimeSeriesTable ) self.shapefiles = self._validate_list_args(shapefiles, Shapefile) - if ( - len(self.datasets) == 0 - and len(self.time_series_tables) == 0 - and len(self.shapefiles) == 0 - ): - raise ValueError( - "At least one dataset, time series table, or shapefile must be specified." - ) - self.description = description - self.data_format = data_format - self.geographic_extents = geographic_extents - self.breakdown_and_data_type_layout = breakdown_and_data_type_layout - self.tst_layout = tst_layout self.api_version = ( self.extract_api_version(kwargs) @@ -767,7 +842,6 @@ def build(self) -> Dict[str, Any]: built = { "description": self.description, - "dataFormat": self.data_format, "collection": self.collection, "version": self.api_version, **self.kwargs, @@ -777,19 +851,22 @@ def build(self) -> Dict[str, Any]: built["datasets"] = { dataset.name: dataset.build() for dataset in self.datasets } + + if self.collection == "nhgis": + built["dataFormat"] = self.data_format built["breakdownAndDataTypeLayout"] = self.breakdown_and_data_type_layout if self.geographic_extents is not None: built["geographicExtents"] = self.geographic_extents - if self.time_series_tables is not None: - built["timeSeriesTables"] = { - tst.name.upper(): tst.build() for tst in self.time_series_tables - } - built["timeSeriesTableLayout"] = self.tst_layout + if self.time_series_tables is not None: + built["timeSeriesTables"] = { + tst.name.upper(): tst.build() for tst in self.time_series_tables + } + built["timeSeriesTableLayout"] = self.tst_layout - if self.shapefiles is not None: - built["shapefiles"] = [shapefile.name for shapefile in self.shapefiles] + if self.shapefiles is not None: + built["shapefiles"] = [shapefile.name for shapefile in self.shapefiles] return built diff --git a/tests/test_api.py b/tests/test_api.py index d08d5ab..22d5f1e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -24,7 +24,8 @@ Variable, Sample, TimeUseVariable, - Dataset, + NhgisDataset, + IhgisDataset, TimeSeriesTable, Shapefile, ) @@ -74,7 +75,7 @@ def simple_nhgis_extract() -> AggregateDataExtract: extract = AggregateDataExtract( "nhgis", description="Simple extract for ipumspy unit testing", - datasets=[Dataset("1990_STF1", ["NP1"], ["state"])], + datasets=[NhgisDataset("1990_STF1", ["NP1"], ["state"])], ) return extract @@ -86,8 +87,8 @@ def complex_nhgis_extract() -> AggregateDataExtract: "nhgis", description="Complex extract for ipumspy unit testing", datasets=[ - Dataset("2010_SF1a", ["P1", "P2"], ["block"]), - Dataset( + NhgisDataset("2010_SF1a", ["P1", "P2"], ["block"]), + NhgisDataset( "2010_SF2a", ["PCT1"], ["state"], @@ -104,6 +105,21 @@ def complex_nhgis_extract() -> AggregateDataExtract: return extract +@pytest.fixture() +def ihgis_extract() -> AggregateDataExtract: + extract = AggregateDataExtract( + "ihgis", + description="IHGIS extract for ipumspy unit testing", + datasets = [ + IhgisDataset( + "KZ2009pop", + data_tables = ["KZ2009pop.AAA", "KZ2009pop.AAB"], + tabulation_geographies = ["KZ2009pop.g0", "KZ2009pop.g1"] + ) + ] + ) + + return extract def test_usa_build_extract(): """ @@ -389,7 +405,7 @@ def test_nhgis_feature_errors(live_api_client: IpumsApiClient): """ extract = AggregateDataExtract( "nhgis", - datasets=[Dataset("a", "b", "c", "d")], + datasets=[NhgisDataset("a", "b", "c", "d")], time_series_tables=[TimeSeriesTable("a", "b")], ) @@ -663,6 +679,19 @@ def test_nhgis_build_extract( "shapefiles": [], } +def test_ihgis_build_extract(ihgis_extract: AggregateDataExtract): + assert ihgis_extract.build() == { + "description": "IHGIS extract for ipumspy unit testing", + "collection": "ihgis", + "version": None, + "datasets": { + "KZ2009pop": { + "dataTables": ["KZ2009pop.AAA", "KZ2009pop.AAB"], + "tabulationGeographies": ["KZ2009pop.g0", "KZ2009pop.g1"], + }, + }, + } + @pytest.mark.vcr def test_rect_on_nonP_extract(live_api_client: IpumsApiClient): @@ -909,10 +938,10 @@ def test_nhgis_extract_from_dict(fixtures_path: Path): for item in extract: assert item.collection == "nhgis" assert item.datasets == [ - Dataset( + NhgisDataset( name="1990_STF1", data_tables=["NP1", "NP2"], geog_levels=["county"] ), - Dataset(name="2010_SF1a", data_tables=["P1"], geog_levels=["state"]), + NhgisDataset(name="2010_SF1a", data_tables=["P1"], geog_levels=["state"]), ] assert item.time_series_tables == [ TimeSeriesTable(name="CW3", geog_levels=["state"], years=["1990"]) From ad89af733f6c5aa211c94dea0ce5189446692873 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 20 May 2025 09:38:12 -0400 Subject: [PATCH 02/20] Add support for IHGIS metadata requests --- src/ipumspy/api/metadata.py | 151 ++++++++++++++-- ...data.yaml => test_get_nhgis_metadata.yaml} | 166 +++++++++++++----- tests/test_metadata.py | 44 ++++- 3 files changed, 297 insertions(+), 64 deletions(-) rename tests/cassettes/test_metadata/{test_get_metadata.yaml => test_get_nhgis_metadata.yaml} (76%) diff --git a/src/ipumspy/api/metadata.py b/src/ipumspy/api/metadata.py index a92ee24..90a828d 100644 --- a/src/ipumspy/api/metadata.py +++ b/src/ipumspy/api/metadata.py @@ -43,19 +43,18 @@ def _validate_collection(self): @dataclass -class DatasetMetadata(IpumsMetadata): +class NhgisDatasetMetadata(IpumsMetadata): """ - Class to request and store metadata for an IPUMS dataset + Class to request and store metadata for an IPUMS NHGIS dataset Args: - collection: name of an IPUMS data collection - name: Name of an IPUMS dataset included in the collection + name: Name of an IPUMS NHGIS dataset """ - collection: str - """Name of an IPUMS data collection""" name: str """IPUMS dataset name""" + collection: str = "nhgis" + """Name of an IPUMS data collection""" nhgis_id: Optional[str] = field(default=None, init=False) """ID used in IPUMS files to reference the dataset""" group: Optional[str] = field(default=None, init=False) @@ -97,6 +96,88 @@ def __post_init__(self): @property def supported_collections(self): return ["nhgis"] + +@dataclass +class IhgisDatasetMetadata(IpumsMetadata): + """ + Class to request and store metadata for an IPUMS IHGIS dataset + + Args: + name: Name of an IPUMS IHGIS dataset + """ + + name: str + """IPUMS IHGIS dataset name""" + collection: str = "ihgis" + """Name of an IPUMS data collection""" + description: Optional[str] = field(default=None, init=False) + """Title of the census""" + dataset_type: Optional[str] = field(default=None, init=False) + """Type of dataset (population, agricultural, or tabulated)""" + country: Optional[str] = field(default=None, init=False) + """Two-character abbreviation of the country""" + country_label: Optional[str] = field(default=None, init=False) + """Name of the country""" + year: Optional[str] = field(default=None, init=False) + """Year the census was conducted""" + statistical_agency: Optional[str] = field(default=None, init=False) + """Name of the statistical agency that conducted the census""" + universe: Optional[str] = field(default=None, init=False) + """Description of the population that was included in the enumeration""" + de_jure_de_facto: Optional[str] = field(default=None, init=False) + """ + Whether the census counted people who reside in the country + (including those who were absent on the census day) [de jure], or people who + were present in the country on the census day (including visitors) [de facto]. + """ + enumeration_unit: Optional[str] = field(default=None, init=False) + """Types of entities (e.g., population, households, etc.) counted in the census""" + reference_period: Optional[str] = field(default=None, init=False) + """ + Date of record; people who were residents of or present in the country + as of this date were counted. + """ + fieldwork_period: Optional[str] = field(default=None, init=False) + """Time period during which enumeration took place""" + fieldwork_type: Optional[str] = field(default=None, init=False) + """Methods used for enumeration, such as face-to-face interviews or online forms""" + enumeration_forms: Optional[str] = field(default=None, init=False) + """Type of enumeration forms used to collect information""" + coverage: Optional[str] = field(default=None, init=False) + """If available, an estimate of how complete the enumeration was""" + sample: Optional[str] = field(default=None, init=False) + """ + If applicable, the proportion of the population included in the sample + on which the data tables are based + """ + dwelling_definition: Optional[str] = field(default=None, init=False) + """Definition used by the census of what constitutes a distinct dwelling unit""" + household_definition: Optional[str] = field(default=None, init=False) + """Definition used by the census of how people are grouped into households""" + group_quarters_definition: Optional[str] = field(default=None, init=False) + """Definition used by the census of what constitutes group quarters""" + sequence: Optional[str] = field(default=None, init=False) + """Order in which the dataset will appear""" + data_table_count: Optional[str] = field(default=None, init=False) + """Number of data tables included in the dataset""" + data_tables: Optional[List[Dict]] = field(default=None, init=False) + """ + Dictionary containing names, codes, and descriptions for the data tables + available for the dataset + """ + tabulation_geographies: Optional[List[Dict]] = field(default=None, init=False) + """ + Dictionary containing names, codes, and descriptions for the tabulation + geographies available for the dataset + """ + + def __post_init__(self): + self._path = f"metadata/datasets/{self.name}" + self._validate_collection() + + @property + def supported_collections(self): + return ["ihgis"] @dataclass @@ -142,22 +223,21 @@ def supported_collections(self): @dataclass -class DataTableMetadata(IpumsMetadata): +class NhgisDataTableMetadata(IpumsMetadata): """ - Class to request and store metadata for an IPUMS data table + Class to request and store metadata for an IPUMS NHGIS data table Args: - collection: IPUMS collection associated with this data table - name: Name of the data table for which to retrieve metadata - dataset_name: Name of the dataset containing this data table + name: Name of the NHGIS data table for which to retrieve metadata + dataset_name: Name of the NHGIS dataset containing this data table """ - collection: str - """Name of an IPUMS data collection""" name: str """IPUMS data table name""" dataset_name: str """Name of the dataset to which this data table belongs""" + collection: str = "nhgis" + """Name of an IPUMS data collection""" description: Optional[str] = field(default=None, init=False) """Description of the data table""" universe: Optional[str] = field(default=None, init=False) @@ -173,7 +253,7 @@ class DataTableMetadata(IpumsMetadata): """Dictionary containing variable descriptions and codes for the variables included in the data table""" def __post_init__(self): - self._path = self._path = ( + self._path = ( f"metadata/datasets/{self.dataset_name}/data_tables/{self.name}" ) self._validate_collection() @@ -181,3 +261,46 @@ def __post_init__(self): @property def supported_collections(self): return ["nhgis"] + +@dataclass +class IhgisDataTableMetadata(IpumsMetadata): + """ + Class to request and store metadata for an IPUMS IHGIS data table + + Args: + name: Name of an IPUMS IHGIS data table + """ + + name: str + """IPUMS data table name""" + dataset_name: Optional[str] = field(default=None, init=False) + """Name of the dataset to which this data table belongs""" + collection: str = "ihgis" + """Name of an IPUMS data collection""" + label: Optional[str] = field(default=None, init=False) + """Title of the data table""" + universe: Optional[str] = field(default=None, init=False) + """ + Statistical population measured by this data table, including + any restrictions on who or what was included + """ + table_num: Optional[str] = field(default=None, init=False) + """Number designating the table in the source publication""" + sequence: Optional[str] = field(default=None, init=False) + """Order in which the data table will appear in the metadata API and extracts""" + tabulation_geographies: Optional[str] = field(default=None, init=False) + """Tabulation geographies for which this table is available""" + footnotes: Optional[str] = field(default=None, init=False) + """Explanatory footnotes associated with the table""" + variables: Optional[str] = field(default=None, init=False) + """Dictionary containing variable descriptions and codes for the variables included in the data table""" + + def __post_init__(self): + self._path = ( + f"metadata/data_tables/{self.name}" + ) + self._validate_collection() + + @property + def supported_collections(self): + return ["ihgis"] diff --git a/tests/cassettes/test_metadata/test_get_metadata.yaml b/tests/cassettes/test_metadata/test_get_nhgis_metadata.yaml similarity index 76% rename from tests/cassettes/test_metadata/test_get_metadata.yaml rename to tests/cassettes/test_metadata/test_get_nhgis_metadata.yaml index 4087bb2..4f3308f 100644 --- a/tests/cassettes/test_metadata/test_get_metadata.yaml +++ b/tests/cassettes/test_metadata/test_get_nhgis_metadata.yaml @@ -122,24 +122,24 @@ interactions: of Value","universe":"Specified owner-occupied housing units","nhgisCode":"ETT","sequence":97,"datasetName":"1990_STF1","nVariables":3},{"name":"NH53","description":"Imputation of Price Asked","universe":"Specified Vacant-for-Sale Only Housing Units","nhgisCode":"ETU","sequence":98,"datasetName":"1990_STF1","nVariables":3},{"name":"NH54","description":"Imputation of Contract Rent","universe":"Specified renter-occupied housing units","nhgisCode":"ETV","sequence":99,"datasetName":"1990_STF1","nVariables":4},{"name":"NH55","description":"Imputation - of Meals Included in Rent","universe":"Specified renter-occupied housing units","nhgisCode":"ETW","sequence":100,"datasetName":"1990_STF1","nVariables":4}],"geogLevels":[{"name":"nation","description":"Nation","hasGeogExtentSelection":false,"sequence":1},{"name":"region","description":"Region","hasGeogExtentSelection":false,"sequence":2},{"name":"division","description":"Division","hasGeogExtentSelection":false,"sequence":3},{"name":"state","description":"State","hasGeogExtentSelection":false,"sequence":4},{"name":"state_260","description":"American - Indian Area/Alaska Native Area/Hawaiian Home Land--State","hasGeogExtentSelection":false,"sequence":5},{"name":"state_262","description":"American - Indian Area/Alaska Native Area (Reservation or Statistical Entity Only)--State","hasGeogExtentSelection":false,"sequence":7},{"name":"state_264","description":"American - Indian Area (Off-Reservation Trust Land Only)/Hawaiian Home Land--State","hasGeogExtentSelection":false,"sequence":8},{"name":"state_381","description":"Metropolitan - Statistical Area/Consolidated Metropolitan Statistical Area--State","hasGeogExtentSelection":false,"sequence":13},{"name":"state_386","description":"Metropolitan + of Meals Included in Rent","universe":"Specified renter-occupied housing units","nhgisCode":"ETW","sequence":100,"datasetName":"1990_STF1","nVariables":4}],"geogLevels":[{"name":"nation","description":"Nation","hasGeogExtentSelection":false,"sequence":1},{"name":"region","description":"Region","hasGeogExtentSelection":false,"sequence":2},{"name":"division","description":"Division","hasGeogExtentSelection":false,"sequence":3},{"name":"state","description":"State","hasGeogExtentSelection":true,"sequence":4},{"name":"state_260","description":"American + Indian Area/Alaska Native Area/Hawaiian Home Land--State","hasGeogExtentSelection":true,"sequence":5},{"name":"state_262","description":"American + Indian Area/Alaska Native Area (Reservation or Statistical Entity Only)--State","hasGeogExtentSelection":true,"sequence":7},{"name":"state_264","description":"American + Indian Area (Off-Reservation Trust Land Only)/Hawaiian Home Land--State","hasGeogExtentSelection":true,"sequence":8},{"name":"state_381","description":"Metropolitan + Statistical Area/Consolidated Metropolitan Statistical Area--State","hasGeogExtentSelection":true,"sequence":13},{"name":"state_386","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area--Primary Metropolitan - Statistical Area--State","hasGeogExtentSelection":false,"sequence":14},{"name":"state_410","description":"Urban - Area--State","hasGeogExtentSelection":false,"sequence":22},{"name":"county","description":"State--County","hasGeogExtentSelection":false,"sequence":25},{"name":"county_155","description":"State--Place--County","hasGeogExtentSelection":false,"sequence":27},{"name":"county_510_103","description":"State--Congressional - District (1993-1995, 103rd Congress)--County","hasGeogExtentSelection":false,"sequence":36},{"name":"county_270","description":"American - Indian Area/Alaska Native Area/Hawaiian Home Land--State--County","hasGeogExtentSelection":false,"sequence":53},{"name":"county_272","description":"American - Indian Area/Alaska Native Area (Reservation or Statistical Entity Only)--State--County","hasGeogExtentSelection":false,"sequence":54},{"name":"county_274","description":"American - Indian Area (Off-Reservation Trust Land Only)/Hawaiian Home Land--State--County","hasGeogExtentSelection":false,"sequence":55},{"name":"county_383","description":"Metropolitan - Statistical Area/Consolidated Metropolitan Statistical Area--State--County","hasGeogExtentSelection":false,"sequence":58},{"name":"county_387","description":"Metropolitan + Statistical Area--State","hasGeogExtentSelection":true,"sequence":14},{"name":"state_410","description":"Urban + Area--State","hasGeogExtentSelection":true,"sequence":22},{"name":"county","description":"State--County","hasGeogExtentSelection":true,"sequence":25},{"name":"county_155","description":"State--Place--County","hasGeogExtentSelection":true,"sequence":27},{"name":"county_510_103","description":"State--Congressional + District (1993-1995, 103rd Congress)--County","hasGeogExtentSelection":true,"sequence":36},{"name":"county_270","description":"American + Indian Area/Alaska Native Area/Hawaiian Home Land--State--County","hasGeogExtentSelection":true,"sequence":53},{"name":"county_272","description":"American + Indian Area/Alaska Native Area (Reservation or Statistical Entity Only)--State--County","hasGeogExtentSelection":true,"sequence":54},{"name":"county_274","description":"American + Indian Area (Off-Reservation Trust Land Only)/Hawaiian Home Land--State--County","hasGeogExtentSelection":true,"sequence":55},{"name":"county_383","description":"Metropolitan + Statistical Area/Consolidated Metropolitan Statistical Area--State--County","hasGeogExtentSelection":true,"sequence":58},{"name":"county_387","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area--Primary Metropolitan - Statistical Area--State--County","hasGeogExtentSelection":false,"sequence":59},{"name":"county_430","description":"Urban - Area--State--County","hasGeogExtentSelection":false,"sequence":63},{"name":"tract","description":"State--County--Census - Tract","hasGeogExtentSelection":false,"sequence":66},{"name":"tract_080","description":"State--County--County - Subdivision--Place/Remainder--Census Tract","hasGeogExtentSelection":false,"sequence":67},{"name":"blck_grp","description":"State--County--Census + Statistical Area--State--County","hasGeogExtentSelection":true,"sequence":59},{"name":"county_430","description":"Urban + Area--State--County","hasGeogExtentSelection":true,"sequence":63},{"name":"tract","description":"State--County--Census + Tract","hasGeogExtentSelection":true,"sequence":66},{"name":"tract_080","description":"State--County--County + Subdivision--Place/Remainder--Census Tract","hasGeogExtentSelection":true,"sequence":67},{"name":"blck_grp","description":"State--County--Census Tract--Block Group","hasGeogExtentSelection":true,"sequence":85},{"name":"blck_grp_595_101","description":"State--County--County Subdivision--Place/Remainder--Census Tract--Congressional District (1987-1993, 100th-102nd Congress)--American Indian/Alaska Native Area/Remainder--Reservation/Trust @@ -150,33 +150,33 @@ interactions: Lands/Remainder--Alaska Native Regional Corporation/Remainder--Urbanized Area/Remainder--Urban/Rural--Block Group [1990 partition]","hasGeogExtentSelection":true,"sequence":90},{"name":"block","description":"State--County--Census Tract--Block","hasGeogExtentSelection":true,"sequence":95},{"name":"cty_sub","description":"State--County--County - Subdivision","hasGeogExtentSelection":false,"sequence":102},{"name":"cty_sub_521_103","description":"State--Congressional + Subdivision","hasGeogExtentSelection":true,"sequence":102},{"name":"cty_sub_521_103","description":"State--Congressional District (1993-1995, 103rd Congress)--County--County Subdivision [10000 or - more persons]","hasGeogExtentSelection":false,"sequence":113},{"name":"cty_sub_440","description":"Urban - Area--State--County--County Subdivision","hasGeogExtentSelection":false,"sequence":131},{"name":"place","description":"State--Place","hasGeogExtentSelection":false,"sequence":148},{"name":"place_070","description":"State--County--County - Subdivision--Place/Remainder","hasGeogExtentSelection":false,"sequence":155},{"name":"place_531_103","description":"State--Congressional - District (1993-1995, 103rd Congress)--Place [10000 or more persons]","hasGeogExtentSelection":false,"sequence":164},{"name":"place_382","description":"Metropolitan + more persons]","hasGeogExtentSelection":true,"sequence":113},{"name":"cty_sub_440","description":"Urban + Area--State--County--County Subdivision","hasGeogExtentSelection":true,"sequence":131},{"name":"place","description":"State--Place","hasGeogExtentSelection":true,"sequence":148},{"name":"place_070","description":"State--County--County + Subdivision--Place/Remainder","hasGeogExtentSelection":true,"sequence":155},{"name":"place_531_103","description":"State--Congressional + District (1993-1995, 103rd Congress)--Place [10000 or more persons]","hasGeogExtentSelection":true,"sequence":164},{"name":"place_382","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area--State--Central - City","hasGeogExtentSelection":false,"sequence":193},{"name":"place_341","description":"Metropolitan + City","hasGeogExtentSelection":true,"sequence":193},{"name":"place_341","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area--Primary Metropolitan - Statistical Area--State--Central City","hasGeogExtentSelection":false,"sequence":194},{"name":"place_460","description":"Urban - Area--State--Central Place","hasGeogExtentSelection":false,"sequence":197},{"name":"place_450","description":"Urban - Area--State--County--County Subdivision--Place/Remainder","hasGeogExtentSelection":false,"sequence":198},{"name":"c_city","description":"State--Consolidated - City","hasGeogExtentSelection":false,"sequence":201},{"name":"c_city_541_103","description":"State--Congressional - District (1993-1995, 103rd Congress)--Consolidated City [10000 or more persons]","hasGeogExtentSelection":false,"sequence":208},{"name":"cd103rd","description":"State--Congressional - District (1993-1995, 103rd Congress)","hasGeogExtentSelection":false,"sequence":221},{"name":"cd101st","description":"State--Congressional - District (1987-1993, 100th-102nd Congress)","hasGeogExtentSelection":false,"sequence":222},{"name":"anrc","description":"Alaska + Statistical Area--State--Central City","hasGeogExtentSelection":true,"sequence":194},{"name":"place_460","description":"Urban + Area--State--Central Place","hasGeogExtentSelection":true,"sequence":197},{"name":"place_450","description":"Urban + Area--State--County--County Subdivision--Place/Remainder","hasGeogExtentSelection":true,"sequence":198},{"name":"c_city","description":"State--Consolidated + City","hasGeogExtentSelection":true,"sequence":201},{"name":"c_city_541_103","description":"State--Congressional + District (1993-1995, 103rd Congress)--Consolidated City [10000 or more persons]","hasGeogExtentSelection":true,"sequence":208},{"name":"cd103rd","description":"State--Congressional + District (1993-1995, 103rd Congress)","hasGeogExtentSelection":true,"sequence":221},{"name":"cd101st","description":"State--Congressional + District (1987-1993, 100th-102nd Congress)","hasGeogExtentSelection":true,"sequence":222},{"name":"anrc","description":"Alaska Native Regional Corporation","hasGeogExtentSelection":false,"sequence":257},{"name":"anrc_560_103","description":"State--Congressional - District (1993-1995, 103rd Congress)--Alaska Native Regional Corporation","hasGeogExtentSelection":false,"sequence":265},{"name":"aianhh","description":"American + District (1993-1995, 103rd Congress)--Alaska Native Regional Corporation","hasGeogExtentSelection":true,"sequence":265},{"name":"aianhh","description":"American Indian Area/Alaska Native Area/Hawaiian Home Land","hasGeogExtentSelection":false,"sequence":268},{"name":"aianhh_550_103","description":"State--Congressional District (1993-1995, 103rd Congress)--American Indian Area/Alaska Native Area/Hawaiian - Home Land","hasGeogExtentSelection":false,"sequence":282},{"name":"res_only","description":"American + Home Land","hasGeogExtentSelection":true,"sequence":282},{"name":"res_only","description":"American Indian Area/Alaska Native Area (Reservation or Statistical Entity Only)","hasGeogExtentSelection":false,"sequence":285},{"name":"res_only_551_103","description":"State--Congressional District (1993-1995, 103rd Congress)--American Indian Area/Alaska Native Area - (Reservation or Statistical Entity Only)","hasGeogExtentSelection":false,"sequence":292},{"name":"trust","description":"American + (Reservation or Statistical Entity Only)","hasGeogExtentSelection":true,"sequence":292},{"name":"trust","description":"American Indian Area (Off-Reservation Trust Land Only)/Hawaiian Home Land","hasGeogExtentSelection":false,"sequence":295},{"name":"trust_552_103","description":"State--Congressional District (1993-1995, 103rd Congress)--American Indian Area (Off-Reservation - Trust Land Only)/Hawaiian Home Land","hasGeogExtentSelection":false,"sequence":302},{"name":"msa_cmsa","description":"Metropolitan + Trust Land Only)/Hawaiian Home Land","hasGeogExtentSelection":true,"sequence":302},{"name":"msa_cmsa","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area","hasGeogExtentSelection":false,"sequence":346},{"name":"pmsa_385","description":"Metropolitan Statistical Area/Consolidated Metropolitan Statistical Area--Primary Metropolitan Statistical Area","hasGeogExtentSelection":false,"sequence":354},{"name":"urb_area","description":"Urban @@ -239,13 +239,13 @@ interactions: Cache-Control: - max-age=0, private, must-revalidate Content-Length: - - '31294' + - '31258' Content-Type: - application/json; charset=utf-8 Date: - - Mon, 11 Nov 2024 20:52:11 GMT + - Tue, 20 May 2025 13:31:55 GMT Etag: - - W/"1d5c2dc8d7bfe618e8c7f9991a0dc4ce" + - W/"58815ca6068c89e6b02430c2237e0c8a" Referrer-Policy: - strict-origin-when-cross-origin Server: @@ -265,9 +265,9 @@ interactions: X-Ratelimit-Reset: - '0' X-Request-Id: - - 0931b24f-99f6-4ca3-a532-b48eaa411bdc + - ce31c738-fb4a-4f17-8833-04949405ecc7 X-Runtime: - - '0.012075' + - '0.028710' X-Xss-Protection: - '0' status: @@ -321,7 +321,7 @@ interactions: Content-Type: - application/json; charset=utf-8 Date: - - Mon, 11 Nov 2024 20:52:11 GMT + - Tue, 20 May 2025 13:31:56 GMT Etag: - W/"cca984aa65af831c2d9b54dd5aa8c148" Referrer-Policy: @@ -343,9 +343,93 @@ interactions: X-Ratelimit-Reset: - '0' X-Request-Id: - - 8a5e8815-5a51-492a-855a-69a659cdaf5d + - bfc70b9f-2746-4015-854a-7304894f9fdd X-Runtime: - - '0.010915' + - '0.035479' + X-Xss-Protection: + - '0' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - python-ipumspy:0.5.1.github.com/ipums/ipumspy + method: GET + uri: https://api.ipums.org/metadata/time_series_tables/CW3?collection=nhgis&pageSize=2500&version=2 + response: + body: + string: '{"name":"CW3","description":"Persons by Age [22]","geographicIntegration":"Standardized + to 2010","sequence":103.05,"timeSeries":[{"name":"AA","description":"Persons: + Under 5 years","sequence":1},{"name":"AB","description":"Persons: 5 to 9 years","sequence":2},{"name":"AC","description":"Persons: + 10 to 14 years","sequence":3},{"name":"AD","description":"Persons: 15 to 17 + years","sequence":4},{"name":"AE","description":"Persons: 18 and 19 years","sequence":5},{"name":"AF","description":"Persons: + 20 years","sequence":6},{"name":"AG","description":"Persons: 21 years","sequence":7},{"name":"AH","description":"Persons: + 22 to 24 years","sequence":8},{"name":"AI","description":"Persons: 25 to 29 + years","sequence":9},{"name":"AJ","description":"Persons: 30 to 34 years","sequence":10},{"name":"AK","description":"Persons: + 35 to 39 years","sequence":11},{"name":"AL","description":"Persons: 40 to + 44 years","sequence":12},{"name":"AM","description":"Persons: 45 to 49 years","sequence":13},{"name":"AN","description":"Persons: + 50 to 54 years","sequence":14},{"name":"AO","description":"Persons: 55 to + 59 years","sequence":15},{"name":"AP","description":"Persons: 60 and 61 years","sequence":16},{"name":"AQ","description":"Persons: + 62 to 64 years","sequence":17},{"name":"AR","description":"Persons: 65 to + 69 years","sequence":18},{"name":"AS","description":"Persons: 70 to 74 years","sequence":19},{"name":"AT","description":"Persons: + 75 to 79 years","sequence":20},{"name":"AU","description":"Persons: 80 to + 84 years","sequence":21},{"name":"AV","description":"Persons: 85 years and + over","sequence":22}],"years":[{"name":"1990","description":"1990","sequence":108},{"name":"2000","description":"2000","sequence":118},{"name":"2010","description":"2010","sequence":131}],"geogLevels":[{"name":"state","description":"State","hasGeogExtentSelection":true,"sequence":4},{"name":"county","description":"State--County","hasGeogExtentSelection":true,"sequence":25},{"name":"tract","description":"State--County--Census + Tract","hasGeogExtentSelection":true,"sequence":66},{"name":"blck_grp","description":"State--County--Census + Tract--Block Group","hasGeogExtentSelection":true,"sequence":85},{"name":"cty_sub","description":"State--County--County + Subdivision","hasGeogExtentSelection":true,"sequence":102},{"name":"place","description":"State--Place","hasGeogExtentSelection":true,"sequence":148},{"name":"cd111th","description":"State--Congressional + District (2007-2013, 110th-112th Congress)","hasGeogExtentSelection":true,"sequence":217},{"name":"cbsa","description":"Metropolitan + Statistical Area/Micropolitan Statistical Area","hasGeogExtentSelection":false,"sequence":338},{"name":"urb_area","description":"Urban + Area","hasGeogExtentSelection":false,"sequence":372},{"name":"zcta","description":"5-Digit + ZIP Code Tabulation Area","hasGeogExtentSelection":false,"sequence":382}],"geographicInstances":[{"name":"010","description":"Alabama"},{"name":"020","description":"Alaska"},{"name":"040","description":"Arizona"},{"name":"050","description":"Arkansas"},{"name":"060","description":"California"},{"name":"080","description":"Colorado"},{"name":"090","description":"Connecticut"},{"name":"100","description":"Delaware"},{"name":"110","description":"District + of Columbia"},{"name":"120","description":"Florida"},{"name":"130","description":"Georgia"},{"name":"150","description":"Hawaii"},{"name":"160","description":"Idaho"},{"name":"170","description":"Illinois"},{"name":"180","description":"Indiana"},{"name":"190","description":"Iowa"},{"name":"200","description":"Kansas"},{"name":"210","description":"Kentucky"},{"name":"220","description":"Louisiana"},{"name":"230","description":"Maine"},{"name":"240","description":"Maryland"},{"name":"250","description":"Massachusetts"},{"name":"260","description":"Michigan"},{"name":"270","description":"Minnesota"},{"name":"280","description":"Mississippi"},{"name":"290","description":"Missouri"},{"name":"300","description":"Montana"},{"name":"310","description":"Nebraska"},{"name":"320","description":"Nevada"},{"name":"330","description":"New + Hampshire"},{"name":"340","description":"New Jersey"},{"name":"350","description":"New + Mexico"},{"name":"360","description":"New York"},{"name":"370","description":"North + Carolina"},{"name":"380","description":"North Dakota"},{"name":"390","description":"Ohio"},{"name":"400","description":"Oklahoma"},{"name":"410","description":"Oregon"},{"name":"420","description":"Pennsylvania"},{"name":"440","description":"Rhode + Island"},{"name":"450","description":"South Carolina"},{"name":"460","description":"South + Dakota"},{"name":"470","description":"Tennessee"},{"name":"480","description":"Texas"},{"name":"490","description":"Utah"},{"name":"500","description":"Vermont"},{"name":"510","description":"Virginia"},{"name":"530","description":"Washington"},{"name":"540","description":"West + Virginia"},{"name":"550","description":"Wisconsin"},{"name":"560","description":"Wyoming"}]}' + headers: + Cache-Control: + - max-age=0, private, must-revalidate + Content-Length: + - '4977' + Content-Type: + - application/json; charset=utf-8 + Date: + - Tue, 20 May 2025 13:31:56 GMT + Etag: + - W/"dd47221979c8c14bd5eabbd81fd84108" + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.22.1 + Vary: + - Origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Ratelimit-Limit: + - '-1' + X-Ratelimit-Remaining: + - '0' + X-Ratelimit-Reset: + - '0' + X-Request-Id: + - bfe81e17-d159-4887-a69f-a1f09cb97749 + X-Runtime: + - '0.062186' X-Xss-Protection: - '0' status: diff --git a/tests/test_metadata.py b/tests/test_metadata.py index d4bd36e..4876102 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -4,8 +4,10 @@ from ipumspy.api import IpumsApiClient from ipumspy.api.metadata import ( - DatasetMetadata, - DataTableMetadata, + NhgisDatasetMetadata, + NhgisDataTableMetadata, + IhgisDatasetMetadata, + IhgisDataTableMetadata, TimeSeriesTableMetadata, ) @@ -49,29 +51,53 @@ def test_get_metadata_catalog(live_api_client: IpumsApiClient): @pytest.mark.vcr -def test_get_metadata(live_api_client: IpumsApiClient): - ds = DatasetMetadata("nhgis", "1990_STF1") - dt = DataTableMetadata("nhgis", "B01001", "2017_2021_ACS5a") +def test_get_nhgis_metadata(live_api_client: IpumsApiClient): + ds = NhgisDatasetMetadata("1990_STF1") + dt = NhgisDataTableMetadata("B01001", "2017_2021_ACS5a") + tt = TimeSeriesTableMetadata("nhgis", "CW3") ds = live_api_client.get_metadata(ds) dt = live_api_client.get_metadata(dt) + tt = live_api_client.get_metadata(tt) - assert isinstance(ds, DatasetMetadata) - assert isinstance(dt, DataTableMetadata) + assert isinstance(ds, NhgisDatasetMetadata) + assert isinstance(dt, NhgisDataTableMetadata) + assert isinstance(tt, TimeSeriesTableMetadata) assert ds.description == "STF 1 - 100% Data" assert dt.description == "Sex by Age" + assert tt.description == "Persons by Age [22]" assert len(ds.data_tables) == 100 assert len(dt.variables) == 49 + assert len(tt.time_series) == 22 +# TODO: Enable test when IHGIS released to live. Currently only on demo +''' +@pytest.mark.vcr +def test_get_ihgis_metadata(live_api_client: IpumsApiClient): + ds = IhgisDatasetMetadata("KZ2009pop") + dt = IhgisDataTableMetadata("KZ2009pop.AAA") + + ds = live_api_client.get_metadata(ds) + dt = live_api_client.get_metadata(dt) + + assert isinstance(ds, IhgisDatasetMetadata) + assert isinstance(dt, IhgisDataTableMetadata) + + assert ds.description == "Results of the 2009 National Population Census of the Republic of Kazakhstan" + assert dt.label == "Urban and rural population" + + assert len(ds.data_tables) == 6 + assert len(dt.variables) == 9 +''' def test_collection_validity(): with pytest.raises(ValueError) as exc_info: - ds = DatasetMetadata("usa", "1990_STF1") + ds = TimeSeriesTableMetadata("usa", "CW3") assert ( exc_info.value.args[0] - == "DatasetMetadata is not a valid metadata type for the usa collection." + == "TimeSeriesTableMetadata is not a valid metadata type for the usa collection." ) From ac9b7a33e1b09fb7b09f14c459574a75d75bad45 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 20 May 2025 16:24:29 -0400 Subject: [PATCH 03/20] Throw error on unexpected IpumsObject in extract def --- src/ipumspy/api/extract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index 5f3aa3e..347cdb3 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -490,7 +490,7 @@ def _validate_list_args(self, list_arg, arg_obj): # before diving into any duplicate validation, make sure the list argument the user provided # is only strings or only IPUMS objects. Raise a useful error and ask the user to fix themselves if not all(isinstance(i, str) for i in list_arg) and not all( - isinstance(i, IpumsObject) for i in list_arg + isinstance(i, arg_obj) for i in list_arg ): raise TypeError( f"The items in {list_arg} must all be string type or {arg_obj} type." From 2508549e967a11010f314a90acce8a9dd8c3fa61 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 20 May 2025 16:39:21 -0400 Subject: [PATCH 04/20] Remove Dataset class IHGIS and NHGIS datasets are really just different objects --- src/ipumspy/api/extract.py | 86 +++++++++------------------- tests/fixtures/nhgis_extract_v2.pkl | Bin 1341 -> 1242 bytes 2 files changed, 28 insertions(+), 58 deletions(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index 347cdb3..ee4980a 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -144,27 +144,7 @@ def build(self): @dataclass -class Dataset(IpumsObject): - """ - IPUMS dataset object to include in an ``AggregateDataExtract`` object. - - Args: - name: IPUMS dataset name - """ - - name: str - """IPUMS dataset name""" - - def build(self): - """Format dataset information for API Extract submission""" - built_dataset = self.__dict__.copy() - # don't repeat the dataset name - built_dataset.pop("name") - - return built_dataset - -@dataclass -class NhgisDataset(Dataset): +class NhgisDataset(IpumsObject): """ IPUMS dataset object to include in an ``AggregateDataExtract`` object. @@ -204,7 +184,7 @@ def build(self): return built_dataset @dataclass -class IhgisDataset(Dataset): +class IhgisDataset(IpumsObject): """ IPUMS dataset object to include in an ``AggregateDataExtract`` object. @@ -343,15 +323,6 @@ def _unpack_ihgis_dataset_dict(dct: dict) -> List[IhgisDataset]: datasets.append(dataset_obj) return datasets -def _unpack_dataset_dict(dct: dict) -> List[Dataset]: - datasets = [] - for dataset in dct.keys(): - dataset_obj = Dataset( - name=dataset, - ) - datasets.append(dataset_obj) - return datasets - def _unpack_tst_dict(dct: dict) -> List[TimeSeriesTable]: time_series_tables = [] for time_series_table in dct.keys(): @@ -510,9 +481,6 @@ def _validate_list_args(self, list_arg, arg_obj): elif isinstance(list_arg, dict) and arg_obj is IhgisDataset: args = _unpack_ihgis_dataset_dict(list_arg) return args - elif isinstance(list_arg, dict) and arg_obj is Dataset: - args = _unpack_dataset_dict(list_arg) - return args elif isinstance(list_arg, dict) and arg_obj is TimeSeriesTable: args = _unpack_tst_dict(list_arg) return args @@ -767,7 +735,7 @@ class AggregateDataExtract(BaseExtract, collection_type="aggregate_data"): def __init__( self, collection: str, - datasets: Optional[List[Dataset]] = [], + datasets: Optional[List[NhgisDataset] | List[IhgisDataset]] = [], time_series_tables: Optional[List[TimeSeriesTable]] = [], shapefiles: Optional[Union[List[str], List[Shapefile]]] = [], description: str = "", @@ -781,7 +749,7 @@ def __init__( Class for defining an extract request for an IPUMS aggregate data collection. Args: - datasets: list of ``Dataset`` objects + datasets: list of ``NhgisDataset`` if ``collection="nhgis"`` or ``IhgisDataset`` objects if ``collection="ihgis"`` time_series_tables: list of ``TimeSeriesTable`` objects shapefiles: list of shapefile names description: short description of your extract @@ -806,20 +774,20 @@ def __init__( self.geographic_extents = geographic_extents self.breakdown_and_data_type_layout = breakdown_and_data_type_layout self.tst_layout = tst_layout + + self.time_series_tables = self._validate_list_args( + time_series_tables, TimeSeriesTable + ) + self.shapefiles = self._validate_list_args(shapefiles, Shapefile) elif collection == "ihgis": self.datasets = self._validate_list_args(datasets, IhgisDataset) - else: - self.datasets = self._validate_list_args(datasets, Dataset) - self.data_format = data_format - self.geographic_extents = geographic_extents - self.breakdown_and_data_type_layout = breakdown_and_data_type_layout - self.tst_layout = tst_layout - - self.time_series_tables = self._validate_list_args( - time_series_tables, TimeSeriesTable - ) - self.shapefiles = self._validate_list_args(shapefiles, Shapefile) - + self.data_format = None + self.geographic_extents = None + self.breakdown_and_data_type_layout = None + self.tst_layout = None + self.time_series_tables = None + self.shapefiles = None + self.description = description self.api_version = ( @@ -852,21 +820,23 @@ def build(self) -> Dict[str, Any]: dataset.name: dataset.build() for dataset in self.datasets } - if self.collection == "nhgis": + if self.data_format is not None: built["dataFormat"] = self.data_format + + if self.breakdown_and_data_type_layout is not None: built["breakdownAndDataTypeLayout"] = self.breakdown_and_data_type_layout - if self.geographic_extents is not None: - built["geographicExtents"] = self.geographic_extents + if self.geographic_extents is not None: + built["geographicExtents"] = self.geographic_extents - if self.time_series_tables is not None: - built["timeSeriesTables"] = { - tst.name.upper(): tst.build() for tst in self.time_series_tables - } - built["timeSeriesTableLayout"] = self.tst_layout + if self.time_series_tables is not None: + built["timeSeriesTables"] = { + tst.name.upper(): tst.build() for tst in self.time_series_tables + } + built["timeSeriesTableLayout"] = self.tst_layout - if self.shapefiles is not None: - built["shapefiles"] = [shapefile.name for shapefile in self.shapefiles] + if self.shapefiles is not None: + built["shapefiles"] = [shapefile.name for shapefile in self.shapefiles] return built diff --git a/tests/fixtures/nhgis_extract_v2.pkl b/tests/fixtures/nhgis_extract_v2.pkl index 2f8e5fd9806403643de78bfe6094aedb74e38fb9..3c4102925d607935b6c5e9538c0b8bb1f4ecb908 100644 GIT binary patch delta 401 zcmdnXb&Hd=fo1A>mWiy665c#Ltnrz7Y57xXr)c!B<(1|pr4~)`=9!pKFU>Heha)Ai zB(XTPq!=vCX=Gq%5FhMjm^fLGQCOyjDZp?_Vh>k(YJR#;YFTPd@s!vpJ*>qgi6yC% zJsDNpjg9ouQw<82jB8{e`X2<}wvL)x2=9N@V zNz9Ososyvl6yZ!NHn5z$no)xfBo8qfB)$0|BNrnZk6%W5X7S`VOp@ksmrd#62Dv%D zBrz!`73?60E4e|gjL$)LrYo~*B*K|V86KLAUh)M5tNt_Jeh?hS|CHDhb_B2u_zrBsHI7I01ZBjiU0rr delta 496 zcmcb`xtEKzfn}-@>qJ&ZDc?NS9@hBGytMo&wNo^D*z!tqlTwSO0EH*U)z^#rdANH9 zE2LJG6eT8?D5MqT=PE=x`ua@i;Ydj=Ni0q+DF$ofG_P63fdQ&M}l(o^%(eNxL(b3l?kY{~hhc_o!o5_?!HQxl88V*E)(sfpPs z`IBuJ`RxoW_0m%f45lQO_HY^*7y_+vGfV_olOYMz&IB|$F+&!}Vl6I7EJ+1&6k?}j zC;?%F_P*McJT$lb12Kaj|8WCl;lHB4zRwMgx}O(j+|q#^12_ From a1469e58edec42a3fb15731adec66768ffc5bdae Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Wed, 21 May 2025 11:04:34 -0400 Subject: [PATCH 05/20] Don't drop extract kwargs with no underscores --- src/ipumspy/api/extract.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index ee4980a..60b51b3 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -447,10 +447,14 @@ def _snake_to_camel(self, kwarg_dict): camelized = "".join([k.capitalize() for k in key_list[1:]]) # prepend the first part camel_key = f"{key_list[0]}{camelized}" - # add the camelCase key - kwarg_dict[camel_key] = kwarg_dict[key] - # pop the snake_case key - kwarg_dict.pop(key) + + # Only replace the key if it has changed, otherwise it gets dropped + if camel_key != key: + # add the camelCase key + kwarg_dict[camel_key] = kwarg_dict[key] + # pop the snake_case key + kwarg_dict.pop(key) + return kwarg_dict def _validate_list_args(self, list_arg, arg_obj): From 8c1f5b0652f95a27810e0eee943033627d08756a Mon Sep 17 00:00:00 2001 From: renae-r Date: Tue, 27 May 2025 16:14:11 -0500 Subject: [PATCH 06/20] update get_metadata_catalog docstring --- src/ipumspy/api/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipumspy/api/core.py b/src/ipumspy/api/core.py index b6ca30f..c09e5c0 100644 --- a/src/ipumspy/api/core.py +++ b/src/ipumspy/api/core.py @@ -592,7 +592,7 @@ def get_metadata_catalog( Args: collection: The name of the IPUMS collection to retrieve metadata for - metadata_type: Name of the type of metadata to retrieve for this collection + metadata_type: Name of the type of metadata to retrieve for this collection. Valid values include 'datasets', 'data_tables', and 'time_series_tables' page_size: Number of items to return per page. Defaults to maximum page size, 2500. Yields: From 71e73b1be165c6170015b96c73f65229fc8bc7c4 Mon Sep 17 00:00:00 2001 From: renae-r Date: Tue, 27 May 2025 16:43:38 -0500 Subject: [PATCH 07/20] more specific metadata choices, :black_heart: --- src/ipumspy/api/core.py | 2 +- src/ipumspy/api/extract.py | 22 ++++++++++++++-------- src/ipumspy/api/metadata.py | 14 ++++++-------- tests/test_api.py | 17 +++++++++++------ tests/test_metadata.py | 6 ++++-- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/ipumspy/api/core.py b/src/ipumspy/api/core.py index c09e5c0..721f177 100644 --- a/src/ipumspy/api/core.py +++ b/src/ipumspy/api/core.py @@ -592,7 +592,7 @@ def get_metadata_catalog( Args: collection: The name of the IPUMS collection to retrieve metadata for - metadata_type: Name of the type of metadata to retrieve for this collection. Valid values include 'datasets', 'data_tables', and 'time_series_tables' + metadata_type: Name of the type of metadata to retrieve for this collection. Valid values for the NHGIS collection include 'datasets', 'data_tables', 'shapefiles', and 'time_series_tables'; valid values for the IHGIS collection include 'datasets', 'data_tables', and 'tabulation_geographies'. page_size: Number of items to return per page. Defaults to maximum page size, 2500. Yields: diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index 60b51b3..afa86b5 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -182,7 +182,8 @@ def build(self): built_dataset["breakdownValues"] = built_dataset.pop("breakdown_values") return built_dataset - + + @dataclass class IhgisDataset(IpumsObject): """ @@ -200,7 +201,7 @@ class IhgisDataset(IpumsObject): """IPUMS data tables to extract from this dataset""" tabulation_geographies: List[str] """Geographic level(s) at which to obtain data for this dataset""" - + def build(self): """Format dataset information for API Extract submission""" built_dataset = self.__dict__.copy() @@ -208,10 +209,13 @@ def build(self): built_dataset.pop("name") # adhere to API schema camelCase convention built_dataset["dataTables"] = built_dataset.pop("data_tables") - built_dataset["tabulationGeographies"] = built_dataset.pop("tabulation_geographies") + built_dataset["tabulationGeographies"] = built_dataset.pop( + "tabulation_geographies" + ) return built_dataset + @dataclass class TimeSeriesTable(IpumsObject): """ @@ -312,6 +316,7 @@ def _unpack_nhgis_dataset_dict(dct: dict) -> List[NhgisDataset]: datasets.append(dataset_obj) return datasets + def _unpack_ihgis_dataset_dict(dct: dict) -> List[IhgisDataset]: datasets = [] for dataset in dct.keys(): @@ -323,6 +328,7 @@ def _unpack_ihgis_dataset_dict(dct: dict) -> List[IhgisDataset]: datasets.append(dataset_obj) return datasets + def _unpack_tst_dict(dct: dict) -> List[TimeSeriesTable]: time_series_tables = [] for time_series_table in dct.keys(): @@ -351,7 +357,7 @@ def _get_collection_type(collection: str) -> str: "nhis": "microdata", "meps": "microdata", "nhgis": "aggregate_data", - "ihgis": "aggregate_data" + "ihgis": "aggregate_data", } return collection_types[collection] @@ -447,14 +453,14 @@ def _snake_to_camel(self, kwarg_dict): camelized = "".join([k.capitalize() for k in key_list[1:]]) # prepend the first part camel_key = f"{key_list[0]}{camelized}" - + # Only replace the key if it has changed, otherwise it gets dropped if camel_key != key: # add the camelCase key kwarg_dict[camel_key] = kwarg_dict[key] # pop the snake_case key kwarg_dict.pop(key) - + return kwarg_dict def _validate_list_args(self, list_arg, arg_obj): @@ -791,7 +797,7 @@ def __init__( self.tst_layout = None self.time_series_tables = None self.shapefiles = None - + self.description = description self.api_version = ( @@ -826,7 +832,7 @@ def build(self) -> Dict[str, Any]: if self.data_format is not None: built["dataFormat"] = self.data_format - + if self.breakdown_and_data_type_layout is not None: built["breakdownAndDataTypeLayout"] = self.breakdown_and_data_type_layout diff --git a/src/ipumspy/api/metadata.py b/src/ipumspy/api/metadata.py index 90a828d..b7963c3 100644 --- a/src/ipumspy/api/metadata.py +++ b/src/ipumspy/api/metadata.py @@ -96,7 +96,8 @@ def __post_init__(self): @property def supported_collections(self): return ["nhgis"] - + + @dataclass class IhgisDatasetMetadata(IpumsMetadata): """ @@ -253,15 +254,14 @@ class NhgisDataTableMetadata(IpumsMetadata): """Dictionary containing variable descriptions and codes for the variables included in the data table""" def __post_init__(self): - self._path = ( - f"metadata/datasets/{self.dataset_name}/data_tables/{self.name}" - ) + self._path = f"metadata/datasets/{self.dataset_name}/data_tables/{self.name}" self._validate_collection() @property def supported_collections(self): return ["nhgis"] + @dataclass class IhgisDataTableMetadata(IpumsMetadata): """ @@ -270,7 +270,7 @@ class IhgisDataTableMetadata(IpumsMetadata): Args: name: Name of an IPUMS IHGIS data table """ - + name: str """IPUMS data table name""" dataset_name: Optional[str] = field(default=None, init=False) @@ -296,9 +296,7 @@ class IhgisDataTableMetadata(IpumsMetadata): """Dictionary containing variable descriptions and codes for the variables included in the data table""" def __post_init__(self): - self._path = ( - f"metadata/data_tables/{self.name}" - ) + self._path = f"metadata/data_tables/{self.name}" self._validate_collection() @property diff --git a/tests/test_api.py b/tests/test_api.py index 22d5f1e..1949b50 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -105,22 +105,24 @@ def complex_nhgis_extract() -> AggregateDataExtract: return extract + @pytest.fixture() def ihgis_extract() -> AggregateDataExtract: extract = AggregateDataExtract( "ihgis", description="IHGIS extract for ipumspy unit testing", - datasets = [ + datasets=[ IhgisDataset( - "KZ2009pop", - data_tables = ["KZ2009pop.AAA", "KZ2009pop.AAB"], - tabulation_geographies = ["KZ2009pop.g0", "KZ2009pop.g1"] + "KZ2009pop", + data_tables=["KZ2009pop.AAA", "KZ2009pop.AAB"], + tabulation_geographies=["KZ2009pop.g0", "KZ2009pop.g1"], ) - ] + ], ) return extract + def test_usa_build_extract(): """ Confirm that test extract formatted correctly @@ -679,6 +681,7 @@ def test_nhgis_build_extract( "shapefiles": [], } + def test_ihgis_build_extract(ihgis_extract: AggregateDataExtract): assert ihgis_extract.build() == { "description": "IHGIS extract for ipumspy unit testing", @@ -941,7 +944,9 @@ def test_nhgis_extract_from_dict(fixtures_path: Path): NhgisDataset( name="1990_STF1", data_tables=["NP1", "NP2"], geog_levels=["county"] ), - NhgisDataset(name="2010_SF1a", data_tables=["P1"], geog_levels=["state"]), + NhgisDataset( + name="2010_SF1a", data_tables=["P1"], geog_levels=["state"] + ), ] assert item.time_series_tables == [ TimeSeriesTable(name="CW3", geog_levels=["state"], years=["1990"]) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 4876102..6feeb24 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -72,8 +72,9 @@ def test_get_nhgis_metadata(live_api_client: IpumsApiClient): assert len(dt.variables) == 49 assert len(tt.time_series) == 22 + # TODO: Enable test when IHGIS released to live. Currently only on demo -''' +""" @pytest.mark.vcr def test_get_ihgis_metadata(live_api_client: IpumsApiClient): ds = IhgisDatasetMetadata("KZ2009pop") @@ -90,7 +91,8 @@ def test_get_ihgis_metadata(live_api_client: IpumsApiClient): assert len(ds.data_tables) == 6 assert len(dt.variables) == 9 -''' +""" + def test_collection_validity(): with pytest.raises(ValueError) as exc_info: From c98199e57fc85717ed490b3cd505e814a7e1d98a Mon Sep 17 00:00:00 2001 From: renae-r Date: Tue, 27 May 2025 17:50:33 -0500 Subject: [PATCH 08/20] add amv feature to Variable --- src/ipumspy/api/extract.py | 3 ++ tests/test_api.py | 64 +++++++++++++++++++++++++++++++++++++- tests/test_readers.py | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index afa86b5..c146efd 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -69,6 +69,8 @@ class Variable(IpumsObject): """Attach characteristics specifications""" data_quality_flags: Optional[bool] = False """Flag to include the variable's associated data quality flags if they exist""" + adjust_monetary_values: Optional[bool] = False + """Flag to include the variable's associated inflation-adjusted equivalent, if possible""" def __post_init__(self): self.name = self.name.upper() @@ -82,6 +84,7 @@ def build(self): built_var["caseSelections"] = built_var.pop("case_selections") built_var["attachedCharacteristics"] = built_var.pop("attached_characteristics") built_var["dataQualityFlags"] = built_var.pop("data_quality_flags") + built_var["adjustMonetaryValues"] = built_var.pop("adjust_monetary_values") return built_var diff --git a/tests/test_api.py b/tests/test_api.py index 1949b50..d7a4e6d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -142,12 +142,14 @@ def test_usa_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -176,12 +178,14 @@ def test_usa_attach_characteristics(): "caseSelections": {}, "attachedCharacteristics": ["father"], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -215,18 +219,21 @@ def test_usa_add_data_quality_flags(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": True, + "adjustMonetaryValues": False, }, "RACE": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -252,18 +259,21 @@ def test_usa_add_data_quality_flags(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": True, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "RACE": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": True, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -293,12 +303,14 @@ def test_usa_select_cases(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "RACE": { "preselected": False, "caseSelections": {"general": ["1"]}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -317,12 +329,14 @@ def test_usa_select_cases(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "RACE": { "preselected": False, "caseSelections": {"detailed": ["100"]}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS USA extract", @@ -451,12 +465,14 @@ def test_cps_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "description": "My IPUMS CPS extract", @@ -486,12 +502,14 @@ def test_ipumsi_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "collection": "ipumsi", @@ -517,12 +535,14 @@ def test_atus_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "timeUseVariables": {"BLS_PCARE": {}}, @@ -548,12 +568,14 @@ def test_atus_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "timeUseVariables": {"BLS_PCARE": {}}, @@ -584,12 +606,14 @@ def test_atus_build_extract(): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "timeUseVariables": { @@ -864,6 +888,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -871,6 +896,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -878,6 +904,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), ] # data structure not currently an extract attribute... @@ -898,6 +925,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=["mother"], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -905,6 +933,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -912,6 +941,7 @@ def test_extract_from_dict(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), ] # data structure not currently an extract attribute... @@ -1174,6 +1204,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -1181,6 +1212,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -1188,6 +1220,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), ] assert item.api_version == 2 @@ -1205,6 +1238,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=["mother"], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -1212,6 +1246,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -1219,6 +1254,7 @@ def test_define_extract_from_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), ] assert item.api_version == 2 @@ -1250,6 +1286,7 @@ def test_extract_from_api_response_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="AGE", @@ -1257,6 +1294,7 @@ def test_extract_from_api_response_json(fixtures_path: Path): case_selections={"general": [1, 2, 3]}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -1264,6 +1302,7 @@ def test_extract_from_api_response_json(fixtures_path: Path): case_selections={}, attached_characteristics=[], data_quality_flags=True, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -1345,6 +1384,7 @@ def test_validate_list_args(): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="SEX", @@ -1352,6 +1392,7 @@ def test_validate_list_args(): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), Variable( name="RACE", @@ -1359,6 +1400,7 @@ def test_validate_list_args(): case_selections={}, attached_characteristics=[], data_quality_flags=False, + adjust_monetary_values=False, ), ] ) @@ -1429,7 +1471,7 @@ def test_validate_list_args(): ) assert ( exc_info.value.args[0] - == "The items in [Variable(name='AGE', preselected=False, case_selections={}, attached_characteristics=[], data_quality_flags=False), 'SEX'] must all be string type or type." + == "The items in [Variable(name='AGE', preselected=False, case_selections={}, attached_characteristics=[], data_quality_flags=False, adjust_monetary_values=False), 'SEX'] must all be string type or type." ) @@ -1451,66 +1493,77 @@ def test_get_extract_by_id(live_api_client: IpumsApiClient): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SERIAL": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "MONTH": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "HWTFINL": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "CPSID": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "PERNUM": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "WTFINL": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "CPSIDP": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "AGE": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "RACE": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "collection": "cps", @@ -1531,54 +1584,63 @@ def test_get_extract_by_id(live_api_client: IpumsApiClient): "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "YEAR": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SAMPLE": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SERIAL": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "HHWT": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "PERNUM": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "PERWT": { "preselected": True, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "AGE": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, "SEX": { "preselected": False, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, }, }, "collection": "ipumsi", diff --git a/tests/test_readers.py b/tests/test_readers.py index 289ade3..153fd5b 100644 --- a/tests/test_readers.py +++ b/tests/test_readers.py @@ -896,6 +896,7 @@ def test_read_extract_description(fixtures_path: Path): "caseSelections": {"general": [1, 2, 3]}, "attachedCharacteristics": [], "dataQualityFlags": False, + "adjustMonetaryValues": False, } # Check that something that is neither YAML nor JSON yields a ValueError From 7dc2d0877df855b3801c98b08fb9ff22aad72d7e Mon Sep 17 00:00:00 2001 From: renae-r Date: Tue, 27 May 2025 18:00:27 -0500 Subject: [PATCH 09/20] add adjust_monetary_values() --- src/ipumspy/api/extract.py | 18 +++++++++++++++ tests/test_api.py | 45 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index c146efd..15c0097 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -742,6 +742,24 @@ def select_cases( self._update_variable_feature( variable, "case_selections", {"detailed": values} ) + + def adjust_monetary_values( + self, variable: Union[Variable, str, List[Variable], List[str]] + ): + """ + A method to update existing IPUMS Extract Variable objects to include that + variable's inflation-adjusted version in the extract if possible. This feature + is only applicable to variables representing dollar amounts. + + Args: + variable: a Variable object or a string variable name + + """ + if isinstance(variable, list): + for v in variable: + self._update_variable_feature(v, "adjust_monetary_values", True) + else: + self._update_variable_feature(variable, "adjust_monetary_values", True) class AggregateDataExtract(BaseExtract, collection_type="aggregate_data"): diff --git a/tests/test_api.py b/tests/test_api.py index d7a4e6d..5a8c077 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -202,7 +202,7 @@ def test_usa_attach_characteristics(): def test_usa_add_data_quality_flags(): """ - Confirm that attach_characteristics updates extract definition correctly + Confirm that add_data_quality_flags updates extract definition correctly """ extract = MicrodataExtract( "usa", @@ -1820,3 +1820,46 @@ def test_get_pages(live_api_client: IpumsApiClient): live_api_client._get_pages(collection="usa", endpoint="extracts", page_size=5) ) assert len(page1["data"]) == 5 + + +def test_cps_adjust_monetary_values(): + """ + Confirm that adjust monetary values updates are happening correctly + """ + extract = MicrodataExtract( + "cps", + ["cps2012_03s"], + ["AGE", "SEX", "HOURWAGE"], + ) + extract.adjust_monetary_values("HOURWAGE") + assert extract.build() == { + "dataStructure": {"rectangular": {"on": "P"}}, + "samples": {"cps2012_03s": {}}, + "variables": { + "AGE": { + "preselected": False, + "caseSelections": {}, + "attachedCharacteristics": [], + "dataQualityFlags": False, + "adjustMonetaryValues": False, + }, + "SEX": { + "preselected": False, + "caseSelections": {}, + "attachedCharacteristics": [], + "dataQualityFlags": False, + "adjustMonetaryValues": False, + }, + "HOURWAGE": { + "preselected": False, + "caseSelections": {}, + "attachedCharacteristics": [], + "dataQualityFlags": False, + "adjustMonetaryValues": True, + }, + }, + "description": "My IPUMS CPS extract", + "dataFormat": "fixed_width", + "collection": "cps", + "version": None, + } From 1edfb101dcef34bf03158bc7a4809d500ee3570c Mon Sep 17 00:00:00 2001 From: renae-r Date: Wed, 28 May 2025 10:52:57 -0500 Subject: [PATCH 10/20] add some tests --- .../test_adjust_monetary_values_errors.yaml | 133 ++++++++++++++++++ tests/test_api.py | 31 ++++ 2 files changed, 164 insertions(+) create mode 100644 tests/cassettes/test_api/test_adjust_monetary_values_errors.yaml diff --git a/tests/cassettes/test_api/test_adjust_monetary_values_errors.yaml b/tests/cassettes/test_api/test_adjust_monetary_values_errors.yaml new file mode 100644 index 0000000..9a37430 --- /dev/null +++ b/tests/cassettes/test_api/test_adjust_monetary_values_errors.yaml @@ -0,0 +1,133 @@ +interactions: +- request: + body: '{"description": "My IPUMS CPS extract", "dataFormat": "fixed_width", "dataStructure": + {"rectangular": {"on": "P"}}, "samples": {"cps2012_03s": {}}, "variables": {"AGE": + {"preselected": false, "caseSelections": {}, "attachedCharacteristics": [], + "dataQualityFlags": false, "adjustMonetaryValues": false}, "SEX": {"preselected": + false, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": + false, "adjustMonetaryValues": true}, "HOURWAGE": {"preselected": false, "caseSelections": + {}, "attachedCharacteristics": [], "dataQualityFlags": false, "adjustMonetaryValues": + false}}, "collection": "cps", "version": 2}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '627' + Content-Type: + - application/json + User-Agent: + - python-ipumspy:0.6.2.github.com/ipums/ipumspy + method: POST + uri: https://api.ipums.org/extracts?collection=cps&version=2 + response: + body: + string: '{"type":"SemanticValidationError","status":{"code":400,"name":"Bad + Request"},"detail":["Monetary value adjustment is not supported for SEX."]}' + headers: + Cache-Control: + - no-cache + Content-Length: + - '142' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 28 May 2025 15:46:19 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.22.1 + Vary: + - Origin + - Accept + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Ratelimit-Limit: + - '-1' + X-Ratelimit-Remaining: + - '0' + X-Ratelimit-Reset: + - '0' + X-Request-Id: + - 7a274944-f227-408a-9570-a6d9e2df9c9c + X-Runtime: + - '0.691613' + X-Xss-Protection: + - '0' + status: + code: 400 + message: Bad Request +- request: + body: '{"description": "My IPUMS ATUS extract", "dataFormat": "fixed_width", "dataStructure": + {"rectangular": {"on": "P"}}, "samples": {"at2012": {}}, "variables": {"AGE": + {"preselected": false, "caseSelections": {}, "attachedCharacteristics": [], + "dataQualityFlags": false, "adjustMonetaryValues": false}, "SEX": {"preselected": + false, "caseSelections": {}, "attachedCharacteristics": [], "dataQualityFlags": + false, "adjustMonetaryValues": false}, "EARNWEEK": {"preselected": false, "caseSelections": + {}, "attachedCharacteristics": [], "dataQualityFlags": false, "adjustMonetaryValues": + true}}, "collection": "atus", "version": 2}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '624' + Content-Type: + - application/json + User-Agent: + - python-ipumspy:0.6.2.github.com/ipums/ipumspy + method: POST + uri: https://api.ipums.org/extracts?collection=atus&version=2 + response: + body: + string: '{"type":"SemanticValidationError","status":{"code":400,"name":"Bad + Request"},"detail":["Monetary value adjustment is not supported for IPUMS + ATUS"]}' + headers: + Cache-Control: + - no-cache + Content-Length: + - '148' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 28 May 2025 15:46:19 GMT + Referrer-Policy: + - strict-origin-when-cross-origin + Server: + - nginx/1.22.1 + Vary: + - Origin + - Accept + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Ratelimit-Limit: + - '-1' + X-Ratelimit-Remaining: + - '0' + X-Ratelimit-Reset: + - '0' + X-Request-Id: + - 53660b57-cfcd-46e1-9699-6ad7d2dd4203 + X-Runtime: + - '0.517223' + X-Xss-Protection: + - '0' + status: + code: 400 + message: Bad Request +version: 1 diff --git a/tests/test_api.py b/tests/test_api.py index 5a8c077..ba755ae 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1863,3 +1863,34 @@ def test_cps_adjust_monetary_values(): "collection": "cps", "version": None, } + + +@pytest.mark.vcr +def test_adjust_monetary_values_errors(live_api_client: IpumsApiClient): + """Confirm correct errors raised by trying to adjust a non-monetary variable""" + extract = MicrodataExtract( + "cps", + ["cps2012_03s"], + ["AGE", "SEX", "HOURWAGE"], + ) + extract.adjust_monetary_values("SEX") + with pytest.raises(BadIpumsApiRequest) as exc_info: + live_api_client.submit_extract(extract) + assert ( + exc_info.value.args[0] + == "Monetary value adjustment is not supported for SEX." + ) + + extract = MicrodataExtract( + "atus", + ["at2012"], + ["AGE", "SEX", "EARNWEEK"], + ) + + extract.adjust_monetary_values("EARNWEEK") + with pytest.raises(BadIpumsApiRequest) as exc_info: + live_api_client.submit_extract(extract) + assert ( + exc_info.value.args[0] + == "Monetary value adjustment is not supported for IPUMS ATUS" + ) From f27ebebc88247e6d72881386fabff8105e63c23a Mon Sep 17 00:00:00 2001 From: renae-r Date: Wed, 28 May 2025 12:53:30 -0500 Subject: [PATCH 11/20] amv documentation updates --- .../ipums_api/ipums_api_micro/index.rst | 25 ++++++++++++++++--- docs/source/reference/api.rst | 9 ++++--- src/ipumspy/api/extract.py | 1 + 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/docs/source/ipums_api/ipums_api_micro/index.rst b/docs/source/ipums_api/ipums_api_micro/index.rst index d431d11..a267c98 100644 --- a/docs/source/ipums_api/ipums_api_micro/index.rst +++ b/docs/source/ipums_api/ipums_api_micro/index.rst @@ -276,6 +276,23 @@ Data quality flags can also be selected for specific variables using the :meth:` # note that this method will also accept a list! extract.add_data_quality_flags(["AGE", "SEX"]) +Adjust Monetary Values +~~~~~~~~~~~~~~~~~~~~~~ + +IPUMS CPS and IPUMS USA offer the option to standardize income or other dollar values to 2010 dollars. This option both retains the original IPUMS variable in your extract and adds a new, adjusted variable called ``_cpiu_2010`` that contains the inflation-adjusted values. Further information on the Adjust Monetary Values feature can be found on the `IPUMS CPS `_ and `IPUMS USA `_ websites. + +Inflation adjusted values are only available for continuous variables that represent dollar amounts and can be selected using the :meth:`.adjust_monetary_values()` method. + +.. code:: python + + extract = MicrodataExtract( + collection="cps", + samples=["cps2022_03s"], + variables=["AGE", "SEX", "INCTOT"], + ) + + extract.adjust_monetary_values("INCTOT") + .. _Using Variable Objects to Include Extract Features: Variable Objects @@ -286,8 +303,8 @@ defining a :class:`MicrodataExtract` using :class:`Variable` objects. The example below defines an IPUMS CPS extract that includes a variable for the age of -the spouse (``attached_characteristics``), limits the sample to women (``case_selections``), and includes the -data quality flag for RACE (``data_quality_flags``). +the spouse (``attached_characteristics``), limits the sample to women (``case_selections``), includes the +data quality flag for RACE (``data_quality_flags``), and an inflation-adjusted version of INCTOT (``adjust_monetary_values``). .. code:: python @@ -300,7 +317,9 @@ data quality flag for RACE (``data_quality_flags``). Variable(name="SEX", case_selections={"general": ["2"]}), Variable(name="RACE", - data_quality_flags=True) + data_quality_flags=True), + Variable(name="INCTOT", + adjust_monetary_values=True), ], description="A fancy CPS extract", ) diff --git a/docs/source/reference/api.rst b/docs/source/reference/api.rst index 53b8e1e..80e7661 100644 --- a/docs/source/reference/api.rst +++ b/docs/source/reference/api.rst @@ -44,7 +44,8 @@ Helpful data classes for defining IPUMS Extract objects. ipumspy.api.Variable ipumspy.api.Sample ipumspy.api.TimeUseVariable - ipumspy.api.Dataset + ipumspy.api.NhgisDataset + ipumspy.api.IhgisDataset ipumspy.api.TimeSeriesTable ipumspy.api.Shapefile @@ -74,8 +75,10 @@ Use these classes and methods to request IPUMS metadata for aggregate data colle :template: class.rst :nosignatures: - ipumspy.api.metadata.DatasetMetadata - ipumspy.api.metadata.DataTableMetadata + ipumspy.api.metadata.NhgisDatasetMetadata + ipumspy.api.metadata.IhgisDatasetMetadata + ipumspy.api.metadata.NhgisDataTableMetadata + ipumspy.api.metadata.IhgisDataTableMetadata ipumspy.api.metadata.TimeSeriesTableMetadata Exceptions diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index 15c0097..f642f1e 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -57,6 +57,7 @@ class Variable(IpumsObject): case_selections: Case selection specifications attached_characteristics: Attach characteristics specifications data_quality_flags: Flag to include the variable's associated data quality flags if they exist + adjust_monetary_values: Flag to include the variable's associated inflation-adjusted equivalent, if possible """ name: str From 9c27ad887f65f6dffb396227299377db0ff9e3db Mon Sep 17 00:00:00 2001 From: renae-r Date: Wed, 28 May 2025 13:00:31 -0500 Subject: [PATCH 12/20] dependency updates --- poetry.lock | 850 +++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 430 insertions(+), 422 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9de7f71..075a5b5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -174,14 +174,14 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2025.1.31" +version = "2025.4.26" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, - {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, + {file = "certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"}, + {file = "certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"}, ] [[package]] @@ -198,104 +198,104 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.1" +version = "3.4.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, - {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, - {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, - {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, - {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, - {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, - {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, - {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, - {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, - {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, + {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, + {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, + {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, + {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, + {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, + {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, + {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, + {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, + {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, ] [[package]] @@ -327,75 +327,79 @@ files = [ [[package]] name = "coverage" -version = "7.8.0" +version = "7.8.2" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2931f66991175369859b5fd58529cd4b73582461877ecfd859b6549869287ffe"}, - {file = "coverage-7.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52a523153c568d2c0ef8826f6cc23031dc86cffb8c6aeab92c4ff776e7951b28"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c8a5c139aae4c35cbd7cadca1df02ea8cf28a911534fc1b0456acb0b14234f3"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a26c0c795c3e0b63ec7da6efded5f0bc856d7c0b24b2ac84b4d1d7bc578d676"}, - {file = "coverage-7.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821f7bcbaa84318287115d54becb1915eece6918136c6f91045bb84e2f88739d"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a321c61477ff8ee705b8a5fed370b5710c56b3a52d17b983d9215861e37b642a"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ed2144b8a78f9d94d9515963ed273d620e07846acd5d4b0a642d4849e8d91a0c"}, - {file = "coverage-7.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:042e7841a26498fff7a37d6fda770d17519982f5b7d8bf5278d140b67b61095f"}, - {file = "coverage-7.8.0-cp310-cp310-win32.whl", hash = "sha256:f9983d01d7705b2d1f7a95e10bbe4091fabc03a46881a256c2787637b087003f"}, - {file = "coverage-7.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a570cd9bd20b85d1a0d7b009aaf6c110b52b5755c17be6962f8ccd65d1dbd23"}, - {file = "coverage-7.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27"}, - {file = "coverage-7.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9"}, - {file = "coverage-7.8.0-cp311-cp311-win32.whl", hash = "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c"}, - {file = "coverage-7.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe"}, - {file = "coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545"}, - {file = "coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b"}, - {file = "coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd"}, - {file = "coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067"}, - {file = "coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323"}, - {file = "coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3"}, - {file = "coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d"}, - {file = "coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487"}, - {file = "coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25"}, - {file = "coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1"}, - {file = "coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a"}, - {file = "coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883"}, - {file = "coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada"}, - {file = "coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257"}, - {file = "coverage-7.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa260de59dfb143af06dcf30c2be0b200bed2a73737a8a59248fcb9fa601ef0f"}, - {file = "coverage-7.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96121edfa4c2dfdda409877ea8608dd01de816a4dc4a0523356067b305e4e17a"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8af63b9afa1031c0ef05b217faa598f3069148eeee6bb24b79da9012423b82"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b1f4af0d4afe495cd4787a68e00f30f1d15939f550e869de90a86efa7e0814"}, - {file = "coverage-7.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ec0be97723ae72d63d3aa41961a0b9a6f5a53ff599813c324548d18e3b9e8c"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a1d96e780bdb2d0cbb297325711701f7c0b6f89199a57f2049e90064c29f6bd"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f1d8a2a57b47142b10374902777e798784abf400a004b14f1b0b9eaf1e528ba4"}, - {file = "coverage-7.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cf60dd2696b457b710dd40bf17ad269d5f5457b96442f7f85722bdb16fa6c899"}, - {file = "coverage-7.8.0-cp39-cp39-win32.whl", hash = "sha256:be945402e03de47ba1872cd5236395e0f4ad635526185a930735f66710e1bd3f"}, - {file = "coverage-7.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:90e7fbc6216ecaffa5a880cdc9c77b7418c1dcb166166b78dbc630d07f278cc3"}, - {file = "coverage-7.8.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd"}, - {file = "coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7"}, - {file = "coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501"}, + {file = "coverage-7.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd8ec21e1443fd7a447881332f7ce9d35b8fbd2849e761bb290b584535636b0a"}, + {file = "coverage-7.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26c2396674816deaeae7ded0e2b42c26537280f8fe313335858ffff35019be"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1aec326ed237e5880bfe69ad41616d333712c7937bcefc1343145e972938f9b3"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e818796f71702d7a13e50c70de2a1924f729228580bcba1607cccf32eea46e6"}, + {file = "coverage-7.8.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:546e537d9e24efc765c9c891328f30f826e3e4808e31f5d0f87c4ba12bbd1622"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab9b09a2349f58e73f8ebc06fac546dd623e23b063e5398343c5270072e3201c"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fd51355ab8a372d89fb0e6a31719e825cf8df8b6724bee942fb5b92c3f016ba3"}, + {file = "coverage-7.8.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0774df1e093acb6c9e4d58bce7f86656aeed6c132a16e2337692c12786b32404"}, + {file = "coverage-7.8.2-cp310-cp310-win32.whl", hash = "sha256:00f2e2f2e37f47e5f54423aeefd6c32a7dbcedc033fcd3928a4f4948e8b96af7"}, + {file = "coverage-7.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:145b07bea229821d51811bf15eeab346c236d523838eda395ea969d120d13347"}, + {file = "coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9"}, + {file = "coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5"}, + {file = "coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb"}, + {file = "coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54"}, + {file = "coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a"}, + {file = "coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975"}, + {file = "coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53"}, + {file = "coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c"}, + {file = "coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99"}, + {file = "coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57"}, + {file = "coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f"}, + {file = "coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8"}, + {file = "coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223"}, + {file = "coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f"}, + {file = "coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca"}, + {file = "coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257"}, + {file = "coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050"}, + {file = "coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48"}, + {file = "coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7"}, + {file = "coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3"}, + {file = "coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7"}, + {file = "coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008"}, + {file = "coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be"}, + {file = "coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b"}, + {file = "coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199"}, + {file = "coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8"}, + {file = "coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d"}, + {file = "coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b"}, + {file = "coverage-7.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:496948261eaac5ac9cf43f5d0a9f6eb7a6d4cb3bedb2c5d294138142f5c18f2a"}, + {file = "coverage-7.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eacd2de0d30871eff893bab0b67840a96445edcb3c8fd915e6b11ac4b2f3fa6d"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b039ffddc99ad65d5078ef300e0c7eed08c270dc26570440e3ef18beb816c1ca"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e49824808d4375ede9dd84e9961a59c47f9113039f1a525e6be170aa4f5c34d"}, + {file = "coverage-7.8.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b069938961dfad881dc2f8d02b47645cd2f455d3809ba92a8a687bf513839787"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:de77c3ba8bb686d1c411e78ee1b97e6e0b963fb98b1637658dd9ad2c875cf9d7"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1676628065a498943bd3f64f099bb573e08cf1bc6088bbe33cf4424e0876f4b3"}, + {file = "coverage-7.8.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8e1a26e7e50076e35f7afafde570ca2b4d7900a491174ca357d29dece5aacee7"}, + {file = "coverage-7.8.2-cp39-cp39-win32.whl", hash = "sha256:6782a12bf76fa61ad9350d5a6ef5f3f020b57f5e6305cbc663803f2ebd0f270a"}, + {file = "coverage-7.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:1efa4166ba75ccefd647f2d78b64f53f14fb82622bc94c5a5cb0a622f50f1c9e"}, + {file = "coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837"}, + {file = "coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32"}, + {file = "coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27"}, ] [package.dependencies] @@ -434,38 +438,42 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.2" +version = "1.3.0" description = "Backport of PEP 654 (exception groups)" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, + {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, + {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + [package.extras] test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.109.2" +version = "0.115.12" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, - {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, + {file = "fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d"}, + {file = "fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.36.3,<0.37.0" +starlette = ">=0.40.0,<0.47.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "furo" @@ -487,14 +495,14 @@ sphinx-basic-ng = "*" [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, ] [[package]] @@ -811,116 +819,116 @@ files = [ [[package]] name = "multidict" -version = "6.4.3" +version = "6.4.4" description = "multidict implementation" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "multidict-6.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32a998bd8a64ca48616eac5a8c1cc4fa38fb244a3facf2eeb14abe186e0f6cc5"}, - {file = "multidict-6.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a54ec568f1fc7f3c313c2f3b16e5db346bf3660e1309746e7fccbbfded856188"}, - {file = "multidict-6.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a7be07e5df178430621c716a63151165684d3e9958f2bbfcb644246162007ab7"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b128dbf1c939674a50dd0b28f12c244d90e5015e751a4f339a96c54f7275e291"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9cb19dfd83d35b6ff24a4022376ea6e45a2beba8ef3f0836b8a4b288b6ad685"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3cf62f8e447ea2c1395afa289b332e49e13d07435369b6f4e41f887db65b40bf"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:909f7d43ff8f13d1adccb6a397094adc369d4da794407f8dd592c51cf0eae4b1"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0bb8f8302fbc7122033df959e25777b0b7659b1fd6bcb9cb6bed76b5de67afef"}, - {file = "multidict-6.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:224b79471b4f21169ea25ebc37ed6f058040c578e50ade532e2066562597b8a9"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a7bd27f7ab3204f16967a6f899b3e8e9eb3362c0ab91f2ee659e0345445e0078"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:99592bd3162e9c664671fd14e578a33bfdba487ea64bcb41d281286d3c870ad7"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a62d78a1c9072949018cdb05d3c533924ef8ac9bcb06cbf96f6d14772c5cd451"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ccdde001578347e877ca4f629450973c510e88e8865d5aefbcb89b852ccc666"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:eccb67b0e78aa2e38a04c5ecc13bab325a43e5159a181a9d1a6723db913cbb3c"}, - {file = "multidict-6.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b6fcf6054fc4114a27aa865f8840ef3d675f9316e81868e0ad5866184a6cba5"}, - {file = "multidict-6.4.3-cp310-cp310-win32.whl", hash = "sha256:f92c7f62d59373cd93bc9969d2da9b4b21f78283b1379ba012f7ee8127b3152e"}, - {file = "multidict-6.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:b57e28dbc031d13916b946719f213c494a517b442d7b48b29443e79610acd887"}, - {file = "multidict-6.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f6f19170197cc29baccd33ccc5b5d6a331058796485857cf34f7635aa25fb0cd"}, - {file = "multidict-6.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2882bf27037eb687e49591690e5d491e677272964f9ec7bc2abbe09108bdfb8"}, - {file = "multidict-6.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbf226ac85f7d6b6b9ba77db4ec0704fde88463dc17717aec78ec3c8546c70ad"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e329114f82ad4b9dd291bef614ea8971ec119ecd0f54795109976de75c9a852"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1f4e0334d7a555c63f5c8952c57ab6f1c7b4f8c7f3442df689fc9f03df315c08"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:740915eb776617b57142ce0bb13b7596933496e2f798d3d15a20614adf30d229"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255dac25134d2b141c944b59a0d2f7211ca12a6d4779f7586a98b4b03ea80508"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4e8535bd4d741039b5aad4285ecd9b902ef9e224711f0b6afda6e38d7ac02c7"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c433a33be000dd968f5750722eaa0991037be0be4a9d453eba121774985bc8"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4eb33b0bdc50acd538f45041f5f19945a1f32b909b76d7b117c0c25d8063df56"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:75482f43465edefd8a5d72724887ccdcd0c83778ded8f0cb1e0594bf71736cc0"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce5b3082e86aee80b3925ab4928198450d8e5b6466e11501fe03ad2191c6d777"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e413152e3212c4d39f82cf83c6f91be44bec9ddea950ce17af87fbf4e32ca6b2"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8aac2eeff69b71f229a405c0a4b61b54bade8e10163bc7b44fcd257949620618"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ab583ac203af1d09034be41458feeab7863c0635c650a16f15771e1386abf2d7"}, - {file = "multidict-6.4.3-cp311-cp311-win32.whl", hash = "sha256:1b2019317726f41e81154df636a897de1bfe9228c3724a433894e44cd2512378"}, - {file = "multidict-6.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:43173924fa93c7486402217fab99b60baf78d33806af299c56133a3755f69589"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f1c2f58f08b36f8475f3ec6f5aeb95270921d418bf18f90dffd6be5c7b0e676"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:26ae9ad364fc61b936fb7bf4c9d8bd53f3a5b4417142cd0be5c509d6f767e2f1"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:659318c6c8a85f6ecfc06b4e57529e5a78dfdd697260cc81f683492ad7e9435a"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1eb72c741fd24d5a28242ce72bb61bc91f8451877131fa3fe930edb195f7054"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3cd06d88cb7398252284ee75c8db8e680aa0d321451132d0dba12bc995f0adcc"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4543d8dc6470a82fde92b035a92529317191ce993533c3c0c68f56811164ed07"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:30a3ebdc068c27e9d6081fca0e2c33fdf132ecea703a72ea216b81a66860adde"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b038f10e23f277153f86f95c777ba1958bcd5993194fda26a1d06fae98b2f00c"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c605a2b2dc14282b580454b9b5d14ebe0668381a3a26d0ac39daa0ca115eb2ae"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8bd2b875f4ca2bb527fe23e318ddd509b7df163407b0fb717df229041c6df5d3"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c2e98c840c9c8e65c0e04b40c6c5066c8632678cd50c8721fdbcd2e09f21a507"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66eb80dd0ab36dbd559635e62fba3083a48a252633164857a1d1684f14326427"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c23831bdee0a2a3cf21be057b5e5326292f60472fb6c6f86392bbf0de70ba731"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1535cec6443bfd80d028052e9d17ba6ff8a5a3534c51d285ba56c18af97e9713"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3b73e7227681f85d19dec46e5b881827cd354aabe46049e1a61d2f9aaa4e285a"}, - {file = "multidict-6.4.3-cp312-cp312-win32.whl", hash = "sha256:8eac0c49df91b88bf91f818e0a24c1c46f3622978e2c27035bfdca98e0e18124"}, - {file = "multidict-6.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:11990b5c757d956cd1db7cb140be50a63216af32cd6506329c2c59d732d802db"}, - {file = "multidict-6.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a76534263d03ae0cfa721fea40fd2b5b9d17a6f85e98025931d41dc49504474"}, - {file = "multidict-6.4.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:805031c2f599eee62ac579843555ed1ce389ae00c7e9f74c2a1b45e0564a88dd"}, - {file = "multidict-6.4.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c56c179839d5dcf51d565132185409d1d5dd8e614ba501eb79023a6cab25576b"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c64f4ddb3886dd8ab71b68a7431ad4aa01a8fa5be5b11543b29674f29ca0ba3"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3002a856367c0b41cad6784f5b8d3ab008eda194ed7864aaa58f65312e2abcac"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d75e621e7d887d539d6e1d789f0c64271c250276c333480a9e1de089611f790"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:995015cf4a3c0d72cbf453b10a999b92c5629eaf3a0c3e1efb4b5c1f602253bb"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b0fabae7939d09d7d16a711468c385272fa1b9b7fb0d37e51143585d8e72e0"}, - {file = "multidict-6.4.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61ed4d82f8a1e67eb9eb04f8587970d78fe7cddb4e4d6230b77eda23d27938f9"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:062428944a8dc69df9fdc5d5fc6279421e5f9c75a9ee3f586f274ba7b05ab3c8"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b90e27b4674e6c405ad6c64e515a505c6d113b832df52fdacb6b1ffd1fa9a1d1"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7d50d4abf6729921e9613d98344b74241572b751c6b37feed75fb0c37bd5a817"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:43fe10524fb0a0514be3954be53258e61d87341008ce4914f8e8b92bee6f875d"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:236966ca6c472ea4e2d3f02f6673ebfd36ba3f23159c323f5a496869bc8e47c9"}, - {file = "multidict-6.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:422a5ec315018e606473ba1f5431e064cf8b2a7468019233dcf8082fabad64c8"}, - {file = "multidict-6.4.3-cp313-cp313-win32.whl", hash = "sha256:f901a5aace8e8c25d78960dcc24c870c8d356660d3b49b93a78bf38eb682aac3"}, - {file = "multidict-6.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:1c152c49e42277bc9a2f7b78bd5fa10b13e88d1b0328221e7aef89d5c60a99a5"}, - {file = "multidict-6.4.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:be8751869e28b9c0d368d94f5afcb4234db66fe8496144547b4b6d6a0645cfc6"}, - {file = "multidict-6.4.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d4b31f8a68dccbcd2c0ea04f0e014f1defc6b78f0eb8b35f2265e8716a6df0c"}, - {file = "multidict-6.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:032efeab3049e37eef2ff91271884303becc9e54d740b492a93b7e7266e23756"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e78006af1a7c8a8007e4f56629d7252668344442f66982368ac06522445e375"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:daeac9dd30cda8703c417e4fddccd7c4dc0c73421a0b54a7da2713be125846be"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f6f90700881438953eae443a9c6f8a509808bc3b185246992c4233ccee37fea"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f84627997008390dd15762128dcf73c3365f4ec0106739cde6c20a07ed198ec8"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3307b48cd156153b117c0ea54890a3bdbf858a5b296ddd40dc3852e5f16e9b02"}, - {file = "multidict-6.4.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ead46b0fa1dcf5af503a46e9f1c2e80b5d95c6011526352fa5f42ea201526124"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1748cb2743bedc339d63eb1bca314061568793acd603a6e37b09a326334c9f44"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:acc9fa606f76fc111b4569348cc23a771cb52c61516dcc6bcef46d612edb483b"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:31469d5832b5885adeb70982e531ce86f8c992334edd2f2254a10fa3182ac504"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ba46b51b6e51b4ef7bfb84b82f5db0dc5e300fb222a8a13b8cd4111898a869cf"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:389cfefb599edf3fcfd5f64c0410da686f90f5f5e2c4d84e14f6797a5a337af4"}, - {file = "multidict-6.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:64bc2bbc5fba7b9db5c2c8d750824f41c6994e3882e6d73c903c2afa78d091e4"}, - {file = "multidict-6.4.3-cp313-cp313t-win32.whl", hash = "sha256:0ecdc12ea44bab2807d6b4a7e5eef25109ab1c82a8240d86d3c1fc9f3b72efd5"}, - {file = "multidict-6.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7146a8742ea71b5d7d955bffcef58a9e6e04efba704b52a460134fefd10a8208"}, - {file = "multidict-6.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5427a2679e95a642b7f8b0f761e660c845c8e6fe3141cddd6b62005bd133fc21"}, - {file = "multidict-6.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:24a8caa26521b9ad09732972927d7b45b66453e6ebd91a3c6a46d811eeb7349b"}, - {file = "multidict-6.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6b5a272bc7c36a2cd1b56ddc6bff02e9ce499f9f14ee4a45c45434ef083f2459"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf74dc5e212b8c75165b435c43eb0d5e81b6b300a938a4eb82827119115e840"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9f35de41aec4b323c71f54b0ca461ebf694fb48bec62f65221f52e0017955b39"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae93e0ff43b6f6892999af64097b18561691ffd835e21a8348a441e256592e1f"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e3929269e9d7eff905d6971d8b8c85e7dbc72c18fb99c8eae6fe0a152f2e343"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6214fe1750adc2a1b801a199d64b5a67671bf76ebf24c730b157846d0e90d2"}, - {file = "multidict-6.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d79cf5c0c6284e90f72123f4a3e4add52d6c6ebb4a9054e88df15b8d08444c6"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2427370f4a255262928cd14533a70d9738dfacadb7563bc3b7f704cc2360fc4e"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:fbd8d737867912b6c5f99f56782b8cb81f978a97b4437a1c476de90a3e41c9a1"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0ee1bf613c448997f73fc4efb4ecebebb1c02268028dd4f11f011f02300cf1e8"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:578568c4ba5f2b8abd956baf8b23790dbfdc953e87d5b110bce343b4a54fc9e7"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:a059ad6b80de5b84b9fa02a39400319e62edd39d210b4e4f8c4f1243bdac4752"}, - {file = "multidict-6.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:dd53893675b729a965088aaadd6a1f326a72b83742b056c1065bdd2e2a42b4df"}, - {file = "multidict-6.4.3-cp39-cp39-win32.whl", hash = "sha256:abcfed2c4c139f25c2355e180bcc077a7cae91eefbb8b3927bb3f836c9586f1f"}, - {file = "multidict-6.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:b1b389ae17296dd739015d5ddb222ee99fd66adeae910de21ac950e00979d897"}, - {file = "multidict-6.4.3-py3-none-any.whl", hash = "sha256:59fe01ee8e2a1e8ceb3f6dbb216b09c8d9f4ef1c22c4fc825d045a147fa2ebc9"}, - {file = "multidict-6.4.3.tar.gz", hash = "sha256:3ada0b058c9f213c5f95ba301f922d402ac234f1111a7d8fd70f1b99f3c281ec"}, + {file = "multidict-6.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8adee3ac041145ffe4488ea73fa0a622b464cc25340d98be76924d0cda8545ff"}, + {file = "multidict-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b61e98c3e2a861035aaccd207da585bdcacef65fe01d7a0d07478efac005e028"}, + {file = "multidict-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75493f28dbadecdbb59130e74fe935288813301a8554dc32f0c631b6bdcdf8b0"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc3c6a37e048b5395ee235e4a2a0d639c2349dffa32d9367a42fc20d399772"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:87cb72263946b301570b0f63855569a24ee8758aaae2cd182aae7d95fbc92ca7"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bbf7bd39822fd07e3609b6b4467af4c404dd2b88ee314837ad1830a7f4a8299"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1f7cbd4f1f44ddf5fd86a8675b7679176eae770f2fc88115d6dddb6cefb59bc"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5ac9e5bfce0e6282e7f59ff7b7b9a74aa8e5c60d38186a4637f5aa764046ad"}, + {file = "multidict-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4efc31dfef8c4eeb95b6b17d799eedad88c4902daba39ce637e23a17ea078915"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fcad2945b1b91c29ef2b4050f590bfcb68d8ac8e0995a74e659aa57e8d78e01"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d877447e7368c7320832acb7159557e49b21ea10ffeb135c1077dbbc0816b598"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:33a12ebac9f380714c298cbfd3e5b9c0c4e89c75fe612ae496512ee51028915f"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0f14ea68d29b43a9bf37953881b1e3eb75b2739e896ba4a6aa4ad4c5b9ffa145"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0327ad2c747a6600e4797d115d3c38a220fdb28e54983abe8964fd17e95ae83c"}, + {file = "multidict-6.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d1a20707492db9719a05fc62ee215fd2c29b22b47c1b1ba347f9abc831e26683"}, + {file = "multidict-6.4.4-cp310-cp310-win32.whl", hash = "sha256:d83f18315b9fca5db2452d1881ef20f79593c4aa824095b62cb280019ef7aa3d"}, + {file = "multidict-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:9c17341ee04545fd962ae07330cb5a39977294c883485c8d74634669b1f7fe04"}, + {file = "multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95"}, + {file = "multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a"}, + {file = "multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2"}, + {file = "multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c"}, + {file = "multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08"}, + {file = "multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49"}, + {file = "multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529"}, + {file = "multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2"}, + {file = "multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d"}, + {file = "multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1"}, + {file = "multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740"}, + {file = "multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e"}, + {file = "multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b"}, + {file = "multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781"}, + {file = "multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9"}, + {file = "multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf"}, + {file = "multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c"}, + {file = "multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4"}, + {file = "multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1"}, + {file = "multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd"}, + {file = "multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373"}, + {file = "multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156"}, + {file = "multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c"}, + {file = "multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab"}, + {file = "multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e"}, + {file = "multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd"}, + {file = "multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e"}, + {file = "multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb"}, + {file = "multidict-6.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:603f39bd1cf85705c6c1ba59644b480dfe495e6ee2b877908de93322705ad7cf"}, + {file = "multidict-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc60f91c02e11dfbe3ff4e1219c085695c339af72d1641800fe6075b91850c8f"}, + {file = "multidict-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:496bcf01c76a70a31c3d746fd39383aad8d685ce6331e4c709e9af4ced5fa221"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4219390fb5bf8e548e77b428bb36a21d9382960db5321b74d9d9987148074d6b"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef4e9096ff86dfdcbd4a78253090ba13b1d183daa11b973e842465d94ae1772"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49a29d7133b1fc214e818bbe025a77cc6025ed9a4f407d2850373ddde07fd04a"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e32053d6d3a8b0dfe49fde05b496731a0e6099a4df92154641c00aa76786aef5"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc403092a49509e8ef2d2fd636a8ecefc4698cc57bbe894606b14579bc2a955"}, + {file = "multidict-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5363f9b2a7f3910e5c87d8b1855c478c05a2dc559ac57308117424dfaad6805c"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e543a40e4946cf70a88a3be87837a3ae0aebd9058ba49e91cacb0b2cd631e2b"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:60d849912350da557fe7de20aa8cf394aada6980d0052cc829eeda4a0db1c1db"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:19d08b4f22eae45bb018b9f06e2838c1e4b853c67628ef8ae126d99de0da6395"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d693307856d1ef08041e8b6ff01d5b4618715007d288490ce2c7e29013c12b9a"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fad6daaed41021934917f4fb03ca2db8d8a4d79bf89b17ebe77228eb6710c003"}, + {file = "multidict-6.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c10d17371bff801af0daf8b073c30b6cf14215784dc08cd5c43ab5b7b8029bbc"}, + {file = "multidict-6.4.4-cp39-cp39-win32.whl", hash = "sha256:7e23f2f841fcb3ebd4724a40032d32e0892fbba4143e43d2a9e7695c5e50e6bd"}, + {file = "multidict-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d7b50b673ffb4ff4366e7ab43cf1f0aef4bd3608735c5fbdf0bdb6f690da411"}, + {file = "multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac"}, + {file = "multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8"}, ] [package.dependencies] @@ -982,14 +990,14 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "1.0.0" +version = "1.1.0" description = "Type system extensions for programs checked with the mypy type checker." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, ] [[package]] @@ -1076,14 +1084,14 @@ files = [ [[package]] name = "packaging" -version = "24.2" +version = "25.0" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] [[package]] @@ -1187,14 +1195,14 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.7" +version = "4.3.8" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, - {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, + {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, + {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, ] [package.extras] @@ -1204,19 +1212,19 @@ type = ["mypy (>=1.14.1)"] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, ] [package.extras] dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] +testing = ["coverage", "pytest", "pytest-benchmark"] [[package]] name = "propcache" @@ -1383,19 +1391,19 @@ test = ["cffi", "hypothesis", "pandas", "pytest", "pytz"] [[package]] name = "pydantic" -version = "2.11.3" +version = "2.11.5" description = "Data validation using Python type hints" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f"}, - {file = "pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3"}, + {file = "pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7"}, + {file = "pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.33.1" +pydantic-core = "2.33.2" typing-extensions = ">=4.12.2" typing-inspection = ">=0.4.0" @@ -1405,111 +1413,111 @@ timezone = ["tzdata"] [[package]] name = "pydantic-core" -version = "2.33.1" +version = "2.33.2" description = "Core functionality for Pydantic validation and serialization" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "pydantic_core-2.33.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3077cfdb6125cc8dab61b155fdd714663e401f0e6883f9632118ec12cf42df26"}, - {file = "pydantic_core-2.33.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ffab8b2908d152e74862d276cf5017c81a2f3719f14e8e3e8d6b83fda863927"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5183e4f6a2d468787243ebcd70cf4098c247e60d73fb7d68d5bc1e1beaa0c4db"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:398a38d323f37714023be1e0285765f0a27243a8b1506b7b7de87b647b517e48"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3776f0001b43acebfa86f8c64019c043b55cc5a6a2e313d728b5c95b46969"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c566dd9c5f63d22226409553531f89de0cac55397f2ab8d97d6f06cfce6d947e"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0d5f3acc81452c56895e90643a625302bd6be351e7010664151cc55b7b97f89"}, - {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d3a07fadec2a13274a8d861d3d37c61e97a816beae717efccaa4b36dfcaadcde"}, - {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f99aeda58dce827f76963ee87a0ebe75e648c72ff9ba1174a253f6744f518f65"}, - {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:902dbc832141aa0ec374f4310f1e4e7febeebc3256f00dc359a9ac3f264a45dc"}, - {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fe44d56aa0b00d66640aa84a3cbe80b7a3ccdc6f0b1ca71090696a6d4777c091"}, - {file = "pydantic_core-2.33.1-cp310-cp310-win32.whl", hash = "sha256:ed3eb16d51257c763539bde21e011092f127a2202692afaeaccb50db55a31383"}, - {file = "pydantic_core-2.33.1-cp310-cp310-win_amd64.whl", hash = "sha256:694ad99a7f6718c1a498dc170ca430687a39894a60327f548e02a9c7ee4b6504"}, - {file = "pydantic_core-2.33.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6e966fc3caaf9f1d96b349b0341c70c8d6573bf1bac7261f7b0ba88f96c56c24"}, - {file = "pydantic_core-2.33.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bfd0adeee563d59c598ceabddf2c92eec77abcb3f4a391b19aa7366170bd9e30"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91815221101ad3c6b507804178a7bb5cb7b2ead9ecd600041669c8d805ebd595"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9fea9c1869bb4742d174a57b4700c6dadea951df8b06de40c2fedb4f02931c2e"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d20eb4861329bb2484c021b9d9a977566ab16d84000a57e28061151c62b349a"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb935c5591573ae3201640579f30128ccc10739b45663f93c06796854405505"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c964fd24e6166420d18fb53996d8c9fd6eac9bf5ae3ec3d03015be4414ce497f"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:681d65e9011f7392db5aa002b7423cc442d6a673c635668c227c6c8d0e5a4f77"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e100c52f7355a48413e2999bfb4e139d2977a904495441b374f3d4fb4a170961"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:048831bd363490be79acdd3232f74a0e9951b11b2b4cc058aeb72b22fdc3abe1"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bdc84017d28459c00db6f918a7272a5190bec3090058334e43a76afb279eac7c"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win32.whl", hash = "sha256:32cd11c5914d1179df70406427097c7dcde19fddf1418c787540f4b730289896"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win_amd64.whl", hash = "sha256:2ea62419ba8c397e7da28a9170a16219d310d2cf4970dbc65c32faf20d828c83"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win_arm64.whl", hash = "sha256:fc903512177361e868bc1f5b80ac8c8a6e05fcdd574a5fb5ffeac5a9982b9e89"}, - {file = "pydantic_core-2.33.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1293d7febb995e9d3ec3ea09caf1a26214eec45b0f29f6074abb004723fc1de8"}, - {file = "pydantic_core-2.33.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99b56acd433386c8f20be5c4000786d1e7ca0523c8eefc995d14d79c7a081498"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35a5ec3fa8c2fe6c53e1b2ccc2454398f95d5393ab398478f53e1afbbeb4d939"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b172f7b9d2f3abc0efd12e3386f7e48b576ef309544ac3a63e5e9cdd2e24585d"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9097b9f17f91eea659b9ec58148c0747ec354a42f7389b9d50701610d86f812e"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc77ec5b7e2118b152b0d886c7514a4653bcb58c6b1d760134a9fab915f777b3"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3d15245b08fa4a84cefc6c9222e6f37c98111c8679fbd94aa145f9a0ae23d"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef99779001d7ac2e2461d8ab55d3373fe7315caefdbecd8ced75304ae5a6fc6b"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fc6bf8869e193855e8d91d91f6bf59699a5cdfaa47a404e278e776dd7f168b39"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:b1caa0bc2741b043db7823843e1bde8aaa58a55a58fda06083b0569f8b45693a"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ec259f62538e8bf364903a7d0d0239447059f9434b284f5536e8402b7dd198db"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win32.whl", hash = "sha256:e14f369c98a7c15772b9da98987f58e2b509a93235582838bd0d1d8c08b68fda"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win_amd64.whl", hash = "sha256:1c607801d85e2e123357b3893f82c97a42856192997b95b4d8325deb1cd0c5f4"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d13f0276806ee722e70a1c93da19748594f19ac4299c7e41237fc791d1861ea"}, - {file = "pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a"}, - {file = "pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d"}, - {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4"}, - {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde"}, - {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e"}, - {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd"}, - {file = "pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f"}, - {file = "pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40"}, - {file = "pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523"}, - {file = "pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d"}, - {file = "pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c"}, - {file = "pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18"}, - {file = "pydantic_core-2.33.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5ab77f45d33d264de66e1884fca158bc920cb5e27fd0764a72f72f5756ae8bdb"}, - {file = "pydantic_core-2.33.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7aaba1b4b03aaea7bb59e1b5856d734be011d3e6d98f5bcaa98cb30f375f2ad"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fb66263e9ba8fea2aa85e1e5578980d127fb37d7f2e292773e7bc3a38fb0c7b"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f2648b9262607a7fb41d782cc263b48032ff7a03a835581abbf7a3bec62bcf5"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:723c5630c4259400818b4ad096735a829074601805d07f8cafc366d95786d331"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d100e3ae783d2167782391e0c1c7a20a31f55f8015f3293647544df3f9c67824"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177d50460bc976a0369920b6c744d927b0ecb8606fb56858ff542560251b19e5"}, - {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3edde68d1a1f9af1273b2fe798997b33f90308fb6d44d8550c89fc6a3647cf6"}, - {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a62c3c3ef6a7e2c45f7853b10b5bc4ddefd6ee3cd31024754a1a5842da7d598d"}, - {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:c91dbb0ab683fa0cd64a6e81907c8ff41d6497c346890e26b23de7ee55353f96"}, - {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f466e8bf0a62dc43e068c12166281c2eca72121dd2adc1040f3aa1e21ef8599"}, - {file = "pydantic_core-2.33.1-cp39-cp39-win32.whl", hash = "sha256:ab0277cedb698749caada82e5d099dc9fed3f906a30d4c382d1a21725777a1e5"}, - {file = "pydantic_core-2.33.1-cp39-cp39-win_amd64.whl", hash = "sha256:5773da0ee2d17136b1f1c6fbde543398d452a6ad2a7b54ea1033e2daa739b8d2"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c834f54f8f4640fd7e4b193f80eb25a0602bba9e19b3cd2fc7ffe8199f5ae02"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:049e0de24cf23766f12cc5cc71d8abc07d4a9deb9061b334b62093dedc7cb068"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a28239037b3d6f16916a4c831a5a0eadf856bdd6d2e92c10a0da3a59eadcf3e"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d3da303ab5f378a268fa7d45f37d7d85c3ec19769f28d2cc0c61826a8de21fe"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25626fb37b3c543818c14821afe0fd3830bc327a43953bc88db924b68c5723f1"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3ab2d36e20fbfcce8f02d73c33a8a7362980cff717926bbae030b93ae46b56c7"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:2f9284e11c751b003fd4215ad92d325d92c9cb19ee6729ebd87e3250072cdcde"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:048c01eee07d37cbd066fc512b9d8b5ea88ceeb4e629ab94b3e56965ad655add"}, - {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5ccd429694cf26af7997595d627dd2637e7932214486f55b8a357edaac9dae8c"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a371dc00282c4b84246509a5ddc808e61b9864aa1eae9ecc92bb1268b82db4a"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f59295ecc75a1788af8ba92f2e8c6eeaa5a94c22fc4d151e8d9638814f85c8fc"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08530b8ac922003033f399128505f513e30ca770527cc8bbacf75a84fcc2c74b"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae370459da6a5466978c0eacf90690cb57ec9d533f8e63e564ef3822bfa04fe"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e3de2777e3b9f4d603112f78006f4ae0acb936e95f06da6cb1a45fbad6bdb4b5"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a64e81e8cba118e108d7126362ea30e021291b7805d47e4896e52c791be2761"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:52928d8c1b6bda03cc6d811e8923dffc87a2d3c8b3bfd2ce16471c7147a24850"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1b30d92c9412beb5ac6b10a3eb7ef92ccb14e3f2a8d7732e2d739f58b3aa7544"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f995719707e0e29f0f41a8aa3bcea6e761a36c9136104d3189eafb83f5cec5e5"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7edbc454a29fc6aeae1e1eecba4f07b63b8d76e76a748532233c4c167b4cb9ea"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad05b683963f69a1d5d2c2bdab1274a31221ca737dbbceaa32bcb67359453cdd"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df6a94bf9452c6da9b5d76ed229a5683d0306ccb91cca8e1eea883189780d568"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7965c13b3967909a09ecc91f21d09cfc4576bf78140b988904e94f130f188396"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3f1fdb790440a34f6ecf7679e1863b825cb5ffde858a9197f851168ed08371e5"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5277aec8d879f8d05168fdd17ae811dd313b8ff894aeeaf7cd34ad28b4d77e33"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8ab581d3530611897d863d1a649fb0644b860286b4718db919bfd51ece41f10b"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0483847fa9ad5e3412265c1bd72aad35235512d9ce9d27d81a56d935ef489672"}, - {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:de9e06abe3cc5ec6a2d5f75bc99b0bdca4f5c719a5b34026f8c57efbdecd2ee3"}, - {file = "pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, + {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, ] [package.dependencies] @@ -1773,26 +1781,26 @@ files = [ [[package]] name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +version = "3.0.1" +description = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." category = "dev" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*" files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, + {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, + {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, ] [[package]] name = "soupsieve" -version = "2.6" +version = "2.7" description = "A modern CSS selector implementation for Beautiful Soup." category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, - {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, + {file = "soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4"}, + {file = "soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a"}, ] [[package]] @@ -1990,22 +1998,22 @@ test = ["pytest"] [[package]] name = "starlette" -version = "0.36.3" +version = "0.46.2" description = "The little ASGI library that shines." category = "dev" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, - {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, + {file = "starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35"}, + {file = "starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5"}, ] [package.dependencies] -anyio = ">=3.4.0,<5" +anyio = ">=3.6.2,<5" typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] +full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"] [[package]] name = "tomli" @@ -2075,14 +2083,14 @@ files = [ [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.1" description = "Runtime typing introspection tools" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, - {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, + {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"}, + {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"}, ] [package.dependencies] @@ -2119,14 +2127,14 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "uvicorn" -version = "0.34.1" +version = "0.34.2" description = "The lightning-fast ASGI server." category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "uvicorn-0.34.1-py3-none-any.whl", hash = "sha256:984c3a8c7ca18ebaad15995ee7401179212c59521e67bfc390c07fa2b8d2e065"}, - {file = "uvicorn-0.34.1.tar.gz", hash = "sha256:af981725fc4b7ffc5cb3b0e9eda6258a90c4b52cb2a83ce567ae0a7ae1757afc"}, + {file = "uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403"}, + {file = "uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328"}, ] [package.dependencies] @@ -2588,14 +2596,14 @@ propcache = ">=0.2.1" [[package]] name = "zipp" -version = "3.21.0" +version = "3.22.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.9" files = [ - {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, - {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, + {file = "zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343"}, + {file = "zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5"}, ] [package.extras] @@ -2603,7 +2611,7 @@ check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +test = ["big-O", "importlib_resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] type = ["pytest-mypy"] [extras] @@ -2612,4 +2620,4 @@ docs = [] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "dcf96220a9ced6d5031be7d2eddbe1415df89297f41848366e42d105eb55562f" +content-hash = "0f7dfb98daffdd53ab296fe780eb6967f02b3c1408604ad8fd757ca54a3379ef" diff --git a/pyproject.toml b/pyproject.toml index 57193a2..901f846 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ mypy = "^1.0.1" pytest = "^8.3.4" pytest-cov = "^4.0.0" python-dotenv = "^1.0.0" -fastapi = "^0.109.2" +fastapi = "^0.115.12" uvicorn = {extras = ["standard"], version = "^0.34.1"} pytest-recording = "^0.12.2" vcrpy = "^4.2.1" From 5b0ce88c93a77bf701ce7089e7dcc2a385717be6 Mon Sep 17 00:00:00 2001 From: renae-r Date: Mon, 2 Jun 2025 10:20:38 -0500 Subject: [PATCH 13/20] amv docs fix --- docs/source/ipums_api/ipums_api_micro/index.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/source/ipums_api/ipums_api_micro/index.rst b/docs/source/ipums_api/ipums_api_micro/index.rst index a267c98..dc0f9fe 100644 --- a/docs/source/ipums_api/ipums_api_micro/index.rst +++ b/docs/source/ipums_api/ipums_api_micro/index.rst @@ -287,11 +287,14 @@ Inflation adjusted values are only available for continuous variables that repre extract = MicrodataExtract( collection="cps", - samples=["cps2022_03s"], - variables=["AGE", "SEX", "INCTOT"], + samples=["cps2022_03b"], + variables=["AGE", "SEX", "HOURWAGE"], ) - extract.adjust_monetary_values("INCTOT") + extract.adjust_monetary_values("HOURWAGE") + +.. note:: + The Adjust Monetary Values feature is not currently available for IPUMS CPS ASEC variables. .. _Using Variable Objects to Include Extract Features: @@ -318,7 +321,7 @@ data quality flag for RACE (``data_quality_flags``), and an inflation-adjusted v case_selections={"general": ["2"]}), Variable(name="RACE", data_quality_flags=True), - Variable(name="INCTOT", + Variable(name="HOURWAGE", adjust_monetary_values=True), ], description="A fancy CPS extract", From 3666a6fbf1b55f9f283d8f71107535b53b5278ee Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Mon, 2 Jun 2025 13:25:03 -0400 Subject: [PATCH 14/20] Revert removal of NHGIS data source check --- src/ipumspy/api/extract.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index f642f1e..b3732ea 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -811,6 +811,15 @@ def __init__( time_series_tables, TimeSeriesTable ) self.shapefiles = self._validate_list_args(shapefiles, Shapefile) + + if ( + len(self.datasets) == 0 + and len(self.time_series_tables) == 0 + and len(self.shapefiles) == 0 + ): + raise ValueError( + "At least one dataset, time series table, or shapefile must be specified." + ) elif collection == "ihgis": self.datasets = self._validate_list_args(datasets, IhgisDataset) self.data_format = None From 6ab1d899b2ad49c78a2470470f09be3b793f2dc7 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 3 Jun 2025 14:02:21 -0400 Subject: [PATCH 15/20] Add IHGIS to website docs --- docs/source/ipums_api/index.rst | 50 +++++--- .../ipums_api/ipums_api_aggregate/index.rst | 119 ++++++++++++------ docs/source/reading_data.rst | 5 - src/ipumspy/api/extract.py | 20 +-- 4 files changed, 127 insertions(+), 67 deletions(-) diff --git a/docs/source/ipums_api/index.rst b/docs/source/ipums_api/index.rst index dbfa3c9..15405ec 100644 --- a/docs/source/ipums_api/index.rst +++ b/docs/source/ipums_api/index.rst @@ -88,6 +88,11 @@ available features for all collections currently supported by the API: - ``nhgis`` - **X** - **X** + * - `IPUMS IHGIS `__ + - Aggregate data + - ``ihgis`` + - **X** + - **X** Note that ipumspy may not necessarily support all the functionality currently supported by the IPUMS API. See the `API documentation `__ for more information @@ -195,29 +200,44 @@ metadata obtained for the requested data source: tst.description #> 'Total Population' -The following table summarizes the currently available metadata endpoints: +The following table summarizes the currently available metadata endpoints. Endpoints listed +in the **Metadata type** column can be used with the indicated collection in :py:meth:`.get_metadata_catalog`. +Classes listed in the **Detailed metadata class** column can be used to obtain detailed metadata for +individual data sources of that type. .. _metadata support table: .. list-table:: Supported metadata endpoints - :widths: 2 3 5 + :widths: 3 2 5 :header-rows: 1 :align: center - * - Metadata type - - Supported collections - - Detailed metadata class analog - * - ``datasets`` - - IPUMS NHGIS - - :py:class:`~ipumspy.api.metadata.DatasetMetadata` - * - ``data_tables`` - - IPUMS NHGIS - - :py:class:`~ipumspy.api.metadata.DataTableMetadata` - * - ``time_series_tables`` - - IPUMS NHGIS + * - Collection + - Metadata type + - Detailed metadata class + * - NHGIS + - ``datasets`` + - :py:class:`~ipumspy.api.metadata.NhgisDatasetMetadata` + * - NHGIS + - ``data_tables`` + - :py:class:`~ipumspy.api.metadata.NhgisDataTableMetadata` + * - NHGIS + - ``time_series_tables`` - :py:class:`~ipumspy.api.metadata.TimeSeriesTableMetadata` - * - ``shapefiles`` - - IPUMS NHGIS + * - NHGIS + - ``shapefiles`` + - + * - + - + - + * - IHGIS + - ``datasets`` + - :py:class:`~ipumspy.api.metadata.IhgisDatasetMetadata` + * - IHGIS + - ``data_tables`` + - :py:class:`~ipumspy.api.metadata.IhgisDataTableMetadata` + * - IHGIS + - ``tabulation_geographies`` - .. _submit-extract: diff --git a/docs/source/ipums_api/ipums_api_aggregate/index.rst b/docs/source/ipums_api/ipums_api_aggregate/index.rst index 1aa57d8..03e1b78 100644 --- a/docs/source/ipums_api/ipums_api_aggregate/index.rst +++ b/docs/source/ipums_api/ipums_api_aggregate/index.rst @@ -6,9 +6,25 @@ Aggregate Data Extracts ======================= IPUMS aggregate data collections distribute aggregated statistics for a set of geographic units. +IPUMS contains two aggregate data collections, both of which are supported by the IPUMS API: -Currently, `IPUMS NHGIS `__ is the only aggregate data collection -supported by the IPUMS API. +- `IPUMS NHGIS `__ +- `IPUMS IHGIS `__ + +IPUMS NHGIS provides 3 different types of data sources: + +- Datasets/data tables +- Time series tables +- Shapefiles + +IPUMS IHGIS provides 1 type of data source: + +- Datasets/data tables + +.. note:: + IHGIS does provide boundary shapefiles, but these are not provided + via the IPUMS API. Shapefiles from IHGIS can be downloaded directly from the + `IHGIS website `__. Extract Objects --------------- @@ -16,26 +32,20 @@ Extract Objects Construct an extract for an IPUMS aggregate data collection using the :class:`AggregateDataExtract` class. An ``AggregateDataExtract`` must contain an IPUMS collection ID -and at least one data source. IPUMS NHGIS provides 3 different types of data sources: - -- Datasets/data tables -- Time series tables -- Shapefiles - -We also recommend providing an extract description to make it easier to identify and -retrieve your extract in the future. +and at least one data source. We also recommend providing an extract description +to make it easier to identify and retrieve your extract in the future. For example: .. code:: python - from ipumspy import AggregateDataExtract, Dataset + from ipumspy import AggregateDataExtract, NhgisDataset extract = AggregateDataExtract( collection="nhgis", description="An NHGIS extract example", datasets=[ - Dataset(name="1990_STF1", data_tables=["NP1", "NP2"], geog_levels=["county"]) + NhgisDataset(name="1990_STF1", data_tables=["NP1", "NP2"], geog_levels=["county"]) ] ) @@ -48,9 +58,7 @@ After instantiation, an ``AggregateDataExtract`` object can be .. note:: The IPUMS API provides a set of metadata endpoints for aggregate data collections that allow you - to browse available data sources and identify their associated API codes. - - You can also browse metadata interactively through the `NHGIS Data Finder `_. + to browse available data sources and identify their associated API codes (see below for examples). Datasets + Data Tables ---------------------- @@ -59,12 +67,17 @@ An IPUMS **dataset** contains a collection of **data tables** that each correspo A dataset is distinguished by the years, geographic levels, and topics that it covers. For instance, 2021 1-year data from the American Community Survey (ACS) is encapsulated in a single dataset. In other cases, a single census product will be split into multiple datasets, typically based on the lowest-level geography for which a set of tables is available. See the -`NHGIS documentation `_ for more details. +`NHGIS `_ and `IHGIS `__ documentation +for more details. To request data contained in an IPUMS dataset, you need to specify the name of the dataset, name of the data table(s) to request -from that dataset, and the geographic level at which those tables should be aggregated. +from that dataset, and the geographic level at which those tables should be aggregated. + +NHGIS Datasets +++++++++++++++ -Use the :class:`Dataset ` class to specify these parameters. +For NHGIS extracts, use the +:class:`NhgisDataset ` class to specify these parameters: .. code:: python @@ -72,7 +85,7 @@ Use the :class:`Dataset ` class to specify these pa collection="nhgis", description="An NHGIS example extract", datasets=[ - Dataset(name="2000_SF1a", data_tables=["NP001A", "NP031A"], geog_levels=["state"]) + NhgisDataset(name="2000_SF1a", data_tables=["NP001A", "NP031A"], geog_levels=["state"]) ], ) @@ -84,7 +97,7 @@ Some datasets span multiple years and require a selection of ``years``: collection="nhgis", description="An NHGIS example extract", datasets=[ - Dataset( + NhgisDataset( name="1988_1997_CBPa", data_tables=["NT004"], geog_levels=["county"], @@ -105,7 +118,7 @@ for a dataset with the ``breakdown_values`` keyword argument: collection="nhgis", description="An NHGIS example extract", datasets=[ - Dataset( + NhgisDataset( name="2000_SF1a", data_tables=["NP001A", "NP031A"], geog_levels=["state"], @@ -122,23 +135,49 @@ For datasets with multiple breakdowns or data types (e.g., the American Communit and margins of error), you can request that the data for each be provided in separate files or together in a single file using the ``breakdown_and_data_type_layout`` argument. +IHGIS Datasets +++++++++++++++ + +For IHGIS, each dataset must be associated with a selection of data tables and tabulation geographies +(the level of geographic aggregation for the requested data). These are the only available parameters +for IHGIS dataset requests. + +.. code:: python + + AggregateDataExtract( + collection="ihgis", + description="An IHGIS example extract", + datasets=[ + IhgisDataset( + "KZ2009pop", + data_tables=["KZ2009pop.AAA"], + tabulation_geographies=["KZ2009pop.g0"] + ) + ] + ) + +.. caution:: + IHGIS extract requests only accept input for ``description`` and ``datasets``. Other ``AggregateDataExtract`` + arguments do not apply to IHGIS extracts and will be omitted from the extract request if included. + Dataset + Data Table Metadata +++++++++++++++++++++++++++++ You can obtain a listing of datasets and data tables as well as detailed information about individual datasets and data tables via the :ref:`IPUMS Metadata API `. -Use the :class:`DatasetMetadata ` data class to browse the available -specification options for a particular dataset and identify the codes to use when -requesting data from the API: +Use the :class:`NhgisDatasetMetadata ` and +:class:`IhgisDatasetMetadata ` data classes +to browse the available specification options for a particular dataset and identify +the codes to use when requesting data from the API: .. code:: python - from ipumspy import IpumsApiClient, DatasetMetadata + from ipumspy import IpumsApiClient, NhgisDatasetMetadata ipums = IpumsApiClient(os.environ.get("IPUMS_API_KEY")) - ds = ipums.get_metadata(DatasetMetadata("nhgis", "2000_SF1a")) + ds = ipums.get_metadata(NhgisDatasetMetadata("2000_SF1a")) The returned object will contain the metadata for the requested dataset. For example: @@ -152,7 +191,9 @@ The returned object will contain the metadata for the requested dataset. For exa # etc... -You can also request metadata for individual data tables using the same workflow with the :class:`DataTableMetadata ` data class. +You can also request metadata for individual data tables using the same workflow with the +:class:`NhgisDataTableMetadata ` and +:class:`IhgisDataTableMetadata ` data classes. Time Series Tables ------------------ @@ -162,7 +203,7 @@ U.S. censuses in a single package. A table is comprised of one or more related t of which describes a single summary statistic measured at multiple times for a given geographic level. Use the :class:`TimeSeriesTable` class to add time series tables -to your extract request. +to your NHGIS extract request. Time series tables are already associated with a specific summary statistic, so they don't require an additional selection of data tables as is required for NHGIS datasets. However, you will need to specify the geographic @@ -218,7 +259,7 @@ Geographic Extent Selection When working with small geographies it can be computationally intensive to work with nationwide data. To avoid this problem, you can request data from a specific geographic area -using the ``geographic_extents`` argument +using the ``geographic_extents`` argument. This argument is only available for NHGIS extracts. The following extract requests ACS 5-year sex-by-age counts at the census block group level, but only includes block groups that fall within Alabama and Arkansas (identified by their FIPS codes with @@ -230,15 +271,15 @@ a trailing 0): collection="nhgis", description="Extent selection example", datasets=[ - Dataset(name="2018_2022_ACS5a", data_tables=["B01001"], geog_levels=["blck_grp"]), - Dataset(name="2017_2021_ACS5a", data_tables=["B01001"], geog_levels=["blck_grp"]) + NhgisDataset(name="2018_2022_ACS5a", data_tables=["B01001"], geog_levels=["blck_grp"]), + NhgisDataset(name="2017_2021_ACS5a", data_tables=["B01001"], geog_levels=["blck_grp"]) ], geographic_extents=["010", "050"] ) .. tip:: You can see available extent selection API codes, if any, in the ``geographic_instances`` attribute of - a submitted :class:`DatasetMetadata ` or + a submitted :class:`NhgisDatasetMetadata ` or :class:`TimeSeriesTableMetadata ` object. The ``geog_levels`` attribute indicates whether a given geographic level supports extent selection. @@ -261,6 +302,8 @@ simply by specifying their names: shapefiles=["us_county_2021_tl2021", "us_county_2020_tl2020"] ) +As mentioned above, IHGIS shapefiles must be downloaded directly from the `IHGIS website `__. + Shapefile Metadata ++++++++++++++++++ @@ -282,8 +325,8 @@ datasets: collection="nhgis", description="An NHGIS example extract", datasets=[ - Dataset(name="2000_SF1a", data_tables=["NP001A"], geog_levels=["state"]), - Dataset(name="2010_SF1a", data_tables=["P1"], geog_levels=["state"]) + NhgisDataset(name="2000_SF1a", data_tables=["NP001A"], geog_levels=["state"]), + NhgisDataset(name="2010_SF1a", data_tables=["P1"], geog_levels=["state"]) ], shapefiles=["us_state_2000_tl2010", "us_state_2010_tl2010"] ) @@ -296,7 +339,7 @@ several ACS years at once using list comprehensions. For instance: acs1_names = ["2017_ACS1", "2018_ACS1", "2019_ACS1"] acs1_specs = [ - Dataset(name, data_tables=["B01001"], geog_levels=["state"]) for name in acs1_names + NhgisDataset(name, data_tables=["B01001"], geog_levels=["state"]) for name in acs1_names ] # Total state-level population from 2017-2019 ACS 1-year estimates @@ -313,8 +356,10 @@ By default, NHGIS extracts are provided in CSV format with only a single header If you like, you can request that your CSV data include a second header row containing a description of each column's contents by setting ``data_format="csv_header"``. -You can also request your data in -fixed-width format if so desired. Note that unlike for microdata projects, NHGIS does +While you can also request your data in +fixed-width format, NHGIS is likely to phase out support for this format in the +future. We therefore suggest that you request data in CSV format. +Also note that unlike for microdata projects, NHGIS does not provide DDI codebook files (in XML format), which allow ipumspy to parse microdata fixed-width files. Thus, loading an NHGIS fixed width file will require manual work to parse the file correctly. diff --git a/docs/source/reading_data.rst b/docs/source/reading_data.rst index 9e8fdb9..d8b5b76 100644 --- a/docs/source/reading_data.rst +++ b/docs/source/reading_data.rst @@ -136,11 +136,6 @@ pandas to load the compressed csv file: with z.open(names[0]) as f: data = pd.read_csv(f) -.. note:: - IPUMS NHGIS does allow you to request an extract in fixed-width format, but ipumspy does not - provide methods to parse these files as it does for Microdata because IPUMS NHGIS does not provide - the necessary DDI codebook. - Shapefile data is delivered in a nested zipfile that can also be unpacked using the ``ZipFile`` module and read using third party libraries such as geopandas. Reading Non-Extractable IPUMS Collections diff --git a/src/ipumspy/api/extract.py b/src/ipumspy/api/extract.py index b3732ea..9be95f2 100644 --- a/src/ipumspy/api/extract.py +++ b/src/ipumspy/api/extract.py @@ -743,7 +743,7 @@ def select_cases( self._update_variable_feature( variable, "case_selections", {"detailed": values} ) - + def adjust_monetary_values( self, variable: Union[Variable, str, List[Variable], List[str]] ): @@ -781,16 +781,16 @@ def __init__( Class for defining an extract request for an IPUMS aggregate data collection. Args: - datasets: list of ``NhgisDataset`` if ``collection="nhgis"`` or ``IhgisDataset`` objects if ``collection="ihgis"`` - time_series_tables: list of ``TimeSeriesTable`` objects - shapefiles: list of shapefile names + datasets: list of ``NhgisDataset`` objects (for NHGIS extracts) or ``IhgisDataset`` objects (for IHGIS extracts) + time_series_tables: list of ``TimeSeriesTable`` objects (for NHGIS extracts) + shapefiles: list of shapefile names (for NHGIS extracts) description: short description of your extract - data_format: desired format of the extract data file. One of ``"csv_no_header"``, ``"csv_header"``, or ``"fixed_width"``. - geographic_extents: Geographic extents to use for all ``datasets`` and ``time_series_tables`` in the extract definition (for instance, to - to obtain data within a particular state). + data_format: desired format of the extract data file (for NHGIS extracts). One of ``"csv_no_header"``, ``"csv_header"``, or ``"fixed_width"``. + geographic_extents: Geographic extents to use for all ``datasets`` and ``time_series_tables`` in an NHGIS extract definition (for instance, to + to obtain data within a particular state) tst_layout: desired data layout for all ``time_series_tables`` in the extract definition. - One of ``"time_by_column_layout"`` (default), ``"time_by_row_layout"``, or ``"time_by_file_layout"``. - breakdown_and_data_type_layout: desired layout of any ``datasets`` that have multiple data types or breakdown values. Either + One of ``"time_by_column_layout"`` (default), ``"time_by_row_layout"``, or ``"time_by_file_layout"`` + breakdown_and_data_type_layout: desired layout of any ``datasets`` that have multiple data types or breakdown values in an NHGIS extract definition. Either ``"single_file"`` (default) or ``"separate files"`` """ @@ -811,7 +811,7 @@ def __init__( time_series_tables, TimeSeriesTable ) self.shapefiles = self._validate_list_args(shapefiles, Shapefile) - + if ( len(self.datasets) == 0 and len(self.time_series_tables) == 0 From 6152f1db3fa8b6b030589807bbf706eca38044c6 Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Tue, 3 Jun 2025 14:02:29 -0400 Subject: [PATCH 16/20] black --- tests/test_api.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index ba755ae..b39f1d7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1820,8 +1820,8 @@ def test_get_pages(live_api_client: IpumsApiClient): live_api_client._get_pages(collection="usa", endpoint="extracts", page_size=5) ) assert len(page1["data"]) == 5 - - + + def test_cps_adjust_monetary_values(): """ Confirm that adjust monetary values updates are happening correctly @@ -1863,7 +1863,7 @@ def test_cps_adjust_monetary_values(): "collection": "cps", "version": None, } - + @pytest.mark.vcr def test_adjust_monetary_values_errors(live_api_client: IpumsApiClient): @@ -1877,16 +1877,15 @@ def test_adjust_monetary_values_errors(live_api_client: IpumsApiClient): with pytest.raises(BadIpumsApiRequest) as exc_info: live_api_client.submit_extract(extract) assert ( - exc_info.value.args[0] - == "Monetary value adjustment is not supported for SEX." + exc_info.value.args[0] == "Monetary value adjustment is not supported for SEX." ) - + extract = MicrodataExtract( "atus", ["at2012"], ["AGE", "SEX", "EARNWEEK"], ) - + extract.adjust_monetary_values("EARNWEEK") with pytest.raises(BadIpumsApiRequest) as exc_info: live_api_client.submit_extract(extract) From 85fddb671d6e3f590964eaaddd398eaab2068822 Mon Sep 17 00:00:00 2001 From: renae-r Date: Fri, 6 Jun 2025 11:12:40 -0500 Subject: [PATCH 17/20] change log and version bump --- docs/source/change-log.rst | 21 +++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/source/change-log.rst b/docs/source/change-log.rst index 4ca6029..3e8982d 100644 --- a/docs/source/change-log.rst +++ b/docs/source/change-log.rst @@ -10,6 +10,27 @@ This project adheres to `Semantic Versioning`_. .. _Semantic Versioning: http://semver.org/ + +0.7.0 +----- +2025-06-6 + +* New Features + + * Support for IPUMS IHGIS extract API, including + + * Support for IPUMS IHGIS has been added to :py:class:`~ipumspy.api.extract.AggregateDataExtract` + * :py:class:`~ipumspy.api.extract.IhgisDataset` added for use when constructing IPUMS IHGIS extract requests. + + * Support for IPUMS IHGIS metadata API, including + + * :py:class:`~ipumspy.api.metadata.IhgisDatasetMetadata` + +* Breaking Changes + + * :py:class:`~ipumspy.api.extract.Dataset` has been renamed :py:class:`~ipumspy.api.extract.NhgisDataset` + * :py:class:`~ipumspy.api.metadata.DatasetMetadata` has been renamed :py:class:`~ipumspy.api.metadata.NhgisDatasetMetadata` + 0.6.2 ----- 2025-04-18 diff --git a/pyproject.toml b/pyproject.toml index 901f846..ec2bd4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ipumspy" -version = "0.6.2" +version = "0.7.0" description = "A collection of tools for working with IPUMS data" authors = ["Kevin H. Wilson ", "Renae Rodgers "] From f82e594003be044e14f40c105ea2cc629937061e Mon Sep 17 00:00:00 2001 From: renae-r Date: Fri, 6 Jun 2025 11:14:39 -0500 Subject: [PATCH 18/20] Add AMV to change log --- docs/source/change-log.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/change-log.rst b/docs/source/change-log.rst index 3e8982d..c6c2f70 100644 --- a/docs/source/change-log.rst +++ b/docs/source/change-log.rst @@ -26,6 +26,8 @@ This project adheres to `Semantic Versioning`_. * :py:class:`~ipumspy.api.metadata.IhgisDatasetMetadata` + * Support for the Monetary Value Adjustment feature on select variables from IPUMS USA and IPUMS CPS + * Breaking Changes * :py:class:`~ipumspy.api.extract.Dataset` has been renamed :py:class:`~ipumspy.api.extract.NhgisDataset` From 58fdcd18f00c1e2e8d2b922452a0726d246f3b3e Mon Sep 17 00:00:00 2001 From: Finn Roberts Date: Fri, 6 Jun 2025 14:38:19 -0400 Subject: [PATCH 19/20] Update changelog --- docs/source/change-log.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/change-log.rst b/docs/source/change-log.rst index c6c2f70..862418d 100644 --- a/docs/source/change-log.rst +++ b/docs/source/change-log.rst @@ -25,6 +25,7 @@ This project adheres to `Semantic Versioning`_. * Support for IPUMS IHGIS metadata API, including * :py:class:`~ipumspy.api.metadata.IhgisDatasetMetadata` + * :py:class:`~ipumspy.api.metadata.IhgisDataTableMetadata` * Support for the Monetary Value Adjustment feature on select variables from IPUMS USA and IPUMS CPS @@ -32,6 +33,7 @@ This project adheres to `Semantic Versioning`_. * :py:class:`~ipumspy.api.extract.Dataset` has been renamed :py:class:`~ipumspy.api.extract.NhgisDataset` * :py:class:`~ipumspy.api.metadata.DatasetMetadata` has been renamed :py:class:`~ipumspy.api.metadata.NhgisDatasetMetadata` + * :py:class:`~ipumspy.api.metadata.DataTableMetadata` has been renamed :py:class:`~ipumspy.api.metadata.NhgisDatasetMetadata` 0.6.2 ----- From 9f0b5d101ed8288707c7a1e124cf8055e236acf9 Mon Sep 17 00:00:00 2001 From: renae-r Date: Mon, 9 Jun 2025 10:36:43 -0500 Subject: [PATCH 20/20] release date bump --- docs/source/change-log.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/change-log.rst b/docs/source/change-log.rst index 862418d..abdcf2d 100644 --- a/docs/source/change-log.rst +++ b/docs/source/change-log.rst @@ -13,7 +13,7 @@ This project adheres to `Semantic Versioning`_. 0.7.0 ----- -2025-06-6 +2025-06-09 * New Features