From 558cf4d87051ca4ce38bb4d077499de5a34980e4 Mon Sep 17 00:00:00 2001 From: krokoko Date: Mon, 10 Feb 2025 00:55:06 -0600 Subject: [PATCH 1/4] chore(knowledgebase): add support for vector type --- .projen/deps.json | 4 +- .projenrc.ts | 2 +- CHANGELOG.md | 4 + DEVELOPER_GUIDE.md | 2 +- apidocs/namespaces/bedrock/README.md | 1 + .../bedrock/classes/BedrockFoundationModel.md | 6 + .../bedrock/enumerations/VectorType.md | 28 +++++ .../interfaces/BedrockFoundationModelProps.md | 8 ++ .../interfaces/VectorKnowledgeBaseProps.md | 14 +++ package.json | 6 +- src/cdk-lib/bedrock/README.md | 42 +++++++ .../knowledge-bases/vector-knowledge-base.ts | 49 +++++++- src/cdk-lib/bedrock/models.ts | 29 +++++ test/cdk-lib/bedrock/knowledge-base.test.ts | 117 ++++++++++++++---- ...a-index-data-loader-integ-test.assets.json | 4 +- ...index-data-loader-integ-test.template.json | 30 ++--- yarn.lock | 16 +-- 17 files changed, 299 insertions(+), 63 deletions(-) create mode 100644 apidocs/namespaces/bedrock/enumerations/VectorType.md diff --git a/.projen/deps.json b/.projen/deps.json index 161b168f..d7aed525 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -6,7 +6,7 @@ }, { "name": "@aws-cdk/integ-tests-alpha", - "version": "2.177.0-alpha.0", + "version": "2.178.0-alpha.0", "type": "build" }, { @@ -142,7 +142,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.177.0", + "version": "^2.178.0", "type": "peer" }, { diff --git a/.projenrc.ts b/.projenrc.ts index 21ba50aa..d0dcfc6f 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -30,7 +30,7 @@ import { const GITHUB_USER = 'awslabs'; const PUBLICATION_NAMESPACE = 'cdklabs'; const PROJECT_NAME = 'generative-ai-cdk-constructs'; -const CDK_VERSION: string = '2.177.0'; +const CDK_VERSION: string = '2.178.0'; function camelCaseIt(input: string): string { // Hypens and dashes to spaces and then CamelCase... diff --git a/CHANGELOG.md b/CHANGELOG.md index f92a76cc..bb2b1984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# CDK Generative AI Constructs V0.1.293 (2025-02-10) + +Based on CDK library version 2.178.0 + # CDK Generative AI Constructs V0.1.291 (2025-01-26) Based on CDK library version 2.177.0 diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index c1bb810b..d6f5206f 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -16,7 +16,7 @@ Default output format [None]: json ``` - [Node](https://nodejs.org/en) >= v20.9.0 -- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.177.0) >= 2.177.0 +- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.178.0) >= 2.178.0 - [Python](https://www.python.org/downloads/) >=3.9 - [Projen](https://github.com/projen/projen) >= 0.91.5 - [Yarn](https://classic.yarnpkg.com/lang/en/docs/cli/install/) >= 1.22.19 diff --git a/apidocs/namespaces/bedrock/README.md b/apidocs/namespaces/bedrock/README.md index df1423dc..93245558 100644 --- a/apidocs/namespaces/bedrock/README.md +++ b/apidocs/namespaces/bedrock/README.md @@ -35,6 +35,7 @@ - [SharePointDataSourceAuthType](enumerations/SharePointDataSourceAuthType.md) - [SharePointObjectType](enumerations/SharePointObjectType.md) - [TransformationStep](enumerations/TransformationStep.md) +- [VectorType](enumerations/VectorType.md) ## Classes diff --git a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md index f8273a75..3f890ecc 100644 --- a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md +++ b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md @@ -65,6 +65,12 @@ The ARN of the Bedrock invokable abstraction. *** +### supportedVectorType? + +> `readonly` `optional` **supportedVectorType**: [`VectorType`](../enumerations/VectorType.md)[] + +*** + ### supportsAgents > `readonly` **supportsAgents**: `boolean` diff --git a/apidocs/namespaces/bedrock/enumerations/VectorType.md b/apidocs/namespaces/bedrock/enumerations/VectorType.md new file mode 100644 index 00000000..ae348210 --- /dev/null +++ b/apidocs/namespaces/bedrock/enumerations/VectorType.md @@ -0,0 +1,28 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / VectorType + +# Enumeration: VectorType + +The data type for the vectors when using a model to convert text into vector embeddings. +The model must support the specified data type for vector embeddings. Floating-point (float32) +is the default data type, and is supported by most models for vector embeddings. See Supported +embeddings models for information on the available models and their vector data types. + +## Enumeration Members + +### BINARY + +> **BINARY**: `"BINARY"` + +`BINARY` convert the data to binary vector embeddings (less precise, but less costly). + +*** + +### FLOATING\_POINT + +> **FLOATING\_POINT**: `"FLOAT32"` + +`FLOATING_POINT` convert the data to floating-point (float32) vector embeddings (more precise, but more costly). diff --git a/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md b/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md index 1fb57248..63e868a8 100644 --- a/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md +++ b/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md @@ -8,6 +8,14 @@ ## Properties +### supportedVectorType? + +> `readonly` `optional` **supportedVectorType**: [`VectorType`](../enumerations/VectorType.md)[] + +Embeddings models have different supported vector types + +*** + ### supportsAgents? > `readonly` `optional` **supportsAgents**: `boolean` diff --git a/apidocs/namespaces/bedrock/interfaces/VectorKnowledgeBaseProps.md b/apidocs/namespaces/bedrock/interfaces/VectorKnowledgeBaseProps.md index 75454ef7..2b2136b0 100644 --- a/apidocs/namespaces/bedrock/interfaces/VectorKnowledgeBaseProps.md +++ b/apidocs/namespaces/bedrock/interfaces/VectorKnowledgeBaseProps.md @@ -149,3 +149,17 @@ type `VectorCollection`, `RedisEnterpriseVectorStore`, ```ts - A new OpenSearch Serverless vector collection is created. ``` + +*** + +### vectorType? + +> `readonly` `optional` **vectorType**: [`VectorType`](../enumerations/VectorType.md) + +The vector type to store vector embeddings. + +#### Default + +```ts +- VectorType.FLOATING_POINT +``` diff --git a/package.json b/package.json index 437e96a9..2eb8ba19 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ }, "devDependencies": { "@aws-cdk/assert": "^2.68.0", - "@aws-cdk/integ-tests-alpha": "2.177.0-alpha.0", + "@aws-cdk/integ-tests-alpha": "2.178.0-alpha.0", "@commitlint/config-conventional": "^18.6.3", "@mrgrain/jsii-struct-builder": "^0.7.43", "@stylistic/eslint-plugin": "^2", @@ -88,7 +88,7 @@ "@typescript-eslint/eslint-plugin": "^8", "@typescript-eslint/parser": "^8", "aws-cdk": "^2", - "aws-cdk-lib": "2.177.0", + "aws-cdk-lib": "2.178.0", "aws-sdk-mock": "^5.9.0", "commit-and-tag-version": "^12", "commitlint": "^18.6.1", @@ -113,7 +113,7 @@ "typescript": "^5.7.3" }, "peerDependencies": { - "aws-cdk-lib": "^2.177.0", + "aws-cdk-lib": "^2.178.0", "constructs": "^10.3.0" }, "dependencies": { diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index 8b8a776c..b2bcd537 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -60,6 +60,7 @@ The resource accepts an `instruction` prop that is provided to any Bedrock Agent |---|---|---|---| | embeddingsModel | BedrockFoundationModel | Yes | The embeddings model for the knowledge base | | name | string | No | The name of the knowledge base | +| vectorType | VectorType | No | The vector type to store vector embeddings | | description | string | No | The description of the knowledge base | | instruction | string | No | Instructions for agents based on the design and type of information of the Knowledge Base that will impact how Agents interact with the Knowledge Base | | existingRole | iam.IRole | No | Existing IAM role with a policy statement granting permission to invoke the specific embeddings model | @@ -378,6 +379,47 @@ bedrock.S3DataSource(self, 'DataSource', ) ``` +#### Vector Knowledge Base - Vector Type + +The data type for the vectors when using a model to convert text into vector embeddings. Embeddings type may impact the availability of some embeddings models and vector stores. The following vector types are available: + +- Floating point: More precise vector representation of the text, but more costly in storage. +- Binary: Not as precise vector representation of the text, but not as costly in storage as a standard floating-point (float32). Not all embedding models and vector stores support binary embeddings + +See [Supported embeddings models](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-supported.html) for information on the available models and their vector data types. + +Typescript + +```ts +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-bedrock-data-sources-integ-test'); + +const kb = new VectorKnowledgeBase(stack, 'MyKnowledgeBase', { + name: 'MyKnowledgeBase', + vectorType: bedrock.VectorType.BINARY, + embeddingsModel: BedrockFoundationModel.COHERE_EMBED_MULTILINGUAL_V3, +}); +``` + +Python + +```python + +from aws_cdk import ( + aws_s3 as s3, +) +from cdklabs.generative_ai_cdk_constructs import ( + bedrock +) + +kb = bedrock.VectorKnowledgeBase(self, 'KnowledgeBase', + name= 'MyKnowledgeBase', + vector_type= bedrock.VectorType.BINARY, + embeddings_model= bedrock.BedrockFoundationModel.COHERE_EMBED_MULTILINGUAL_V3, +) +``` + + #### Vector Knowledge Base - Data Sources Data sources are the various repositories or systems from which information is extracted and ingested into the diff --git a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts index 681c4f58..86e7e817 100644 --- a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts +++ b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts @@ -33,7 +33,7 @@ import { S3DataSource, S3DataSourceAssociationProps } from '../data-sources/s3-d import { SalesforceDataSource, SalesforceDataSourceAssociationProps } from '../data-sources/salesforce-data-source'; import { SharePointDataSource, SharePointDataSourceAssociationProps } from '../data-sources/sharepoint-data-source'; import { WebCrawlerDataSource, WebCrawlerDataSourceAssociationProps } from '../data-sources/web-crawler-data-source'; -import { BedrockFoundationModel } from '../models'; +import { BedrockFoundationModel, VectorType } from '../models'; /****************************************************************************** * ENUMS @@ -212,6 +212,13 @@ export interface VectorKnowledgeBaseProps extends CommonKnowledgeBaseProps { */ readonly embeddingsModel: BedrockFoundationModel; + /** + * The vector type to store vector embeddings. + * + * @default - VectorType.FLOATING_POINT + */ + readonly vectorType?: VectorType; + /** * The name of the vector index. * If vectorStore is not of type `VectorCollection`, @@ -361,6 +368,7 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { // Set properties or defaults // ------------------------------------------------------ const embeddingsModel = props.embeddingsModel; + const vectorType = props.vectorType ?? VectorType.FLOATING_POINT; const indexName = props.indexName ?? 'bedrock-knowledge-base-default-index'; const vectorField = props.vectorField ?? 'bedrock-knowledge-base-default-vector'; const textField = 'AMAZON_BEDROCK_TEXT_CHUNK'; @@ -370,7 +378,7 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { //this.knowledgeBaseState = props.knowledgeBaseState ?? 'ENABLED'; this.instruction = props.instruction; - validateModel(embeddingsModel); + validateModel(embeddingsModel, vectorType); validateVectorIndex(props.vectorStore, props.vectorIndex, props.vectorField, props.indexName); if (props.vectorIndex) { validateIndexParameters(props.vectorIndex, indexName, vectorField); @@ -428,6 +436,10 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { this.handleOpenSearchDefaultVectorCollection()); } + // perform this validation after the vector store is handled since if the user + // doesn't provide one, the method above will create it + validateVectorType(this.vectorStore, vectorType); + /** * We need to add `secretsmanager:GetSecretValue` to the role * of the knowledge base if we use data sources @@ -521,6 +533,7 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { : metadataField, }; + // ------------------------------------------------------ // L1 Instantiation // ------------------------------------------------------ @@ -532,9 +545,14 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { // Used this approach as if property is specified on models that do not // support configurable dimensions CloudFormation throws an error at runtime embeddingModelConfiguration: - embeddingsModel.modelId === 'amazon.titan-embed-text-v2:0' - ? { bedrockEmbeddingModelConfiguration: { dimensions: embeddingsModel.vectorDimensions } } - : undefined, + { + bedrockEmbeddingModelConfiguration: embeddingsModel.modelId === 'amazon.titan-embed-text-v2:0' + ? { + dimensions: embeddingsModel.vectorDimensions, + embeddingDataType: vectorType, + } + : { embeddingDataType: vectorType }, + }, }, }, name: this.name, @@ -692,10 +710,29 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { * * @internal This is an internal core function and should not be called directly. */ -function validateModel(foundationModel: BedrockFoundationModel) { +function validateModel(foundationModel: BedrockFoundationModel, vectorType: VectorType) { if (!foundationModel.supportsKnowledgeBase) { throw new Error(`The model ${foundationModel} is not supported by Bedrock Knowledge Base.`); } + if (foundationModel.supportedVectorType && !foundationModel.supportedVectorType.includes(vectorType)) { + throw new Error(`The vector type ${vectorType} is not supported by the model ${foundationModel}.`); + } +} + +/** + * Validate that the storage configuration can use the selected vector type. + * It prevents the use of vector types with vector stores that do not support them, + * thereby avoiding potential runtime errors. + * + * @internal This is an internal core function and should not be called directly. + */ +function validateVectorType(vectorStore: any, vectorType: VectorType) { + if (!(vectorStore instanceof VectorCollection) && (vectorType == VectorType.BINARY)) { + console.log(vectorStore); + throw new Error( + 'Amazon OpenSearch Serverless is currently the only vector store that supports storing binary vectors.', + ); + } } /** diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index fb350049..d6135c9f 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -16,6 +16,23 @@ import { IModel, FoundationModel, FoundationModelIdentifier } from 'aws-cdk-lib/ import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; import { IConstruct } from 'constructs'; +/** + * The data type for the vectors when using a model to convert text into vector embeddings. + * The model must support the specified data type for vector embeddings. Floating-point (float32) + * is the default data type, and is supported by most models for vector embeddings. See Supported + * embeddings models for information on the available models and their vector data types. + */ +export enum VectorType { + /** + * `FLOATING_POINT` convert the data to floating-point (float32) vector embeddings (more precise, but more costly). + */ + FLOATING_POINT = 'FLOAT32', + /** + * `BINARY` convert the data to binary vector embeddings (less precise, but less costly). + */ + BINARY = 'BINARY', +} + /** * Represents an Amazon Bedrock abstraction on which you can * run the `Invoke` API. This can be a Foundational Model, @@ -56,6 +73,10 @@ export interface BedrockFoundationModelProps { * Only applicable for embedding models. */ readonly vectorDimensions?: number; + /** + * Embeddings models have different supported vector types + */ + readonly supportedVectorType?: VectorType[]; } /** @@ -94,21 +115,25 @@ export class BedrockFoundationModel implements IInvokable { public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel('amazon.titan-embed-text-v1', { supportsKnowledgeBase: true, vectorDimensions: 1536, + supportedVectorType: [VectorType.FLOATING_POINT], }); public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 1024, + supportedVectorType: [VectorType.FLOATING_POINT, VectorType.BINARY], }); public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 512, + supportedVectorType: [VectorType.FLOATING_POINT, VectorType.BINARY], }); public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 256, + supportedVectorType: [VectorType.FLOATING_POINT, VectorType.BINARY], }); /**************************************************************************** * ANTHROPIC @@ -161,11 +186,13 @@ export class BedrockFoundationModel implements IInvokable { public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel('cohere.embed-english-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, + supportedVectorType: [VectorType.FLOATING_POINT, VectorType.BINARY], }); public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel('cohere.embed-multilingual-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, + supportedVectorType: [VectorType.FLOATING_POINT, VectorType.BINARY], }); /**************************************************************************** @@ -220,6 +247,7 @@ export class BedrockFoundationModel implements IInvokable { public readonly supportsCrossRegion: boolean; public readonly vectorDimensions?: number; public readonly supportsKnowledgeBase: boolean; + public readonly supportedVectorType?: VectorType[]; constructor(value: string, props: BedrockFoundationModelProps = {}) { this.modelId = value; this.modelArn = Arn.format({ @@ -236,6 +264,7 @@ export class BedrockFoundationModel implements IInvokable { this.supportsAgents = props.supportsAgents ?? false; this.vectorDimensions = props.vectorDimensions; this.supportsKnowledgeBase = props.supportsKnowledgeBase ?? false; + this.supportedVectorType = props.supportedVectorType; } toString(): string { diff --git a/test/cdk-lib/bedrock/knowledge-base.test.ts b/test/cdk-lib/bedrock/knowledge-base.test.ts index a3386e32..01ed5999 100644 --- a/test/cdk-lib/bedrock/knowledge-base.test.ts +++ b/test/cdk-lib/bedrock/knowledge-base.test.ts @@ -20,7 +20,7 @@ import { Annotations, Match, Template } from 'aws-cdk-lib/assertions'; import { AwsSolutionsChecks } from 'cdk-nag'; import { AmazonAuroraVectorStore } from '../../../src/cdk-lib/amazonaurora'; import { VectorKnowledgeBase } from '../../../src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base'; -import { BedrockFoundationModel } from '../../../src/cdk-lib/bedrock/models'; +import { BedrockFoundationModel, VectorType } from '../../../src/cdk-lib/bedrock/models'; import { VectorCollection } from '../../../src/cdk-lib/opensearchserverless'; import { PineconeVectorStore } from '../../../src/cdk-lib/pinecone'; @@ -32,7 +32,11 @@ describe('VectorKnowledgeBase', () => { let modelVectorDimension: number; beforeAll(() => { - app = new cdk.App(); + app = new cdk.App({ + context: { + '@aws-cdk/core:stackResourceLimit': 0, + }, + }); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); stack = new cdk.Stack(app, 'test-stack', { env: { @@ -153,12 +157,6 @@ describe('VectorKnowledgeBase', () => { }, }), ); - // const policyDocument = knowledgeBase.role.?.toJSON(); - // expect(policyDocument).toBeDefined(); - // expect(policyDocument.Statement).toHaveLength(2); - // expect(policyDocument.Statement[0].Action).toContain('sts:AssumeRole'); - // expect(policyDocument.Statement[0].Principal).toHaveProperty('Service'); - // expect(policyDocument.Statement[0].Principal.Service).toContain('bedrock.amazonaws.com'); }); test('Should throw error when vectorStore is not VectorCollection and indexName is provided', () => { @@ -233,15 +231,41 @@ describe('VectorKnowledgeBase', () => { expect(knowledgeBase.vectorStore).toBe(vectorStore); }); + test('Vector store with unsupported vector type', () => { + const model = BedrockFoundationModel.COHERE_EMBED_ENGLISH_V3; + const vectorStore = new AmazonAuroraVectorStore(stack, 'AuroraVectorStore22', { + embeddingsModelVectorDimension: modelVectorDimension, + }); + + expect(() => { + new VectorKnowledgeBase(stack, 'AuroraKnowledgeBase2', { + embeddingsModel: model, + vectorStore: vectorStore, + vectorType: VectorType.BINARY, + }); + }).toThrow(); + }); + + test('Embedding model with unsupported vector type', () => { + const model = BedrockFoundationModel.TITAN_EMBED_TEXT_V1; + + expect(() => { + new VectorKnowledgeBase(stack, 'OSS22', { + embeddingsModel: model, + vectorType: VectorType.BINARY, + }); + }).toThrow(); + }); + test('No unsuppressed Errors', () => { const errors = Annotations.fromStack(stack).findError('*', Match.stringLikeRegexp('AwsSolutions-.*')); const errorData = errors.map(error => error.entry.data); expect(errorData).toHaveLength(2); // AwsSolutions-IAM4 and AwsSolutions-IAM5 }); - test('Knowledge Base with Embedding Model NOT supporting Configurable Dimensions', () => { + test('Knowledge Base with Embedding Model NOT supporting Configurable Dimensions and floating point', () => { //GIVEN - new VectorKnowledgeBase(stack, 'AuroraDefaultKnowledgeBaseTitan1024', { + new VectorKnowledgeBase(stack, 'DefaultKnowledgeBaseTitan1024FP', { embeddingsModel: BedrockFoundationModel.COHERE_EMBED_MULTILINGUAL_V3, }); //THEN @@ -250,18 +274,72 @@ describe('VectorKnowledgeBase', () => { KnowledgeBaseConfiguration: { Type: 'VECTOR', VectorKnowledgeBaseConfiguration: { - EmbeddingModelConfiguration: ABSENT, + EmbeddingModelConfiguration: { + BedrockEmbeddingModelConfiguration: { + Dimensions: ABSENT, + EmbeddingDataType: 'FLOAT32', + }, + }, }, }, }), ); }); - test('Knowledge Base with Embedding Model supporting Configurable Dimensions', () => { + test('Knowledge Base with Embedding Model NOT supporting Configurable Dimensions and binary', () => { //GIVEN - new VectorKnowledgeBase(stack, 'AuroraDefaultKnowledgeBaseTitan512', { + new VectorKnowledgeBase(stack, 'AuroraDefaultKnowledgeBaseTitan1024Binary', { + embeddingsModel: BedrockFoundationModel.COHERE_EMBED_MULTILINGUAL_V3, + vectorType: VectorType.BINARY, + }); + //THEN + cdkExpect(stack).to( + haveResourceLike('AWS::Bedrock::KnowledgeBase', { + KnowledgeBaseConfiguration: { + Type: 'VECTOR', + VectorKnowledgeBaseConfiguration: { + EmbeddingModelConfiguration: { + BedrockEmbeddingModelConfiguration: { + Dimensions: ABSENT, + EmbeddingDataType: 'BINARY', + }, + }, + }, + }, + }), + ); + }); + + test('Knowledge Base with Embedding Model supporting Configurable Dimensions and floating point', () => { + //GIVEN + new VectorKnowledgeBase(stack, 'AuroraDefaultKnowledgeBaseTitan512FP', { + embeddingsModel: BedrockFoundationModel.TITAN_EMBED_TEXT_V2_512, + }); + //THEN + cdkExpect(stack).to( + haveResourceLike('AWS::Bedrock::KnowledgeBase', { + KnowledgeBaseConfiguration: { + Type: 'VECTOR', + VectorKnowledgeBaseConfiguration: { + EmbeddingModelConfiguration: { + BedrockEmbeddingModelConfiguration: { + Dimensions: 512, + EmbeddingDataType: 'FLOAT32', + }, + }, + }, + }, + }), + ); + }); + + test('Knowledge Base with Embedding Model supporting Configurable Dimensions and Binary', () => { + //GIVEN + new VectorKnowledgeBase(stack, 'AuroraDefaultKnowledgeBaseTitan512Binary', { embeddingsModel: BedrockFoundationModel.TITAN_EMBED_TEXT_V2_512, + vectorType: VectorType.BINARY, }); + console.log(stack.toJsonString); //THEN cdkExpect(stack).to( haveResourceLike('AWS::Bedrock::KnowledgeBase', { @@ -271,6 +349,7 @@ describe('VectorKnowledgeBase', () => { EmbeddingModelConfiguration: { BedrockEmbeddingModelConfiguration: { Dimensions: 512, + EmbeddingDataType: 'BINARY', }, }, }, @@ -313,17 +392,5 @@ describe('VectorKnowledgeBase', () => { expect(s3datasource.dataSourceType).toEqual('S3'); expect(s3datasource.knowledgeBase.knowledgeBaseId).toEqual('OVGH4TEBDH'); cdkExpect(stack).to(haveResource('AWS::Bedrock::DataSource')); - - // console.log(Template.fromStack(stack).toJSON) - - // Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { - // KnowledgeBaseId: 'OVGH4TEBDH', - // Name: 'TestDataSourceS3', - // DataSourceConfiguration: { - // S3Configuration: { - // BucketArn: 'arn:aws:s3:::aws-cdk-bedrock-test-bucket-83908e77-cdxrc7lilg6v' - // }, - // }, - // }); }); }); diff --git a/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.assets.json b/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.assets.json index f3cd84dc..af27b02a 100644 --- a/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.assets.json +++ b/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.assets.json @@ -14,7 +14,7 @@ } } }, - "51c815aa4873ecd577f19e12f0731bf14f73527e5a03b65d82151ef0488c5b74": { + "420049665cd9be064eb11c2119c1a399770c43becb751ab88308733c3a556f79": { "source": { "path": "aws-llama-index-data-loader-integ-test.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "51c815aa4873ecd577f19e12f0731bf14f73527e5a03b65d82151ef0488c5b74.json", + "objectKey": "420049665cd9be064eb11c2119c1a399770c43becb751ab88308733c3a556f79.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.template.json b/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.template.json index 98384213..3f7c8f0f 100644 --- a/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.template.json +++ b/test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/aws-llama-index-data-loader.integ.snapshot/aws-llama-index-data-loader-integ-test.template.json @@ -3202,17 +3202,6 @@ "Properties": { "PolicyDocument": { "Statement": [ - { - "Action": "sns:Publish", - "Effect": "Allow", - "Principal": { - "Service": "s3.amazonaws.com" - }, - "Resource": { - "Ref": "testTopic20AA7407" - }, - "Sid": "0" - }, { "Action": "sns:Publish", "Condition": { @@ -3227,6 +3216,17 @@ }, "Sid": "AllowPublishThroughSSLOnly" }, + { + "Action": "sns:Publish", + "Effect": "Allow", + "Principal": { + "Service": "s3.amazonaws.com" + }, + "Resource": { + "Ref": "testTopic20AA7407" + }, + "Sid": "1" + }, { "Action": "sns:Publish", "Condition": { @@ -3573,10 +3573,10 @@ "value": "nodejs20.x" }, "cn-north-1": { - "value": "nodejs18.x" + "value": "nodejs20.x" }, "cn-northwest-1": { - "value": "nodejs18.x" + "value": "nodejs20.x" }, "eu-central-1": { "value": "nodejs20.x" @@ -3627,10 +3627,10 @@ "value": "nodejs20.x" }, "us-gov-east-1": { - "value": "nodejs18.x" + "value": "nodejs20.x" }, "us-gov-west-1": { - "value": "nodejs18.x" + "value": "nodejs20.x" }, "us-iso-east-1": { "value": "nodejs18.x" diff --git a/yarn.lock b/yarn.lock index 243a3fc9..9bbe1b7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,10 +71,10 @@ string-width "^4.2.3" table "^6.8.1" -"@aws-cdk/integ-tests-alpha@2.177.0-alpha.0": - version "2.177.0-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.177.0-alpha.0.tgz#f4f642c56c29080f5b10db923be1ee1dce5ffc0d" - integrity sha512-bvvlfjtd8bYVLieiLbzIK7Ln3UG2GxAM/JybYZVRSiSLolJgtwejAQObU2aLfhlpKPucwQGRyqPQ5UYucsV8Mg== +"@aws-cdk/integ-tests-alpha@2.178.0-alpha.0": + version "2.178.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.178.0-alpha.0.tgz#851cd21a502c430122068600fb63098c55dbf34e" + integrity sha512-IjnhNGLBCpn1kTsuL1xGdGLTjBbGVosRN8HatOpJwsyhvVt0VOF/24hxT3dQQ9k0c7XQmk9CzsckhZqvH5ONyg== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.26.2": version "7.26.2" @@ -1524,10 +1524,10 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.177.0: - version "2.177.0" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.177.0.tgz#dd161eb9b3fca56d0677c903ff758780a3eeb974" - integrity sha512-nTnHAwjZaPJ5gfJjtzE/MyK6q0a66nWthoJl7l8srucRb+I30dczhbbXor6QCdVpJaTRAEliMOMq23aglsAQbg== +aws-cdk-lib@2.178.0: + version "2.178.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.178.0.tgz#e6ed362fec2008466cd8ca7ddcc57f8094c1f297" + integrity sha512-rk0nmSa6uO1k15wH/je3yHup+oW5p0MMPGL9edSf4IG8YZbwAOrFYcQ6CtXieW2ags2JLtUThbqIxOIQWWQaaw== dependencies: "@aws-cdk/asset-awscli-v1" "^2.2.208" "@aws-cdk/asset-kubectl-v20" "^2.1.3" From c5814aa2d91eee8490c6a24d42629d042c996b0a Mon Sep 17 00:00:00 2001 From: krokoko Date: Mon, 10 Feb 2025 11:59:51 -0600 Subject: [PATCH 2/4] chore(oss): update vector index --- .../interfaces/VectorIndexProps.md | 12 ++++++++++++ .../custom_resources/opensearch_index.py | 17 +++++++++++++++-- .../knowledge-bases/vector-knowledge-base.ts | 2 ++ .../opensearch-vectorindex/vector-index.ts | 13 +++++++++++++ .../opensearch-vectorindex/vector-index.test.ts | 2 ++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apidocs/namespaces/opensearch_vectorindex/interfaces/VectorIndexProps.md b/apidocs/namespaces/opensearch_vectorindex/interfaces/VectorIndexProps.md index 0348d3ac..e1079f40 100644 --- a/apidocs/namespaces/opensearch_vectorindex/interfaces/VectorIndexProps.md +++ b/apidocs/namespaces/opensearch_vectorindex/interfaces/VectorIndexProps.md @@ -32,6 +32,12 @@ The OpenSearch Vector Collection. *** +### distanceType + +> `readonly` **distanceType**: `string` + +*** + ### indexName > `readonly` **indexName**: `string` @@ -48,6 +54,12 @@ The metadata management fields. *** +### precision + +> `readonly` **precision**: `string` + +*** + ### vectorDimensions > `readonly` **vectorDimensions**: `number` diff --git a/lambda/opensearch-serverless-custom-resources/custom_resources/opensearch_index.py b/lambda/opensearch-serverless-custom-resources/custom_resources/opensearch_index.py index 009fcab3..f06a9a4c 100644 --- a/lambda/opensearch-serverless-custom-resources/custom_resources/opensearch_index.py +++ b/lambda/opensearch-serverless-custom-resources/custom_resources/opensearch_index.py @@ -51,6 +51,8 @@ class AnalyzerProperties(TypedDict): class VectorIndexProperties(TypedDict): Endpoint: str + Precision: str + DistanceType: str IndexName: str VectorField: str Dimensions: int | str @@ -70,6 +72,10 @@ def validate_event(event: CustomResourceRequest[VectorIndexProperties]) -> bool: raise ValueError("VectorField is required") if event["ResourceProperties"]["Dimensions"] is None: raise ValueError("Dimensions is required") + if event["ResourceProperties"]["Precision"] is None: + raise ValueError("Precision is required") + if event["ResourceProperties"]["DistanceType"] is None: + raise ValueError("DistanceType is required") if isinstance(int(event["ResourceProperties"]["Dimensions"]), int) is False: raise ValueError("Dimensions must be an integer") if event["ResourceProperties"]["MetadataManagement"] is None: @@ -125,6 +131,8 @@ def connect_opensearch(endpoint: str) -> OpenSearch: def create_mapping( vector_field: str, dimensions: int, + precision: str, + distance_type: str, metadata_management: Sequence[MetadataManagementField], ) -> dict: mapping = { @@ -132,9 +140,10 @@ def create_mapping( vector_field: { "type": "knn_vector", "dimension": dimensions, + "data_type": precision, "method": { "engine": "faiss", - "space_type": "l2", + "space_type": distance_type, "name": "hnsw", "parameters": {}, }, @@ -206,6 +215,8 @@ def handle_create( index_name: str, vector_field: str, dimensions: int, + precision: str, + distance_type: str, metadata_management: Sequence[MetadataManagementField], analyzer: AnalyzerProperties | None, ): @@ -213,7 +224,7 @@ def handle_create( raise ValueError(f"Index {index_name} already exists") try: - mapping = create_mapping(vector_field, dimensions, metadata_management) + mapping = create_mapping(vector_field, dimensions, precision, distance_type, metadata_management) setting = create_setting(analyzer) create_index(client, index_name, mapping, setting) except Exception as e: @@ -248,6 +259,8 @@ def on_create( event["ResourceProperties"]["IndexName"], event["ResourceProperties"]["VectorField"], int(event["ResourceProperties"]["Dimensions"]), + event["ResourceProperties"]["Precision"], + event["ResourceProperties"]["DistanceType"], event["ResourceProperties"]["MetadataManagement"], event["ResourceProperties"].get("Analyzer", None), ) diff --git a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts index 86e7e817..e7afb83b 100644 --- a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts +++ b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts @@ -484,6 +484,8 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { indexName, vectorField, vectorDimensions: embeddingsModel.vectorDimensions!, + precision: props.vectorType === VectorType.BINARY ? 'Binary' : 'FP32', + distanceType: props.vectorType === VectorType.BINARY ? 'hamming' : 'euclidiean', mappings: [ { mappingField: 'AMAZON_BEDROCK_TEXT_CHUNK', diff --git a/src/cdk-lib/opensearch-vectorindex/vector-index.ts b/src/cdk-lib/opensearch-vectorindex/vector-index.ts index 8c81397d..0d1846bf 100644 --- a/src/cdk-lib/opensearch-vectorindex/vector-index.ts +++ b/src/cdk-lib/opensearch-vectorindex/vector-index.ts @@ -86,6 +86,14 @@ interface VectorIndexResourceProps { * The number of dimensions in the vector. */ readonly Dimensions: number; + /** + * The data_type of the binary vector index. + */ + readonly Precision: string; + /** + * The space_type of the binary vector index. + */ + readonly DistanceType: string; /** * The metadata management fields. */ @@ -154,6 +162,8 @@ export interface VectorIndexProps { * The number of dimensions in the vector. */ readonly vectorDimensions: number; + readonly precision: string; + readonly distanceType: string; /** * The metadata management fields. */ @@ -188,6 +198,7 @@ export class VectorIndex extends cdk.Resource { this.indexName = props.indexName; this.vectorField = props.vectorField; this.vectorDimensions = props.vectorDimensions; + const crProvider = OpenSearchIndexCRProvider.getProvider(this); crProvider.role.addManagedPolicy(props.collection.aossPolicy); @@ -244,6 +255,8 @@ export class VectorIndex extends cdk.Resource { IndexName: props.indexName, VectorField: props.vectorField, Dimensions: props.vectorDimensions, + Precision: props.precision, + DistanceType: props.distanceType, MetadataManagement: props.mappings.map((m) => { return { MappingField: m.mappingField, diff --git a/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts b/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts index 621a63d1..deb3df11 100644 --- a/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts +++ b/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts @@ -159,6 +159,8 @@ describe('OpenSearch Serverless Vector Index with analyzer', () => { indexName: 'test-index', vectorField: 'vector', vectorDimensions: 1536, + distanceType: 'euclidian', + precision: 'fp32', mappings: [ { mappingField: 'AMAZON_BEDROCK_TEXT_CHUNK', From 8f2f73fe5cbe88d1d68afea31994cbf1e8ed5a89 Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 11 Feb 2025 14:22:37 -0600 Subject: [PATCH 3/4] chore(build): fix build --- .../poetry.lock | 348 +++++++++--------- .../opensearch-vectorindex/vector-index.ts | 2 +- .../vector-index.test.ts | 2 + 3 files changed, 182 insertions(+), 170 deletions(-) diff --git a/lambda/opensearch-serverless-custom-resources/poetry.lock b/lambda/opensearch-serverless-custom-resources/poetry.lock index 8a91b16e..f33e71aa 100644 --- a/lambda/opensearch-serverless-custom-resources/poetry.lock +++ b/lambda/opensearch-serverless-custom-resources/poetry.lock @@ -2,32 +2,32 @@ [[package]] name = "boto3" -version = "1.34.128" +version = "1.36.17" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.128-py3-none-any.whl", hash = "sha256:a048ff980a81cd652724a73bc496c519b336fabe19cc8bfc6c53b2ff6eb22c7b"}, - {file = "boto3-1.34.128.tar.gz", hash = "sha256:43a6e99f53a8d34b3b4dbe424dbcc6b894350dc41a85b0af7c7bc24a7ec2cead"}, + {file = "boto3-1.36.17-py3-none-any.whl", hash = "sha256:59bcf0c4b04d9cc36f8b418ad17ab3c4a99a21a175d2fad7096aa21cbe84630b"}, + {file = "boto3-1.36.17.tar.gz", hash = "sha256:5ecae20e780a3ce9afb3add532b61c466a8cb8960618e4fa565b3883064c1346"}, ] [package.dependencies] -botocore = ">=1.34.128,<1.35.0" +botocore = ">=1.36.17,<1.37.0" jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.10.0,<0.11.0" +s3transfer = ">=0.11.0,<0.12.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.128" +version = "1.36.17" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.128-py3-none-any.whl", hash = "sha256:db67fda136c372ab3fa432580c819c89ba18d28a6152a4d2a7ea40d44082892e"}, - {file = "botocore-1.34.128.tar.gz", hash = "sha256:8d8e03f7c8c080ecafda72036eb3b482d649f8417c90b5dca33b7c2c47adb0c9"}, + {file = "botocore-1.36.17-py3-none-any.whl", hash = "sha256:069858b2fd693548035d7fd53a774e37e4260fea64e0ac9b8a3aee904f9321df"}, + {file = "botocore-1.36.17.tar.gz", hash = "sha256:cec13e0a7ce78e71aad0b397581b4e81824c7981ef4c261d2e296d200c399b09"}, ] [package.dependencies] @@ -36,116 +36,118 @@ python-dateutil = ">=2.1,<3.0.0" urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} [package.extras] -crt = ["awscrt (==0.20.11)"] +crt = ["awscrt (==0.23.8)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2025.1.31" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, + {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, ] [[package]] name = "charset-normalizer" -version = "3.3.2" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, - {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, - {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, - {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, - {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, - {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, - {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, - {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -171,15 +173,18 @@ files = [ [[package]] name = "idna" -version = "3.7" +version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -204,46 +209,52 @@ files = [ [[package]] name = "mypy" -version = "1.10.0" +version = "1.15.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"}, + {file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"}, + {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b"}, + {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3"}, + {file = "mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b"}, + {file = "mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828"}, + {file = "mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f"}, + {file = "mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5"}, + {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e"}, + {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c"}, + {file = "mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f"}, + {file = "mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f"}, + {file = "mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd"}, + {file = "mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f"}, + {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464"}, + {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee"}, + {file = "mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e"}, + {file = "mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22"}, + {file = "mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445"}, + {file = "mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d"}, + {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5"}, + {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036"}, + {file = "mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357"}, + {file = "mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf"}, + {file = "mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078"}, + {file = "mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba"}, + {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"}, + {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b"}, + {file = "mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2"}, + {file = "mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980"}, + {file = "mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e"}, + {file = "mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" -typing-extensions = ">=4.1.0" +mypy_extensions = ">=1.0.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] @@ -261,38 +272,37 @@ files = [ [[package]] name = "opensearch-py" -version = "2.6.0" +version = "2.8.0" description = "Python client for OpenSearch" optional = false python-versions = "<4,>=3.8" files = [ - {file = "opensearch_py-2.6.0-py2.py3-none-any.whl", hash = "sha256:b6e78b685dd4e9c016d7a4299cf1de69e299c88322e3f81c716e6e23fe5683c1"}, - {file = "opensearch_py-2.6.0.tar.gz", hash = "sha256:0b7c27e8ed84c03c99558406927b6161f186a72502ca6d0325413d8e5523ba96"}, + {file = "opensearch_py-2.8.0-py3-none-any.whl", hash = "sha256:52c60fdb5d4dcf6cce3ee746c13b194529b0161e0f41268b98ab8f1624abe2fa"}, + {file = "opensearch_py-2.8.0.tar.gz", hash = "sha256:6598df0bc7a003294edd0ba88a331e0793acbb8c910c43edf398791e3b2eccda"}, ] [package.dependencies] -certifi = ">=2022.12.07" +certifi = ">=2024.07.04" Events = "*" python-dateutil = "*" -requests = ">=2.4.0,<3.0.0" -six = "*" -urllib3 = {version = ">=1.26.18,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} +requests = ">=2.32.0,<3.0.0" +urllib3 = {version = ">=1.26.19,<2.2.0 || >2.2.0,<2.2.1 || >2.2.1,<3", markers = "python_version >= \"3.10\""} [package.extras] async = ["aiohttp (>=3.9.4,<4)"] -develop = ["black (>=24.3.0)", "botocore", "coverage (<8.0.0)", "jinja2", "mock", "myst-parser", "pytest (>=3.0.0)", "pytest-cov", "pytest-mock (<4.0.0)", "pytz", "pyyaml", "requests (>=2.0.0,<3.0.0)", "sphinx", "sphinx-copybutton", "sphinx-rtd-theme"] -docs = ["aiohttp (>=3.9.4,<4)", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-rtd-theme"] -kerberos = ["requests-kerberos"] +develop = ["black (>=24.3.0)", "botocore", "coverage (<8.0.0)", "jinja2", "myst_parser", "pytest (>=3.0.0)", "pytest-cov", "pytest-mock (<4.0.0)", "pytz", "pyyaml", "requests (>=2.0.0,<3.0.0)", "sphinx", "sphinx_copybutton", "sphinx_rtd_theme"] +docs = ["aiohttp (>=3.9.4,<4)", "myst_parser", "sphinx", "sphinx_copybutton", "sphinx_rtd_theme"] +kerberos = ["requests_kerberos"] [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -367,41 +377,41 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "s3transfer" -version = "0.10.1" +version = "0.11.2" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"}, - {file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"}, + {file = "s3transfer-0.11.2-py3-none-any.whl", hash = "sha256:be6ecb39fadd986ef1701097771f87e4d2f821f27f6071c872143884d2950fbc"}, + {file = "s3transfer-0.11.2.tar.gz", hash = "sha256:3b39185cb72f5acc77db1a58b6e25b977f28d20496b6e58d6813d75f464d632f"}, ] [package.dependencies] -botocore = ">=1.33.2,<2.0a.0" +botocore = ">=1.36.0,<2.0a.0" [package.extras] -crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] +crt = ["botocore[crt] (>=1.36.0,<2.0a.0)"] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "tenacity" -version = "8.4.1" +version = "8.5.0" description = "Retry code until it succeeds" optional = false python-versions = ">=3.8" files = [ - {file = "tenacity-8.4.1-py3-none-any.whl", hash = "sha256:28522e692eda3e1b8f5e99c51464efcc0b9fc86933da92415168bc1c4e2308fa"}, - {file = "tenacity-8.4.1.tar.gz", hash = "sha256:54b1412b878ddf7e1f1577cd49527bad8cdef32421bd599beac0c6c3f10582fd"}, + {file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"}, + {file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"}, ] [package.extras] @@ -421,13 +431,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.2" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, - {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] diff --git a/src/cdk-lib/opensearch-vectorindex/vector-index.ts b/src/cdk-lib/opensearch-vectorindex/vector-index.ts index 0d1846bf..8085c7ab 100644 --- a/src/cdk-lib/opensearch-vectorindex/vector-index.ts +++ b/src/cdk-lib/opensearch-vectorindex/vector-index.ts @@ -198,7 +198,7 @@ export class VectorIndex extends cdk.Resource { this.indexName = props.indexName; this.vectorField = props.vectorField; this.vectorDimensions = props.vectorDimensions; - + const crProvider = OpenSearchIndexCRProvider.getProvider(this); crProvider.role.addManagedPolicy(props.collection.aossPolicy); diff --git a/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts b/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts index deb3df11..47a9ff0f 100644 --- a/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts +++ b/test/cdk-lib/opensearch-vectorindex/vector-index.test.ts @@ -54,6 +54,8 @@ describe('OpenSearch Serverless Vector Index', () => { aossVectorIndex = new VectorIndex(stack, 'test-aoss-vector-index', { collection: aossVector, indexName: 'test-index', + distanceType: 'euclidian', + precision: 'fp32', vectorField: 'vector', vectorDimensions: 1536, mappings: [ From 6199a1faedc71e1eb29dc3b9b0803c56b66d3c53 Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 11 Feb 2025 17:10:25 -0600 Subject: [PATCH 4/4] chore(doc): update doc and fix typo --- .../knowledge-bases/vector-knowledge-base.ts | 4 +-- src/cdk-lib/opensearch-vectorindex/README.md | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts index e7afb83b..17dc4a2a 100644 --- a/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts +++ b/src/cdk-lib/bedrock/knowledge-bases/vector-knowledge-base.ts @@ -484,8 +484,8 @@ export class VectorKnowledgeBase extends VectorKnowledgeBaseBase { indexName, vectorField, vectorDimensions: embeddingsModel.vectorDimensions!, - precision: props.vectorType === VectorType.BINARY ? 'Binary' : 'FP32', - distanceType: props.vectorType === VectorType.BINARY ? 'hamming' : 'euclidiean', + precision: props.vectorType === VectorType.BINARY ? 'Binary' : 'float', + distanceType: props.vectorType === VectorType.BINARY ? 'hamming' : 'l2', mappings: [ { mappingField: 'AMAZON_BEDROCK_TEXT_CHUNK', diff --git a/src/cdk-lib/opensearch-vectorindex/README.md b/src/cdk-lib/opensearch-vectorindex/README.md index 2ebbc8c0..f74a2d4d 100644 --- a/src/cdk-lib/opensearch-vectorindex/README.md +++ b/src/cdk-lib/opensearch-vectorindex/README.md @@ -28,6 +28,7 @@ This construct library provides a resource that creates a vector index on an Ama - [API](#api) - [Vector Index](#vector-index) +- [Default values](#default-values) ## API @@ -55,6 +56,8 @@ new opensearch_vectorindex.VectorIndex(this, 'VectorIndex', { indexName: 'bedrock-knowledge-base-default-index', vectorField: 'bedrock-knowledge-base-default-vector', vectorDimensions: 1536, + precision: 'float', + distanceType: 'l2', mappings: [ { mappingField: 'AMAZON_BEDROCK_TEXT_CHUNK', @@ -93,6 +96,8 @@ vectorIndex = opensearch_vectorindex.VectorIndex(self, "VectorIndex", collection=vectorCollection, index_name='bedrock-knowledge-base-default-index', vector_field='bedrock-knowledge-base-default-vector', + precision='float', + distance_type='l2', mappings= [ opensearch_vectorindex.MetadataManagementFieldProps( mapping_field='AMAZON_BEDROCK_TEXT_CHUNK', @@ -115,3 +120,33 @@ vectorIndex = opensearch_vectorindex.VectorIndex(self, "VectorIndex", ) ) ``` + +## Default values + +Behind the scenes, the custom resource creates a k-NN vector in the OpenSearch index, allowing to perform different kinds of k-NN search. The knn_vector field is highly configurable and can serve many different k-NN workloads. It is created as follows: + +Python + +```py +"properties": { + vector_field: { + "type": "knn_vector", + "dimension": dimensions, + "data_type": precision, + "method": { + "engine": "faiss", + "space_type": distance_type, + "name": "hnsw", + "parameters": {}, + }, + }, + "id": { + "type": "text", + "fields": {"keyword": {"type": "keyword", "ignore_above": 256}}, + }, + }, +``` + +Users can currently configure the ```vector_field```, ```dimension```, ```data_type```, and ```distance_type``` fields through the construct interface. + +For details on the different settings, you can refer to the [Knn plugin documentation](https://opensearch.org/docs/latest/search-plugins/knn/knn-index/). \ No newline at end of file