welp, i've hit the census api too many times today

This commit is contained in:
Emma Nechamkin 2022-09-06 16:29:21 -04:00
parent b7af13b2a6
commit 6d9e11d081
4 changed files with 161 additions and 191 deletions

View file

@ -619,16 +619,6 @@ class CensusACSETL(ExtractTransformLoad):
lower=0
)
# All values should have a value at this point
assert (
df[
self.ADJUSTED_AND_IMPUTED_POVERTY_LESS_THAN_200_PERCENT_FPL_FIELD_NAME
]
.isna()
.sum()
== 0
), "Error: not all values were filled..."
logger.info("Renaming columns...")
df = df.rename(
columns={

View file

@ -1,6 +1,7 @@
from typing import Any, List, NamedTuple, Tuple
import pandas as pd
import geopandas as gpd
from data_pipeline.score.field_names import GEOID_TRACT_FIELD
import numpy as np
from data_pipeline.utils import get_module_logger
@ -9,53 +10,15 @@ from data_pipeline.utils import get_module_logger
logger = get_module_logger(__name__)
def _get_fips_mask(
geo_df: gpd.GeoDataFrame,
row: gpd.GeoSeries,
fips_digits: int,
geoid_field: str = "GEOID10_TRACT",
) -> pd.Series:
return (
geo_df[geoid_field].str[:fips_digits] == row[geoid_field][:fips_digits]
)
def _get_neighbor_mask(
geo_df: gpd.GeoDataFrame, row: gpd.GeoSeries
) -> pd.Series:
return geo_df["geometry"].touches(row["geometry"])
def _choose_best_mask(
geo_df: gpd.GeoDataFrame,
masks_in_priority_order: List[pd.Series],
column_to_impute: str,
) -> pd.Series:
for mask in masks_in_priority_order:
if any(geo_df[mask][column_to_impute].notna()):
return mask
raise Exception("No mask found")
def _prepare_dataframe_for_imputation(
impute_var_named_tup_list: List[NamedTuple],
columns_to_impute: list,
geo_df: gpd.GeoDataFrame,
geoid_field: str = "GEOID10_TRACT",
) -> Tuple[Any, gpd.GeoDataFrame]:
imputing_cols = [
impute_var_pair.raw_field_name
for impute_var_pair in impute_var_named_tup_list
]
# prime column to exist
for impute_var_pair in impute_var_named_tup_list:
geo_df[impute_var_pair.imputed_field_name] = geo_df[
impute_var_pair.raw_field_name
].copy()
):
# generate a list of tracts for which at least one of the imputation
# columns is null
tract_list = geo_df[geo_df[imputing_cols].isna().any(axis=1)][
tract_list = geo_df[geo_df[columns_to_impute].isna().any(axis=1)][
geoid_field
].unique()
@ -66,15 +29,36 @@ def _prepare_dataframe_for_imputation(
return tract_list, geo_df
def _get_state_and_county_fills(df, tract_list, impute_var_pair_list):
# When there is no neighbor average, we take the county-level average or state-level averages
for impute_var_pair in impute_var_pair_list:
# Fill missings with county means
df[impute_var_pair.imputed_field_name] = np.where(
(df[impute_var_pair.imputed_field_name].isna())
& (df[GEOID_TRACT_FIELD].isin(tract_list)),
df.groupby(df[GEOID_TRACT_FIELD].str[:5])[
impute_var_pair.raw_field_name
].transform(np.mean),
df[impute_var_pair.imputed_field_name],
)
# Fill the remaining missings with state means
df[impute_var_pair.imputed_field_name] = np.where(
(df[impute_var_pair.imputed_field_name].isna())
& (df[GEOID_TRACT_FIELD].isin(tract_list)),
df.groupby(df[GEOID_TRACT_FIELD].str[:2])[
impute_var_pair.raw_field_name
].transform(np.mean),
df[impute_var_pair.imputed_field_name],
)
return df
def calculate_income_measures(
impute_var_named_tup_list: list,
geo_df: gpd.GeoDataFrame,
geoid_field: str,
) -> pd.DataFrame:
"""Impute values based on geographic neighbors
We only want to check neighbors a single time, so all variables
that we impute get imputed here.
"""Impute values based on geographic neighbors or county fields.
Takes in:
required:
@ -84,50 +68,58 @@ def calculate_income_measures(
Returns: non-geometry pd.DataFrame
"""
raw_fields = []
imputed_fields = []
rename_dict = {}
for impute_var in impute_var_named_tup_list:
raw_fields.append(impute_var.raw_field_name)
imputed_fields.append(impute_var.imputed_field_name)
assert (
impute_var.raw_field_name not in rename_dict
), f"Error: trying to impute {impute_var.raw_field_name} twice"
rename_dict[impute_var.raw_field_name] = impute_var.imputed_field_name
# Determine where to impute variables and fill a column with nulls
tract_list, geo_df = _prepare_dataframe_for_imputation(
impute_var_named_tup_list=impute_var_named_tup_list,
columns_to_impute=raw_fields,
geo_df=geo_df,
geoid_field=geoid_field,
)
# Iterate through the dataframe to impute in place
## TODO: We should probably convert this to a spatial join now that we are doing >1 imputation and it's taking a lot
## of time, but thinking through how to do this while maintaining the masking will take some time. I think the best
## way would be to (1) spatial join to all neighbors, and then (2) iterate to take the "smallest" set of neighbors...
## but haven't implemented it yet.
for index, row in geo_df.iterrows():
if row[geoid_field] in tract_list:
neighbor_mask = _get_neighbor_mask(geo_df, row)
county_mask = _get_fips_mask(
geo_df=geo_df, row=row, fips_digits=5, geoid_field=geoid_field
)
## TODO: Did CEQ decide to cut this?
state_mask = _get_fips_mask(
geo_df=geo_df, row=row, fips_digits=2, geoid_field=geoid_field
)
missing_tracts_df = geo_df[geo_df[GEOID_TRACT_FIELD].isin(tract_list)]
# Impute fields for every row missing at least one value using the best possible set of neighbors
# Note that later, we will pull raw.fillna(imputed), so the mechanics of this step aren't critical
for impute_var_pair in impute_var_named_tup_list:
mask_to_use = _choose_best_mask(
geo_df=geo_df,
masks_in_priority_order=[
neighbor_mask,
county_mask,
state_mask,
],
column_to_impute=impute_var_pair.raw_field_name,
)
geo_df.loc[index, impute_var_pair.imputed_field_name] = geo_df[
mask_to_use
][impute_var_pair.raw_field_name].mean()
# Perform as spatial merge to save time
spatially_joined_df = missing_tracts_df[
[GEOID_TRACT_FIELD, "geometry"]
].sjoin(
geo_df[raw_fields + ["geometry"]],
predicate="touches",
)
logger.info("Casting geodataframe as a typical dataframe")
# First take the neighbor averages
neighbor_averages_df = (
spatially_joined_df.groupby(GEOID_TRACT_FIELD)[raw_fields]
.mean()
.reset_index()
.rename(columns=rename_dict)
)
logger.info("Merging and casting geodataframe as a typical dataframe")
# get rid of the geometry column and cast as a typical df
df = pd.DataFrame(
geo_df[[col for col in geo_df.columns if col != "geometry"]]
geo_df[[col for col in geo_df.columns if col != "geometry"]].merge(
neighbor_averages_df,
on=[GEOID_TRACT_FIELD],
how="outer",
)
)
logger.info(df.head())
logger.info("Filling with county or state")
df = _get_state_and_county_fills(df, tract_list, impute_var_named_tup_list)
logger.info(df.head())
# finally, return the df
return df

View file

@ -6,6 +6,7 @@ from functools import lru_cache
import geopandas as gpd
from data_pipeline.utils import get_module_logger
from .census.etl import CensusETL
from data_pipeline.score import field_names
logger = get_module_logger(__name__)
@ -27,7 +28,9 @@ def get_tract_geojson(
else:
logger.debug("Loading existing tract geojson")
tract_data = gpd.read_file(GEOJSON_PATH, include_fields=["GEOID10"])
tract_data.rename(columns={"GEOID10": "GEOID10_TRACT"}, inplace=True)
tract_data.rename(
columns={"GEOID10": field_names.GEOID_TRACT_FIELD}, inplace=True
)
return tract_data
@ -55,7 +58,7 @@ def add_tracts_for_geometries(
), f"Dataframe must be projected to {tract_data.crs}"
df = gpd.sjoin(
df,
tract_data[["GEOID10_TRACT", "geometry"]],
tract_data[[field_names.GEOID_TRACT_FIELD, "geometry"]],
how="inner",
op="intersects",
)

View file

@ -67,16 +67,19 @@ tests = ["pytest"]
[[package]]
name = "astroid"
version = "2.11.7"
version = "2.12.5"
description = "An abstract syntax tree for Python with inference support."
category = "main"
optional = false
python-versions = ">=3.6.2"
python-versions = ">=3.7.2"
[package.dependencies]
lazy-object-proxy = ">=1.4.0"
typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""}
wrapt = ">=1.11,<2"
wrapt = [
{version = ">=1.11,<2", markers = "python_version < \"3.11\""},
{version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
]
[[package]]
name = "atomicwrites"
@ -209,7 +212,7 @@ pycparser = "*"
[[package]]
name = "charset-normalizer"
version = "2.1.0"
version = "2.1.1"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
category = "main"
optional = false
@ -267,15 +270,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "configparser"
version = "5.2.0"
description = "Updated configparser from Python 3.8 for Python 2.6+."
version = "5.3.0"
description = "Updated configparser from stdlib for earlier Pythons."
category = "dev"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "types-backports", "pytest-black (>=0.3.7)", "pytest-mypy"]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "types-backports", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
[[package]]
name = "cycler"
@ -322,7 +325,7 @@ graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "distlib"
version = "0.3.5"
version = "0.3.6"
description = "Distribution utilities"
category = "dev"
optional = false
@ -439,7 +442,7 @@ pyflakes = ">=2.3.0,<2.4.0"
[[package]]
name = "fonttools"
version = "4.35.0"
version = "4.37.1"
description = "Tools to manipulate font files"
category = "main"
optional = false
@ -486,7 +489,7 @@ python-versions = ">=3.5"
name = "importlib-metadata"
version = "4.12.0"
description = "Read metadata from Python packages"
category = "dev"
category = "main"
optional = false
python-versions = ">=3.7"
@ -536,7 +539,7 @@ toml = {version = ">=0.10.2", markers = "python_version > \"3.6\""}
[[package]]
name = "ipykernel"
version = "6.15.1"
version = "6.15.2"
description = "IPython Kernel for Jupyter"
category = "main"
optional = false
@ -556,7 +559,7 @@ tornado = ">=6.1"
traitlets = ">=5.1.0"
[package.extras]
test = ["pytest (>=6.0)", "pytest-timeout", "pytest-cov", "pre-commit", "ipyparallel", "flaky"]
test = ["flaky", "ipyparallel", "pre-commit", "pytest-cov", "pytest-timeout", "pytest (>=6.0)"]
[[package]]
name = "ipython"
@ -600,22 +603,21 @@ python-versions = "*"
[[package]]
name = "ipywidgets"
version = "7.7.1"
description = "IPython HTML widgets for Jupyter"
version = "8.0.1"
description = "Jupyter interactive widgets"
category = "main"
optional = false
python-versions = "*"
python-versions = ">=3.7"
[package.dependencies]
ipykernel = ">=4.5.1"
ipython = {version = ">=4.0.0", markers = "python_version >= \"3.3\""}
ipython-genutils = ">=0.2.0,<0.3.0"
jupyterlab-widgets = {version = ">=1.0.0", markers = "python_version >= \"3.6\""}
ipython = ">=6.1.0"
jupyterlab-widgets = ">=3.0,<4.0"
traitlets = ">=4.3.1"
widgetsnbextension = ">=3.6.0,<3.7.0"
widgetsnbextension = ">=4.0,<5.0"
[package.extras]
test = ["mock", "pytest-cov", "pytest (>=3.6.0)"]
test = ["jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"]
[[package]]
name = "isort"
@ -670,7 +672,7 @@ i18n = ["Babel (>=2.7)"]
[[package]]
name = "json5"
version = "0.9.9"
version = "0.9.10"
description = "A Python implementation of the JSON5 data format."
category = "dev"
optional = false
@ -681,7 +683,7 @@ dev = ["hypothesis"]
[[package]]
name = "jsonschema"
version = "4.10.0"
version = "4.15.0"
description = "An implementation of JSON Schema validation for Python"
category = "main"
optional = false
@ -715,7 +717,7 @@ qtconsole = "*"
[[package]]
name = "jupyter-client"
version = "7.3.4"
version = "7.3.5"
description = "Jupyter protocol implementation and client libraries"
category = "main"
optional = false
@ -727,12 +729,12 @@ jupyter-core = ">=4.9.2"
nest-asyncio = ">=1.5.4"
python-dateutil = ">=2.8.2"
pyzmq = ">=23.0"
tornado = ">=6.0"
tornado = ">=6.2"
traitlets = "*"
[package.extras]
test = ["pytest-timeout", "pytest-cov", "pytest-asyncio (>=0.18)", "pytest", "pre-commit", "mypy", "ipython", "ipykernel (>=6.5)", "coverage", "codecov"]
doc = ["sphinxcontrib-github-alt", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "myst-parser", "ipykernel"]
doc = ["ipykernel", "myst-parser", "sphinx-rtd-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt"]
test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"]
[[package]]
name = "jupyter-console"
@ -913,7 +915,7 @@ python-versions = ">=3.7"
[[package]]
name = "jupyterlab-server"
version = "2.15.0"
version = "2.15.1"
description = "A set of server components for JupyterLab and JupyterLab like applications."
category = "dev"
optional = false
@ -935,11 +937,11 @@ test = ["codecov", "ipykernel", "jupyter-server", "openapi-core (>=0.14.2)", "op
[[package]]
name = "jupyterlab-widgets"
version = "1.1.1"
description = "A JupyterLab extension."
version = "3.0.2"
description = "Jupyter interactive widgets for JupyterLab"
category = "main"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
[[package]]
name = "kiwisolver"
@ -994,7 +996,7 @@ python-versions = ">=3.7"
[[package]]
name = "marshmallow"
version = "3.17.0"
version = "3.17.1"
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
category = "main"
optional = false
@ -1004,9 +1006,9 @@ python-versions = ">=3.7"
packaging = ">=17.0"
[package.extras]
dev = ["pytest", "pytz", "simplejson", "mypy (==0.961)", "flake8 (==4.0.1)", "flake8-bugbear (==22.6.22)", "pre-commit (>=2.4,<3.0)", "tox"]
docs = ["sphinx (==4.5.0)", "sphinx-issues (==3.0.1)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.8)"]
lint = ["mypy (==0.961)", "flake8 (==4.0.1)", "flake8-bugbear (==22.6.22)", "pre-commit (>=2.4,<3.0)"]
dev = ["pytest", "pytz", "simplejson", "mypy (==0.971)", "flake8 (==5.0.4)", "flake8-bugbear (==22.8.22)", "pre-commit (>=2.4,<3.0)", "tox"]
docs = ["sphinx (==5.1.1)", "sphinx-issues (==3.0.1)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.9)"]
lint = ["mypy (==0.971)", "flake8 (==5.0.4)", "flake8-bugbear (==22.8.22)", "pre-commit (>=2.4,<3.0)"]
tests = ["pytest", "pytz", "simplejson"]
[[package]]
@ -1061,7 +1063,7 @@ setuptools_scm = ">=4,<7"
[[package]]
name = "matplotlib-inline"
version = "0.1.3"
version = "0.1.6"
description = "Inline Matplotlib backend for Jupyter"
category = "main"
optional = false
@ -1080,8 +1082,8 @@ python-versions = "*"
[[package]]
name = "mistune"
version = "0.8.4"
description = "The fastest markdown parser in pure Python"
version = "2.0.4"
description = "A sane Markdown parser with useful plugins and renderers"
category = "main"
optional = false
python-versions = "*"
@ -1171,7 +1173,7 @@ docs = ["myst-parser", "sphinx-rtd-theme", "sphinxcontrib-github-alt", "nbsphinx
[[package]]
name = "nbclient"
version = "0.6.6"
version = "0.6.7"
description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor."
category = "main"
optional = false
@ -1185,11 +1187,11 @@ traitlets = ">=5.2.2"
[package.extras]
sphinx = ["autodoc-traits", "mock", "moto", "myst-parser", "Sphinx (>=1.7)", "sphinx-book-theme"]
test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "ipywidgets (<8.0.0)", "mypy", "pip (>=18.1)", "pre-commit", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=60.0)", "testpath", "twine (>=1.11.0)", "xmltodict"]
test = ["black", "check-manifest", "flake8", "ipykernel", "ipython", "ipywidgets", "mypy", "nbconvert", "pip (>=18.1)", "pre-commit", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=60.0)", "testpath", "twine (>=1.11.0)", "xmltodict"]
[[package]]
name = "nbconvert"
version = "6.5.3"
version = "7.0.0"
description = "Converting Jupyter Notebooks"
category = "main"
optional = false
@ -1199,13 +1201,13 @@ python-versions = ">=3.7"
beautifulsoup4 = "*"
bleach = "*"
defusedxml = "*"
entrypoints = ">=0.2.2"
importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""}
jinja2 = ">=3.0"
jupyter-core = ">=4.7"
jupyterlab-pygments = "*"
lxml = "*"
MarkupSafe = ">=2.0"
mistune = ">=0.8.1,<2"
markupsafe = ">=2.0"
mistune = ">=2.0.3,<3"
nbclient = ">=0.5.0"
nbformat = ">=5.1"
packaging = "*"
@ -1215,10 +1217,12 @@ tinycss2 = "*"
traitlets = ">=5.0"
[package.extras]
all = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "tornado (>=6.1)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"]
docs = ["sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"]
all = ["ipykernel", "ipython", "ipywidgets (>=7)", "nbsphinx (>=0.2.12)", "pre-commit", "pyppeteer (>=1,<1.1)", "pyqtwebengine (>=5.15)", "pytest", "pytest-cov", "pytest-dependency", "sphinx-rtd-theme", "sphinx (==5.0.2)", "tornado (>=6.1)"]
docs = ["ipython", "nbsphinx (>=0.2.12)", "sphinx-rtd-theme", "sphinx (==5.0.2)"]
qtpdf = ["pyqtwebengine (>=5.15)"]
qtpng = ["pyqtwebengine (>=5.15)"]
serve = ["tornado (>=6.1)"]
test = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)"]
test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency"]
webpdf = ["pyppeteer (>=1,<1.1)"]
[[package]]
@ -1322,7 +1326,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "pandas"
version = "1.4.3"
version = "1.4.4"
description = "Powerful data structures for data analysis, time series, and statistics"
category = "main"
optional = false
@ -1330,16 +1334,16 @@ python-versions = ">=3.8"
[package.dependencies]
numpy = [
{version = ">=1.21.0", markers = "python_version >= \"3.10\""},
{version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""},
{version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""},
{version = ">=1.18.5", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""},
{version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""},
{version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""},
{version = ">=1.21.0", markers = "python_version >= \"3.10\""},
]
python-dateutil = ">=2.8.1"
pytz = ">=2020.1"
[package.extras]
test = ["pytest-xdist (>=1.31)", "pytest (>=6.0)", "hypothesis (>=5.5.3)"]
test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"]
[[package]]
name = "pandas-vet"
@ -1405,11 +1409,11 @@ testing = ["docopt", "pytest (<6.0.0)"]
[[package]]
name = "pathspec"
version = "0.9.0"
version = "0.10.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
python-versions = ">=3.7"
[[package]]
name = "pexpect"
@ -1537,14 +1541,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "pydantic"
version = "1.9.2"
version = "1.10.1"
description = "Data validation and settings management using python type hints"
category = "main"
optional = false
python-versions = ">=3.6.1"
python-versions = ">=3.7"
[package.dependencies]
typing-extensions = ">=3.7.4.3"
typing-extensions = ">=4.1.0"
[package.extras]
dotenv = ["python-dotenv (>=0.10.4)"]
@ -1571,14 +1575,14 @@ plugins = ["importlib-metadata"]
[[package]]
name = "pylint"
version = "2.14.5"
version = "2.15.0"
description = "python code static checker"
category = "main"
optional = false
python-versions = ">=3.7.2"
[package.dependencies]
astroid = ">=2.11.6,<=2.12.0-dev0"
astroid = ">=2.12.4,<=2.14.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = ">=0.2"
isort = ">=4.2.5,<6"
@ -1733,7 +1737,7 @@ py = {version = "*", markers = "implementation_name == \"pypy\""}
[[package]]
name = "qtconsole"
version = "5.3.1"
version = "5.3.2"
description = "Jupyter Qt console"
category = "main"
optional = false
@ -1750,8 +1754,8 @@ qtpy = ">=2.0.1"
traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2"
[package.extras]
test = ["pytest-qt", "pytest", "flaky"]
doc = ["Sphinx (>=1.3)"]
test = ["flaky", "pytest", "pytest-qt"]
[[package]]
name = "qtpy"
@ -1875,7 +1879,7 @@ toml = ["setuptools (>=42)"]
[[package]]
name = "shapely"
version = "1.8.2"
version = "1.8.4"
description = "Geometric objects, predicates, and operations"
category = "main"
optional = false
@ -2059,7 +2063,7 @@ test = ["pytest", "pre-commit"]
[[package]]
name = "types-requests"
version = "2.28.8"
version = "2.28.9"
description = "Typing stubs for requests"
category = "main"
optional = false
@ -2070,7 +2074,7 @@ types-urllib3 = "<1.27"
[[package]]
name = "types-urllib3"
version = "1.26.22"
version = "1.26.23"
description = "Typing stubs for urllib3"
category = "main"
optional = false
@ -2086,7 +2090,7 @@ python-versions = ">=3.7"
[[package]]
name = "typing-inspect"
version = "0.7.1"
version = "0.8.0"
description = "Runtime inspection utilities for typing module."
category = "main"
optional = false
@ -2098,16 +2102,16 @@ typing-extensions = ">=3.7.4"
[[package]]
name = "urllib3"
version = "1.26.11"
version = "1.26.12"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
[package.extras]
brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
secure = ["ipaddress", "certifi", "idna (>=2.0.0)", "cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"]
brotli = ["brotlipy (>=0.6.0)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
[[package]]
name = "us"
@ -2122,7 +2126,7 @@ jellyfish = "0.6.1"
[[package]]
name = "virtualenv"
version = "20.16.3"
version = "20.16.4"
description = "Virtual Python Environment builder"
category = "dev"
optional = false
@ -2155,27 +2159,24 @@ python-versions = "*"
[[package]]
name = "websocket-client"
version = "1.3.3"
version = "1.4.0"
description = "WebSocket client for Python with low level API options"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"]
optional = ["python-socks", "wsaccel"]
test = ["websockets"]
optional = ["wsaccel", "python-socks"]
docs = ["sphinx-rtd-theme (>=0.5)", "Sphinx (>=3.4)"]
[[package]]
name = "widgetsnbextension"
version = "3.6.1"
description = "IPython HTML widgets for Jupyter"
version = "4.0.2"
description = "Jupyter interactive widgets for Jupyter Notebook"
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
notebook = ">=4.4.1"
python-versions = ">=3.7"
[[package]]
name = "wrapt"
@ -2283,10 +2284,7 @@ cligj = [
{file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"},
]
colorama = []
configparser = [
{file = "configparser-5.2.0-py3-none-any.whl", hash = "sha256:e8b39238fb6f0153a069aa253d349467c3c4737934f253ef6abac5fe0eca1e5d"},
{file = "configparser-5.2.0.tar.gz", hash = "sha256:1b35798fdf1713f1c3139016cfcbc461f09edbf099d1fb658d4b7479fcaa3daa"},
]
configparser = []
cycler = [
{file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
{file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"},
@ -2490,18 +2488,12 @@ marshmallow-enum = [
{file = "marshmallow_enum-1.5.1-py2.py3-none-any.whl", hash = "sha256:57161ab3dbfde4f57adeb12090f39592e992b9c86d206d02f6bd03ebec60f072"},
]
matplotlib = []
matplotlib-inline = [
{file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
{file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
]
matplotlib-inline = []
mccabe = [
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
]
mistune = [
{file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"},
{file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"},
]
mistune = []
munch = [
{file = "munch-2.5.0-py2.py3-none-any.whl", hash = "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd"},
{file = "munch-2.5.0.tar.gz", hash = "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2"},
@ -2568,10 +2560,7 @@ parso = [
{file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
{file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
]
pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
]
pathspec = []
pexpect = [
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
@ -2845,11 +2834,7 @@ traitlets = []
types-requests = []
types-urllib3 = []
typing-extensions = []
typing-inspect = [
{file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"},
{file = "typing_inspect-0.7.1-py3-none-any.whl", hash = "sha256:3cd7d4563e997719a710a3bfe7ffb544c6b72069b6812a02e9b414a8fa3aaa6b"},
{file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"},
]
typing-inspect = []
urllib3 = []
us = [
{file = "us-2.0.2.tar.gz", hash = "sha256:cb11ad0d43deff3a1c3690c74f0c731cff5b862c73339df2edd91133e1496fbc"},