diff --git a/.github/labeler.yml b/.github/labeler.yml index c19e1e9fb8..e9ecb0c45a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -7,6 +7,8 @@ backend: - appserver/**/* - statistical-enrichment/* - statistical-enrichment/**/* + - llm/* + - llm/**/* - cache-invalidator/* - cache-invalidator/**/* diff --git a/appserver/config.py b/appserver/config.py index c094e85bb1..c007a196bc 100644 --- a/appserver/config.py +++ b/appserver/config.py @@ -72,6 +72,9 @@ class Base: SE_HOST = os.environ.get('SE_HOST', 'statistical-enrichment') SE_PORT = os.environ.get('SE_PORT', '5010') + LLM_HOST = os.environ.get('LLM_HOST', 'llm') + LLM_PORT = os.environ.get('LLM_PORT', '5000') + NLP_SERVICE_ENDPOINT = os.environ.get( 'NLP_SERVICE_ENDPOINT', 'https://nlp-api.lifelike.bio/v1/predict' ) diff --git a/appserver/neo4japp/blueprints/context.py b/appserver/neo4japp/blueprints/context.py index 5460da633b..2df2d42ff3 100644 --- a/appserver/neo4japp/blueprints/context.py +++ b/appserver/neo4japp/blueprints/context.py @@ -5,6 +5,7 @@ from neo4japp.schemas.context import ContextRelationshipRequestSchema from neo4japp.services.chat_gpt import ChatGPT +from neo4japp.services.llm import LLM from neo4japp.utils.globals import get_current_username bp = Blueprint('chat-gpt-api', __name__, url_prefix='/explain') @@ -50,3 +51,25 @@ def relationship(params): "result": choice.get('message').get('content').strip(), "query_params": create_params, } + + +@bp.route('/relationship/graph', methods=['POST']) +@use_args(ContextRelationshipRequestSchema) +def relationship_graph(params): + entities = params.get('entities', []) + context = params.get('context') + options = params.get('options', {}) + create_params = dict( + model="gpt-3.5-turbo", + query=( + 'What is the relationship between ' + + ', '.join(entities) + + (f', {context}' if context else '') + + '?' + ), + temperature=options.get('temperature', 0), + max_tokens=2000, + user=str(hash(get_current_username())), + timeout=60, + ) + return LLM.graph_qa(**create_params) diff --git a/appserver/neo4japp/services/llm.py b/appserver/neo4japp/services/llm.py new file mode 100644 index 0000000000..5009ed5f61 --- /dev/null +++ b/appserver/neo4japp/services/llm.py @@ -0,0 +1,87 @@ +import json +from http import HTTPStatus +from typing import cast + +import requests +from flask import current_app, Response, g + +from neo4japp.exceptions import ServerException +from neo4japp.utils.globals import config +from neo4japp.utils.transaction_id import transaction_id + + +class LLM: + @classmethod + def request(cls, path, **request_args) -> Response: + host = config.get('LLM_HOST') + port = config.get('LLM_PORT') + host_port = f'{host}:{port}' + url = f'http://{host_port}{path}' + try: + request_args['url'] = url + resp = requests.request(**request_args) + excluded_headers = [ + 'content-encoding', + 'content-length', + 'transfer-encoding', + 'connection', + ] + headers = [ + (name, value) + for (name, value) in resp.raw.headers.items() + if name.lower() not in excluded_headers + ] + except Exception as e: + raise ServerException( + 'An unexpected error occurred while connecting to service.', + fields={ + arg: request_args[arg] + for arg in request_args + if arg not in ['headers', 'cookies'] + }, + ) from e + + # 500 should contain message from service so we try to include it + if resp.status_code == HTTPStatus.INTERNAL_SERVER_ERROR: + try: + decoded_error_message = json.loads(resp.content)['message'] + except Exception as e: + # log and proceed so general error can be raised + current_app.logger.error( + f'Could not process 500 error response from forwarded request.', + exc_info=e, + ) + else: + raise ServerException( + 'Service error', + decoded_error_message, + code=cast(HTTPStatus, resp.status_code), + ) + + # All errors including failure to parse internal error message + if 400 <= resp.status_code < 600: + raise ServerException( + 'Unable to process request', + 'An internal error of service occurred.', + code=cast(HTTPStatus, resp.status_code), + ) + + return Response(resp.content, resp.status_code, headers) + + @classmethod + def graph_qa(cls, query, user, **data): + return cls.request( + '/graph', + data=json.dumps( + { + 'query': query, + 'transaction_id': getattr(g, 'transaction_id'), + 'user': user, + 'graph': { + 'database_type': 'arango', + }, + } + ), + method='POST', + headers={'Content-Type': 'application/json'}, + ) diff --git a/client/src/app/drawing-tool/components/prompt/prompt.component.html b/client/src/app/drawing-tool/components/prompt/prompt.component.html index b2308eaa5e..36eabc30b5 100644 --- a/client/src/app/drawing-tool/components/prompt/prompt.component.html +++ b/client/src/app/drawing-tool/components/prompt/prompt.component.html @@ -65,7 +65,9 @@ -
-
-
- - - - - - - {{ state.explanation.value.result }} + +
+
+
+ ChatGPT + + + + + + +
+ + + + + {{ state.explanation.value.result }} + +
-
+
+
+
+ ChatGPT over graph + + + + + + +
+ + + + + {{ state.graph_explanation.value?.result?.result }} + + +
+
+ + + diff --git a/client/src/app/drawing-tool/components/prompt/prompt.component.ts b/client/src/app/drawing-tool/components/prompt/prompt.component.ts index 802a608740..692f5ad478 100644 --- a/client/src/app/drawing-tool/components/prompt/prompt.component.ts +++ b/client/src/app/drawing-tool/components/prompt/prompt.component.ts @@ -19,8 +19,8 @@ import { } from 'app/playground/components/form/drawing-tool-prompt-form/drawing-tool-prompt-form.component'; import { OpenPlaygroundParams } from 'app/playground/components/open-playground/open-playground.component'; import { OpenFileProvider } from 'app/shared/providers/open-file/open-file.provider'; -import { ExplainService } from 'app/shared/services/explain.service'; import { DropdownController } from 'app/shared/utils/dropdown.controller.factory'; +import { ExplainService, GraphChatGPTResponse } from 'app/shared/services/explain.service'; import { openModal } from 'app/shared/utils/modals'; import { PlaygroundComponent } from 'app/playground/components/playground.component'; import { ChatgptResponseInfoModalComponent } from 'app/shared/components/chatgpt-response-info-modal/chatgpt-response-info-modal.component'; @@ -28,6 +28,7 @@ import { ChatGPTResponse } from 'app/enrichment/services/enrichment-visualisatio import { addStatus, PipeStatus } from 'app/shared/pipes/add-status.pipe'; import { ClipboardService } from 'app/shared/services/clipboard.service'; import { AuthenticationService } from 'app/auth/services/authentication.service'; +import { annotationTypesMap } from 'app/shared/annotation-styles'; import { MapStoreService, setContext } from '../../services/map-store.service'; @@ -46,6 +47,44 @@ export class DrawingToolPromptComponent implements OnDestroy, OnChanges { readonly authService: AuthenticationService ) {} + networkConfig = { + interaction: { + hover: true, + multiselect: true, + selectConnectedEdges: false, + }, + physics: { + enabled: true, + solver: 'barnesHut', + }, + edges: { + font: { + size: 12, + }, + length: 250, + widthConstraint: { + maximum: 90, + }, + }, + nodes: { + scaling: { + min: 25, + max: 50, + label: { + enabled: true, + min: 12, + max: 72, + maxVisible: 72, + drawThreshold: 5, + }, + }, + shape: 'box', + widthConstraint: { + maximum: 180, + }, + }, + }; + private readonly destroy$: Subject = new Subject(); @Input() entities!: Iterable; @@ -110,6 +149,38 @@ export class DrawingToolPromptComponent implements OnDestroy, OnChanges { ) ); + readonly graphExplanation$: Observable> = this.params$.pipe( + switchMap((params) => + this.explain$.pipe( + map(() => params), + takeUntil(this.destroy$), + switchMap(({ entities, temperature, context }) => + this.explainService + .relationshipGraph(entities, context, { temperature }) + .pipe(addStatus()) + ), + startWith(undefined) + ) + ) + ); + + readonly graph$ = this.graphExplanation$.pipe( + map((explanation) => explanation?.value?.graph), + map((graph) => + graph + ? { + edges: graph.edges, + nodes: graph.nodes.map(({ eid, type, entityType, displayName }) => ({ + id: eid, + label: displayName, + color: annotationTypesMap.get((type ?? entityType)?.toLowerCase())?.color, + })), + } + : undefined + ), + shareReplay({ bufferSize: 1, refCount: true }) + ); + readonly playgroundParams$: Observable> = combineLatest([this.params$, this.contexts$]).pipe( map(([{ temperature, entities, context }, contexts]) => ({ diff --git a/client/src/app/shared/directives/shareddirectives.module.ts b/client/src/app/shared/directives/shareddirectives.module.ts index 52563751cf..7a7ba48335 100644 --- a/client/src/app/shared/directives/shareddirectives.module.ts +++ b/client/src/app/shared/directives/shareddirectives.module.ts @@ -33,6 +33,7 @@ import { InteractiveInterfaceHasPlaceholderDirective, ShowPlaceholderDirective, } from './placeholder.directive'; +import { VisNetworkDirective } from './vis-network.directive'; const directives = [ HasPlaceholderDirective, @@ -43,6 +44,7 @@ const directives = [ DebounceInputDirective, LinkWithoutHrefDirective, LinkWithHrefDirective, + VisNetworkDirective, FormInputDirective, AutoFocusDirective, InnerXMLDirective, @@ -67,7 +69,7 @@ const directives = [ @NgModule({ imports: [], - declarations: [...directives], + declarations: [...directives, VisNetworkDirective], exports: [...directives], }) export class SharedDirectivesModule {} diff --git a/client/src/app/shared/directives/vis-network.directive.ts b/client/src/app/shared/directives/vis-network.directive.ts new file mode 100644 index 0000000000..fc2234ff17 --- /dev/null +++ b/client/src/app/shared/directives/vis-network.directive.ts @@ -0,0 +1,414 @@ +import { + AfterViewInit, + Directive, + ElementRef, + Input, + OnChanges, + OnDestroy, + Output, + Renderer2, + SimpleChanges, +} from '@angular/core'; + +import { + BoundingBox, + ClusterOptions, + Data, + DirectionType, + EdgeOptions, + FitOptions, + FocusOptions, + IdType, + MoveToOptions, + Network, + NetworkEvents, + NodeOptions, + OpenClusterOptions, + Options, + Position, + SelectionOptions, +} from 'vis-network'; +import { Observable, ReplaySubject } from 'rxjs'; +import { shareReplay, switchMap } from 'rxjs/operators'; + +@Directive({ + selector: 'app-vis-network[data][options], [appVisNetwork][data][options]', +}) +export class VisNetworkDirective implements Network, OnChanges, AfterViewInit, OnDestroy { + /** + * Versatile yet simple wrapper, implementing vis-network Network class as Angular component/directive. + * It allows to use vis-network in Angular templates in a declarative way. + * To avoid name conflicts all events has been prefixed with 'network' word. + * + * Examples of usage in templates: + * ```html + * + *
+ * + *
+ * ``` + * + * Example of usage in component class: + * ```ts + * @ViewChild(VisNetworkDirective) networkInstance: VisNetworkDirective; + * this.networkInstance.network.fit(); + * ``` + * + * Example of usage in component class handling events outside Angular zone: + * ```ts + * @ViewChild(VisNetworkDirective) networkInstance: VisNetworkDirective; + * this.networkInstance.network.on('click', (params) => this.click(params)); + * ``` + * + * [See official vis-network documentation for details on methods and events.](https://visjs.github.io/vis-network/docs/network/) + */ + constructor(private readonly element: ElementRef, private readonly renderer: Renderer2) { + // Set display to block to allow setting width and height + // TODO: This could be write to not overwrite diferent acceptable display values like inline-block + this.renderer.setStyle(element.nativeElement, 'display', 'block'); + } + + @Input() data!: Data; + @Input() options!: Options; + private _network: Network; // current vis-network instance, used to implement all methods + private _network$ = new ReplaySubject(1); // used to implement all events + // tslint:disable-next-line:no-output-rename + @Output('network') network$ = this._network$.asObservable(); + + get network(): Network { + return this._network; + } + + set network(network: Network) { + this._network?.destroy(); + this._network = network; + this._network$.next(network); + } + + // region Network Events proxies + /** + * WARNING: These proxies will run in angular zone, so they will trigger change detection. + * If you want to avoid this, use VisNetworkDirective.on('eventName', callback) instead. + */ + @Output() readonly networkClick = this.networkEventToEventEmitter('click'); + @Output() readonly networkDoubleClick = this.networkEventToEventEmitter('doubleClick'); + @Output() readonly networkOnContext = this.networkEventToEventEmitter('oncontext'); + @Output() readonly networkHold = this.networkEventToEventEmitter('hold'); + @Output() readonly networkRelease = this.networkEventToEventEmitter('release'); + @Output() readonly networkSelect = this.networkEventToEventEmitter('select'); + @Output() readonly networkSelectNode = this.networkEventToEventEmitter('selectNode'); + @Output() readonly networkSelectEdge = this.networkEventToEventEmitter('selectEdge'); + @Output() readonly networkDeselectNode = this.networkEventToEventEmitter('deselectNode'); + @Output() readonly networkDeselectEdge = this.networkEventToEventEmitter('deselectEdge'); + @Output() readonly networkDragStart = this.networkEventToEventEmitter('dragStart'); + @Output() readonly networkDragging = this.networkEventToEventEmitter('dragging'); + @Output() readonly networkDragEnd = this.networkEventToEventEmitter('dragEnd'); + @Output() readonly networkControlNodeDragging = + this.networkEventToEventEmitter('controlNodeDragging'); + @Output() readonly networkControlNodeDragEnd = + this.networkEventToEventEmitter('controlNodeDragEnd'); + @Output() readonly networkHoverNode = this.networkEventToEventEmitter('hoverNode'); + @Output() readonly networkBlurNode = this.networkEventToEventEmitter('blurNode'); + @Output() readonly networkHoverEdge = this.networkEventToEventEmitter('hoverEdge'); + @Output() readonly networkBlurEdge = this.networkEventToEventEmitter('blurEdge'); + @Output() readonly networkZoom = this.networkEventToEventEmitter('zoom'); + @Output() readonly networkShowPopup = this.networkEventToEventEmitter('showPopup'); + @Output() readonly networkHidePopup = this.networkEventToEventEmitter('hidePopup'); + @Output() readonly networkStartStabilizing = this.networkEventToEventEmitter('startStabilizing'); + @Output() readonly networkStabilizationProgress = + this.networkEventToEventEmitter('stabilizationProgress'); + @Output() readonly networkStabilizationIterationsDone = this.networkEventToEventEmitter( + 'stabilizationIterationsDone' + ); + @Output() readonly networkStabilized = this.networkEventToEventEmitter('stabilized'); + @Output() readonly networkResize = this.networkEventToEventEmitter('resize'); + @Output() readonly networkInitRedraw = this.networkEventToEventEmitter('initRedraw'); + @Output() readonly networkBeforeDrawing = this.networkEventToEventEmitter('beforeDrawing'); + @Output() readonly networkAfterDrawing = this.networkEventToEventEmitter('afterDrawing'); + @Output() readonly networkAnimationFinished = + this.networkEventToEventEmitter('animationFinished'); + @Output() readonly networkConfigChange = this.networkEventToEventEmitter('configChange'); + + private networkEventToEventEmitter(eventName: NetworkEvents) { + return this._network$.pipe( + switchMap( + (network) => + new Observable((subscriber) => { + const callback = (e: any) => subscriber.next(e); + network.on(eventName, callback); + + return function unsubscribe() { + network.off(eventName, callback); + }; + }) + ), + shareReplay({ bufferSize: 1, refCount: true }) + ); + } + // endregion + + // region Lifecycle + ngOnChanges({ data, options }: SimpleChanges) { + if (data && !data.firstChange) { + // initial value is set in ngAfterViewInit + this._network.setData(data.currentValue); + } + if (options && !options.firstChange) { + // initial value is set in ngAfterViewInit + this._network.setOptions(options.currentValue); + } + } + + ngAfterViewInit() { + this._network = new Network(this.element.nativeElement, this.data, this.options); + } + + ngOnDestroy() { + this._network?.destroy(); + } + // endregion + + // region Network methods proxy + DOMtoCanvas(position: Position): Position { + return this._network.DOMtoCanvas(position); + } + + addEdgeMode(): void { + this._network.addEdgeMode(); + } + + addNodeMode(): void { + this._network.addNodeMode(); + } + + canvasToDOM(position: Position): Position { + return this._network.canvasToDOM(position); + } + + cluster(options?: ClusterOptions): void { + this._network.cluster(options); + } + + clusterByConnection(nodeId: string, options?: ClusterOptions): void { + this._network.clusterByConnection(nodeId, options); + } + + clusterByHubsize(hubsize?: number, options?: ClusterOptions): void { + this._network.clusterByHubsize(hubsize, options); + } + + clusterOutliers(options?: ClusterOptions): void { + this._network.clusterOutliers(options); + } + + deleteSelected(): void { + this._network.deleteSelected(); + } + + destroy(): void { + this._network.destroy(); + } + + disableEditMode(): void { + this._network.disableEditMode(); + } + + editEdgeMode(): void { + this._network.editEdgeMode(); + } + + editNode(): void { + this._network.editNode(); + } + + enableEditMode(): void { + this._network.enableEditMode(); + } + + findNode(nodeId: IdType): IdType[] { + return this._network.findNode(nodeId); + } + + fit(options?: FitOptions): void { + this._network.fit(options); + } + + focus(nodeId: IdType, options?: FocusOptions): void { + this._network.focus(nodeId, options); + } + + getBaseEdge(clusteredEdgeId: IdType): IdType { + return this._network.getBaseEdge(clusteredEdgeId); + } + + getBaseEdges(clusteredEdgeId: IdType): IdType[] { + return this._network.getBaseEdges(clusteredEdgeId); + } + + getBoundingBox(nodeId: IdType): BoundingBox { + return this._network.getBoundingBox(nodeId); + } + + getClusteredEdges(baseEdgeId: IdType): IdType[] { + return this._network.getClusteredEdges(baseEdgeId); + } + + getConnectedEdges(nodeId: IdType): IdType[] { + return this._network.getConnectedEdges(nodeId); + } + + getConnectedNodes( + nodeOrEdgeId: IdType, + direction?: DirectionType + ): + | IdType[] + | Array<{ + fromId: IdType; + toId: IdType; + }> { + return this._network.getConnectedNodes(nodeOrEdgeId, direction); + } + + getEdgeAt(position: Position): IdType { + return this._network.getEdgeAt(position); + } + + getNodeAt(position: Position): IdType { + return this._network.getNodeAt(position); + } + + getNodesInCluster(clusterNodeId: IdType): IdType[] { + return this._network.getNodesInCluster(clusterNodeId); + } + + getOptionsFromConfigurator(): any { + return this._network.getOptionsFromConfigurator(); + } + + getPosition(nodeId: IdType): Position { + return this._network.getPosition(nodeId); + } + + getPositions(nodeIds?: IdType[] | IdType): { [p: string]: Position } { + return this._network.getPositions(nodeIds); + } + + getScale(): number { + return this._network.getScale(); + } + + getSeed(): number | string { + return this._network.getSeed(); + } + + getSelectedEdges(): IdType[] { + return this._network.getSelectedEdges(); + } + + getSelectedNodes(): IdType[] { + return this._network.getSelectedNodes(); + } + + getSelection(): { nodes: IdType[]; edges: IdType[] } { + return this._network.getSelection(); + } + + getViewPosition(): Position { + return this._network.getViewPosition(); + } + + isCluster(nodeId: IdType): boolean { + return this._network.isCluster(nodeId); + } + + moveNode(nodeId: IdType, x: number, y: number): void { + this._network.moveNode(nodeId, x, y); + } + + moveTo(options: MoveToOptions): void { + this._network.moveTo(options); + } + + off(eventName: NetworkEvents, callback?: (params?: any) => void): void { + this._network.off(eventName, callback); + } + + on(eventName: NetworkEvents, callback: (params?: any) => void): void { + this._network.on(eventName, callback); + } + + once(eventName: NetworkEvents, callback: (params?: any) => void): void { + this._network.once(eventName, callback); + } + + openCluster(nodeId: IdType, options?: OpenClusterOptions): void { + this._network.openCluster(nodeId, options); + } + + redraw(): void { + this._network.redraw(); + } + + releaseNode(): void { + this._network.releaseNode(); + } + + selectEdges(edgeIds: IdType[]): void { + this._network.selectEdges(edgeIds); + } + + selectNodes(nodeIds: IdType[], highlightEdges?: boolean): void { + this._network.selectNodes(nodeIds, highlightEdges); + } + + setData(data: Data): void { + this._network.setData(data); + } + + setOptions(options: Options): void { + this._network.setOptions(options); + } + + setSelection( + selection: { + nodes?: IdType[]; + edges?: IdType[]; + }, + options?: SelectionOptions + ): void { + this._network.setSelection(selection, options); + } + + setSize(width: string, height: string): void { + this._network.setSize(width, height); + } + + stabilize(iterations?: number): void { + this._network.stabilize(iterations); + } + + startSimulation(): void { + this._network.startSimulation(); + } + + stopSimulation(): void { + this._network.stopSimulation(); + } + + storePositions(): void { + this._network.storePositions(); + } + + unselectAll(): void { + this._network.unselectAll(); + } + + updateClusteredNode(clusteredNodeId: IdType, options?: NodeOptions): void { + this._network.updateClusteredNode(clusteredNodeId, options); + } + + updateEdge(startEdgeId: IdType, options?: EdgeOptions): void { + this._network.updateEdge(startEdgeId, options); + } + // endregion +} diff --git a/client/src/app/shared/services/explain.service.ts b/client/src/app/shared/services/explain.service.ts index 3065b9db5c..35dbef7f8a 100644 --- a/client/src/app/shared/services/explain.service.ts +++ b/client/src/app/shared/services/explain.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { map, tap } from 'rxjs/operators'; import { SingleResult } from 'app/shared/schemas/common'; import { ChatGPTResponse } from 'app/enrichment/services/enrichment-visualisation.service'; @@ -36,6 +36,23 @@ export interface ChatGPTModel { root: string; } +export interface GraphChatGPTResponse { + graph: { + nodes: { + eid: string; + displayName: string; + type: string; + entityType: string; + }[]; + edges: { + from: string; + to: string; + label: string; + }[]; + }; + response: ChatGPTResponse; +} + @Injectable({ providedIn: 'root' }) export class ExplainService { endpoint = '/api/explain/'; @@ -53,4 +70,18 @@ export class ExplainService { options, }); } + + relationshipGraph( + entities: Iterable, + context?: string, + options: ExplainRelationshipOptions = {} + ): Observable { + return this.http + .post(this.endpoint + 'relationship/graph', { + entities: Array.from(entities), + context, + options, + }) + .pipe(tap((response) => console.log(response))); + } } diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 2df05883fb..f516322a51 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -33,6 +33,9 @@ x-appserver: &appserver # StatisticalEnrichment - SE_HOST=statistical-enrichment - SE_PORT=5010 + # LLM + - LLM_HOST=llm + - LLM_PORT=5000 # Other - DOMAIN=http://localhost:4200 - LMDB_HOME_FOLDER=/home/n4j/neo4japp/services/annotations/lmdb/ @@ -82,6 +85,41 @@ services: networks: - frontend + llm: + container_name: llm + build: + context: ./llm + target: dev + entrypoint: flask run --host 0.0.0.0 + ports: + - "5020:5000" + env_file: + - azure-secrets.env + environment: + # Flask + FLASK_APP: llmlib + FLASK_APP_CONFIG: Development + FLASK_DEBUG: 1 + FLASK_ENV: development + # Arango + ARANGO_HOST: http://arangodb:8529 + ARANGO_USERNAME: root + ARANGO_PASSWORD: password + ARANGO_DB_NAME: lifelike + # Redis + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_USERNAME: default + REDIS_PASSWORD: password + REDIS_SSL: false + volumes: + - ./llm:/home/user + networks: + - backend + depends_on: + - arangodb + - redis + statistical-enrichment: container_name: statistical-enrichment build: ./statistical-enrichment diff --git a/docker-compose.yml b/docker-compose.yml index 82f61fb645..0bbe5139bf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,5 +16,8 @@ services: cache-invalidator: image: ${REGISTRY:-lifelike.azurecr.io}/kg-cache-invalidator:${GITHUB_HASH:-latest} + llm: + image: ${REGISTRY:-lifelike.azurecr.io}/kg-llm:${GITHUB_HASH:-latest} + statistical-enrichment: image: ${REGISTRY:-lifelike.azurecr.io}/kg-statistical-enrichment:${GITHUB_HASH:-latest} diff --git a/llm/.githooks/pre-commit b/llm/.githooks/pre-commit new file mode 100755 index 0000000000..984588bbda --- /dev/null +++ b/llm/.githooks/pre-commit @@ -0,0 +1,27 @@ +#!/bin/sh + +# Path from shell to folder containing this file +__dir__="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +# Runs linting on only files that are staged +staged_files=$(getStaged llmlib '\.(py)$') + +# shellcheck disable=SC2236 +if [[ -n $staged_files ]]; +then + ( + echo "> 🌽 Running flake8..." + echo ${staged_files} | \ + xargs docker run --rm \ + -v $(pwd)/llmlib:/apps \ + alpine/flake8:6.0.0 + ) && ( + echo "> 🐍 Running pycodestyle..." + echo ${staged_files} | \ + xargs docker run --rm \ + -v $(pwd)/llmlib:/data \ + cytopia/pycodestyle:2 + ) +else + echo "> Skipping python files check for llm..." +fi diff --git a/llm/.gitignore b/llm/.gitignore new file mode 100644 index 0000000000..84ded39530 --- /dev/null +++ b/llm/.gitignore @@ -0,0 +1,6 @@ +**/.ipynb_checkpoints +**/.Trash-0 +**/.jupyter +**/*.egg-info +**/chroma_db_oai +**/.pytest_cache diff --git a/llm/Dockerfile b/llm/Dockerfile new file mode 100644 index 0000000000..5d8cecab4c --- /dev/null +++ b/llm/Dockerfile @@ -0,0 +1,61 @@ +FROM python:3.11 as base +LABEL app=kg-prototypes + +ENV _USER user +ENV _HOME /home/$_USER +ENV UID 1000 +ENV GID 1000 + +# Root acces only if in ***ARANGO_USERNAME*** group +RUN echo "auth required pam_wheel.so" >> /etc/pam.d/su + +# Install dependencies +RUN pip install pipenv==2026.0.3 + +# User and group creation +RUN addgroup --system wheel && \ + groupadd -g $GID $_USER && \ + useradd -u $UID -g $GID -G wheel --create-home --shell /bin/bash $_USER + +WORKDIR $_HOME + +# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache +COPY --chown=$UID:$GID Pipfile . + +FROM base as lock + +COPY --chown=$UID:$GID . . + +CMD [ "pipenv", "lock" ] + +FROM base as build + +COPY --chown=$UID:$GID Pipfile.lock . + +ENV FLASK_APP=llm + +FROM build as dev + +# Copy files first so pipenv can link to editable package +COPY --chown=$UID:$GID . . + +# Install dev dependencies +# (NOTE: cannot run after `pipenv install` - https://github.com/pypa/pipenv/issues/4435) +RUN pipenv install --dev --deploy --system + +COPY --chown=$UID:$GID . . + +USER $_USER + +# Jupyter Notebook +EXPOSE 8888 + +FROM build as prod + +RUN pipenv install --deploy --system + +COPY --chown=$UID:$GID . . + +USER $_USER + +CMD [ "bin/startup.sh" ] diff --git a/llm/Pipfile b/llm/Pipfile new file mode 100644 index 0000000000..22c212923d --- /dev/null +++ b/llm/Pipfile @@ -0,0 +1,35 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +pytest = "*" +mypy = "==1.5.1" +pycodestyle = "==2.11.0" +jupyterlab = "*" +anyio = "*" +ipycytoscape = "*" +ipywidgets = "*" +networkx = "*" +adbnx-adapter = "*" +llmlib = {file = ".", editable = true} +tiktoken = "*" + +[packages] +flask-marshmallow = "==0.15.0" +Flask = "==2.3.3" +gunicorn = "==21.2.0" +python-arango = "==7.6.2" +openai = "==0.28.0" +langchain = "==0.0.296" +redis = "==5.0.0" +cachetools = "==5.3.1" +webargs = "*" +notebook = ">=7.0" +timeflake = "*" +chromadb = "*" +neo4j = "*" + +[requires] +python_version = "3.11" diff --git a/llm/Pipfile.lock b/llm/Pipfile.lock new file mode 100644 index 0000000000..823a86770f --- /dev/null +++ b/llm/Pipfile.lock @@ -0,0 +1,4474 @@ +{ + "_meta": { + "hash": { + "sha256": "1057a684dff40a1507710ea54d2eb6f9bbbbd246db817be1eccb62c84c1ded1d" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aiohttp": { + "hashes": [ + "sha256:002f23e6ea8d3dd8d149e569fd580c999232b5fbc601c48d55398fbc2e582e8c", + "sha256:01770d8c04bd8db568abb636c1fdd4f7140b284b8b3e0b4584f070180c1e5c62", + "sha256:0912ed87fee967940aacc5306d3aa8ba3a459fcd12add0b407081fbefc931e53", + "sha256:0cccd1de239afa866e4ce5c789b3032442f19c261c7d8a01183fd956b1935349", + "sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47", + "sha256:13da35c9ceb847732bf5c6c5781dcf4780e14392e5d3b3c689f6d22f8e15ae31", + "sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9", + "sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887", + "sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358", + "sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566", + "sha256:1f13f60d78224f0dace220d8ab4ef1dbc37115eeeab8c06804fec11bec2bbd07", + "sha256:229852e147f44da0241954fc6cb910ba074e597f06789c867cb7fb0621e0ba7a", + "sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e", + "sha256:255ba9d6d5ff1a382bb9a578cd563605aa69bec845680e21c44afc2670607a95", + "sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93", + "sha256:2b8d4e166e600dcfbff51919c7a3789ff6ca8b3ecce16e1d9c96d95dd569eb4c", + "sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad", + "sha256:3161ce82ab85acd267c8f4b14aa226047a6bee1e4e6adb74b798bd42c6ae1f80", + "sha256:33164093be11fcef3ce2571a0dccd9041c9a93fa3bde86569d7b03120d276c6f", + "sha256:39a312d0e991690ccc1a61f1e9e42daa519dcc34ad03eb6f826d94c1190190dd", + "sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0", + "sha256:3c68330a59506254b556b99a91857428cab98b2f84061260a67865f7f52899f5", + "sha256:3f0e27e5b733803333bb2371249f41cf42bae8884863e8e8965ec69bebe53132", + "sha256:3f5c7ce535a1d2429a634310e308fb7d718905487257060e5d4598e29dc17f0b", + "sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096", + "sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321", + "sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1", + "sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f", + "sha256:45ad816b2c8e3b60b510f30dbd37fe74fd4a772248a52bb021f6fd65dff809b6", + "sha256:4ac39027011414dbd3d87f7edb31680e1f430834c8cef029f11c66dad0670aa5", + "sha256:4d4cbe4ffa9d05f46a28252efc5941e0462792930caa370a6efaf491f412bc66", + "sha256:4fcf3eabd3fd1a5e6092d1242295fa37d0354b2eb2077e6eb670accad78e40e1", + "sha256:5d791245a894be071d5ab04bbb4850534261a7d4fd363b094a7b9963e8cdbd31", + "sha256:6c43ecfef7deaf0617cee936836518e7424ee12cb709883f2c9a1adda63cc460", + "sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22", + "sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34", + "sha256:713103a8bdde61d13490adf47171a1039fd880113981e55401a0f7b42c37d071", + "sha256:71783b0b6455ac8f34b5ec99d83e686892c50498d5d00b8e56d47f41b38fbe04", + "sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8", + "sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d", + "sha256:7ee912f7e78287516df155f69da575a0ba33b02dd7c1d6614dbc9463f43066e3", + "sha256:86f20cee0f0a317c76573b627b954c412ea766d6ada1a9fcf1b805763ae7feeb", + "sha256:89341b2c19fb5eac30c341133ae2cc3544d40d9b1892749cdd25892bbc6ac951", + "sha256:8a9b5a0606faca4f6cc0d338359d6fa137104c337f489cd135bb7fbdbccb1e39", + "sha256:8d399dade330c53b4106160f75f55407e9ae7505263ea86f2ccca6bfcbdb4921", + "sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5", + "sha256:90c72ebb7cb3a08a7f40061079817133f502a160561d0675b0a6adf231382c92", + "sha256:918810ef188f84152af6b938254911055a72e0f935b5fbc4c1a4ed0b0584aed1", + "sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865", + "sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d", + "sha256:99c5ac4ad492b4a19fc132306cd57075c28446ec2ed970973bbf036bcda1bcc6", + "sha256:9c19b26acdd08dd239e0d3669a3dddafd600902e37881f13fbd8a53943079dbc", + "sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543", + "sha256:9e2ee0ac5a1f5c7dd3197de309adfb99ac4617ff02b0603fd1e65b07dc772e4b", + "sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684", + "sha256:a3628b6c7b880b181a3ae0a0683698513874df63783fd89de99b7b7539e3e8a8", + "sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed", + "sha256:b04691bc6601ef47c88f0255043df6f570ada1a9ebef99c34bd0b72866c217ae", + "sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c", + "sha256:b2fe42e523be344124c6c8ef32a011444e869dc5f883c591ed87f84339de5976", + "sha256:b30e963f9e0d52c28f284d554a9469af073030030cef8693106d918b2ca92f54", + "sha256:bb54c54510e47a8c7c8e63454a6acc817519337b2b78606c4e840871a3e15349", + "sha256:bd111d7fc5591ddf377a408ed9067045259ff2770f37e2d94e6478d0f3fc0c17", + "sha256:bdf70bfe5a1414ba9afb9d49f0c912dc524cf60141102f3a11143ba3d291870f", + "sha256:ca80e1b90a05a4f476547f904992ae81eda5c2c85c66ee4195bb8f9c5fb47f28", + "sha256:caf486ac1e689dda3502567eb89ffe02876546599bbf915ec94b1fa424eeffd4", + "sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2", + "sha256:d25036d161c4fe2225d1abff2bd52c34ed0b1099f02c208cd34d8c05729882f0", + "sha256:d52d5dc7c6682b720280f9d9db41d36ebe4791622c842e258c9206232251ab2b", + "sha256:d67f8baed00870aa390ea2590798766256f31dc5ed3ecc737debb6e97e2ede78", + "sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403", + "sha256:d95fc1bf33a9a81469aa760617b5971331cdd74370d1214f0b3109272c0e1e3c", + "sha256:de6a1c9f6803b90e20869e6b99c2c18cef5cc691363954c93cb9adeb26d9f3ae", + "sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965", + "sha256:e2a988a0c673c2e12084f5e6ba3392d76c75ddb8ebc6c7e9ead68248101cd446", + "sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a", + "sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca", + "sha256:e827d48cf802de06d9c935088c2924e3c7e7533377d66b6f31ed175c1620e05e", + "sha256:ebf3fd9f141700b510d4b190094db0ce37ac6361a6806c153c161dc6c041ccda", + "sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2", + "sha256:ec4fd86658c6a8964d75426517dc01cbf840bbf32d055ce64a9e63a40fd7b771", + "sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb", + "sha256:f0f03211fd14a6a0aed2997d4b1c013d49fb7b50eeb9ffdf5e51f23cfe2c77fa", + "sha256:f628dbf3c91e12f4d6c8b3f092069567d8eb17814aebba3d7d60c149391aee3a", + "sha256:f8ef51e459eb2ad8e7a66c1d6440c808485840ad55ecc3cafefadea47d1b1ba2", + "sha256:fc37e9aef10a696a5a4474802930079ccfc14d9f9c10b4662169671ff034b7df", + "sha256:fdee8405931b0615220e5ddf8cd7edd8592c606a8e4ca2a00704883c396e4479" + ], + "markers": "python_version >= '3.6'", + "version": "==3.8.6" + }, + "aiosignal": { + "hashes": [ + "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", + "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "annotated-types": { + "hashes": [ + "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43", + "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d" + ], + "markers": "python_version >= '3.8'", + "version": "==0.6.0" + }, + "anyio": { + "hashes": [ + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" + ], + "markers": "python_version >= '3.7'", + "version": "==3.7.1" + }, + "argon2-cffi": { + "hashes": [ + "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", + "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "argon2-cffi-bindings": { + "hashes": [ + "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670", + "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f", + "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583", + "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194", + "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", + "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a", + "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", + "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5", + "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", + "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7", + "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", + "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", + "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", + "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", + "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", + "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", + "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d", + "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", + "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb", + "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", + "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351" + ], + "markers": "python_version >= '3.6'", + "version": "==21.2.0" + }, + "arrow": { + "hashes": [ + "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", + "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85" + ], + "markers": "python_version >= '3.8'", + "version": "==1.3.0" + }, + "asttokens": { + "hashes": [ + "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", + "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0" + ], + "version": "==2.4.1" + }, + "async-lru": { + "hashes": [ + "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", + "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224" + ], + "markers": "python_version >= '3.8'", + "version": "==2.0.4" + }, + "async-timeout": { + "hashes": [ + "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", + "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.3" + }, + "attrs": { + "hashes": [ + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "babel": { + "hashes": [ + "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900", + "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed" + ], + "markers": "python_version >= '3.7'", + "version": "==2.13.1" + }, + "backoff": { + "hashes": [ + "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", + "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8" + ], + "markers": "python_version >= '3.7'", + "version": "==2.2.1" + }, + "bcrypt": { + "hashes": [ + "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535", + "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0", + "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410", + "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd", + "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665", + "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab", + "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71", + "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215", + "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b", + "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda", + "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9", + "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a", + "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344", + "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f", + "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d", + "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c", + "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c", + "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2", + "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d", + "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e", + "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3" + ], + "markers": "python_version >= '3.6'", + "version": "==4.0.1" + }, + "beautifulsoup4": { + "hashes": [ + "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da", + "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==4.12.2" + }, + "bleach": { + "hashes": [ + "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", + "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" + ], + "markers": "python_version >= '3.8'", + "version": "==6.1.0" + }, + "blinker": { + "hashes": [ + "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", + "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" + ], + "markers": "python_version >= '3.8'", + "version": "==1.7.0" + }, + "cachetools": { + "hashes": [ + "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590", + "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==5.3.1" + }, + "certifi": { + "hashes": [ + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.7.22" + }, + "cffi": { + "hashes": [ + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" + ], + "markers": "python_version >= '3.8'", + "version": "==1.16.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "chroma-hnswlib": { + "hashes": [ + "sha256:108bc4c293d819b56476d8f7865803cb03afd6ca128a2a04d678fffc139af029", + "sha256:11e7ca93fb8192214ac2b9c0943641ac0daf8f9d4591bb7b73be808a83835667", + "sha256:1c92dc1ebe062188e53970ba13f6b07e0ae32e64c9770eb7f7ffa83f149d4210", + "sha256:368e57fe9ebae05ee5844840fa588028a023d1182b0cfdb1d13f607c9ea05756", + "sha256:454df3dd3e97aa784fba7cf888ad191e0087eef0fd8c70daf28b753b3b591170", + "sha256:49da700a6656fed8753f68d44b8cc8ae46efc99fc8a22a6d970dc1697f49b403", + "sha256:51b8d411486ee70d7b66ec08cc8b9b6620116b650df9c19076d2d8b6ce2ae914", + "sha256:54f053dedc0e3ba657f05fec6e73dd541bc5db5b09aa8bc146466ffb734bdc86", + "sha256:59d6a7c6f863c67aeb23e79a64001d537060b6995c3eca9a06e349ff7b0998ca", + "sha256:5aef10b4952708f5a1381c124a29aead0c356f8d7d6e0b520b778aaa62a356f4", + "sha256:6f552e4d23edc06cdeb553cdc757d2fe190cdeb10d43093d6a3319f8d4bf1c6b", + "sha256:70f897dc6218afa1d99f43a9ad5eb82f392df31f57ff514ccf4eeadecd62f544", + "sha256:7cea425df2e6b8a5e201fff0d922a1cc1d165b3cfe762b1408075723c8892218", + "sha256:7ee2d8d1529fca3898d512079144ec3e28a81d9c17e15e0ea4665697a7923253", + "sha256:9d706782b628e4f43f1b8a81e9120ac486837fbd9bcb8ced70fe0d9b95c72d77", + "sha256:a4021a70e898783cd6f26e00008b494c6249a7babe8774e90ce4766dd288c8ba", + "sha256:a8f61fa1d417fda848e3ba06c07671f14806a2585272b175ba47501b066fe6b1", + "sha256:b6137bedde49fffda6af93b0297fe00429fc61e5a072b1ed9377f909ed95a932", + "sha256:b7dca27b8896b494456db0fd705b689ac6b73af78e186eb6a42fea2de4f71c6f", + "sha256:c2358a795870156af6761890f9eb5ca8cade57eb10c5f046fe94dae1faa04b9e", + "sha256:d71a3f4f232f537b6152947006bd32bc1629a8686df22fd97777b70f416c127a", + "sha256:d7563be58bc98e8f0866907368e22ae218d6060601b79c42f59af4eccbbd2e0a", + "sha256:df587d15007ca701c6de0ee7d5585dd5e976b7edd2b30ac72bc376b3c3f85882", + "sha256:e607c5a71c610a73167a517062d302c0827ccdd6e259af6e4869a5c1306ffb5d", + "sha256:f96f4d5699e486eb1fb95849fe35ab79ab0901265805be7e60f4eaa83ce263ec" + ], + "version": "==0.7.3" + }, + "chromadb": { + "hashes": [ + "sha256:120f9d364719b664d5314500f8e6097f0e0b24496bb97a429bc324f8d11f1b52", + "sha256:8cb88162bc6124441ba5a4b93819463a10e9aaafbe05a3286e876cbdc7a7e11d" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.4.17" + }, + "click": { + "hashes": [ + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.7" + }, + "coloredlogs": { + "hashes": [ + "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", + "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==15.0.1" + }, + "comm": { + "hashes": [ + "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001", + "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be" + ], + "markers": "python_version >= '3.8'", + "version": "==0.2.0" + }, + "dataclasses-json": { + "hashes": [ + "sha256:1b934c1bd63e775880946b8361a902d7de86e894bab8098eab27c010f95724d1", + "sha256:71816ced3d0f55a2c5bc1a813ace1b8d4234e79a08744269a7cf84d6f7c06e99" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==0.6.2" + }, + "debugpy": { + "hashes": [ + "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332", + "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0", + "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f", + "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa", + "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6", + "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637", + "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6", + "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8", + "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb", + "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b", + "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4", + "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153", + "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f", + "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd", + "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595", + "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926", + "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e", + "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada" + ], + "markers": "python_version >= '3.8'", + "version": "==1.8.0" + }, + "decorator": { + "hashes": [ + "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", + "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" + ], + "markers": "python_version >= '3.5'", + "version": "==5.1.1" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, + "deprecated": { + "hashes": [ + "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", + "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.2.14" + }, + "executing": { + "hashes": [ + "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", + "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc" + ], + "markers": "python_version >= '3.5'", + "version": "==2.0.1" + }, + "fastapi": { + "hashes": [ + "sha256:752dc31160cdbd0436bb93bad51560b57e525cbb1d4bbf6f4904ceee75548241", + "sha256:e5e4540a7c5e1dcfbbcf5b903c234feddcdcd881f191977a1c5dfd917487e7ae" + ], + "markers": "python_version >= '3.8'", + "version": "==0.104.1" + }, + "fastjsonschema": { + "hashes": [ + "sha256:06dc8680d937628e993fa0cd278f196d20449a1adc087640710846b324d422ea", + "sha256:aec6a19e9f66e9810ab371cc913ad5f4e9e479b63a7072a2cd060a9369e329a8" + ], + "version": "==2.18.1" + }, + "filelock": { + "hashes": [ + "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", + "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" + ], + "markers": "python_version >= '3.8'", + "version": "==3.13.1" + }, + "flask": { + "hashes": [ + "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc", + "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b" + ], + "markers": "python_version >= '3.8'", + "version": "==2.3.3" + }, + "flask-marshmallow": { + "hashes": [ + "sha256:2083ae55bebb5142fff98c6bbd483a2f5dbc531a8bc1be2180ed5f75e7f3fccc", + "sha256:ce08a153f74da6ebfffd8065d1687508b0179df37fff7fc0c8f28ccfb64f1b56" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==0.15.0" + }, + "flatbuffers": { + "hashes": [ + "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89", + "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1" + ], + "version": "==23.5.26" + }, + "fqdn": { + "hashes": [ + "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", + "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014" + ], + "version": "==1.5.1" + }, + "frozenlist": { + "hashes": [ + "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", + "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", + "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", + "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", + "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", + "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", + "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", + "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", + "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", + "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", + "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", + "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", + "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", + "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", + "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", + "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", + "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", + "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", + "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", + "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", + "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", + "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", + "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", + "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", + "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", + "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", + "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", + "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", + "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", + "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", + "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", + "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", + "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", + "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", + "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", + "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", + "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", + "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", + "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", + "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", + "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", + "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", + "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", + "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", + "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", + "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", + "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", + "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", + "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", + "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", + "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", + "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", + "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", + "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", + "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", + "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", + "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", + "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", + "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", + "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", + "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" + ], + "markers": "python_version >= '3.8'", + "version": "==1.4.0" + }, + "fsspec": { + "hashes": [ + "sha256:330c66757591df346ad3091a53bd907e15348c2ba17d63fd54f5c39c4457d2a5", + "sha256:346a8f024efeb749d2a5fca7ba8854474b1ff9af7c3faaf636a4548781136529" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.10.0" + }, + "google-auth": { + "hashes": [ + "sha256:79905d6b1652187def79d491d6e23d0cbb3a21d3c7ba0dbaa9c8a01906b13ff3", + "sha256:d4bbc92fe4b8bfd2f3e8d88e5ba7085935da208ee38a134fc280e7ce682a05f2" + ], + "markers": "python_version >= '3.7'", + "version": "==2.23.4" + }, + "googleapis-common-protos": { + "hashes": [ + "sha256:22f1915393bb3245343f6efe87f6fe868532efc12aa26b391b15132e1279f1c0", + "sha256:8a64866a97f6304a7179873a465d6eee97b7a24ec6cfd78e0f575e96b821240b" + ], + "markers": "python_version >= '3.7'", + "version": "==1.61.0" + }, + "greenlet": { + "hashes": [ + "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174", + "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd", + "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa", + "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a", + "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec", + "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565", + "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d", + "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c", + "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234", + "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d", + "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546", + "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2", + "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74", + "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de", + "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd", + "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9", + "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3", + "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846", + "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2", + "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353", + "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8", + "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166", + "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206", + "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b", + "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d", + "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe", + "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997", + "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445", + "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0", + "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96", + "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884", + "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6", + "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1", + "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619", + "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94", + "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4", + "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1", + "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63", + "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd", + "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a", + "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376", + "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57", + "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16", + "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e", + "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc", + "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a", + "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c", + "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5", + "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a", + "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72", + "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9", + "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9", + "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e", + "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8", + "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65", + "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064", + "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36" + ], + "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')))))", + "version": "==3.0.1" + }, + "grpcio": { + "hashes": [ + "sha256:023088764012411affe7db183d1ada3ad9daf2e23ddc719ff46d7061de661340", + "sha256:08d77e682f2bf730a4961eea330e56d2f423c6a9b91ca222e5b1eb24a357b19f", + "sha256:0a4a3833c0e067f3558538727235cd8a49709bff1003200bbdefa2f09334e4b1", + "sha256:0a754aff9e3af63bdc4c75c234b86b9d14e14a28a30c4e324aed1a9b873d755f", + "sha256:11168ef43e4a43ff1b1a65859f3e0ef1a173e277349e7fb16923ff108160a8cd", + "sha256:128e20f57c5f27cb0157e73756d1586b83c1b513ebecc83ea0ac37e4b0e4e758", + "sha256:1f9524d1d701e399462d2c90ba7c193e49d1711cf429c0d3d97c966856e03d00", + "sha256:1ff16d68bf453275466a9a46739061a63584d92f18a0f5b33d19fc97eb69867c", + "sha256:2067274c88bc6de89c278a672a652b4247d088811ece781a4858b09bdf8448e3", + "sha256:2171c39f355ba5b551c5d5928d65aa6c69807fae195b86ef4a7d125bcdb860a9", + "sha256:242adc47725b9a499ee77c6a2e36688fa6c96484611f33b1be4c57ab075a92dd", + "sha256:27f879ae604a7fcf371e59fba6f3ff4635a4c2a64768bd83ff0cac503142fef4", + "sha256:2b230028a008ae1d0f430acb227d323ff8a619017415cf334c38b457f814119f", + "sha256:3059668df17627f0e0fa680e9ef8c995c946c792612e9518f5cc1503be14e90b", + "sha256:31176aa88f36020055ace9adff2405a33c8bdbfa72a9c4980e25d91b2f196873", + "sha256:36f53c2b3449c015880e7d55a89c992c357f176327b0d2873cdaaf9628a37c69", + "sha256:3b4368b33908f683a363f376dfb747d40af3463a6e5044afee07cf9436addf96", + "sha256:3c61d641d4f409c5ae46bfdd89ea42ce5ea233dcf69e74ce9ba32b503c727e29", + "sha256:4abb717e320e74959517dc8e84a9f48fbe90e9abe19c248541e9418b1ce60acd", + "sha256:4c93f4abbb54321ee6471e04a00139c80c754eda51064187963ddf98f5cf36a4", + "sha256:535561990e075fa6bd4b16c4c3c1096b9581b7bb35d96fac4650f1181e428268", + "sha256:53c9aa5ddd6857c0a1cd0287225a2a25873a8e09727c2e95c4aebb1be83a766a", + "sha256:5d573e70a6fe77555fb6143c12d3a7d3fa306632a3034b4e7c59ca09721546f8", + "sha256:6009386a2df66159f64ac9f20425ae25229b29b9dd0e1d3dd60043f037e2ad7e", + "sha256:686e975a5d16602dc0982c7c703948d17184bd1397e16c8ee03511ecb8c4cdda", + "sha256:6959fb07e8351e20501ffb8cc4074c39a0b7ef123e1c850a7f8f3afdc3a3da01", + "sha256:6b25ed37c27e652db01be341af93fbcea03d296c024d8a0e680017a268eb85dd", + "sha256:6da6dea3a1bacf99b3c2187e296db9a83029ed9c38fd4c52b7c9b7326d13c828", + "sha256:72ca2399097c0b758198f2ff30f7178d680de8a5cfcf3d9b73a63cf87455532e", + "sha256:73abb8584b0cf74d37f5ef61c10722adc7275502ab71789a8fe3cb7ef04cf6e2", + "sha256:74100fecaec8a535e380cf5f2fb556ff84957d481c13e54051c52e5baac70541", + "sha256:75c6ecb70e809cf1504465174343113f51f24bc61e22a80ae1c859f3f7034c6d", + "sha256:7cf05053242f61ba94014dd3a986e11a083400a32664058f80bf4cf817c0b3a1", + "sha256:9411e24328a2302e279e70cae6e479f1fddde79629fcb14e03e6d94b3956eabf", + "sha256:a213acfbf186b9f35803b52e4ca9addb153fc0b67f82a48f961be7000ecf6721", + "sha256:bb7e0fe6ad73b7f06d7e2b689c19a71cf5cc48f0c2bf8608469e51ffe0bd2867", + "sha256:c2504eed520958a5b77cc99458297cb7906308cb92327f35fb7fbbad4e9b2188", + "sha256:c35aa9657f5d5116d23b934568e0956bd50c615127810fffe3ac356a914c176a", + "sha256:c5f09cffa619adfb44799fa4a81c2a1ad77c887187613fb0a8f201ab38d89ba1", + "sha256:c978f864b35f2261e0819f5cd88b9830b04dc51bcf055aac3c601e525a10d2ba", + "sha256:cbe946b3e6e60a7b4618f091e62a029cb082b109a9d6b53962dd305087c6e4fd", + "sha256:cc3e4cd087f07758b16bef8f31d88dbb1b5da5671d2f03685ab52dece3d7a16e", + "sha256:cf0dead5a2c5a3347af2cfec7131d4f2a2e03c934af28989c9078f8241a491fa", + "sha256:d2794f0e68b3085d99b4f6ff9c089f6fdd02b32b9d3efdfbb55beac1bf22d516", + "sha256:d2fa68a96a30dd240be80bbad838a0ac81a61770611ff7952b889485970c4c71", + "sha256:d6f70406695e3220f09cd7a2f879333279d91aa4a8a1d34303b56d61a8180137", + "sha256:d8f9cd4ad1be90b0cf350a2f04a38a36e44a026cac1e036ac593dc48efe91d52", + "sha256:da2d94c15f88cd40d7e67f7919d4f60110d2b9d5b1e08cf354c2be773ab13479", + "sha256:e1727c1c0e394096bb9af185c6923e8ea55a5095b8af44f06903bcc0e06800a2", + "sha256:e420ced29b5904cdf9ee5545e23f9406189d8acb6750916c2db4793dada065c6", + "sha256:e82c5cf1495244adf5252f925ac5932e5fd288b3e5ab6b70bec5593074b7236c", + "sha256:f1ef0d39bc1feb420caf549b3c657c871cad4ebbcf0580c4d03816b0590de0cf", + "sha256:f8753a6c88d1d0ba64302309eecf20f70d2770f65ca02d83c2452279085bfcd3", + "sha256:f93dbf58f03146164048be5426ffde298b237a5e059144847e4940f5b80172c3" + ], + "markers": "python_version >= '3.7'", + "version": "==1.59.2" + }, + "gunicorn": { + "hashes": [ + "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0", + "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033" + ], + "index": "pypi", + "markers": "python_version >= '3.5'", + "version": "==21.2.0" + }, + "h11": { + "hashes": [ + "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", + "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" + }, + "httptools": { + "hashes": [ + "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563", + "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142", + "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d", + "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b", + "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4", + "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb", + "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658", + "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084", + "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2", + "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97", + "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837", + "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3", + "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58", + "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da", + "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d", + "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90", + "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0", + "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1", + "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2", + "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e", + "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0", + "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf", + "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc", + "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3", + "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503", + "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a", + "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3", + "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949", + "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84", + "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb", + "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a", + "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f", + "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e", + "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81", + "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185", + "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3" + ], + "version": "==0.6.1" + }, + "huggingface-hub": { + "hashes": [ + "sha256:40439632b211311f788964602bf8b0d9d6b7a2314fba4e8d67b2ce3ecea0e3fd", + "sha256:545eb3665f6ac587add946e73984148f2ea5c7877eac2e845549730570c1933a" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==0.17.3" + }, + "humanfriendly": { + "hashes": [ + "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", + "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==10.0" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "importlib-metadata": { + "hashes": [ + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" + ], + "markers": "python_version >= '3.8'", + "version": "==6.8.0" + }, + "importlib-resources": { + "hashes": [ + "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a", + "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6" + ], + "markers": "python_version >= '3.8'", + "version": "==6.1.1" + }, + "ipykernel": { + "hashes": [ + "sha256:3ba3dc97424b87b31bb46586b5167b3161b32d7820b9201a9e698c71e271602c", + "sha256:553856658eb8430bbe9653ea041a41bff63e9606fc4628873fc92a6cf3abd404" + ], + "markers": "python_version >= '3.8'", + "version": "==6.26.0" + }, + "ipython": { + "hashes": [ + "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb", + "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444" + ], + "markers": "python_version >= '3.9'", + "version": "==8.17.2" + }, + "isoduration": { + "hashes": [ + "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", + "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042" + ], + "version": "==20.11.0" + }, + "itsdangerous": { + "hashes": [ + "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", + "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.2" + }, + "jedi": { + "hashes": [ + "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", + "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" + ], + "markers": "python_version >= '3.6'", + "version": "==0.19.1" + }, + "jinja2": { + "hashes": [ + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.2" + }, + "json5": { + "hashes": [ + "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f", + "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02" + ], + "version": "==0.9.14" + }, + "jsonpointer": { + "hashes": [ + "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a", + "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88" + ], + "version": "==2.4" + }, + "jsonschema": { + "hashes": [ + "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392", + "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc" + ], + "markers": "python_version >= '3.8'", + "version": "==4.19.2" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1", + "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.7.1" + }, + "jupyter-client": { + "hashes": [ + "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7", + "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99" + ], + "markers": "python_version >= '3.8'", + "version": "==8.6.0" + }, + "jupyter-core": { + "hashes": [ + "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3", + "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805" + ], + "markers": "python_version >= '3.8'", + "version": "==5.5.0" + }, + "jupyter-events": { + "hashes": [ + "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399", + "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf" + ], + "markers": "python_version >= '3.8'", + "version": "==0.9.0" + }, + "jupyter-lsp": { + "hashes": [ + "sha256:8ebbcb533adb41e5d635eb8fe82956b0aafbf0fd443b6c4bfa906edeeb8635a1", + "sha256:9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.0" + }, + "jupyter-server": { + "hashes": [ + "sha256:47b8f5e63440125cb1bb8957bf12b18453ee5ed9efe42d2f7b2ca66a7019a278", + "sha256:dde56c9bc3cb52d7b72cc0f696d15d7163603526f1a758eb4a27405b73eab2a5" + ], + "markers": "python_version >= '3.8'", + "version": "==2.10.0" + }, + "jupyter-server-terminals": { + "hashes": [ + "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d", + "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36" + ], + "markers": "python_version >= '3.8'", + "version": "==0.4.4" + }, + "jupyterlab": { + "hashes": [ + "sha256:2ff5aa2a51eb21df241d6011c236e88bd1ff9a5dbb75bebc54472f9c18bfffa4", + "sha256:c4fe93f977bcc987bd395d7fae5ab02e0c042bf4e0f7c95196f3e2e578c2fb3a" + ], + "markers": "python_version >= '3.8'", + "version": "==4.0.8" + }, + "jupyterlab-pygments": { + "hashes": [ + "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f", + "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d" + ], + "markers": "python_version >= '3.7'", + "version": "==0.2.2" + }, + "jupyterlab-server": { + "hashes": [ + "sha256:6491283b0000698eae1a38c48507930560dfcf7461aea0015368698aab34dd9c", + "sha256:dce9714d91fb3e53d2b37d0e0619fa26ed223c8e7b8c81cca112926de19b53a4" + ], + "markers": "python_version >= '3.8'", + "version": "==2.25.1" + }, + "kubernetes": { + "hashes": [ + "sha256:10f56f8160dcb73647f15fafda268e7f60cf7dbc9f8e46d52fcd46d3beb0c18d", + "sha256:1468069a573430fb1cb5ad22876868f57977930f80a6749405da31cd6086a7e9" + ], + "markers": "python_version >= '3.6'", + "version": "==28.1.0" + }, + "langchain": { + "hashes": [ + "sha256:567ff99cf37195be2846148cdc71f545bfde60dfb7b948c63fc7d6c95f0609ec", + "sha256:bd452c76d447208ce27420c604a3e86461db710d2165bf4b310eabd53b437dcb" + ], + "index": "pypi", + "markers": "python_version < '4.0' and python_full_version >= '3.8.1'", + "version": "==0.0.296" + }, + "langsmith": { + "hashes": [ + "sha256:461acdcd8332d1325c16dc57e8a2d5ec9d1578490a4eaabe14db74db74ceaf21", + "sha256:e78c02501c2cff24fff7bd2d28ff3765b21675c7f0fcf6a09932bc218603c36e" + ], + "markers": "python_version < '4.0' and python_full_version >= '3.8.1'", + "version": "==0.0.64" + }, + "markupsafe": { + "hashes": [ + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", + "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", + "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.3" + }, + "marshmallow": { + "hashes": [ + "sha256:5d2371bbe42000f2b3fb5eaa065224df7d8f8597bc19a1bbfa5bfe7fba8da889", + "sha256:684939db93e80ad3561392f47be0230743131560a41c5110684c16e21ade0a5c" + ], + "markers": "python_version >= '3.8'", + "version": "==3.20.1" + }, + "matplotlib-inline": { + "hashes": [ + "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", + "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" + ], + "markers": "python_version >= '3.5'", + "version": "==0.1.6" + }, + "mistune": { + "hashes": [ + "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", + "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" + ], + "markers": "python_version >= '3.7'", + "version": "==3.0.2" + }, + "monotonic": { + "hashes": [ + "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7", + "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c" + ], + "version": "==1.6" + }, + "mpmath": { + "hashes": [ + "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", + "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c" + ], + "version": "==1.3.0" + }, + "multidict": { + "hashes": [ + "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", + "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", + "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", + "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", + "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", + "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", + "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", + "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", + "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", + "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", + "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", + "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", + "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", + "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", + "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", + "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", + "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", + "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", + "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", + "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", + "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", + "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", + "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", + "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", + "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", + "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", + "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", + "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", + "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", + "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", + "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", + "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", + "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", + "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", + "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", + "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", + "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", + "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", + "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", + "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", + "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", + "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", + "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", + "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", + "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", + "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", + "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", + "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", + "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", + "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", + "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", + "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", + "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", + "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", + "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", + "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", + "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", + "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", + "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", + "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", + "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", + "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", + "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", + "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", + "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", + "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", + "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", + "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", + "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", + "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", + "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", + "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", + "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", + "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + ], + "markers": "python_version >= '3.7'", + "version": "==6.0.4" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "nbclient": { + "hashes": [ + "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e", + "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==0.9.0" + }, + "nbconvert": { + "hashes": [ + "sha256:abedc01cf543177ffde0bfc2a69726d5a478f6af10a332fc1bf29fcb4f0cf000", + "sha256:d1d417b7f34a4e38887f8da5bdfd12372adf3b80f995d57556cb0972c68909fe" + ], + "markers": "python_version >= '3.8'", + "version": "==7.11.0" + }, + "nbformat": { + "hashes": [ + "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9", + "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192" + ], + "markers": "python_version >= '3.8'", + "version": "==5.9.2" + }, + "neo4j": { + "hashes": [ + "sha256:3200be8550ed16622b2fadf4f749d08b9982989c4bfce6f99ab693f104104cb4" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==5.14.1" + }, + "nest-asyncio": { + "hashes": [ + "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb", + "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d" + ], + "markers": "python_version >= '3.5'", + "version": "==1.5.8" + }, + "notebook": { + "hashes": [ + "sha256:0fe8f67102fea3744fedf652e4c15339390902ca70c5a31c4f547fa23da697cc", + "sha256:ec6113b06529019f7f287819af06c97a2baf7a95ac21a8f6e32192898e9f9a58" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==7.0.6" + }, + "notebook-shim": { + "hashes": [ + "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7", + "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9" + ], + "markers": "python_version >= '3.7'", + "version": "==0.2.3" + }, + "numexpr": { + "hashes": [ + "sha256:0983052f308ea75dd232eb7f4729eed839db8fe8d82289940342b32cc55b15d0", + "sha256:11121b14ee3179bade92e823f25f1b94e18716d33845db5081973331188c3338", + "sha256:32934d51b5bc8a6636436326da79ed380e2f151989968789cf65b1210572cb46", + "sha256:3a84284e0a407ca52980fd20962e89aff671c84cd6e73458f2e29ea2aa206356", + "sha256:47a249cecd1382d482a5bf1fac0d11392fb2ed0f7d415ebc4cd901959deb1ec9", + "sha256:4ecaa5be24cf8fa0f00108e9dfa1021b7510e9dd9d159b8d8bc7c7ddbb995b31", + "sha256:5340d2c86d83f52e1a3e7fd97c37d358ae99af9de316bdeeab2565b9b1e622ca", + "sha256:5496fc9e3ae214637cbca1ab556b0e602bd3afe9ff4c943a29c482430972cda8", + "sha256:56ec95f8d1db0819e64987dcf1789acd500fa4ea396eeabe4af6efdcb8902d07", + "sha256:596eeb3bbfebc912f4b6eaaf842b61ba722cebdb8bc42dfefa657d3a74953849", + "sha256:81451962d4145a46dba189df65df101d4d1caddb6efe6ebfe05982cd9f62b2cf", + "sha256:8bf005acd7f1985c71b1b247aaac8950d6ea05a0fe0bbbbf3f96cd398b136daa", + "sha256:a371cfc1670a18eea2d5c70abaa95a0e8824b70d28da884bad11931266e3a0ca", + "sha256:a4546416004ff2e7eb9cf52c2d7ab82732b1b505593193ee9f93fa770edc5230", + "sha256:b8a5b2c21c26b62875bf819d375d798b96a32644e3c28bd4ce7789ed1fb489da", + "sha256:c7bf60fc1a9c90a9cb21c4c235723e579bff70c8d5362228cb2cf34426104ba2", + "sha256:cb2f473fdfd09d17db3038e34818d05b6bc561a36785aa927d6c0e06bccc9911", + "sha256:cf5f112bce5c5966c47cc33700bc14ce745c8351d437ed57a9574fff581f341a", + "sha256:d43f1f0253a6f2db2f76214e6f7ae9611b422cba3f7d4c86415d7a78bbbd606f", + "sha256:d46c47e361fa60966a3339cb4f463ae6151ce7d78ed38075f06e8585d2c8929f", + "sha256:d88531ffea3ea9287e8a1665c6a2d0206d3f4660d5244423e2a134a7f0ce5fba", + "sha256:da55ba845b847cc33c4bf81cee4b1bddfb0831118cabff8db62888ab8697ec34", + "sha256:db1065ba663a854115cf1f493afd7206e2efcef6643129e8061e97a51ad66ebb", + "sha256:dccf572763517db6562fb7b17db46aacbbf62a9ca0a66672872f4f71aee7b186", + "sha256:e838289e3b7bbe100b99e35496e6cc4cc0541c2207078941ee5a1d46e6b925ae", + "sha256:f021ac93cb3dd5d8ba2882627b615b1f58cb089dcc85764c6fbe7a549ed21b0c", + "sha256:f29f4d08d9b0ed6fa5d32082971294b2f9131b8577c2b7c36432ed670924313f", + "sha256:f3bdf8cbc00c77a46230c765d242f92d35905c239b20c256c48dbac91e49f253", + "sha256:fd93b88d5332069916fa00829ea1b972b7e73abcb1081eee5c905a514b8b59e3" + ], + "markers": "python_version >= '3.9'", + "version": "==2.8.7" + }, + "numpy": { + "hashes": [ + "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a", + "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6", + "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2", + "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79", + "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9", + "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919", + "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d", + "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060", + "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75", + "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f", + "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe", + "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167", + "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef", + "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75", + "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3", + "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7", + "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7", + "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d", + "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b", + "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186", + "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0", + "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1", + "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6", + "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e", + "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523", + "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36", + "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841", + "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818", + "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00", + "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80", + "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440", + "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210", + "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8", + "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea", + "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec", + "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841" + ], + "markers": "python_version >= '3.9'", + "version": "==1.26.2" + }, + "oauthlib": { + "hashes": [ + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.2" + }, + "onnxruntime": { + "hashes": [ + "sha256:0ffd3b8a3039be713476b8783d254564976664c9b51ec70e7fb5d3e2832bf0f0", + "sha256:16217fa87d3482300a91036f9b499c85215a3b495de1ef9a68cbcf3df1a7c548", + "sha256:1f1e90fa0f43e988cd043e5a4b1eb77eda6cbd7523f316d93d36b33ff1ceb91f", + "sha256:3382934f9d86060b6bacd3eb4633c5ff904be2c99d3a7fb7faf2828381b15928", + "sha256:4fed41edb766c6adea6c34f1eb63a344d697fd4625133e5e48f23950bce60803", + "sha256:68f8d3347f11fcc6256266c562e4314b8c6da3e30fc275052a2ab693540b17fd", + "sha256:713101b65d74438f380f5ea2475ce4f6026171e6229100e5be2baa92519fca17", + "sha256:773c231e526f815b8a3f3549d216cd8fed4c9e226e9e16e86af1b69a4bd29b58", + "sha256:773f6d99d1e6a58936a55a4933c66674241dace9ec4bab71664cdfa170a7cd87", + "sha256:7cadf175baa782599f36586c23f84fe12b02702ceb59be57dbd8eefc6cc13cc4", + "sha256:8616f56905775dd8beeae11cf145542fff06c38cd97bfe9afe0c4a66142fc6d5", + "sha256:90e83a93b3d946c4a1d9dcbae286350accb0d80512d7c1b85953a444d19c0058", + "sha256:98a49bda980bcf819f8d9be880e3e7ba8a1df66aa5ce4fc7bb68ba9acf1fc7ad", + "sha256:9f5e1d5ca5560044896edb2ad79113f863dc7daa804a26787c7b21c2a96d41e7", + "sha256:9fc410ec220804fb384e7cb4fd68c474d89da11a1b68184db2001d64ba1477a9", + "sha256:aa09d8d9d9a4dc2f6647b5135bb540da36e2d78206aaf14140ba73e05928c4f8", + "sha256:b0cbdb7df8078b2e8d9804de948963961eb8c6f417ef35ed243455162a9a065c", + "sha256:b93c1cbd885c5fe0018b982c9dabe3cc3531416a3b50d0958a291605b32fe3ce", + "sha256:b97ce538ffb668c4897e7500a586c150a045869876e0234e0611c4e4f428be63", + "sha256:ce6b7046005442fcd09b86647bdc9a85d60c1367cb36ce7f16b942744cf27fe4", + "sha256:ceef600de846997e3ef5f9af956ae87c88d84d6e925c3e9d435ce17ea223568f", + "sha256:e19316bb15c29ca0397e78861ee7cdb4db763ac5c53eaa83169bcdcb1149878c", + "sha256:e2211f336e83819edbf174dcf56de35b0dcbfc6c92d3b685c8d85fba19bdf97d", + "sha256:e8b8df9583a6e874f1983b85a361d22c205c96e926626eb486d3e69d72642f79" + ], + "version": "==1.16.2" + }, + "openai": { + "hashes": [ + "sha256:417b78c4c2864ba696aedaf1ccff77be1f04a581ab1739f0a56e0aae19e5a794", + "sha256:d207ece78469be5648eb87b825753282225155a29d0eec6e02013ddbf8c31c0c" + ], + "index": "pypi", + "markers": "python_full_version >= '3.7.1'", + "version": "==0.28.0" + }, + "opentelemetry-api": { + "hashes": [ + "sha256:4bb86b28627b7e41098f0e93280fe4892a1abed1b79a19aec6f928f39b17dffb", + "sha256:d6185fd5043e000075d921822fd2d26b953eba8ca21b1e2fa360dd46a7686316" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-common": { + "hashes": [ + "sha256:61db274d8a68d636fb2ec2a0f281922949361cdd8236e25ff5539edf942b3226", + "sha256:97b1022b38270ec65d11fbfa348e0cd49d12006485c2321ea3b1b7037d42b6ec" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-grpc": { + "hashes": [ + "sha256:a497c5611245a2d17d9aa1e1cbb7ab567843d53231dcc844a62cea9f0924ffa7", + "sha256:ab37c63d6cb58d6506f76d71d07018eb1f561d83e642a8f5aa53dddf306087a4" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-proto": { + "hashes": [ + "sha256:32fc4248e83eebd80994e13963e683f25f3b443226336bb12b5b6d53638f50ba", + "sha256:7d5172c29ed1b525b5ecf4ebe758c7138a9224441b3cfe683d0a237c33b1941f" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-sdk": { + "hashes": [ + "sha256:3ec8cd3020328d6bc5c9991ccaf9ae820ccb6395a5648d9a95d3ec88275b8879", + "sha256:9fe633243a8c655fedace3a0b89ccdfc654c0290ea2d8e839bd5db3131186f73" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-semantic-conventions": { + "hashes": [ + "sha256:44ae67a0a3252a05072877857e5cc1242c98d4cf12870159f1a94bec800d38ec", + "sha256:5cd719cbfec448af658860796c5d0fcea2fdf0945a2bed2363f42cb1ee39f526" + ], + "markers": "python_version >= '3.7'", + "version": "==0.42b0" + }, + "overrides": { + "hashes": [ + "sha256:3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d", + "sha256:9502a3cca51f4fac40b5feca985b6703a5c1f6ad815588a7ca9e285b9dca6757" + ], + "markers": "python_version >= '3.6'", + "version": "==7.4.0" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "pandocfilters": { + "hashes": [ + "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38", + "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.5.0" + }, + "parso": { + "hashes": [ + "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", + "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" + ], + "markers": "python_version >= '3.6'", + "version": "==0.8.3" + }, + "pexpect": { + "hashes": [ + "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", + "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + ], + "markers": "sys_platform != 'win32'", + "version": "==4.8.0" + }, + "platformdirs": { + "hashes": [ + "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", + "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.0" + }, + "posthog": { + "hashes": [ + "sha256:701fba6e446a4de687c6e861b587e7b7741955ad624bf34fe013c06a0fec6fb3", + "sha256:a8c0af6f2401fbe50f90e68c4143d0824b54e872de036b1c2f23b5abb39d88ce" + ], + "version": "==3.0.2" + }, + "prometheus-client": { + "hashes": [ + "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17", + "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184" + ], + "markers": "python_version >= '3.8'", + "version": "==0.18.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", + "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.0.41" + }, + "protobuf": { + "hashes": [ + "sha256:1a3ba712877e6d37013cdc3476040ea1e313a6c2e1580836a94f76b3c176d575", + "sha256:1a53d6f64b00eecf53b65ff4a8c23dc95df1fa1e97bb06b8122e5a64f49fc90a", + "sha256:32ac2100b0e23412413d948c03060184d34a7c50b3e5d7524ee96ac2b10acf51", + "sha256:5c1203ac9f50e4853b0a0bfffd32c67118ef552a33942982eeab543f5c634395", + "sha256:63714e79b761a37048c9701a37438aa29945cd2417a97076048232c1df07b701", + "sha256:683dc44c61f2620b32ce4927de2108f3ebe8ccf2fd716e1e684e5a50da154054", + "sha256:68f7caf0d4f012fd194a301420cf6aa258366144d814f358c5b32558228afa7c", + "sha256:b2cf8b5d381f9378afe84618288b239e75665fe58d0f3fd5db400959274296e9", + "sha256:c40ff8f00aa737938c5378d461637d15c442a12275a81019cc2fef06d81c9419", + "sha256:cf21faba64cd2c9a3ed92b7a67f226296b10159dbb8fbc5e854fc90657d908e4", + "sha256:d94a33db8b7ddbd0af7c467475fb9fde0c705fb315a8433c0e2020942b863a1f" + ], + "markers": "python_version >= '3.8'", + "version": "==4.25.0" + }, + "psutil": { + "hashes": [ + "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28", + "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017", + "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602", + "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac", + "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a", + "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9", + "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4", + "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c", + "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c", + "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c", + "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a", + "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c", + "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57", + "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a", + "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d", + "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==5.9.6" + }, + "ptyprocess": { + "hashes": [ + "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", + "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" + ], + "markers": "os_name != 'nt'", + "version": "==0.7.0" + }, + "pulsar-client": { + "hashes": [ + "sha256:0f64c62746ccd5b65a0c505f5f40b9af1f147eb1fa2d8f9c90cd5c8b92dd8597", + "sha256:1e4b5d44b992c9b036286b483f3588c10b89c6047fb59d80c7474445997f4e10", + "sha256:1f66982284571674b215324cc26b5c2f7c56c7043113c47a7084cb70d67a8afb", + "sha256:33656450536d83eed1563ff09692c2c415fb199d88e9ed97d701ca446a119e1b", + "sha256:33c4e6865fda62a2e460f823dce4d49ac2973a4459b8ff99eda5fdd6aaaebf46", + "sha256:386e78ff52058d881780bae1f6e84ac9434ae0b01a8581755ca8cc0dc844a332", + "sha256:3e4ecb780df58bcfd3918590bd3ff31ed79bccfbef3a1a60370642eb1e14a9d2", + "sha256:42c8f3eaa98e2351805ecb6efb6d5fedf47a314a3ce6af0e05ea1449ea7244ed", + "sha256:43f98afdf0334b2b957a4d96f97a1fe8a7f7fd1e2631d40c3f00b4162f396485", + "sha256:497a59ac6b650835a3b2c502f53477e5c98e5226998ca3f17c0b0a3eb4d67d08", + "sha256:5b84a20c9012e3c4ef1b7085acd7467197118c090b378dec27d773fb79d91556", + "sha256:5e69750f8ae57e55fddf97b459ce0d8b38b2bb85f464a71e871ee6a86d893be7", + "sha256:5e7a48b2e505cde758fd51a601b5da0671fa98c9baee38362aaaa3ab2b930c28", + "sha256:694530af1d6c75fb81456fb509778c1868adee31e997ddece6e21678200182ea", + "sha256:72cbb1bdcba2dd1265296b5ba65331622ee89c16db75edaad46dd7b90c6dd447", + "sha256:7b5dd25cf778d6c980d36c53081e843ea272afe7af4f0ad6394ae9513f94641b", + "sha256:7ce1e215c252f22a6f26ca5e9076826041a04d88dc213b92c86b524be2774a64", + "sha256:7e147e5ba460c1818bc05254279a885b4e552bcafb8961d40e31f98d5ff46628", + "sha256:7fe50a06f81c48a75a9b95c27a6446260039adca71d9face273740de96b2efca", + "sha256:8259c3b856eb6deaa1f93dce893ab18d99d36d102da5612c8e97a4fb41b70ab1", + "sha256:88b0fd5be73a4103986b9dbe3a66468cf8829371e34af87ff8f216e3980f4cbe", + "sha256:c31afd3e67a044ff93177df89e08febf214cc965e95ede097d9fe8755af00e01", + "sha256:c4e15fa696e275ccb66d0791fdc19c4dea0420d81349c8055e485b134125e14f", + "sha256:ce33de700b06583df8777e139d68cb4b4b3d0a2eac168d74278d8935f357fb10", + "sha256:d4c46a4b96a6e9919cfe220156d69a2ede8053d9ea1add4ada108abcf2ba9775", + "sha256:d54dd12955bf587dd46d9184444af5e853d9da2a14bbfb739ed2c7c3b78ce280", + "sha256:ede264385d47257b2f2b08ecde9181ec5338bea5639cc543d1856f01736778d2", + "sha256:efe7c1e6a96daccc522c3567b6847ffa54c13e0f510d9a427b4aeff9fbebe54b", + "sha256:f1810ddc623c8de2675d17405ce47057a9a2b92298e708ce4d9564847f5ad904", + "sha256:f28e94420090fceeb38e23fc744f3edf8710e48314ef5927d2b674a1d1e43ee0" + ], + "version": "==3.3.0" + }, + "pure-eval": { + "hashes": [ + "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", + "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" + ], + "version": "==0.2.2" + }, + "pyasn1": { + "hashes": [ + "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", + "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.5.0" + }, + "pyasn1-modules": { + "hashes": [ + "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c", + "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==0.3.0" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pydantic": { + "hashes": [ + "sha256:69bd6fb62d2d04b7055f59a396993486a2ee586c43a0b89231ce0000de07627c", + "sha256:7ce6e766c456ad026fe5712f7bcf036efc34bd5d107b3e669ef7ea01b3a9050c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.5.0" + }, + "pydantic-core": { + "hashes": [ + "sha256:023b6d7ec4e97890b28eb2ee24413e69a6d48de4e8b75123957edd5432f4eeb3", + "sha256:052d8731aaf844f91fe4cd3faf28983b109a5865b3a256ec550b80a5689ead87", + "sha256:0a8c8daf4e3aa3aeb98e3638fc3d58a359738f3d12590b2474c6bb64031a0764", + "sha256:0d82a6ee815388a362885186e431fac84c7a06623bc136f508e9f88261d8cadb", + "sha256:101df420e954966868b8bc992aefed5fa71dd1f2755104da62ee247abab28e2f", + "sha256:102ac85a775e77821943ae38da9634ddd774b37a8d407181b4f7b05cdfb36b55", + "sha256:1185548665bc61bbab0dc78f10c8eafa0db0aa1e920fe9a451b77782b10a65cc", + "sha256:12163197fec7c95751a3c71b36dcc1909eed9959f011ffc79cc8170a6a74c826", + "sha256:130e49aa0cb316f743bc7792c36aefa39fc2221312f1d4b333b19edbdd71f2b1", + "sha256:132b40e479cb5cebbbb681f77aaceabbc8355df16c9124cff1d4060ada83cde2", + "sha256:144f2c1d5579108b6ed1193fcc9926124bd4142b0f7020a7744980d1235c8a40", + "sha256:16f4a7e1ec6b3ea98a1e108a2739710cd659d68b33fbbeaba066202cab69c7b6", + "sha256:184ff7b30c3f60e1b775378c060099285fd4b5249271046c9005f8b247b39377", + "sha256:1bfb63821ada76719ffcd703fc40dd57962e0d8c253e3c565252e6de6d3e0bc6", + "sha256:1e7208946ea9b27a8cef13822c339d4ae96e45952cc01fc4a91c7f1cb0ae2861", + "sha256:217dcbfaf429a9b8f1d54eb380908b9c778e78f31378283b30ba463c21e89d5d", + "sha256:2459cc06572730e079ec1e694e8f68c99d977b40d98748ae72ff11ef21a56b0b", + "sha256:24ba48f9d0b8d64fc5e42e1600366c3d7db701201294989aebdaca23110c02ab", + "sha256:26242e3593d4929123615bd9365dd86ef79b7b0592d64a96cd11fd83c69c9f34", + "sha256:2871daf5b2823bf77bf7d3d43825e5d904030c155affdf84b21a00a2e00821d2", + "sha256:28734bcfb8fc5b03293dec5eb5ea73b32ff767f6ef79a31f6e41dad2f5470270", + "sha256:2a7d08b39fac97540fba785fce3b21ee01a81f081a07a4d031efd791da6666f9", + "sha256:2be018a84995b6be1bbd40d6064395dbf71592a981169cf154c0885637f5f54a", + "sha256:3303113fdfaca927ef11e0c5f109e2ec196c404f9d7ba5f8ddb63cdf287ea159", + "sha256:36c3bf96f803e207a80dbcb633d82b98ff02a9faa76dd446e969424dec8e2b9f", + "sha256:3d5b2a4b3c10cad0615670cab99059441ff42e92cf793a0336f4bc611e895204", + "sha256:3f48d4afd973abbd65266ac24b24de1591116880efc7729caf6b6b94a9654c9e", + "sha256:42d5d0e9bbb50481a049bd0203224b339d4db04006b78564df2b782e2fd16ebc", + "sha256:443dc5eede7fa76b2370213e0abe881eb17c96f7d694501853c11d5d56916602", + "sha256:49ee28d65f506b2858a60745cc974ed005298ebab12693646b97641dd7c99c35", + "sha256:4f0788699a92d604f348e9c1ac5e97e304e97127ba8325c7d0af88dcc7d35bd3", + "sha256:51506e7652a2ef1d1cf763c4b51b972ff4568d1dddc96ca83931a6941f5e6389", + "sha256:53efe03cc383a83660cfdda6a3cb40ee31372cedea0fde0b2a2e55e838873ab6", + "sha256:55713d155da1e508083c4b08d0b1ad2c3054f68b8ef7eb3d3864822e456f0bb5", + "sha256:581bb606a31749a00796f5257947a0968182d7fe91e1dada41f06aeb6bfbc91a", + "sha256:5879ac4791508d8f0eb7dec71ff8521855180688dac0c55f8c99fc4d1a939845", + "sha256:587d75aec9ae50d0d63788cec38bf13c5128b3fc1411aa4b9398ebac884ab179", + "sha256:59fa83873223f856d898452c6162a390af4297756f6ba38493a67533387d85d9", + "sha256:5a1570875eb0d1479fb2270ed80c88c231aaaf68b0c3f114f35e7fb610435e4f", + "sha256:5b45b7be9f99991405ecd6f6172fb6798908a8097106ae78d5cc5cc15121bad9", + "sha256:6015beb28deb5306049ecf2519a59627e9e050892927850a884df6d5672f8c7d", + "sha256:6590ed9d13eb51b28ea17ddcc6c8dbd6050b4eb589d497105f0e13339f223b72", + "sha256:66dc0e63349ec39c1ea66622aa5c2c1f84382112afd3ab2fa0cca4fb01f7db39", + "sha256:679cc4e184f213c8227862e57340d12fd4d4d19dc0e3ddb0f653f86f01e90f94", + "sha256:69cd74e55a5326d920e7b46daa2d81c2bdb8bcf588eafb2330d981297b742ddc", + "sha256:69df82892ff00491d673b1929538efb8c8d68f534fdc6cb7fd3ac8a5852b9034", + "sha256:72c2ef3787c3b577e5d6225d73a77167b942d12cef3c1fbd5e74e55b7f881c36", + "sha256:744b807fe2733b6da3b53e8ad93e8b3ea3ee3dfc3abece4dd2824cc1f39aa343", + "sha256:7977e261cac5f99873dc2c6f044315d09b19a71c4246560e1e67593889a90978", + "sha256:798590d38c9381f07c48d13af1f1ef337cebf76ee452fcec5deb04aceced51c7", + "sha256:812beca1dcb2b722cccc7e9c620bd972cbc323321194ec2725eab3222e6ac573", + "sha256:8276bbab68a9dbe721da92d19cbc061f76655248fe24fb63969d0c3e0e5755e7", + "sha256:85bb66d661be51b2cba9ca06759264b3469d2dbb53c3e6effb3f05fec6322be6", + "sha256:871c641a83719caaa856a11dcc61c5e5b35b0db888e1a0d338fe67ce744575e2", + "sha256:893bf4fb9bfb9c4639bc12f3de323325ada4c6d60e478d5cded65453e9364890", + "sha256:8d927d042c0ef04607ee7822828b208ab045867d20477ec6593d612156798547", + "sha256:8e17f0c3ba4cb07faa0038a59ce162de584ed48ba645c8d05a5de1e40d4c21e7", + "sha256:9486e27bb3f137f33e2315be2baa0b0b983dae9e2f5f5395240178ad8e644728", + "sha256:94cf6d0274eb899d39189144dcf52814c67f9b0fd196f211420d9aac793df2da", + "sha256:97246f896b4df7fd84caa8a75a67abb95f94bc0b547665bf0889e3262b060399", + "sha256:9d59e0d7cdfe8ed1d4fcd28aad09625c715dc18976c7067e37d8a11b06f4be3e", + "sha256:a15f6e5588f7afb7f6fc4b0f4ff064749e515d34f34c666ed6e37933873d8ad8", + "sha256:a2ccdc53cb88e51c7d47d74c59630d7be844428f6b8d463055ffad6f0392d8da", + "sha256:a68a36d71c7f638dda6c9e6b67f6aabf3fa1471b198d246457bfdc7c777cdeb7", + "sha256:a7991f25b98038252363a03e6a9fe92e60fe390fda2631d238dc3b0e396632f8", + "sha256:aadf74a40a7ae49c3c1aa7d32334fe94f4f968e21dd948e301bb4ed431fb2412", + "sha256:abae6fd5504e5e438e4f6f739f8364fd9ff5a5cdca897e68363e2318af90bc28", + "sha256:ac417312bf6b7a0223ba73fb12e26b2854c93bf5b1911f7afef6d24c379b22aa", + "sha256:ad9ea86f5fc50f1b62c31184767fe0cacaa13b54fe57d38898c3776d30602411", + "sha256:b4ff385a525017f5adf6066d7f9fb309f99ade725dcf17ed623dc7dce1f85d9f", + "sha256:b89821a2c77cc1b8f2c1fc3aacd6a3ecc5df8f7e518dc3f18aef8c4dcf66003d", + "sha256:b8ff0302518dcd001bd722bbe342919c29e5066c7eda86828fe08cdc112668b8", + "sha256:b91b5ec423e88caa16777094c4b2b97f11453283e7a837e5e5e1b886abba1251", + "sha256:ba55d73a2df4771b211d0bcdea8b79454980a81ed34a1d77a19ddcc81f98c895", + "sha256:bb1c6ecb53e4b907ee8486f453dd940b8cbb509946e2b671e3bf807d310a96fc", + "sha256:bc6a4ea9f88a810cb65ccae14404da846e2a02dd5c0ad21dee712ff69d142638", + "sha256:c36987f5eb2a7856b5f5feacc3be206b4d1852a6ce799f6799dd9ffb0cba56ae", + "sha256:c6e98227eb02623d57e1fd061788837834b68bb995a869565211b9abf3de4bf4", + "sha256:c7411cd06afeb263182e38c6ca5b4f5fe4f20d91466ad7db0cd6af453a02edec", + "sha256:c8c466facec2ccdf025b0b1455b18f2c3d574d5f64d24df905d3d7b8f05d5f4e", + "sha256:c964c0cc443d6c08a2347c0e5c1fc2d85a272dc66c1a6f3cde4fc4843882ada4", + "sha256:ca942a2dc066ca5e04c27feaa8dfb9d353ddad14c6641660c565149186095343", + "sha256:cb2fd3ab67558eb16aecfb4f2db4febb4d37dc74e6b8613dc2e7160fb58158a9", + "sha256:d312ad20e3c6d179cb97c42232b53111bcd8dcdd5c1136083db9d6bdd489bc73", + "sha256:d965bdb50725a805b083f5f58d05669a85705f50a6a864e31b545c589290ee31", + "sha256:d983222223f63e323a5f497f5b85e211557a5d8fb670dc88f343784502b466ba", + "sha256:dee4682bd7947afc682d342a8d65ad1834583132383f8e801601a8698cb8d17a", + "sha256:e2be646a5155d408e68b560c0553e8a83dc7b9f90ec6e5a2fc3ff216719385db", + "sha256:e2c689439f262c29cf3fcd5364da1e64d8600facecf9eabea8643b8755d2f0de", + "sha256:e5a111f9158555582deadd202a60bd7803b6c68f406391b7cf6905adf0af6811", + "sha256:e905014815687d88cbb14bbc0496420526cf20d49f20606537d87646b70f1046", + "sha256:ebc79120e105e4bcd7865f369e3b9dbabb0d492d221e1a7f62a3e8e292550278", + "sha256:f1a30eef060e21af22c7d23349f1028de0611f522941c80efa51c05a63142c62", + "sha256:f483467c046f549572f8aca3b7128829e09ae3a9fe933ea421f7cb7c58120edb", + "sha256:f523e116879bc6714e61d447ce934676473b068069dce6563ea040381dc7a257", + "sha256:f53a3ccdc30234cb4342cec541e3e6ed87799c7ca552f0b5f44e3967a5fed526", + "sha256:fb290491f1f0786a7da4585250f1feee200fc17ff64855bdd7c42fb54526fa29", + "sha256:fc3227408808ba7df8e95eb1d8389f4ba2203bed8240b308de1d7ae66d828f24", + "sha256:fd80a2d383940eec3db6a5b59d1820f947317acc5c75482ff8d79bf700f8ad6a", + "sha256:fd937733bf2fe7d6a8bf208c12741f1f730b7bf5636033877767a75093c29b8a", + "sha256:ffba979801e3931a19cd30ed2049450820effe8f152aaa317e2fd93795d318d7" + ], + "markers": "python_version >= '3.7'", + "version": "==2.14.1" + }, + "pygments": { + "hashes": [ + "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", + "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" + ], + "markers": "python_version >= '3.7'", + "version": "==2.16.1" + }, + "pyjwt": { + "hashes": [ + "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", + "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" + ], + "markers": "python_version >= '3.7'", + "version": "==2.8.0" + }, + "pypika": { + "hashes": [ + "sha256:838836a61747e7c8380cd1b7ff638694b7a7335345d0f559b04b2cd832ad5378" + ], + "version": "==0.48.9" + }, + "python-arango": { + "hashes": [ + "sha256:8ae893d32220bbf7d0158fd8675a011219076189c82371543df75d650f9d0707", + "sha256:e8e9caefd65b21c263ec399d5d73ddaf119288cf684ffacada2c28cba322d2ba" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==7.6.2" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.2" + }, + "python-dotenv": { + "hashes": [ + "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", + "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" + ], + "version": "==1.0.0" + }, + "python-json-logger": { + "hashes": [ + "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c", + "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.7" + }, + "pytz": { + "hashes": [ + "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b", + "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7" + ], + "version": "==2023.3.post1" + }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "pyzmq": { + "hashes": [ + "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a", + "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf", + "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45", + "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505", + "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2", + "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e", + "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f", + "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2", + "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55", + "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd", + "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2", + "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf", + "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae", + "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a", + "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5", + "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222", + "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0", + "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b", + "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23", + "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618", + "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062", + "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9", + "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414", + "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2", + "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a", + "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f", + "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa", + "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123", + "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790", + "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb", + "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76", + "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0", + "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6", + "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3", + "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978", + "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a", + "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb", + "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1", + "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6", + "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995", + "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7", + "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f", + "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304", + "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e", + "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e", + "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849", + "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329", + "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71", + "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728", + "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115", + "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752", + "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8", + "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a", + "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c", + "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8", + "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8", + "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83", + "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c", + "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69", + "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a", + "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996", + "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3", + "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6", + "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369", + "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28", + "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075", + "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0", + "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c", + "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca", + "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9", + "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800", + "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6", + "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb", + "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d", + "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22", + "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb", + "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71", + "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83", + "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae", + "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb", + "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d", + "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2", + "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0", + "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7", + "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008", + "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762", + "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec", + "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef", + "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180", + "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787", + "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e", + "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7", + "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4" + ], + "markers": "python_version >= '3.6'", + "version": "==25.1.1" + }, + "redis": { + "hashes": [ + "sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0", + "sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==5.0.0" + }, + "referencing": { + "hashes": [ + "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf", + "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0" + ], + "markers": "python_version >= '3.8'", + "version": "==0.30.2" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "requests-oauthlib": { + "hashes": [ + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.0.0" + }, + "rfc3339-validator": { + "hashes": [ + "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", + "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.1.4" + }, + "rfc3986-validator": { + "hashes": [ + "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", + "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.1.1" + }, + "rpds-py": { + "hashes": [ + "sha256:0525847f83f506aa1e28eb2057b696fe38217e12931c8b1b02198cfe6975e142", + "sha256:05942656cb2cb4989cd50ced52df16be94d344eae5097e8583966a1d27da73a5", + "sha256:0831d3ecdea22e4559cc1793f22e77067c9d8c451d55ae6a75bf1d116a8e7f42", + "sha256:0853da3d5e9bc6a07b2486054a410b7b03f34046c123c6561b535bb48cc509e1", + "sha256:08e6e7ff286254016b945e1ab632ee843e43d45e40683b66dd12b73791366dd1", + "sha256:0a38612d07a36138507d69646c470aedbfe2b75b43a4643f7bd8e51e52779624", + "sha256:0bedd91ae1dd142a4dc15970ed2c729ff6c73f33a40fa84ed0cdbf55de87c777", + "sha256:0c5441b7626c29dbd54a3f6f3713ec8e956b009f419ffdaaa3c80eaf98ddb523", + "sha256:0e9e976e0dbed4f51c56db10831c9623d0fd67aac02853fe5476262e5a22acb7", + "sha256:0fadfdda275c838cba5102c7f90a20f2abd7727bf8f4a2b654a5b617529c5c18", + "sha256:1096ca0bf2d3426cbe79d4ccc91dc5aaa73629b08ea2d8467375fad8447ce11a", + "sha256:171d9a159f1b2f42a42a64a985e4ba46fc7268c78299272ceba970743a67ee50", + "sha256:188912b22b6c8225f4c4ffa020a2baa6ad8fabb3c141a12dbe6edbb34e7f1425", + "sha256:1b4cf9ab9a0ae0cb122685209806d3f1dcb63b9fccdf1424fb42a129dc8c2faa", + "sha256:1e04581c6117ad9479b6cfae313e212fe0dfa226ac727755f0d539cd54792963", + "sha256:1fa73ed22c40a1bec98d7c93b5659cd35abcfa5a0a95ce876b91adbda170537c", + "sha256:2124f9e645a94ab7c853bc0a3644e0ca8ffbe5bb2d72db49aef8f9ec1c285733", + "sha256:240687b5be0f91fbde4936a329c9b7589d9259742766f74de575e1b2046575e4", + "sha256:25740fb56e8bd37692ed380e15ec734be44d7c71974d8993f452b4527814601e", + "sha256:27ccc93c7457ef890b0dd31564d2a05e1aca330623c942b7e818e9e7c2669ee4", + "sha256:281c8b219d4f4b3581b918b816764098d04964915b2f272d1476654143801aa2", + "sha256:2d34a5450a402b00d20aeb7632489ffa2556ca7b26f4a63c35f6fccae1977427", + "sha256:301bd744a1adaa2f6a5e06c98f1ac2b6f8dc31a5c23b838f862d65e32fca0d4b", + "sha256:30e5ce9f501fb1f970e4a59098028cf20676dee64fc496d55c33e04bbbee097d", + "sha256:33ab498f9ac30598b6406e2be1b45fd231195b83d948ebd4bd77f337cb6a2bff", + "sha256:35585a8cb5917161f42c2104567bb83a1d96194095fc54a543113ed5df9fa436", + "sha256:389c0e38358fdc4e38e9995e7291269a3aead7acfcf8942010ee7bc5baee091c", + "sha256:3acadbab8b59f63b87b518e09c4c64b142e7286b9ca7a208107d6f9f4c393c5c", + "sha256:3b7a64d43e2a1fa2dd46b678e00cabd9a49ebb123b339ce799204c44a593ae1c", + "sha256:3c8c0226c71bd0ce9892eaf6afa77ae8f43a3d9313124a03df0b389c01f832de", + "sha256:429349a510da82c85431f0f3e66212d83efe9fd2850f50f339341b6532c62fe4", + "sha256:466030a42724780794dea71eb32db83cc51214d66ab3fb3156edd88b9c8f0d78", + "sha256:47aeceb4363851d17f63069318ba5721ae695d9da55d599b4d6fb31508595278", + "sha256:48aa98987d54a46e13e6954880056c204700c65616af4395d1f0639eba11764b", + "sha256:4b2416ed743ec5debcf61e1242e012652a4348de14ecc7df3512da072b074440", + "sha256:4d0a675a7acbbc16179188d8c6d0afb8628604fc1241faf41007255957335a0b", + "sha256:4eb74d44776b0fb0782560ea84d986dffec8ddd94947f383eba2284b0f32e35e", + "sha256:4f8a1d990dc198a6c68ec3d9a637ba1ce489b38cbfb65440a27901afbc5df575", + "sha256:513ccbf7420c30e283c25c82d5a8f439d625a838d3ba69e79a110c260c46813f", + "sha256:5210a0018c7e09c75fa788648617ebba861ae242944111d3079034e14498223f", + "sha256:54cdfcda59251b9c2f87a05d038c2ae02121219a04d4a1e6fc345794295bdc07", + "sha256:56dd500411d03c5e9927a1eb55621e906837a83b02350a9dc401247d0353717c", + "sha256:57ec6baec231bb19bb5fd5fc7bae21231860a1605174b11585660236627e390e", + "sha256:5f1519b080d8ce0a814f17ad9fb49fb3a1d4d7ce5891f5c85fc38631ca3a8dc4", + "sha256:6174d6ad6b58a6bcf67afbbf1723420a53d06c4b89f4c50763d6fa0a6ac9afd2", + "sha256:68172622a5a57deb079a2c78511c40f91193548e8ab342c31e8cb0764d362459", + "sha256:6915fc9fa6b3ec3569566832e1bb03bd801c12cea030200e68663b9a87974e76", + "sha256:6b75b912a0baa033350367a8a07a8b2d44fd5b90c890bfbd063a8a5f945f644b", + "sha256:6f5dcb658d597410bb7c967c1d24eaf9377b0d621358cbe9d2ff804e5dd12e81", + "sha256:6f8d7fe73d1816eeb5378409adc658f9525ecbfaf9e1ede1e2d67a338b0c7348", + "sha256:7036316cc26b93e401cedd781a579be606dad174829e6ad9e9c5a0da6e036f80", + "sha256:7188ddc1a8887194f984fa4110d5a3d5b9b5cd35f6bafdff1b649049cbc0ce29", + "sha256:761531076df51309075133a6bc1db02d98ec7f66e22b064b1d513bc909f29743", + "sha256:7979d90ee2190d000129598c2b0c82f13053dba432b94e45e68253b09bb1f0f6", + "sha256:8015835494b21aa7abd3b43fdea0614ee35ef6b03db7ecba9beb58eadf01c24f", + "sha256:81c4d1a3a564775c44732b94135d06e33417e829ff25226c164664f4a1046213", + "sha256:81cf9d306c04df1b45971c13167dc3bad625808aa01281d55f3cf852dde0e206", + "sha256:88857060b690a57d2ea8569bca58758143c8faa4639fb17d745ce60ff84c867e", + "sha256:8c567c664fc2f44130a20edac73e0a867f8e012bf7370276f15c6adc3586c37c", + "sha256:91bd2b7cf0f4d252eec8b7046fa6a43cee17e8acdfc00eaa8b3dbf2f9a59d061", + "sha256:9620650c364c01ed5b497dcae7c3d4b948daeae6e1883ae185fef1c927b6b534", + "sha256:9b007c2444705a2dc4a525964fd4dd28c3320b19b3410da6517cab28716f27d3", + "sha256:9bf9acce44e967a5103fcd820fc7580c7b0ab8583eec4e2051aec560f7b31a63", + "sha256:a239303acb0315091d54c7ff36712dba24554993b9a93941cf301391d8a997ee", + "sha256:a2baa6be130e8a00b6cbb9f18a33611ec150b4537f8563bddadb54c1b74b8193", + "sha256:a54917b7e9cd3a67e429a630e237a90b096e0ba18897bfb99ee8bd1068a5fea0", + "sha256:a689e1ded7137552bea36305a7a16ad2b40be511740b80748d3140614993db98", + "sha256:a952ae3eb460c6712388ac2ec706d24b0e651b9396d90c9a9e0a69eb27737fdc", + "sha256:aa32205358a76bf578854bf31698a86dc8b2cb591fd1d79a833283f4a403f04b", + "sha256:b2287c09482949e0ca0c0eb68b2aca6cf57f8af8c6dfd29dcd3bc45f17b57978", + "sha256:b6b0e17d39d21698185097652c611f9cf30f7c56ccec189789920e3e7f1cee56", + "sha256:b710bf7e7ae61957d5c4026b486be593ed3ec3dca3e5be15e0f6d8cf5d0a4990", + "sha256:b8e11715178f3608874508f08e990d3771e0b8c66c73eb4e183038d600a9b274", + "sha256:b92aafcfab3d41580d54aca35a8057341f1cfc7c9af9e8bdfc652f83a20ced31", + "sha256:bec29b801b4adbf388314c0d050e851d53762ab424af22657021ce4b6eb41543", + "sha256:c694bee70ece3b232df4678448fdda245fd3b1bb4ba481fb6cd20e13bb784c46", + "sha256:c6b52b7028b547866c2413f614ee306c2d4eafdd444b1ff656bf3295bf1484aa", + "sha256:cb41ad20064e18a900dd427d7cf41cfaec83bcd1184001f3d91a1f76b3fcea4e", + "sha256:cd316dbcc74c76266ba94eb021b0cc090b97cca122f50bd7a845f587ff4bf03f", + "sha256:ced40cdbb6dd47a032725a038896cceae9ce267d340f59508b23537f05455431", + "sha256:d1c562a9bb72244fa767d1c1ab55ca1d92dd5f7c4d77878fee5483a22ffac808", + "sha256:d389ff1e95b6e46ebedccf7fd1fadd10559add595ac6a7c2ea730268325f832c", + "sha256:d56b1cd606ba4cedd64bb43479d56580e147c6ef3f5d1c5e64203a1adab784a2", + "sha256:d72a4315514e5a0b9837a086cb433b004eea630afb0cc129de76d77654a9606f", + "sha256:d9e7f29c00577aff6b318681e730a519b235af292732a149337f6aaa4d1c5e31", + "sha256:dbc25baa6abb205766fb8606f8263b02c3503a55957fcb4576a6bb0a59d37d10", + "sha256:e57919c32ee295a2fca458bb73e4b20b05c115627f96f95a10f9f5acbd61172d", + "sha256:e5bbe011a2cea9060fef1bb3d668a2fd8432b8888e6d92e74c9c794d3c101595", + "sha256:e6aea5c0eb5b0faf52c7b5c4a47c8bb64437173be97227c819ffa31801fa4e34", + "sha256:e888be685fa42d8b8a3d3911d5604d14db87538aa7d0b29b1a7ea80d354c732d", + "sha256:eebaf8c76c39604d52852366249ab807fe6f7a3ffb0dd5484b9944917244cdbe", + "sha256:efbe0b5e0fd078ed7b005faa0170da4f72666360f66f0bb2d7f73526ecfd99f9", + "sha256:efddca2d02254a52078c35cadad34762adbae3ff01c6b0c7787b59d038b63e0d", + "sha256:f05450fa1cd7c525c0b9d1a7916e595d3041ac0afbed2ff6926e5afb6a781b7f", + "sha256:f12d69d568f5647ec503b64932874dade5a20255736c89936bf690951a5e79f5", + "sha256:f45321224144c25a62052035ce96cbcf264667bcb0d81823b1bbc22c4addd194", + "sha256:f62581d7e884dd01ee1707b7c21148f61f2febb7de092ae2f108743fcbef5985", + "sha256:f8832a4f83d4782a8f5a7b831c47e8ffe164e43c2c148c8160ed9a6d630bc02a", + "sha256:fa35ad36440aaf1ac8332b4a4a433d4acd28f1613f0d480995f5cfd3580e90b7" + ], + "markers": "python_version >= '3.8'", + "version": "==0.12.0" + }, + "rsa": { + "hashes": [ + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" + ], + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==4.9" + }, + "send2trash": { + "hashes": [ + "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679", + "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.8.2" + }, + "setuptools": { + "hashes": [ + "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", + "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" + ], + "markers": "python_version >= '3.8'", + "version": "==68.2.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sniffio": { + "hashes": [ + "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", + "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "soupsieve": { + "hashes": [ + "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", + "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7" + ], + "markers": "python_version >= '3.8'", + "version": "==2.5" + }, + "sqlalchemy": { + "hashes": [ + "sha256:0666031df46b9badba9bed00092a1ffa3aa063a5e68fa244acd9f08070e936d3", + "sha256:0a8c6aa506893e25a04233bc721c6b6cf844bafd7250535abb56cb6cc1368884", + "sha256:0e680527245895aba86afbd5bef6c316831c02aa988d1aad83c47ffe92655e74", + "sha256:14aebfe28b99f24f8a4c1346c48bc3d63705b1f919a24c27471136d2f219f02d", + "sha256:1e018aba8363adb0599e745af245306cb8c46b9ad0a6fc0a86745b6ff7d940fc", + "sha256:227135ef1e48165f37590b8bfc44ed7ff4c074bf04dc8d6f8e7f1c14a94aa6ca", + "sha256:31952bbc527d633b9479f5f81e8b9dfada00b91d6baba021a869095f1a97006d", + "sha256:3e983fa42164577d073778d06d2cc5d020322425a509a08119bdcee70ad856bf", + "sha256:42d0b0290a8fb0165ea2c2781ae66e95cca6e27a2fbe1016ff8db3112ac1e846", + "sha256:42ede90148b73fe4ab4a089f3126b2cfae8cfefc955c8174d697bb46210c8306", + "sha256:4895a63e2c271ffc7a81ea424b94060f7b3b03b4ea0cd58ab5bb676ed02f4221", + "sha256:4af79c06825e2836de21439cb2a6ce22b2ca129bad74f359bddd173f39582bf5", + "sha256:5f94aeb99f43729960638e7468d4688f6efccb837a858b34574e01143cf11f89", + "sha256:616fe7bcff0a05098f64b4478b78ec2dfa03225c23734d83d6c169eb41a93e55", + "sha256:62d9e964870ea5ade4bc870ac4004c456efe75fb50404c03c5fd61f8bc669a72", + "sha256:638c2c0b6b4661a4fd264f6fb804eccd392745c5887f9317feb64bb7cb03b3ea", + "sha256:63bfc3acc970776036f6d1d0e65faa7473be9f3135d37a463c5eba5efcdb24c8", + "sha256:6463aa765cf02b9247e38b35853923edbf2f6fd1963df88706bc1d02410a5577", + "sha256:64ac935a90bc479fee77f9463f298943b0e60005fe5de2aa654d9cdef46c54df", + "sha256:683ef58ca8eea4747737a1c35c11372ffeb84578d3aab8f3e10b1d13d66f2bc4", + "sha256:75eefe09e98043cff2fb8af9796e20747ae870c903dc61d41b0c2e55128f958d", + "sha256:787af80107fb691934a01889ca8f82a44adedbf5ef3d6ad7d0f0b9ac557e0c34", + "sha256:7c424983ab447dab126c39d3ce3be5bee95700783204a72549c3dceffe0fc8f4", + "sha256:7e0dc9031baa46ad0dd5a269cb7a92a73284d1309228be1d5935dac8fb3cae24", + "sha256:87a3d6b53c39cd173990de2f5f4b83431d534a74f0e2f88bd16eabb5667e65c6", + "sha256:89a01238fcb9a8af118eaad3ffcc5dedaacbd429dc6fdc43fe430d3a941ff965", + "sha256:9585b646ffb048c0250acc7dad92536591ffe35dba624bb8fd9b471e25212a35", + "sha256:964971b52daab357d2c0875825e36584d58f536e920f2968df8d581054eada4b", + "sha256:967c0b71156f793e6662dd839da54f884631755275ed71f1539c95bbada9aaab", + "sha256:9ca922f305d67605668e93991aaf2c12239c78207bca3b891cd51a4515c72e22", + "sha256:a86cb7063e2c9fb8e774f77fbf8475516d270a3e989da55fa05d08089d77f8c4", + "sha256:aeb397de65a0a62f14c257f36a726945a7f7bb60253462e8602d9b97b5cbe204", + "sha256:b41f5d65b54cdf4934ecede2f41b9c60c9f785620416e8e6c48349ab18643855", + "sha256:bd45a5b6c68357578263d74daab6ff9439517f87da63442d244f9f23df56138d", + "sha256:c14eba45983d2f48f7546bb32b47937ee2cafae353646295f0e99f35b14286ab", + "sha256:c1bda93cbbe4aa2aa0aa8655c5aeda505cd219ff3e8da91d1d329e143e4aff69", + "sha256:c4722f3bc3c1c2fcc3702dbe0016ba31148dd6efcd2a2fd33c1b4897c6a19693", + "sha256:c80c38bd2ea35b97cbf7c21aeb129dcbebbf344ee01a7141016ab7b851464f8e", + "sha256:cabafc7837b6cec61c0e1e5c6d14ef250b675fa9c3060ed8a7e38653bd732ff8", + "sha256:cc1d21576f958c42d9aec68eba5c1a7d715e5fc07825a629015fe8e3b0657fb0", + "sha256:d0f7fb0c7527c41fa6fcae2be537ac137f636a41b4c5a4c58914541e2f436b45", + "sha256:d4041ad05b35f1f4da481f6b811b4af2f29e83af253bf37c3c4582b2c68934ab", + "sha256:d5578e6863eeb998980c212a39106ea139bdc0b3f73291b96e27c929c90cd8e1", + "sha256:e3b5036aa326dc2df50cba3c958e29b291a80f604b1afa4c8ce73e78e1c9f01d", + "sha256:e599a51acf3cc4d31d1a0cf248d8f8d863b6386d2b6782c5074427ebb7803bda", + "sha256:f3420d00d2cb42432c1d0e44540ae83185ccbbc67a6054dcc8ab5387add6620b", + "sha256:f48ed89dd11c3c586f45e9eec1e437b355b3b6f6884ea4a4c3111a3358fd0c18", + "sha256:f508ba8f89e0a5ecdfd3761f82dda2a3d7b678a626967608f4273e0dba8f07ac", + "sha256:fd54601ef9cc455a0c61e5245f690c8a3ad67ddb03d3b91c361d076def0b4c60" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.23" + }, + "stack-data": { + "hashes": [ + "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", + "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" + ], + "version": "==0.6.3" + }, + "starlette": { + "hashes": [ + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" + ], + "markers": "python_version >= '3.7'", + "version": "==0.27.0" + }, + "sympy": { + "hashes": [ + "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5", + "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8" + ], + "markers": "python_version >= '3.8'", + "version": "==1.12" + }, + "tenacity": { + "hashes": [ + "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a", + "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c" + ], + "markers": "python_version >= '3.7'", + "version": "==8.2.3" + }, + "terminado": { + "hashes": [ + "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded", + "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e" + ], + "markers": "python_version >= '3.8'", + "version": "==0.18.0" + }, + "timeflake": { + "hashes": [ + "sha256:0db76000a4a0d20f2fafede7da321567a4df5d2641a01845356cf6f63e37e8ce", + "sha256:8a7f74e15fd1c2a3b00d02ce88991d27854056328f7151605dd480643ae5429a" + ], + "index": "pypi", + "version": "==0.4.3" + }, + "tinycss2": { + "hashes": [ + "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", + "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.1" + }, + "tokenizers": { + "hashes": [ + "sha256:00df4c5bf25c153b432b98689609b426ae701a44f3d8074dcb619f410bc2a870", + "sha256:01d2bd5935642de22a6c6778bb2307f9949cd6eaeeb5c77f9b98f0060b69f0db", + "sha256:040ee44efc1806900de72b13c1c3036154077d9cde189c9a7e7a50bbbdcbf39f", + "sha256:04ec1134a18ede355a05641cdc7700f17280e01f69f2f315769f02f7e295cf1e", + "sha256:08e55920b453c30b46d58accc68a38e8e7488d0c03babfdb29c55d3f39dd2052", + "sha256:0c8ee283b249c3c3c201c41bc23adc3be2514ae4121eacdb5c5250a461eaa8c6", + "sha256:0ce2f0ff2e5f12ac5bebaa690606395725239265d7ffa35f35c243a379316297", + "sha256:102f118fa9b720b93c3217c1e239ed7bc1ae1e8dbfe9b4983a4f2d7b4ce6f2ec", + "sha256:11284b32f0036fe7ef4b8b00201dda79c00f3fcea173bc0e5c599e09c937ab0f", + "sha256:117c8da60d1bd95a6df2692926f36de7971baa1d89ff702fae47b6689a4465ad", + "sha256:1ff516d129f01bb7a4aa95bc6aae88e4d86dd63bfc2d57db9302c2624d1be7cb", + "sha256:232445e7b85255ccfe68dfd42185db8a3f3349b34ad7068404856c4a5f67c355", + "sha256:2539831838ab5393f78a893d7bbf27d5c36e43baf77e91dc9992922b2b97e09d", + "sha256:26fee36a6d8f2bd9464f3566b95e3e3fb7fd7dad723f775c500aac8204ec98c6", + "sha256:2cda65b689aec63b7c76a77f43a08044fa90bbc6ad9849267cedfee9795913f3", + "sha256:2ecdfe9736c4a73343f629586016a137a10faed1a29c6dc699d8ab20c2d3cf64", + "sha256:319e4367596fb0d52be645b3de1616faf0fadaf28507ce1c7595bebd9b4c402c", + "sha256:3678be5db330726f19c1949d8ae1b845a02eeb2a2e1d5a8bb8eaa82087ae25c1", + "sha256:370b5b86da9bddbe65fa08711f0e8ffdf8b0036558178d1a31dfcb44efcde72a", + "sha256:37cc955c84ec67c2d11183d372044399342b20a1fa447b7a33040f4889bba318", + "sha256:42b180ed1bec58ab9bdc65d406577e0c0fb7241b74b8c032846073c7743c9f86", + "sha256:44f1748035c36c939848c935715bde41734d9249ab7b844ff9bfbe984be8952c", + "sha256:463ee5f3afbfec29cbf5652752c9d1032bdad63daf48bb8cb9970064cc81d5f9", + "sha256:49f5336b82e315a33bef1025d247ca08d95719715b29e33f0e9e8cf15ff1dfb6", + "sha256:4c7cfc3d42e81cda802f93aa9e92caf79feaa1711426e28ce620560b8aaf5e4d", + "sha256:50f03d2330a153a9114c2429061137bd323736059f384de8348d7cb1ca1baa15", + "sha256:53614f44f36917282a583180e402105bc63d61d1aca067d51cb7f051eb489901", + "sha256:5760a831c0f3c6d3229b50ef3fafa4c164ec99d7e8c2237fe144e67a9d33b120", + "sha256:59c7df2103052b30b7c76d4fa8251326c9f82689578a912698a127dc1737f43e", + "sha256:5bef76c4d9329913cef2fe79ce1f4dab98f77fa4887e5f0420ffc9386941de32", + "sha256:5f9afdcf701a1aa3c41e0e748c152d2162434d61639a1e5d8523ecf60ae35aea", + "sha256:60fec380778d75cbb492f14ca974f11f37b41d53c057b9c8ba213315b86e1f84", + "sha256:628b654ba555b2ba9111c0936d558b14bfc9d5f57b8c323b02fc846036b38b2f", + "sha256:638abedb39375f0ddce2de536fc9c976639b2d1b7202d715c2e7a25f0ebfd091", + "sha256:67d3adff654dc7f7c7091dd259b3b847fe119c08d0bda61db91e2ea2b61c38c0", + "sha256:6859d81243cd09854be9054aca3ecab14a2dee5b3c9f6d7ef12061d478ca0c57", + "sha256:68c4699147dded6926a3d2c2f948d435d54d027f69909e0ef3c6587933723ed2", + "sha256:6cba7483ba45600346a35c466bde32327b108575022f73c35a0f7170b5a71ae2", + "sha256:72d9967fb1f927542cfb5347207fde01b29f25c9bb8cbc7ced280decfa015983", + "sha256:72e95184bf5b9a4c08153ed07c16c130ff174835c9a1e6ee2b311be758c8b3ef", + "sha256:7560fca3e17a6bc876d20cd825d7721c101fa2b1cd0bfa0abf9a2e781e49b37b", + "sha256:7618b84118ae704f7fa23c4a190bd80fc605671841a4427d5ca14b9b8d9ec1a3", + "sha256:7975178f9478ccedcf613332d5d6f37b67c74ef4e2e47e0c965597506b921f04", + "sha256:7d9025b185465d9d18679406f6f394850347d5ed2681efc203539d800f36f459", + "sha256:89cbeec7e9d5d8773ec4779c64e3cbcbff53d234ca6ad7b1a3736588003bba48", + "sha256:8b019c4810903fdea3b230f358b9d27377c0f38454778b607676c9e1b57d14b7", + "sha256:8db3a6f3d430ac3dc3793c53fa8e5e665c23ba359484d365a191027ad8b65a30", + "sha256:8e63781da85aa8948864970e529af10abc4084a990d30850c41bbdb5f83eee45", + "sha256:901635098565773a44f74068639d265f19deaaca47ea77b428fd9bee13a61d87", + "sha256:91d32bd1056c0e83a0f90e4ffa213c25096b2d8b9f0e2d172a45f138c7d8c081", + "sha256:92c34de04fec7f4ff95f7667d4eb085c4e4db46c31ef44c3d35c38df128430da", + "sha256:930c19b699dd7e1077eac98967adc2fe5f0b104bd96cc1f26778ab82b31ceb24", + "sha256:956729b7dd599020e57133fb95b777e4f81ee069ff0a70e80f6eeac82658972f", + "sha256:9930f31f603ecc6ea54d5c6dfa299f926ab3e921f72f94babcb02598c32b57c6", + "sha256:a1e30a13376db5329570e09b14c8eb36c017909ed7e88591ca3aa81f3c7d6f32", + "sha256:a480bd902e327dfcaa52b7dd14fdc71e7aa45d73a3d6e41e028a75891d2823cf", + "sha256:a687099e085f5162e5b88b3402adb6c2b41046180c015c5075c9504440b6e971", + "sha256:a7093767e070269e22e2c5f845e46510304f124c32d2cd249633c0f27eb29d86", + "sha256:aae42798ba1da3bc1572b2048fe42e61dd6bacced2b424cb0f5572c5432f79c2", + "sha256:acfc8db61c6e919d932448cc7985b85e330c8d745528e12fce6e62d40d268bce", + "sha256:ad759ba39cd32c2c2247864d02c84ea5883b5f6cc6a4ee0c95602a3dde52268f", + "sha256:b05ec04132394c20bd6bcb692d557a8eb8ab1bac1646d28e49c67c00907d17c8", + "sha256:b886e0f5c72aa4249c609c24b9610a9ca83fd963cbb5066b19302723ea505279", + "sha256:ba336bc9107acbc1da2ad30967df7b2db93448ca66538ad86aa1fbb91116f631", + "sha256:bfe164a1c72c6be3c5c26753c6c412f81412f4dae0d7d06371e0b396a9cc0fc9", + "sha256:c11444984aecd342f0cf160c3320288edeb1763871fbb560ed466654b2a7016c", + "sha256:c2c659f2106b6d154f118ad1b700e68148c46c59b720f04867b1fc5f26a85060", + "sha256:c318a5acb429ca38f632577754235140bbb8c5a27faca1c51b43fbf575596e34", + "sha256:c375161b588982be381c43eb7158c250f430793d0f708ce379a0f196164c6778", + "sha256:c65d76052561c60e17cb4fa289885ed00a9995d59e97019fac2138bd45142057", + "sha256:c84b456ff8525ec3ff09762e32ccc27888d036dcd0ba2883e1db491e164dd725", + "sha256:c84d3cb1349936c2b96ca6175b50f5a9518170bffd76464219ee0ea6022a64a7", + "sha256:ca0bfc79b27d84fcb7fa09339b2ee39077896738d9a30ff99c0332376e985072", + "sha256:ca304402ea66d58f99c05aa3d7a6052faea61e5a8313b94f6bc36fbf27960e2d", + "sha256:caf0df8657277e32671aa8a4d3cc05f2050ab19d9b49447f2265304168e9032c", + "sha256:cb3c6bc6e599e46a26ad559ad5dec260ffdf705663cc9b894033d64a69314e86", + "sha256:cce4d1a97a7eb2253b5d3f29f4a478d8c37ba0303ea34024eb9e65506d4209f8", + "sha256:d091c62cb7abbd32e527a85c41f7c8eb4526a926251891fc4ecbe5f974142ffb", + "sha256:d3a6330c9f1deda22873e8b4ac849cc06d3ff33d60b3217ac0bb397b541e1509", + "sha256:d49567a2754e9991c05c2b5a7e6650b56e24365b7cab504558e58033dcf0edc4", + "sha256:d72d25c57a9c814240802d188ff0a808b701e2dd2bf1c64721c7088ceeeb1ed7", + "sha256:db96cf092d86d4cb543daa9148e299011e0a40770380bb78333b9fd700586fcb", + "sha256:df4f058e96e8b467b7742e5dba7564255cd482d3c1e6cf81f8cb683bb0433340", + "sha256:e3b6082e9532309727273443c8943bb9558d52e36788b246aa278bda7c642116", + "sha256:e448b2be0430ab839cf7954715c39d6f34ff6cf2b49393f336283b7a59f485af", + "sha256:e8984114fd83ed3913d89526c992395920930c9620a2feee61faf035f41d7b9a", + "sha256:e9f27399b8d50c5d3f08f0aae961bcc66a1dead1cd0ae9401e4c2a43a623322a", + "sha256:ea3b3f8908a9a5b9d6fc632b5f012ece7240031c44c6d4764809f33736534166", + "sha256:ebefbc26ccff5e96ae7d40772172e7310174f9aa3683d2870a1882313ec3a4d5", + "sha256:ec8f46d533092d8e20bc742c47918cbe24b8641dbfbbcb83177c5de3c9d4decb", + "sha256:ee6b63aecf929a7bcf885bdc8a8aec96c43bc4442f63fe8c6d48f24fc992b05b", + "sha256:f475d5eda41d2ed51ca775a07c80529a923dd759fcff7abf03ccdd83d9f7564e", + "sha256:f522f28c88a0d5b2f9e895cf405dd594cd518e99d61905406aec74d30eb6383b", + "sha256:f77371b5030e53f8bf92197640af437539e3bba1bc8342b97888c8e26567bfdc", + "sha256:f8cf2fcdc2368df4317e05571e33810eeed24cd594acc9dfc9788b21dac6b3a8", + "sha256:fe2ea1177146a7ab345ab61e90a490eeea25d5f063e1cb9d4eb1425b169b64d7", + "sha256:fee553657dcdb7e73df8823c49e8611457ba46e9d7026b7e9c44820c08c327c3", + "sha256:ff66577ae55114f7d0f6aa0d4d335f27cae96bf245962a745b718ec887bbe7eb" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.1" + }, + "tornado": { + "hashes": [ + "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f", + "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5", + "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d", + "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3", + "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2", + "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a", + "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16", + "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a", + "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17", + "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0", + "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe" + ], + "markers": "python_version >= '3.8'", + "version": "==6.3.3" + }, + "tqdm": { + "hashes": [ + "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386", + "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7" + ], + "markers": "python_version >= '3.7'", + "version": "==4.66.1" + }, + "traitlets": { + "hashes": [ + "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5", + "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619" + ], + "markers": "python_version >= '3.8'", + "version": "==5.13.0" + }, + "typer": { + "hashes": [ + "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2", + "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee" + ], + "markers": "python_version >= '3.6'", + "version": "==0.9.0" + }, + "types-python-dateutil": { + "hashes": [ + "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b", + "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9" + ], + "version": "==2.8.19.14" + }, + "typing-extensions": { + "hashes": [ + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + ], + "markers": "python_version >= '3.8'", + "version": "==4.8.0" + }, + "typing-inspect": { + "hashes": [ + "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", + "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78" + ], + "version": "==0.9.0" + }, + "uri-template": { + "hashes": [ + "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", + "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363" + ], + "version": "==1.3.0" + }, + "urllib3": { + "hashes": [ + "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", + "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.18" + }, + "uvicorn": { + "extras": [ + "standard" + ], + "hashes": [ + "sha256:09c8e5a79dc466bdf28dead50093957db184de356fcdc48697bad3bde4c2588e", + "sha256:7c84fea70c619d4a710153482c0d230929af7bcf76c7bfa6de151f0a3a80121e" + ], + "markers": "python_version >= '3.8'", + "version": "==0.24.0.post1" + }, + "uvloop": { + "hashes": [ + "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", + "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", + "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", + "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", + "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", + "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", + "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", + "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", + "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", + "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", + "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", + "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", + "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", + "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", + "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", + "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", + "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", + "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", + "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", + "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", + "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", + "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", + "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", + "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", + "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", + "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", + "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", + "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", + "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", + "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", + "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" + ], + "version": "==0.19.0" + }, + "watchfiles": { + "hashes": [ + "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc", + "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365", + "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0", + "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e", + "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124", + "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c", + "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317", + "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094", + "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7", + "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235", + "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c", + "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c", + "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c", + "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235", + "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293", + "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa", + "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef", + "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19", + "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8", + "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d", + "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915", + "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429", + "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097", + "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe", + "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0", + "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d", + "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99", + "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1", + "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a", + "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895", + "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94", + "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562", + "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab", + "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360", + "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1", + "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7", + "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f", + "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03", + "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01", + "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58", + "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052", + "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e", + "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765", + "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6", + "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137", + "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85", + "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca", + "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f", + "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214", + "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7", + "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7", + "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3", + "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b", + "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7", + "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6", + "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994", + "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9", + "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec", + "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128", + "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c", + "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2", + "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078", + "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3", + "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e", + "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a", + "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6", + "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49", + "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b", + "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28", + "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9", + "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586", + "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400", + "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165", + "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303", + "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d" + ], + "version": "==0.21.0" + }, + "wcwidth": { + "hashes": [ + "sha256:390c7454101092a6a5e43baad8f83de615463af459201709556b6e4b1c861f97", + "sha256:aec5179002dd0f0d40c456026e74a729661c9d468e1ed64405e3a6c2176ca36f" + ], + "version": "==0.2.10" + }, + "webargs": { + "hashes": [ + "sha256:69d7ac874d746b6f4f47eac923c2abf6fc7788dfca2ebcfd9f4ac52ec9646446", + "sha256:cab207941b0686c4d086c823632ddcd4343151644341a32fcf50b8eaa71e31c7" + ], + "index": "pypi", + "markers": "python_full_version >= '3.7.2'", + "version": "==8.3.0" + }, + "webcolors": { + "hashes": [ + "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf", + "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a" + ], + "version": "==1.13" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "websocket-client": { + "hashes": [ + "sha256:084072e0a7f5f347ef2ac3d8698a5e0b4ffbfcab607628cadabc650fc9a83a24", + "sha256:b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df" + ], + "markers": "python_version >= '3.8'", + "version": "==1.6.4" + }, + "websockets": { + "hashes": [ + "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b", + "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6", + "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", + "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", + "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205", + "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892", + "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53", + "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", + "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", + "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c", + "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", + "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", + "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931", + "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", + "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370", + "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", + "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec", + "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", + "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62", + "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", + "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", + "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", + "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123", + "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9", + "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", + "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", + "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", + "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", + "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438", + "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137", + "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", + "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", + "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", + "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", + "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", + "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", + "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967", + "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", + "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d", + "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def", + "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", + "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", + "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2", + "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", + "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b", + "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28", + "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7", + "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d", + "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", + "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468", + "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8", + "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae", + "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611", + "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", + "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9", + "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", + "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", + "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2", + "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", + "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", + "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6", + "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", + "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", + "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", + "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", + "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399", + "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", + "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", + "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", + "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", + "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8", + "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7" + ], + "version": "==12.0" + }, + "werkzeug": { + "hashes": [ + "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", + "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.1" + }, + "wrapt": { + "hashes": [ + "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", + "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", + "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", + "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", + "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", + "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", + "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", + "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", + "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", + "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", + "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", + "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", + "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", + "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", + "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", + "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", + "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", + "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", + "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", + "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", + "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", + "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", + "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", + "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", + "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", + "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", + "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", + "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", + "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", + "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", + "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", + "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", + "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", + "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", + "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", + "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", + "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", + "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", + "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", + "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", + "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", + "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", + "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", + "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", + "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", + "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", + "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", + "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", + "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", + "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", + "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", + "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", + "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", + "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", + "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", + "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", + "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", + "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", + "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", + "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", + "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", + "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", + "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", + "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", + "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", + "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", + "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", + "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", + "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", + "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + ], + "markers": "python_version >= '3.6'", + "version": "==1.16.0" + }, + "yarl": { + "hashes": [ + "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571", + "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3", + "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3", + "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c", + "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7", + "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04", + "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191", + "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea", + "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4", + "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4", + "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095", + "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e", + "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74", + "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef", + "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33", + "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde", + "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45", + "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf", + "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b", + "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac", + "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0", + "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528", + "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716", + "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb", + "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18", + "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72", + "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6", + "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582", + "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5", + "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368", + "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc", + "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9", + "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be", + "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a", + "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80", + "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8", + "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6", + "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417", + "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574", + "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59", + "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608", + "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82", + "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1", + "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3", + "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d", + "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8", + "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc", + "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac", + "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8", + "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955", + "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0", + "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367", + "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb", + "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a", + "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623", + "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2", + "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6", + "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7", + "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4", + "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051", + "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938", + "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8", + "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9", + "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3", + "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5", + "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9", + "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333", + "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185", + "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3", + "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560", + "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b", + "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7", + "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78", + "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7" + ], + "markers": "python_version >= '3.7'", + "version": "==1.9.2" + }, + "zipp": { + "hashes": [ + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + ], + "markers": "python_version >= '3.8'", + "version": "==3.17.0" + } + }, + "develop": { + "adbnx-adapter": { + "hashes": [ + "sha256:56b576c47382f0995cb712bf9364fbfb50a55f14540565bd5ded463a6b1ad0a9", + "sha256:842a6912ad3e03e48f9fac912b89fbf9f3366b07a1fd68eea23ed227b1c98203" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==4.2.0" + }, + "anyio": { + "hashes": [ + "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780", + "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5" + ], + "markers": "python_version >= '3.7'", + "version": "==3.7.1" + }, + "argon2-cffi": { + "hashes": [ + "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", + "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "argon2-cffi-bindings": { + "hashes": [ + "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670", + "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f", + "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583", + "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194", + "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", + "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a", + "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", + "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5", + "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", + "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7", + "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", + "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", + "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", + "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", + "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", + "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", + "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d", + "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", + "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb", + "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", + "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351" + ], + "markers": "python_version >= '3.6'", + "version": "==21.2.0" + }, + "arrow": { + "hashes": [ + "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", + "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85" + ], + "markers": "python_version >= '3.8'", + "version": "==1.3.0" + }, + "asttokens": { + "hashes": [ + "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", + "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0" + ], + "version": "==2.4.1" + }, + "async-lru": { + "hashes": [ + "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", + "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224" + ], + "markers": "python_version >= '3.8'", + "version": "==2.0.4" + }, + "attrs": { + "hashes": [ + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "babel": { + "hashes": [ + "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900", + "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed" + ], + "markers": "python_version >= '3.7'", + "version": "==2.13.1" + }, + "beautifulsoup4": { + "hashes": [ + "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da", + "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==4.12.2" + }, + "bleach": { + "hashes": [ + "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", + "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" + ], + "markers": "python_version >= '3.8'", + "version": "==6.1.0" + }, + "certifi": { + "hashes": [ + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.7.22" + }, + "cffi": { + "hashes": [ + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" + ], + "markers": "python_version >= '3.8'", + "version": "==1.16.0" + }, + "charset-normalizer": { + "hashes": [ + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" + }, + "comm": { + "hashes": [ + "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001", + "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be" + ], + "markers": "python_version >= '3.8'", + "version": "==0.2.0" + }, + "debugpy": { + "hashes": [ + "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332", + "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0", + "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f", + "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa", + "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6", + "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637", + "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6", + "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8", + "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb", + "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b", + "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4", + "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153", + "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f", + "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd", + "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595", + "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926", + "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e", + "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada" + ], + "markers": "python_version >= '3.8'", + "version": "==1.8.0" + }, + "decorator": { + "hashes": [ + "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", + "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" + ], + "markers": "python_version >= '3.5'", + "version": "==5.1.1" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, + "executing": { + "hashes": [ + "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", + "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc" + ], + "markers": "python_version >= '3.5'", + "version": "==2.0.1" + }, + "fastjsonschema": { + "hashes": [ + "sha256:06dc8680d937628e993fa0cd278f196d20449a1adc087640710846b324d422ea", + "sha256:aec6a19e9f66e9810ab371cc913ad5f4e9e479b63a7072a2cd060a9369e329a8" + ], + "version": "==2.18.1" + }, + "fqdn": { + "hashes": [ + "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", + "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014" + ], + "version": "==1.5.1" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "importlib-metadata": { + "hashes": [ + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" + ], + "markers": "python_version >= '3.8'", + "version": "==6.8.0" + }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "ipycytoscape": { + "hashes": [ + "sha256:4bc205724971f5f7a3fc2b09dfec20c357c4c6dfa2b4bd41e7c33c995c3f6906", + "sha256:b6f3199df034f088e92d388e27e629f58ae2901b213cb9299e5b564272f9a2f8" + ], + "index": "pypi", + "version": "==1.3.3" + }, + "ipykernel": { + "hashes": [ + "sha256:3ba3dc97424b87b31bb46586b5167b3161b32d7820b9201a9e698c71e271602c", + "sha256:553856658eb8430bbe9653ea041a41bff63e9606fc4628873fc92a6cf3abd404" + ], + "markers": "python_version >= '3.8'", + "version": "==6.26.0" + }, + "ipython": { + "hashes": [ + "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb", + "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444" + ], + "markers": "python_version >= '3.9'", + "version": "==8.17.2" + }, + "ipywidgets": { + "hashes": [ + "sha256:2b88d728656aea3bbfd05d32c747cfd0078f9d7e159cf982433b58ad717eed7f", + "sha256:40211efb556adec6fa450ccc2a77d59ca44a060f4f9f136833df59c9f538e6e8" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==8.1.1" + }, + "isoduration": { + "hashes": [ + "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", + "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042" + ], + "version": "==20.11.0" + }, + "jedi": { + "hashes": [ + "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", + "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" + ], + "markers": "python_version >= '3.6'", + "version": "==0.19.1" + }, + "jinja2": { + "hashes": [ + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.2" + }, + "json5": { + "hashes": [ + "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f", + "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02" + ], + "version": "==0.9.14" + }, + "jsonpointer": { + "hashes": [ + "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a", + "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88" + ], + "version": "==2.4" + }, + "jsonschema": { + "hashes": [ + "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392", + "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc" + ], + "markers": "python_version >= '3.8'", + "version": "==4.19.2" + }, + "jsonschema-specifications": { + "hashes": [ + "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1", + "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb" + ], + "markers": "python_version >= '3.8'", + "version": "==2023.7.1" + }, + "jupyter-client": { + "hashes": [ + "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7", + "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99" + ], + "markers": "python_version >= '3.8'", + "version": "==8.6.0" + }, + "jupyter-core": { + "hashes": [ + "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3", + "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805" + ], + "markers": "python_version >= '3.8'", + "version": "==5.5.0" + }, + "jupyter-events": { + "hashes": [ + "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399", + "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf" + ], + "markers": "python_version >= '3.8'", + "version": "==0.9.0" + }, + "jupyter-lsp": { + "hashes": [ + "sha256:8ebbcb533adb41e5d635eb8fe82956b0aafbf0fd443b6c4bfa906edeeb8635a1", + "sha256:9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f" + ], + "markers": "python_version >= '3.8'", + "version": "==2.2.0" + }, + "jupyter-server": { + "hashes": [ + "sha256:47b8f5e63440125cb1bb8957bf12b18453ee5ed9efe42d2f7b2ca66a7019a278", + "sha256:dde56c9bc3cb52d7b72cc0f696d15d7163603526f1a758eb4a27405b73eab2a5" + ], + "markers": "python_version >= '3.8'", + "version": "==2.10.0" + }, + "jupyter-server-terminals": { + "hashes": [ + "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d", + "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36" + ], + "markers": "python_version >= '3.8'", + "version": "==0.4.4" + }, + "jupyterlab": { + "hashes": [ + "sha256:2ff5aa2a51eb21df241d6011c236e88bd1ff9a5dbb75bebc54472f9c18bfffa4", + "sha256:c4fe93f977bcc987bd395d7fae5ab02e0c042bf4e0f7c95196f3e2e578c2fb3a" + ], + "markers": "python_version >= '3.8'", + "version": "==4.0.8" + }, + "jupyterlab-pygments": { + "hashes": [ + "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f", + "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d" + ], + "markers": "python_version >= '3.7'", + "version": "==0.2.2" + }, + "jupyterlab-server": { + "hashes": [ + "sha256:6491283b0000698eae1a38c48507930560dfcf7461aea0015368698aab34dd9c", + "sha256:dce9714d91fb3e53d2b37d0e0619fa26ed223c8e7b8c81cca112926de19b53a4" + ], + "markers": "python_version >= '3.8'", + "version": "==2.25.1" + }, + "jupyterlab-widgets": { + "hashes": [ + "sha256:3cf5bdf5b897bf3bccf1c11873aa4afd776d7430200f765e0686bd352487b58d", + "sha256:6005a4e974c7beee84060fdfba341a3218495046de8ae3ec64888e5fe19fdb4c" + ], + "markers": "python_version >= '3.7'", + "version": "==3.0.9" + }, + "llmlib": { + "editable": true, + "file": "." + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "markupsafe": { + "hashes": [ + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", + "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", + "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.3" + }, + "matplotlib-inline": { + "hashes": [ + "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", + "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" + ], + "markers": "python_version >= '3.5'", + "version": "==0.1.6" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "mistune": { + "hashes": [ + "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", + "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" + ], + "markers": "python_version >= '3.7'", + "version": "==3.0.2" + }, + "mypy": { + "hashes": [ + "sha256:159aa9acb16086b79bbb0016145034a1a05360626046a929f84579ce1666b315", + "sha256:258b22210a4a258ccd077426c7a181d789d1121aca6db73a83f79372f5569ae0", + "sha256:26f71b535dfc158a71264e6dc805a9f8d2e60b67215ca0bfa26e2e1aa4d4d373", + "sha256:26fb32e4d4afa205b24bf645eddfbb36a1e17e995c5c99d6d00edb24b693406a", + "sha256:2fc3a600f749b1008cc75e02b6fb3d4db8dbcca2d733030fe7a3b3502902f161", + "sha256:32cb59609b0534f0bd67faebb6e022fe534bdb0e2ecab4290d683d248be1b275", + "sha256:330857f9507c24de5c5724235e66858f8364a0693894342485e543f5b07c8693", + "sha256:361da43c4f5a96173220eb53340ace68cda81845cd88218f8862dfb0adc8cddb", + "sha256:4a465ea2ca12804d5b34bb056be3a29dc47aea5973b892d0417c6a10a40b2d65", + "sha256:51cb1323064b1099e177098cb939eab2da42fea5d818d40113957ec954fc85f4", + "sha256:57b10c56016adce71fba6bc6e9fd45d8083f74361f629390c556738565af8eeb", + "sha256:596fae69f2bfcb7305808c75c00f81fe2829b6236eadda536f00610ac5ec2243", + "sha256:5d627124700b92b6bbaa99f27cbe615c8ea7b3402960f6372ea7d65faf376c14", + "sha256:6ac9c21bfe7bc9f7f1b6fae441746e6a106e48fc9de530dea29e8cd37a2c0cc4", + "sha256:82cb6193de9bbb3844bab4c7cf80e6227d5225cc7625b068a06d005d861ad5f1", + "sha256:8f772942d372c8cbac575be99f9cc9d9fb3bd95c8bc2de6c01411e2c84ebca8a", + "sha256:9fece120dbb041771a63eb95e4896791386fe287fefb2837258925b8326d6160", + "sha256:a156e6390944c265eb56afa67c74c0636f10283429171018446b732f1a05af25", + "sha256:a9ec1f695f0c25986e6f7f8778e5ce61659063268836a38c951200c57479cc12", + "sha256:abed92d9c8f08643c7d831300b739562b0a6c9fcb028d211134fc9ab20ccad5d", + "sha256:b031b9601f1060bf1281feab89697324726ba0c0bae9d7cd7ab4b690940f0b92", + "sha256:c543214ffdd422623e9fedd0869166c2f16affe4ba37463975043ef7d2ea8770", + "sha256:d28ddc3e3dfeab553e743e532fb95b4e6afad51d4706dd22f28e1e5e664828d2", + "sha256:f33592ddf9655a4894aef22d134de7393e95fcbdc2d15c1ab65828eee5c66c70", + "sha256:f6b0e77db9ff4fda74de7df13f30016a0a663928d669c9f2c057048ba44f09bb", + "sha256:f757063a83970d67c444f6e01d9550a7402322af3557ce7630d3c957386fa8f5", + "sha256:ff0cedc84184115202475bbb46dd99f8dcb87fe24d5d0ddfc0fe6b8575c88d2f" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.5.1" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "nbclient": { + "hashes": [ + "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e", + "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==0.9.0" + }, + "nbconvert": { + "hashes": [ + "sha256:abedc01cf543177ffde0bfc2a69726d5a478f6af10a332fc1bf29fcb4f0cf000", + "sha256:d1d417b7f34a4e38887f8da5bdfd12372adf3b80f995d57556cb0972c68909fe" + ], + "markers": "python_version >= '3.8'", + "version": "==7.11.0" + }, + "nbformat": { + "hashes": [ + "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9", + "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192" + ], + "markers": "python_version >= '3.8'", + "version": "==5.9.2" + }, + "nest-asyncio": { + "hashes": [ + "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb", + "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d" + ], + "markers": "python_version >= '3.5'", + "version": "==1.5.8" + }, + "networkx": { + "hashes": [ + "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", + "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.2.1" + }, + "notebook-shim": { + "hashes": [ + "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7", + "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9" + ], + "markers": "python_version >= '3.7'", + "version": "==0.2.3" + }, + "overrides": { + "hashes": [ + "sha256:3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d", + "sha256:9502a3cca51f4fac40b5feca985b6703a5c1f6ad815588a7ca9e285b9dca6757" + ], + "markers": "python_version >= '3.6'", + "version": "==7.4.0" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, + "pandocfilters": { + "hashes": [ + "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38", + "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.5.0" + }, + "parso": { + "hashes": [ + "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", + "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" + ], + "markers": "python_version >= '3.6'", + "version": "==0.8.3" + }, + "pexpect": { + "hashes": [ + "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", + "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + ], + "markers": "sys_platform != 'win32'", + "version": "==4.8.0" + }, + "platformdirs": { + "hashes": [ + "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", + "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.0" + }, + "pluggy": { + "hashes": [ + "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", + "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + ], + "markers": "python_version >= '3.8'", + "version": "==1.3.0" + }, + "prometheus-client": { + "hashes": [ + "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17", + "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184" + ], + "markers": "python_version >= '3.8'", + "version": "==0.18.0" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", + "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.0.41" + }, + "psutil": { + "hashes": [ + "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28", + "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017", + "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602", + "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac", + "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a", + "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9", + "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4", + "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c", + "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c", + "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c", + "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a", + "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c", + "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57", + "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a", + "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d", + "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==5.9.6" + }, + "ptyprocess": { + "hashes": [ + "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", + "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" + ], + "markers": "os_name != 'nt'", + "version": "==0.7.0" + }, + "pure-eval": { + "hashes": [ + "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", + "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" + ], + "version": "==0.2.2" + }, + "pycodestyle": { + "hashes": [ + "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0", + "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.11.0" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pygments": { + "hashes": [ + "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", + "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" + ], + "markers": "python_version >= '3.7'", + "version": "==2.16.1" + }, + "pyjwt": { + "hashes": [ + "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", + "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" + ], + "markers": "python_version >= '3.7'", + "version": "==2.8.0" + }, + "pytest": { + "hashes": [ + "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac", + "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==7.4.3" + }, + "python-arango": { + "hashes": [ + "sha256:8ae893d32220bbf7d0158fd8675a011219076189c82371543df75d650f9d0707", + "sha256:e8e9caefd65b21c263ec399d5d73ddaf119288cf684ffacada2c28cba322d2ba" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==7.6.2" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.2" + }, + "python-json-logger": { + "hashes": [ + "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c", + "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.7" + }, + "pyyaml": { + "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "pyzmq": { + "hashes": [ + "sha256:019e59ef5c5256a2c7378f2fb8560fc2a9ff1d315755204295b2eab96b254d0a", + "sha256:034239843541ef7a1aee0c7b2cb7f6aafffb005ede965ae9cbd49d5ff4ff73cf", + "sha256:03b3f49b57264909aacd0741892f2aecf2f51fb053e7d8ac6767f6c700832f45", + "sha256:047a640f5c9c6ade7b1cc6680a0e28c9dd5a0825135acbd3569cc96ea00b2505", + "sha256:04ccbed567171579ec2cebb9c8a3e30801723c575601f9a990ab25bcac6b51e2", + "sha256:057e824b2aae50accc0f9a0570998adc021b372478a921506fddd6c02e60308e", + "sha256:11baebdd5fc5b475d484195e49bae2dc64b94a5208f7c89954e9e354fc609d8f", + "sha256:11c1d2aed9079c6b0c9550a7257a836b4a637feb334904610f06d70eb44c56d2", + "sha256:11d58723d44d6ed4dd677c5615b2ffb19d5c426636345567d6af82be4dff8a55", + "sha256:12720a53e61c3b99d87262294e2b375c915fea93c31fc2336898c26d7aed34cd", + "sha256:17ef5f01d25b67ca8f98120d5fa1d21efe9611604e8eb03a5147360f517dd1e2", + "sha256:18d43df3f2302d836f2a56f17e5663e398416e9dd74b205b179065e61f1a6edf", + "sha256:1a5d26fe8f32f137e784f768143728438877d69a586ddeaad898558dc971a5ae", + "sha256:1af379b33ef33757224da93e9da62e6471cf4a66d10078cf32bae8127d3d0d4a", + "sha256:1ccf825981640b8c34ae54231b7ed00271822ea1c6d8ba1090ebd4943759abf5", + "sha256:21eb4e609a154a57c520e3d5bfa0d97e49b6872ea057b7c85257b11e78068222", + "sha256:2243700cc5548cff20963f0ca92d3e5e436394375ab8a354bbea2b12911b20b0", + "sha256:255ca2b219f9e5a3a9ef3081512e1358bd4760ce77828e1028b818ff5610b87b", + "sha256:259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23", + "sha256:25f0e6b78220aba09815cd1f3a32b9c7cb3e02cb846d1cfc526b6595f6046618", + "sha256:273bc3959bcbff3f48606b28229b4721716598d76b5aaea2b4a9d0ab454ec062", + "sha256:292fe3fc5ad4a75bc8df0dfaee7d0babe8b1f4ceb596437213821f761b4589f9", + "sha256:2ca57a5be0389f2a65e6d3bb2962a971688cbdd30b4c0bd188c99e39c234f414", + "sha256:2d163a18819277e49911f7461567bda923461c50b19d169a062536fffe7cd9d2", + "sha256:2d81f1ddae3858b8299d1da72dd7d19dd36aab654c19671aa8a7e7fb02f6638a", + "sha256:2f957ce63d13c28730f7fd6b72333814221c84ca2421298f66e5143f81c9f91f", + "sha256:330f9e188d0d89080cde66dc7470f57d1926ff2fb5576227f14d5be7ab30b9fa", + "sha256:34c850ce7976d19ebe7b9d4b9bb8c9dfc7aac336c0958e2651b88cbd46682123", + "sha256:35b5ab8c28978fbbb86ea54958cd89f5176ce747c1fb3d87356cf698048a7790", + "sha256:3669cf8ee3520c2f13b2e0351c41fea919852b220988d2049249db10046a7afb", + "sha256:381469297409c5adf9a0e884c5eb5186ed33137badcbbb0560b86e910a2f1e76", + "sha256:3d0a409d3b28607cc427aa5c30a6f1e4452cc44e311f843e05edb28ab5e36da0", + "sha256:44e58a0554b21fc662f2712814a746635ed668d0fbc98b7cb9d74cb798d202e6", + "sha256:458dea649f2f02a0b244ae6aef8dc29325a2810aa26b07af8374dc2a9faf57e3", + "sha256:48e466162a24daf86f6b5ca72444d2bf39a5e58da5f96370078be67c67adc978", + "sha256:49d238cf4b69652257db66d0c623cd3e09b5d2e9576b56bc067a396133a00d4a", + "sha256:4ca1ed0bb2d850aa8471387882247c68f1e62a4af0ce9c8a1dbe0d2bf69e41fb", + "sha256:52533489f28d62eb1258a965f2aba28a82aa747202c8fa5a1c7a43b5db0e85c1", + "sha256:548d6482dc8aadbe7e79d1b5806585c8120bafa1ef841167bc9090522b610fa6", + "sha256:5619f3f5a4db5dbb572b095ea3cb5cc035335159d9da950830c9c4db2fbb6995", + "sha256:57459b68e5cd85b0be8184382cefd91959cafe79ae019e6b1ae6e2ba8a12cda7", + "sha256:5a34d2395073ef862b4032343cf0c32a712f3ab49d7ec4f42c9661e0294d106f", + "sha256:61706a6b6c24bdece85ff177fec393545a3191eeda35b07aaa1458a027ad1304", + "sha256:724c292bb26365659fc434e9567b3f1adbdb5e8d640c936ed901f49e03e5d32e", + "sha256:73461eed88a88c866656e08f89299720a38cb4e9d34ae6bf5df6f71102570f2e", + "sha256:76705c9325d72a81155bb6ab48d4312e0032bf045fb0754889133200f7a0d849", + "sha256:76c1c8efb3ca3a1818b837aea423ff8a07bbf7aafe9f2f6582b61a0458b1a329", + "sha256:77a41c26205d2353a4c94d02be51d6cbdf63c06fbc1295ea57dad7e2d3381b71", + "sha256:79986f3b4af059777111409ee517da24a529bdbd46da578b33f25580adcff728", + "sha256:7cff25c5b315e63b07a36f0c2bab32c58eafbe57d0dce61b614ef4c76058c115", + "sha256:7f7e58effd14b641c5e4dec8c7dab02fb67a13df90329e61c869b9cc607ef752", + "sha256:820c4a08195a681252f46926de10e29b6bbf3e17b30037bd4250d72dd3ddaab8", + "sha256:87e34f31ca8f168c56d6fbf99692cc8d3b445abb5bfd08c229ae992d7547a92a", + "sha256:8f03d3f0d01cb5a018debeb412441996a517b11c5c17ab2001aa0597c6d6882c", + "sha256:90f26dc6d5f241ba358bef79be9ce06de58d477ca8485e3291675436d3827cf8", + "sha256:955215ed0604dac5b01907424dfa28b40f2b2292d6493445dd34d0dfa72586a8", + "sha256:985bbb1316192b98f32e25e7b9958088431d853ac63aca1d2c236f40afb17c83", + "sha256:a382372898a07479bd34bda781008e4a954ed8750f17891e794521c3e21c2e1c", + "sha256:a882ac0a351288dd18ecae3326b8a49d10c61a68b01419f3a0b9a306190baf69", + "sha256:aa8d6cdc8b8aa19ceb319aaa2b660cdaccc533ec477eeb1309e2a291eaacc43a", + "sha256:abc719161780932c4e11aaebb203be3d6acc6b38d2f26c0f523b5b59d2fc1996", + "sha256:abf34e43c531bbb510ae7e8f5b2b1f2a8ab93219510e2b287a944432fad135f3", + "sha256:ade6d25bb29c4555d718ac6d1443a7386595528c33d6b133b258f65f963bb0f6", + "sha256:afea96f64efa98df4da6958bae37f1cbea7932c35878b185e5982821bc883369", + "sha256:b1579413ae492b05de5a6174574f8c44c2b9b122a42015c5292afa4be2507f28", + "sha256:b3451108ab861040754fa5208bca4a5496c65875710f76789a9ad27c801a0075", + "sha256:b9af3757495c1ee3b5c4e945c1df7be95562277c6e5bccc20a39aec50f826cd0", + "sha256:bc16ac425cc927d0a57d242589f87ee093884ea4804c05a13834d07c20db203c", + "sha256:c2910967e6ab16bf6fbeb1f771c89a7050947221ae12a5b0b60f3bca2ee19bca", + "sha256:c2b92812bd214018e50b6380ea3ac0c8bb01ac07fcc14c5f86a5bb25e74026e9", + "sha256:c2f20ce161ebdb0091a10c9ca0372e023ce24980d0e1f810f519da6f79c60800", + "sha256:c56d748ea50215abef7030c72b60dd723ed5b5c7e65e7bc2504e77843631c1a6", + "sha256:c7c133e93b405eb0d36fa430c94185bdd13c36204a8635470cccc200723c13bb", + "sha256:c9c6c9b2c2f80747a98f34ef491c4d7b1a8d4853937bb1492774992a120f475d", + "sha256:cbc8df5c6a88ba5ae385d8930da02201165408dde8d8322072e3e5ddd4f68e22", + "sha256:cff084c6933680d1f8b2f3b4ff5bbb88538a4aac00d199ac13f49d0698727ecb", + "sha256:d2045d6d9439a0078f2a34b57c7b18c4a6aef0bee37f22e4ec9f32456c852c71", + "sha256:d20a0ddb3e989e8807d83225a27e5c2eb2260eaa851532086e9e0fa0d5287d83", + "sha256:d457aed310f2670f59cc5b57dcfced452aeeed77f9da2b9763616bd57e4dbaae", + "sha256:d89528b4943d27029a2818f847c10c2cecc79fa9590f3cb1860459a5be7933eb", + "sha256:db0b2af416ba735c6304c47f75d348f498b92952f5e3e8bff449336d2728795d", + "sha256:deee9ca4727f53464daf089536e68b13e6104e84a37820a88b0a057b97bba2d2", + "sha256:df27ffddff4190667d40de7beba4a950b5ce78fe28a7dcc41d6f8a700a80a3c0", + "sha256:e0c95ddd4f6e9fca4e9e3afaa4f9df8552f0ba5d1004e89ef0a68e1f1f9807c7", + "sha256:e1c1be77bc5fb77d923850f82e55a928f8638f64a61f00ff18a67c7404faf008", + "sha256:e1ffa1c924e8c72778b9ccd386a7067cddf626884fd8277f503c48bb5f51c762", + "sha256:e2400a94f7dd9cb20cd012951a0cbf8249e3d554c63a9c0cdfd5cbb6c01d2dec", + "sha256:e61f091c3ba0c3578411ef505992d356a812fb200643eab27f4f70eed34a29ef", + "sha256:e8a701123029cc240cea61dd2d16ad57cab4691804143ce80ecd9286b464d180", + "sha256:eadbefd5e92ef8a345f0525b5cfd01cf4e4cc651a2cffb8f23c0dd184975d787", + "sha256:f32260e556a983bc5c7ed588d04c942c9a8f9c2e99213fec11a031e316874c7e", + "sha256:f8115e303280ba09f3898194791a153862cbf9eef722ad8f7f741987ee2a97c7", + "sha256:fedbdc753827cf014c01dbbee9c3be17e5a208dcd1bf8641ce2cd29580d1f0d4" + ], + "markers": "python_version >= '3.6'", + "version": "==25.1.1" + }, + "referencing": { + "hashes": [ + "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf", + "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0" + ], + "markers": "python_version >= '3.8'", + "version": "==0.30.2" + }, + "regex": { + "hashes": [ + "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a", + "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07", + "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca", + "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58", + "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54", + "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed", + "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff", + "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528", + "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9", + "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971", + "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14", + "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af", + "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302", + "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec", + "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597", + "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b", + "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd", + "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767", + "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f", + "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6", + "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293", + "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be", + "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41", + "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc", + "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29", + "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964", + "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d", + "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a", + "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc", + "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55", + "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af", + "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930", + "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e", + "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d", + "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863", + "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c", + "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f", + "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e", + "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d", + "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368", + "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb", + "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52", + "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8", + "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4", + "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac", + "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e", + "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2", + "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a", + "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4", + "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa", + "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533", + "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b", + "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588", + "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0", + "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915", + "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841", + "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a", + "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988", + "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292", + "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3", + "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c", + "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f", + "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420", + "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9", + "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f", + "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0", + "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b", + "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037", + "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b", + "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee", + "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c", + "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b", + "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353", + "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051", + "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039", + "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a", + "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b", + "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e", + "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5", + "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf", + "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94", + "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991", + "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711", + "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a", + "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab", + "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a", + "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11", + "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48" + ], + "markers": "python_version >= '3.7'", + "version": "==2023.10.3" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.0.0" + }, + "rfc3339-validator": { + "hashes": [ + "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", + "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.1.4" + }, + "rfc3986-validator": { + "hashes": [ + "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", + "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.1.1" + }, + "rich": { + "hashes": [ + "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245", + "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==13.6.0" + }, + "rpds-py": { + "hashes": [ + "sha256:0525847f83f506aa1e28eb2057b696fe38217e12931c8b1b02198cfe6975e142", + "sha256:05942656cb2cb4989cd50ced52df16be94d344eae5097e8583966a1d27da73a5", + "sha256:0831d3ecdea22e4559cc1793f22e77067c9d8c451d55ae6a75bf1d116a8e7f42", + "sha256:0853da3d5e9bc6a07b2486054a410b7b03f34046c123c6561b535bb48cc509e1", + "sha256:08e6e7ff286254016b945e1ab632ee843e43d45e40683b66dd12b73791366dd1", + "sha256:0a38612d07a36138507d69646c470aedbfe2b75b43a4643f7bd8e51e52779624", + "sha256:0bedd91ae1dd142a4dc15970ed2c729ff6c73f33a40fa84ed0cdbf55de87c777", + "sha256:0c5441b7626c29dbd54a3f6f3713ec8e956b009f419ffdaaa3c80eaf98ddb523", + "sha256:0e9e976e0dbed4f51c56db10831c9623d0fd67aac02853fe5476262e5a22acb7", + "sha256:0fadfdda275c838cba5102c7f90a20f2abd7727bf8f4a2b654a5b617529c5c18", + "sha256:1096ca0bf2d3426cbe79d4ccc91dc5aaa73629b08ea2d8467375fad8447ce11a", + "sha256:171d9a159f1b2f42a42a64a985e4ba46fc7268c78299272ceba970743a67ee50", + "sha256:188912b22b6c8225f4c4ffa020a2baa6ad8fabb3c141a12dbe6edbb34e7f1425", + "sha256:1b4cf9ab9a0ae0cb122685209806d3f1dcb63b9fccdf1424fb42a129dc8c2faa", + "sha256:1e04581c6117ad9479b6cfae313e212fe0dfa226ac727755f0d539cd54792963", + "sha256:1fa73ed22c40a1bec98d7c93b5659cd35abcfa5a0a95ce876b91adbda170537c", + "sha256:2124f9e645a94ab7c853bc0a3644e0ca8ffbe5bb2d72db49aef8f9ec1c285733", + "sha256:240687b5be0f91fbde4936a329c9b7589d9259742766f74de575e1b2046575e4", + "sha256:25740fb56e8bd37692ed380e15ec734be44d7c71974d8993f452b4527814601e", + "sha256:27ccc93c7457ef890b0dd31564d2a05e1aca330623c942b7e818e9e7c2669ee4", + "sha256:281c8b219d4f4b3581b918b816764098d04964915b2f272d1476654143801aa2", + "sha256:2d34a5450a402b00d20aeb7632489ffa2556ca7b26f4a63c35f6fccae1977427", + "sha256:301bd744a1adaa2f6a5e06c98f1ac2b6f8dc31a5c23b838f862d65e32fca0d4b", + "sha256:30e5ce9f501fb1f970e4a59098028cf20676dee64fc496d55c33e04bbbee097d", + "sha256:33ab498f9ac30598b6406e2be1b45fd231195b83d948ebd4bd77f337cb6a2bff", + "sha256:35585a8cb5917161f42c2104567bb83a1d96194095fc54a543113ed5df9fa436", + "sha256:389c0e38358fdc4e38e9995e7291269a3aead7acfcf8942010ee7bc5baee091c", + "sha256:3acadbab8b59f63b87b518e09c4c64b142e7286b9ca7a208107d6f9f4c393c5c", + "sha256:3b7a64d43e2a1fa2dd46b678e00cabd9a49ebb123b339ce799204c44a593ae1c", + "sha256:3c8c0226c71bd0ce9892eaf6afa77ae8f43a3d9313124a03df0b389c01f832de", + "sha256:429349a510da82c85431f0f3e66212d83efe9fd2850f50f339341b6532c62fe4", + "sha256:466030a42724780794dea71eb32db83cc51214d66ab3fb3156edd88b9c8f0d78", + "sha256:47aeceb4363851d17f63069318ba5721ae695d9da55d599b4d6fb31508595278", + "sha256:48aa98987d54a46e13e6954880056c204700c65616af4395d1f0639eba11764b", + "sha256:4b2416ed743ec5debcf61e1242e012652a4348de14ecc7df3512da072b074440", + "sha256:4d0a675a7acbbc16179188d8c6d0afb8628604fc1241faf41007255957335a0b", + "sha256:4eb74d44776b0fb0782560ea84d986dffec8ddd94947f383eba2284b0f32e35e", + "sha256:4f8a1d990dc198a6c68ec3d9a637ba1ce489b38cbfb65440a27901afbc5df575", + "sha256:513ccbf7420c30e283c25c82d5a8f439d625a838d3ba69e79a110c260c46813f", + "sha256:5210a0018c7e09c75fa788648617ebba861ae242944111d3079034e14498223f", + "sha256:54cdfcda59251b9c2f87a05d038c2ae02121219a04d4a1e6fc345794295bdc07", + "sha256:56dd500411d03c5e9927a1eb55621e906837a83b02350a9dc401247d0353717c", + "sha256:57ec6baec231bb19bb5fd5fc7bae21231860a1605174b11585660236627e390e", + "sha256:5f1519b080d8ce0a814f17ad9fb49fb3a1d4d7ce5891f5c85fc38631ca3a8dc4", + "sha256:6174d6ad6b58a6bcf67afbbf1723420a53d06c4b89f4c50763d6fa0a6ac9afd2", + "sha256:68172622a5a57deb079a2c78511c40f91193548e8ab342c31e8cb0764d362459", + "sha256:6915fc9fa6b3ec3569566832e1bb03bd801c12cea030200e68663b9a87974e76", + "sha256:6b75b912a0baa033350367a8a07a8b2d44fd5b90c890bfbd063a8a5f945f644b", + "sha256:6f5dcb658d597410bb7c967c1d24eaf9377b0d621358cbe9d2ff804e5dd12e81", + "sha256:6f8d7fe73d1816eeb5378409adc658f9525ecbfaf9e1ede1e2d67a338b0c7348", + "sha256:7036316cc26b93e401cedd781a579be606dad174829e6ad9e9c5a0da6e036f80", + "sha256:7188ddc1a8887194f984fa4110d5a3d5b9b5cd35f6bafdff1b649049cbc0ce29", + "sha256:761531076df51309075133a6bc1db02d98ec7f66e22b064b1d513bc909f29743", + "sha256:7979d90ee2190d000129598c2b0c82f13053dba432b94e45e68253b09bb1f0f6", + "sha256:8015835494b21aa7abd3b43fdea0614ee35ef6b03db7ecba9beb58eadf01c24f", + "sha256:81c4d1a3a564775c44732b94135d06e33417e829ff25226c164664f4a1046213", + "sha256:81cf9d306c04df1b45971c13167dc3bad625808aa01281d55f3cf852dde0e206", + "sha256:88857060b690a57d2ea8569bca58758143c8faa4639fb17d745ce60ff84c867e", + "sha256:8c567c664fc2f44130a20edac73e0a867f8e012bf7370276f15c6adc3586c37c", + "sha256:91bd2b7cf0f4d252eec8b7046fa6a43cee17e8acdfc00eaa8b3dbf2f9a59d061", + "sha256:9620650c364c01ed5b497dcae7c3d4b948daeae6e1883ae185fef1c927b6b534", + "sha256:9b007c2444705a2dc4a525964fd4dd28c3320b19b3410da6517cab28716f27d3", + "sha256:9bf9acce44e967a5103fcd820fc7580c7b0ab8583eec4e2051aec560f7b31a63", + "sha256:a239303acb0315091d54c7ff36712dba24554993b9a93941cf301391d8a997ee", + "sha256:a2baa6be130e8a00b6cbb9f18a33611ec150b4537f8563bddadb54c1b74b8193", + "sha256:a54917b7e9cd3a67e429a630e237a90b096e0ba18897bfb99ee8bd1068a5fea0", + "sha256:a689e1ded7137552bea36305a7a16ad2b40be511740b80748d3140614993db98", + "sha256:a952ae3eb460c6712388ac2ec706d24b0e651b9396d90c9a9e0a69eb27737fdc", + "sha256:aa32205358a76bf578854bf31698a86dc8b2cb591fd1d79a833283f4a403f04b", + "sha256:b2287c09482949e0ca0c0eb68b2aca6cf57f8af8c6dfd29dcd3bc45f17b57978", + "sha256:b6b0e17d39d21698185097652c611f9cf30f7c56ccec189789920e3e7f1cee56", + "sha256:b710bf7e7ae61957d5c4026b486be593ed3ec3dca3e5be15e0f6d8cf5d0a4990", + "sha256:b8e11715178f3608874508f08e990d3771e0b8c66c73eb4e183038d600a9b274", + "sha256:b92aafcfab3d41580d54aca35a8057341f1cfc7c9af9e8bdfc652f83a20ced31", + "sha256:bec29b801b4adbf388314c0d050e851d53762ab424af22657021ce4b6eb41543", + "sha256:c694bee70ece3b232df4678448fdda245fd3b1bb4ba481fb6cd20e13bb784c46", + "sha256:c6b52b7028b547866c2413f614ee306c2d4eafdd444b1ff656bf3295bf1484aa", + "sha256:cb41ad20064e18a900dd427d7cf41cfaec83bcd1184001f3d91a1f76b3fcea4e", + "sha256:cd316dbcc74c76266ba94eb021b0cc090b97cca122f50bd7a845f587ff4bf03f", + "sha256:ced40cdbb6dd47a032725a038896cceae9ce267d340f59508b23537f05455431", + "sha256:d1c562a9bb72244fa767d1c1ab55ca1d92dd5f7c4d77878fee5483a22ffac808", + "sha256:d389ff1e95b6e46ebedccf7fd1fadd10559add595ac6a7c2ea730268325f832c", + "sha256:d56b1cd606ba4cedd64bb43479d56580e147c6ef3f5d1c5e64203a1adab784a2", + "sha256:d72a4315514e5a0b9837a086cb433b004eea630afb0cc129de76d77654a9606f", + "sha256:d9e7f29c00577aff6b318681e730a519b235af292732a149337f6aaa4d1c5e31", + "sha256:dbc25baa6abb205766fb8606f8263b02c3503a55957fcb4576a6bb0a59d37d10", + "sha256:e57919c32ee295a2fca458bb73e4b20b05c115627f96f95a10f9f5acbd61172d", + "sha256:e5bbe011a2cea9060fef1bb3d668a2fd8432b8888e6d92e74c9c794d3c101595", + "sha256:e6aea5c0eb5b0faf52c7b5c4a47c8bb64437173be97227c819ffa31801fa4e34", + "sha256:e888be685fa42d8b8a3d3911d5604d14db87538aa7d0b29b1a7ea80d354c732d", + "sha256:eebaf8c76c39604d52852366249ab807fe6f7a3ffb0dd5484b9944917244cdbe", + "sha256:efbe0b5e0fd078ed7b005faa0170da4f72666360f66f0bb2d7f73526ecfd99f9", + "sha256:efddca2d02254a52078c35cadad34762adbae3ff01c6b0c7787b59d038b63e0d", + "sha256:f05450fa1cd7c525c0b9d1a7916e595d3041ac0afbed2ff6926e5afb6a781b7f", + "sha256:f12d69d568f5647ec503b64932874dade5a20255736c89936bf690951a5e79f5", + "sha256:f45321224144c25a62052035ce96cbcf264667bcb0d81823b1bbc22c4addd194", + "sha256:f62581d7e884dd01ee1707b7c21148f61f2febb7de092ae2f108743fcbef5985", + "sha256:f8832a4f83d4782a8f5a7b831c47e8ffe164e43c2c148c8160ed9a6d630bc02a", + "sha256:fa35ad36440aaf1ac8332b4a4a433d4acd28f1613f0d480995f5cfd3580e90b7" + ], + "markers": "python_version >= '3.8'", + "version": "==0.12.0" + }, + "send2trash": { + "hashes": [ + "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679", + "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.8.2" + }, + "setuptools": { + "hashes": [ + "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", + "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" + ], + "markers": "python_version >= '3.8'", + "version": "==68.2.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sniffio": { + "hashes": [ + "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", + "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0" + }, + "soupsieve": { + "hashes": [ + "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", + "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7" + ], + "markers": "python_version >= '3.8'", + "version": "==2.5" + }, + "spectate": { + "hashes": [ + "sha256:49a2dde0962fcecf120cb361cc293989489078eb29ba1d8c3d342a741e898b7e", + "sha256:c4585194c238979f953fbf2ecf9f94c84d9d0a929432c7104e39984f52c9e718" + ], + "markers": "python_version >= '3.6'", + "version": "==1.0.1" + }, + "stack-data": { + "hashes": [ + "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", + "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" + ], + "version": "==0.6.3" + }, + "terminado": { + "hashes": [ + "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded", + "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e" + ], + "markers": "python_version >= '3.8'", + "version": "==0.18.0" + }, + "tiktoken": { + "hashes": [ + "sha256:1f2b3b253e22322b7f53a111e1f6d7ecfa199b4f08f3efdeb0480f4033b5cdc6", + "sha256:1fe99953b63aabc0c9536fbc91c3c9000d78e4755edc28cc2e10825372046a2d", + "sha256:27e773564232004f4f810fd1f85236673ec3a56ed7f1206fc9ed8670ebedb97a", + "sha256:2b0bae3fd56de1c0a5874fb6577667a3c75bf231a6cef599338820210c16e40a", + "sha256:2b756a65d98b7cf760617a6b68762a23ab8b6ef79922be5afdb00f5e8a9f4e76", + "sha256:323cec0031358bc09aa965c2c5c1f9f59baf76e5b17e62dcc06d1bb9bc3a3c7c", + "sha256:426e7def5f3f23645dada816be119fa61e587dfb4755de250e136b47a045c365", + "sha256:43ce0199f315776dec3ea7bf86f35df86d24b6fcde1babd3e53c38f17352442f", + "sha256:46b8554b9f351561b1989157c6bb54462056f3d44e43aa4e671367c5d62535fc", + "sha256:5abd9436f02e2c8eda5cce2ff8015ce91f33e782a7423de2a1859f772928f714", + "sha256:5d5a187ff9c786fae6aadd49f47f019ff19e99071dc5b0fe91bfecc94d37c686", + "sha256:709a5220891f2b56caad8327fab86281787704931ed484d9548f65598dea9ce4", + "sha256:714efb2f4a082635d9f5afe0bf7e62989b72b65ac52f004eb7ac939f506c03a4", + "sha256:74c90d2be0b4c1a2b3f7dde95cd976757817d4df080d6af0ee8d461568c2e2ad", + "sha256:779c4dea5edd1d3178734d144d32231e0b814976bec1ec09636d1003ffe4725f", + "sha256:7ef730db4097f5b13df8d960f7fdda2744fe21d203ea2bb80c120bb58661b155", + "sha256:8079ac065572fe0e7c696dbd63e1fdc12ce4cdca9933935d038689d4732451df", + "sha256:92ed3bbf71a175a6a4e5fbfcdb2c422bdd72d9b20407e00f435cf22a68b4ea9b", + "sha256:9b180a22db0bbcc447f691ffc3cf7a580e9e0587d87379e35e58b826ebf5bc7b", + "sha256:a10488d1d1a5f9c9d2b2052fdb4cf807bba545818cb1ef724a7f5d44d9f7c3d4", + "sha256:a84657c083d458593c0235926b5c993eec0b586a2508d6a2020556e5347c2f0d", + "sha256:b5dcfcf9bfb798e86fbce76d40a1d5d9e3f92131aecfa3d1e5c9ea1a20f1ef1a", + "sha256:ba9873c253ca1f670e662192a0afcb72b41e0ba3e730f16c665099e12f4dac2d", + "sha256:c008375c0f3d97c36e81725308699116cd5804fdac0f9b7afc732056329d2790", + "sha256:dcdc630461927718b317e6f8be7707bd0fc768cee1fdc78ddaa1e93f4dc6b2b1", + "sha256:e21840043dbe2e280e99ad41951c00eff8ee3b63daf57cd4c1508a3fd8583ea2", + "sha256:e4c73d47bdc1a3f1f66ffa019af0386c48effdc6e8797e5e76875f6388ff72e9", + "sha256:e529578d017045e2f0ed12d2e00e7e99f780f477234da4aae799ec4afca89f37", + "sha256:edd2ffbb789712d83fee19ab009949f998a35c51ad9f9beb39109357416344ff" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==0.5.1" + }, + "tinycss2": { + "hashes": [ + "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", + "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.1" + }, + "tornado": { + "hashes": [ + "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f", + "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5", + "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d", + "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3", + "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2", + "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a", + "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16", + "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a", + "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17", + "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0", + "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe" + ], + "markers": "python_version >= '3.8'", + "version": "==6.3.3" + }, + "traitlets": { + "hashes": [ + "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5", + "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619" + ], + "markers": "python_version >= '3.8'", + "version": "==5.13.0" + }, + "types-python-dateutil": { + "hashes": [ + "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b", + "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9" + ], + "version": "==2.8.19.14" + }, + "typing-extensions": { + "hashes": [ + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" + ], + "markers": "python_version >= '3.8'", + "version": "==4.8.0" + }, + "uri-template": { + "hashes": [ + "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", + "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363" + ], + "version": "==1.3.0" + }, + "urllib3": { + "hashes": [ + "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", + "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.18" + }, + "wcwidth": { + "hashes": [ + "sha256:390c7454101092a6a5e43baad8f83de615463af459201709556b6e4b1c861f97", + "sha256:aec5179002dd0f0d40c456026e74a729661c9d468e1ed64405e3a6c2176ca36f" + ], + "version": "==0.2.10" + }, + "webcolors": { + "hashes": [ + "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf", + "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a" + ], + "version": "==1.13" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "websocket-client": { + "hashes": [ + "sha256:084072e0a7f5f347ef2ac3d8698a5e0b4ffbfcab607628cadabc650fc9a83a24", + "sha256:b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df" + ], + "markers": "python_version >= '3.8'", + "version": "==1.6.4" + }, + "widgetsnbextension": { + "hashes": [ + "sha256:3c1f5e46dc1166dfd40a42d685e6a51396fd34ff878742a3e47c6f0cc4a2a385", + "sha256:91452ca8445beb805792f206e560c1769284267a30ceb1cec9f5bcc887d15175" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.9" + }, + "zipp": { + "hashes": [ + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + ], + "markers": "python_version >= '3.8'", + "version": "==3.17.0" + } + } +} diff --git a/llm/bin/dev.sh b/llm/bin/dev.sh new file mode 100755 index 0000000000..0493520bdd --- /dev/null +++ b/llm/bin/dev.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -o errexit # exit on command failure; use || true to allow for exception +set -o nounset # exit when script tries to use undeclared variables + +python -m jupyterlab --ip=0.0.0.0 --allow-***ARANGO_USERNAME*** --no-browser --port 8888 diff --git a/llm/bin/startup.sh b/llm/bin/startup.sh new file mode 100755 index 0000000000..510a631fca --- /dev/null +++ b/llm/bin/startup.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -o errexit # exit on command failure; use || true to allow for exception +set -o nounset # exit when script tries to use undeclared variables + +if [ "${FLASK_ENV}" = "development" ] && [ "${FLASK_APP_CONFIG}" = "Development" ]; then + flask run --host 0.0.0.0 +elif [ "${FLASK_APP_CONFIG}" = "Production" ] || [ "${FLASK_APP_CONFIG}" = "Staging" ] || [ "${FLASK_APP_CONFIG}" = "QA" ]; then + gunicorn -b 0.0.0.0:5000 --workers=2 --max-requests=200 "llmlib.app:app" --timeout 1200 +else + echo "No environment setup for ${FLASK_ENV}" +fi diff --git a/llm/develop/Using query chain.ipynb b/llm/develop/Using query chain.ipynb new file mode 100644 index 0000000000..441dcf3da6 --- /dev/null +++ b/llm/develop/Using query chain.ipynb @@ -0,0 +1,1208 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6fda1acd-9514-4db5-ba8e-68255beb4c51", + "metadata": {}, + "source": [ + "# Init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d349fffb-0042-4a5a-8984-d9c937be660e", + "metadata": { + "collapsed": false, + "is_executing": true, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "%load_ext autoreload" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98bb8a3a-1acb-4fab-a8dd-c7671b684fab", + "metadata": {}, + "outputs": [], + "source": [ + "from app import app\n", + "context = app.app_context()\n", + "context.push()" + ] + }, + { + "cell_type": "markdown", + "id": "77a6dda5-ebc3-4d0a-8c22-62295460d871", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "603eded2-cac8-4cf6-9a7f-9294369e96cd", + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "from utils import formatters # Provide jupyter output formating" + ] + }, + { + "cell_type": "markdown", + "id": "bd918ef6-ec05-420f-8dc4-3a84e50de805", + "metadata": {}, + "source": [ + "## Inputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0ad8eda-d372-4002-b609-42899582eb2a", + "metadata": {}, + "outputs": [], + "source": [ + "query=\"What is the relationship between Zn2+ and glycolate?\"" + ] + }, + { + "cell_type": "markdown", + "id": "877af485-bd94-4352-a511-d25d3e561b87", + "metadata": {}, + "source": [ + "## Initial check\n", + "\n", + "Current response:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f791641-1009-4fb6-b1ea-26521b8dddd2", + "metadata": {}, + "outputs": [], + "source": [ + "import openai\n", + "response = openai.ChatCompletion.create(\n", + " messages=[\n", + " { \"role\": \"user\", \"content\": query }\n", + " ],\n", + " model=\"gpt-3.5-turbo\",\n", + " temperature=0\n", + ")\n", + "response" + ] + }, + { + "cell_type": "markdown", + "id": "2c0298d0-b147-4971-9606-d871307ebe56", + "metadata": {}, + "source": [ + "# Extract core terms" + ] + }, + { + "cell_type": "markdown", + "id": "9ac517bb-5e7c-4562-9e49-25dbd2658122", + "metadata": {}, + "source": [ + "## Init model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7c93291-a342-485f-950e-97d12e528bfc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain.chat_models import ChatOpenAI\n", + "llm = ChatOpenAI(temperature=0)\n", + "llm" + ] + }, + { + "cell_type": "markdown", + "id": "b3d667ea-96aa-48e6-8d36-4da4e6157069", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Pepare prompts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa15f752-9d1f-4f29-9b56-14d4e6224dcf", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain.prompts import PromptTemplate\n", + "from langchain.prompts.chat import (\n", + " ChatPromptTemplate,\n", + " SystemMessagePromptTemplate,\n", + " HumanMessagePromptTemplate,\n", + ")\n", + "QUERY_KEY = 'query'\n", + "\n", + "core_terms_prompt_template = ChatPromptTemplate.from_messages([\n", + " SystemMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=\"Always response with comma separated list of chemical or biological terms identified in prompt.\",\n", + " input_variables=[]\n", + " )\n", + " ),\n", + " HumanMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=f\"{{{QUERY_KEY}}}\",\n", + " input_variables=[QUERY_KEY],\n", + " )\n", + " )\n", + "])\n", + "core_terms_prompt_template" + ] + }, + { + "cell_type": "markdown", + "id": "ee248fb0-b606-46e4-8989-948a41ca0be7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Create output parser" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08883978-6bf6-401d-a26f-29eca24e761d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain.output_parsers import CommaSeparatedListOutputParser\n", + "output_parser = CommaSeparatedListOutputParser()\n", + "output_parser" + ] + }, + { + "cell_type": "markdown", + "id": "4204b681-7b63-4f06-8076-e1cde25a7261", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Create chain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3fe60f84-e54c-4903-84e3-05e2a9864cb8", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain import LLMChain\n", + "CORE_TERMS_KEY = 'core_terms'\n", + "core_terms_chain = LLMChain(\n", + " llm=llm,\n", + " prompt=core_terms_prompt_template,\n", + " output_parser=output_parser,\n", + " output_key=CORE_TERMS_KEY,\n", + " verbose=True\n", + ")\n", + "core_terms_chain" + ] + }, + { + "cell_type": "markdown", + "id": "e0179e2f-146a-4d28-97f3-abdfa79713b6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "161651c8-d245-43a9-b8a7-18aa0e1a48d2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "core_terms = core_terms_chain.run(query)\n", + "core_terms" + ] + }, + { + "cell_type": "markdown", + "id": "24f4dca0-4c03-41bf-a916-817443a1850b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# Find core terms eids" + ] + }, + { + "cell_type": "markdown", + "id": "5248bd24-f3ef-4316-95a1-dccb8a99862d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Create chain construct to query db" + ] + }, + { + "cell_type": "markdown", + "id": "ae4445d6-22a6-4178-a5f7-0dc4cc1f2674", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Prepare graph results output parser\n", + "Unwraps query output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99d1e485-fa7d-456e-a66a-34433fa3ec9e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from llmlib.utils.output_parsers.graph_results import GraphResultsOutputParser" + ] + }, + { + "cell_type": "markdown", + "id": "66a53296-7b73-48bb-b02f-12e56d30000e", + "metadata": {}, + "source": [ + "### Prepare chain construct with output parser" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1b3acd93-57da-4d93-8204-aeed3862cb25", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from llmlib.utils.chains.graph_query import GraphQueryChain" + ] + }, + { + "cell_type": "markdown", + "id": "546e6ec9-4de6-4931-a1b2-690701c752bb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Get graph reference" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4a43b53-a0df-4c5c-adf4-18a7e60d32e3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from llmlib.database import Neo4j" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2bf3d50-25b5-42fd-88ae-4d6fe3aec03e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph = Neo4j().graph()" + ] + }, + { + "cell_type": "markdown", + "id": "619cfbef-3d3a-4319-b515-bcddabd85655", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Create chain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0831a9c4-32d0-419a-af0e-ee740bf24011", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "query_output_key = 'output'\n", + "EID_MAPPING_KEY = 'eid_mapping'\n", + "find_eids_chain = GraphQueryChain(\n", + " query=f\"\"\"\n", + "UNWIND ${CORE_TERMS_KEY} AS term\n", + "MATCH (s:Synonym {{lowercase_name: toLower(term)}})<-[:HAS_SYNONYM]-(n)\n", + "WHERE n.eid IS NOT NULL\n", + "WITH DISTINCT s.name as term, collect(n.eid) as eids\n", + "RETURN apoc.text.format(\n", + " \"{{term: %s, eid: [%s]}}\",\n", + " [term, apoc.text.join(eids, ',')]\n", + ") as {query_output_key}\n", + "\"\"\",\n", + " input_keys=[CORE_TERMS_KEY],\n", + " output_key=EID_MAPPING_KEY,\n", + " graph=graph,\n", + " output_parser=GraphResultsOutputParser(key=query_output_key),\n", + " verbose=True\n", + ")\n", + "find_eids_chain" + ] + }, + { + "cell_type": "markdown", + "id": "3917447a-cff1-48db-a935-bafbd16f866d", + "metadata": {}, + "source": [ + "### Run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "589b9106-c144-48ec-b139-69a512151f1c", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "eid_mapping = find_eids_chain.run(core_terms)\n", + "eid_mapping" + ] + }, + { + "cell_type": "markdown", + "id": "c9a04cf2-19a3-4bf6-b8c3-5a996820c9ac", + "metadata": {}, + "source": [ + "## Combine chains test" + ] + }, + { + "cell_type": "markdown", + "id": "b3d3e753-dd60-4d11-9be5-4ae546e51994", + "metadata": {}, + "source": [ + "### Combine chains" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "762a5ba9-8e42-4867-ad76-3e82eabb6d50", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chains import SimpleSequentialChain\n", + "chain = SimpleSequentialChain(\n", + " chains=[\n", + " core_terms_chain,\n", + " find_eids_chain\n", + " ],\n", + " verbose=True\n", + ")\n", + "chain" + ] + }, + { + "cell_type": "markdown", + "id": "d72f2714-571a-4747-b9b4-3ec8db36a9be", + "metadata": {}, + "source": [ + "### Test" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6f78e535-790b-42c2-aba7-57490e49257f", + "metadata": {}, + "outputs": [], + "source": [ + "output = chain.run(query)\n", + "output" + ] + }, + { + "cell_type": "markdown", + "id": "e6214fa0-f74d-40b6-9c7f-2519568db3fe", + "metadata": {}, + "source": [ + "# Respond to inquiry given database context" + ] + }, + { + "cell_type": "markdown", + "id": "da63ae13-c0b2-4ef6-8b5b-a3842b9e80c3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Get graph reference" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30dfe983-ab71-42b0-a159-1ab1d6301fe8", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from llmlib.database import Neo4j" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a08b693-a770-40fc-a0c2-0c2d78551488", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph = Neo4j().graph()" + ] + }, + { + "cell_type": "markdown", + "id": "5104d3a5-ff86-4dae-be7b-79d8f236a9ea", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "### Show schema preview" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb795e6b-1ad9-44f7-9e1a-dce85bd18ac9", + "metadata": { + "editable": true, + "raw_mimetype": "", + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph.schema" + ] + }, + { + "cell_type": "markdown", + "id": "64527b5b-82cb-415e-9bbb-63daedd2f0c6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Limit schema\n", + "\n", + "Whole schema is too big to fit into request context - limit it to required parts." + ] + }, + { + "cell_type": "markdown", + "id": "6ae59ca1-93d2-496b-aa54-554e4661a1ef", + "metadata": {}, + "source": [ + "### Set utils" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65d66ba9-b760-45fa-80aa-9d06f1d0dfc2", + "metadata": {}, + "outputs": [], + "source": [ + "result_parser_factory = lambda key: lambda result: list(map(lambda row: row[key], result))\n", + "output_result_parser = result_parser_factory('output')" + ] + }, + { + "cell_type": "markdown", + "id": "81d6c3cf-1c02-491f-af31-b6dc7bb1db80", + "metadata": {}, + "source": [ + "### Get preselected node properties" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92112ba0-c2f3-4153-ab82-4e6e49c5dcec", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "preselected_node_properties = [ \"displayName\", \"eid\" ]\n", + "preselected_node_labels = [\"Compound\", \"Reaction\", \"EnzReaction\", \"Regulation\"]\n", + "node_properties_query = \"\"\"\n", + "CALL apoc.meta.data()\n", + "YIELD label, other, elementType, type, property\n", + "WHERE NOT type = \"RELATIONSHIP\" AND elementType = \"node\" AND label in $preselected_node_labels AND property in $preselected_node_properties\n", + "WITH label AS nodeLabels, collect({property:property, type:type}) AS properties\n", + "RETURN {labels: nodeLabels, properties: properties} AS output\n", + "\"\"\"\n", + "node_properties = output_result_parser(\n", + " graph.query(\n", + " node_properties_query,\n", + " dict(\n", + " preselected_node_properties=preselected_node_properties,\n", + " preselected_node_labels=preselected_node_labels\n", + " )\n", + " )\n", + ")\n", + "node_properties" + ] + }, + { + "cell_type": "markdown", + "id": "576cdc57-aa35-44eb-80a9-7d8e190a94eb", + "metadata": {}, + "source": [ + "### Get preselected relationship properties" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f59f8403-3e8a-448d-a410-7d70bc835ee3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "preselected_relationship_types = [\"CONSUMED_BY\", \"PRODUCES\", \"CATALYZES\", \"REGULATES\"]\n", + "rel_properties_query = \"\"\"\n", + "CALL apoc.meta.data()\n", + "YIELD label, other, elementType, type, property\n", + "WHERE NOT type = \"RELATIONSHIP\" AND elementType = \"relationship\" AND type in $preselected_relationship_types\n", + "WITH label AS nodeLabels, collect({property:property, type:type}) AS properties\n", + "RETURN {type: nodeLabels, properties: properties} AS output\n", + "\"\"\"\n", + "relationships_properties = output_result_parser(\n", + " graph.query(\n", + " rel_properties_query,\n", + " dict(\n", + " preselected_relationship_types=preselected_relationship_types,\n", + " )\n", + " )\n", + ")\n", + "relationships_properties" + ] + }, + { + "cell_type": "markdown", + "id": "7dcccf1f-42f5-40c8-85e0-371a552302a2", + "metadata": {}, + "source": [ + "### Get preselected relationships" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d0bba8c-c3d6-425e-94d2-e7afc5d059ad", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "rel_query = \"\"\"\n", + "CALL apoc.meta.data()\n", + "YIELD label, other, elementType, type, property\n", + "WHERE type = \"RELATIONSHIP\" AND elementType = \"node\" AND property in $preselected_relationship_types AND label in $preselected_node_labels\n", + "UNWIND other AS other_node\n", + "WITH label, property, toString(other_node) as other_node\n", + "WHERE other_node in $preselected_node_labels\n", + "RETURN {start: label, type: property, end: toString(other_node)} AS output\n", + "\"\"\"\n", + "relationships = output_result_parser(\n", + " graph.query(\n", + " rel_query,\n", + " dict(\n", + " preselected_relationship_types=preselected_relationship_types,\n", + " preselected_node_labels=preselected_node_labels\n", + " )\n", + " )\n", + ")\n", + "relationships" + ] + }, + { + "cell_type": "markdown", + "id": "e6971ce7-21bd-4ec4-b231-ed805a8b334e", + "metadata": {}, + "source": [ + "### Compose schema" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ab33653c-75ba-4a31-a78f-7750d1194d24", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "limited_schema = f\"\"\"\n", + "Node properties are the following:\n", + "{node_properties}\n", + "Relationship properties are the following:\n", + "{relationships_properties}\n", + "The relationships are the following:\n", + "{relationships}\n", + "\"\"\"\n", + "limited_schema" + ] + }, + { + "cell_type": "markdown", + "id": "1bd1da66-81cb-46d8-8148-71a8986046a3", + "metadata": {}, + "source": [ + "### Set schema on the graph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1a9644c-23ab-42bb-a0b8-6f2873929b22", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph.schema = limited_schema\n", + "graph.structured_schema = {\n", + " \"node_props\": {el[\"labels\"]: el[\"properties\"] for el in node_properties},\n", + " \"rel_props\": {el[\"type\"]: el[\"properties\"] for el in relationships_properties},\n", + " \"relationships\": relationships,\n", + "}\n", + "graph.structured_schema" + ] + }, + { + "cell_type": "markdown", + "id": "1d0eadfb-2220-4085-bcbe-f00892d62560", + "metadata": {}, + "source": [ + "## Prepare prompts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bcc8a296-950e-4d3a-bf13-5c2244c78137", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "from langchain import OpenAI, PromptTemplate\n", + "\n", + "SCHEMA_KEY = 'schema'\n", + "EXAMPLES_KEY = 'examples'\n", + "\n", + "cypher_generation_template = f\"\"\"\n", + "Task:Generate Cypher statements to query a graph database.\n", + "Instructions:\n", + "Use only the provided relationship types and properties in the schema.\n", + "Do not use any other relationship types or properties that are not provided.\n", + "If quering for relationship filter out following eids: [\"PROTON\"]\n", + "Schema:\n", + "{{{SCHEMA_KEY}}}\n", + "Examples:\n", + "{{{EXAMPLES_KEY}}}\n", + "Note: Do not include any explanations or apologies in your responses.\n", + "Do not respond to any questions that might ask anything else than for you to construct a Cypher statements.\n", + "Do not include any text except the generated Cypher statements.\n", + "Do not wrap statements in brackets.\n", + "Use example queries.\n", + "\n", + "The question is:\n", + "{{{QUERY_KEY}}}\n", + "\"\"\"\n", + "\n", + "cypher_prompt = PromptTemplate(\n", + " input_variables=[SCHEMA_KEY, EXAMPLES_KEY, QUERY_KEY], template=cypher_generation_template\n", + ")\n", + "cypher_prompt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6dfb939-aab1-46a6-838f-c443b193d6a6", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "from langchain.prompts import PromptTemplate\n", + "from langchain.chains import GraphCypherQAChain\n", + "from langchain.prompts.chat import (\n", + " ChatPromptTemplate,\n", + " SystemMessagePromptTemplate,\n", + " HumanMessagePromptTemplate,\n", + " AIMessagePromptTemplate,\n", + ")\n", + "\n", + "graph_qa_prompt_template = ChatPromptTemplate.from_messages([\n", + " SystemMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=\"You are an expert in field of biology and chemistry with access to graph database.\",\n", + " input_variables=[]\n", + " )\n", + " ),\n", + " HumanMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=f\"\"\"\n", + " Step 1: For given inquiry identify core terms.\n", + " Step 2: Return mapping from core term to list of database 'eid' for related entities.\n", + " Inqury: {{{QUERY_KEY}}}\n", + " \"\"\",\n", + " input_variables=[QUERY_KEY],\n", + " )\n", + " ),\n", + " AIMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=f\"{{{EID_MAPPING_KEY}}}\",\n", + " input_variables=[EID_MAPPING_KEY]\n", + " )\n", + " ),\n", + " HumanMessagePromptTemplate(prompt=cypher_prompt)\n", + "])\n", + "graph_qa_prompt_template" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b720d7b3-31cd-4ec8-afac-f37e76a6e96f", + "metadata": {}, + "outputs": [], + "source": [ + "qa_prompt_template = f\"\"\"You are an assistant that helps to form nice and human understandable answers.\n", + "The information part contains the provided information that you can use to construct an answer.\n", + "Make the answer sound as a response to the question. Do not mention that you based the result on the given information.\n", + "Information:\n", + "{{context}}\n", + "\n", + "Question:\n", + "{{{QUERY_KEY}}}\n", + "Helpful Answer:\"\"\"\n", + "qa_prompt = PromptTemplate(\n", + " input_variables=[\"context\", QUERY_KEY], template=qa_prompt_template\n", + ")\n", + "qa_prompt" + ] + }, + { + "cell_type": "markdown", + "id": "8c8e15d2-07ca-48a4-8ea0-654387f0311d", + "metadata": {}, + "source": [ + "## Create chain" + ] + }, + { + "cell_type": "markdown", + "id": "457c788b-7939-4348-be6b-fcda1815c821", + "metadata": {}, + "source": [ + "#### Adapt GraphCypherQAChain to accept custom input keys" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e5eeaa8-8bcf-45bd-8ebf-d9dd50d54634", + "metadata": {}, + "outputs": [], + "source": [ + "from llmlib.utils.chains.graph_cypher_qa_chain import GraphCypherQAChain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b4b3b5c-ba8a-40cd-85f1-8de2cf50c959", + "metadata": { + "editable": true, + "raw_mimetype": "", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "RESPONSE_KEY = 'response'\n", + "graph_qa_chain = GraphCypherQAChain.from_llm(\n", + " ChatOpenAI(temperature=0),\n", + " graph=graph,\n", + " verbose=True,\n", + " cypher_prompt=graph_qa_prompt_template,\n", + " qa_prompt=qa_prompt,\n", + " output_key=RESPONSE_KEY,\n", + " return_intermediate_steps=True\n", + ")\n", + "graph_qa_chain" + ] + }, + { + "cell_type": "markdown", + "id": "1b682554-65d3-454d-b029-1dde12cbb25a", + "metadata": {}, + "source": [ + "### Declare query examples" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "975185f8-ef84-4167-8493-de2ed929f263", + "metadata": {}, + "outputs": [], + "source": [ + "all_relation_type_str = \"|\".join(preselected_relationship_types)\n", + "max_search_depth = 5\n", + "examples=[\n", + " f\"\"\"\n", + " // Get shortest path between nodes\n", + " MATCH (a), (b)\n", + " WHERE a.eid in AND b.eid in \n", + " MATCH path=allShortestPaths((a)-[:{all_relation_type_str}*1..{max_search_depth}]-(b))\n", + " RETURN [e in apoc.path.elements(path) | coalesce(e.eid, type(e))] as path LIMIT 1;\n", + " \"\"\",\n", + " \"\"\"\n", + " // Get nodes information\n", + " UNWIND as eid\n", + " MATCH (node {{eid: eid}}\n", + " RETURN node;\n", + " \"\"\"\n", + "]\n", + "examples" + ] + }, + { + "cell_type": "markdown", + "id": "ee716f40-cb4a-4c24-8ccd-c428134b52a9", + "metadata": {}, + "source": [ + "### Declare run parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "068b52ac-bf35-44ab-a06a-e224a517018b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph_qa_chain_inputs = {\n", + " QUERY_KEY: query,\n", + " EID_MAPPING_KEY: eid_mapping,\n", + " EXAMPLES_KEY: examples\n", + "}\n", + "graph_qa_chain_inputs" + ] + }, + { + "cell_type": "markdown", + "id": "4706a36a-ee22-457f-9802-4ac160a70db8", + "metadata": {}, + "source": [ + "### Run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01645dd2-b34c-4e75-a84b-03b44966619a", + "metadata": {}, + "outputs": [], + "source": [ + "graph_qa_chain.run(graph_qa_chain_inputs)" + ] + }, + { + "cell_type": "markdown", + "id": "764e609b-dec4-4189-8d8e-0b3b313b9f4c", + "metadata": {}, + "source": [ + "### Combine chains" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0255bbee-99d9-4345-aa9b-28bb55d23a3c", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.chains import SequentialChain\n", + "chain = SequentialChain(\n", + " chains=[\n", + " core_terms_chain,\n", + " find_eids_chain,\n", + " graph_qa_chain\n", + " ],\n", + " input_variables=[QUERY_KEY, EXAMPLES_KEY],\n", + " output_variables=[RESPONSE_KEY],\n", + " verbose=True\n", + ")\n", + "chain" + ] + }, + { + "cell_type": "markdown", + "id": "32d92363-5fcb-4dfa-8b56-662335022013", + "metadata": {}, + "source": [ + "### Test" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3536688-2b27-4f13-8bc5-971f8582e1c8", + "metadata": {}, + "outputs": [], + "source": [ + "output = chain.run({\n", + " QUERY_KEY: query,\n", + " EXAMPLES_KEY: examples\n", + "})\n", + "output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "151c5471-219c-4a70-a58f-269ea8ef9515", + "metadata": {}, + "outputs": [], + "source": [ + "output = chain.run({\n", + " QUERY_KEY: \"What is the relationship between Zn2+ and glcD?\",\n", + " EXAMPLES_KEY: examples\n", + "})\n", + "output" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2441ff0-e32a-4fe0-9076-93d87a9a34bc", + "metadata": {}, + "outputs": [], + "source": [ + "output = chain.run({\n", + " QUERY_KEY: \"What is the relationship between INHBA and MTMR4?\",\n", + " EXAMPLES_KEY: examples\n", + "})\n", + "output" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/llm/develop/Using query retriever.ipynb b/llm/develop/Using query retriever.ipynb new file mode 100644 index 0000000000..e845192dfb --- /dev/null +++ b/llm/develop/Using query retriever.ipynb @@ -0,0 +1,606 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6fda1acd-9514-4db5-ba8e-68255beb4c51", + "metadata": {}, + "source": [ + "# Init" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "feb21004", + "metadata": { + "collapsed": false, + "is_executing": true, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "%load_ext autoreload" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "98bb8a3a-1acb-4fab-a8dd-c7671b684fab", + "metadata": { + "is_executing": true + }, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'app'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mapp\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m app\n\u001b[1;32m 2\u001b[0m context \u001b[38;5;241m=\u001b[39m app\u001b[38;5;241m.\u001b[39mapp_context()\n\u001b[1;32m 3\u001b[0m context\u001b[38;5;241m.\u001b[39mpush()\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'app'" + ] + } + ], + "source": [ + "from app import app\n", + "context = app.app_context()\n", + "context.push()" + ] + }, + { + "cell_type": "markdown", + "id": "77a6dda5-ebc3-4d0a-8c22-62295460d871", + "metadata": {}, + "source": [ + "## Imports" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fbb6602c", + "metadata": { + "collapsed": false, + "is_executing": true, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "from develop.utils import formatters" + ] + }, + { + "cell_type": "markdown", + "id": "bd918ef6-ec05-420f-8dc4-3a84e50de805", + "metadata": {}, + "source": [ + "## Inputs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0ad8eda-d372-4002-b609-42899582eb2a", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "query=\"What is the relationship between Zn2+ and glycolate?\"" + ] + }, + { + "cell_type": "markdown", + "id": "877af485-bd94-4352-a511-d25d3e561b87", + "metadata": {}, + "source": [ + "## Initial check\n", + "\n", + "Current response:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2f791641-1009-4fb6-b1ea-26521b8dddd2", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "import openai\n", + "response = openai.ChatCompletion.create(\n", + " messages=[\n", + " { \"role\": \"user\", \"content\": query }\n", + " ],\n", + " model=\"gpt-3.5-turbo\",\n", + " temperature=0\n", + ")\n", + "response" + ] + }, + { + "cell_type": "markdown", + "id": "2c0298d0-b147-4971-9606-d871307ebe56", + "metadata": {}, + "source": [ + "# Compose chain" + ] + }, + { + "cell_type": "markdown", + "id": "9ac517bb-5e7c-4562-9e49-25dbd2658122", + "metadata": {}, + "source": [ + "## Init llm model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a7c93291-a342-485f-950e-97d12e528bfc", + "metadata": { + "editable": true, + "is_executing": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain.chat_models import ChatOpenAI\n", + "llm = ChatOpenAI(temperature=0, verbose=True)\n", + "llm" + ] + }, + { + "cell_type": "markdown", + "id": "b3d667ea-96aa-48e6-8d36-4da4e6157069", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Pepare prompts for core term extraction" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa15f752-9d1f-4f29-9b56-14d4e6224dcf", + "metadata": { + "editable": true, + "is_executing": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from langchain.prompts import PromptTemplate\n", + "from langchain.prompts.chat import (\n", + " ChatPromptTemplate,\n", + " SystemMessagePromptTemplate,\n", + " HumanMessagePromptTemplate,\n", + ")\n", + "QUERY_KEY = 'query'\n", + "\n", + "core_terms_prompt_template = ChatPromptTemplate.from_messages([\n", + " SystemMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=\"Always response with comma separated list of chemical or biological terms identified in prompt.\",\n", + " input_variables=[]\n", + " )\n", + " ),\n", + " HumanMessagePromptTemplate(\n", + " prompt=PromptTemplate(\n", + " template=f\"{{{QUERY_KEY}}}\",\n", + " input_variables=[QUERY_KEY],\n", + " )\n", + " )\n", + "])\n", + "core_terms_prompt_template" + ] + }, + { + "cell_type": "markdown", + "id": "27fbf490-99f0-431e-ac65-7c3870ed3ce3", + "metadata": {}, + "source": [ + "## Define embedding model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26df7344-3bd5-41c4-9522-0ef5270a20c6", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from langchain.embeddings import OpenAIEmbeddings\n", + "embeddings = OpenAIEmbeddings()\n", + "embeddings" + ] + }, + { + "cell_type": "markdown", + "id": "a09da740-e364-487f-899a-ea83c6dd448b", + "metadata": {}, + "source": [ + "## Define vectorstore" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d9301443-d21d-463e-bf69-a0a83fb633bb", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from langchain.vectorstores import Chroma" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2a5b1d9-1f22-4afb-8886-2914f24abd4c", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "# Vectorstore\n", + "vectorstore = Chroma(embedding_function=embeddings, persist_directory=\"./chroma_db_oai\")\n", + "vectorstore" + ] + }, + { + "cell_type": "markdown", + "id": "546e6ec9-4de6-4931-a1b2-690701c752bb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Get graph reference" + ] + }, + { + "cell_type": "markdown", + "id": "9649640e-0d07-4978-8840-2229c3cee419", + "metadata": {}, + "source": [ + "### Define neo4j connector" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4a43b53-a0df-4c5c-adf4-18a7e60d32e3", + "metadata": { + "editable": true, + "is_executing": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from llmlib.database import Neo4j" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2bf3d50-25b5-42fd-88ae-4d6fe3aec03e", + "metadata": { + "editable": true, + "is_executing": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "graph = Neo4j().graph()\n", + "graph.schema = '' # Overwrite schema to avoid it to be loaded from db (lengthy process not ussed in here)\n", + "graph" + ] + }, + { + "cell_type": "markdown", + "id": "55ba2794-7262-4008-977d-141a26b00ef9", + "metadata": {}, + "source": [ + "#### Init graph search API wrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07435c6b-cf54-492d-95e0-692e23a88768", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from llmlib.utils.search.cypher_search_api_wrapper import CypherSearchAPIWrapper" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a80ffecb-7d05-4ac6-b4c8-607eeecfaa3d", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "search = CypherSearchAPIWrapper(\n", + " graph=graph,\n", + " verbose=True,\n", + " return_intermediate_steps=True\n", + ")\n", + "search" + ] + }, + { + "cell_type": "markdown", + "id": "40d4403a-d125-4074-9cac-6ea152e3004f", + "metadata": {}, + "source": [ + "## Compose QA chain with graph retriever" + ] + }, + { + "cell_type": "markdown", + "id": "4653c28a-f701-4c7a-abae-0ac19f7ba79c", + "metadata": {}, + "source": [ + "### Init graph retriever" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12c53834-4d0f-488c-8609-6d6ab76f11e0", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from llmlib.utils.retrievers.graph_search_retriever import GraphSearchRetriever" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a0d27a79-56ec-4203-bae3-23a0767fc0c6", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "retriever = GraphSearchRetriever.from_llm(\n", + " vectorstore=vectorstore,\n", + " llm=llm,\n", + " graph_search=search,\n", + " prompt=core_terms_prompt_template,\n", + " verbose=True,\n", + " return_intermediate_steps=True\n", + ")\n", + "retriever" + ] + }, + { + "cell_type": "markdown", + "id": "ea067678-3976-4e77-beef-3fbb67a51d37", + "metadata": {}, + "source": [ + "### Define callback handler" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fa0358c-5636-46cc-a596-46feb7a56fb0", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.callbacks.stdout import StdOutCallbackHandler\n", + "handler = StdOutCallbackHandler()\n", + "handler" + ] + }, + { + "cell_type": "markdown", + "id": "fb42705c-7ee1-4020-9808-c02fd7a909bf", + "metadata": {}, + "source": [ + "### Init QA chain" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "301da357-d958-4915-92b7-643dc33e0d55", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from langchain.chains import RetrievalQA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6c9335f-c2dd-458d-bbf8-6d1de5c59d10", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa = RetrievalQA.from_chain_type(\n", + " llm=llm,\n", + " chain_type=\"stuff\",\n", + " retriever=retriever,\n", + " verbose=True,\n", + " callbacks=[handler]\n", + ")\n", + "qa" + ] + }, + { + "cell_type": "markdown", + "id": "9ba40ea3-5937-460c-a6f1-8ee83b3357d4", + "metadata": {}, + "source": [ + "# Test" + ] + }, + { + "cell_type": "markdown", + "id": "99bd213f-349c-4966-9259-c6714bcc9c94", + "metadata": {}, + "source": [ + "## Initial query" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "275c8dc5-980e-4adf-8973-561c10914c0b", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa.run(query, callbacks=[handler])" + ] + }, + { + "cell_type": "markdown", + "id": "7b2c4008-081b-44cf-b71b-4b26e75f43d5", + "metadata": {}, + "source": [ + "## Check background noise" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2441ff0-e32a-4fe0-9076-93d87a9a34bc", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa.run(\"What is the relationship between INHBA and MTMR4?\", callbacks=[handler])" + ] + }, + { + "cell_type": "markdown", + "id": "1909e2f9-de55-46b9-a13c-8e911366f954", + "metadata": {}, + "source": [ + "## Check different qa stuffing techniques" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9676eb1f-ca4f-4df3-a0f5-9490e3451196", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "from langchain.chains import RetrievalQA" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a52e9184-4868-4bfc-ba3f-f3d3d3c02246", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa = RetrievalQA.from_chain_type(\n", + " llm=llm,\n", + " chain_type=\"map_reduce\",\n", + " retriever=retriever,\n", + " verbose=True,\n", + " callbacks=[handler]\n", + ")\n", + "qa" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47f68be0-571b-4425-abde-d945aa647612", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa.run(query, callbacks=[handler])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e81092f0-ca74-4c22-9d57-a296beeed009", + "metadata": { + "is_executing": true + }, + "outputs": [], + "source": [ + "qa.run(\"What is the relationship between INHBA and MTMR4?\", callbacks=[handler])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/llm/develop/__init__.py b/llm/develop/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/llm/develop/utils/__init__.py b/llm/develop/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/llm/develop/utils/callback_manager.py b/llm/develop/utils/callback_manager.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/llm/develop/utils/formatters/__init__.py b/llm/develop/utils/formatters/__init__.py new file mode 100644 index 0000000000..1b18c0bb2e --- /dev/null +++ b/llm/develop/utils/formatters/__init__.py @@ -0,0 +1,12 @@ +from IPython import get_ipython +from .html import html_formatters + + +def register_formatters(type_: str, formatters: dict): + ipython_formatters = get_ipython().display_formatter.formatters + ipython_html_formatter = ipython_formatters[type_] + for cls, formatter in formatters.items(): + ipython_html_formatter.for_type(cls, formatter) + + +register_formatters('text/html', html_formatters) diff --git a/llm/develop/utils/formatters/html.py b/llm/develop/utils/formatters/html.py new file mode 100644 index 0000000000..9d321c982a --- /dev/null +++ b/llm/develop/utils/formatters/html.py @@ -0,0 +1,98 @@ +import string + +from IPython import display +from jinja2 import Environment, PackageLoader +from langchain import PromptTemplate, LLMChain +from langchain.chains import SimpleSequentialChain, SequentialChain + +from langchain.chat_models import ChatOpenAI +from langchain.embeddings import OpenAIEmbeddings +from langchain.graphs import Neo4jGraph +from langchain.prompts import ChatPromptTemplate +from langchain.prompts.chat import BaseStringMessagePromptTemplate +from llmlib.utils.search.cypher_search_api_wrapper import CypherSearchAPIWrapper +from openai.openai_object import OpenAIObject + +from llmlib.utils.chains.graph_query import GraphQueryChain + +from llmlib.utils.chains.graph_cypher_qa_chain import GraphCypherQAChain +from pydantic.v1 import BaseModel + +from .utils import format_object_factory, register_filter + +_html_env = Environment( + loader=PackageLoader('develop.utils.formatters', 'html_templates'), + lstrip_blocks=True, + trim_blocks=True, +) + +# noinspection PyProtectedMember +register_filter( + _html_env, + lambda *args, **kwargs: display.Code(*args, **kwargs)._repr_html_(), + 'code', +) +register_filter( + _html_env, + lambda t, *args, **kwargs: string.Template(t).safe_substitute(*args, **kwargs), + 'template', +) + + +def pydantic_model_formatter(model: BaseModel) -> str: + kwargs_exclude_defaults = model.dict(exclude_defaults=True) + return _html_env.get_template('pydantic_model.html.jinja2').render( + model=model, + not_default_keys=tuple(kwargs_exclude_defaults.keys()), + ) + + +html_formatters = { + ChatPromptTemplate: lambda pt: _html_env.get_template( + 'chat_prompt_template.html.jinja2' + ).render(pt=pt), + BaseStringMessagePromptTemplate: lambda pt: _html_env.get_template( + 'base_string_message_prompt_template.html.jinja2' + ).render(pt=pt), + PromptTemplate: lambda pt: _html_env.get_template( + 'prompt_template.html.jinja2' + ).render(pt=pt), + LLMChain: lambda chain: _html_env.get_template('llm_chain.html.jinja2').render( + chain=chain + ), + SimpleSequentialChain: lambda chain: _html_env.get_template( + 'sequential_chain.html.jinja2' + ).render(chain=chain), + SequentialChain: lambda chain: _html_env.get_template( + 'sequential_chain.html.jinja2' + ).render(chain=chain), + list: lambda l: _html_env.get_template('list.html.jinja2').render(l=l), + dict: lambda obj: _html_env.get_template('dict.html.jinja2').render(obj=obj), + str: lambda s: _html_env.get_template('str.html.jinja2').render(s=s), + GraphQueryChain: lambda chain: _html_env.get_template( + 'graph_query_chain.html.jinja2' + ).render(chain=chain), + GraphCypherQAChain: lambda chain: _html_env.get_template( + 'graph_cypher_qa_chain.html.jinja2' + ).render(chain=chain), + Neo4jGraph: lambda graph: _html_env.get_template('neo4j_graph.html.jinja2').render( + graph=graph + ), + OpenAIObject: lambda obj: _html_env.get_template( + 'openai_object.html.jinja2' + ).render(obj=obj), + ChatOpenAI: lambda obj: _html_env.get_template('openai_chat.html.jinja2').render( + obj=obj + ), + OpenAIEmbeddings: lambda obj: _html_env.get_template( + 'openai_embeddings.html.jinja2' + ).render(obj=obj), + BaseModel: pydantic_model_formatter, + CypherSearchAPIWrapper: lambda obj: _html_env.get_template( + 'cypher_search_api_wrapper.html.jinja2' + ).render(obj=obj), +} + +register_filter( + _html_env, format_object_factory(html_formatters, _html_env.filters['escape']) +) diff --git a/llm/develop/utils/formatters/html_templates/base_string_message_prompt_template.html.jinja2 b/llm/develop/utils/formatters/html_templates/base_string_message_prompt_template.html.jinja2 new file mode 100644 index 0000000000..e1f06102c5 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/base_string_message_prompt_template.html.jinja2 @@ -0,0 +1,6 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(pt, ('prompt',), 'prompt') %} +
+ {{ pt.prompt|format_object }} +
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/chat_prompt_template.html.jinja2 b/llm/develop/utils/formatters/html_templates/chat_prompt_template.html.jinja2 new file mode 100644 index 0000000000..164abfed35 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/chat_prompt_template.html.jinja2 @@ -0,0 +1,12 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(pt, ('messages',), 'messages') %} +
+
    + {% for message in pt.messages %} +
  • + {{ message|format_object }} +
  • + {% endfor %} +
+
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/cypher_search_api_wrapper.html.jinja2 b/llm/develop/utils/formatters/html_templates/cypher_search_api_wrapper.html.jinja2 new file mode 100644 index 0000000000..74d70827cb --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/cypher_search_api_wrapper.html.jinja2 @@ -0,0 +1,7 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(obj) %} +
related nodes query
+
{{ obj.related_nodes_query|template(obj.related_nodes_query_params)|code(language='cypher') }}
+
relationships query
+
{{ obj.relationships_query|template(obj.relationships_query_params)|code(language='cypher') }}
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/dict.html.jinja2 b/llm/develop/utils/formatters/html_templates/dict.html.jinja2 new file mode 100644 index 0000000000..a5ec52d0b6 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/dict.html.jinja2 @@ -0,0 +1,12 @@ +{% if obj %} +
+ {% for key, value in obj|items %} + {% if key not in omit %} +
{{ key|replace('_',' ') }}
+
{{ value|format_object }} 
+ {% endif %} + {% endfor %} +
+{% else %} +{{ obj }} +{% endif %} diff --git a/llm/develop/utils/formatters/html_templates/graph_cypher_qa_chain.html.jinja2 b/llm/develop/utils/formatters/html_templates/graph_cypher_qa_chain.html.jinja2 new file mode 100644 index 0000000000..b9ab19651f --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/graph_cypher_qa_chain.html.jinja2 @@ -0,0 +1,9 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(pt, ('cypher_generation_chain', 'qa_chain', 'graph')) %} +
graph
+
{{ chain.graph|format_object }}
+
cypher generation chain
+
{{ chain.cypher_generation_chain|format_object }}
+
qa chain
+
{{ chain.qa_chain|format_object }}
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/graph_query_chain.html.jinja2 b/llm/develop/utils/formatters/html_templates/graph_query_chain.html.jinja2 new file mode 100644 index 0000000000..c19e4bd76d --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/graph_query_chain.html.jinja2 @@ -0,0 +1,4 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(pt, ('query'), 'query') %} +
{{ chain.query|code }}
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/list.html.jinja2 b/llm/develop/utils/formatters/html_templates/list.html.jinja2 new file mode 100644 index 0000000000..79518b6d67 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/list.html.jinja2 @@ -0,0 +1,9 @@ +{% if l %} +
    + {% for value in l %} +
  • {{ value|format_object }}
  • + {% endfor %} +
+{% else %} + [] +{% endif %} diff --git a/llm/develop/utils/formatters/html_templates/llm_chain.html.jinja2 b/llm/develop/utils/formatters/html_templates/llm_chain.html.jinja2 new file mode 100644 index 0000000000..5f20a265b1 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/llm_chain.html.jinja2 @@ -0,0 +1,7 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(chain, ('llm', 'prompt')) %} +
llm
+
{{ chain.llm|format_object }} 
+
prompt
+
{{ chain.prompt|format_object }} 
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/macros/collapsed_object_dict_dl.html.jinja2 b/llm/develop/utils/formatters/html_templates/macros/collapsed_object_dict_dl.html.jinja2 new file mode 100644 index 0000000000..521d24e179 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/macros/collapsed_object_dict_dl.html.jinja2 @@ -0,0 +1,18 @@ +{% macro collapsed_object_dict_dl(obj, omit={}, dangling=None, details='') %} +
+
+ {{ obj.__class__.__name__ }} + {% for key, value in dict(obj)|items %} + {% if key not in omit %} +
{{ key|replace('_',' ')|escape }}
+
{{ value|format_object }}
+ {% endif %} + {% endfor %} + {{ details }} + {% if dangling %} +
{{ dangling }}
+ {% endif %} +
+ {{ caller() }} {# content projection #} +
+{% endmacro %} diff --git a/llm/develop/utils/formatters/html_templates/neo4j_graph.html.jinja2 b/llm/develop/utils/formatters/html_templates/neo4j_graph.html.jinja2 new file mode 100644 index 0000000000..1cb0875600 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/neo4j_graph.html.jinja2 @@ -0,0 +1,7 @@ +
+ Neo4jGraph +
+
graph
+
{{ graph.schema|format_object }}
+
+
diff --git a/llm/develop/utils/formatters/html_templates/openai_chat.html.jinja2 b/llm/develop/utils/formatters/html_templates/openai_chat.html.jinja2 new file mode 100644 index 0000000000..40a43acf32 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/openai_chat.html.jinja2 @@ -0,0 +1,7 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(obj, ('model_name', 'client', 'openai_api_key')) %} +
client
+
{{ obj.client|escape }} 
+
model name
+
{{ obj.model_name|escape }} 
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/openai_embeddings.html.jinja2 b/llm/develop/utils/formatters/html_templates/openai_embeddings.html.jinja2 new file mode 100644 index 0000000000..d0e4257171 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/openai_embeddings.html.jinja2 @@ -0,0 +1,7 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(obj, ('model', 'client', 'openai_api_key')) %} +
client
+
{{ obj.client|escape }} 
+
model name
+
{{ obj.model|escape }} 
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/openai_object.html.jinja2 b/llm/develop/utils/formatters/html_templates/openai_object.html.jinja2 new file mode 100644 index 0000000000..2c907e1632 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/openai_object.html.jinja2 @@ -0,0 +1,26 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% set usage %} +
usage
+
+
+
prompt
+
{{ obj.usage.prompt_tokens|escape }} tokens
+
completion
+
{{ obj.usage.completion_tokens|escape }} tokens
+
total
+
{{ obj.usage.total_tokens|escape }} tokens
+
+
+{% endset %} +{% call collapsed_object_dict_dl(obj, ('usage', 'choices'), 'choices', usage) %} +
+
+ {% for choice in obj.choices %} +
+ {{ choice.message.role }} +
+
{{ choice.message.content|escape }}
+ {% endfor %} +
+
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/prompt_template.html.jinja2 b/llm/develop/utils/formatters/html_templates/prompt_template.html.jinja2 new file mode 100644 index 0000000000..0b38a13772 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/prompt_template.html.jinja2 @@ -0,0 +1,4 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(pt, ('template',), 'template') %} +
{{ pt.template|escape }} 
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/pydantic_model.html.jinja2 b/llm/develop/utils/formatters/html_templates/pydantic_model.html.jinja2 new file mode 100644 index 0000000000..7e0091f347 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/pydantic_model.html.jinja2 @@ -0,0 +1,9 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(model, not_default_keys) %} + {% for key, value in dict(model)|items %} + {% if key in not_default_keys %} +
{{ key|replace('_',' ') }}
+
{{ value|format_object }}
+ {% endif %} + {% endfor %} +{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/sequential_chain.html.jinja2 b/llm/develop/utils/formatters/html_templates/sequential_chain.html.jinja2 new file mode 100644 index 0000000000..b44fe5c01c --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/sequential_chain.html.jinja2 @@ -0,0 +1,12 @@ +{% from 'macros/collapsed_object_dict_dl.html.jinja2' import collapsed_object_dict_dl %} +{% call collapsed_object_dict_dl(chain, ('chains',), 'chains') %} +
+
    + {% for c in chain.chains %} +
  1. + {{ c|format_object }} +
  2. + {% endfor %} +
+
+{% endcall %} diff --git a/llm/develop/utils/formatters/html_templates/str.html.jinja2 b/llm/develop/utils/formatters/html_templates/str.html.jinja2 new file mode 100644 index 0000000000..2cd58fa588 --- /dev/null +++ b/llm/develop/utils/formatters/html_templates/str.html.jinja2 @@ -0,0 +1,7 @@ +
+    {%- if s -%}
+        {{ s|escape }}
+    {%- else -%}
+        ''
+    {%- endif -%}
+
diff --git a/llm/develop/utils/formatters/utils.py b/llm/develop/utils/formatters/utils.py new file mode 100644 index 0000000000..f8ac291b9d --- /dev/null +++ b/llm/develop/utils/formatters/utils.py @@ -0,0 +1,33 @@ +from typing import Dict, Callable, Any +from jinja2 import Environment + + +def format_object_factory( + _formatters: Dict[type, Callable[[Any], str]], escape: Callable[[str], str] +): + def format_object(obj: Any) -> str: + """Format an object. + + Args: + obj: object to format + + Returns: + str + """ + if type(obj) in _formatters: + return _formatters[type(obj)](obj) + for _formatter in _formatters: + if isinstance(obj, _formatter): + return _formatters[_formatter](obj) + if hasattr(obj, '_repr_html_'): + # noinspection PyProtectedMember + return obj._repr_html_() + return escape(repr(obj)) + + return format_object + + +def register_filter( + env: Environment, filter_: Callable[[Any], Any], filter_name: str = None +): + env.filters[filter_name if filter_name else filter_.__name__] = filter_ diff --git a/llm/llmlib/__init__.py b/llm/llmlib/__init__.py new file mode 100644 index 0000000000..6b274abdd1 --- /dev/null +++ b/llm/llmlib/__init__.py @@ -0,0 +1 @@ +from .views import * diff --git a/llm/llmlib/app.py b/llm/llmlib/app.py new file mode 100644 index 0000000000..c2815db7ae --- /dev/null +++ b/llm/llmlib/app.py @@ -0,0 +1,3 @@ +from .factory import create_app + +app = create_app() diff --git a/llm/llmlib/config.py b/llm/llmlib/config.py new file mode 100644 index 0000000000..c6569f3302 --- /dev/null +++ b/llm/llmlib/config.py @@ -0,0 +1,55 @@ +import os + + +class Base: + """Default values""" + + JWKS_URL = os.environ.get('JWKS_URL', None) + JWT_SECRET = os.environ.get('JWT_SECRET', 'secrets') + JWT_AUDIENCE = os.environ.get('JWT_AUDIENCE', None) + JWT_ALGORITHM = os.environ.get('JWT_ALGORITHM', 'HS256') + + POSTGRES_HOST = os.environ.get('POSTGRES_HOST') + POSTGRES_PORT = os.environ.get('POSTGRES_PORT') + POSTGRES_USER = os.environ.get('POSTGRES_USER') + POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD') + POSTGRES_DB = os.environ.get('POSTGRES_DB') + + SQLALCHEMY_DATABASE_URI = 'postgresql://%s:%s@%s:%s/%s' % ( + POSTGRES_USER, + POSTGRES_PASSWORD, + POSTGRES_HOST, + POSTGRES_PORT, + POSTGRES_DB, + ) + + NEO4J_HOST = os.environ.get('NEO4J_HOST', '0.0.0.0') + NEO4J_SCHEME = os.environ.get('NEO4J_SCHEME', 'bolt') + NEO4J_AUTH = os.environ.get('NEO4J_AUTH', 'neo4j/password') + NEO4J_PORT = os.environ.get('NEO4J_PORT', '7687') + NEO4J_DATABASE = os.environ.get('NEO4J_DATABASE') + + ARANGO_HOST = os.environ.get('ARANGO_HOST', 'http://localhost:8529') + ARANGO_USERNAME = os.environ.get('ARANGO_USERNAME', '***ARANGO_USERNAME***') + ARANGO_PASSWORD = os.environ.get('ARANGO_PASSWORD', 'password') + ARANGO_DB_NAME = os.environ.get('ARANGO_DB_NAME', '***ARANGO_DB_NAME***') + + OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY') + + REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost') + REDIS_PORT = port = os.environ.get('REDIS_PORT', '6379') + REDIS_PASSWORD = os.environ.get('REDIS_PASSWORD', '') + REDIS_SSL = os.environ.get('REDIS_SSL', 'false').lower() == 'true' + CACHE_REDIS_DB = os.environ.get('CACHE_REDIS_DB', '0') + CACHE_REDIS_URL = '{protocol}://:{password}@{host}:{port}/{db}'.format( + protocol='rediss' if REDIS_SSL else 'redis', + host=REDIS_HOST, + port=REDIS_PORT, + password=REDIS_PASSWORD, + db=CACHE_REDIS_DB, + ) + + # Optional for tracking the master branch for the build + GITHUB_HASH = os.environ.get('GITHUB_HASH', '__VERSION__') + + FORWARD_STACKTRACE = False diff --git a/llm/llmlib/database.py b/llm/llmlib/database.py new file mode 100644 index 0000000000..edcff57604 --- /dev/null +++ b/llm/llmlib/database.py @@ -0,0 +1,75 @@ +from abc import ABC +from functools import lru_cache + +from llmlib.interfaces import Graph +from llmlib.utils.config import config + +from llmlib.utils.singleton import Singleton + + +class Neo4j(Graph, metaclass=Singleton): + @lru_cache(maxsize=1) + def graph(self, name: str = None): + from llmlib.utils.lazy_neo4j_graph import LazyNeo4jGraph + + host = config.get('NEO4J_HOST') + scheme = config.get('NEO4J_SCHEME') + port = config.get('NEO4J_PORT') + url = f'{scheme}://{host}:{port}' + username, password = config.get('NEO4J_AUTH', 'neo4j/password').split('/') + return LazyNeo4jGraph( + url=url, + username=username, + password=password, + database=name or config.get('NEO4J_DATABASE', 'neo4j'), + ) + + +class Arango(Graph, metaclass=Singleton): + _client = None + + @property + def client(self): + if self._client is None: + from arango import ArangoClient + + self._client = ArangoClient(hosts=config.get('ARANGO_HOST')) + return self._client + + @lru_cache(maxsize=1) + def db(self, name: str = None): + return self.client.db( + name=name or config.get('ARANGO_DB_NAME', '_system'), + username=config.get('ARANGO_USERNAME', '***ARANGO_USERNAME***'), + password=config.get('ARANGO_PASSWORD', 'password'), + ) + + @lru_cache(maxsize=1) + def graph(self, name: str = None): + from langchain.graphs import ArangoGraph + + return ArangoGraph(self.db(name)) + + def __del__(self): + if self._client is not None: + self._client.close() + + +class RedisCache(ABC): + _client = None + + @classmethod + def client(cls): + if cls._client is None: + from redis import Redis, BlockingConnectionPool + + cls._client = Redis( + connection_pool=BlockingConnectionPool.from_url( + config.get('CACHE_REDIS_URL') + ) + ) + return cls._client + + def __del__(self): + if self._client is not None: + self._client.close() diff --git a/llm/llmlib/exceptions/exceptions.py b/llm/llmlib/exceptions/exceptions.py new file mode 100644 index 0000000000..3cd8a4d336 --- /dev/null +++ b/llm/llmlib/exceptions/exceptions.py @@ -0,0 +1,155 @@ +from abc import ABC +from dataclasses import dataclass, field, asdict +from http import HTTPStatus +from typing import Tuple, Optional, Callable, Any + +import yaml +from openai import OpenAIError + +from ..utils.transaction_id import transaction_id +from ..utils.dataclass import CauseDefaultingDescriptor, LazyDefaulDescriptor +from ..utils.string import compose_lines, indent_lines + + +@dataclass(repr=False, eq=False, frozen=True) +class BaseServerException(ABC): + title: str + message: Optional[str] = None + additional_msgs: Tuple[str, ...] = tuple() + fields: Optional[dict] = None + stacktrace: Optional[str] = None + version: Optional[str] = None + + def __new__(cls, *args, **kwargs): + if cls == BaseServerException or BaseServerException in cls.__bases__: + raise TypeError("Cannot instantiate abstract class.") + return super().__new__(cls) + + @property + def transaction_id(self): + return transaction_id + + @property + def type(self): + return type(self).__name__ + + def to_dict(self): + return asdict(self) + + def __repr__(self): + return f'<{self.type} {self.transaction_id}> {self.title}:{self.message}' + + def __str__(self): + return compose_lines( + self.__repr__(), + *indent_lines( + # Additional msgs wrapped with new lines, or just singular newline + *( + ('', *self.additional_msgs, '') + if len(self.additional_msgs) + else ('',) + ), + *yaml.dump( + { + k: v + for k, v in self.to_dict().items() + if v + and k + not in ( + # Already printed above + 'type', + 'transaction_id', + 'title', + 'message', + 'additional_msgs', + ) + } + ).splitlines(), + ), + ) + + +@dataclass(repr=False, eq=False, frozen=True) +class ServerException(Exception, BaseServerException): + """ + Create a new exception. + :param title: the title of the error, which sometimes used on the client + :param message: a message that can be displayed to the user + :param additional_msgs: a list of messages that contain more details for the user + :param code: the error code + :param fields: + """ + + title: str = field(default=CauseDefaultingDescriptor("We're sorry!")) # type: ignore + message: Optional[str] = field( # type: ignore + default=CauseDefaultingDescriptor("Looks like something went wrong!") + ) + additional_msgs: Tuple[str, ...] = field( + default=CauseDefaultingDescriptor(tuple()) # type: ignore + ) + fields: Optional[dict] = field(default=CauseDefaultingDescriptor(None)) # type: ignore + code: HTTPStatus = field( # type: ignore + default=CauseDefaultingDescriptor(HTTPStatus.INTERNAL_SERVER_ERROR) + ) + + @property + def type(self): + return type(self).__name__ + + @property + def transaction_id(self): + return transaction_id + + def __repr__(self): + return f'<{self.type} {self.transaction_id}>\t{self.title}:\t{self.message}' + + def __str__(self): + lines = [self.__repr__()] + try: + lines += [f'\t{key}:\t{value}' for key, value in self.fields.items()] + except Exception: + pass + return '\n'.join(lines) + + def to_dict(self): + return asdict(self) + + +@dataclass(repr=False, eq=False, frozen=True) +class JWTTokenException(ServerException): + """Signals JWT token issue""" + + code: HTTPStatus = HTTPStatus.UNAUTHORIZED + + +@dataclass(repr=False, eq=False, frozen=True) +class JWTAuthTokenException(JWTTokenException): + """Signals the JWT auth token has an issue""" + + pass + + +def openai_cause_accessor(prop: str, default) -> Callable[[Any, str], Any]: + def _accessor(obj, _): + if isinstance(obj.__cause__, OpenAIError): + value = getattr(obj.__cause__, prop) + if value: + return value + return default + + return _accessor + + +@dataclass(repr=False, eq=False, frozen=True) +class OpenAiServerException(ServerException): + title: str = 'OpenAI Server Error' + message: str = field( # type: ignore + default=LazyDefaulDescriptor( + openai_cause_accessor('user_message', "OpenAI Server Error") + ) + ) + code: HTTPStatus = field( # type: ignore + default=LazyDefaulDescriptor( + openai_cause_accessor('http_status', HTTPStatus.INTERNAL_SERVER_ERROR) + ) + ) diff --git a/llm/llmlib/exceptions/wrap_exceptions.py b/llm/llmlib/exceptions/wrap_exceptions.py new file mode 100644 index 0000000000..5f5233bd9a --- /dev/null +++ b/llm/llmlib/exceptions/wrap_exceptions.py @@ -0,0 +1,38 @@ +import functools +from typing import Tuple, Union, Type, Protocol +from .exceptions import ServerException + + +class WrappingExceptionFactory(Protocol): + def __call__(self, exception: Exception, **kwargs) -> Exception: + ... + + +def wrap_exceptions( + wrapping_exception: Union[Type[Exception], WrappingExceptionFactory], + wrapped_exceptions: Union[ + Type[Exception], Tuple[Type[Exception], ...] + ] = ServerException, + **exception_kwargs +): + """Decorator that reraises wrapping exception in case given exception occurs""" + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except wrapped_exceptions as e: + if isinstance(wrapping_exception, type): + # noinspection PyArgumentList + raise wrapping_exception(**exception_kwargs) from e + else: + raise wrapping_exception(e, **exception_kwargs) from e + + wrapper.__wrapped__ = func + return wrapper + + return decorator + + +__all__ = ["wrap_exceptions"] diff --git a/llm/llmlib/factory.py b/llm/llmlib/factory.py new file mode 100644 index 0000000000..a7224835e1 --- /dev/null +++ b/llm/llmlib/factory.py @@ -0,0 +1,22 @@ +from flask import Flask, jsonify +import os + +from openai import OpenAIError + +from .schemas.error import OpenAiErrorResponseSchema +from .services.chat_gpt import ChatGPT +from .config import Base + + +def handle_openai_error(ex): + return jsonify(OpenAiErrorResponseSchema().dump(ex)), ex.code + + +def create_app(): + app_name = os.environ.get('FLASK_APP', __name__) + app = Flask(app_name) + app.config.from_object(Base) + app.register_error_handler(OpenAIError, handle_openai_error) + ChatGPT.init_app(app) + + return app diff --git a/llm/llmlib/interfaces.py b/llm/llmlib/interfaces.py new file mode 100644 index 0000000000..868bb9e6d2 --- /dev/null +++ b/llm/llmlib/interfaces.py @@ -0,0 +1,13 @@ +from abc import ABC, abstractmethod, ABCMeta +from typing import TypedDict + + +class Graph(ABC): + @abstractmethod + def graph(self, name: str): + ... + + +class GraphRef(TypedDict): + database_type: str + database_name: str diff --git a/llm/llmlib/schemas/__init__.py b/llm/llmlib/schemas/__init__.py new file mode 100644 index 0000000000..f3f28d32ab --- /dev/null +++ b/llm/llmlib/schemas/__init__.py @@ -0,0 +1,42 @@ +from marshmallow import Schema +from marshmallow.fields import Str, Nested +from marshmallow.validate import OneOf + +from .error import OpenAiErrorResponseSchema +from .openai.chat_completions import ChatCompletionsRequestSchema +from .openai.completions import CompletionsRequestSchema + + +class ServerRequestSchema(Schema): + user = Str(required=True) + transaction_id = Str(required=True) + + +class DBRequestSchema(Schema): + database_type = Str(validate=OneOf(['arango', 'neo4j']), default='arango') + database_name = Str() + + +class GraphRequestSchema(ServerRequestSchema): + graph = Nested(DBRequestSchema()) + + +class GraphCompletionsRequestSchema(CompletionsRequestSchema, GraphRequestSchema): + pass + + +class GraphChatCompletionsRequestSchema( + ChatCompletionsRequestSchema, GraphRequestSchema +): + pass + + +class GraphQARequestSchema(GraphRequestSchema): + query = Str(required=True) + + +__all__ = [ + 'OpenAiErrorResponseSchema', + 'GraphCompletionsRequestSchema', + 'GraphChatCompletionsRequestSchema', +] diff --git a/llm/llmlib/schemas/error.py b/llm/llmlib/schemas/error.py new file mode 100644 index 0000000000..c6f003d430 --- /dev/null +++ b/llm/llmlib/schemas/error.py @@ -0,0 +1,30 @@ +import traceback + +from flask import current_app +from marshmallow import fields, Schema + +from llmlib.utils import transaction_id + + +class OpenAiErrorResponseSchema(Schema): + """All errors are emitted with this schema.""" + + title = "OpenAI Server Error" + type = fields.Function(lambda obj: type(obj).__name__) + message = fields.Function(lambda obj: obj.user_message) + code = fields.Function(lambda obj: obj.http_status) + transaction_id = fields.Function(lambda obj: transaction_id) + + stacktrace = fields.Method('get_stacktrace') + + # noinspection PyMethodMayBeStatic + def get_stacktrace(self, ex): + if current_app.config.get('FORWARD_STACKTRACE'): + return ''.join( + traceback.format_exception( + etype=type(ex), value=ex, tb=ex.__traceback__ + ) + ) + + +__all__ = ['OpenAiErrorResponseSchema'] diff --git a/llm/llmlib/schemas/fields.py b/llm/llmlib/schemas/fields.py new file mode 100644 index 0000000000..e734d35e09 --- /dev/null +++ b/llm/llmlib/schemas/fields.py @@ -0,0 +1,17 @@ +from typing import Iterable + +from marshmallow import fields, ValidationError + + +class UnionType(fields.Field): + def __init__(self, *args, types: Iterable[fields.Field], **kwargs): + super().__init__(*args, **kwargs) + self.types = types + + def _deserialize(self, value, attr, data, **kwargs): + for field_type in self.types: + try: + return field_type.deserialize(value) + except ValidationError: + pass + raise ValidationError('Value does not match any of the types!') diff --git a/llm/llmlib/schemas/openai/chat_completions.py b/llm/llmlib/schemas/openai/chat_completions.py new file mode 100644 index 0000000000..31365a021e --- /dev/null +++ b/llm/llmlib/schemas/openai/chat_completions.py @@ -0,0 +1,35 @@ +from marshmallow import fields, Schema, validate + +from ..fields import UnionType +from .completions_base import CompletionsBaseRequestSchema + + +class MessageSchema(Schema): + role = fields.String( + validate=fields.validate.OneOf(['system', 'user', 'assistant', 'function']), + required=True, + ) + content = fields.String(nullable=True, required=True) + name = fields.String() + function_call = fields.Dict() + + +class FunctionSchema(Schema): + name = fields.String(required=True) + description = fields.String() + parameters = fields.Dict(keys=fields.String(), values=fields.Raw(), required=True) + + +class ChatCompletionsRequestSchema(CompletionsBaseRequestSchema): + model = fields.String(required=True) + messages = fields.List(fields.Nested(MessageSchema()), required=True) + functions = fields.List(fields.Nested(FunctionSchema())) + function_call = UnionType( + types=( + fields.String(validate=validate.OneOf(('none', 'all'))), + fields.Dict( + keys=fields.String(), + values=fields.String(), + ), + ), + ) diff --git a/llm/llmlib/schemas/openai/completions.py b/llm/llmlib/schemas/openai/completions.py new file mode 100644 index 0000000000..f2a5c66d8e --- /dev/null +++ b/llm/llmlib/schemas/openai/completions.py @@ -0,0 +1,11 @@ +from marshmallow import fields + +from .completions_base import CompletionsBaseRequestSchema + + +class CompletionsRequestSchema(CompletionsBaseRequestSchema): + model = fields.String(required=True) + prompt = fields.String(required=True) + suffix = fields.String() + echo = fields.Boolean() + best_of = fields.Integer() diff --git a/llm/llmlib/schemas/openai/completions_base.py b/llm/llmlib/schemas/openai/completions_base.py new file mode 100644 index 0000000000..2760449eef --- /dev/null +++ b/llm/llmlib/schemas/openai/completions_base.py @@ -0,0 +1,21 @@ +from marshmallow import fields, validate, Schema + + +class CompletionsBaseRequestSchema(Schema): + timeout = fields.Float() + max_tokens = fields.Integer() + temperature = fields.Float(validate=validate.Range(min=0, max=2)) + top_p = fields.Float() + n = fields.Integer() + stream = fields.Boolean() + logprobs = fields.Integer(validate=validate.Range(min=0, max=5), allow_none=True) + stop = fields.List( + fields.String(required=True), validate=validate.Length(min=0, max=4) + ) + presence_penalty = fields.Float(validate=validate.Range(min=-2, max=2)) + frequency_penalty = fields.Float(validate=validate.Range(min=-2, max=2)) + logit_bias = fields.Dict( + keys=fields.String(), + values=fields.Float(validate=validate.Range(min=-100, max=100)), + ) + user = fields.String() diff --git a/llm/llmlib/services/chat_gpt.py b/llm/llmlib/services/chat_gpt.py new file mode 100644 index 0000000000..798f0f55c3 --- /dev/null +++ b/llm/llmlib/services/chat_gpt.py @@ -0,0 +1,104 @@ +import openai +from cachetools import Cache, cached +from openai import OpenAIError + +from ..exceptions.wrap_exceptions import wrap_exceptions +from ..exceptions.exceptions import OpenAiServerException, ServerException +from .redis_cache import RedisCache + + +class ChatGPT: + """Wrapper for OpenAI's Chat API""" + + DELIMITER = "```" # Used to escape user defined input + + @staticmethod + def escape(text: str): + return text.replace(ChatGPT.DELIMITER, f'[ignored]') + + class Completion(openai.Completion): + cache: Cache = RedisCache( + 'ChatGPT', 'Completion', ex=3600 * 24 * 7 # Cache for a week + ) + # Information which seems to be only avaliable in here: + # https://platform.openai.com/docs/models/model-endpoint-compatibility + _compatible_models = [ + "text-davinci-003", + "text-davinci-002", + "text-davinci-001", + "text-curie-001", + "text-babbage-001", + "text-ada-001", + "davinci", + "curie", + "babbage", + "ada", + ] + + @staticmethod + @cached(cache=cache) + def model_list(*args, **kwargs): + return [ + model + for model in ChatGPT.Model.list(*args, **kwargs) + if model.get('id') in ChatGPT.Completion._compatible_models + ] + + @staticmethod + @cached(cache=cache) + def create(*args, **kwargs): + return openai.Completion.create(*args, **kwargs) + + @staticmethod + def create_stream(*args, **kwargs): + return openai.Completion.create(*args, **kwargs) + + class ChatCompletion(openai.ChatCompletion): + cache: Cache = RedisCache( + 'ChatGPT', 'ChatCompletion', ex=3600 * 24 * 7 # Cache for a week + ) + # Information which seems to be only avaliable in here: + # https://platform.openai.com/docs/models/model-endpoint-compatibility + _compatible_models = [ + "gpt-4", + "gpt-4-0613", + "gpt-4-32k", + "gpt-4-32k-0613", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0613", + "gpt-3.5-turbo-16k", + "gpt-3.5-turbo-16k-0613", + ] + + @staticmethod + @cached(cache=cache) + def model_list(*args, **kwargs): + return [ + model + for model in ChatGPT.Model.list(*args, **kwargs) + if model.get('id') in ChatGPT.ChatCompletion._compatible_models + ] + + @staticmethod + @cached(cache=cache) + def create(*args, **kwargs): + return openai.ChatCompletion.create(*args, **kwargs) + + @staticmethod + def create_stream(*args, **kwargs): + return openai.ChatCompletion.create(*args, **kwargs) + + class Model(openai.Model): + cache: Cache = RedisCache('ChatGPT', 'Model', ex=3600 * 24) # Cache for a day + + @staticmethod + @cached(cache=cache) + def list(*args, **kwargs): + return openai.Model.list(*args, **kwargs)['data'] + + @staticmethod + def init_app(app): + openai.api_key = app.config.get("OPENAI_API_KEY") + + +__all__ = ["ChatGPT"] diff --git a/llm/llmlib/services/redis_cache.py b/llm/llmlib/services/redis_cache.py new file mode 100644 index 0000000000..a1bea1a7c2 --- /dev/null +++ b/llm/llmlib/services/redis_cache.py @@ -0,0 +1,86 @@ +""" Redis Cache """ +import json +from typing import TypeVar, Generic, Callable, Tuple, Optional + +import redis +from cachetools import Cache + +from ..utils.config import config + +DEFAULT_CACHE_SETTINGS = {'ex': 3600 * 24} + +_redis_server: Optional[redis.Redis] = None + + +def get_redis_cache_server(): + global _redis_server + if _redis_server is None: + _redis_server = redis.Redis( + connection_pool=redis.BlockingConnectionPool.from_url( + config.get('CACHE_REDIS_URL') + ) + ) + return _redis_server + + +Key = TypeVar('Key') +Value = TypeVar('Value') + + +class RedisCache(Generic[Key, Value], Cache): + _prefixes: Tuple[str, ...] + _prefix_separator: str = ':' + _dumps: Callable[[Value], str] + _loads: Callable[[str], Value] + _cache_setting = DEFAULT_CACHE_SETTINGS + + @property + def _redis(self) -> redis.Redis: + return get_redis_cache_server() + + def __init__( + self, + *prefixes: str, + dumps: Callable[[Value], str] = json.dumps, + loads: Callable[[str], Value] = json.loads, + maxsize=float('inf'), + getsizeof=None, + **cache_setting, + ): + super().__init__(maxsize, getsizeof) + self._prefixes = prefixes + self._dumps = dumps + self._loads = loads + self._cache_setting = {**DEFAULT_CACHE_SETTINGS, **cache_setting} + + def compose_key(self, key: Key) -> str: + return self._prefix_separator.join( + part for part in (*self._prefixes, str(key)) if part + ) + + def __getitem__(self, key: Key): + item = self._redis.get(self.compose_key(key)) + if item is None: + return self.__missing__(key) + return self._loads(item) + + def __setitem__(self, key, value): + self._redis.set( + self.compose_key(key), self._dumps(value), **self._cache_setting + ) + + def __delitem__(self, key): + self._redis.delete(self.compose_key(key)) + + def __contains__(self, key): + return self._redis.exists(self.compose_key(key)) + + def __iter__(self): + return self._redis.scan_iter() + + def __len__(self): + return self._redis.dbsize() + + @property + def currsize(self): + return len(self) diff --git a/llm/llmlib/utils/__init__.py b/llm/llmlib/utils/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/llm/llmlib/utils/callbacks/base.py b/llm/llmlib/utils/callbacks/base.py new file mode 100644 index 0000000000..bba0c75caf --- /dev/null +++ b/llm/llmlib/utils/callbacks/base.py @@ -0,0 +1,55 @@ +from abc import abstractmethod +from typing import Any, Type, List, Protocol, runtime_checkable + +from langchain.callbacks.base import BaseCallbackHandler +from langchain.callbacks.manager import CallbackManager + + +@runtime_checkable +class GraphRetrieverHandlerProtocol(Protocol): + @abstractmethod + def on_related_nodes(self, nodes) -> Any: + """Callback for related nodes load.""" + + @abstractmethod + def on_related_relationships(self, relationships) -> Any: + """Callback for related relationships load.""" + + +class GraphRetrieverManagerMixin: + nodes: Any + relationships: Any + + def on_related_nodes(self, nodes) -> Any: + """Callback for related nodes load.""" + self.nodes = nodes + + def on_related_relationships(self, relationships) -> Any: + """Callback for related relationships load.""" + self.relationships = relationships + + +class GraphCallbackManager: + handlers: List[BaseCallbackHandler] + + @classmethod + def from_callback_manager(cls, callback_manager: Type[CallbackManager], **kwargs) -> Any: + return type( + 'GraphCallbackManager', + (callback_manager, GraphCallbackManager), + kwargs + ) + + def on_related_nodes(self, nodes) -> Any: + """Callback for related nodes load.""" + + for handler in self.handlers: + if isinstance(handler, GraphRetrieverHandlerProtocol): + handler.on_related_nodes(nodes) + + def on_related_relationships(self, relationships) -> Any: + """Callback for related relationships load.""" + + for handler in self.handlers: + if isinstance(handler, GraphRetrieverHandlerProtocol): + handler.on_related_relationships(relationships) diff --git a/llm/llmlib/utils/callbacks/manager.py b/llm/llmlib/utils/callbacks/manager.py new file mode 100644 index 0000000000..1d90cab1d7 --- /dev/null +++ b/llm/llmlib/utils/callbacks/manager.py @@ -0,0 +1,22 @@ +from typing import Any + +from langchain.callbacks.manager import ParentRunManager +from .base import GraphRetrieverManagerMixin, GraphRetrieverHandlerProtocol + + +class CallbackManagerForGraphRetrieverRun(ParentRunManager, GraphRetrieverManagerMixin): + """Callback manager for graph retriever run.""" + + def on_related_nodes(self, nodes) -> Any: + """Callback for related nodes load.""" + + for handler in self.handlers: + if isinstance(handler, GraphRetrieverHandlerProtocol): + handler.on_related_nodes(nodes) + + def on_related_relationships(self, relationships) -> Any: + """Callback for related relationships load.""" + + for handler in self.handlers: + if isinstance(handler, GraphRetrieverHandlerProtocol): + handler.on_related_relationships(relationships) diff --git a/llm/llmlib/utils/chains/graph_cypher_qa_chain.py b/llm/llmlib/utils/chains/graph_cypher_qa_chain.py new file mode 100644 index 0000000000..9984cad06a --- /dev/null +++ b/llm/llmlib/utils/chains/graph_cypher_qa_chain.py @@ -0,0 +1,211 @@ +"""Question answering over a graph.""" +from __future__ import annotations + +import re +from typing import Any, Dict, List, Optional + +from langchain.callbacks.manager import CallbackManagerForChainRun +from langchain.chains.base import Chain +from langchain.chains.graph_qa.prompts import CYPHER_GENERATION_PROMPT, CYPHER_QA_PROMPT +from langchain.chains.llm import LLMChain +from langchain.graphs.neo4j_graph import Neo4jGraph +from langchain.pydantic_v1 import Field +from langchain.schema import BasePromptTemplate +from langchain.schema.language_model import BaseLanguageModel + +INTERMEDIATE_STEPS_KEY = "intermediate_steps" + + +def extract_cypher(text: str) -> str: + """Extract Cypher code from a text. + + Args: + text: Text to extract Cypher code from. + + Returns: + Cypher code extracted from the text. + """ + # The pattern to find Cypher code enclosed in triple backticks + pattern = r"```(.*?)```" + + # Find all matches in the input text + matches = re.findall(pattern, text, re.DOTALL) + + return matches[0] if matches else text + + +def construct_schema( + structured_schema: Dict[str, Any], + include_types: List[str], + exclude_types: List[str], +) -> str: + """Filter the schema based on included or excluded types""" + + def filter_func(x: str) -> bool: + return x in include_types if include_types else x not in exclude_types + + filtered_schema = { + "node_props": { + k: v + for k, v in structured_schema.get("node_props", {}).items() + if filter_func(k) + }, + "rel_props": { + k: v + for k, v in structured_schema.get("rel_props", {}).items() + if filter_func(k) + }, + "relationships": [ + r + for r in structured_schema.get("relationships", []) + if all(filter_func(r[t]) for t in ["start", "end", "type"]) + ], + } + + return ( + f"Node properties are the following: \n {filtered_schema['node_props']}\n" + f"Relationships properties are the following: \n {filtered_schema['rel_props']}" + "\nRelationships are: \n" + + str( + [ + f"(:{el['start']})-[:{el['type']}]->(:{el['end']})" + for el in filtered_schema["relationships"] + ] + ) + ) + + +class GraphCypherQAChain(Chain): + """Chain for question-answering against a graph by generating Cypher statements.""" + + graph: Neo4jGraph = Field(exclude=True) + cypher_generation_chain: LLMChain + qa_chain: LLMChain + graph_schema: str + input_key: str = "query" #: :meta private: + output_key: str = "result" #: :meta private: + top_k: int = 10 + """Number of results to return from the query""" + return_intermediate_steps: bool = False + """Whether or not to return the intermediate steps along with the final answer.""" + return_direct: bool = False + """Whether or not to return the result of querying the graph directly.""" + + @property + def input_keys(self) -> List[str]: + """Return the input keys. + + :meta private: + """ + return [self.input_key] + + @property + def output_keys(self) -> List[str]: + """Return the output keys. + + :meta private: + """ + _output_keys = [self.output_key] + return _output_keys + + @property + def _chain_type(self) -> str: + return "graph_cypher_chain" + + @classmethod + def from_llm( + cls, + llm: Optional[BaseLanguageModel] = None, + *, + qa_prompt: BasePromptTemplate = CYPHER_QA_PROMPT, + cypher_prompt: BasePromptTemplate = CYPHER_GENERATION_PROMPT, + cypher_llm: Optional[BaseLanguageModel] = None, + qa_llm: Optional[BaseLanguageModel] = None, + exclude_types: List[str] = [], + include_types: List[str] = [], + **kwargs: Any, + ) -> GraphCypherQAChain: + """Initialize from LLM.""" + + if not cypher_llm and not llm: + raise ValueError("Either `llm` or `cypher_llm` parameters must be provided") + if not qa_llm and not llm: + raise ValueError("Either `llm` or `qa_llm` parameters must be provided") + if cypher_llm and qa_llm and llm: + raise ValueError( + "You can specify up to two of 'cypher_llm', 'qa_llm'" + ", and 'llm', but not all three simultaneously." + ) + + qa_chain = LLMChain(llm=qa_llm or llm, prompt=qa_prompt) + cypher_generation_chain = LLMChain(llm=cypher_llm or llm, prompt=cypher_prompt) + + if exclude_types and include_types: + raise ValueError( + "Either `exclude_types` or `include_types` " + "can be provided, but not both" + ) + + graph_schema = construct_schema( + kwargs["graph"].structured_schema, include_types, exclude_types + ) + + return cls( + graph_schema=graph_schema, + qa_chain=qa_chain, + cypher_generation_chain=cypher_generation_chain, + **kwargs, + ) + + def _call( + self, + inputs: Dict[str, Any], + run_manager: Optional[CallbackManagerForChainRun] = None, + ) -> Dict[str, Any]: + """Generate Cypher statement, use it to look up in db and answer question.""" + _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager() + callbacks = _run_manager.get_child() + + intermediate_steps: List = [] + + generated_cypher = self.cypher_generation_chain.run( + {**inputs, "schema": self.graph_schema}, callbacks=callbacks + ) + + # Extract Cypher code if it is wrapped in backticks + generated_cypher = extract_cypher(generated_cypher) + + _run_manager.on_text("Generated Cypher:", end="\n", verbose=self.verbose) + _run_manager.on_text( + generated_cypher, color="green", end="\n", verbose=self.verbose + ) + + intermediate_steps.append({"query": generated_cypher}) + + context = [] + for statement in generated_cypher.split(';'): + if statement: + # Retrieve and limit the number of results + context += self.graph.query(statement)[: self.top_k] + + if self.return_direct: + final_result = context + else: + _run_manager.on_text("Full Context:", end="\n", verbose=self.verbose) + _run_manager.on_text( + str(context), color="green", end="\n", verbose=self.verbose + ) + + intermediate_steps.append({"context": context}) + + result = self.qa_chain( + {**inputs, "context": context}, + callbacks=callbacks, + ) + final_result = result[self.qa_chain.output_key] + + chain_result: Dict[str, Any] = {self.output_key: final_result} + if self.return_intermediate_steps: + chain_result[INTERMEDIATE_STEPS_KEY] = intermediate_steps + + return chain_result diff --git a/llm/llmlib/utils/chains/graph_query.py b/llm/llmlib/utils/chains/graph_query.py new file mode 100644 index 0000000000..924d1176fc --- /dev/null +++ b/llm/llmlib/utils/chains/graph_query.py @@ -0,0 +1,78 @@ +from typing import Any, Dict, List, Optional, TypeVar, Generic + +from langchain.callbacks.manager import CallbackManagerForChainRun +from langchain.pydantic_v1 import Field +from langchain.chains.base import Chain +from langchain.schema import BaseOutputParser + +Graph = TypeVar("Graph") + + +class GraphQueryChain(Chain, Generic[Graph]): + """Chain for converting terms to eid mappings""" + + graph: Graph = Field(exclude=True) + graph_exception: Exception = Field(exclude=True, default=Exception) + aliased_input_keys: List[str] = Field( + alias='input_keys', default_factory=lambda: [] + ) + output_key: str = "results" #: :meta private: + output_parser: BaseOutputParser = None + + # Query to get term eids, input_keys are avaliable as query params + query: str + + @property + def input_keys(self) -> List[str]: + return self.aliased_input_keys + + @property + def output_keys(self) -> List[str]: + return [self.output_key] + + def create_outputs(self, result: List[dict]) -> Dict[str, Any]: + """Create outputs from response.""" + return { + self.output_key: self.output_parser.parse_result(result) + if self.output_parser + else result + } + + def _call( + self, + inputs: Dict[str, Any], + run_manager: Optional[CallbackManagerForChainRun] = None, + ) -> Dict[str, Any]: + """ + Users can modify the following FindEidsChain Class Variables: + + :var top_k: The maximum number of AQL Query Results to return + :type top_k: int + """ + _run_manager = run_manager or CallbackManagerForChainRun.get_noop_manager() + + graph_result = [] + + ##################### + # Execute Query # + + try: + graph_result = self.graph.query(self.query, inputs) + except self.graph_exception as e: + _run_manager.on_text( + "Graph Query Execution Error: ", end="\n", verbose=self.verbose + ) + _run_manager.on_text(e, color="yellow", end="\n\n", verbose=self.verbose) + else: + _run_manager.on_text("Graph Result:", end="\n", verbose=self.verbose) + _run_manager.on_text( + str(graph_result), color="green", end="\n", verbose=self.verbose + ) + ##################### + + # Return results # + return self.create_outputs(graph_result) + + @property + def _chain_type(self) -> str: + return "graph_query_chain" diff --git a/llm/llmlib/utils/chains/graph_retrieval_qa.py b/llm/llmlib/utils/chains/graph_retrieval_qa.py new file mode 100644 index 0000000000..27da426cb3 --- /dev/null +++ b/llm/llmlib/utils/chains/graph_retrieval_qa.py @@ -0,0 +1,40 @@ +from typing import List + +from langchain.callbacks.manager import ( + AsyncCallbackManagerForChainRun, + CallbackManagerForChainRun, +) +from langchain.chains.retrieval_qa.base import RetrievalQA +from langchain.schema import BaseRetriever, Document +from pydantic import Field + + +class GraphRetrievalQA(RetrievalQA): + retriever: BaseRetriever = Field(exclude=True) + + def _get_docs( + self, + question: str, + *, + run_manager: CallbackManagerForChainRun, + ) -> List[Document]: + """Get docs.""" + return self.retriever.get_relevant_documents( + question, callbacks=run_manager.get_child() + ) + + async def _aget_docs( + self, + question: str, + *, + run_manager: AsyncCallbackManagerForChainRun, + ) -> List[Document]: + """Get docs.""" + return await self.retriever.aget_relevant_documents( + question, callbacks=run_manager.get_child() + ) + + @property + def _chain_type(self) -> str: + """Return the chain type.""" + return "retrieval_qa" diff --git a/llm/llmlib/utils/config.py b/llm/llmlib/utils/config.py new file mode 100644 index 0000000000..478012b022 --- /dev/null +++ b/llm/llmlib/utils/config.py @@ -0,0 +1,4 @@ +from flask import current_app +from werkzeug.local import LocalProxy + +config = LocalProxy(lambda: current_app.config) diff --git a/llm/llmlib/utils/dataclass.py b/llm/llmlib/utils/dataclass.py new file mode 100644 index 0000000000..db1bffc491 --- /dev/null +++ b/llm/llmlib/utils/dataclass.py @@ -0,0 +1,108 @@ +from dataclasses import MISSING, fields +from typing import Generic, Callable, overload, Any, TypeVar, Union + +Obj = TypeVar('Obj') +T = TypeVar('T') + + +class Descriptor(Generic[Obj, T]): + _property_prefix: str + _name: str + + def __init__(self, property_prefix: str = '_descriptor_'): + self._property_prefix = property_prefix + + def __set_name__(self, owner, name): + self._name = name + + @property + def _prefixed_name(self): + return self._property_prefix + self._name + + @overload + def __get__(self, instance: None, owner: type[Obj]) -> T: + """This is happening when dataclass is being created""" + ... + + @overload + def __get__(self, instance: Obj, owner: type[Obj]) -> T: + ... + + def __get__(self, instance: Union[Obj, None], owner: type[Obj]) -> T: + return getattr(instance, self._prefixed_name, MISSING) # type: ignore + + def _update_value(self, instance: Obj, value: T): + setattr(instance, self._prefixed_name, value) + + def __set__(self, instance: Obj, value): + if value is not self: + # Dealing with frozen instances (once we read|write the value should be consider frozen) + if hasattr(instance, self._prefixed_name): + setattr(instance, self._prefixed_name, value) + else: + object.__setattr__(instance, self._prefixed_name, value) + + def __repr__(self): + return f'<{type(self).__name__} {self._name}>' + + +class LazyDefaulDescriptor(Descriptor[Obj, T]): + """Decriptor which calls default_factory only when the value is not set yet upon first read + Note: It can be used within frozen dataclassses + WARNING: Be very carefull while debugging this descriptor. + Revealing the property in the debugger will cause the descriptor to be called, + moreover during such call all debugging points will be suppressed. + """ + + _default_factory: Callable[[Obj, str], T] + + def __init__( + self, default_factory: Callable[[Obj, str], T], property_prefix: str = '_lazy_' + ): + super().__init__(property_prefix=property_prefix) + self._default_factory = default_factory + + def __get__(self, instance: Union[Obj, None], owner: Any) -> T: + # If we are accessing the descriptor from the dataclass wrapper, return the descriptor + if instance is None: + return self # type: ignore + + # If the value is already set, return it + set_value = getattr(instance, self._prefixed_name, MISSING) + if set_value is not MISSING: + return set_value + + # If the value is not set, create it and set it + default = self._default_factory(instance, self._name) + object.__setattr__(instance, self._prefixed_name, default) + return default + + +class CauseDefaultingDescriptor(LazyDefaulDescriptor[Any, T]): + """Descriptor which returns default value from the exception __cause__ if it exists + If running on a dataclass, it will try to match the type of the field + """ + + def __init__( + self, + default: T = MISSING, # type: ignore + prefix: str = '_cause_', + replace_self: bool = False, + ): + def _default_factory(instance: Any, prop: str) -> T: + cause = getattr(instance, '__cause__', MISSING) + if cause is not MISSING: + cause_value = getattr(cause, prop, MISSING) + if cause_value is not MISSING: + try: + for f in fields(instance): + if f.name == prop: + if isinstance(cause_value, f.type): + return cause_value + break + except TypeError: + # Running on a non dataclass + return cause_value + return default + + super().__init__(default_factory=_default_factory, property_prefix=prefix) diff --git a/llm/llmlib/utils/lazy_neo4j_graph.py b/llm/llmlib/utils/lazy_neo4j_graph.py new file mode 100644 index 0000000000..88052923cc --- /dev/null +++ b/llm/llmlib/utils/lazy_neo4j_graph.py @@ -0,0 +1,32 @@ +from functools import cache + +from langchain.graphs import Neo4jGraph + + +class LazyNeo4jGraph(Neo4jGraph): + """ + A lazy Neo4j graph wrapper that only refreshes the schema when it is accessed. + This allows for custom schema to be set without heavy call to the database. + """ + + @cache + def lazy_refresh_schema(self) -> None: + """ + Refreshes the Neo4j graph schema information. + """ + return super().refresh_schema() + + def refresh_schema(self) -> None: + pass + + _schema: str + + @property + def schema(self): + if self._schema is None: + self.lazy_refresh_schema() + return self._schema + + @schema.setter + def schema(self, value): + self._schema = value diff --git a/llm/llmlib/utils/output_parsers/graph_results.py b/llm/llmlib/utils/output_parsers/graph_results.py new file mode 100644 index 0000000000..414ec39ac3 --- /dev/null +++ b/llm/llmlib/utils/output_parsers/graph_results.py @@ -0,0 +1,26 @@ +from langchain.output_parsers.list import ListOutputParser +from typing import List, Dict, Any + + +class GraphResultsOutputParser(ListOutputParser): + """Parse the output of a graph query to a list.""" + + key: str = 'output' + separator: str = '\n' + + def get_format_instructions(self) -> str: + return ( + "Your response should be a list of results, " + "eg: `[{key:}, {key:}]`" + ) + + @property + def _type(self) -> str: + return "graph-result-list" + + def parse_result(self, result: List[Dict[str, Any]]) -> List[str]: + """Parse the output of a graph query.""" + return self.parse(self.separator.join(map(lambda row: row[self.key], result))) + + def parse(self, text: str) -> str: + return text diff --git a/llm/llmlib/utils/retrievers/graph_search_retriever.py b/llm/llmlib/utils/retrievers/graph_search_retriever.py new file mode 100644 index 0000000000..3888b468b4 --- /dev/null +++ b/llm/llmlib/utils/retrievers/graph_search_retriever.py @@ -0,0 +1,109 @@ +from typing import Optional, Self, List, Any + +from langchain import LLMChain, PromptTemplate, BasePromptTemplate +from langchain.callbacks.manager import CallbackManagerForRetrieverRun +from langchain.chat_models.base import BaseChatModel +from langchain.output_parsers import CommaSeparatedListOutputParser +from langchain.prompts import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate, +) +from langchain.pydantic_v1 import Field +from langchain.schema import BaseRetriever, Document +from llmlib.utils.search.graph_search_api_wrapper import GraphSearchAPIWrapper + + +def default_terms_prompt_factory(query_key: str): + return ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate( + prompt=PromptTemplate( + template="Always response with comma separated list of terms identified in prompt.", + input_variables=[], + ) + ), + HumanMessagePromptTemplate( + prompt=PromptTemplate( + template=f"{{{query_key}}}", + input_variables=[query_key], + ) + ), + ] + ) + + +class GraphSearchRetriever(BaseRetriever): + llm_chain: LLMChain + graph_search: GraphSearchAPIWrapper = Field( + ..., description="Graph search API wrapper." + ) + verbose: bool = False + relationships: List[Any] = [] + + @classmethod + def from_llm( + cls, + llm: BaseChatModel, + graph_search: GraphSearchAPIWrapper, + prompt: Optional[BasePromptTemplate] = None, + **kwargs: Any, + ) -> Self: + """Initialize from LLM using the default template.""" + if not prompt: + prompt = default_terms_prompt_factory(cls.query_key) + + llm_chain = LLMChain( + llm=llm, + prompt=prompt, + output_parser=CommaSeparatedListOutputParser(), + ) + + return cls( + llm_chain=llm_chain, + graph_search=graph_search, + **kwargs, + ) + + def _get_relevant_documents( + self, query: str, *, run_manager: CallbackManagerForRetrieverRun + ) -> List[Document]: + """Get relevant documents from the graph.""" + + def sub_text(text, verbose=self.verbose, end='\n', **kwargs): + return run_manager.on_text( + '\t' + text.replace('\n', '\n\t'), verbose=verbose, end=end, **kwargs + ) + + def sub_header(text, verbose=self.verbose, end='\n', **kwargs): + return run_manager.on_text( + '\n\t\033[1m>> ' + text.replace('\n', '\n\t') + '\033[0m', + verbose=verbose, + end=end, + **kwargs, + ) + + # Get search terms + sub_header("Generating list of revelant terms") + inputs = self.llm_chain.prep_inputs({"query": query}) + output = self.llm_chain(inputs) + terms = output['text'] + sub_text(f"Identified Terms:\n{terms}") + + sub_header("Searching for related graph nodes") + nodes = self.graph_search.get_related_nodes(terms) + sub_text(f"Identified Nodes:\n{nodes}") + + if len(nodes) > 1: + sub_header("Searching for related graph relationships\n") + relationships = self.graph_search.get_relationships(nodes) + sub_text(f"Identified Relationships:\n{relationships}\n") + self.relationships = relationships + + if len(relationships) > 0: + return [ + self.graph_search.relationship_to_document(relationship) + for relationship in relationships + ] + + return [self.graph_search.node_to_document(node) for node in nodes] diff --git a/llm/llmlib/utils/search/cypher_search_api_wrapper.py b/llm/llmlib/utils/search/cypher_search_api_wrapper.py new file mode 100644 index 0000000000..5540c5c233 --- /dev/null +++ b/llm/llmlib/utils/search/cypher_search_api_wrapper.py @@ -0,0 +1,173 @@ +from typing import List, Any, Dict, TypedDict + +import yaml +from langchain.schema import Document +from llmlib.utils.lazy_neo4j_graph import LazyNeo4jGraph +from llmlib.utils.search.graph_search_api_wrapper import GraphSearchAPIWrapper +from math import floor + +CURRENCY_METABOLITES = [ + 'NAD-P-OR-NOP', 'NADH-P-OR-NOP', 'Donor-H2', 'Acceptor', 'HYDROGEN-PEROXIDE', 'OXYGEN-MOLECULE', + 'NAD', 'NADP', 'NADH', 'NADPH', 'WATER', 'CARBON-DIOXIDE', 'FAD', 'CO-A', 'UDP', 'AMMONIA', + 'NA+', + 'AMMONIUM', 'PROTON', 'CARBON-MONOXIDE', 'GTP', 'ADP', 'GDP', 'AMP', 'ATP', '3-5-ADP', 'PPI', + 'Pi' +] + +RANKED_RELATED_NODES_MAPPING_QUERY = """ +UNWIND $terms AS term +MATCH (s:Synonym {lowercase_name: toLower(term)})<-[:HAS_SYNONYM]-(n) +WHERE n.eid IS NOT NULL AND NOT n.eid IN $exclude_eids +WITH apoc.text.levenshteinSimilarity(term, n.name) as similarity, s, n, term +ORDER BY similarity DESC +WHERE similarity > 0.5 +WITH DISTINCT term, collect({node: n, node_id: id(n), similarity: similarity})[0..$top_k_matches] as matches +RETURN term, matches +""" + +RELATED_SHORTEST_PATH_QUERY = """ +UNWIND apoc.coll.combinations($term_match, 2) AS termPair +UNWIND termPair[0]['matches'] as matchA +UNWIND termPair[1]['matches'] as matchB +WITH matchA, matchB, matchA['similarity'] * matchB['similarity'] AS similarity +ORDER BY similarity DESC +WHERE similarity > 0.5 +MATCH (a), (b) +WHERE id(a) = matchA['id'] AND id(b) = matchB['id'] +MATCH path=allShortestPaths((a)-[*1..]-(b)) +WHERE + all(r in relationships(path) where type(r) in $include_rels) + and all(n in nodes(path) where not n.eid in $exclude_eids) +RETURN path LIMIT $top_k +""" + + +class Node(TypedDict): + eid: str + + +class NodeMatch(TypedDict): + node: Node + node_id: int + similarity: float + + +class TermMatches(TypedDict): + term: str + matches: List[NodeMatch] + + +def preformat_entity(entity): + return { + k: v + for k, v in entity.items() + if v and ( + k not in ( + 'genes', 'inchi', 'inchi_key', 'original_entity_types', 'left_end_position', + 'right_end_position', + ) + ) + } + + +def term_match_template(obj): + return yaml.dump( + { + obj['term']: [ + { + 'matches': [ + preformat_entity(match['node']) + for match in obj['matches'] + ] + } + ] + } + ) + + +def relationship_template(obj): + return yaml.dump( + { + 'relationship': { + 'path': ' - '.join( + map( + lambda n: n.get('eid', '') if isinstance(n, dict) else n, + obj['path'], + ) + ), + 'segments': [ + (preformat_entity(n) if isinstance(n, dict) else n) + for n in obj['path'] + ] + } + } + ) + + +class CypherSearchAPIWrapper(GraphSearchAPIWrapper): + graph: LazyNeo4jGraph + + class Config: + arbitrary_types_allowed = True + + related_nodes_query: str = RANKED_RELATED_NODES_MAPPING_QUERY + related_nodes_query_params: Dict[str, Any] = dict( + top_k_matches=5, + exclude_eids=CURRENCY_METABOLITES, + ) + relationships_query: str = RELATED_SHORTEST_PATH_QUERY + relationships_query_params: Dict[str, Any] = dict( + top_k=3, + include_rels=['CONSUMED_BY', 'PRODUCES', 'CATALYZES', 'REGULATES', 'HAS_TXONOMY', 'IS', + 'HAS_KO', 'ELEMENT_OF', 'ENCODES'], + exclude_eids=CURRENCY_METABOLITES, + ) + + def node_to_document(self, term_match: TermMatches) -> Document: + return Document( + page_content=term_match_template(term_match), + metadata=dict( + term=term_match['term'], + ), + ) + + def relationship_to_document(self, relationship: dict) -> Document: + path_len = len(relationship['path']) + return Document( + page_content=relationship_template(relationship), + metadata=dict( + start_eid=relationship['path'][0]['eid'], + end_eid=relationship['path'][path_len - 1]['eid'], + distance=floor(path_len / 2) + ), + ) + + def get_related_nodes(self, terms: List[str]) -> List[TermMatches]: + mapping = self.graph.query( + self.related_nodes_query, + dict(**self.related_nodes_query_params, terms=terms), + ) + assert len(mapping) <= len(terms) + return mapping + + def get_relationships(self, term_match: List[TermMatches]) -> List[dict]: + term_match_id = [ + { + 'term': term_match['term'], + 'matches': [ + { + 'id': match['node_id'], + 'similarity': match['similarity'], + } + for match in term_match['matches'] + ], + } + for term_match in term_match + ] + + return self.graph.query( + self.relationships_query, + dict( + **self.relationships_query_params, term_match=term_match_id + ), + ) diff --git a/llm/llmlib/utils/search/graph_search_api_wrapper.py b/llm/llmlib/utils/search/graph_search_api_wrapper.py new file mode 100644 index 0000000000..3f848e43e1 --- /dev/null +++ b/llm/llmlib/utils/search/graph_search_api_wrapper.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod +from typing import List, TypeVar, Generic + +from langchain.schema import Document +from pydantic.v1 import BaseModel + +NODE = TypeVar("NODE") +RELATIONSHIP = TypeVar("RELATIONSHIP") + + +class GraphSearchAPIWrapper(ABC, Generic[NODE, RELATIONSHIP], BaseModel): + """Abstract class for graph search API wrappers.""" + + @abstractmethod + def node_to_document(self, node: NODE) -> Document: + ... + + @abstractmethod + def relationship_to_document(self, relationship: RELATIONSHIP) -> Document: + ... + + @abstractmethod + def get_related_nodes(self, terms: List[str]) -> List[NODE]: + ... + + @abstractmethod + def get_relationships(self, nodes: List[NODE]) -> List[RELATIONSHIP]: + ... diff --git a/llm/llmlib/utils/singleton.py b/llm/llmlib/utils/singleton.py new file mode 100644 index 0000000000..8f026e07d4 --- /dev/null +++ b/llm/llmlib/utils/singleton.py @@ -0,0 +1,13 @@ +from abc import ABCMeta + + +class Singleton(ABCMeta): + """Singleton metaclass.""" + + _instances = {} + + def __call__(cls, *args, **kwargs): + """Return singleton instance.""" + if cls not in cls._instances: + cls._instances[cls] = super().__call__(*args, **kwargs) + return cls._instances[cls] diff --git a/llm/llmlib/utils/string.py b/llm/llmlib/utils/string.py new file mode 100644 index 0000000000..d15ff0c2de --- /dev/null +++ b/llm/llmlib/utils/string.py @@ -0,0 +1,27 @@ +import itertools +import re +import sys +from enum import Enum +from enum import EnumMeta +from json import JSONDecodeError +from string import punctuation, whitespace +from typing import Iterator, Dict + +import attr +import unicodedata +from _decimal import Decimal, InvalidOperation +from flask import json + + +def indent_lines(*lines: str, level=1, indent_string: str = '\t'): + return list(map(lambda s: indent_string * level + s, lines)) + + +def compose_lines(*lines: str, new_line_delimeter: str = '\n'): + return new_line_delimeter.join(lines) + + +__all__ = [ + 'indent_lines', + 'compose_lines', +] diff --git a/llm/llmlib/utils/transaction_id.py b/llm/llmlib/utils/transaction_id.py new file mode 100644 index 0000000000..835da7294e --- /dev/null +++ b/llm/llmlib/utils/transaction_id.py @@ -0,0 +1,6 @@ +from flask import g +from werkzeug.local import LocalProxy + +transaction_id = LocalProxy( + lambda: getattr(g, 'transaction_id', 'call_from_outside_of_request_scope') +) diff --git a/llm/llmlib/v0/__init__.py b/llm/llmlib/v0/__init__.py new file mode 100644 index 0000000000..485077561b --- /dev/null +++ b/llm/llmlib/v0/__init__.py @@ -0,0 +1,101 @@ +from typing import List, TypedDict, Union + +from langchain import PromptTemplate +from langchain.callbacks import StdOutCallbackHandler +from langchain.chains import RetrievalQA +from langchain.chat_models import ChatOpenAI +from langchain.prompts import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate, +) +from llmlib.utils.retrievers.graph_search_retriever import GraphSearchRetriever +from llmlib.utils.search.cypher_search_api_wrapper import CypherSearchAPIWrapper + +core_terms_prompt_template = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate( + prompt=PromptTemplate( + template="Always response with comma separated list of chemical or biological terms identified in prompt.", + input_variables=[], + ) + ), + HumanMessagePromptTemplate( + prompt=PromptTemplate( + template="{query}", + input_variables=["query"], + ) + ), + ] +) +handler = StdOutCallbackHandler() +qa_system_template = """Use the following pieces of context to answer the users question. Each piece of information repsesents uncorelated cases, responses based on different pieces shoul be places into separate paragraphs. +If you don't know the answer, just say that you don't know, don't try to make up an answer. +Work on the answear in two steps: +1. Rephase pieces of context ussing natural language +2. Based on repharsed text respond to the question +---------------- +{context} +----------------""" +qa_prompt_template = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate.from_template(qa_system_template), + HumanMessagePromptTemplate.from_template("{question}"), + ] +) + + +class PathRow(TypedDict): + path: List[Union[str, dict]] + + +def paths_to_graph(paths: List[PathRow]): + nodes = {} + edges = [] + for path_row in paths: + path = path_row["path"] + for index, segment in enumerate(path): + if isinstance(segment, dict): + nodes[segment["eid"]] = segment + else: + edges.append( + { + 'from': path[index - 1]["eid"], + 'to': path[index + 1]["eid"], + 'label': segment, + } + ) + + return dict( + nodes=list(nodes.values()), + edges=edges, + ) + + +def graph_qa_v0(query: str, graph, **kwargs): + """Query the LLM for a given text.""" + llm = ChatOpenAI(**{**dict(temperature=0, verbose=True), **kwargs}) # defaults + search = CypherSearchAPIWrapper( + graph=graph, verbose=True, return_intermediate_steps=True + ) + # noinspection PyTypeChecker + retriever = GraphSearchRetriever.from_llm( + llm=llm, + graph_search=search, + prompt=core_terms_prompt_template, + verbose=True, + return_intermediate_steps=True, + callbacks=[handler], + ) + qa = RetrievalQA.from_chain_type( + llm=llm, + chain_type_kwargs=dict(prompt=qa_prompt_template), + retriever=retriever, + verbose=True, + callbacks=[handler], + ) + + return dict( + result=qa(query), + graph=paths_to_graph(retriever.relationships), + ) diff --git a/llm/llmlib/views.py b/llm/llmlib/views.py new file mode 100644 index 0000000000..82ae519703 --- /dev/null +++ b/llm/llmlib/views.py @@ -0,0 +1,88 @@ +from typing import Union + +from flask import g +from langchain import OpenAI +from langchain.chat_models import ChatOpenAI +from langchain.graphs import Neo4jGraph, ArangoGraph +from llmlib.schemas import GraphQARequestSchema +from webargs.flaskparser import use_args +from .app import app +from .database import Arango, Neo4j +from .interfaces import GraphRef +from .schemas import GraphCompletionsRequestSchema, GraphChatCompletionsRequestSchema + + +@app.route('/', methods=['GET', 'POST']) +def enrich(): + raise Exception('No function provided!') + + +@app.route('/healthz', methods=['GET', 'POST']) +def healthz(): + return "I am OK!" + + +def map_graph_ref(graph: GraphRef) -> Union[ArangoGraph, Neo4jGraph]: + database_type = graph['database_type'] + if database_type == 'arango': + database = Arango + elif database_type == 'neo4j': + database = Neo4j + else: + raise Exception('Invalid database type!') + database_name = graph.get('database_name') + return database().graph(database_name) if database_name else database().graph() + + +def map_request_arguments(args): + model_kwargs = dict() + if 'graph' in args: + model_kwargs['graph'] = map_graph_ref(args['graph']) + if 'temperature' in args: + model_kwargs['temperature'] = args['temperature'] + if 'top_p' in args: + model_kwargs['top_p'] = args['top_p'] + if 'frequency_penalty' in args: + model_kwargs['frequency_penalty'] = args['frequency_penalty'] + if 'presence_penalty' in args: + model_kwargs['presence_penalty'] = args['presence_penalty'] + if 'stop' in args: + model_kwargs['stop'] = args['stop'] + if 'n' in args: + model_kwargs['n'] = args['n'] + if 'logit_bias' in args: + model_kwargs['logit_bias'] = args['logit_bias'] + if 'logprobs' in args: + model_kwargs['logprobs'] = args['logprobs'] + if 'stream' in args: + model_kwargs['stream'] = args['stream'] + if 'max_tokens' in args: + model_kwargs['max_tokens'] = args['max_tokens'] + if 'timeout' in args: + model_kwargs['timeout'] = args['timeout'] + if 'user' in args: + model_kwargs['user'] = args['user'] + return model_kwargs + + +@app.route('/completions', methods=['POST']) +@use_args(GraphCompletionsRequestSchema) +def completions(args): + getattr(g, 'transaction_id', args['transaction_id']) + return OpenAI(**map_request_arguments(args)) + + +@app.route('/chat', methods=['POST']) +@use_args(GraphChatCompletionsRequestSchema) +def chat(args): + getattr(g, 'transaction_id', args['transaction_id']) + return ChatOpenAI(**map_request_arguments(args)) + + +@app.route('/graph', methods=['POST']) +@use_args(GraphQARequestSchema) +def graph(args): + getattr(g, 'transaction_id', args['transaction_id']) + from llmlib.v0 import graph_qa_v0 + + return graph_qa_v0(args['query'], **map_request_arguments(args)) diff --git a/llm/makefile b/llm/makefile new file mode 100644 index 0000000000..015b1571f2 --- /dev/null +++ b/llm/makefile @@ -0,0 +1,17 @@ +prettify: + docker run --rm -v .:/apps alpine/flake8:6.0.0 . + +lint: + docker run --rm -v .:/data cytopia/pycodestyle:2 . + +dev: + docker compose\ + -f ../docker-compose.yml\ + -f ../docker-compose.override.yml\ + run --rm -p 8888:8888 llm ./bin/dev.sh + +lock: + docker run --rm -v $$(pwd)/:/home/user $$(docker build -q --target lock .) pipenv lock + +test: + docker run --rm \$$\(docker build -q --target dev .\) pytest tests diff --git a/llm/setup.cfg b/llm/setup.cfg new file mode 100644 index 0000000000..788d8dabca --- /dev/null +++ b/llm/setup.cfg @@ -0,0 +1,26 @@ +[pycodestyle] +max-line-length = 100 +ignore = E203 +exclude = .local/,.svn,CVS,.bzr,.hg,.git + +[mypy] +follow_imports = silent +ignore_missing_imports = true + +[flake8] +max-line-length = 100 +select = F +exclude = .local/,.svn,CVS,.bzr,.hg,.git +extend-ignore = +# for compability with black + E203, +# 'X' imported but unused + F401, +# from .X import *' used; unable to detect undefined names + F403, +# 'X' may be undefined, or defined from star imports: .Y + F405, +# f-string is missing placeholders + F541, +# local variable 'X' is assigned to but never used + F841 diff --git a/llm/setup.py b/llm/setup.py new file mode 100644 index 0000000000..d1bc91a13f --- /dev/null +++ b/llm/setup.py @@ -0,0 +1,7 @@ +from setuptools import setup, find_packages + +setup( + name="llmlib", + version="0.1", + packages=find_packages(), +) diff --git a/llm/tests/test_queries.py b/llm/tests/test_queries.py new file mode 100644 index 0000000000..dc31fe869d --- /dev/null +++ b/llm/tests/test_queries.py @@ -0,0 +1,66 @@ +from langchain.callbacks import StdOutCallbackHandler +from langchain.chains import RetrievalQA +from langchain.chat_models import ChatOpenAI +from langchain.embeddings import OpenAIEmbeddings +from langchain.prompts import PromptTemplate +from langchain.prompts.chat import ( + ChatPromptTemplate, + SystemMessagePromptTemplate, + HumanMessagePromptTemplate, +) +from langchain.vectorstores import Chroma +from llmlib.database import Neo4j +from llmlib.utils.retrievers.graph_search_retriever import GraphSearchRetriever +from llmlib.utils.search.cypher_search_api_wrapper import CypherSearchAPIWrapper + +from app import app + +QUERIES = ( + "What is the relationship between Zn2+ and glycolate?", + "What is the relationship between INHBA and MTMR4?", +) + + +def test_queries(): + with app.app_context(): + llm = ChatOpenAI(temperature=0, verbose=True) + core_terms_prompt_template = ChatPromptTemplate.from_messages( + [ + SystemMessagePromptTemplate( + prompt=PromptTemplate( + template="Always response with comma separated list of chemical or biological terms identified in prompt.", + input_variables=[], + ) + ), + HumanMessagePromptTemplate( + prompt=PromptTemplate( + template="{query}", + input_variables=["query"], + ) + ), + ] + ) + embeddings = OpenAIEmbeddings() + vectorstore = Chroma( + embedding_function=embeddings, persist_directory="./chroma_db_oai" + ) + graph = Neo4j().graph() + search = CypherSearchAPIWrapper( + graph=graph, verbose=True, return_intermediate_steps=True + ) + handler = StdOutCallbackHandler() + retriever = GraphSearchRetriever.from_llm( + vectorstore=vectorstore, + llm=llm, + graph_search=search, + prompt=core_terms_prompt_template, + verbose=True, + return_intermediate_steps=True, + callbacks=[handler], + ) + qa = RetrievalQA.from_chain_type( + llm=llm, retriever=retriever, verbose=True, callbacks=[handler] + ) + + for query in QUERIES: + print(qa.run(query))