From 280c26d23dddd106ee2f14b1da49232eaecaa4af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thor=20=E9=9B=B7=E7=A5=9E=20Schaeff?= <5748289+thorwebdev@users.noreply.github.com> Date: Tue, 26 Mar 2024 18:13:18 +0800 Subject: [PATCH] feat: add amazon bedrock vecs example. (#21963) * feat: add amazon bedrock vecs example. * feat: add Amazon Bedrock guides. * feat: add blogpost. * chore: add video. * Apply suggestions from code review Co-authored-by: Oliver Rice Co-authored-by: Greg Richardson * chore: update example. * chore: updates from review. --------- Co-authored-by: Oliver Rice Co-authored-by: Greg Richardson --- .../NavigationMenu.constants.ts | 8 + apps/docs/content/guides/ai.mdx | 6 + .../semantic-image-search-amazon-titan.mdx | 234 +++++ .../guides/ai/integrations/amazon-bedrock.mdx | 139 +++ ...6-semantic-image-search-amazon-bedrock.mdx | 247 +++++ .../amazon-bedrock-supabase-vecs.png | Bin 0 -> 49419 bytes .../ai/aws_bedrock_image_search/.gitignore | 3 + .../ai/aws_bedrock_image_search/README.md | 41 + .../image_search/main.py | 137 +++ .../aws_bedrock_image_search/images/four.jpg | Bin 0 -> 15933 bytes .../aws_bedrock_image_search/images/one.jpg | Bin 0 -> 22649 bytes .../aws_bedrock_image_search/images/three.jpg | Bin 0 -> 16618 bytes .../aws_bedrock_image_search/images/two.jpg | Bin 0 -> 16837 bytes .../ai/aws_bedrock_image_search/poetry.lock | 925 ++++++++++++++++++ .../aws_bedrock_image_search/pyproject.toml | 21 + .../supabase/.gitignore | 4 + .../supabase/config.toml | 161 +++ .../supabase/seed.sql | 0 .../tests/__init__.py | 0 19 files changed, 1926 insertions(+) create mode 100644 apps/docs/content/guides/ai/examples/semantic-image-search-amazon-titan.mdx create mode 100644 apps/docs/content/guides/ai/integrations/amazon-bedrock.mdx create mode 100644 apps/www/_blog/2024-03-26-semantic-image-search-amazon-bedrock.mdx create mode 100644 apps/www/public/images/blog/getting-started/amazon-bedrock/amazon-bedrock-supabase-vecs.png create mode 100644 examples/ai/aws_bedrock_image_search/.gitignore create mode 100644 examples/ai/aws_bedrock_image_search/README.md create mode 100644 examples/ai/aws_bedrock_image_search/image_search/main.py create mode 100644 examples/ai/aws_bedrock_image_search/images/four.jpg create mode 100644 examples/ai/aws_bedrock_image_search/images/one.jpg create mode 100644 examples/ai/aws_bedrock_image_search/images/three.jpg create mode 100644 examples/ai/aws_bedrock_image_search/images/two.jpg create mode 100644 examples/ai/aws_bedrock_image_search/poetry.lock create mode 100644 examples/ai/aws_bedrock_image_search/pyproject.toml create mode 100644 examples/ai/aws_bedrock_image_search/supabase/.gitignore create mode 100644 examples/ai/aws_bedrock_image_search/supabase/config.toml create mode 100644 examples/ai/aws_bedrock_image_search/supabase/seed.sql create mode 100644 examples/ai/aws_bedrock_image_search/tests/__init__.py diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index c36bc455b6f..ff66fca757a 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -1495,6 +1495,10 @@ export const ai = { name: 'Image search with OpenAI CLIP', url: '/guides/ai/examples/image-search-openai-clip', }, + { + name: 'Semantic search with Amazon Titan', + url: '/guides/ai/examples/semantic-image-search-amazon-titan', + }, { name: 'Building ChatGPT Plugins', url: '/guides/ai/examples/building-chatgpt-plugins', @@ -1525,6 +1529,10 @@ export const ai = { name: 'Roboflow', url: '/guides/ai/integrations/roboflow', }, + { + name: 'Amazon Bedrock', + url: '/guides/ai/integrations/amazon-bedrock', + }, ], }, ], diff --git a/apps/docs/content/guides/ai.mdx b/apps/docs/content/guides/ai.mdx index ba7bcada9b6..8ce2de8c1a9 100644 --- a/apps/docs/content/guides/ai.mdx +++ b/apps/docs/content/guides/ai.mdx @@ -99,6 +99,12 @@ export const integrations = [ 'OpenAI is an AI research and deployment company. Supabase provides a simple way to use OpenAI in your applications.', href: '/guides/ai/examples/building-chatgpt-plugins', }, + { + name: 'Amazon Bedrock', + description: + 'A fully managed service that offers a choice of high-performing foundation models from leading AI companies.', + href: '/guides/ai/amazon-bedrock', + }, { name: 'Hugging Face', description: diff --git a/apps/docs/content/guides/ai/examples/semantic-image-search-amazon-titan.mdx b/apps/docs/content/guides/ai/examples/semantic-image-search-amazon-titan.mdx new file mode 100644 index 00000000000..c2dd616366e --- /dev/null +++ b/apps/docs/content/guides/ai/examples/semantic-image-search-amazon-titan.mdx @@ -0,0 +1,234 @@ +--- +id: 'semantic-image-search-python-amazon-titan' +title: 'Semantic Image Search with Amazon Titan' +description: 'Implement semantic image search with Amazon Titan and Supabase Vector in Python.' +subtitle: 'Implement semantic image search with Amazon Titan and Supabase Vector in Python.' +tocVideo: 'A3uND5sgiO0' +--- + +[Amazon Bedrock](https://aws.amazon.com/bedrock) is a fully managed service that offers a choice of high-performing foundation models (FMs) from leading AI companies like AI21 Labs, Anthropic, Cohere, Meta, Mistral AI, Stability AI, and Amazon. Each model is accessible through a common API which implements a broad set of features to help build generative AI applications with security, privacy, and responsible AI in mind. + +[Amazon Titan](https://aws.amazon.com/bedrock/titan/) is a family of foundation models (FMs) for text and image generation, summarization, classification, open-ended Q&A, information extraction, and text or image search. + +In this guide we'll look at how we can get started with Amazon Bedrock and Supabase Vector in Python using the Amazon Titan multimodal model and the [vecs client](/docs/guides/ai/vecs-python-client). + +You can find the full application code as a Python Poetry project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search). + +## Create a new Python project with Poetry + +[Poetry](https://python-poetry.org/) provides packaging and dependency management for Python. If you haven't already, install poetry via pip: + +```shell +pip install poetry +``` + +Then initialize a new project: + +```shell +poetry new aws_bedrock_image_search +``` + +## Spin up a Postgres Database with pgvector + +If you haven't already, head over to [database.new](https://database.new) and create a new project. Every Supabase project comes with a full Postgres database and the [pgvector extension](/docs/guides/database/extensions/pgvector) preconfigured. + +When creating your project, make sure to note down your database password as you will need it to construct the `DB_URL` in the next step. + +You can find the database connection string in your Supabase Dashboard [database settings](https://supabase.com/dashboard/project/_/settings/database). Select "Use connection pooling" with `Mode: Session` for a direct connection to your Postgres database. It will look something like this: + +```txt +postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres +``` + +## Install the dependencies + +We will need to add the following dependencies to our project: + +- [`vecs`](https://github.com/supabase/vecs#vecs): Supabase Vector Python Client. +- [`boto3`](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html): AWS SDK for Python. +- [`matplotlib`](https://matplotlib.org/): for displaying our image result. + +```shell +poetry add vecs boto3 matplotlib +``` + +## Import the necessary dependencies + +At the top of your main python script, import the dependencies and store your `DB URL` from above in a variable: + +```python +import sys +import boto3 +import vecs +import json +import base64 +from matplotlib import pyplot as plt +from matplotlib import image as mpimg +from typing import Optional + +DB_CONNECTION = "postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres" +``` + +Next, get the [credentials to your AWS account](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html) and instantiate the `boto3` client: + +```python +bedrock_client = boto3.client( + 'bedrock-runtime', + region_name='us-west-2', + # Credentials from your AWS account + aws_access_key_id='', + aws_secret_access_key='', + aws_session_token='', +) +``` + +## Create embeddings for your images + +In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search/images) or you can find license free images on [unsplash](https://unsplash.com). + +To send images to the Amazon Bedrock API we need to need to encode them as `base64` strings. Create the following helper methods: + +```python +def readFileAsBase64(file_path): + """Encode image as base64 string.""" + try: + with open(file_path, "rb") as image_file: + input_image = base64.b64encode(image_file.read()).decode("utf8") + return input_image + except: + print("bad file name") + sys.exit(0) + + +def construct_bedrock_image_body(base64_string): + """Construct the request body. + + https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-mm.html + """ + return json.dumps( + { + "inputImage": base64_string, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + ) + + +def get_embedding_from_titan_multimodal(body): + """Invoke the Amazon Titan Model via API request.""" + response = bedrock_client.invoke_model( + body=body, + modelId="amazon.titan-embed-image-v1", + accept="application/json", + contentType="application/json", + ) + + response_body = json.loads(response.get("body").read()) + print(response_body) + return response_body["embedding"] + + +def encode_image(file_path): + """Generate embedding for the image at file_path.""" + base64_string = readFileAsBase64(file_path) + body = construct_bedrock_image_body(base64_string) + emb = get_embedding_from_titan_multimodal(body) + return emb +``` + +Next, create a `seed` method, which will create a new Supabase Vector Collection, generate embeddings for your images, and upsert the embeddings into your database: + +```python +def seed(): + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + + # get or create a collection of vectors with 1024 dimensions + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Generate image embeddings with Amazon Titan Model + img_emb1 = encode_image('./images/one.jpg') + img_emb2 = encode_image('./images/two.jpg') + img_emb3 = encode_image('./images/three.jpg') + img_emb4 = encode_image('./images/four.jpg') + + # add records to the *images* collection + images.upsert( + records=[ + ( + "one.jpg", # the vector's identifier + img_emb1, # the vector. list or np.array + {"type": "jpg"} # associated metadata + ), ( + "two.jpg", + img_emb2, + {"type": "jpg"} + ), ( + "three.jpg", + img_emb3, + {"type": "jpg"} + ), ( + "four.jpg", + img_emb4, + {"type": "jpg"} + ) + ] + ) + print("Inserted images") + + # index the collection for fast search performance + images.create_index() + print("Created index") +``` + +Add this method as a script in your `pyproject.toml` file: + +```toml +[tool.poetry.scripts] +seed = "image_search.main:seed" +search = "image_search.main:search" +``` + +After activating the virtual environtment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](https://supabase.com/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table. + +## Perform an image search from a text query + +With Supabase Vector we can easily query our embeddings. We can use either an image as the search input or alternatively we can generate an embedding from a string input and use that as the query input: + +```python +def search(query_term: Optional[str] = None): + if query_term is None: + query_term = sys.argv[1] + + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Encode text query + text_emb = get_embedding_from_titan_multimodal(json.dumps( + { + "inputText": query_term, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + )) + + # query the collection filtering metadata for "type" = "jpg" + results = images.query( + data=text_emb, # required + limit=1, # number of records to return + filters={"type": {"$eq": "jpg"}}, # metadata filters + ) + result = results[0] + print(result) + plt.title(result) + image = mpimg.imread('./images/' + result) + plt.imshow(image) + plt.show() +``` + +By limiting the query to one result, we can show the most relevant image to the user. Finally we use `matplotlib` to show the image result to the user. + +That's it, go ahead and test it out by running `poetry run search` and you will be presented with an image of a "bike in front of a red brick wall". + +## Conclusion + +With just a couple of lines of Python you are able to implement image search as well as reverse image search using the Amazon Titan multimodal model and Supabase Vector. diff --git a/apps/docs/content/guides/ai/integrations/amazon-bedrock.mdx b/apps/docs/content/guides/ai/integrations/amazon-bedrock.mdx new file mode 100644 index 00000000000..d18f9a6bc83 --- /dev/null +++ b/apps/docs/content/guides/ai/integrations/amazon-bedrock.mdx @@ -0,0 +1,139 @@ +--- +id: 'ai-amazon-bedrock' +title: 'Amazon Bedrock' +description: 'Learn how to integrate Supabase with Amazon Bedrock, a fully managed service of high-performing foundation models.' +sidebar_label: 'Amazon Bedrock' +tocVideo: 'A3uND5sgiO0' +--- + +[Amazon Bedrock](https://aws.amazon.com/bedrock) is a fully managed service that offers a choice of high-performing foundation models (FMs) from leading AI companies like AI21 Labs, Anthropic, Cohere, Meta, Mistral AI, Stability AI, and Amazon. Each model is accessible through a common API which implements a broad set of features to help build generative AI applications with security, privacy, and responsible AI in mind. + +This guide will walk you through an example using Amazon Bedrock SDK with `vecs`. We will create embeddings using the Amazon Titan Embeddings G1 – Text v1.2 (amazon.titan-embed-text-v1) model, insert these embeddings into a PostgreSQL database using vecs, and then query the collection to find the most similar sentences to a given query sentence. + +## Create an Environment + +First, you need to set up your environment. You will need Python 3.7+ with the `vecs` and `boto3` libraries installed. + +You can install the necessary Python libraries using pip: + +```sh +pip install vecs boto3 +``` + +You'll also need: + +- [Credentials to your AWS account](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html) +- [A Postgres Database with the pgvector extension](hosting.md) + +## Create Embeddings + +Next, we will use Amazon’s Titan Embedding G1 - Text v1.2 model to create embeddings for a set of sentences. + +```python +import boto3 +import vecs +import json + +client = boto3.client( + 'bedrock-runtime', + region_name='us-east-1', + # Credentials from your AWS account + aws_access_key_id='', + aws_secret_access_key='', + aws_session_token='', +) + +dataset = [ + "The cat sat on the mat.", + "The quick brown fox jumps over the lazy dog.", + "Friends, Romans, countrymen, lend me your ears", + "To be or not to be, that is the question.", +] + +embeddings = [] + +for sentence in dataset: + # invoke the embeddings model for each sentence + response = client.invoke_model( + body= json.dumps({"inputText": sentence}), + modelId= "amazon.titan-embed-text-v1", + accept = "application/json", + contentType = "application/json" + ) + # collect the embedding from the response + response_body = json.loads(response["body"].read()) + # add the embedding to the embedding list + embeddings.append((sentence, response_body.get("embedding"), {})) + +``` + +### Store the Embeddings with vecs + +Now that we have our embeddings, we can insert them into a PostgreSQL database using vecs. + +```python +import vecs + +DB_CONNECTION = "postgresql://:@:/" + +# create vector store client +vx = vecs.Client(DB_CONNECTION) + +# create a collection named 'sentences' with 1536 dimensional vectors +# to match the default dimension of the Titan Embeddings G1 - Text model +sentences = vx.get_or_create_collection(name="sentences", dimension=1536) + +# upsert the embeddings into the 'sentences' collection +sentences.upsert(records=embeddings) + +# create an index for the 'sentences' collection +sentences.create_index() +``` + +### Querying for Most Similar Sentences + +Now, we query the `sentences` collection to find the most similar sentences to a sample query sentence. First need to create an embedding for the query sentence. Next, we query the collection we created earlier to find the most similar sentences. + +```python +query_sentence = "A quick animal jumps over a lazy one." + +# create vector store client +vx = vecs.Client(DB_CONNECTION) + +# create an embedding for the query sentence +response = client.invoke_model( + body= json.dumps({"inputText": query_sentence}), + modelId= "amazon.titan-embed-text-v1", + accept = "application/json", + contentType = "application/json" + ) + +response_body = json.loads(response["body"].read()) + +query_embedding = response_body.get("embedding") + +# query the 'sentences' collection for the most similar sentences +results = sentences.query( + data=query_embedding, + limit=3, + include_value = True +) + +# print the results +for result in results: + print(result) +``` + +This returns the most similar 3 records and their distance to the query vector. + +``` +('The quick brown fox jumps over the lazy dog.', 0.27600620558852) +('The cat sat on the mat.', 0.609986272479202) +('To be or not to be, that is the question.', 0.744849503688346) +``` + +## Resources + +- [Amazon Bedrock](https://aws.amazon.com/bedrock) +- [Amazon Titan](https://aws.amazon.com/bedrock/titan) +- [Semantic Image Search with Amazon Titan](/docs/guides/ai/examples/semantic-image-search-amazon-titan) diff --git a/apps/www/_blog/2024-03-26-semantic-image-search-amazon-bedrock.mdx b/apps/www/_blog/2024-03-26-semantic-image-search-amazon-bedrock.mdx new file mode 100644 index 00000000000..6e6b9677b31 --- /dev/null +++ b/apps/www/_blog/2024-03-26-semantic-image-search-amazon-bedrock.mdx @@ -0,0 +1,247 @@ +--- +title: 'Implementing semantic image search with Amazon Titan and Supabase Vector' +description: 'Implementing semantic image search with Amazon Titan and Supabase Vector in Python.' +author: thor_schaeff +image: getting-started/amazon-bedrock/amazon-bedrock-supabase-vecs.png +thumb: getting-started/amazon-bedrock/amazon-bedrock-supabase-vecs.png +categories: + - engineering +tags: + - postgres + - developers + - ai +date: '2024-03-26' +toc_depth: 3 +--- + +[Amazon Bedrock](https://aws.amazon.com/bedrock) is a fully managed service that offers a choice of high-performing foundation models (FMs) from leading AI companies like AI21 Labs, Anthropic, Cohere, Meta, Mistral AI, Stability AI, and Amazon. Each model is accessible through a common API which implements a broad set of features to help build generative AI applications with security, privacy, and responsible AI in mind. + +[Amazon Titan](https://aws.amazon.com/bedrock/titan/) is a family of foundation models (FMs) for text and image generation, summarization, classification, open-ended Q&A, information extraction, and text or image search. + +In this post we'll look at how we can get started with Amazon Bedrock and Supabase Vector in Python using the Amazon Titan multimodal model and the [vecs client](/docs/guides/ai/vecs-python-client). + +You can find the full application code as a Python Poetry project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search). + +## Create a new Python project with Poetry + +[Poetry](https://python-poetry.org/) provides packaging and dependency management for Python. If you haven't already, install poetry via pip: + +```shell +pip install poetry +``` + +Then initialize a new project: + +```shell +poetry new aws_bedrock_image_search +``` + +## Spin up a Postgres Database with pgvector + +If you haven't already, head over to [database.new](https://database.new) and create a new project. Every Supabase project comes with a full Postgres database and the [pgvector extension](/docs/guides/database/extensions/pgvector) preconfigured. + +When creating your project, make sure to note down your database password as you will need it to construct the `DB_URL` in the next step. + +You can find the database connection string in your Supabase Dashboard [database settings](https://supabase.com/dashboard/project/_/settings/database). Select "Use connection pooling" with `Mode: Session` for a direct connection to your Postgres database. It will look something like this: + +```txt +postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres +``` + +## Install the dependencies + +We will need to add the following dependencies to our project: + +- [`vecs`](https://github.com/supabase/vecs#vecs): Supabase Vector Python Client. +- [`boto3`](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html): AWS SDK for Python. +- [`matplotlib`](https://matplotlib.org/): for displaying our image result. + +```shell +poetry add vecs boto3 matplotlib +``` + +## Import the necessary dependencies + +At the top of your main python script, import the dependencies and store your `DB URL` from above in a variable: + +```python +import sys +import boto3 +import vecs +import json +import base64 +from matplotlib import pyplot as plt +from matplotlib import image as mpimg +from typing import Optional + +DB_CONNECTION = "postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@aws-0-[REGION].pooler.supabase.com:5432/postgres" +``` + +Next, get the [credentials to your AWS account](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html) and instantiate the `boto3` client: + +```python +bedrock_client = boto3.client( + 'bedrock-runtime', + region_name='us-west-2', + # Credentials from your AWS account + aws_access_key_id='', + aws_secret_access_key='', + aws_session_token='', +) +``` + +## Create embeddings for your images + +In the root of your project, create a new folder called `images` and add some images. You can use the images from the example project on [GitHub](https://github.com/supabase/supabase/tree/master/examples/ai/aws_bedrock_image_search/images) or you can find license free images on [unsplash](https://unsplash.com). + +To send images to the Amazon Bedrock API we need to need to encode them as `base64` strings. Create the following helper methods: + +```python +def readFileAsBase64(file_path): + """Encode image as base64 string.""" + try: + with open(file_path, "rb") as image_file: + input_image = base64.b64encode(image_file.read()).decode("utf8") + return input_image + except: + print("bad file name") + sys.exit(0) + + +def construct_bedrock_image_body(base64_string): + """Construct the request body. + + https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-mm.html + """ + return json.dumps( + { + "inputImage": base64_string, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + ) + + +def get_embedding_from_titan_multimodal(body): + """Invoke the Amazon Titan Model via API request.""" + response = bedrock_client.invoke_model( + body=body, + modelId="amazon.titan-embed-image-v1", + accept="application/json", + contentType="application/json", + ) + + response_body = json.loads(response.get("body").read()) + print(response_body) + return response_body["embedding"] + + +def encode_image(file_path): + """Generate embedding for the image at file_path.""" + base64_string = readFileAsBase64(file_path) + body = construct_bedrock_image_body(base64_string) + emb = get_embedding_from_titan_multimodal(body) + return emb +``` + +Next, create a `seed` method, which will create a new Supabase Vector Collection, generate embeddings for your images, and upsert the embeddings into your database: + +```python +def seed(): + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + + # get or create a collection of vectors with 1024 dimensions + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Generate image embeddings with Amazon Titan Model + img_emb1 = encode_image('./images/one.jpg') + img_emb2 = encode_image('./images/two.jpg') + img_emb3 = encode_image('./images/three.jpg') + img_emb4 = encode_image('./images/four.jpg') + + # add records to the *images* collection + images.upsert( + records=[ + ( + "one.jpg", # the vector's identifier + img_emb1, # the vector. list or np.array + {"type": "jpg"} # associated metadata + ), ( + "two.jpg", + img_emb2, + {"type": "jpg"} + ), ( + "three.jpg", + img_emb3, + {"type": "jpg"} + ), ( + "four.jpg", + img_emb4, + {"type": "jpg"} + ) + ] + ) + print("Inserted images") + + # index the collection for fast search performance + images.create_index() + print("Created index") +``` + +Add this method as a script in your `pyproject.toml` file: + +```toml +[tool.poetry.scripts] +seed = "image_search.main:seed" +search = "image_search.main:search" +``` + +After activating the virtual environtment with `poetry shell` you can now run your seed script via `poetry run seed`. You can inspect the generated embeddings in your Supabase Dashboard by visiting the [Table Editor](https://supabase.com/dashboard/project/_/editor), selecting the `vecs` schema, and the `image_vectors` table. + +## Perform an image search from a text query + +With Supabase Vector we can easily query our embeddings. We can use either an image as the search input or alternatively we can generate an embedding from a string input and use that as the query input: + +```python +def search(query_term: Optional[str] = None): + if query_term is None: + query_term = sys.argv[1] + + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Encode text query + text_emb = get_embedding_from_titan_multimodal(json.dumps( + { + "inputText": query_term, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + )) + + # query the collection filtering metadata for "type" = "jpg" + results = images.query( + data=text_emb, # required + limit=1, # number of records to return + filters={"type": {"$eq": "jpg"}}, # metadata filters + ) + result = results[0] + print(result) + plt.title(result) + image = mpimg.imread('./images/' + result) + plt.imshow(image) + plt.show() +``` + +By limiting the query to one result, we can show the most relevant image to the user. Finally we use `matplotlib` to show the image result to the user. + +That's it, go ahead and test it out by running `poetry run search` and you will be presented with an image of a "bike in front of a red brick wall". + +## Conclusion + +With just a couple of lines of Python you are able to implement image search as well as reverse image search using the Amazon Titan multimodal model and Supabase Vector. + +## More Supabase + +- [Getting started with Amazon Bedrock and vecs](/docs/guides/ai/integrations/amazon-bedrock) +- [Matryoshka embeddings: faster OpenAI vector search using Adaptive Retrieval](/blog/matryoshka-embeddings) diff --git a/apps/www/public/images/blog/getting-started/amazon-bedrock/amazon-bedrock-supabase-vecs.png b/apps/www/public/images/blog/getting-started/amazon-bedrock/amazon-bedrock-supabase-vecs.png new file mode 100644 index 0000000000000000000000000000000000000000..a4d4dcb1d1e4755afd40df76e40926bb6afa0734 GIT binary patch literal 49419 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

L_~c6N3GzeORABcI*aD4ag{ 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 L0=!g0*Y|$`Fqobb literal 0 HcmV?d00001 diff --git a/examples/ai/aws_bedrock_image_search/.gitignore b/examples/ai/aws_bedrock_image_search/.gitignore new file mode 100644 index 00000000000..c791ff59a37 --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/.gitignore @@ -0,0 +1,3 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] \ No newline at end of file diff --git a/examples/ai/aws_bedrock_image_search/README.md b/examples/ai/aws_bedrock_image_search/README.md new file mode 100644 index 00000000000..705e2d7625b --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/README.md @@ -0,0 +1,41 @@ +# Image Search with Amazon Bedrock and Supabase Vector + +In this example we're implementing image search using the [Amazon Titan Multimodal Embeddings G1](https://aws.amazon.com/bedrock/titan), a set of pre-trained high-performing image, multimodal, and text model, accessible via a fully managed API. + +We're implementing two methods in the [`/image_search/main.py` file](/image_search/main.py): + +1. The `seed` method generates embeddings for the images in the `images` folder and upserts them into a collection in Supabase Vector. +2. The `search` method generates an embedding from the search query and performs a vector similarity search query. + +## Setup + +- Install poetry: `pip install poetry` +- Activate the virtual environment: `poetry shell` + - (to leave the venv just run `exit`) +- Install app dependencies: `poetry install` + +## Run locally + +### Generate the embeddings and seed the collection + +- `supabase start` +- `poetry run seed` +- Check the embeddings stored in the local Supabase Dashboard: http://localhost:54323/project/default/editor > schema: vecs + +### Perform a search + +- `poetry run search "bike in front of red brick wall"` + +## Run on hosted Supabase project + +- Set `DB_CONNECTION` with the connection string from your hosted Supabase Dashboard: https://supabase.com/dashboard/project/_/settings/database > Connection string > URI + +## Attributions + +### Models + +[Amazon Titan Multimodal Embeddings G1](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-mm.html) + +### Images + +Images from https://unsplash.com/license via https://picsum.photos/ diff --git a/examples/ai/aws_bedrock_image_search/image_search/main.py b/examples/ai/aws_bedrock_image_search/image_search/main.py new file mode 100644 index 00000000000..dd83817c9be --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/image_search/main.py @@ -0,0 +1,137 @@ +import sys +import boto3 +import vecs +import json +import base64 +from matplotlib import pyplot as plt +from matplotlib import image as mpimg +from typing import Optional + +DB_CONNECTION = "postgresql://postgres:postgres@localhost:54322/postgres" + +bedrock_client = boto3.client( + 'bedrock-runtime', + region_name='us-west-2', + # Credentials from your AWS account + aws_access_key_id='', + aws_secret_access_key='', + aws_session_token='', +) + + +def readFileAsBase64(file_path): + """Encode image as base64 string.""" + try: + with open(file_path, "rb") as image_file: + input_image = base64.b64encode(image_file.read()).decode("utf8") + return input_image + except: + print("bad file name") + sys.exit(0) + + +def construct_bedrock_image_body(base64_string): + """Construct the request body. + + https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-embed-mm.html + """ + return json.dumps( + { + "inputImage": base64_string, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + ) + + +def get_embedding_from_titan_multimodal(body): + """Invoke the Amazon Titan Model via API request.""" + response = bedrock_client.invoke_model( + body=body, + modelId="amazon.titan-embed-image-v1", + accept="application/json", + contentType="application/json", + ) + + response_body = json.loads(response.get("body").read()) + print(response_body) + return response_body["embedding"] + + +def encode_image(file_path): + """Generate embedding for the image at file_path.""" + base64_string = readFileAsBase64(file_path) + body = construct_bedrock_image_body(base64_string) + emb = get_embedding_from_titan_multimodal(body) + return emb + + +def seed(): + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + + # get or create a collection of vectors with 1024 dimensions + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Generate image embeddings with Amazon Titan Model + img_emb1 = encode_image('./images/one.jpg') + img_emb2 = encode_image('./images/two.jpg') + img_emb3 = encode_image('./images/three.jpg') + img_emb4 = encode_image('./images/four.jpg') + + # add records to the *images* collection + images.upsert( + records=[ + ( + "one.jpg", # the vector's identifier + img_emb1, # the vector. list or np.array + {"type": "jpg"} # associated metadata + ), ( + "two.jpg", + img_emb2, + {"type": "jpg"} + ), ( + "three.jpg", + img_emb3, + {"type": "jpg"} + ), ( + "four.jpg", + img_emb4, + {"type": "jpg"} + ) + ] + ) + print("Inserted images") + + # index the collection for fast search performance + images.create_index() + print("Created index") + + +def search(query_term: Optional[str] = None): + if query_term is None: + query_term = sys.argv[1] + + # create vector store client + vx = vecs.create_client(DB_CONNECTION) + images = vx.get_or_create_collection(name="image_vectors", dimension=1024) + + # Encode text query + text_emb = get_embedding_from_titan_multimodal(json.dumps( + { + "inputText": query_term, + "embeddingConfig": {"outputEmbeddingLength": 1024}, + } + )) + + # query the collection filtering metadata for "type" = "jpg" + results = images.query( + data=text_emb, # required + limit=1, # number of records to return + filters={"type": {"$eq": "jpg"}}, # metadata filters + ) + result = results[0] + print(result) + plt.title(result) + image = mpimg.imread('./images/' + result) + plt.imshow(image) + plt.show() diff --git a/examples/ai/aws_bedrock_image_search/images/four.jpg b/examples/ai/aws_bedrock_image_search/images/four.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91a61643ce6aa86f82c503a84480dc39dde3bb16 GIT binary patch literal 15933 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 E*&bKtK>z>% literal 0 HcmV?d00001 diff --git a/examples/ai/aws_bedrock_image_search/images/three.jpg b/examples/ai/aws_bedrock_image_search/images/three.jpg new file mode 100644 index 0000000000000000000000000000000000000000..537b6bf30e9d633a9376b81717cf725e2088a936 GIT binary patch literal 16618 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

5R+vIh=~ka&6C`lv+wWVa%3!mbIN_yY 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 R>C%5Ul{*H^80dYh{vYP_Sz`bI literal 0 HcmV?d00001 diff --git a/examples/ai/aws_bedrock_image_search/poetry.lock b/examples/ai/aws_bedrock_image_search/poetry.lock new file mode 100644 index 00000000000..46a359e79fb --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/poetry.lock @@ -0,0 +1,925 @@ +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. + +[[package]] +name = "boto3" +version = "1.34.59" +description = "The AWS SDK for Python" +category = "main" +optional = false +python-versions = ">= 3.8" +files = [ + {file = "boto3-1.34.59-py3-none-any.whl", hash = "sha256:004e67b078be58d34469406f93cc8b95bc43becef4bbe44523a0b8e51f84c668"}, + {file = "boto3-1.34.59.tar.gz", hash = "sha256:162edf182e53c198137a28432a626dba103f787a8f5000ed4758b73ccd203fa0"}, +] + +[package.dependencies] +botocore = ">=1.34.59,<1.35.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.10.0,<0.11.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.34.59" +description = "Low-level, data-driven core of boto 3." +category = "main" +optional = false +python-versions = ">= 3.8" +files = [ + {file = "botocore-1.34.59-py3-none-any.whl", hash = "sha256:4bc112dafb1679ab571117593f7656604726a3da0e5ae5bad00ea772fa40e75c"}, + {file = "botocore-1.34.59.tar.gz", hash = "sha256:24edb4d21d7c97dea0c6c4a80d36b3809b1443a30b0bd5e317d6c319dfac823f"}, +] + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = {version = ">=1.25.4,<2.1", markers = "python_version >= \"3.10\""} + +[package.extras] +crt = ["awscrt (==0.19.19)"] + +[[package]] +name = "contourpy" +version = "1.0.7" +description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, + {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"}, + {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"}, + {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"}, + {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"}, + {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"}, + {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"}, + {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"}, + {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"}, + {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"}, + {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"}, + {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"}, + {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"}, + {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"}, + {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"}, + {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"}, + {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"}, + {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"}, + {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"}, + {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"}, + {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"}, + {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"}, + {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"}, + {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"}, + {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"}, +] + +[package.dependencies] +numpy = ">=1.16" + +[package.extras] +bokeh = ["bokeh", "chromedriver", "selenium"] +docs = ["furo", "sphinx-copybutton"] +mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"] +test = ["Pillow", "matplotlib", "pytest"] +test-no-images = ["pytest"] + +[[package]] +name = "cycler" +version = "0.11.0" +description = "Composable style cycles" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] + +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + +[[package]] +name = "flupy" +version = "1.2.0" +description = "Method chaining built on generators" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "flupy-1.2.0.tar.gz", hash = "sha256:12487a008e9744cd35d0f6ea3cfa06f4b2b27cb138bf57d0788f5c26e57afe69"}, +] + +[package.dependencies] +typing_extensions = "*" + +[package.extras] +dev = ["black", "mypy", "pre-commit", "pylint", "pytest", "pytest-benchmark", "pytest-cov"] + +[[package]] +name = "fonttools" +version = "4.39.4" +description = "Tools to manipulate font files" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"}, + {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "scipy"] +lxml = ["lxml (>=4.0,<5)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.0.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "kiwisolver" +version = "1.4.4" +description = "A fast implementation of the Cassowary constraint solver" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, + {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, + {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, + {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, + {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, + {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, + {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] + +[[package]] +name = "matplotlib" +version = "3.7.1" +description = "Python plotting package" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, + {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, + {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, + {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, + {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, + {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, + {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, + {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, + {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, + {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, + {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, + {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, + {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, + {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, + {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, + {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, + {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, + {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, + {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, + {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, + {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.20" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[[package]] +name = "numpy" +version = "1.24.3" +description = "Fundamental package for array computing in Python" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, + {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, + {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, + {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, + {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, + {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, + {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, + {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, + {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, + {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, + {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, + {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, + {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, + {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, + {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, + {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, + {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, + {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, + {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, + {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, + {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, + {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, + {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, + {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, + {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, +] + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + +[[package]] +name = "pgvector" +version = "0.1.8" +description = "pgvector support for Python" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pgvector-0.1.8-py2.py3-none-any.whl", hash = "sha256:99dce3a6580ef73863edb9b8441937671f4e1a09383826e6b0838176cd441a96"}, +] + +[package.dependencies] +numpy = "*" + +[[package]] +name = "pillow" +version = "9.5.0" +description = "Python Imaging Library (Fork)" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, + {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, + {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, + {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, + {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, + {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, + {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, + {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, + {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, + {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, + {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, + {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, + {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, + {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, + {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, + {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, + {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, + {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, + {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, + {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, + {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, + {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, + {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, + {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, + {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, + {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, + {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, + {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, + {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, + {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, + {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "psycopg2-binary" +version = "2.9.9" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, +] + +[[package]] +name = "pyparsing" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +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 = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "s3transfer" +version = "0.10.0" +description = "An Amazon S3 Transfer Manager" +category = "main" +optional = false +python-versions = ">= 3.8" +files = [ + {file = "s3transfer-0.10.0-py3-none-any.whl", hash = "sha256:3cdb40f5cfa6966e812209d0994f2a4709b561c88e90cf00c2696d2df4e56b2e"}, + {file = "s3transfer-0.10.0.tar.gz", hash = "sha256:d0c8bbf672d5eebbe4e57945e23b972d963f07d82f661cabf678a5c88831595b"}, +] + +[package.dependencies] +botocore = ">=1.33.2,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] + +[[package]] +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 = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.28" +description = "Database Abstraction Library" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0b148ab0438f72ad21cb004ce3bdaafd28465c4276af66df3b9ecd2037bf252"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbda76961eb8f27e6ad3c84d1dc56d5bc61ba8f02bd20fcf3450bd421c2fcc9c"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feea693c452d85ea0015ebe3bb9cd15b6f49acc1a31c28b3c50f4db0f8fb1e71"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da98815f82dce0cb31fd1e873a0cb30934971d15b74e0d78cf21f9e1b05953f"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a5adf383c73f2d49ad15ff363a8748319ff84c371eed59ffd0127355d6ea1da"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56856b871146bfead25fbcaed098269d90b744eea5cb32a952df00d542cdd368"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-win32.whl", hash = "sha256:943aa74a11f5806ab68278284a4ddd282d3fb348a0e96db9b42cb81bf731acdc"}, + {file = "SQLAlchemy-2.0.28-cp310-cp310-win_amd64.whl", hash = "sha256:c6c4da4843e0dabde41b8f2e8147438330924114f541949e6318358a56d1875a"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46a3d4e7a472bfff2d28db838669fc437964e8af8df8ee1e4548e92710929adc"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3dd67b5d69794cfe82862c002512683b3db038b99002171f624712fa71aeaa"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61e2e41656a673b777e2f0cbbe545323dbe0d32312f590b1bc09da1de6c2a02"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0315d9125a38026227f559488fe7f7cee1bd2fbc19f9fd637739dc50bb6380b2"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af8ce2d31679006e7b747d30a89cd3ac1ec304c3d4c20973f0f4ad58e2d1c4c9"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81ba314a08c7ab701e621b7ad079c0c933c58cdef88593c59b90b996e8b58fa5"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-win32.whl", hash = "sha256:1ee8bd6d68578e517943f5ebff3afbd93fc65f7ef8f23becab9fa8fb315afb1d"}, + {file = "SQLAlchemy-2.0.28-cp311-cp311-win_amd64.whl", hash = "sha256:ad7acbe95bac70e4e687a4dc9ae3f7a2f467aa6597049eeb6d4a662ecd990bb6"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d3499008ddec83127ab286c6f6ec82a34f39c9817f020f75eca96155f9765097"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b66fcd38659cab5d29e8de5409cdf91e9986817703e1078b2fdaad731ea66f5"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea30da1e76cb1acc5b72e204a920a3a7678d9d52f688f087dc08e54e2754c67"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:124202b4e0edea7f08a4db8c81cc7859012f90a0d14ba2bf07c099aff6e96462"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e23b88c69497a6322b5796c0781400692eca1ae5532821b39ce81a48c395aae9"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b6303bfd78fb3221847723104d152e5972c22367ff66edf09120fcde5ddc2e2"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-win32.whl", hash = "sha256:a921002be69ac3ab2cf0c3017c4e6a3377f800f1fca7f254c13b5f1a2f10022c"}, + {file = "SQLAlchemy-2.0.28-cp312-cp312-win_amd64.whl", hash = "sha256:b4a2cf92995635b64876dc141af0ef089c6eea7e05898d8d8865e71a326c0385"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e91b5e341f8c7f1e5020db8e5602f3ed045a29f8e27f7f565e0bdee3338f2c7"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45c7b78dfc7278329f27be02c44abc0d69fe235495bb8e16ec7ef1b1a17952db"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eba73ef2c30695cb7eabcdb33bb3d0b878595737479e152468f3ba97a9c22a4"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5df5d1dafb8eee89384fb7a1f79128118bc0ba50ce0db27a40750f6f91aa99d5"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2858bbab1681ee5406650202950dc8f00e83b06a198741b7c656e63818633526"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-win32.whl", hash = "sha256:9461802f2e965de5cff80c5a13bc945abea7edaa1d29360b485c3d2b56cdb075"}, + {file = "SQLAlchemy-2.0.28-cp37-cp37m-win_amd64.whl", hash = "sha256:a6bec1c010a6d65b3ed88c863d56b9ea5eeefdf62b5e39cafd08c65f5ce5198b"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:843a882cadebecc655a68bd9a5b8aa39b3c52f4a9a5572a3036fb1bb2ccdc197"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dbb990612c36163c6072723523d2be7c3eb1517bbdd63fe50449f56afafd1133"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7e4baf9161d076b9a7e432fce06217b9bd90cfb8f1d543d6e8c4595627edb9"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0a5354cb4de9b64bccb6ea33162cb83e03dbefa0d892db88a672f5aad638a75"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fffcc8edc508801ed2e6a4e7b0d150a62196fd28b4e16ab9f65192e8186102b6"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aca7b6d99a4541b2ebab4494f6c8c2f947e0df4ac859ced575238e1d6ca5716b"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-win32.whl", hash = "sha256:8c7f10720fc34d14abad5b647bc8202202f4948498927d9f1b4df0fb1cf391b7"}, + {file = "SQLAlchemy-2.0.28-cp38-cp38-win_amd64.whl", hash = "sha256:243feb6882b06a2af68ecf4bec8813d99452a1b62ba2be917ce6283852cf701b"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc4974d3684f28b61b9a90fcb4c41fb340fd4b6a50c04365704a4da5a9603b05"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87724e7ed2a936fdda2c05dbd99d395c91ea3c96f029a033a4a20e008dd876bf"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68722e6a550f5de2e3cfe9da6afb9a7dd15ef7032afa5651b0f0c6b3adb8815d"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328529f7c7f90adcd65aed06a161851f83f475c2f664a898af574893f55d9e53"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:df40c16a7e8be7413b885c9bf900d402918cc848be08a59b022478804ea076b8"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:426f2fa71331a64f5132369ede5171c52fd1df1bd9727ce621f38b5b24f48750"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-win32.whl", hash = "sha256:33157920b233bc542ce497a81a2e1452e685a11834c5763933b440fedd1d8e2d"}, + {file = "SQLAlchemy-2.0.28-cp39-cp39-win_amd64.whl", hash = "sha256:2f60843068e432311c886c5f03c4664acaef507cf716f6c60d5fde7265be9d7b"}, + {file = "SQLAlchemy-2.0.28-py3-none-any.whl", hash = "sha256:78bb7e8da0183a8301352d569900d9d3594c48ac21dc1c2ec6b3121ed8b6c986"}, + {file = "SQLAlchemy-2.0.28.tar.gz", hash = "sha256:dd53b6c4e6d960600fd6532b79ee28e2da489322fcf6648738134587faf767b6"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "typing-extensions" +version = "4.10.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, +] + +[[package]] +name = "urllib3" +version = "2.0.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "vecs" +version = "0.4.3" +description = "pgvector client" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "vecs-0.4.3.tar.gz", hash = "sha256:0a60294143aec43bd0344bb9235b6e57f8f919d102538f6b989d7b85095a31ce"}, +] + +[package.dependencies] +deprecated = ">=1.2.0,<1.3.0" +flupy = ">=1.0.0,<2.0.0" +pgvector = ">=0.1.0,<0.2.0" +psycopg2-binary = ">=2.9.0,<2.10.0" +sqlalchemy = ">=2.0.0,<3.0.0" + +[package.extras] +dev = ["numpy", "parse", "pytest", "pytest-cov"] +docs = ["mike", "mkdocs", "pygments", "pymarkdown", "pymdown-extensions"] +text-embedding = ["sentence-transformers (>=2.0.0,<3.0.0)"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "52193cbe33f6ea90a7284b67ba45e95408eb14efd6f84d50abeafc11fe5889fa" diff --git a/examples/ai/aws_bedrock_image_search/pyproject.toml b/examples/ai/aws_bedrock_image_search/pyproject.toml new file mode 100644 index 00000000000..da8c9af710b --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/pyproject.toml @@ -0,0 +1,21 @@ +[tool.poetry] +name = "image-search" +version = "0.1.0" +description = "Image Search with Supabase Vector" +authors = ["thorwebdev "] +readme = "README.md" +packages = [{include = "image_search"}] + +[tool.poetry.dependencies] +python = "^3.11" +matplotlib = "^3.7.1" +vecs = "^0.4.3" +boto3 = "^1.34.59" + +[tool.poetry.scripts] +seed = "image_search.main:seed" +search = "image_search.main:search" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/examples/ai/aws_bedrock_image_search/supabase/.gitignore b/examples/ai/aws_bedrock_image_search/supabase/.gitignore new file mode 100644 index 00000000000..a3ad88055b7 --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/supabase/.gitignore @@ -0,0 +1,4 @@ +# Supabase +.branches +.temp +.env diff --git a/examples/ai/aws_bedrock_image_search/supabase/config.toml b/examples/ai/aws_bedrock_image_search/supabase/config.toml new file mode 100644 index 00000000000..2af8d3e1813 --- /dev/null +++ b/examples/ai/aws_bedrock_image_search/supabase/config.toml @@ -0,0 +1,161 @@ +# A string used to distinguish different Supabase projects on the same host. Defaults to the +# working directory name when running `supabase init`. +project_id = "aws_bedrock_image_search" + +[api] +enabled = true +# Port to use for the API URL. +port = 54321 +# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API +# endpoints. public and storage are always included. +schemas = ["public", "storage", "graphql_public"] +# Extra schemas to add to the search_path of every request. public is always included. +extra_search_path = ["public", "extensions"] +# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size +# for accidental or malicious requests. +max_rows = 1000 + +[db] +# Port to use for the local database URL. +port = 54322 +# Port used by db diff command to initialize the shadow database. +shadow_port = 54320 +# The database major version to use. This has to be the same as your remote database's. Run `SHOW +# server_version;` on the remote database to check. +major_version = 15 + +[db.pooler] +enabled = false +# Port to use for the local connection pooler. +port = 54329 +# Specifies when a server connection can be reused by other clients. +# Configure one of the supported pooler modes: `transaction`, `session`. +pool_mode = "transaction" +# How many server connections to allow per user/database pair. +default_pool_size = 20 +# Maximum number of client connections allowed. +max_client_conn = 100 + +[realtime] +enabled = true +# Bind realtime via either IPv4 or IPv6. (default: IPv6) +# ip_version = "IPv6" +# The maximum length in bytes of HTTP request headers. (default: 4096) +# max_header_length = 4096 + +[studio] +enabled = true +# Port to use for Supabase Studio. +port = 54323 +# External URL of the API server that frontend connects to. +api_url = "http://127.0.0.1" +# OpenAI API Key to use for Supabase AI in the Supabase Studio. +openai_api_key = "env(OPENAI_API_KEY)" + +# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they +# are monitored, and you can view the emails that would have been sent from the web interface. +[inbucket] +enabled = true +# Port to use for the email testing server web interface. +port = 54324 +# Uncomment to expose additional ports for testing user applications that send emails. +# smtp_port = 54325 +# pop3_port = 54326 + +[storage] +enabled = true +# The maximum file size allowed (e.g. "5MB", "500KB"). +file_size_limit = "50MiB" + +[auth] +enabled = true +# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used +# in emails. +site_url = "http://127.0.0.1:3000" +# A list of *exact* URLs that auth providers are permitted to redirect to post authentication. +additional_redirect_urls = ["https://127.0.0.1:3000"] +# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). +jwt_expiry = 3600 +# If disabled, the refresh token will never expire. +enable_refresh_token_rotation = true +# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds. +# Requires enable_refresh_token_rotation = true. +refresh_token_reuse_interval = 10 +# Allow/disallow new user signups to your project. +enable_signup = true +# Allow/disallow testing manual linking of accounts +enable_manual_linking = false + +[auth.email] +# Allow/disallow new user signups via email to your project. +enable_signup = true +# If enabled, a user will be required to confirm any email change on both the old, and new email +# addresses. If disabled, only the new email is required to confirm. +double_confirm_changes = true +# If enabled, users need to confirm their email address before signing in. +enable_confirmations = false + +# Uncomment to customize email template +# [auth.email.template.invite] +# subject = "You have been invited" +# content_path = "./supabase/templates/invite.html" + +[auth.sms] +# Allow/disallow new user signups via SMS to your project. +enable_signup = true +# If enabled, users need to confirm their phone number before signing in. +enable_confirmations = false +# Template for sending OTP to users +template = "Your code is {{ .Code }} ." + +# Use pre-defined map of phone number to OTP for testing. +[auth.sms.test_otp] +# 4152127777 = "123456" + +# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used. +[auth.hook.custom_access_token] +# enabled = true +# uri = "pg-functions:////" + + +# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`. +[auth.sms.twilio] +enabled = false +account_sid = "" +message_service_sid = "" +# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead: +auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)" + +# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`, +# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`, +# `twitter`, `slack`, `spotify`, `workos`, `zoom`. +[auth.external.apple] +enabled = false +client_id = "" +# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead: +secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)" +# Overrides the default auth redirectUrl. +redirect_uri = "" +# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure, +# or any other third-party OIDC providers. +url = "" + +[analytics] +enabled = false +port = 54327 +vector_port = 54328 +# Configure one of the supported backends: `postgres`, `bigquery`. +backend = "postgres" + +# Experimental features may be deprecated any time +[experimental] +# Configures Postgres storage engine to use OrioleDB (S3) +orioledb_version = "" +# Configures S3 bucket URL, eg. .s3-.amazonaws.com +s3_host = "env(S3_HOST)" +# Configures S3 bucket region, eg. us-east-1 +s3_region = "env(S3_REGION)" +# Configures AWS_ACCESS_KEY_ID for S3 bucket +s3_access_key = "env(S3_ACCESS_KEY)" +# Configures AWS_SECRET_ACCESS_KEY for S3 bucket +s3_secret_key = "env(S3_SECRET_KEY)" diff --git a/examples/ai/aws_bedrock_image_search/supabase/seed.sql b/examples/ai/aws_bedrock_image_search/supabase/seed.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/ai/aws_bedrock_image_search/tests/__init__.py b/examples/ai/aws_bedrock_image_search/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d