From 4a092b4a2bd23dcf85c76757169c29b73848c69d Mon Sep 17 00:00:00 2001 From: Soren Spicknall Date: Wed, 7 Feb 2024 09:41:13 -0600 Subject: [PATCH] Upgrade jupyter-book to v1.0.0 (#3265) --- .../01-data-analysis-intro.md | 46 +- .../02-data-analysis-intermediate.md | 20 +- .../03-data-management.md | 40 +- docs/analytics_new_analysts/04-notebooks.md | 8 + .../05-spatial-analysis-basics.md | 18 +- .../06-spatial-analysis-intro.md | 32 +- .../07-spatial-analysis-intermediate.md | 28 +- .../08-spatial-analysis-advanced.md | 8 +- docs/analytics_tools/data_catalogs.md | 14 +- docs/analytics_tools/github_setup.md | 2 + docs/analytics_tools/jupyterhub.md | 16 +- docs/analytics_tools/knowledge_sharing.md | 38 +- docs/analytics_tools/python_libraries.md | 18 +- docs/analytics_tools/saving_code.md | 18 +- docs/analytics_tools/storing_data.md | 34 +- docs/analytics_welcome/how_we_work.md | 2 +- docs/architecture/services.md | 2 +- docs/conf.py | 2 +- docs/requirements.txt | 11 +- docs/transit_database/transitdatabase.md | 4 + docs/warehouse/developing_dbt_models.md | 13 +- docs/warehouse/warehouse_starter_kit.md | 10 + images/jupyter-singleuser/poetry.lock | 784 ++++++++++++------ images/jupyter-singleuser/pyproject.toml | 8 +- 24 files changed, 791 insertions(+), 385 deletions(-) diff --git a/docs/analytics_new_analysts/01-data-analysis-intro.md b/docs/analytics_new_analysts/01-data-analysis-intro.md index 755ecc6ccd..f7d0e8fdb4 100644 --- a/docs/analytics_new_analysts/01-data-analysis-intro.md +++ b/docs/analytics_new_analysts/01-data-analysis-intro.md @@ -4,8 +4,8 @@ Below are Python tutorials covering the basics of data cleaning and wrangling. [Chris Albon's guide](https://chrisalbon.com/#python) is particularly helpful. Rather than reinventing the wheel, this tutorial instead highlights specific methods and operations that might make your life easier as a data analyst. -- [Import and export data in Python](#import-and-export-data-in-python) -- [Merge tabular and geospatial data](#merge-tabular-and-geospatial-data) +- [Import and export data in Python](#data-analysis-import-and-export-data-in-python) +- [Merge tabular and geospatial data](#data-analysis-merge-tabular-and-geospatial-data) - [Functions](#functions) - [Grouping](#grouping) - [Aggregating](#aggregating) @@ -13,19 +13,21 @@ Below are Python tutorials covering the basics of data cleaning and wrangling. [ ## Getting Started -``` +```python import numpy as np import pandas as pd import geopandas as gpd ``` -## Import and Export Data in Python +(data-analysis-import-and-export-data-in-python)= + +## Import and Export Data in Python for Data Analysis ### **Local files** We import a tabular dataframe `my_csv.csv` and an Excel spreadsheet `my_excel.xlsx`. -``` +```python df = pd.read_csv('./folder/my_csv.csv') df = pd.read_excel('./folder/my_excel.xlsx', sheet_name = 'Sheet1') @@ -35,7 +37,7 @@ df = pd.read_excel('./folder/my_excel.xlsx', sheet_name = 'Sheet1') The data we use outside of the warehouse can be stored in GCS buckets. -``` +```python # Read from GCS df = pd.read_csv('gs://calitp-analytics-data/data-analyses/bucket-name/df_csv.csv') @@ -45,7 +47,9 @@ df.to_csv('gs://calitp-analytics-data/data-analyses/bucket-name/df_csv.csv') Refer to the [Data Management best practices](data-management-page) and [Basics of Working with Geospatial Data](geo-intro) for additional information on importing various file types. -## Merge Tabular and Geospatial Data +(data-analysis-merge-tabular-and-geospatial-data)= + +## Merge Tabular and Geospatial Data for Data Analysis Merging data from multiple sources creates one large dataframe (df) to perform data analysis. Let's say there are 3 sources of data that need to be merged: @@ -81,7 +85,7 @@ Dataframe #3: `council_boundaries` (geospatial) First, merge `paunch_locations` with `council_population` using the `CD` column, which they have in common. -``` +```python merge1 = pd.merge( paunch_locations, council_population, @@ -96,7 +100,7 @@ merge1 = pd.merge( Next, merge `merge1` and `council_boundaries`. Columns don't have to have the same names to be matched on, as long as they hold the same values. -``` +```python merge2 = pd.merge( merge1, council_boundaries, @@ -123,6 +127,8 @@ Here are some things to know about `merge2`: | 5 | Pawnee | $4 | 1 | (x5, y5) | Leslie Knope | 1,500 | polygon | | 6 | Pawnee | $6 | 2 | (x6, y6) | Jeremy Jamm | 2,000 | polygon | +(functions)= + ## Functions A function is a set of instructions to *do something*. It can be as simple as changing values in a column or as complicated as a series of steps to clean, group, aggregate, and plot the data. @@ -142,7 +148,7 @@ Lambda functions are quick and dirty. You don't even have to name the function! ### **If-Else Statements** -``` +```python # Create column called duration. If Songs > 10, duration is 'long'. # Otherwise, duration is 'short'. df['duration'] = df.apply(lambda row: 'long' if row.Songs > 10 @@ -174,7 +180,7 @@ df ### **Other Lambda Functions** -``` +```python # Split the band name at the spaces # [1] means we want to extract the second word # [0:2] means we want to start at the first character @@ -197,7 +203,7 @@ You should use a full function when a function is too complicated to be a lambda `df.apply` is one common usage of a function. -``` +```python def years_active(row): if row.Band == 'Mouse Rat': return '2009-2014' @@ -218,13 +224,15 @@ df | Jet Black Pope | 4 | 2008 | | Nothing Rhymes with Orange | 6 | 2008 | +(grouping)= + ## Grouping Sometimes it's necessary to create a new column to group together certain values of a column. Here are two ways to accomplish this: Method #1: Write a function using if-else statement and apply it using a lambda function. -``` +```python # The function is called elected_year, and it operates on every row. def elected_year(row): # For each row, if Council_Member says 'Leslie Knope', then return 2012 @@ -252,7 +260,7 @@ council_population Method #2: Loop over every value, fill in the new column value, then attach that new column. -``` +```python # Create a list to store the new column sales_group = [] @@ -283,13 +291,15 @@ paunch_locations | 6 | Pawnee | $6 | 2 | (x6, y6) | high | | 7 | Indianapolis | $7 | | (x7, y7) | high | +(aggregating)= + ## Aggregating One of the most common form of summary statistics is aggregating by groups. In Excel, it's called a pivot table. In ArcGIS, it's doing a dissolve and calculating summary statistics. There are two ways to do it in Python: `groupby` and `agg` or `pivot_table`. To answer the question of how many Paunch Burger locations there are per Council District and the sales generated per resident, -``` +```python # Method #1: groupby and agg pivot = (merge2.groupby(['CD']) .agg({'Sales_millions': 'sum', @@ -322,13 +332,15 @@ pivot = merge2.pivot_table( | 2 | $8.5 | 2 | Jeremy Jamm | 2,000 | | 3 | $2.5 | 1 | Douglass Howser | 2,250 | +(export-aggregated-output)= + ## Export Aggregated Output Python can do most of the heavy lifting for data cleaning, transformations, and general wrangling. But, for charts or tables, it might be preferable to finish in Excel so that visualizations conform to the corporate style guide. Dataframes can be exported into Excel and written into multiple sheets. -``` +```python import xlsxwriter # initiate a writer @@ -345,7 +357,7 @@ writer.save() Geodataframes can be exported as a shapefile or GeoJSON to visualize in ArcGIS/QGIS. -``` +```python gdf.to_file(driver = 'ESRI Shapefile', filename = '../folder/my_shapefile.shp' ) gdf.to_file(driver = 'GeoJSON', filename = '../folder/my_geojson.geojson') diff --git a/docs/analytics_new_analysts/02-data-analysis-intermediate.md b/docs/analytics_new_analysts/02-data-analysis-intermediate.md index a5e1c0baeb..546bd787b9 100644 --- a/docs/analytics_new_analysts/02-data-analysis-intermediate.md +++ b/docs/analytics_new_analysts/02-data-analysis-intermediate.md @@ -10,12 +10,14 @@ After polishing off the [intro tutorial](pandas-intro), you're ready to devour s ## Getting Started -``` +```python import numpy as np import pandas as pd import geopandas as gpd ``` +(create-a-new-column-using-a-dictionary-to-map-the-values)= + ### Create a New Column Using a Dictionary to Map the Values Sometimes, you want to create a new column by converting one set of values into a different set of values. We could write a function or we could use the map function to add a new column. For our `df`, we want a new column that shows the state. @@ -33,7 +35,7 @@ Sometimes, you want to create a new column by converting one set of values into [Quick refresher on functions](pandas-intro) -``` +```python # Create a function called state_abbrev. def state_abbrev(row): # The find function returns the index of where 'Indiana' is found in @@ -56,7 +58,7 @@ df['State'] = df.apply(state_abbrev, axis = 1) But, writing a function could take up a lot of space, especially with all the if-elif-else statements. Alternatively, a dictionary would also work. We could use a dictionary and map the four different city-state values into the state abbreviation. -``` +```python state_abbrev1 = {'Eagleton, Indiana': 'IN', 'South Carolina': 'SC', 'Michigan': 'MI', 'Partridge, Minnesota': 'MN'} @@ -65,7 +67,7 @@ df['State'] = df.Birthplace.map(state_abbrev1) But, if we wanted to avoid writing out all the possible combinations, we would first extract the *state* portion of the city-state text. Then we could map the state's full name with its abbreviation. -``` +```python # The split function splits at the comma and expand the columns. # Everything is stored in a new df called 'fullname'. fullname = df['Birthplace'].str.split(",", expand = True) @@ -101,11 +103,13 @@ All 3 methods would give us this `df`: | Ann Perkins | Michigan | MI | | Ben Wyatt | Partridge, Minnesota | MN | +(loop-over-columns-with-a-dictionary)= + ### Loop over Columns with a Dictionary If there are operations or data transformations that need to be performed on multiple columns, the best way to do that is with a loop. -``` +```python columns = ['colA', 'colB', 'colC'] for c in columns: @@ -115,6 +119,8 @@ for c in columns: df[c] = df[c] * 0.5 ``` +(loop-over-dataframes-with-a-dictionary)= + ### Loop over Dataframes with a Dictionary It's easier and more efficient to use a loop to do the same operations over the different dataframes (df). Here, we want to find the number of Pawnee businesses and Tom Haverford businesses located in each Council District. @@ -138,7 +144,7 @@ This type of question is perfect for a loop. Each df will be spatially joined to | Entertainment 720 | x2 | y2 | 1 | Point(x2, y2) | | Rent-A-Swag | x3 | y3 | 4 | Point(x3, y3) | -``` +```python # Save our existing dfs into a dictionary. The business df is named # 'pawnee"; the tom df is named 'tom'. dfs = {'pawnee': business, 'tom': tom} @@ -166,7 +172,7 @@ for key, value in dfs.items(): Now, our `summary_dfs` dictionary contains 2 items, which are the 2 dataframes with everything aggregated. -``` +```python # To view the contents of this dictionary for key, value in summary_dfs.items(): display(key) diff --git a/docs/analytics_new_analysts/03-data-management.md b/docs/analytics_new_analysts/03-data-management.md index 369f1c4f12..78712b174d 100644 --- a/docs/analytics_new_analysts/03-data-management.md +++ b/docs/analytics_new_analysts/03-data-management.md @@ -20,8 +20,12 @@ Below is a series of tips, tricks and use-cases for managing data throughout the - [Databases](#databases) - [Pickles](#pickles) +(reading-and-writing-data)= + ## Reading and Writing Data +(gcs)= + ### GCS Our team often uses Google Cloud Storage (GCS) for object storage. If you haven't set up your Google authentication, go [here](https://docs.calitp.org/data-infra/analytics_tools/notebooks.html#connecting-to-warehouse) for the instructions. For a walkthrough on how to use GCS buckets, go [here](https://docs.calitp.org/data-infra/analytics_tools/storing_data.html#in-gcs). @@ -30,7 +34,7 @@ By putting data on GCS, anybody on the team can use/access/replicate the data wi To write and read a pandas dataframe as a CSV to GCS: -``` +```python import pandas as pd df.to_csv('gs://calitp-analytics-data/data-analyses/bucket-name/my_csv.csv') @@ -39,11 +43,13 @@ pd.read_csv('gs://calitp-analytics-data/data-analyses/bucket-name/my_csv.csv') ``` +(local-folders)= + ### Local Folders Sometimes, it is easiest to simply use your local file system to store data. -``` +```python import pandas as pd df.to_csv('./my_csv.csv') @@ -52,10 +58,14 @@ pd.read_csv('./my_csv.csv') ``` +(formats-and-use-cases)= + ## Formats and Use-cases Data Interchange: Where everything can be broken. +(csvs)= + ### CSVs CSVs are the lowest common denominator of data files. They are plain text files that contain a list of data. They are best for getting raw data from SQL and storing large blobs on cloud services. For interchange, it is better to use Parquet or even Excel as they preserve datatypes. @@ -64,13 +74,15 @@ Benefits to CSVs include their readability and ease of use for users. Unlike Par The downsides to CSVs are that their sizes can easily get out of hand, making Parquet files a preferable alternative in that regard. CSVs also don't store data types for columns. If there are different data types within a single column, this can lead to numerous issues. For example, if there are strings and integers mixed within a single column, the process of analyzing that CSV becomes extremely difficult and even impossible at times. Finally, another key issue with CSVs is the ability to only store a single sheet in a file without any formatting or formulas. Excel files do a better job of allowing for formulas and different formats. +(excel)= + ### Excel Excel/XLSX is a binary file format that holds information about all the worksheets in a file, including both content and formatting. This means Excel files are capable of holding formatting, images, charts, formulas, etc. CSVs are more limited in this respect. A downside to Excel files is that they aren't commonly readable by data analysis platforms. Every data analysis platform is capable of processing CSVs, but Excel files are a proprietary format that often require extensions in order to be processed. The ease of processing CSVs makes it easier to move data between different platforms, compared with Excel files. Excel files are best for sharing with other teams, except for geographic info (use Shapefiles or GeoJSON instead), if the Excel format is the only available and accessible format. You often might want to write multiple dataframes to a single excel files as sheets. Here's a guide: -``` +```python ## init a writer writer = pd.ExcelWriter('../outputs/filename.xlsx', engine='xlsxwriter') @@ -83,6 +95,8 @@ for key, value in district_dfs.items(): writer.save() ``` +(parquet)= + ### Parquet Parquet is an "open source columnar storage format for use in data analysis systems." Columnar storage is more efficient as it is easily compressed and the data is more homogenous. CSV files utilize a row-based storage format which is harder to compress, a reason why Parquets files are preferable for larger datasets. Parquet files are faster to read than CSVs, as they have a higher querying speed and preserve datatypes (i.e. Number, Timestamps, Points). They are best for intermediate data storage and large datasets (1GB+) on most any on-disk storage. This file format is also good for passing dataframes between Python and R. A similar option is [feather](https://blog.rstudio.com/2016/03/29/feather/). @@ -91,13 +105,15 @@ One of the downsides to Parquet files is the inability to quickly look at the da Here is a way to use pandas to convert a local CSV file to a Parquet file: -``` +```python import pandas as pd df = pd.read_csv('my_csv_name.csv') df2 = df.to_parquet('my_parquet_name.parquet') ``` +(feather-files)= + ### Feather Files Feather provides a lightweight binary columnar serialization format for data frames. It is designed to make reading and writing data frames more efficient, as well as to make sharing data across languages easier. Just like Parquet, Feather is also capable of passing dataframes between Python and R, as well as storing column data types. @@ -108,23 +124,27 @@ Feather is not be the ideal file format if you're looking for long-term data sto Once you install the feather package with `$ pip install feather-format` then you can easily write a dataframe. -``` +```python import feather path = 'my_data.feather' feather.write_dataframe(df, path) df = feather.read_dataframe(path) ``` +(geojson)= + ### GeoJSON GeoJSON is an [open-standard format](https://geojson.org/) for encoding a variety of geographic data structures using JavaScript Object Notation (JSON). A GeoJSON object may represent a region of space (a Geometry), a spatially bounded entity (a Feature), or a list of Features (a FeatureCollection). It supports geometry types: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection. JSON is light and easier to read than most geospatial formats, but GeoJSON files can quickly get too large to handle. The upside is that a GeoJSON file is often easier to work with than a Shapefile. -``` +```python import geopandas as gpd gdf = gpd.read_file('https://data.cityofnewyork.us/api/geospatial/tqmj-j8zm?method=export&format=GeoJSON') ``` +(shapefiles)= + ### Shapefiles Shapefiles are a geospatial vector data format for geographic information system software and the original file format for geospatial data. They are capable of spatially describing vector features: points, lines, and polygons. Geopandas has good support for reading / writing shapefiles. @@ -135,7 +155,7 @@ It is often better to use `geojson` vs `shapefiles` since the former is easier t Here is a template for one way to read and write shapefiles using pandas: -``` +```python import geopandas as gpd import os @@ -148,14 +168,20 @@ if not os.path.exists('./outputs/my_dir_name'): gdf.to_file('./outputs/my_dir_name') ``` +(pbf-protocolbuffer-binary-format)= + ### PBF (Protocolbuffer Binary Format) Protocol Buffers is a method of serializing structured data. It is used for storing and interchanging structured information of all types. PBF involves an interface description language that describes the structure of some data and a program that generates source code from that description for generating or parsing a stream of bytes that represents the structured data. As compared to XML, it is designed to be simpler and quicker. A benefit of using PBF is that you can define how you want your data to be structured once and then use special generated source code to easily write and read your structured data to and from a variety of data streams. It is also possible to update the defined data structure without breaking deployed programs that are compiled against the older structure/format. Although PBF was designed as a better medium for communication between systems than XML, it only has some marginal advantages when compared to JSON. +(databases)= + ### Databases A whole field of study, it is often useful to use a DB for analytics and aggregated queries, rather than just your production datastore. +(pickles)= + ### Pickles A way of serializing arbitrary python objects into a byte stream with the intent of storing it in a file/database. Danger lives here. diff --git a/docs/analytics_new_analysts/04-notebooks.md b/docs/analytics_new_analysts/04-notebooks.md index a329e31452..192a240233 100644 --- a/docs/analytics_new_analysts/04-notebooks.md +++ b/docs/analytics_new_analysts/04-notebooks.md @@ -24,6 +24,8 @@ This document is meant to outline some recommendations for how to best use noteb - [Prose and Documentation](#prose-and-documentation) - [Data Access](#data-access) +(notebooks-and-reproducibility)= + ## Notebooks and Reproducibility [Scientific](https://arxiv.org/abs/1605.04339) @@ -56,6 +58,8 @@ if a notebook analysis cannot be run without human intervention, it is not repro This all can be summarized as "restart and run all, or it didn't happen." +(notebooks-and-version-control)= + ## Notebooks and Version Control Jupyter notebooks are stored as JSON documents. @@ -82,6 +86,8 @@ There are a few things that can be done to mitigate this: Often such code is best removed from the interactive notebook environment and put in plain-text scripts, where it can be more easily automated and tracked. +(prose-and-documentation)= + ## Prose and Documentation One of the best features about notebooks is that they allow for richer content than normal scripts. @@ -99,6 +105,8 @@ One of the most remarkable findings of this study was just how many notebooks in Over a quarter of notebooks include no prose. We should endeavor to *not* be in that first bin. +(data-access)= + ## Data Access Many attempts to reproduce data analyses fail quickly. diff --git a/docs/analytics_new_analysts/05-spatial-analysis-basics.md b/docs/analytics_new_analysts/05-spatial-analysis-basics.md index 8f9b533c87..baef6e1117 100644 --- a/docs/analytics_new_analysts/05-spatial-analysis-basics.md +++ b/docs/analytics_new_analysts/05-spatial-analysis-basics.md @@ -6,24 +6,26 @@ Place matters. That's why data analysis often includes a geospatial or geographi Below are short demos for getting started: -- [Import and export data in Python](#import-and-export-data-in-python) +- [Import and export data in Python](#spatial-analysis-import-and-export-data-in-python) - [Setting and projecting coordinate reference system](#setting-and-projecting-coordinate-reference-system) ## Getting Started -``` +```python # Import Python packages import pandas as pd import geopandas as gpd ``` -## Import and Export Data in Python +(spatial-analysis-import-and-export-data-in-python)= + +## Import and Export Data in Python for Spatial Analysis ### **Local files** We import a tabular dataframe `my_csv.csv` and a geodataframe `my_geojson.geojson` or `my_shapefile.shp`. -``` +```python df = pd.read_csv('../folder/my_csv.csv') # GeoJSON @@ -41,7 +43,7 @@ gdf.to_file(driver = 'ESRI Shapefile', filename = '../folder/my_shapefile.shp' ) To read in our dataframe (df) and geodataframe (gdf) from GCS: -``` +```python GCS_BUCKET = 'gs://calitp-analytics-data/data-analyses/bucket_name/' df = pd.read_csv(f'{GCS_BUCKET}my-csv.csv') @@ -61,6 +63,8 @@ utils.geoparquet_gcs_export(gdf, GCS_FILE_PATH, FILE_NAME) Additional general information about various file types can be found in the [Data Management section](data-management-page). +(setting-and-projecting-coordinate-reference-system)= + ## Setting and Projecting Coordinate Reference System A coordinate reference system (CRS) tells geopandas how to plot the coordinates on the Earth. Starting with a shapefile usually means that the CRS is already set. In that case, we are interested in re-projecting the gdf to a different CRS. The CRS is chosen specific to a region (i.e., USA, Southern California, New York, etc) or for its map units (i.e., decimal degrees, US feet, meters, etc). Map units that are US feet or meters are easier to work when it comes to defining distances (100 ft buffer, etc). @@ -86,7 +90,7 @@ In ArcGIS, layers must have the same geographic coordinate system and projected In Python, the `geometry` column holds information about the geographic coordinate system and its projection. All gdfs must be set to the same CRS before performing any spatial operations between them. Changing `geometry` from WGS84 to CA State Plane is a datum transformation (WGS84 to NAD83) and projection to CA State Plane Zone 5. -``` +```python # Check to see what the CRS is gdf.crs @@ -105,7 +109,7 @@ There are [lots of different CRS available](https://epsg.io). The most common on | 2229 | CA State Plane Zone 5 | US feet | | 3310 | CA Albers | meters | -``` +```python # If the CRS is not set after checking it with gdf.crs gdf = gdf.set_crs('EPSG:4326') diff --git a/docs/analytics_new_analysts/06-spatial-analysis-intro.md b/docs/analytics_new_analysts/06-spatial-analysis-intro.md index 8e7e3310e9..50d309a7ac 100644 --- a/docs/analytics_new_analysts/06-spatial-analysis-intro.md +++ b/docs/analytics_new_analysts/06-spatial-analysis-intro.md @@ -6,20 +6,22 @@ Place matters. That's why data analysis often includes a geospatial or geographi Below are short demos of common techniques to help get you started with exploring your geospatial data. -- [Merge tabular and geospatial data](#merge-tabular-and-geospatial-data) +- [Merge tabular and geospatial data](#spatial-analysis-merge-tabular-and-geospatial-data) - [Attach geographic characteristics to all points or lines that fall within a boundary (spatial join and dissolve)](#attach-geographic-characteristics-to-all-points-or-lines-that-fall-within-a-boundary) - [Aggregate and calculate summary statistics](#aggregate-and-calculate-summary-statistics) - [Buffers](#buffers) ## Getting Started -``` +```python # Import Python packages import pandas as pd import geopandas as gpd ``` -## Merge Tabular and Geospatial Data +(spatial-analysis-merge-tabular-and-geospatial-data)= + +## Merge Tabular and Geospatial Data for Spatial Analysis We have two files: Council District boundaries (geospatial) and population values (tabular). Through visual inspection, we know that `CD` and `District` are columns that help us make this match. @@ -41,7 +43,7 @@ We have two files: Council District boundaries (geospatial) and population value We could merge these two dfs using the District and CD columns. If our left df is a geodataframe (gdf), then our merged df will also be a gdf. -``` +```python merge = pd.merge(gdf, df, left_on = 'District', right_on = 'CD') merge ``` @@ -52,13 +54,15 @@ merge | 2 | polygon | 2 | Jeremy Jamm | 2,000 | | 3 | polygon | 3 | Douglass Howser | 2,250 | +(attach-geographic-characteristics-to-all-points-or-lines-that-fall-within-a-boundary)= + ## Attach Geographic Characteristics to All Points or Lines That Fall Within a Boundary Sometimes with a point shapefile (list of lat/lon points), we want to count how many points fall within the boundary. Unlike the previous example, these points aren't attached with Council District information, so we need to generate that ourselves. The ArcGIS equivalent of this is a **spatial join** between the point and polygon shapefiles, then **dissolving** to calculate summary statistics. -``` +```python locations = gpd.read_file('../folder/paunch_burger_locations.geojson') gdf = gpd.read_file('../folder/council_boundaries.geojson') @@ -91,7 +95,7 @@ gdf = gdf.to_crs('EPSG:4326') A spatial join finds the Council District the location falls within and attaches that information. -``` +```python join = gpd.sjoin(locations, gdf, how = 'inner', predicate = 'intersects') # how = 'inner' means that we only want to keep observations that matched, @@ -110,11 +114,13 @@ The `join` gdf looks like this. We lost Stores 4 (Eagleton) and 7 (Indianapolis) | 5 | Pawnee | $4 | (x5, y5) | 1 | polygon | | 6 | Pawnee | $6 | (x6, y6) | 2 | polygon | +(aggregate-and-calculate-summary-statistics)= + ## Aggregate and Calculate Summary Statistics We want to count the number of Paunch Burger locations and their total sales within each District. -``` +```python summary = join.pivot_table( index = ['District'], @@ -150,7 +156,7 @@ summary By keeping the `Geometry` column, we're able to export this as a GeoJSON or shapefile. -``` +```python summary.to_file(driver = 'GeoJSON', filename = '../folder/pawnee_sales_by_district.geojson') @@ -158,6 +164,8 @@ summary.to_file(driver = 'ESRI Shapefile', filename = '../folder/pawnee_sales_by_district.shp') ``` +(buffers)= + ## Buffers Buffers are areas of a certain distance around a given point, line, or polygon. Buffers are used to determine proximity. A 5 mile buffer around a point would be a circle of 5 mile radius centered at the point. This [ESRI page](http://desktop.arcgis.com/en/arcmap/10.3/tools/analysis-toolbox/buffer.htm) shows how buffers for points, lines, and polygons look. @@ -193,7 +201,7 @@ We start with two point shapefiles: `locations` (Paunch Burger locations) and `h First, prepare our point gdf and change it to the right projection. Pawnee is in Indiana, so we'll use EPSG:2965. -``` +```python # Use NAD83/Indiana East projection (units are in feet) homes = homes.to_crs('EPSG:2965') locations = locations.to_crs('EPSG:2965') @@ -201,7 +209,7 @@ locations = locations.to_crs('EPSG:2965') Next, draw a 2 mile buffer around `homes`. -``` +```python # Make a copy of the homes gdf homes_buffer = homes.copy() @@ -215,7 +223,7 @@ homes_buffer['geometry'] = homes.geometry.buffer(two_miles) Do a spatial join between `locations` and `homes_buffer`. Repeat the process of spatial join and aggregation in Python as illustrated in the previous section (spatial join and dissolve in ArcGIS). -``` +```python sjoin = gpd.sjoin( locations, homes_buffer, @@ -240,7 +248,7 @@ sjoin Count the number of Paunch Burger locations for each friend. -``` +```python count = sjoin.pivot_table(index = 'Name', values = 'Store', aggfunc = 'count').reset_index() diff --git a/docs/analytics_new_analysts/07-spatial-analysis-intermediate.md b/docs/analytics_new_analysts/07-spatial-analysis-intermediate.md index b9569caaca..c27c175a46 100644 --- a/docs/analytics_new_analysts/07-spatial-analysis-intermediate.md +++ b/docs/analytics_new_analysts/07-spatial-analysis-intermediate.md @@ -13,7 +13,7 @@ Below are short demos of other common manipulations of geospatial data. ## Getting Started -``` +```python # Import Python packages import pandas as pd import geopandas as gpd @@ -29,6 +29,8 @@ df = pd.read_csv('../folder/pawnee_businesses.csv') | Jurassic Fork | x3 | y3 | 2 | | Gryzzl | x4 | y4 | 40 | +(create-geometry-column-from-latitude-and-longitude-coordinates)= + ## Create Geometry Column from Latitude and Longitude Coordinates Sometimes, latitude and longitude coordinates are given in a tabular form. The file is read in as a dataframe (df), but it needs to be converted into a geodataframe (gdf). The `geometry` column contains a Shapely object (point, line, or polygon), and is what makes it a geodataframe. A gdf can be exported as GeoJSON, parquet, or shapefile. @@ -37,7 +39,7 @@ In ArcGIS/QGIS, this is equivalent to adding XY data, selecting the columns that First, drop all the points that are potentially problematic (NAs or zeroes). -``` +```python # Drop NAs df = df.dropna(subset=['X', 'Y']) @@ -47,7 +49,7 @@ df = df[(df.X != 0) & (df.Y != 0)] Then, create the `geometry` column. We use a lambda function and apply it to all rows in our df. For every row, take the XY coordinates and make it Point(X,Y). Make sure you set the projection (coordinate reference system)! -``` +```python # Rename columns df.rename(columns = {'X': 'longitude', 'Y':'latitude'}, inplace=True) @@ -69,6 +71,8 @@ gdf | Jurassic Fork | x3 | y3 | 2 | Point(x3, y3) | | Gryzzl | x4 | y4 | 40 | Point(x4, y4) | +(create-geometry-column-from-text)= + ## Create Geometry Column from Text If you are importing your df directly from a CSV or database, the geometry information might be stored as as text. To create our geometry column, we extract the latitude and longitude information and use these components to create a Shapely object. @@ -84,7 +88,7 @@ If you are importing your df directly from a CSV or database, the geometry infor First, we split `Coord` at the comma. -``` +```python # We want to expand the result into multiple columns. # Save the result and call it new. new = df.Coord.str.split(", ", expand = True) @@ -92,7 +96,7 @@ new = df.Coord.str.split(", ", expand = True) Then, extract our X, Y components. Put lat, lon into a Shapely object as demonstrated [in the prior section.](#create-geometry-column-from-latitude-and-longitude-coordinates) -``` +```python # Make sure only numbers, not parentheses, are captured. Cast it as float. # 0 corresponds to the portion before the comma. [1:] means starting from @@ -107,7 +111,7 @@ df['lon'] = new[1].str[:-1].astype(float) Or, do it in one swift move: -``` +```python df['geometry'] = df.dropna(subset=['Coord']).apply( lambda x: Point( float(str(x.Coord).split(",")[0][1:]), @@ -123,6 +127,8 @@ gdf = gpd.GeoDataFrame(df) gdf = df.set_crs('EPSG:4326') ``` +(use-a-loop-to-do-spatial-joins-and-aggregations-over-different-boundaries)= + ## Use a Loop to Do Spatial Joins and Aggregations Over Different Boundaries Let's say we want to do a spatial join between `df` to 2 different boundaries. Different government departments often use different boundaries for their operations (i.e. city planning districts, water districts, transportation districts, etc). Looping over dictionary items would be an efficient way to do this. @@ -140,7 +146,7 @@ We want to count the number of stores and total sales within each Council Distri `council_district` and `planning_district` are polygon shapefiles while `df` is a point shapefile. For simplicity, `council_district` and `planning_district` both use column `ID` as the unique identifier. -``` +```python # Save the dataframes into dictionaries boundaries = {'council': council_district, 'planning': planning_district} @@ -164,7 +170,7 @@ for key, value in boundaries.items(): Our results dictionary contains 2 dataframes: `council_summary` and `planning_summary`. We can see the contents of the results dictionary using this: -``` +```python for key, value in results.items(): display(key) display(value.head()) @@ -183,11 +189,13 @@ results["planning_summary"].head() | 2 | 1 | 2 | | 3 | 1 | 30 | +(multiple-geometry-columns)= + ## Multiple Geometry Columns Sometimes we want to iterate over different options, and we want to see the results side-by-side. Here, we draw multiple buffers around `df`, specifically, 100 ft and 200 ft buffers. -``` +```python # Make sure our projection has US feet as its units df.to_crs('EPSG:2965') @@ -207,7 +215,7 @@ df To create a new gdf with just 100 ft buffers, select the relevant geometry column, `geometry100`, and set it as the geometry of the gdf. -``` +```python df100 = df[['Business', 'Sales_millions', 'geometry100']].set_geometry('geometry100') ``` diff --git a/docs/analytics_new_analysts/08-spatial-analysis-advanced.md b/docs/analytics_new_analysts/08-spatial-analysis-advanced.md index f4eb6ae9a0..58d97cf406 100644 --- a/docs/analytics_new_analysts/08-spatial-analysis-advanced.md +++ b/docs/analytics_new_analysts/08-spatial-analysis-advanced.md @@ -11,7 +11,7 @@ Below are more detailed explanations for dealing with geometry in Python. ## Getting Started -``` +```python # Import Python packages import pandas as pd import geopandas as gpd @@ -19,6 +19,8 @@ from shapely.geometry import Point from geoalchemy2 import WKTElement ``` +(types-of-geometric-shapes)= + ## Types of Geometric Shapes There are six possible geometric shapes that are represented in geospatial data. [More description here.](http://postgis.net/workshops/postgis-intro/geometries.html#representing-real-world-objects) @@ -32,6 +34,8 @@ There are six possible geometric shapes that are represented in geospatial data. The ArcGIS equivalent of these are just points, lines, and polygons. +(geometry-in-memory-and-in-databases)= + ## Geometry In-Memory and in Databases If you're loading a GeoDataFrame (gdf), having the `geometry` column is necessary to do spatial operations in your Python session. The `geometry` column is composed of Shapely objects, such as Point or MultiPoint, LineString or MultiLineString, and Polygon or MultiPolygon. @@ -49,7 +53,7 @@ To summarize: | Local Python session, in-memory | shapely | shapely object: Point, LineString, Polygon and Multi equivalents | CRS is usually set, but most likely will still need to re-project your CRS using EPSG | | Database (PostGIS, SpatiaLite, etc) | geoalchemy | WKT or WKB | define the SRID | -``` +```python # Set the SRID srid = 4326 df = df.dropna(subset=['lat', 'lon']) diff --git a/docs/analytics_tools/data_catalogs.md b/docs/analytics_tools/data_catalogs.md index 5935c0abd3..41de8b2dc4 100644 --- a/docs/analytics_tools/data_catalogs.md +++ b/docs/analytics_tools/data_catalogs.md @@ -30,13 +30,15 @@ Each task sub-folder within the `data-analyses` repo should come with its own da 3. [Google Cloud Storage](#google-cloud-storage) (GCS) Buckets 4. [Sample Data Catalog](#sample-data-catalog) +(intake)= + ### Intake Data analysts tend to load their data from many heterogeneous sources (Databases, CSVs, JSON, etc), but at the end of the day, they often end up with the data in dataframes or numpy arrays. One tool for managing that in Python is the relatively new project `intake`. Intake provides a way to make data catalogs can then be used load sources into dataframes and arrays. These catalogs are plain text and can then be versioned and published, allowing for more ergonomic documentation of the data sources used for a project. `intake-dcat` is a tool for allowing intake to more easily interact with DCAT catalogs commonly found on open data portals. -Refer to this [sample-catalog.yml](sample-catalog) to see how various data sources and file types are documented. Each dataset is given a human-readable name, with optional metadata associated. +Refer to this [sample-catalog.yml](#sample-data-catalog) to see how various data sources and file types are documented. Each dataset is given a human-readable name, with optional metadata associated. File types that work within GCS buckets, URLs, or DCATs (open data catalogs): @@ -54,13 +56,15 @@ catalog = intake.open_catalog("./sample-catalog.yml") catalog = intake.open_catalog("./*.yml") ``` +(open-data-portals)= + ### Open Data Portals Open data portals (such as the CA Open Data Portal and CA Geoportal) usually provide a DCAT catalog for their datasets, including links for downloading them and metadata describing them. Many civic data analysis projects end up using these open datasets. When they do, it should be clearly documented. - To input a dataset from an open data portal, find the dataset's identifier for the `catalog.yml`. -- Ex: The URL for CA Open Data Portal is: https://data.ca.gov. -- Navigate to the corresponding `data.json` file at https://data.ca.gov/data.json +- Ex: The URL for CA Open Data Portal is: [https://data.ca.gov](https://data.ca.gov). +- Navigate to the corresponding `data.json` file at [https://data.ca.gov/data.json](https://data.ca.gov/data.json). - Each dataset has associated metadata, including `accessURL`, `landingPage`, etc. Find the dataset's `identifier`, and input that as the catalog item. ```yaml @@ -79,7 +83,7 @@ To import this dataset as a dataframe within the notebook: df = catalog.ca_open_data.cdcr_population_covid_tracking.read() ``` -(catalogue-cloud-storage)= +(google-cloud-storage)= ### Google Cloud Storage @@ -124,7 +128,7 @@ gdf1 = catalog.test_zipped_shapefile.read() gdf2 = catalog.test_geoparquet.read() ``` -(sample-catalog)= +(sample-data-catalog)= # Sample Data Catalog diff --git a/docs/analytics_tools/github_setup.md b/docs/analytics_tools/github_setup.md index 533d598685..3a5fc57fcd 100644 --- a/docs/analytics_tools/github_setup.md +++ b/docs/analytics_tools/github_setup.md @@ -10,6 +10,8 @@ - [Cloning a Repository](cloning-a-repository) 2. [Onboarding Setup (Caltrans Windows PC)](#onboarding-setup-ct) +(onboarding-setup)= + ## Onboarding Setup (JupyterHub) We'll work through getting set up with SSH and GitHub on JupyterHub and cloning one GitHub repo. This is the first task you'll need to complete before contributing code. Repeat the steps in [Cloning a Repository](cloning-a-repository) for other repos. diff --git a/docs/analytics_tools/jupyterhub.md b/docs/analytics_tools/jupyterhub.md index 4865d81e51..4160fb3bbb 100644 --- a/docs/analytics_tools/jupyterhub.md +++ b/docs/analytics_tools/jupyterhub.md @@ -23,19 +23,23 @@ Analyses on JupyterHub are accomplished using notebooks, which allow users to mi 09. [Jupyter Notebook Best Practices](notebook-shortcuts) 10. [Developing warehouse models in Jupyter](jupyterhub-warehouse) +(using-jupyterhub)= + ## Using JupyterHub For Python users, we have deployed a cloud-based instance of JupyterHub to make creating, using, and sharing notebooks easy. This avoids the need to set up a local environment, provides dedicated storage, and allows you to push to GitHub. +(logging-in-to-jupyterhub)= + ### Logging in to JupyterHub JupyterHub currently lives at [notebooks.calitp.org](https://notebooks.calitp.org/). Note: you will need to have been added to the Cal-ITP organization on GitHub to obtain access. If you have yet to be added to the organization and need to be, ask in the `#services-team` channel in Slack. -(connecting-to-warehouse)= +(connecting-to-the-warehouse)= ### Connecting to the Warehouse @@ -63,6 +67,8 @@ gcloud auth application-default login If you are still not able to connect, make sure you have the suite of permissions associated with other analysts. +(increasing-the-query-limit)= + ### Increasing the Query Limit By default, there is a query limit set within the Jupyter Notebook. Most queries should be within that limit, and running into `DatabaseError: 500 Query exceeded limit for bytes billed` should be a red flag to investigate whether such a large query is needed for the analysis. To increase the query limit, add and execute the following in your notebook: @@ -76,7 +82,7 @@ os.environ["CALITP_BQ_MAX_BYTES"] = str(20_000_000_000) tbls._init() ``` -(querying-sql-jupyterhub)= +(increasing-the-storage-limit)= ### Increasing the Storage Limit @@ -88,6 +94,8 @@ After making the configuration change in GKE, shut down and restart the user's J 100GB should generally be more than enough for a given user - if somebody's storage has already been set to 100GB and they hit a space limit again, that may indicate a need to clean up past work rather than a need to increase available storage. +(querying-sql-jupyterhub)= + ### Querying with SQL in JupyterHub JupyterHub makes it easy to query SQL in the notebooks. @@ -125,12 +133,14 @@ LIMIT 10 ### Saving Code to Github -Use [this link](committing-from-jupyterhub) to navigate to the `Saving Code` section of the docs to learn how to commit code to GitHub from the Jupyter terminal. Once there, you will need to complete the instructions in the following sections: +Use [this link](#saving-code-jupyter) to navigate to the `Saving Code` section of the docs to learn how to commit code to GitHub from the Jupyter terminal. Once there, you will need to complete the instructions in the following sections: - [Adding a GitHub SSH Key to Jupyter](authenticating-github-jupyter) - [Persisting your SSH Key and Enabling Extensions](persisting-ssh-and-extensions) - [Cloning a Repository](cloning-a-repository) +(environment-variables)= + ### Environment Variables Sometimes if data access is expensive, or if there is sensitive data, then accessing it will require some sort of credentials (which may take the form of passwords or tokens). diff --git a/docs/analytics_tools/knowledge_sharing.md b/docs/analytics_tools/knowledge_sharing.md index fd28df323f..5add3ed9a3 100644 --- a/docs/analytics_tools/knowledge_sharing.md +++ b/docs/analytics_tools/knowledge_sharing.md @@ -18,8 +18,12 @@ Here are some resources data analysts have collected and referenced, that will h - [Ipywidgets](#ipywidgets) - [Markdown](#markdown) +(data-analysis)= + ## Data Analysis +(python)= + ### Python - [Composing Programs: comprehensive Python course](https://composingprograms.com/) @@ -29,6 +33,8 @@ Here are some resources data analysts have collected and referenced, that will h - [Find the elements that are in one list, but not in another list.](https://stackoverflow.com/questions/41125909/python-find-elements-in-one-list-that-are-not-in-the-other) - [What does += do?](https://stackoverflow.com/questions/4841436/what-exactly-does-do) +(pandas)= + ### Pandas - [Turn columns into dummy variables.](https://pandas.pydata.org/docs/reference/api/pandas.get_dummies.html) @@ -36,6 +42,8 @@ Here are some resources data analysts have collected and referenced, that will h - [Display multiple dataframes side by side.](https://stackoverflow.com/questions/38783027/jupyter-notebook-display-two-pandas-tables-side-by-side) - [Display all rows or columns of a dataframe in the notebook](https://pandas.pydata.org/pandas-docs/stable/user_guide/options.html) +(summarizing)= + ### Summarizing - [Groupby and calculate a new value, then use that value within your DataFrame.](https://stackoverflow.com/questions/35640364/python-pandas-max-value-in-a-group-as-a-new-column) @@ -43,6 +51,8 @@ Here are some resources data analysts have collected and referenced, that will h - [Pandas profiling tool: creates html reports from DataFrames.](https://github.com/ydataai/pandas-profiling) - [Examples](https://pandas-profiling.ydata.ai/examples/master/census/census_report.html) +(merging)= + ### Merging - When working with data sets where the "merge on" column is a string data type, it can be difficult to get the DataFrames to join. For example, df1 lists County of Sonoma, Human Services Department, Adult and Aging Division, but df2 references the same department as: County of Sonoma (Human Services Department) . @@ -50,34 +60,38 @@ Here are some resources data analysts have collected and referenced, that will h - Potential Solution #2: [use the package fuzzymatcher. This will require you to carefully comb through for any bad matches.](https://pbpython.com/record-linking.html) - Potential Solution #3: [if you don't have too many values, use a dictionary.](https://github.com/cal-itp/data-analyses/blob/main/drmt_grants/TIRCP_functions.py#:~:text=%23%23%23%20RECIPIENTS%20%23%23%23,%7D) +(dates)= + ### Dates - [Use shift to calculate the number of days between two dates.](https://towardsdatascience.com/all-the-pandas-shift-you-should-know-for-data-analysis-791c1692b5e) -``` +```python df['n_days_between'] = (df['prepared_date'] - df.shift(1)['prepared_date']).dt.days ``` - [Assign fiscal year to a date.](https://stackoverflow.com/questions/59181855/get-the-financial-year-from-a-date-in-a-pandas-dataframe-and-add-as-new-column) -``` +```python # Make sure your column is a date time object df['financial_year'] = df['base_date'].map(lambda x: x.year if x.month > 3 else x.year-1) ``` +(monetary-values)= + ### Monetary Values - [Reformat values that are in scientific notation into millions or thousands.](https://github.com/d3/d3-format) - [Example in notebook.](https://github.com/cal-itp/data-analyses/blob/30de5cd2fed3a37e2c9cfb661929252ad76f6514/dla/e76_obligated_funds/_dla_utils.py#L221) -``` +```python x=alt.X("Funding Amount", axis=alt.Axis(format="$.2s", title="Obligated Funding ($2021)")) ``` - [Reformat values from 19000000 to $19.0M.](https://stackoverflow.com/questions/41271673/format-numbers-in-a-python-pandas-dataframe-as-currency-in-thousands-or-millions) - Adjust for inflation. -``` +```python # Must install and import cpi package for the function to work. def adjust_prices(df): cols = ["total_requested", @@ -114,8 +128,12 @@ def adjust_prices(df): return df ``` +(visualization)= + ## Visualization +(charts)= + ### Charts #### Altair @@ -123,30 +141,36 @@ def adjust_prices(df): - [Manually concatenate a bar chart and line chart to create a dual axis graph.](https://github.com/altair-viz/altair/issues/1934) - [Adjust the time units of a datetime column for an axis.](https://altair-viz.github.io/user_guide/transform/timeunit.html) - [Label the lines on a line chart.](https://stackoverflow.com/questions/61194028/adding-labels-at-end-of-line-chart-in-altair) -- [Layer altair charts, lose color with no encoding, workaround to get different colors to appear on legend.](altair-viz/altair#1099) +- [Layer altair charts, lose color with no encoding, workaround to get different colors to appear on legend.](https://github.com/altair-viz/altair/issues/1099) - [Add regression line to scatterplot.](https://stackoverflow.com/questions/61447422/quick-way-to-visualise-multiple-columns-in-altair-with-regression-lines) - [Adjust scales for axes to be the min and max values.](https://stackoverflow.com/questions/62281179/how-to-adjust-scale-ranges-in-altair) - [Resolving the error 'TypeError: Object of type 'Timestamp' is not JSON serializable'](https://github.com/altair-viz/altair/issues/1355) - [Manually sort a legend.](https://github.com/cal-itp/data-analyses/blob/460e9fc8f4311e90d9c647e149a23a9e38035394/Agreement_Overlap/Visuals.ipynb) - Add tooltip to chart functions. -``` +```python def add_tooltip(chart, tooltip1, tooltip2): chart = ( chart.encode(tooltip= [tooltip1,tooltip2])) return chart ``` +(maps)= + ### Maps - [Examples of folium, branca, and color maps.](https://nbviewer.org/github/python-visualization/folium/blob/v0.2.0/examples/Colormaps.ipynb) - [Quick interactive maps with Geopandas.gdf.explore()](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.explore.html) +(dataframes)= + ### DataFrames - [Styling dataframes with HTML.](https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html) - [After styling a DataFrame, you will have to access the underlying data with .data](https://stackoverflow.com/questions/56647813/perform-operations-after-styling-in-a-dataframe). +(ipywidgets)= + ### ipywidgets #### Tabs @@ -156,6 +180,8 @@ def add_tooltip(chart, tooltip1, tooltip2): - [Notebook example.](https://github.com/cal-itp/data-analyses/blob/main/dla/e76_obligated_funds/charting_function_work.ipynb?short_path=1c01de9#L302333) - [Example on Ipywidgets docs page.](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html#Tabs) +(markdown)= + ### Markdown - [Create a markdown table.](https://www.pluralsight.com/guides/working-tables-github-markdown) diff --git a/docs/analytics_tools/python_libraries.md b/docs/analytics_tools/python_libraries.md index 2bf02c6e8c..0ce25308c3 100644 --- a/docs/analytics_tools/python_libraries.md +++ b/docs/analytics_tools/python_libraries.md @@ -27,11 +27,11 @@ The following libraries are available and recommended for use by Cal-ITP data an
- [Basic Query](#basic-query)
- [Collect Query Results](#collect-query-results)
- [Show Query SQL](#show-query-sql) -
- [More siuba Resources](more-siuba-resources) -4. [pandas](pandas-resources) +
- [More siuba Resources](#more-siuba-resources) +4. [pandas](#pandas-resources) 5. [Add New Packages](#add-new-packages) 6. [Updating calitp-data-analysis](#updating-calitp-data-analysis) -7. [Appendix: calitp-data-infra](appendix) +7. [Appendix: calitp-data-infra](#appendix) (shared-utils)= @@ -116,6 +116,8 @@ It supports most [pandas Series methods](https://pandas.pydata.org/pandas-docs/s The examples below go through the basics of using siuba, collecting a database query to a local DataFrame, and showing SQL test queries that siuba code generates. +(basic-query)= + ### Basic query ```{code-cell} @@ -130,6 +132,8 @@ from siuba import _, filter, count, collect, show_query ) ``` +(collect-query-results)= + ### Collect query results Note that siuba by default prints out a preview of the SQL query results. @@ -143,6 +147,8 @@ tbl_agency_names.head() ``` +(show-query-sql)= + ### Show query SQL While `collect()` fetches query results, `show_query()` prints out the SQL code that siuba generates. @@ -172,6 +178,8 @@ The library pandas is very commonly used in data analysis, and the external reso - [Cheat Sheet - pandas](https://pandas.pydata.org/Pandas_Cheat_Sheet.pdf) +(add-new-packages)= + ## Add New Packages While most Python packages an analyst uses come in JupyterHub, there may be additional packages you'll want to use in your analysis. @@ -192,13 +200,13 @@ Adapted from [this Slack thread](https://cal-itp.slack.com/archives/C02KH3DGZL7/ 1. Make the changes you want in the `calitp-data-analysis` folder inside `packages` [here](https://github.com/cal-itp/data-infra/tree/main/packages/calitp-data-analysis). If you are only changing package metadata (author information, package description, etc.) without changing the function of the package itself, that information lives in `pyproject.toml` rather than in the `calitp-data-analysis` subfolder. - If you are adding a new function that relies on a package that isn't already a dependency, run `poetry add ` after changing directories to `data-infra/packages/calitp_data_analysis`. Check this [Jupyter image file](https://github.com/cal-itp/data-infra/blob/main/images/jupyter-singleuser/pyproject.toml) for the version number associated with the package, because you should specify the version. - - For example, your function relies on `dask`. In the Jupyter image file, the version is `dask = "~2022.8"` so run `poetry add dask==~2022.8` in the terminal. + - For example, your function relies on `dask`. In the Jupyter image file, the version is `dask = "~2022.8"` so run `poetry add dask==~2022.8` in the terminal. - You may also have run `poetry install mypy`. `mypy` is a package that audits all the functions. [Read more about it here.](https://mypy-lang.org/) 2. Each time you update the package, you must also update the version number. We use dates to reflect which version we are on. Update the version in [pyproject.toml](https://github.com/cal-itp/data-infra/blob/main/packages/calitp-data-analysis/pyproject.toml#L3) that lives in `calitp-data-analysis` to either today's date or a future date. 3. Open a new pull request and make sure the new version date appears on the [test version page](https://test.pypi.org/project/calitp-data-analysis/). - The new version date may not show up on the test page due to errors. Check the GitHub Action page of your pull request to see the errors that have occurred. - If you run into the error message like this, `error: Skipping analyzing "dask_geopandas": module is installed, but missing library stubs or py.typed marker [import]` go to your `.py` file and add `# type: ignore` behind the package import. - - To fix the error above, change `import dask_geopandas as dg` to `import dask_geopandas as dg # type: ignore`. + - To fix the error above, change `import dask_geopandas as dg` to `import dask_geopandas as dg # type: ignore`. - It is encouraged to make changes in a set of smaller commits. For example, add all the necessary packages with `poetry run ` in a cell of Jupyter notebook and import a package (or two) such as `from calitp_data_analysis import styleguide`. 5. Update the new version number in the `data-infra` repository [here](https://github.com/cal-itp/data-infra/blob/main/images/dask/requirements.txt#L30), [here](https://github.com/cal-itp/data-infra/blob/main/images/jupyter-singleuser/pyproject.toml#L48), [here](https://github.com/cal-itp/data-infra/blob/main/docs/requirements.txt), and anywhere else you find a reference to the old version of the package. You'll also want to do the same for any other Cal-ITP repositories that reference the calitp-data-analysis package. diff --git a/docs/analytics_tools/saving_code.md b/docs/analytics_tools/saving_code.md index 61889eeeb6..dd663e30e7 100644 --- a/docs/analytics_tools/saving_code.md +++ b/docs/analytics_tools/saving_code.md @@ -10,14 +10,14 @@ Doing work locally and pushing directly from the command line is a similar workf 1. What's a typical [project workflow](#project-workflow)? 2. Someone is collaborating on my branch, how do we [stay in sync](#pulling-and-pushing-changes)? - - The `main` branch is ahead, and I want to [sync my branch with `main`](rebase-and-merge) + - The `main` branch is ahead, and I want to [sync my branch with `main`](#rebase-and-merge) - [Rebase](#rebase) or [merge](#merge) - - Options to [Resolve Merge Conflicts](resolve-merge-conflicts) + - Options to [Resolve Merge Conflicts](#resolve-merge-conflicts) 3. [Other Common GitHub Commands](#other-common-github-commands) - - [External Git Resources](external-git-resources) + - [External Git Resources](#external-git-resources) - [Committing in the Github User Interface](#pushing-drag-drop) -(committing-from-jupyterhub)= +(project-workflow)= ## Project Workflow @@ -30,13 +30,15 @@ In the `data-analyses` repo, separate analysis tasks live in their own directori 03. Do some work...add, delete, rename files, etc 04. See all the status changes to your files: `git status` 05. When you're ready to save some of that work, stage the files you want to commit with `git add foldername/notebook1.ipynb foldername/script1.py`. To stage all the files, use `git add .`. -06. Once you are ready to commit, add a commit message to associate with all the changes: `git commit -m "exploratory work" ` +06. Once you are ready to commit, add a commit message to associate with all the changes: `git commit -m "exploratory work"` 07. Push those changes from local to remote branch (note: branch is `my-new-branch` and not `main`): `git push origin my-new-branch`. 08. To review a log of past commits: `git log` 09. When you are ready to merge all the commits into `main`, open a pull request (PR) on the remote repository, and merge it in! 10. Go back to `main` and update your local to match the remote: `git switch main`, `git pull origin main` 11. Once you've merged your branch into `main` and deleted it from the remote, you can delete your branch locally: `git branch -d my-new-branch`. You can reuse the branch name later. +(pulling-and-pushing-changes)= + ## Pulling and Pushing Changes Especially when you have a collaborator working on the same branch, you want to regularly sync your work with what's been committed by your collaborator. Doing this frequently allows you to stay in sync, and avoid unnecessary merge conflicts. @@ -63,6 +65,8 @@ Read more about the differences between `rebase` and `merge`: - [Stack Overflow](https://stackoverflow.com/questions/59622140/git-merge-vs-git-rebase-for-merge-conflict-scenarios)
+(rebase)= + #### Rebase Rebasing is an important tool to be familiar with and introduce into your workflow. The video and instructions below help to provide information on how to begin using it in your collaborations with the team. @@ -80,6 +84,8 @@ A rebase might be preferred, especially if all your work is contained on your br 7. Make any commits you want (from step 1) with `git add`, `git commit -m "commit message"` 8. Force-push those changes to complete the rebase and rewrite the commit history: `git push origin my-new-branch -f` +(merge)= + #### Merge Note: Merging with [fast-forward](https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---ff) behaves similarly to a rebase. @@ -105,6 +111,8 @@ If you discover merge conflicts and they are within a single notebook that only `git checkout --theirs path/to/notebook.ipynb` - From here, just add the file and commit with a message as you normally would and the conflict should be fixed in your Pull Request. +(other-common-github-commands)= + ## Other Common GitHub Commands These are helpful Git commands an analyst might need, listed in no particular order. diff --git a/docs/analytics_tools/storing_data.md b/docs/analytics_tools/storing_data.md index 8f50c07a89..bd5010b009 100644 --- a/docs/analytics_tools/storing_data.md +++ b/docs/analytics_tools/storing_data.md @@ -22,16 +22,18 @@ Our team uses Google Cloud Storage (GCS) buckets, specifically the `calitp-analy ## Table of Contents 1. [Introduction](#introduction) -2. [Storing New Data - Screencast](storing-new-data-screencast) -3. [Uploading Data from a Notebook](uploading-from-notebook) +2. [Storing New Data - Screencast](#storing-new-data-screencast) +3. [Uploading Data from a Notebook](#uploading-from-notebook)
- [Tabular Data](#tabular-data) -
- [Parquet](#parquet) +
- [Parquet](#storing-data-parquet)
- [CSV](#csv)
- [Geospatial Data](#geospatial-data)
- [Geoparquet](#geoparquet)
- [Zipped shapefile](#zipped-shapefile) -
- [GeoJSON](#geojson) -4. [Uploading data in Google Cloud Storage](in-gcs) +
- [GeoJSON](#storing-data-geojson) +4. [Uploading data in Google Cloud Storage](#in-gcs) + +(introduction)= ## Introduction @@ -44,7 +46,7 @@ In order to save data being used in a report, you can use two methods: Watch the screencast below and read the additional information to begin. -**Note**: To access Google Cloud Storage you will need to have set up your Google authentication. If you have yet to do so, [follow these instructions](connecting-to-warehouse). +**Note**: To access Google Cloud Storage you will need to have set up your Google authentication. If you have yet to do so, [follow these instructions](https://docs.calitp.org/data-infra/analytics_tools/notebooks.html#connecting-to-warehouse). (storing-new-data-screencast)= @@ -67,10 +69,14 @@ from calitp_data_analysis import get_fs fs = get_fs() ``` +(tabular-data)= + ### Tabular Data While GCS can store CSVs, parquets, Excel spreadsheets, etc, parquets are the preferred file type. Interacting with tabular datasets in GCS is fairly straightforward and is handled well by `pandas`. +(storing-data-parquet)= + #### Parquet Parquet is an “open source columnar storage format for use in data analysis systems.” Columnar storage is more efficient as it is easily compressed and the data is more homogenous. CSV files utilize a row-based storage format which is harder to compress, a reason why Parquets files are preferable for larger datasets. Parquet files are faster to read than CSVs, as they have a higher querying speed and preserve datatypes (ie, Number, Timestamps, Points). They are best for intermediate data storage and large datasets (1GB+) on most any on-disk storage. This file format is also good for passing dataframes between Python and R. A similar option is feather. @@ -83,6 +89,8 @@ df = pd.read_parquet('gs://calitp-analytics-data/data-analyses/task-subfolder/te df.to_parquet('gs://calitp-analytics-data/data-analyses/task-subfolder/test.parquet') ``` +(csv)= + #### CSV ```python @@ -91,10 +99,14 @@ df = pd.read_csv('gs://calitp-analytics-data/data-analyses/task-subfolder/test.c df.to_csv('gs://calitp-analytics-data/data-analyses/task-subfolder/test.parquet') ``` +(geospatial-data)= + ### Geospatial Data Geospatial data may require a little extra work, due to how `geopandas` and GCS interacts. +(geoparquet)= + #### Geoparquet Importing geoparquets directly from GCS works with `geopandas`, but exporting geoparquets into GCS requires an extra step of uploading. @@ -124,13 +136,17 @@ utils.geoparquet_gcs_export( ) ``` +(zipped-shapefile)= + #### Zipped Shapefile -Refer to the [data catalogs doc](catalogue-cloud-storage) to list a zipped shapefile, and read in the zipped shapefile with the `intake` method. Zipped shapefiles saved in GCS cannot be read in directly using `geopandas`. +Refer to the [data catalogs doc](data-catalogs) to list a zipped shapefile, and read in the zipped shapefile with the `intake` method. Zipped shapefiles saved in GCS cannot be read in directly using `geopandas`. + +(storing-data-geojson)= #### GeoJSON -Refer to the [data catalogs doc](catalogue-cloud-storage) to list a GeoJSON, and read in the GeoJSON with the `intake` method. GeoJSONs saved in GCS cannot be read in directly using `geopandas`. +Refer to the [data catalogs doc](data-catalogs) to list a GeoJSON, and read in the GeoJSON with the `intake` method. GeoJSONs saved in GCS cannot be read in directly using `geopandas`. Use the `calitp_data_analysis` package to read in or export geojsons. @@ -158,6 +174,6 @@ utils.geojson_gcs_export( ## Uploading data in Google Cloud Storage -You can access the cloud bucket from the web from https://console.cloud.google.com/storage/browser/calitp-analytics-data. +You can access the cloud bucket from the web from [https://console.cloud.google.com/storage/browser/calitp-analytics-data](https://console.cloud.google.com/storage/browser/calitp-analytics-data). See the above screencast for a walkthrough of using the bucket. diff --git a/docs/analytics_welcome/how_we_work.md b/docs/analytics_welcome/how_we_work.md index c99aeea4b8..4e2ad7a028 100644 --- a/docs/analytics_welcome/how_we_work.md +++ b/docs/analytics_welcome/how_we_work.md @@ -51,6 +51,6 @@ The screencast below introduces: ### GitHub Analytics Repo -The `data-analyses` repo is our main data analysis repository, for sharing quick reports and works in progress. Get set up on GitHub and clone the data-analyses repository [using this link](committing-from-jupyterhub). +The `data-analyses` repo is our main data analysis repository, for sharing quick reports and works in progress. Get set up on GitHub and clone the data-analyses repository [using this link](saving-code-jupyter). For collaborative short-term tasks, create a new folder and work off a separate branch. diff --git a/docs/architecture/services.md b/docs/architecture/services.md index 695cd00753..2fd98bb347 100644 --- a/docs/architecture/services.md +++ b/docs/architecture/services.md @@ -2,7 +2,7 @@ Many services and websites are deployed as part of the Cal-ITP ecosystem, maintained directly by Cal-ITP contributors and orchestrated via Google Kubernetes Engine or published via Netlify or GitHub Pages. -With the exception of Airflow, which is [managed via Google Cloud Composer](../../airflow/README.md#upgrading-airflow-itself), changes to the services discussed here are deployed via CI/CD processes that run automatically when new code is merged to the relevant Cal-ITP repository. These CI/CD processes are not all identical - different services have different testing steps that run when a pull request is opened against the services's code. Some services undergo a full test deployment when a PR is opened, some report the changes that a subject [Helm chart](https://helm.sh/docs/topics/charts/) will undergo upon merge, and some just perform basic linting. +With the exception of Airflow, which is [managed via Google Cloud Composer](https://github.com/cal-itp/data-infra/tree/main/airflow#upgrading-airflow-itself), changes to the services discussed here are deployed via CI/CD processes that run automatically when new code is merged to the relevant Cal-ITP repository. These CI/CD processes are not all identical - different services have different testing steps that run when a pull request is opened against the services's code. Some services undergo a full test deployment when a PR is opened, some report the changes that a subject [Helm chart](https://helm.sh/docs/topics/charts/) will undergo upon merge, and some just perform basic linting. READMEs describing the individual testing and deployment process for each service are linked in the below table, and [the CI README](https://github.com/cal-itp/data-infra/tree/main/ci/README.md) provides some more general context for Kubernetes-based deployments. diff --git a/docs/conf.py b/docs/conf.py index bbceb3a0f3..9dcbd32277 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,7 +56,7 @@ } html_title = "Cal-ITP Data Services" jupyter_cache = "" -jupyter_execute_notebooks = "force" +nb_execution_mode = "force" language = None latex_engine = "pdflatex" myst_enable_extensions = [ diff --git a/docs/requirements.txt b/docs/requirements.txt index d2f2529d59..808ba89aa2 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,12 +1,3 @@ calitp-data-analysis==2023.9.18 -jupyter-book==0.12.0 -# Temporary pinning of pydata-sphinx-theme to workaround Sphinx 4.3.0 error -# https://github.com/pydata/pydata-sphinx-theme/issues/508 -pydata-sphinx-theme==0.7.2 +jupyter-book==1.0.0 sphinxcontrib-mermaid==0.8.1 -# Temporary pinning of older sphinxcontrib-[xyz] reqs until we use Sphinx 5.0.0 or higher -sphinxcontrib-applehelp==1.0.4 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 diff --git a/docs/transit_database/transitdatabase.md b/docs/transit_database/transitdatabase.md index aeabd0fe63..b4cfd7e43c 100644 --- a/docs/transit_database/transitdatabase.md +++ b/docs/transit_database/transitdatabase.md @@ -66,12 +66,16 @@ This requires special handling when importing to the warehouse, because Airtable The following entity relationship diagrams were last updated in 2022 but are preserved for general reference purposes. +(california-transit)= + ### California Transit [![](https://mermaid.ink/img/pako:eNqVVEtv4jAQ_iuWz0W9c1stbbWHbhFw5DLEEzJax07HDqss4b_vOCQQXlLLBSX6XuP5nL3OvEE91cgzgi1DuXZKfh-8BUf_IJJ36tBOJn6vlsg7ynCq1roEB1sMa_0ltK-QIT6C-w7-FvMwgwgBY6Jk3oW6_BalYm_q7HuUemMpFEfOY9b4XaJRUBUwuqj8GO3zu9btQxEwJTkKEZnc9sta7a3W-_zjebGa_1C5ZxULVJIO0sN3RCRQolYWnEt5oI6FZ4rNQ9VHw7bqp69dbN7QS6OqounlCwTzWQPLwGgUuUHnCq3atgs4t5DhhYbBkDFtMKiso0ws7tCKkoQqjwFG8V4l77KR4y0HxeuRoaosiVr05wL0vQ3D8kc9Pu4dIoMLFAer3qx2Rk5tzilu2V2C9oKcC-DUzQUZ5AV-1sRYpiLdml1mS6QXS1uSwsbm5HLDsvLvgtCwA5Pt93czX3ck_Y3oX6WLkTQYc4tZlBVtmsF7dHGG2e4wKS2mrJiCkM8VXkH4c_c8Bep3GJ7_ehaAPxXiFdG8Y2TKwtCoq5t7bkIqJqOVne5QiaLnCE7mO9v_Xs1-SUMGpXEJQtIqvDXinueUEdgEV0acujz6SZco3SIj38h90ltrcSxxrY8xcqhtTE4HgdaVEPHFUPSsp5FrfNJyjfyycdnwfMT0H1s9zcEGPPwHJNjt_A)](https://mermaid-js.github.io/mermaid-live-editor/edit/#pako:eNqVVEtv4jAQ_iuWz0W9c1stbbWHbhFw5DLEEzJax07HDqss4b_vOCQQXlLLBSX6XuP5nL3OvEE91cgzgi1DuXZKfh-8BUf_IJJ36tBOJn6vlsg7ynCq1roEB1sMa_0ltK-QIT6C-w7-FvMwgwgBY6Jk3oW6_BalYm_q7HuUemMpFEfOY9b4XaJRUBUwuqj8GO3zu9btQxEwJTkKEZnc9sta7a3W-_zjebGa_1C5ZxULVJIO0sN3RCRQolYWnEt5oI6FZ4rNQ9VHw7bqp69dbN7QS6OqounlCwTzWQPLwGgUuUHnCq3atgs4t5DhhYbBkDFtMKiso0ws7tCKkoQqjwFG8V4l77KR4y0HxeuRoaosiVr05wL0vQ3D8kc9Pu4dIoMLFAer3qx2Rk5tzilu2V2C9oKcC-DUzQUZ5AV-1sRYpiLdml1mS6QXS1uSwsbm5HLDsvLvgtCwA5Pt93czX3ck_Y3oX6WLkTQYc4tZlBVtmsF7dHGG2e4wKS2mrJiCkM8VXkH4c_c8Bep3GJ7_ehaAPxXiFdG8Y2TKwtCoq5t7bkIqJqOVne5QiaLnCE7mO9v_Xs1-SUMGpXEJQtIqvDXinueUEdgEV0acujz6SZco3SIj38h90ltrcSxxrY8xcqhtTE4HgdaVEPHFUPSsp5FrfNJyjfyycdnwfMT0H1s9zcEGPPwHJNjt_A) [editable source](https://mermaid-js.github.io/mermaid-live-editor/edit/#pako:eNqVVEtv4jAQ_iuWz0W9c1stbbWHbhFw5DLEEzJax07HDqss4b_vOCQQXlLLBSX6XuP5nL3OvEE91cgzgi1DuXZKfh-8BUf_IJJ36tBOJn6vlsg7ynCq1roEB1sMa_0ltK-QIT6C-w7-FvMwgwgBY6Jk3oW6_BalYm_q7HuUemMpFEfOY9b4XaJRUBUwuqj8GO3zu9btQxEwJTkKEZnc9sta7a3W-_zjebGa_1C5ZxULVJIO0sN3RCRQolYWnEt5oI6FZ4rNQ9VHw7bqp69dbN7QS6OqounlCwTzWQPLwGgUuUHnCq3atgs4t5DhhYbBkDFtMKiso0ws7tCKkoQqjwFG8V4l77KR4y0HxeuRoaosiVr05wL0vQ3D8kc9Pu4dIoMLFAer3qx2Rk5tzilu2V2C9oKcC-DUzQUZ5AV-1sRYpiLdml1mS6QXS1uSwsbm5HLDsvLvgtCwA5Pt93czX3ck_Y3oX6WLkTQYc4tZlBVtmsF7dHGG2e4wKS2mrJiCkM8VXkH4c_c8Bep3GJ7_ehaAPxXiFdG8Y2TKwtCoq5t7bkIqJqOVne5QiaLnCE7mO9v_Xs1-SUMGpXEJQtIqvDXinueUEdgEV0acujz6SZco3SIj38h90ltrcSxxrY8xcqhtTE4HgdaVEPHFUPSsp5FrfNJyjfyycdnwfMT0H1s9zcEGPPwHJNjt_A) +(transit-technology-stacks)= + ### Transit Stacks [![](https://mermaid.ink/img/pako:eNqdk7tuwzAMRX9F0JzH7jXp0ClF09ELITGyAFs0KClFG-ffS7_6SNu0iEbp3MtLSjppQxZ1oZG3HhxDUwYla8cOgn-F5ClEde6WSzqpPfLRGyxUqRsI4DCW-kecBnxDITGY1PP0HP4PV1Tb6_QDk80jHLGuB3jEp4wbaloKGJIoVqvuS3YfVY5oVSLV1hDWYy9rapEh4Vz3N6NPpcUoSlQF8bqoU-8bk0wa9cH9JbwYi-hapqO3ffaKKbvqo-9HrMcRVb79ZtZ1Q4rL_d50x975AEOcOJ4rMwNzulvNn4Adpht9pwlsIcHeVNhA73gfxSUENEmGkKOkLrVe6Aa5AW_lHZ9651InEchV9hKLB8j1UPMsaG6t3PKd9YlYFweoIy405ET7l2B0kTjjDE0_YqLOb7JEHuQ)](https://mermaid-js.github.io/mermaid-live-editor/edit/#pako:eNqdk7tuwzAMRX9F0JzH7jXp0ClF09ELITGyAFs0KClFG-ffS7_6SNu0iEbp3MtLSjppQxZ1oZG3HhxDUwYla8cOgn-F5ClEde6WSzqpPfLRGyxUqRsI4DCW-kecBnxDITGY1PP0HP4PV1Tb6_QDk80jHLGuB3jEp4wbaloKGJIoVqvuS3YfVY5oVSLV1hDWYy9rapEh4Vz3N6NPpcUoSlQF8bqoU-8bk0wa9cH9JbwYi-hapqO3ffaKKbvqo-9HrMcRVb79ZtZ1Q4rL_d50x975AEOcOJ4rMwNzulvNn4Adpht9pwlsIcHeVNhA73gfxSUENEmGkKOkLrVe6Aa5AW_lHZ9651InEchV9hKLB8j1UPMsaG6t3PKd9YlYFweoIy405ET7l2B0kTjjDE0_YqLOb7JEHuQ) diff --git a/docs/warehouse/developing_dbt_models.md b/docs/warehouse/developing_dbt_models.md index c39f82a807..a9dd484d5e 100644 --- a/docs/warehouse/developing_dbt_models.md +++ b/docs/warehouse/developing_dbt_models.md @@ -6,15 +6,16 @@ Information related to contributing to the [Cal-ITP dbt project](https://github. ## What is dbt? -[dbt](https://docs.getdbt.com/docs/introduction#the-power-of-dbt) is the tool we use to manage the data models (tables and views) in our BigQuery data warehouse. We use dbt to define the SQL code that creates our data models, to manage dependencies between models, to document models, and to test models. +[dbt](https://docs.getdbt.com/docs/introduction#the-power-of-dbt) is the tool we use to manage the data models (tables and views) in our BigQuery data warehouse. We use dbt to define the SQL code that creates our data models, to manage dependencies between models, to document models, and to test models. -The [Cal-ITP dbt project](https://github.com/cal-itp/data-infra/tree/main/warehouse) runs every day, [orchestrated by Airflow](https://github.com/cal-itp/data-infra/tree/main/airflow/dags/transform_warehouse). When the dbt project runs, it refreshes all the data in the warehouse by running all the queries within the project in order based on the dependencies defined between models. For example, if model B depends on model A, the project will execute model A before model B. +The [Cal-ITP dbt project](https://github.com/cal-itp/data-infra/tree/main/warehouse) runs every day, [orchestrated by Airflow](https://github.com/cal-itp/data-infra/tree/main/airflow/dags/transform_warehouse). When the dbt project runs, it refreshes all the data in the warehouse by running all the queries within the project in order based on the dependencies defined between models. For example, if model B depends on model A, the project will execute model A before model B. ### dbt project structure -The dbt project (specifically [the `models/` directory](https://github.com/cal-itp/data-infra/tree/main/warehouse/models)) is broken out into data processing stages, broadly according to the [standard outlined by dbt](https://docs.getdbt.com/best-practices/how-we-structure/1-guide-overview#guide-structure-overview). You can read dbt documentation on the purpose of [staging](https://docs.getdbt.com/best-practices/how-we-structure/2-staging#staging-models), [intermediate](https://docs.getdbt.com/best-practices/how-we-structure/3-intermediate#intermediate-models), and [mart](https://docs.getdbt.com/best-practices/how-we-structure/4-marts#marts-models) models. +The dbt project (specifically [the `models/` directory](https://github.com/cal-itp/data-infra/tree/main/warehouse/models)) is broken out into data processing stages, broadly according to the [standard outlined by dbt](https://docs.getdbt.com/best-practices/how-we-structure/1-guide-overview#guide-structure-overview). You can read dbt documentation on the purpose of [staging](https://docs.getdbt.com/best-practices/how-we-structure/2-staging#staging-models), [intermediate](https://docs.getdbt.com/best-practices/how-we-structure/3-intermediate#intermediate-models), and [mart](https://docs.getdbt.com/best-practices/how-we-structure/4-marts#marts-models) models. Project level configuration lives in two separate places: + * `dbt_project.yml` ([dbt documentation](https://docs.getdbt.com/reference/dbt_project.yml), [our file](https://github.com/cal-itp/data-infra/blob/main/warehouse/dbt_project.yml)): This contains information about the dbt project structure, for example configuring how the folder structure should be interpreted. * `profiles.yml` ([dbt documentation](https://docs.getdbt.com/docs/core/connect-data-platform/profiles.yml), [production file (should be used for prod runs only)](https://github.com/cal-itp/data-infra/blob/main/warehouse/profiles.yml), [template for local/testing use](https://github.com/cal-itp/data-infra/tree/main/warehouse#clone-and-install-the-warehouse-project)): This contains information about how the dbt project should connect to our cloud warehouse (BigQuery) and configures settings associated with that database connection, for example, what the query timeout should be. @@ -43,7 +44,7 @@ We recommend that everyone who does dbt development joins the [`#data-warehouse ```{admonition} See next section for modeling considerations This section describes the high-level mechanics/process of the developer workflow to edit the dbt project. -**Please read the [next section](developing_dbt_models#modeling-considerations) for things you should consider from the data modeling perspective.** +**Please read the [next section](#modeling-considerations) for things you should consider from the data modeling perspective.** ``` To develop dbt models, you can edit the `.sql` files for your models, save your changes, and then [run the model from the command line](https://github.com/cal-itp/data-infra/tree/main/warehouse#dbt-commands) to execute the SQL you updated. @@ -52,7 +53,7 @@ To inspect tables as you are working, the fastest method is usually to run some When you run dbt commands locally or on JupyterHub, your models will be created in the `cal-itp-data-infra-staging._` BigQuery dataset. Note that this is in the `cal-itp-data-infra-staging` Google Cloud Platform project, *not* the production `cal-itp-data-infra` project. -Once your models are working the way you want and you have added all necessary documentation and tests in YAML files ([see below](developing_dbt_models#modeling-considerations) for more on modeling, documentation, and testing considerations), you are ready to merge. +Once your models are working the way you want and you have added all necessary documentation and tests in YAML files ([see below](#modeling-considerations) for more on modeling, documentation, and testing considerations), you are ready to merge. Because the warehouse is collectively maintained and changes can affect a variety of users, please open PRs against `main` when work is ready to merge and keep an eye out for comments and questions from reviewers, who might require tweaks before merging. @@ -292,7 +293,7 @@ To confirm that the grain is what you expect, you should check whether an antici , COUNT(*) AS ct FROM tbl - -- adjust this based on the number of columns that make the composite unique key + -- adjust this based on the number of columns that make the composite unique key GROUP BY 1, 2, 3 HAVING ct > 1 ) diff --git a/docs/warehouse/warehouse_starter_kit.md b/docs/warehouse/warehouse_starter_kit.md index 42c16000f1..893b089c77 100644 --- a/docs/warehouse/warehouse_starter_kit.md +++ b/docs/warehouse/warehouse_starter_kit.md @@ -10,12 +10,16 @@ - [Daily](#daily) - [Other](#other) +(links)= + ## Important Links - [DBT Docs Cal-ITP](https://dbt-docs.calitp.org/#!/overview) contains information on all the tables in the warehouse. - [Example notebook](https://github.com/cal-itp/data-analyses/blob/main/starter_kit/gtfs_utils_v2_examples.ipynb) uses functions in `shared_utils.gtfs_utils_v2` that query some of the tables below. +(trips)= + ## Trips On a given day: @@ -27,6 +31,8 @@ On a given day: - Realtime observations of trips to get a full picture of what occurred. - Find a trip's start time, where it went, and which route it is associated with. +(shapes)= + ## Shapes - [fct_daily_scheduled_shapes](https://dbt-docs.calitp.org/#!/model/model.calitp_warehouse.fct_daily_scheduled_shapes) @@ -35,6 +41,8 @@ On a given day: - Each shape has its own `shape_id` and `shape_array_key`. - An express version and the regular version of a route are considered two different shapes. +(daily)= + ## Daily For a given day: @@ -53,6 +61,8 @@ For a given day: - Please note,the `name` column returned from the function above refers to a name of the feed, not to a provider. - Use `gtfs_utils_v2.schedule_daily_feed_to_organization()` to find regional feed type, gtfs dataset key, and feed type for an organization. +(other)= + ### Other - [dim_annual_ntd_agency_information](https://dbt-docs.calitp.org/#!/model/model.calitp_warehouse.dim_annual_database_agency_information) diff --git a/images/jupyter-singleuser/poetry.lock b/images/jupyter-singleuser/poetry.lock index 5693517597..8555774445 100644 --- a/images/jupyter-singleuser/poetry.lock +++ b/images/jupyter-singleuser/poetry.lock @@ -1,9 +1,25 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. + +[[package]] +name = "accessible-pygments" +version = "0.0.4" +description = "A collection of accessible pygments styles" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "accessible-pygments-0.0.4.tar.gz", hash = "sha256:e7b57a9b15958e9601c7e9eb07a440c813283545a20973f2574a5f453d0e953e"}, + {file = "accessible_pygments-0.0.4-py2.py3-none-any.whl", hash = "sha256:416c6d8c1ea1c5ad8701903a20fcedf953c6e720d64f33dc47bfb2d3f2fa4e8d"}, +] + +[package.dependencies] +pygments = ">=1.5" [[package]] name = "agate" version = "1.7.1" description = "A data analysis library that is optimized for humans instead of machines." +category = "main" optional = false python-versions = "*" files = [ @@ -27,6 +43,7 @@ test = ["PyICU (>=2.4.2)", "coverage (>=3.7.1)", "cssselect (>=0.9.1)", "lxml (> name = "agate-dbf" version = "0.2.2" description = "agate-dbf adds read support for dbf files to agate." +category = "main" optional = false python-versions = "*" files = [ @@ -42,6 +59,7 @@ dbfread = ">=2.0.5" name = "agate-excel" version = "0.2.5" description = "agate-excel adds read support for Excel files (xls and xlsx) to agate." +category = "main" optional = false python-versions = "*" files = [ @@ -64,6 +82,7 @@ test = ["nose (>=1.1.2)"] name = "agate-sql" version = "0.5.9" description = "agate-sql adds SQL read/write support to agate." +category = "main" optional = false python-versions = "*" files = [ @@ -83,6 +102,7 @@ test = ["crate", "geojson", "pytest", "pytest-cov"] name = "aiobotocore" version = "2.5.2" description = "Async client for aws services using botocore and aiohttp" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -104,6 +124,7 @@ boto3 = ["boto3 (>=1.26.161,<1.26.162)"] name = "aiohttp" version = "3.9.0" description = "Async http client/server framework (asyncio)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -200,6 +221,7 @@ speedups = ["Brotli", "aiodns", "brotlicffi"] name = "aioitertools" version = "0.11.0" description = "itertools and builtins for AsyncIO and mixed iterables" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -214,6 +236,7 @@ typing_extensions = {version = ">=4.0", markers = "python_version < \"3.10\""} name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -228,6 +251,7 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -239,6 +263,7 @@ files = [ name = "altair" version = "5.1.1" description = "Vega-Altair: A declarative statistical visualization library for Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -263,6 +288,7 @@ doc = ["docutils", "geopandas", "jinja2", "myst-parser", "numpydoc", "pillow (>= name = "altair-data-server" version = "0.4.1" description = "A background data server for Altair charts." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -279,6 +305,7 @@ tornado = "*" name = "altair-saver" version = "0.5.0" description = "Altair extension for saving charts to various formats." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -296,6 +323,7 @@ selenium = "*" name = "altair-viewer" version = "0.4.0" description = "Viewer for Altair and Vega-Lite visualizations." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -311,6 +339,7 @@ altair-data-server = ">=0.4.0" name = "ansiwrap" version = "0.8.4" description = "textwrap, but savvy to ANSI colors and styles" +category = "dev" optional = false python-versions = "*" files = [ @@ -325,6 +354,7 @@ textwrap3 = ">=0.9.2" name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -346,6 +376,7 @@ trio = ["trio (<0.22)"] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" optional = false python-versions = "*" files = [ @@ -357,6 +388,7 @@ files = [ name = "appnope" version = "0.1.3" description = "Disable App Nap on macOS >= 10.9" +category = "main" optional = false python-versions = "*" files = [ @@ -368,6 +400,7 @@ files = [ name = "argon2-cffi" version = "21.3.0" description = "The secure Argon2 password hashing algorithm." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -387,6 +420,7 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -424,6 +458,7 @@ tests = ["pytest"] name = "asttokens" version = "2.2.1" description = "Annotate AST trees with source code positions" +category = "main" optional = false python-versions = "*" files = [ @@ -441,6 +476,7 @@ test = ["astroid", "pytest"] name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -452,6 +488,7 @@ files = [ name = "attrs" version = "21.4.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -469,6 +506,7 @@ tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy" name = "babel" version = "2.12.1" description = "Internationalization utilities" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -480,6 +518,7 @@ files = [ name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" +category = "main" optional = false python-versions = "*" files = [ @@ -491,6 +530,7 @@ files = [ name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" +category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -509,6 +549,7 @@ lxml = ["lxml"] name = "black" version = "22.3.0" description = "The uncompromising code formatter." +category = "main" optional = false python-versions = ">=3.6.2" files = [ @@ -555,6 +596,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -573,6 +615,7 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "bokeh" version = "3.2.1" description = "Interactive plots and applications in the browser from Python" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -595,6 +638,7 @@ xyzservices = ">=2021.09.1" name = "botocore" version = "1.29.161" description = "Low-level, data-driven core of boto 3." +category = "main" optional = false python-versions = ">= 3.7" files = [ @@ -614,6 +658,7 @@ crt = ["awscrt (==0.16.9)"] name = "branca" version = "0.4.2" description = "Generate complex HTML+JS pages with Python" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -628,6 +673,7 @@ jinja2 = "*" name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -639,6 +685,7 @@ files = [ name = "calitp-data-analysis" version = "2023.9.18" description = "Shared code for querying Cal-ITP data in notebooks, primarily." +category = "main" optional = false python-versions = ">=3.9,<3.10" files = [ @@ -665,6 +712,7 @@ sqlalchemy-bigquery = ">=1.6.1,<2.0.0" name = "calitp-map-utils" version = "2023.8.1" description = "" +category = "main" optional = false python-versions = ">=3.9,<3.10" files = [ @@ -686,6 +734,7 @@ typer = ">=0.9.0,<0.10.0" name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -697,6 +746,7 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = "*" files = [ @@ -773,6 +823,7 @@ pycparser = "*" name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." +category = "main" optional = false python-versions = ">=3.6.1" files = [ @@ -784,6 +835,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -868,6 +920,7 @@ files = [ name = "click" version = "8.1.6" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -882,6 +935,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +category = "main" optional = false python-versions = "*" files = [ @@ -899,6 +953,7 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "cligj" version = "0.7.2" description = "Click params for commmand line interfaces to GeoJSON" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" files = [ @@ -916,6 +971,7 @@ test = ["pytest-cov"] name = "cloudpickle" version = "2.2.1" description = "Extended pickling support for Python objects" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -927,6 +983,7 @@ files = [ name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -938,6 +995,7 @@ files = [ name = "comm" version = "0.1.3" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -957,6 +1015,7 @@ typing = ["mypy (>=0.990)"] name = "contourpy" version = "1.1.0" description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1019,6 +1078,7 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "cpi" version = "1.0.19" description = "Quickly adjust U.S. dollars for inflation using the Consumer Price Index (CPI)" +category = "dev" optional = false python-versions = "*" files = [ @@ -1036,6 +1096,7 @@ requests = "*" name = "cramjam" version = "2.7.0" description = "Thin Python bindings to de/compression algorithms in Rust" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1117,6 +1178,7 @@ dev = ["black (==22.3.0)", "hypothesis", "numpy", "pytest (>=5.30)", "pytest-xdi name = "csvkit" version = "1.0.7" description = "A suite of command-line tools for working with CSV, the king of tabular file formats." +category = "main" optional = false python-versions = "*" files = [ @@ -1139,6 +1201,7 @@ test = ["coverage (>=4.4.2)", "mock (>=1.3.0)", "pytest", "pytest-cov"] name = "cycler" version = "0.11.0" description = "Composable style cycles" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1150,6 +1213,7 @@ files = [ name = "dacite" version = "1.8.1" description = "Simple creation of data classes from dictionaries." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1163,6 +1227,7 @@ dev = ["black", "coveralls", "mypy", "pre-commit", "pylint", "pytest (>=5)", "py name = "dask" version = "2022.8.1" description = "Parallel PyData with Task Scheduling" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1190,6 +1255,7 @@ test = ["pandas[test]", "pre-commit", "pytest", "pytest-rerunfailures", "pytest- name = "dask-bigquery" version = "2022.5.0" description = "Dask + BigQuery intergration" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1211,6 +1277,7 @@ test = ["distributed", "google-auth (>=1.30.0)", "pandas-gbq (<=0.15)", "pytest" name = "dask-geopandas" version = "0.2.0" description = "Parallel GeoPandas with Dask" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1229,6 +1296,7 @@ pygeos = "*" name = "dask-labextension" version = "5.3.0" description = "A JupyterLab extension for Dask." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1246,6 +1314,7 @@ jupyterlab = ">=3.0.0" name = "db-dtypes" version = "1.1.1" description = "Pandas Data Types for SQL systems (BigQuery, Spanner)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1263,6 +1332,7 @@ pyarrow = ">=3.0.0" name = "dbfread" version = "2.0.7" description = "Read DBF Files with Python" +category = "main" optional = false python-versions = "*" files = [ @@ -1274,6 +1344,7 @@ files = [ name = "debugpy" version = "1.6.7" description = "An implementation of the Debug Adapter Protocol for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1301,6 +1372,7 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1312,6 +1384,7 @@ files = [ name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1323,6 +1396,7 @@ files = [ name = "descartes" version = "1.1.0" description = "Use geometric objects as matplotlib paths and patches" +category = "main" optional = false python-versions = "*" files = [ @@ -1338,6 +1412,7 @@ matplotlib = "*" name = "distlib" version = "0.3.7" description = "Distribution utilities" +category = "main" optional = false python-versions = "*" files = [ @@ -1349,6 +1424,7 @@ files = [ name = "distributed" version = "2022.8.1" description = "Distributed scheduler for Dask" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1377,6 +1453,7 @@ zict = ">=0.1.3" name = "docutils" version = "0.16" description = "Docutils -- Python Documentation Utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1388,6 +1465,7 @@ files = [ name = "entrypoints" version = "0.4" description = "Discover and load entry points from installed packages." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1399,6 +1477,7 @@ files = [ name = "et-xmlfile" version = "1.1.0" description = "An implementation of lxml.xmlfile for the standard library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1410,6 +1489,7 @@ files = [ name = "exceptiongroup" version = "1.1.2" description = "Backport of PEP 654 (exception groups)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1424,6 +1504,7 @@ test = ["pytest (>=6)"] name = "executing" version = "1.2.0" description = "Get the currently executing AST node of a frame, and other information" +category = "main" optional = false python-versions = "*" files = [ @@ -1438,6 +1519,7 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] name = "fastjsonschema" version = "2.18.0" description = "Fastest Python implementation of JSON schema" +category = "main" optional = false python-versions = "*" files = [ @@ -1452,6 +1534,7 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "fastparquet" version = "2023.7.0" description = "Python support for Parquet file format" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1504,6 +1587,7 @@ lzo = ["python-lzo"] name = "filelock" version = "3.12.2" description = "A platform independent file lock." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1519,6 +1603,7 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "fiona" version = "1.9.4.post1" description = "Fiona reads and writes spatial data files" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1563,6 +1648,7 @@ test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] name = "folium" version = "0.12.1.post1" description = "Make beautiful maps with Leaflet.js & Python" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1583,6 +1669,7 @@ testing = ["pytest"] name = "fonttools" version = "4.41.1" description = "Tools to manipulate font files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1640,6 +1727,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1710,6 +1798,7 @@ files = [ name = "fsspec" version = "2023.6.0" description = "File-system specification" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1745,6 +1834,7 @@ tqdm = ["tqdm"] name = "furl" version = "2.1.3" description = "URL manipulation made simple." +category = "main" optional = false python-versions = "*" files = [ @@ -1760,6 +1850,7 @@ six = ">=1.8.0" name = "gcsfs" version = "2023.6.0" description = "Convenient Filesystem interface over GCS" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1784,6 +1875,7 @@ gcsfuse = ["fusepy"] name = "geojson-pydantic" version = "0.6.3" description = "Pydantic data models for the GeoJSON spec." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1802,6 +1894,7 @@ test = ["pytest", "pytest-cov", "shapely"] name = "geopandas" version = "0.14.0" description = "Geographic pandas extensions" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -1816,41 +1909,11 @@ pandas = ">=1.4.0" pyproj = ">=3.3.0" shapely = ">=1.8.0" -[[package]] -name = "gitdb" -version = "4.0.10" -description = "Git Object Database" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, - {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, -] - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.37" -description = "GitPython is a Python library used to interact with Git repositories" -optional = false -python-versions = ">=3.7" -files = [ - {file = "GitPython-3.1.37-py3-none-any.whl", hash = "sha256:5f4c4187de49616d710a77e98ddf17b4782060a1788df441846bddefbb89ab33"}, - {file = "GitPython-3.1.37.tar.gz", hash = "sha256:f9b9ddc0761c125d5780eab2d64be4873fc6817c2899cbcb34b02344bdc7bc54"}, -] - -[package.dependencies] -gitdb = ">=4.0.1,<5" - -[package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-sugar"] - [[package]] name = "google-api-core" version = "2.11.1" description = "Google API client core library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1875,6 +1938,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] name = "google-auth" version = "2.22.0" description = "Google Authentication Library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1900,6 +1964,7 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"] name = "google-auth-oauthlib" version = "1.0.0" description = "Google Authentication Library" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1918,6 +1983,7 @@ tool = ["click (>=6.0.0)"] name = "google-cloud-bigquery" version = "3.11.4" description = "Google BigQuery API client library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1926,7 +1992,7 @@ files = [ ] [package.dependencies] -google-api-core = {version = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev", extras = ["grpc"]} +google-api-core = {version = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev", extras = ["grpc"]} google-cloud-core = ">=1.6.0,<3.0.0dev" google-resumable-media = ">=0.6.0,<3.0dev" grpcio = ">=1.47.0,<2.0dev" @@ -1950,6 +2016,7 @@ tqdm = ["tqdm (>=4.7.4,<5.0.0dev)"] name = "google-cloud-bigquery-storage" version = "2.22.0" description = "Google Cloud Bigquery Storage API client library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1958,7 +2025,7 @@ files = [ ] [package.dependencies] -google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +google-api-core = {version = ">=1.34.0,<2.0.0 || >=2.11.0,<3.0.0dev", extras = ["grpc"]} proto-plus = ">=1.22.0,<2.0.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" @@ -1971,6 +2038,7 @@ pyarrow = ["pyarrow (>=0.15.0)"] name = "google-cloud-core" version = "2.3.3" description = "Google Cloud API client core library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1979,7 +2047,7 @@ files = [ ] [package.dependencies] -google-api-core = ">=1.31.6,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-api-core = ">=1.31.6,<2.0.0 || >2.3.0,<3.0.0dev" google-auth = ">=1.25.0,<3.0dev" [package.extras] @@ -1989,6 +2057,7 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)"] name = "google-cloud-storage" version = "2.10.0" description = "Google Cloud Storage API client library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1997,7 +2066,7 @@ files = [ ] [package.dependencies] -google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-api-core = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev" google-auth = ">=1.25.0,<3.0dev" google-cloud-core = ">=2.3.0,<3.0dev" google-resumable-media = ">=2.3.2" @@ -2010,6 +2079,7 @@ protobuf = ["protobuf (<5.0.0dev)"] name = "google-crc32c" version = "1.5.0" description = "A python wrapper of the C library 'Google CRC32C'" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2090,6 +2160,7 @@ testing = ["pytest"] name = "google-resumable-media" version = "2.5.0" description = "Utilities for Google Media Downloads and Resumable Uploads" +category = "main" optional = false python-versions = ">= 3.7" files = [ @@ -2108,6 +2179,7 @@ requests = ["requests (>=2.18.0,<3.0.0dev)"] name = "googleapis-common-protos" version = "1.60.0" description = "Common protobufs used in Google APIs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2125,6 +2197,7 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] name = "graphviz" version = "0.20.1" description = "Simple Python interface for Graphviz" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2141,6 +2214,7 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -2218,6 +2292,7 @@ test = ["objgraph", "psutil"] name = "grpcio" version = "1.56.2" description = "HTTP/2-based RPC framework" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2275,6 +2350,7 @@ protobuf = ["grpcio-tools (>=1.56.2)"] name = "grpcio-status" version = "1.56.2" description = "Status proto mapping for gRPC" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2291,6 +2367,7 @@ protobuf = ">=4.21.6" name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2302,6 +2379,7 @@ files = [ name = "htmlmin" version = "0.1.12" description = "An HTML Minifier" +category = "main" optional = false python-versions = "*" files = [ @@ -2312,6 +2390,7 @@ files = [ name = "humanize" version = "4.7.0" description = "Python humanize utilities" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2326,6 +2405,7 @@ tests = ["freezegun", "pytest", "pytest-cov"] name = "identify" version = "2.5.26" description = "File identification library for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2340,6 +2420,7 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2351,6 +2432,7 @@ files = [ name = "imagehash" version = "4.3.1" description = "Image Hashing library" +category = "main" optional = false python-versions = "*" files = [ @@ -2368,6 +2450,7 @@ scipy = "*" name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2379,6 +2462,7 @@ files = [ name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2398,6 +2482,7 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2409,6 +2494,7 @@ files = [ name = "intake" version = "0.6.4" description = "Data load and catalog system" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2435,6 +2521,7 @@ server = ["msgpack-python", "python-snappy", "tornado"] name = "intake-dcat" version = "0.4.0" description = "DCAT to Intake Catalog translation layer" +category = "main" optional = false python-versions = "*" files = [ @@ -2454,6 +2541,7 @@ s3fs = "*" name = "intake-geopandas" version = "0.3.0" description = "Geopandas plugin for Intake" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2473,6 +2561,7 @@ regionmask = ["regionmask"] name = "intake-parquet" version = "0.2.3" description = "Intake parquet plugin" +category = "main" optional = false python-versions = "*" files = [ @@ -2490,6 +2579,7 @@ pyarrow = "*" name = "ipykernel" version = "6.25.0" description = "IPython Kernel for Jupyter" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2503,7 +2593,7 @@ comm = ">=0.1.1" debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -2523,6 +2613,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" name = "ipyleaflet" version = "0.15.0" description = "A Jupyter widget for dynamic Leaflet maps" +category = "main" optional = false python-versions = "*" files = [ @@ -2539,6 +2630,7 @@ xyzservices = ">=2021.8.1" name = "ipython" version = "8.14.0" description = "IPython: Productive Interactive Computing" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2578,6 +2670,7 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pa name = "ipython-genutils" version = "0.2.0" description = "Vestigial utilities from IPython" +category = "main" optional = false python-versions = "*" files = [ @@ -2589,6 +2682,7 @@ files = [ name = "ipywidgets" version = "7.8.0" description = "IPython HTML widgets for Jupyter" +category = "main" optional = false python-versions = "*" files = [ @@ -2611,6 +2705,7 @@ test = ["ipykernel", "mock", "pytest (>=3.6.0)", "pytest-cov"] name = "isodate" version = "0.6.1" description = "An ISO 8601 date/time/duration parser and formatter" +category = "main" optional = false python-versions = "*" files = [ @@ -2625,6 +2720,7 @@ six = "*" name = "isort" version = "5.10.1" description = "A Python utility / library to sort Python imports." +category = "main" optional = false python-versions = ">=3.6.1,<4.0" files = [ @@ -2642,6 +2738,7 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "jedi" version = "0.19.0" description = "An autocompletion tool for Python that can be used for text editors." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2661,6 +2758,7 @@ testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.0.3" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2678,6 +2776,7 @@ i18n = ["Babel (>=2.7)"] name = "jmespath" version = "1.0.1" description = "JSON Matching Expressions" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2689,6 +2788,7 @@ files = [ name = "joblib" version = "1.3.1" description = "Lightweight pipelining with Python functions" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2700,6 +2800,7 @@ files = [ name = "json5" version = "0.9.14" description = "A Python implementation of the JSON5 data format." +category = "main" optional = false python-versions = "*" files = [ @@ -2714,6 +2815,7 @@ dev = ["hypothesis"] name = "jsonschema" version = "3.2.0" description = "An implementation of JSON Schema validation for Python" +category = "main" optional = false python-versions = "*" files = [ @@ -2735,6 +2837,7 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va name = "jupyter" version = "1.0.0" description = "Jupyter metapackage. Install all the Jupyter components in one go." +category = "main" optional = false python-versions = "*" files = [ @@ -2753,69 +2856,75 @@ qtconsole = "*" [[package]] name = "jupyter-book" -version = "0.12.3" +version = "1.0.0" description = "Build a book with Jupyter Notebooks and Sphinx." +category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "jupyter-book-0.12.3.tar.gz", hash = "sha256:ed695f29b1d1a0816e1fc0c409755ccb2a15fda36e507b19da69e3bdc4f5c7a8"}, - {file = "jupyter_book-0.12.3-py3-none-any.whl", hash = "sha256:063ab998ae7dae00ae2992ab986f83253c71385af99faa36c643e6e9f491b27d"}, + {file = "jupyter_book-1.0.0-py3-none-any.whl", hash = "sha256:18238f1e7e1d425731e60ab509a7da878dd6db88b7d77bcfab4690361b72e1be"}, + {file = "jupyter_book-1.0.0.tar.gz", hash = "sha256:539c5d0493546200d9de27bd4b5f77eaea03115f8937f825d4ff82b3801a987e"}, ] [package.dependencies] click = ">=7.1,<9" -docutils = ">=0.15,<0.18" -Jinja2 = "<3.1" -jsonschema = "<4" -linkify-it-py = ">=1.0.1,<1.1.0" -myst-nb = ">=0.13.1,<0.14.0" +Jinja2 = "*" +jsonschema = "<5" +linkify-it-py = ">=2,<3" +myst-nb = ">=1,<3" +myst-parser = ">=1,<3" pyyaml = "*" -sphinx = ">=3,<5" -sphinx_book_theme = ">=0.1.4,<0.2.0" +sphinx = ">=5,<8" +sphinx-book-theme = ">=1.1.0,<2" sphinx-comments = "*" sphinx-copybutton = "*" -sphinx-external-toc = ">=0.2.3,<0.3.0" -sphinx-jupyterbook-latex = ">=0.4.6,<0.5.0" -sphinx-multitoc-numbering = ">=0.1.3,<0.2.0" -sphinx-panels = ">=0.6.0,<0.7.0" -sphinx-thebe = ">=0.1.1,<0.2.0" +sphinx-design = ">=0.5,<1" +sphinx-external-toc = ">=1.0.1,<2" +sphinx-jupyterbook-latex = ">=1,<2" +sphinx-multitoc-numbering = ">=0.1.3,<1" +sphinx-thebe = ">=0.3,<1" sphinx_togglebutton = "*" -sphinxcontrib-bibtex = ">=2.2.0,<=2.5.0" +sphinxcontrib-bibtex = ">=2.5.0,<3" [package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] +code-style = ["pre-commit (>=3.1,<4.0)"] pdfhtml = ["pyppeteer"] -sphinx = ["altair", "bokeh", "folium", "ipywidgets", "jupytext", "matplotlib", "nbclient", "numpy", "pandas", "plotly", "sphinx-click", "sphinx-proof", "sphinx_inline_tabs", "sphinxext-rediraffe (>=0.2.3,<0.3.0)", "sympy"] -testing = ["altair", "beautifulsoup4", "beautifulsoup4", "cookiecutter", "coverage", "jupytext", "matplotlib", "pyppeteer", "pytest (>=6.2.4)", "pytest-cov", "pytest-regressions", "pytest-timeout", "pytest-xdist", "sphinx_click", "sphinx_tabs", "texsoup"] +sphinx = ["altair", "bokeh", "folium", "ipywidgets", "jupytext", "matplotlib", "nbclient", "numpy", "pandas", "plotly", "sphinx-click", "sphinx-examples", "sphinx-proof", "sphinx_inline_tabs", "sphinxext-rediraffe (>=0.2.3,<0.3.0)", "sympy"] +testing = ["altair", "beautifulsoup4", "beautifulsoup4", "cookiecutter", "coverage", "jupytext", "matplotlib", "pyppeteer", "pytest (>=6.2.4)", "pytest-cov", "pytest-regressions", "pytest-timeout", "pytest-xdist", "sphinx_click", "sphinx_inline_tabs", "texsoup"] [[package]] name = "jupyter-cache" -version = "0.4.3" +version = "1.0.0" description = "A defined interface for working with a cache of jupyter notebooks." +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "jupyter-cache-0.4.3.tar.gz", hash = "sha256:4c9b5431b1d320bc68440c21fa0a155bbeb29c5b979bef72222e244a7bcd54fc"}, - {file = "jupyter_cache-0.4.3-py3-none-any.whl", hash = "sha256:6d5d662d81f565d18009e8dcfd3a56fb876af47eafead2a19ef0045aba8ffe3b"}, + {file = "jupyter_cache-1.0.0-py3-none-any.whl", hash = "sha256:594b1c4e29b488b36547e12477645f489dbdc62cc939b2408df5679f79245078"}, + {file = "jupyter_cache-1.0.0.tar.gz", hash = "sha256:d0fa7d7533cd5798198d8889318269a8c1382ed3b22f622c09a9356521f48687"}, ] [package.dependencies] attrs = "*" -nbclient = ">=0.2,<0.6" -nbdime = "*" +click = "*" +importlib-metadata = "*" +nbclient = ">=0.2" nbformat = "*" -sqlalchemy = ">=1.3.12,<1.5" +pyyaml = "*" +sqlalchemy = ">=1.3.12,<3" +tabulate = "*" [package.extras] -cli = ["click", "click-completion", "click-log", "pyyaml", "tabulate"] -code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] -rtd = ["myst-nb (>=0.7,<1.0)", "pydata-sphinx-theme", "sphinx-copybutton"] -testing = ["coverage", "ipykernel", "matplotlib", "nbformat (>=5.1)", "numpy", "pandas", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions", "sympy"] +cli = ["click-log"] +code-style = ["pre-commit (>=2.12)"] +rtd = ["ipykernel", "jupytext", "myst-nb", "nbdime", "sphinx-book-theme", "sphinx-copybutton"] +testing = ["coverage", "ipykernel", "jupytext", "matplotlib", "nbdime", "nbformat (>=5.1)", "numpy", "pandas", "pytest (>=6,<8)", "pytest-cov", "pytest-regressions", "sympy"] [[package]] name = "jupyter-client" version = "7.3.4" description = "Jupyter protocol implementation and client libraries" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2840,6 +2949,7 @@ test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-comm name = "jupyter-console" version = "6.6.3" description = "Jupyter terminal console" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2851,7 +2961,7 @@ files = [ ipykernel = ">=6.14" ipython = "*" jupyter-client = ">=7.0.0" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" prompt-toolkit = ">=3.0.30" pygments = "*" pyzmq = ">=17" @@ -2864,6 +2974,7 @@ test = ["flaky", "pexpect", "pytest"] name = "jupyter-core" version = "5.3.1" description = "Jupyter core package. A base package on which Jupyter projects rely." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2884,6 +2995,7 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyter-resource-usage" version = "0.6.1" description = "Jupyter Extension to show resource usage" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2903,6 +3015,7 @@ dev = ["autopep8", "black", "flake8", "mock", "pytest", "pytest-cov (>=2.6.1)"] name = "jupyter-server" version = "1.24.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2915,7 +3028,7 @@ anyio = ">=3.1.0,<4" argon2-cffi = "*" jinja2 = "*" jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" nbconvert = ">=6.4.4" nbformat = ">=5.2.0" packaging = "*" @@ -2931,27 +3044,11 @@ websocket-client = "*" [package.extras] test = ["coverage", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-mock", "pytest-timeout", "pytest-tornasync", "requests"] -[[package]] -name = "jupyter-server-mathjax" -version = "0.2.6" -description = "MathJax resources as a Jupyter Server Extension." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyter_server_mathjax-0.2.6-py3-none-any.whl", hash = "sha256:416389dde2010df46d5fbbb7adb087a5607111070af65a1445391040f2babb5e"}, - {file = "jupyter_server_mathjax-0.2.6.tar.gz", hash = "sha256:bb1e6b6dc0686c1fe386a22b5886163db548893a99c2810c36399e9c4ca23943"}, -] - -[package.dependencies] -jupyter-server = ">=1.1" - -[package.extras] -test = ["jupyter-server[test]", "pytest"] - [[package]] name = "jupyter-server-proxy" version = "4.0.0" description = "A JupyterLab extension accompanying the PyPI package jupyter-server-proxy adding launcher items for configured server processes." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2969,28 +3066,11 @@ simpervisor = ">=0.4" acceptance = ["jupyter-server-proxy[test]", "notebook (<7)", "robotframework-jupyterlibrary (>=0.4.2)"] test = ["pytest", "pytest-cov", "pytest-html"] -[[package]] -name = "jupyter-sphinx" -version = "0.3.2" -description = "Jupyter Sphinx Extensions" -optional = false -python-versions = ">= 3.6" -files = [ - {file = "jupyter_sphinx-0.3.2-py3-none-any.whl", hash = "sha256:301e36d0fb3007bb5802f6b65b60c24990eb99c983332a2ab6eecff385207dc9"}, - {file = "jupyter_sphinx-0.3.2.tar.gz", hash = "sha256:37fc9408385c45326ac79ca0452fbd7ae2bf0e97842d626d2844d4830e30aaf2"}, -] - -[package.dependencies] -IPython = "*" -ipywidgets = ">=7.0.0" -nbconvert = ">=5.5" -nbformat = "*" -Sphinx = ">=2" - [[package]] name = "jupyterlab" version = "3.5.3" description = "JupyterLab computational environment" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3017,6 +3097,7 @@ test = ["check-manifest", "coverage", "jupyterlab-server[test]", "pre-commit", " name = "jupyterlab-code-formatter" version = "1.4.10" description = "Code formatter for JupyterLab" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3031,6 +3112,7 @@ jupyterlab = ">=3.0,<4.0" name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3042,6 +3124,7 @@ files = [ name = "jupyterlab-server" version = "2.16.6" description = "A set of server components for JupyterLab and JupyterLab like applications." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3070,6 +3153,7 @@ typing = ["mypy (>=0.990)"] name = "jupyterlab-widgets" version = "1.1.5" description = "A JupyterLab extension." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3081,6 +3165,7 @@ files = [ name = "jupytext" version = "1.13.5" description = "Jupyter notebooks as Markdown documents, Julia, Python or R scripts" +category = "main" optional = false python-versions = "~=3.6" files = [ @@ -3103,6 +3188,7 @@ toml = ["toml"] name = "kiwisolver" version = "1.4.4" description = "A fast implementation of the Cassowary constraint solver" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3180,6 +3266,7 @@ files = [ name = "latexcodec" version = "2.0.1" description = "A lexer and codec to work with LaTeX code in Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3194,6 +3281,7 @@ six = ">=1.4.1" name = "leather" version = "0.3.4" description = "Python charting for 80% of humans." +category = "main" optional = false python-versions = "*" files = [ @@ -3206,13 +3294,14 @@ six = ">=1.6.1" [[package]] name = "linkify-it-py" -version = "1.0.3" +version = "2.0.3" description = "Links recognition library with FULL unicode support." +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "linkify-it-py-1.0.3.tar.gz", hash = "sha256:2b3f168d5ce75e3a425e34b341a6b73e116b5d9ed8dbbbf5dc7456843b7ce2ee"}, - {file = "linkify_it_py-1.0.3-py3-none-any.whl", hash = "sha256:11e29f00150cddaa8f434153f103c14716e7e097a8fd372d9eb1ed06ed91524d"}, + {file = "linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048"}, + {file = "linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79"}, ] [package.dependencies] @@ -3220,7 +3309,7 @@ uc-micro-py = "*" [package.extras] benchmark = ["pytest", "pytest-benchmark"] -dev = ["black", "flake8", "isort", "pre-commit"] +dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] doc = ["myst-parser", "sphinx", "sphinx-book-theme"] test = ["coverage", "pytest", "pytest-cov"] @@ -3228,6 +3317,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "llvmlite" version = "0.39.1" description = "lightweight wrapper around basic LLVM functionality" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3265,6 +3355,7 @@ files = [ name = "locket" version = "1.0.0" description = "File-based locks for Python on Linux and Windows" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3276,6 +3367,7 @@ files = [ name = "loguru" version = "0.6.0" description = "Python logging made (stupidly) simple" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -3294,6 +3386,7 @@ dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils name = "lxml" version = "4.9.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -3401,6 +3494,7 @@ source = ["Cython (>=0.29.35)"] name = "mapclassify" version = "2.6.0" description = "Classification Schemes for Choropleth Maps." +category = "dev" optional = false python-versions = "*" files = [ @@ -3424,6 +3518,7 @@ tests = ["codecov", "geopandas", "libpysal", "networkx", "palettable", "pytest", name = "markdown-it-py" version = "1.1.0" description = "Python port of markdown-it. Markdown parsing, done right!" +category = "main" optional = false python-versions = "~=3.6" files = [ @@ -3446,6 +3541,7 @@ testing = ["coverage", "psutil", "pytest (>=3.6,<4)", "pytest-benchmark (>=3.2,< name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3515,6 +3611,7 @@ files = [ name = "matplotlib" version = "3.5.0" description = "Python plotting package" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3570,6 +3667,7 @@ setuptools-scm = ">=4" name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3582,27 +3680,29 @@ traitlets = "*" [[package]] name = "mdit-py-plugins" -version = "0.2.8" +version = "0.3.5" description = "Collection of plugins for markdown-it-py" +category = "main" optional = false -python-versions = "~=3.6" +python-versions = ">=3.7" files = [ - {file = "mdit-py-plugins-0.2.8.tar.gz", hash = "sha256:5991cef645502e80a5388ec4fc20885d2313d4871e8b8e320ca2de14ac0c015f"}, - {file = "mdit_py_plugins-0.2.8-py3-none-any.whl", hash = "sha256:1833bf738e038e35d89cb3a07eb0d227ed647ce7dd357579b65343740c6d249c"}, + {file = "mdit-py-plugins-0.3.5.tar.gz", hash = "sha256:eee0adc7195e5827e17e02d2a258a2ba159944a0748f59c5099a4a27f78fcf6a"}, + {file = "mdit_py_plugins-0.3.5-py3-none-any.whl", hash = "sha256:ca9a0714ea59a24b2b044a1831f48d817dd0c817e84339f20e7889f392d77c4e"}, ] [package.dependencies] -markdown-it-py = ">=1.0,<2.0" +markdown-it-py = ">=1.0.0,<3.0.0" [package.extras] -code-style = ["pre-commit (==2.6)"] -rtd = ["myst-parser (==0.14.0a3)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] -testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] +code-style = ["pre-commit"] +rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "mistune" version = "0.8.4" description = "The fastest markdown parser in pure Python" +category = "main" optional = false python-versions = "*" files = [ @@ -3614,6 +3714,7 @@ files = [ name = "mizani" version = "0.10.0" description = "Scales for Python" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3640,6 +3741,7 @@ typing = ["pandas-stubs", "pyright"] name = "msgpack" version = "1.0.5" description = "MessagePack serializer" +category = "main" optional = false python-versions = "*" files = [ @@ -3712,6 +3814,7 @@ files = [ name = "multidict" version = "6.0.4" description = "multidict implementation" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3795,6 +3898,7 @@ files = [ name = "multimethod" version = "1.9.1" description = "Multiple argument dispatching." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3806,6 +3910,7 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3815,63 +3920,65 @@ files = [ [[package]] name = "myst-nb" -version = "0.13.2" +version = "1.0.0" description = "A Jupyter Notebook Sphinx reader built on top of the MyST markdown parser." +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "myst-nb-0.13.2.tar.gz", hash = "sha256:81e0a4f186bb35c487f5443c7005a474d68ffb58f518f469102d1db7b452066a"}, - {file = "myst_nb-0.13.2-py3-none-any.whl", hash = "sha256:1b9ea3a04c9e0eee05145aa297d2feeabb94c4e23e3047b92efa011ddba4f4b4"}, + {file = "myst_nb-1.0.0-py3-none-any.whl", hash = "sha256:ee8febc6dd7d9e32bede0c66a9b962b2e2fdab697428ee9fbfd4919d82380911"}, + {file = "myst_nb-1.0.0.tar.gz", hash = "sha256:9077e42a1c6b441ea55078506f83555dda5d6c816ef4930841d71d239e3e0c5e"}, ] [package.dependencies] -docutils = ">=0.15,<0.18" -importlib-metadata = "*" +importlib_metadata = "*" +ipykernel = "*" ipython = "*" -ipywidgets = ">=7.0.0,<8" -jupyter-cache = ">=0.4.1,<0.5.0" -jupyter-sphinx = ">=0.3.2,<0.4.0" -myst-parser = ">=0.15.2,<0.16.0" -nbconvert = ">=5.6,<7" -nbformat = ">=5.0,<6.0" +jupyter-cache = ">=0.5" +myst-parser = ">=1.0.0" +nbclient = "*" +nbformat = ">=5.0" pyyaml = "*" -sphinx = ">=3.1,<5" -sphinx-togglebutton = ">=0.3.0,<0.4.0" +sphinx = ">=5" +typing-extensions = "*" [package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -rtd = ["alabaster", "altair", "bokeh", "coconut (>=1.4.3,<1.5.0)", "ipykernel (>=5.5,<6.0)", "ipywidgets", "jupytext (>=1.11.2,<1.12.0)", "matplotlib", "numpy", "pandas", "plotly", "sphinx-book-theme (>=0.1.0,<0.2.0)", "sphinx-copybutton", "sphinx-panels (>=0.4.1,<0.5.0)", "sphinxcontrib-bibtex", "sympy"] -testing = ["coverage (<5.0)", "ipykernel (>=5.5,<6.0)", "ipython (<8)", "jupytext (>=1.11.2,<1.12.0)", "matplotlib (>=3.3.0,<3.4.0)", "numpy", "pandas (<1.4)", "pytest (>=5.4,<6.0)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions", "sympy"] +code-style = ["pre-commit"] +rtd = ["alabaster", "altair", "bokeh", "coconut (>=1.4.3,<3.1.0)", "ipykernel (>=5.5,<7.0)", "ipywidgets", "jupytext (>=1.11.2,<1.16.0)", "matplotlib", "numpy", "pandas", "plotly", "sphinx-book-theme (>=0.3)", "sphinx-copybutton", "sphinx-design (>=0.4.0,<0.5.0)", "sphinxcontrib-bibtex", "sympy"] +testing = ["beautifulsoup4", "coverage (>=6.4,<8.0)", "ipykernel (>=5.5,<7.0)", "ipython (!=8.1.0,<8.17)", "ipywidgets (>=8)", "jupytext (>=1.11.2,<1.16.0)", "matplotlib (>=3.7.0,<3.8.0)", "nbdime", "numpy", "pandas", "pytest (>=7.1,<8.0)", "pytest-cov (>=3,<5)", "pytest-param-files (>=0.3.3,<0.4.0)", "pytest-regressions", "sympy (>=1.10.1)"] [[package]] name = "myst-parser" -version = "0.15.2" -description = "An extended commonmark compliant parser, with bridges to docutils & sphinx." +version = "1.0.0" +description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "myst-parser-0.15.2.tar.gz", hash = "sha256:f7f3b2d62db7655cde658eb5d62b2ec2a4631308137bd8d10f296a40d57bbbeb"}, - {file = "myst_parser-0.15.2-py3-none-any.whl", hash = "sha256:40124b6f27a4c42ac7f06b385e23a9dcd03d84801e9c7130b59b3729a554b1f9"}, + {file = "myst-parser-1.0.0.tar.gz", hash = "sha256:502845659313099542bd38a2ae62f01360e7dd4b1310f025dd014dfc0439cdae"}, + {file = "myst_parser-1.0.0-py3-none-any.whl", hash = "sha256:69fb40a586c6fa68995e6521ac0a525793935db7e724ca9bac1d33be51be9a4c"}, ] [package.dependencies] -docutils = ">=0.15,<0.18" +docutils = ">=0.15,<0.20" jinja2 = "*" -markdown-it-py = ">=1.0.0,<2.0.0" -mdit-py-plugins = ">=0.2.8,<0.3.0" +markdown-it-py = ">=1.0.0,<3.0.0" +mdit-py-plugins = ">=0.3.4,<0.4.0" pyyaml = "*" -sphinx = ">=3.1,<5" +sphinx = ">=5,<7" [package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] +code-style = ["pre-commit (>=3.0,<4.0)"] linkify = ["linkify-it-py (>=1.0,<2.0)"] -rtd = ["ipython", "sphinx-book-theme (>=0.1.0,<0.2.0)", "sphinx-panels (>=0.5.2,<0.6.0)", "sphinxcontrib-bibtex (>=2.1,<3.0)", "sphinxcontrib.mermaid (>=0.6.3,<0.7.0)", "sphinxext-opengraph (>=0.4.2,<0.5.0)", "sphinxext-rediraffe (>=0.2,<1.0)"] -testing = ["beautifulsoup4", "coverage", "docutils (>=0.17.0,<0.18.0)", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] +rtd = ["ipython", "pydata-sphinx-theme (==v0.13.0rc4)", "sphinx-autodoc2 (>=0.4.2,<0.5.0)", "sphinx-book-theme (==1.0.0rc2)", "sphinx-copybutton", "sphinx-design2", "sphinx-pyscript", "sphinx-tippy (>=0.3.1)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.7.5,<0.8.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=7,<8)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx-pytest"] +testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4,<0.4.0)"] [[package]] name = "nbclassic" version = "1.0.0" description = "Jupyter Notebook as a Jupyter Server extension." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3907,6 +4014,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p name = "nbclient" version = "0.5.13" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -3928,6 +4036,7 @@ test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "i name = "nbconvert" version = "6.5.4" description = "Converting Jupyter Notebooks" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3961,36 +4070,11 @@ serve = ["tornado (>=6.1)"] test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency"] webpdf = ["pyppeteer (>=1,<1.1)"] -[[package]] -name = "nbdime" -version = "3.2.1" -description = "Diff and merge of Jupyter Notebooks" -optional = false -python-versions = ">=3.6" -files = [ - {file = "nbdime-3.2.1-py2.py3-none-any.whl", hash = "sha256:a99fed2399fd939e2e577db4bb6e957aac860af4cf583044b723cc9a448c644e"}, - {file = "nbdime-3.2.1.tar.gz", hash = "sha256:31409a30f848ffc6b32540697e82d5a0a1b84dcc32716ca74e78bcc4b457c453"}, -] - -[package.dependencies] -colorama = "*" -GitPython = "<2.1.4 || >2.1.4,<2.1.5 || >2.1.5,<2.1.6 || >2.1.6" -jinja2 = ">=2.9" -jupyter-server = "*" -jupyter-server-mathjax = ">=0.2.2" -nbformat = "*" -pygments = "*" -requests = "*" -tornado = "*" - -[package.extras] -docs = ["recommonmark", "sphinx", "sphinx-rtd-theme"] -test = ["jsonschema", "jupyter-server[test]", "notebook", "pytest (>=3.6)", "pytest-cov", "pytest-timeout", "pytest-tornado", "requests", "tabulate"] - [[package]] name = "nbformat" version = "5.9.2" description = "The Jupyter Notebook format" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4012,6 +4096,7 @@ test = ["pep440", "pre-commit", "pytest", "testpath"] name = "nest-asyncio" version = "1.5.7" description = "Patch asyncio to allow nested event loops" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4023,6 +4108,7 @@ files = [ name = "networkx" version = "3.1" description = "Python package for creating and manipulating graphs and networks" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4041,6 +4127,7 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -4055,6 +4142,7 @@ setuptools = "*" name = "notebook" version = "6.5.4" description = "A web-based notebook environment for interactive computing" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4089,6 +4177,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixs name = "notebook-shim" version = "0.2.3" description = "A shim layer for notebook traits and config" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4106,6 +4195,7 @@ test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync" name = "numba" version = "0.56.4" description = "compiling Python code using LLVM" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4140,7 +4230,7 @@ files = [ ] [package.dependencies] -llvmlite = "==0.39.*" +llvmlite = ">=0.39.0dev0,<0.40" numpy = ">=1.18,<1.24" setuptools = "*" @@ -4148,6 +4238,7 @@ setuptools = "*" name = "numpy" version = "1.23.5" description = "NumPy is the fundamental package for array computing with Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4185,6 +4276,7 @@ files = [ name = "oauthlib" version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4201,6 +4293,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] name = "olefile" version = "0.46" description = "Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office)" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4211,6 +4304,7 @@ files = [ name = "openpyxl" version = "3.0.9" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4225,6 +4319,7 @@ et-xmlfile = "*" name = "orderedmultidict" version = "1.0.1" description = "Ordered Multivalue Dictionary" +category = "main" optional = false python-versions = "*" files = [ @@ -4239,6 +4334,7 @@ six = ">=1.8.0" name = "outcome" version = "1.2.0" description = "Capture the outcome of Python function calls." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4253,6 +4349,7 @@ attrs = ">=19.2.0" name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4264,6 +4361,7 @@ files = [ name = "pandas" version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4308,6 +4406,7 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] name = "pandas-gbq" version = "0.19.2" description = "Google BigQuery connector for pandas" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4335,6 +4434,7 @@ tqdm = ["tqdm (>=4.23.0)"] name = "pandocfilters" version = "1.5.0" description = "Utilities for writing pandoc filters in python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4346,6 +4446,7 @@ files = [ name = "papermill" version = "2.4.0" description = "Parametrize and run Jupyter and nteract Notebooks" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4379,6 +4480,7 @@ test = ["attrs (>=17.4.0)", "azure-datalake-store (>=0.0.30)", "azure-storage-bl name = "parsedatetime" version = "2.6" description = "Parse human-readable date/time text." +category = "main" optional = false python-versions = "*" files = [ @@ -4390,6 +4492,7 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4405,6 +4508,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "partd" version = "1.4.0" description = "Appendable key-value storage" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4423,6 +4527,7 @@ complete = ["blosc", "numpy (>=1.9.0)", "pandas (>=0.19.0)", "pyzmq"] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4434,6 +4539,7 @@ files = [ name = "patsy" version = "0.5.3" description = "A Python package for describing statistical models and for building design matrices." +category = "main" optional = false python-versions = "*" files = [ @@ -4452,6 +4558,7 @@ test = ["pytest", "pytest-cov", "scipy"] name = "pendulum" version = "2.1.2" description = "Python datetimes made easy" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4486,6 +4593,7 @@ pytzdata = ">=2020.1" name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." +category = "main" optional = false python-versions = "*" files = [ @@ -4500,6 +4608,7 @@ ptyprocess = ">=0.5" name = "phik" version = "0.12.3" description = "Phi_K correlation analyzer library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4539,6 +4648,7 @@ test = ["jupyter-client (>=5.2.3)", "nbconvert (>=5.3.1)", "pytest (>=4.0.2)", " name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" +category = "main" optional = false python-versions = "*" files = [ @@ -4550,6 +4660,7 @@ files = [ name = "pillow" version = "10.0.1" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4617,6 +4728,7 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4632,6 +4744,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "plotly" version = "5.5.0" description = "An open-source, interactive data visualization library for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4647,6 +4760,7 @@ tenacity = ">=6.2.0" name = "plotnine" version = "0.8.0" description = "A grammar of graphics for python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4671,6 +4785,7 @@ all = ["scikit-learn", "scikit-misc"] name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -4686,6 +4801,7 @@ testing = ["pytest", "pytest-benchmark"] name = "portpicker" version = "1.5.2" description = "A library to choose unique available network ports." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4700,6 +4816,7 @@ psutil = "*" name = "pre-commit" version = "2.18.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4719,6 +4836,7 @@ virtualenv = ">=20.0.8" name = "prometheus-client" version = "0.17.1" description = "Python client for the Prometheus monitoring system." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4733,6 +4851,7 @@ twisted = ["twisted"] name = "prompt-toolkit" version = "3.0.39" description = "Library for building powerful interactive command lines in Python" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -4747,6 +4866,7 @@ wcwidth = "*" name = "proto-plus" version = "1.22.3" description = "Beautiful, Pythonic protocol buffers." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4764,6 +4884,7 @@ testing = ["google-api-core[grpc] (>=1.31.5)"] name = "protobuf" version = "4.23.4" description = "" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4786,6 +4907,7 @@ files = [ name = "psutil" version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4812,6 +4934,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -4823,6 +4946,7 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" +category = "main" optional = false python-versions = "*" files = [ @@ -4837,6 +4961,7 @@ tests = ["pytest"] name = "pyaml" version = "21.10.1" description = "PyYAML-based module to produce pretty and readable YAML-serialized data" +category = "dev" optional = false python-versions = "*" files = [ @@ -4851,6 +4976,7 @@ PyYAML = "*" name = "pyarrow" version = "14.0.1" description = "Python library for Apache Arrow" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4899,6 +5025,7 @@ numpy = ">=1.16.6" name = "pyasn1" version = "0.5.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -4910,6 +5037,7 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -4924,6 +5052,7 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pybtex" version = "0.24.0" description = "A BibTeX-compatible bibliography processor in Python" +category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" files = [ @@ -4943,6 +5072,7 @@ test = ["pytest"] name = "pybtex-docutils" version = "1.0.2" description = "A docutils backend for pybtex." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4958,6 +5088,7 @@ pybtex = ">=0.16" name = "pycparser" version = "2.21" description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4969,6 +5100,7 @@ files = [ name = "pydantic" version = "1.10.12" description = "Data validation and settings management using python type hints" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5021,6 +5153,7 @@ email = ["email-validator (>=1.0.3)"] name = "pydata-google-auth" version = "1.8.2" description = "PyData helpers for authenticating to Google APIs" +category = "main" optional = false python-versions = "*" files = [ @@ -5035,28 +5168,37 @@ setuptools = "*" [[package]] name = "pydata-sphinx-theme" -version = "0.7.2" +version = "0.15.2" description = "Bootstrap-based Sphinx theme from the PyData community" +category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.9" files = [ - {file = "pydata-sphinx-theme-0.7.2.tar.gz", hash = "sha256:671df35fcdd290eafbd23d0595e6d359dbe90b2e64e6c3f4dc88276eed4a065e"}, - {file = "pydata_sphinx_theme-0.7.2-py3-none-any.whl", hash = "sha256:bc1abc45e103b254c6c7a8f2ddabbaf8aa1f0817d85cae65dd163dd554c52700"}, + {file = "pydata_sphinx_theme-0.15.2-py3-none-any.whl", hash = "sha256:0c5fa1fa98a9b26dae590666ff576f27e26c7ba708fee754ecb9e07359ed4588"}, + {file = "pydata_sphinx_theme-0.15.2.tar.gz", hash = "sha256:4243fee85b3afcfae9df64f83210a04e7182e53bc3db8841ffff6d21d95ae320"}, ] [package.dependencies] +accessible-pygments = "*" +Babel = "*" beautifulsoup4 = "*" docutils = "!=0.17.0" -sphinx = "*" +packaging = "*" +pygments = ">=2.7" +sphinx = ">=5.0" +typing-extensions = "*" [package.extras] -coverage = ["beautifulsoup4", "codecov", "docutils (==0.16)", "jupyter-sphinx", "numpy", "numpydoc", "pandas", "plotly", "pytest", "pytest-cov", "pytest-regressions", "recommonmark", "sphinx", "sphinx-sitemap", "xarray"] -test = ["beautifulsoup4", "docutils (==0.16)", "jupyter-sphinx", "numpy", "numpydoc", "pandas", "plotly", "pytest", "pytest-regressions", "recommonmark", "sphinx", "sphinx-sitemap", "xarray"] +a11y = ["pytest-playwright"] +dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] +doc = ["ablog (>=0.11.0rc2)", "colorama", "ipykernel", "ipyleaflet", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (>=3.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (<1.4)", "sphinxext-rediraffe", "xarray"] +test = ["pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "pygeos" version = "0.12.0" description = "GEOS wrapped in numpy ufuncs" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5107,6 +5249,7 @@ test = ["pytest"] name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5121,6 +5264,7 @@ plugins = ["importlib-metadata"] name = "pyodbc" version = "4.0.39" description = "DB API Module for ODBC" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -5165,6 +5309,7 @@ files = [ name = "pyparsing" version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" optional = false python-versions = ">=3.6.8" files = [ @@ -5179,6 +5324,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyproj" version = "3.6.0" description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -5216,6 +5362,7 @@ certifi = "*" name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5252,6 +5399,7 @@ files = [ name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5264,6 +5412,7 @@ files = [ name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -5286,6 +5435,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -5300,6 +5450,7 @@ six = ">=1.5" name = "python-dotenv" version = "0.19.2" description = "Read key-value pairs from a .env file and set them as environment variables" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -5314,6 +5465,7 @@ cli = ["click (>=5.0)"] name = "python-slugify" version = "6.1.2" description = "A Python slugify application that also handles Unicode" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -5331,6 +5483,7 @@ unidecode = ["Unidecode (>=1.1.1)"] name = "pytimeparse" version = "1.1.8" description = "Time expression parser" +category = "main" optional = false python-versions = "*" files = [ @@ -5342,6 +5495,7 @@ files = [ name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ @@ -5353,6 +5507,7 @@ files = [ name = "pytzdata" version = "2020.1" description = "The Olson timezone database for Python." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5364,6 +5519,7 @@ files = [ name = "pywavelets" version = "1.4.1" description = "PyWavelets, wavelet transform module" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5401,6 +5557,7 @@ numpy = ">=1.17.3" name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "main" optional = false python-versions = "*" files = [ @@ -5424,6 +5581,7 @@ files = [ name = "pywinpty" version = "2.0.11" description = "Pseudo terminal support for Windows from Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5438,6 +5596,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5497,6 +5656,7 @@ files = [ name = "pyzmq" version = "25.1.0" description = "Python bindings for 0MQ" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5586,6 +5746,7 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "qtconsole" version = "5.4.3" description = "Jupyter Qt console" +category = "main" optional = false python-versions = ">= 3.7" files = [ @@ -5612,6 +5773,7 @@ test = ["flaky", "pytest", "pytest-qt"] name = "qtpy" version = "2.3.1" description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5629,6 +5791,7 @@ test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5650,6 +5813,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-oauthlib" version = "1.3.1" description = "OAuthlib authentication support for Requests." +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5668,6 +5832,7 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] name = "rsa" version = "4.9" description = "Pure-Python RSA implementation" +category = "main" optional = false python-versions = ">=3.6,<4" files = [ @@ -5682,6 +5847,7 @@ pyasn1 = ">=0.1.3" name = "rtree" version = "0.9.7" description = "R-Tree spatial index for Python GIS" +category = "main" optional = false python-versions = "*" files = [ @@ -5718,6 +5884,7 @@ files = [ name = "s3fs" version = "2023.6.0" description = "Convenient Filesystem interface over S3" +category = "main" optional = false python-versions = ">= 3.8" files = [ @@ -5738,6 +5905,7 @@ boto3 = ["aiobotocore[boto3] (>=2.5.0,<2.6.0)"] name = "scikit-learn" version = "1.3.0" description = "A set of python modules for machine learning and data mining" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -5780,6 +5948,7 @@ tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc ( name = "scipy" version = "1.11.1" description = "Fundamental algorithms for scientific computing in Python" +category = "main" optional = false python-versions = "<3.13,>=3.9" files = [ @@ -5816,6 +5985,7 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo name = "seaborn" version = "0.11.2" description = "seaborn: statistical data visualization" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5833,6 +6003,7 @@ scipy = ">=1.0" name = "selenium" version = "4.11.2" description = "" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5850,6 +6021,7 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]} name = "send2trash" version = "1.8.2" description = "Send file to trash natively under Mac OS X, Windows and Linux" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -5866,6 +6038,7 @@ win32 = ["pywin32"] name = "setuptools" version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5882,6 +6055,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "setuptools-scm" version = "7.1.0" description = "the blessed package to manage your versions by scm tags" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5903,6 +6077,7 @@ toml = ["setuptools (>=42)"] name = "shapely" version = "2.0.1" description = "Manipulation and analysis of geometric objects" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5950,13 +6125,14 @@ files = [ numpy = ">=1.14" [package.extras] -docs = ["matplotlib", "numpydoc (==1.1.*)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] +docs = ["matplotlib", "numpydoc (>=1.1.0,<1.2.0)", "sphinx", "sphinx-book-theme", "sphinx-remove-toctrees"] test = ["pytest", "pytest-cov"] [[package]] name = "simpervisor" version = "1.0.0" description = "Simple async process supervisor" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5971,6 +6147,7 @@ test = ["aiohttp", "psutil", "pytest", "pytest-asyncio", "pytest-cov"] name = "siuba" version = "0.4.2" description = "A package for quick, scrappy analyses with pandas and SQL" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5992,6 +6169,7 @@ test = ["hypothesis", "pytest"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -5999,21 +6177,11 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[[package]] -name = "smmap" -version = "5.0.0" -description = "A pure Python implementation of a sliding window memory map manager" -optional = false -python-versions = ">=3.6" -files = [ - {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, - {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, -] - [[package]] name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6025,6 +6193,7 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "main" optional = false python-versions = "*" files = [ @@ -6036,6 +6205,7 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "main" optional = false python-versions = "*" files = [ @@ -6047,6 +6217,7 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6056,27 +6227,28 @@ files = [ [[package]] name = "sphinx" -version = "4.5.0" +version = "5.3.0" description = "Python documentation generator" +category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, - {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, + {file = "Sphinx-5.3.0.tar.gz", hash = "sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5"}, + {file = "sphinx-5.3.0-py3-none-any.whl", hash = "sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.20" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.12" requests = ">=2.5.0" -snowballstemmer = ">=1.1" +snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" @@ -6086,37 +6258,35 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "flake8-simplify", "isort", "mypy (>=0.981)", "sphinx-lint", "types-requests", "types-typed-ast"] +test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] [[package]] name = "sphinx-book-theme" -version = "0.1.10" +version = "1.1.0" description = "A clean book theme for scientific explanations and documentation with Sphinx" +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "sphinx-book-theme-0.1.10.tar.gz", hash = "sha256:c74d7deb36e6fea4bcb3a979d162d9fd80e93b7ea4da78ebf8286da4b898582a"}, - {file = "sphinx_book_theme-0.1.10-py3-none-any.whl", hash = "sha256:1722b60c8ac87aa53758f4403912972cb28d0c253196446339859124e92f686f"}, + {file = "sphinx_book_theme-1.1.0-py3-none-any.whl", hash = "sha256:088bc69d65fab8446adb8691ed61687f71bf7504c9740af68bc78cf936a26112"}, + {file = "sphinx_book_theme-1.1.0.tar.gz", hash = "sha256:ad4f92998e53e24751ecd0978d3eb79fdaa59692f005b1b286ecdd6146ebc9c1"}, ] [package.dependencies] -beautifulsoup4 = ">=4.6.1,<5" -docutils = ">=0.15,<0.17" -pydata-sphinx-theme = ">=0.7.2,<0.8.0" -pyyaml = "*" -sphinx = ">=3,<5" +pydata-sphinx-theme = ">=0.14" +sphinx = ">=5" [package.extras] -code-style = ["pre-commit (>=2.7.0,<2.8.0)"] -live-dev = ["sphinx-autobuild", "web-compile (>=0.2.1,<0.3.0)"] -sphinx = ["ablog (>=0.10.13,<0.11.0)", "folium", "ipywidgets", "matplotlib", "myst-nb (>=0.13,<1.0)", "nbclient", "numpy", "pandas", "plotly", "sphinx (>=4.0,<5.0)", "sphinx-copybutton", "sphinx-design", "sphinx-thebe", "sphinx-togglebutton (>=0.2.1)", "sphinxcontrib-bibtex (>=2.2,<3.0)", "sphinxext-opengraph"] -testing = ["coverage", "myst-nb (>=0.13,<1.0)", "pytest (>=6.0.1,<6.1.0)", "pytest-cov", "pytest-regressions (>=2.0.1,<2.1.0)", "sphinx-thebe"] +code-style = ["pre-commit"] +doc = ["ablog", "folium", "ipywidgets", "matplotlib", "myst-nb", "nbclient", "numpy", "numpydoc", "pandas", "plotly", "sphinx-copybutton", "sphinx-design", "sphinx-examples", "sphinx-tabs", "sphinx-thebe", "sphinx-togglebutton", "sphinxcontrib-bibtex", "sphinxcontrib-youtube", "sphinxext-opengraph"] +test = ["beautifulsoup4", "coverage", "myst-nb", "pytest", "pytest-cov", "pytest-regressions", "sphinx_thebe"] [[package]] name = "sphinx-comments" version = "0.0.3" description = "Add comments and annotation to your documentation." +category = "main" optional = false python-versions = "*" files = [ @@ -6136,6 +6306,7 @@ testing = ["beautifulsoup4", "myst-parser", "pytest", "pytest-regressions", "sph name = "sphinx-copybutton" version = "0.5.2" description = "Add a copy button to each of your code cells." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6150,52 +6321,79 @@ sphinx = ">=1.8" code-style = ["pre-commit (==2.12.1)"] rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] +[[package]] +name = "sphinx-design" +version = "0.5.0" +description = "A sphinx extension for designing beautiful, view size responsive web components." +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinx_design-0.5.0-py3-none-any.whl", hash = "sha256:1af1267b4cea2eedd6724614f19dcc88fe2e15aff65d06b2f6252cee9c4f4c1e"}, + {file = "sphinx_design-0.5.0.tar.gz", hash = "sha256:e8e513acea6f92d15c6de3b34e954458f245b8e761b45b63950f65373352ab00"}, +] + +[package.dependencies] +sphinx = ">=5,<8" + +[package.extras] +code-style = ["pre-commit (>=3,<4)"] +rtd = ["myst-parser (>=1,<3)"] +testing = ["myst-parser (>=1,<3)", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"] +theme-furo = ["furo (>=2023.7.0,<2023.8.0)"] +theme-pydata = ["pydata-sphinx-theme (>=0.13.0,<0.14.0)"] +theme-rtd = ["sphinx-rtd-theme (>=1.0,<2.0)"] +theme-sbt = ["sphinx-book-theme (>=1.0,<2.0)"] + [[package]] name = "sphinx-external-toc" -version = "0.2.4" +version = "1.0.1" description = "A sphinx extension that allows the site-map to be defined in a single YAML file." +category = "main" optional = false -python-versions = "~=3.6" +python-versions = ">=3.9" files = [ - {file = "sphinx_external_toc-0.2.4-py3-none-any.whl", hash = "sha256:f7906620e74fbef50f0c3b8adf943da03000ab955ffe957ae4760d6cd5a09717"}, - {file = "sphinx_external_toc-0.2.4.tar.gz", hash = "sha256:f073c482d959a166f844ca8caadd13e24fa43153750cc120646ded37ff622018"}, + {file = "sphinx_external_toc-1.0.1-py3-none-any.whl", hash = "sha256:d9e02d50731dee9697c1887e4f8b361e7b86d38241f0e66bd5a9f4096779646f"}, + {file = "sphinx_external_toc-1.0.1.tar.gz", hash = "sha256:a7d2c63cc47ec688546443b28bc4ef466121827ef3dc7bb509de354bad4ea2e0"}, ] [package.dependencies] -attrs = ">=20.3,<22" -click = ">=7.1,<9" +click = ">=7.1" pyyaml = "*" -sphinx = ">=3,<5" +sphinx = ">=5" [package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -rtd = ["myst-parser (>=0.15.0,<0.16.0)", "sphinx-book-theme (>=0.0.36)"] -testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"] +code-style = ["pre-commit (>=2.12)"] +rtd = ["myst-parser (>=1.0.0)", "sphinx-book-theme (>=1.0.0)"] +testing = ["coverage", "pytest (>=7.1)", "pytest-cov", "pytest-regressions"] [[package]] name = "sphinx-jupyterbook-latex" -version = "0.4.7" +version = "1.0.0" description = "Latex specific features for jupyter book" +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.9" files = [ - {file = "sphinx_jupyterbook_latex-0.4.7-py3-none-any.whl", hash = "sha256:616990de4e5680879bede70260dd4f3821586c4c0f36d1b1a1ebb736020a7f92"}, - {file = "sphinx_jupyterbook_latex-0.4.7.tar.gz", hash = "sha256:288640a8d5476e75bc4d88c7b2446d2af385adf8c57e45e6ec27cd3345806b07"}, + {file = "sphinx_jupyterbook_latex-1.0.0-py3-none-any.whl", hash = "sha256:e0cd3e9e1c5af69136434e21a533343fdf013475c410a414d5b7b4922b4f3891"}, + {file = "sphinx_jupyterbook_latex-1.0.0.tar.gz", hash = "sha256:f54c6674c13f1616f9a93443e98b9b5353f9fdda8e39b6ec552ccf0b3e5ffb62"}, ] [package.dependencies] -sphinx = ">=3,<5" +packaging = "*" +sphinx = ">=5" [package.extras] code-style = ["pre-commit (>=2.12,<3.0)"] -myst = ["myst-nb (>=0.13,<0.14)"] +myst = ["myst-nb (>=1.0.0)"] rtd = ["myst-parser", "sphinx-book-theme", "sphinx-design", "sphinx-jupyterbook-latex"] -testing = ["coverage (<5.0)", "myst-nb (>=0.13,<0.14)", "pytest (>=3.6,<4)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions", "sphinx-external-toc (>=0.1.0,<0.3.0)", "sphinxcontrib-bibtex (>=2.2.1,<2.3.0)", "texsoup"] +testing = ["coverage (>=6.0)", "myst-nb (>=1.0.0)", "pytest (>=7.1)", "pytest-cov (>=3)", "pytest-regressions", "sphinx-external-toc (>=1.0.0)", "sphinxcontrib-bibtex (>=2.6.0)", "texsoup"] [[package]] name = "sphinx-multitoc-numbering" version = "0.1.3" description = "Supporting continuous HTML section numbering" +category = "main" optional = false python-versions = "*" files = [ @@ -6211,49 +6409,31 @@ code-style = ["black", "flake8 (>=3.7.0,<3.8.0)", "pre-commit (==1.17.0)"] rtd = ["myst-parser", "sphinx (>=3.0)", "sphinx-book-theme"] testing = ["coverage (<5.0)", "jupyter-book", "pytest (>=5.4,<6.0)", "pytest-cov (>=2.8,<3.0)", "pytest-regressions"] -[[package]] -name = "sphinx-panels" -version = "0.6.0" -description = "A sphinx extension for creating panels in a grid layout." -optional = false -python-versions = "*" -files = [ - {file = "sphinx-panels-0.6.0.tar.gz", hash = "sha256:d36dcd26358117e11888f7143db4ac2301ebe90873ac00627bf1fe526bf0f058"}, - {file = "sphinx_panels-0.6.0-py3-none-any.whl", hash = "sha256:bd64afaf85c07f8096d21c8247fc6fd757e339d1be97832c8832d6ae5ed2e61d"}, -] - -[package.dependencies] -docutils = "*" -sphinx = ">=2,<5" - -[package.extras] -code-style = ["pre-commit (>=2.7.0,<2.8.0)"] -live-dev = ["sphinx-autobuild", "web-compile (>=0.2.0,<0.3.0)"] -testing = ["pytest (>=6.0.1,<6.1.0)", "pytest-regressions (>=2.0.1,<2.1.0)"] -themes = ["myst-parser (>=0.12.9,<0.13.0)", "pydata-sphinx-theme (>=0.4.0,<0.5.0)", "sphinx-book-theme (>=0.0.36,<0.1.0)", "sphinx-rtd-theme"] - [[package]] name = "sphinx-thebe" -version = "0.1.2" +version = "0.3.0" description = "Integrate interactive code blocks into your documentation with Thebe and Binder." +category = "main" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "sphinx-thebe-0.1.2.tar.gz", hash = "sha256:756f1dd6643f5abb491f8a27b22825b04f47e05c5d214bbb2e6b5d42b621b85e"}, - {file = "sphinx_thebe-0.1.2-py3-none-any.whl", hash = "sha256:42bb15287bba3459a1faf6081d1bb7a6a426c77a6ba41ac8d3aa98e8f75baa6b"}, + {file = "sphinx_thebe-0.3.0-py3-none-any.whl", hash = "sha256:e58579c18562593a2dae4a561e2cf294af315a3e5ef961b048761202b49e4b34"}, + {file = "sphinx_thebe-0.3.0.tar.gz", hash = "sha256:c60dab1b59b92d6a2eab8d7119e87c0730470da62f3c84bf6ca75690487d0505"}, ] [package.dependencies] -sphinx = ">=3.5,<5" +sphinx = ">=4" [package.extras] -sphinx = ["matplotlib", "myst-nb", "sphinx-book-theme", "sphinx-copybutton", "sphinx-panels"] -testing = ["beautifulsoup4", "matplotlib", "pytest", "pytest-regressions"] +dev = ["sphinx-thebe[testing]"] +sphinx = ["myst-nb", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design"] +testing = ["beautifulsoup4", "matplotlib", "myst-nb (>=1.0.0rc0)", "pytest", "pytest-regressions", "sphinx-copybutton", "sphinx-design"] [[package]] name = "sphinx-togglebutton" version = "0.3.2" description = "Toggle page content and collapse admonitions in Sphinx." +category = "main" optional = false python-versions = "*" files = [ @@ -6274,6 +6454,7 @@ sphinx = ["matplotlib", "myst-nb", "numpy", "sphinx-book-theme", "sphinx-design" name = "sphinxcontrib-applehelp" version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6289,6 +6470,7 @@ test = ["pytest"] name = "sphinxcontrib-bibtex" version = "2.5.0" description = "Sphinx extension for BibTeX style citations." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6307,6 +6489,7 @@ Sphinx = ">=2.1" name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6322,6 +6505,7 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6337,6 +6521,7 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6351,6 +6536,7 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6366,6 +6552,7 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6381,6 +6568,7 @@ test = ["pytest"] name = "sqlalchemy" version = "1.4.49" description = "Database Abstraction Library" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -6462,6 +6650,7 @@ sqlcipher = ["sqlcipher3-binary"] name = "sqlalchemy-bigquery" version = "1.7.0" description = "SQLAlchemy dialect for BigQuery" +category = "main" optional = false python-versions = ">=3.7, <3.12" files = [ @@ -6470,7 +6659,7 @@ files = [ ] [package.dependencies] -google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0dev" +google-api-core = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev" google-auth = ">=1.25.0,<3.0.0dev" google-cloud-bigquery = ">=2.25.2,<4.0.0dev" packaging = "*" @@ -6487,6 +6676,7 @@ tests = ["packaging", "pytz"] name = "stack-data" version = "0.6.2" description = "Extract data from python stack frames and tracebacks for informative displays" +category = "main" optional = false python-versions = "*" files = [ @@ -6506,6 +6696,7 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "statsmodels" version = "0.14.0" description = "Statistical computations and models for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6552,10 +6743,26 @@ build = ["cython (>=0.29.26)"] develop = ["colorama", "cython (>=0.29.26)", "cython (>=0.29.28,<3.0.0)", "flake8", "isort", "joblib", "matplotlib (>=3)", "oldest-supported-numpy (>=2022.4.18)", "pytest (>=7.0.1,<7.1.0)", "pytest-randomly", "pytest-xdist", "pywinpty", "setuptools-scm[toml] (>=7.0.0,<7.1.0)"] docs = ["ipykernel", "jupyter-client", "matplotlib", "nbconvert", "nbformat", "numpydoc", "pandas-datareader", "sphinx"] +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tangled-up-in-unicode" version = "0.2.0" description = "Access to the Unicode Character Database (UCD)" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6567,6 +6774,7 @@ files = [ name = "tblib" version = "2.0.0" description = "Traceback serialization library." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6578,6 +6786,7 @@ files = [ name = "tenacity" version = "8.2.2" description = "Retry code until it succeeds" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6592,6 +6801,7 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] name = "terminado" version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6612,6 +6822,7 @@ test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" +category = "main" optional = false python-versions = "*" files = [ @@ -6623,6 +6834,7 @@ files = [ name = "textwrap3" version = "0.9.2" description = "textwrap from Python 3.6 backport (plus a few tweaks)" +category = "dev" optional = false python-versions = "*" files = [ @@ -6634,6 +6846,7 @@ files = [ name = "threadpoolctl" version = "3.2.0" description = "threadpoolctl" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -6645,6 +6858,7 @@ files = [ name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6663,6 +6877,7 @@ test = ["flake8", "isort", "pytest"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -6674,6 +6889,7 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6685,6 +6901,7 @@ files = [ name = "toolz" version = "0.12.0" description = "List processing tools and functional utilities" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6696,6 +6913,7 @@ files = [ name = "tornado" version = "6.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "main" optional = false python-versions = ">= 3.5" files = [ @@ -6746,6 +6964,7 @@ files = [ name = "tqdm" version = "4.65.0" description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6766,6 +6985,7 @@ telegram = ["requests"] name = "traitlets" version = "5.9.0" description = "Traitlets Python configuration system" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6781,6 +7001,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] name = "traittypes" version = "0.2.1" description = "Scipy trait types" +category = "main" optional = false python-versions = "*" files = [ @@ -6798,6 +7019,7 @@ test = ["numpy", "pandas", "pytest", "xarray"] name = "trio" version = "0.22.2" description = "A friendly Python library for async concurrency and I/O" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6818,6 +7040,7 @@ sortedcontainers = "*" name = "trio-websocket" version = "0.10.3" description = "WebSocket library for Trio" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6834,6 +7057,7 @@ wsproto = ">=0.14" name = "typeguard" version = "2.13.3" description = "Run-time type checker for Python" +category = "main" optional = false python-versions = ">=3.5.3" files = [ @@ -6849,6 +7073,7 @@ test = ["mypy", "pytest", "typing-extensions"] name = "typer" version = "0.9.0" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6870,6 +7095,7 @@ test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6. name = "typing-extensions" version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6881,6 +7107,7 @@ files = [ name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" +category = "main" optional = false python-versions = ">=2" files = [ @@ -6892,6 +7119,7 @@ files = [ name = "uc-micro-py" version = "1.0.2" description = "Micro subset of unicode data files for linkify-it-py projects." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6906,6 +7134,7 @@ test = ["coverage", "pytest", "pytest-cov"] name = "urllib3" version = "1.26.18" 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.*" files = [ @@ -6925,6 +7154,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "vega" version = "3.5.0" description = "A Jupyter widget for Vega 5 and Vega-Lite 4" +category = "main" optional = false python-versions = ">=3.6.1" files = [ @@ -6940,6 +7170,7 @@ pandas = ">=1.0.0,<2.0.0" name = "virtualenv" version = "20.24.2" description = "Virtual Python Environment builder" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6960,6 +7191,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "visions" version = "0.7.5" description = "Visions" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6989,6 +7221,7 @@ type-image-path = ["Pillow", "imagehash"] name = "voila" version = "0.3.6" description = "Voilà turns Jupyter notebooks into standalone web applications" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7015,6 +7248,7 @@ visual-test = ["bqplot", "ipympl (==0.8.7)", "ipyvolume", "jupyterlab (>=3.0,<4. name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" +category = "main" optional = false python-versions = "*" files = [ @@ -7026,6 +7260,7 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" +category = "main" optional = false python-versions = "*" files = [ @@ -7037,6 +7272,7 @@ files = [ name = "websocket-client" version = "1.6.1" description = "WebSocket client for Python with low level API options" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7053,6 +7289,7 @@ test = ["websockets"] name = "websockets" version = "11.0.3" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7132,6 +7369,7 @@ files = [ name = "wheel" version = "0.41.0" description = "A built-package format for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7146,6 +7384,7 @@ test = ["pytest (>=6.0.0)", "setuptools (>=65)"] name = "widgetsnbextension" version = "3.6.5" description = "IPython HTML widgets for Jupyter" +category = "main" optional = false python-versions = "*" files = [ @@ -7160,6 +7399,7 @@ notebook = ">=4.4.1" name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -7174,6 +7414,7 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] name = "wordcloud" version = "1.9.2" description = "A little word cloud generator" +category = "main" optional = false python-versions = "*" files = [ @@ -7243,6 +7484,7 @@ pillow = "*" name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -7327,6 +7569,7 @@ files = [ name = "wsproto" version = "1.2.0" description = "WebSockets state-machine based protocol implementation" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -7341,6 +7584,7 @@ h11 = ">=0.9.0,<1" name = "xlrd" version = "2.0.1" description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -7357,6 +7601,7 @@ test = ["pytest", "pytest-cov"] name = "xmltodict" version = "0.13.0" description = "Makes working with XML feel like you are working with JSON" +category = "dev" optional = false python-versions = ">=3.4" files = [ @@ -7368,6 +7613,7 @@ files = [ name = "xyzservices" version = "2023.7.0" description = "Source of XYZ tiles providers" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7379,6 +7625,7 @@ files = [ name = "yarl" version = "1.9.2" description = "Yet another URL library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7466,6 +7713,7 @@ multidict = ">=4.0" name = "ydata-profiling" version = "4.4.0" description = "Generate profile report for pandas DataFrame" +category = "main" optional = false python-versions = ">=3.7, <3.12" files = [ @@ -7505,6 +7753,7 @@ unicode = ["tangled-up-in-unicode (==0.2.0)"] name = "zict" version = "3.0.0" description = "Mutable mapping tools" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7516,6 +7765,7 @@ files = [ name = "zipp" version = "3.16.2" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7530,4 +7780,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "~3.9" -content-hash = "e1777d181b70749a16e4a1b6e46513aee3e5b12164e549da6df0a0ed5bb992ba" +content-hash = "086c38c285571e229f1daefa5cd3b45c0969325136a8af34e7d610ca82183dd6" diff --git a/images/jupyter-singleuser/pyproject.toml b/images/jupyter-singleuser/pyproject.toml index 820345f91e..18afc7066a 100644 --- a/images/jupyter-singleuser/pyproject.toml +++ b/images/jupyter-singleuser/pyproject.toml @@ -1,8 +1,8 @@ [tool.poetry] name = "jupyter-singleuser" -version = "2023.8.1" +version = "2024.2.5" description = "" -authors = ["Andrew Vaccaro "] +authors = ["Soren Spicknall "] [tool.poetry.dependencies] python = "~3.9" @@ -47,6 +47,7 @@ pendulum = "^2.1.2" numba = "^0.56.4" calitp-data-analysis = "2023.9.18" calitp-map-utils = "2023.8.1" +jupyter-book = "1.0.0" [tool.poetry.dev-dependencies] pytest = "^7.2.0" @@ -65,8 +66,7 @@ nbformat = "^5.8.0" papermill = "^2.4.0" python-slugify = "^6.1.1" pyaml = "^21.10.1" -# must wait on https://github.com/pydata/pydata-sphinx-theme/issues/1253 to upgrade -jupyter-book = "^0.12.2" +jupyter-book = "^1.0.0" [build-system] requires = ["poetry-core>=1.0.0"]