From 5426a0c988e37c160a473657c09c4a609bb4ef5a Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 14:28:13 +0200 Subject: [PATCH 01/23] add changes --- appserver/Dockerfile | 151 ++++------------- appserver/neo4japp/blueprints/reports.py | 71 ++++---- appserver/neo4japp/blueprints/user.py | 4 + appserver/neo4japp/constants.py | 2 +- cache-invalidator/Dockerfile | 75 +++------ client/Dockerfile | 86 ++++++---- client/landing/src/index.html | 5 +- client/src/app/app-routing.module.ts | 20 +-- client/src/app/app.component.html | 3 - client/src/app/app.module.ts | 2 - .../published-browser.component.html | 3 + .../published-browser.component.ts | 2 + client/src/environments/development.css | 1 - client/src/environments/production.css | 1 - docs/wiki/Architecture overview.drawio.png | Bin 0 -> 534406 bytes docs/wiki/README.md | 159 ++++++++++++++++++ docs/wiki/binderhub/cluster-issuer-prod.yaml | 2 +- docs/wiki/binderhub/cluster-issuer-stg.yaml | 2 +- docs/wiki/binderhub/config-prod.yaml | 154 +++++++++++------ docs/wiki/binderhub/config-stg.yaml | 154 +++++++++++------ docs/wiki/binderhub/ingress-nginx.yaml | 9 +- docs/wiki/binderhub/setup-binderhub.md | 77 +++++---- filebeat/Dockerfile | 3 +- filebeat/config/filebeat.yml | 7 +- graph-db/.gitignore | 140 +++++++++++++++ graph-db/README.md | 5 + logstash/.dockerignore | 1 + statistical-enrichment/Dockerfile | 92 +++------- 28 files changed, 745 insertions(+), 486 deletions(-) create mode 100644 docs/wiki/Architecture overview.drawio.png create mode 100644 docs/wiki/README.md create mode 100644 logstash/.dockerignore diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 66b2431483..d2e572feb9 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -1,133 +1,44 @@ -# ======================================== -# Base image -# ======================================== -FROM python:3.10-slim as base - -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONFAULTHANDLER 1 +FROM fedora:33 as base +LABEL app=kg-prototypes +# Install dependencies +RUN dnf install htop postgresql graphviz python-pip python3-devel vim net-tools which -y \ + && dnf groupinstall 'Development Tools' -y \ + && dnf clean packages RUN pip install pipenv +ENV N4J_USER n4j +ENV N4J_HOME /home/$N4J_USER +ENV UID 1000 +ENV GID 1000 -# ======================================== -# Build dependencies stage -# ======================================== -FROM base as build-deps - -# Install build dependencies -RUN apt-get update \ - && apt-get install -y liblmdb-dev python3-dev libxml2-dev libxslt-dev build-essential \ - && apt-get clean - -# Copy Pipfiles -COPY Pipfile Pipfile.lock ./ - -# Install Python dependencies -ARG DEV -RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) - - -# ======================================== -# Runtime stage -# ======================================== -FROM base -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - -# Install runtime system dependencies -RUN apt-get update \ - && apt-get install -y libmagic-dev graphviz libgraphviz-dev curl \ - && apt-get clean - -# Copy Python virtual environment -COPY --from=build-deps /.venv /.venv -ENV PATH="/.venv/bin:$PATH" - -# Set user and workdir -WORKDIR /app -RUN useradd -m -d /app app -USER app - -# Copy application code -COPY --chown=app . . - -# Set to 1 to automatically apply any pending DB migrations at startup -ENV MIGRATE_DB= - -# Create an initial admin user -ENV INITIAL_ADMIN_EMAIL= - -# LMDB database volume -ENV LMDB_DATA_DIR=/lmdb -VOLUME /lmdb - -# LMDB download cloud storage -# ENV AZURE_ACCOUNT_STORAGE_NAME= -# ENV AZURE_ACCOUNT_STORAGE_KEY= - -# JWT Authendication -ENV JWT_SECRET=secret - -# Base URL of this app, reachable by external services -ENV APPSERVER_URL=http://localhost:5000 - -# Base URL of the frontend app, for link generation -ENV FRONTEND_URL=http://localhost:4242 - -# PostgreSQL configuration -ENV POSTGRES_HOST=postgres -ENV POSTGRES_PORT=5432 -ENV POSTGRES_USER=postgres -ENV POSTGRES_PASSWORD=postgres -ENV POSTGRES_DB=postgres - -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_DATABASE=neo4j -ENV NEO4J_SCHEME=bolt - -# Elasticsearch configuration -ENV ELASTICSEARCH_URL=http://elasticsearch:9200 -ENV ELASTICSEARCH_FILE_INDEX=file - -# Statistical enrichment service -ENV STATISTICAL_ENRICHMENT_URL=http://statistical-enrichment:5000 - -# PDFParser service -ENV PDFPARSER_URL=http://pdfparser:7600 +# User and group creation +RUN groupadd -g $GID $N4J_USER && \ + useradd -u $UID -g $GID -G wheel --create-home --home-dir $N4J_HOME --shell /bin/bash $N4J_USER -# NLP Processing service -ENV NLP_URL=https://nlp-api.lifelike.bio/v1/predict -ENV NLP_SECRET=secret +WORKDIR $N4J_HOME -# Mailserver configuration -ENV FROM_EMAIL=lifelike@example.com +# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache +COPY --chown=1000:1000 Pipfile . +COPY --chown=1000:1000 Pipfile.lock . +RUN pipenv install --dev --deploy --system -# Sendgrid integration -ENV SENDGRID_API_KEY= +# ...then copy everything else +COPY --chown=1000:1000 . . -# Optional Sentry logging configuration -ENV SENTRY_DSN= +# TODO: We should consider breaking this apart into dev and prod +# builds, so we don't build unnecessary packages -# Optional Elastic APM configuration. -# To enable, at least ELASTIC_APM_SERVER_URL must be set -# Other available variables: https://www.elastic.co/guide/en/apm/agent/python/master/configuration.html -ENV ELASTIC_APM_SERVER_URL= -ENV ELASTIC_APM_SERVICE_NAME=appserver +# Don't lose stdin, stdout and stderr output due to buffering +ENV PYTHONUNBUFFERED 1 +ENV PYTHONPATH $N4J_HOME -# Flask env (development, testing, production) -ENV FLASK_ENV=production +# Set Python3 as the default when running "python" +RUN echo 'alias python=python3' >> ~/.bashrc && source ~/.bashrc -# Listen port -ENV PORT=5000 -EXPOSE $PORT +USER $N4J_USER -# Health check by requesting system info to /meta endpoint -HEALTHCHECK --start-period=30s \ - CMD curl -f localhost:$PORT/meta || exit 1 +# Setup flask application environment vars +ENV MAX_ALLOWED_LOGIN_FAILURES 6 -RUN chmod +x bin/docker-entrypoint.sh -ENTRYPOINT ["bin/docker-entrypoint.sh"] +CMD [ "bin/startup.sh" ] diff --git a/appserver/neo4japp/blueprints/reports.py b/appserver/neo4japp/blueprints/reports.py index 3529036c0f..c9b55d444e 100644 --- a/appserver/neo4japp/blueprints/reports.py +++ b/appserver/neo4japp/blueprints/reports.py @@ -20,7 +20,36 @@ class CopyrightInfringementReportView(MethodView): @use_args(CopyrightInfringementRequestSchema) def post(self, params: dict): - with db.session.begin_nested(): + # Try to send an email to the user and currator + send_email_exception = None + try: + message = Mail( + from_email=MESSAGE_SENDER_IDENTITY, + to_emails=params['email'], + subject=COPYRIGHT_REPORT_CONFIRMATION_EMAIL_TITLE, + html_content=COPYRIGHT_REPORT_CONFIRMATION_EMAIL_CONTENT.format( + url=params['url'], + description=params['description'], + name=params['name'], + company=params['company'], + address=params['address'], + country=params['country'], + city=params['city'], + province=params['province'], + zip=params['zip'], + phone=params['phone'], + fax=params['fax'], + email=params['email'], + ), + ) + message.add_bcc(bcc_email=LIFELIKE_EMAIL_ACCOUNT) + get_send_grid_service().send(message) + except Exception as e: + # If the email fails to send, store the exception to raise later + # after the report is saved to the database + send_email_exception = e + + try: copyright_infringement_report = CopyrightInfringementRequest( url=params['url'], description=params['description'], @@ -41,38 +70,16 @@ def post(self, params: dict): signature=params['signature'], ) db.session.add(copyright_infringement_report) - - message = Mail( - from_email=MESSAGE_SENDER_IDENTITY, - to_emails=params['email'], - subject=COPYRIGHT_REPORT_CONFIRMATION_EMAIL_TITLE, - html_content=COPYRIGHT_REPORT_CONFIRMATION_EMAIL_CONTENT.format( - url=params['url'], - description=params['description'], - name=params['name'], - company=params['company'], - address=params['address'], - country=params['country'], - city=params['city'], - province=params['province'], - zip=params['zip'], - phone=params['phone'], - fax=params['fax'], - email=params['email'], - ), - ) - message.add_bcc(bcc_email=LIFELIKE_EMAIL_ACCOUNT) - try: - get_send_grid_service().send(message) - except Exception as e: - with db.session.begin_nested(): - # If for some reason we cannot send a confirmation email, delete the row we just - # created and re-raise the error. - db.session.delete(copyright_infringement_report) - # rollback in case of error? + db.session.commit() + except Exception: + db.session.rollback() raise - - return jsonify(dict(result=copyright_infringement_report.to_dict())) + else: + return jsonify(dict(result=copyright_infringement_report.to_dict())) + finally: + # If the email failed to send, raise the exception before returning + if send_email_exception: + raise send_email_exception copyright_infringement_report_view = CopyrightInfringementReportView.as_view( diff --git a/appserver/neo4japp/blueprints/user.py b/appserver/neo4japp/blueprints/user.py index e33c85c59e..e0d7be30c2 100644 --- a/appserver/neo4japp/blueprints/user.py +++ b/appserver/neo4japp/blueprints/user.py @@ -7,6 +7,7 @@ from webargs.flaskparser import use_args from neo4japp.database import db +from neo4japp.exceptions import NotAuthorized from neo4japp.models import Projects, Files from neo4japp.schemas.filesystem import ( PublishSchema, @@ -48,6 +49,9 @@ def get(self, user_hash_id: str): @use_args(PublishSchema, locations=['json', 'form', 'files', 'mixed_form_json']) def post(self, params: dict, user_hash_id: str): + if g.current_user.has_role('admin') is False: + raise NotAuthorized() + file = Publish.create_uncommited_publication( user_hash_id, creator=g.current_user, **params ) diff --git a/appserver/neo4japp/constants.py b/appserver/neo4japp/constants.py index 1952651df5..9b1ae5a969 100644 --- a/appserver/neo4japp/constants.py +++ b/appserver/neo4japp/constants.py @@ -451,7 +451,7 @@ def is_db_name(s: str): RESET_PASSWORD_ALPHABET = RESET_PASSWORD_SYMBOLS + string.ascii_letters + string.digits # Start email constants -LIFELIKE_EMAIL_ACCOUNT = 'lifelike.science@gmail.com' +LIFELIKE_EMAIL_ACCOUNT = 'lifelike@biosustain.dtu.dk' MESSAGE_SENDER_IDENTITY = 'lifelike-account-service@lifelike.bio' MAILING_API_KEY = LocalProxy(lambda: config.get('SEND_GRID_EMAIL_API_KEY')) RESET_PASSWORD_EMAIL_TITLE = 'Lifelike: Account password reset' diff --git a/cache-invalidator/Dockerfile b/cache-invalidator/Dockerfile index 33f146b5ba..7a94eac270 100644 --- a/cache-invalidator/Dockerfile +++ b/cache-invalidator/Dockerfile @@ -1,64 +1,33 @@ -# ======================================== -# Base image -# ======================================== FROM python:3.10-slim as base +LABEL app=kg-prototypes -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONFAULTHANDLER 1 - +# Install dependencies +RUN apt-get update && apt-get install -y curl && apt-get clean RUN pip install pipenv +ENV APP_USER lifelike +ENV APP_HOME /home/$APP_USER +ENV UID 1000 +ENV GID 1000 -# ======================================== -# Build dependencies stage -# ======================================== -FROM base as build-deps - -# Copy Pipfiles -COPY Pipfile Pipfile.lock ./ - -# Install Python dependencies -ARG DEV -RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) - - -# ======================================== -# Runtime stage -# ======================================== -FROM base -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - -# Copy Python virtual environment -COPY --from=build-deps /.venv /.venv -ENV PATH="/.venv/bin:$PATH" - -# Set user and working directory -WORKDIR /app -RUN useradd -m -d /app app -USER app +# User and group creation +RUN groupadd -g $GID $APP_USER && \ + useradd -u $UID -g $GID -G sudo --create-home --home-dir $APP_HOME --shell /bin/bash $APP_USER -# Copy application code -COPY --chown=app main.py ./ +WORKDIR $APP_HOME -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_SCHEME=bolt -ENV NEO4J_DATABASE=neo4j +# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache +COPY --chown=1000:1000 Pipfile . +COPY --chown=1000:1000 Pipfile.lock . +RUN pipenv install --deploy --dev --system -# Redis cache configuration -ENV REDIS_HOST=redis -ENV REDIS_PORT=6379 -ENV REDIS_PASSWORD=password -ENV REDIS_DB=0 +# ...then copy everything else +COPY --chown=1000:1000 . . -# Default TTL for cache -ENV CACHE_TTL=86400 +# Don't lose stdin, stdout and stderr output due to buffering +ENV PYTHONUNBUFFERED 1 +ENV PYTHONPATH $APP_HOME -# Logging level -ENV LOG_LEVEL=INFO +USER $APP_USER -CMD ["python", "main.py"] +CMD [ "bin/startup.sh" ] diff --git a/client/Dockerfile b/client/Dockerfile index 268192f7ce..af7fe9281b 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,5 +1,20 @@ ARG NODE_IMAGE_TAG=node:14 +# ======================================== +# Landing page +# ======================================== +FROM $NODE_IMAGE_TAG as landing-build +WORKDIR /app + +# Install dependencies +COPY landing/package.json landing/yarn.lock ./ +RUN yarn install + +# Build landing page +COPY landing ./ +RUN yarn build + + # ================================================================== # Angular app dependencies by default used for local development # ================================================================== @@ -8,58 +23,71 @@ WORKDIR /app # Install dependencies COPY package.json yarn.lock ./ -ARG YARN_INSTALL_OPTS -RUN yarn install ${YARN_INSTALL_OPTS} - -ENV ENVIRONMENT_CONFIG development +RUN yarn install +# build time arguments for Angular environment +ARG ANGULAR_CONFIG=development +ARG CLIENT_VERSION=undefined +# default enviroment presets +ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG # ======================================== # Angular app bundle build # ======================================== FROM angular-deps as angular-build +# build time arguments for Angular environment +ARG ANGULAR_CONFIG=production +ARG CLIENT_VERSION=undefined + # Copy the code and build the app bundle COPY src ./src COPY tslint ./tslint COPY e2e ./e2e COPY *.json browserslist ./ - -ARG ANGULAR_CONFIG=production -ENV NODE_OPTIONS=--max-old-space-size=4096 -RUN yarn build --configuration=$ANGULAR_CONFIG --output-path=dist - -# When targeting this image stage, run angulat dev server -EXPOSE 4200 -HEALTHCHECK --interval=5m --timeout=10s \ - CMD curl -f localhost:4200 || exit 1 -CMD yarn dev-start - +RUN sed -i "s/__VERSION__/${CLIENT_VERSION}/" src/environments/environment.ts +RUN yarn build --configuration=$ANGULAR_CONFIG --aot --output-path=dist # ======================================== # Runtime stage - NGINX # ======================================== -FROM nginx:1.21 -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - +FROM nginx:1.25.1 +LABEL app=kg-prototypes WORKDIR /usr/share/nginx/html -# Copy built assets -COPY --from=angular-build /app/dist ./ +# URL to proxy requests to /api +ENV APPSERVER_UPSTREAM http://appserver:5000 -# Copy nginx configuraiton template -COPY nginx.conf /etc/nginx/templates/default.conf.template +# Whether to run the app in prod mode +ENV PRODUCTION_MODE true -# appserver URL to proxy /api requests -ENV APPSERVER_URL http://appserver:5000 +# Whether we are running with valid KEGG license +ENV KEGG_ENABLED false + +# Whether to run the app with oauth login +ENV OAUTH_ENABLED false + +# OAuth issuer discovert URL +ENV OAUTH_ISSUER "" + +# Client ID of the OAuth application +ENV OAUTH_CLIENT_ID "" # List of space delimited list of non-stantdard MIME types # which are known to benefit from gzip compression (text based content) ENV GZIP_EXTRA_TYPES text/tsv vnd.lifelike.document/bioc vnd.lifelike.document/enrichment-table vnd.lifelike.document/graph vnd.lifelike.document/map -# Runtime environment configuration preset -ENV ENVIRONMENT_CONFIG production +# build time argument for Angular environment +ARG ANGULAR_CONFIG=production + +# default enviroment presets +ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG + +# Copy nginx configuraiton template +COPY nginx.conf /etc/nginx/templates/default.conf.template + +# Copy built assets +COPY --from=landing-build /app/dist ./ +COPY --from=angular-build /app/dist ./ -# Listen port -ENV PORT 80 -EXPOSE $PORT +EXPOSE 80 diff --git a/client/landing/src/index.html b/client/landing/src/index.html index 468d424815..2664fc7ce3 100644 --- a/client/landing/src/index.html +++ b/client/landing/src/index.html @@ -45,12 +45,13 @@

From Big Data
to Big Picture

picture understanding, augmenting our intelligence in solving complex problems. - + diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts index 0ae44202f8..3e43ffe2af 100644 --- a/client/src/app/app-routing.module.ts +++ b/client/src/app/app-routing.module.ts @@ -4,7 +4,6 @@ import { Router, RouterModule, Routes } from '@angular/router'; import { Store } from '@ngrx/store'; import { AdminPanelComponent } from 'app/admin/components/admin-panel.component'; -import { UserFileImportComponent } from 'app/user-file-import/components/user-file-import.component'; import { VisualizationComponent } from 'app/visualization/containers/visualization/visualization.component'; import { GraphSearchComponent } from 'app/search/components/graph-search.component'; import { ObjectBrowserComponent } from 'app/file-browser/components/object-browser.component'; @@ -25,9 +24,8 @@ import { CommunityBrowserComponent } from 'app/file-browser/components/community import { BrowserComponent } from 'app/file-browser/components/browser/browser.component'; import { ContentSearchComponent } from 'app/search/components/content-search.component'; import { ObjectNavigatorComponent } from 'app/file-navigator/components/object-navigator.component'; -import { ShortestPathComponent } from 'app/shortest-path/containers/shortest-path.component'; -import {EnrichmentTableViewerComponent} from 'app/enrichment/components/table/enrichment-table-viewer.component'; -import {EnrichmentVisualisationViewerComponent} from 'app/enrichment/components/visualisation/enrichment-visualisation-viewer.component'; +import { EnrichmentTableViewerComponent } from 'app/enrichment/components/table/enrichment-table-viewer.component'; +import { EnrichmentVisualisationViewerComponent } from 'app/enrichment/components/visualisation/enrichment-visualisation-viewer.component'; import { BiocViewComponent } from 'app/bioc-viewer/components/bioc-view.component'; import { ObjectViewerComponent } from 'app/file-browser/components/object-viewer.component'; import { SankeyViewComponent } from 'app/sankey/components/sankey-view.component'; @@ -113,11 +111,6 @@ const routes: Routes = [ fontAwesomeIcon: 'search', }, }, - { - path: 'pathway-browser-prototype', - canActivate: [AuthGuard], - component: ShortestPathComponent, - }, { path: 'projects/:project_name/enrichment-table/:file_id', canActivate: [], @@ -172,15 +165,6 @@ const routes: Routes = [ fontAwesomeIcon: 'fas fa-chart-network', }, }, - { - path: 'upload', - component: UserFileImportComponent, - canActivate: [AuthGuard], - data: { - title: 'Knowledge Graph Upload', - fontAwesomeIcon: 'fas fa-chart-network', - }, - }, ], }, { diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html index b92e740d4f..6328577354 100644 --- a/client/src/app/app.component.html +++ b/client/src/app/app.component.html @@ -105,9 +105,6 @@ [appAutoCloseTooltipOutOfView]="tooltipRef"> --> - - - Publish diff --git a/client/src/app/file-browser/components/published-browser/published-browser.component.ts b/client/src/app/file-browser/components/published-browser/published-browser.component.ts index bb7cbe0349..b68c26555c 100644 --- a/client/src/app/file-browser/components/published-browser/published-browser.component.ts +++ b/client/src/app/file-browser/components/published-browser/published-browser.component.ts @@ -49,6 +49,8 @@ export class PublishedBrowserComponent implements OnInit, OnDestroy { ); private loadTaskSubscription: Subscription; + readonly disablePublishMessage = + 'You do not have permission to publish files. Please contact administrator if you need this feature.'; constructor( private readonly filesystemService: FilesystemService, diff --git a/client/src/environments/development.css b/client/src/environments/development.css index 8b13789179..e69de29bb2 100644 --- a/client/src/environments/development.css +++ b/client/src/environments/development.css @@ -1 +0,0 @@ - diff --git a/client/src/environments/production.css b/client/src/environments/production.css index 8b13789179..e69de29bb2 100644 --- a/client/src/environments/production.css +++ b/client/src/environments/production.css @@ -1 +0,0 @@ - diff --git a/docs/wiki/Architecture overview.drawio.png b/docs/wiki/Architecture overview.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..21b24aa01b63a310b425296bb28aab0336edffed GIT binary patch literal 534406 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

}y|Ha( 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≀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�;*HZ*xXMi5^7PsNkpn?dI6HUXN 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 z z^2QW{W}a(3d-k;N<&uE)>(^VrTwPra%orCI7TR<3IYXfk+1;?-XY&3z}UvqSuj@>i@jb{XKQ_LGDg$Nf0B|C)L7LBXRLBMTZof_kt z{n*zN-ckT(UpR*{OWqEipRDLw&m=s>}*<)6C z=V^%}P?{M&3vOA*YQ0!1j1}enG|M&`^CqCc&b8TcWJVmq8rAIrVf)Ucv&uK6Dvi^* z0BSTPlQaA*+0?yfb{ks|fy4EW%+A{W#?@^^=7IpZ$#ZShKQWp(hA~)rXQ|8P_Fl zi__6bW*CkBHj;aIqlGs%lvX{Z5Qp3vv9<;eWjUFF2>@^a$yx44-qiPf5EAqRX&xxd z4t!<%RGA!Ygg8dHa*ThCmh}a5qc*g@DA#$)X8Xp?A`q}Y9F*y~5Ur-OP^&8m@Etz` z*`6oG!Y?$2mhl3z{yrB;VWxqmmkaV5n!D&pfRq=>afYYoSj;<{gt!&KtS$(;pYZEt zu_Q-qY$1t98%^K);J73~#|onsD!}{rnPwS2qOJX{ObT)D;e1|oJ0hN?P4aGzP)hYl z-7F-WM_SG=%*9RV`xIA~YB2f2;Flz@urMgsZmojWiu6p*jg17IdA6Rnng(gDd+#@L za6=d4&2e?T0X&~;hkX@=eg3PGBT=Z5B};`9=q8Q$G(Q(VFH7jD zh|s#AofzY9e(-0xj3PI#<_i>cz9T!!?OlCje+m0POT6Xm3jagk@ zsIOhS7LGaQ7+bfprW0WOx0ucX3DxpV^M~@;$zY%1z3M1t^ zAby+F-cwm_pc@gM3x?MFN)P@GBml!ex1^#rA{_TJ(&AB+x;JXbLI;mhO0W0TD&JLl zXSfna8zWyS%EAA7gZ|4MYZNauiuu)WBz|6V%m2n|2i~;dx$;Z%jFk<2`}T!*-g(D@ zRGwSy+O@MK1HLSopJASR%+dw|0n5xXQ`->Sa`^!RXs)qmK>foHKY*>@E-kgHiC8RV z=h8o#YmKd@w+Y-fiaFNQiKY?w)kgpsIA{g?(hkOPIz@xN#}#r`egmVZO)+nVgW`yA zNQ?nUF>G9$hk?Mo1U90@E(Y0gw0*HzMquKFp;V-WHFnC>OG!~8l9yVfrObNFC_`pv zUGm_HV>=ybja0T(&}lEdx^B^^!8e@t3s;{90R3CEY}xbk=$;=1Vu>G{!tp3V>4}K& z*M=^vEWJg<3$!tB6zAGJ%^RP7^}Wvu!ab&)7-`J~QM}!6*(5fr5-0|v1FsddP3=~f zCFp!4b(SG4^%>5Ml{K9LPJkEJ@6ZQg#-A1Qg`4yDK89&AX|i@$_<1 z`dQy?nsWmQ=;jRJjP4w=uC{y6I_u(`2iLtghR`u$znIR8;jLRKQ)THz1Q;(29R{l< z+v!*t&IXu}CnxkTgs5w*%wM%={ zo9ZxF=UQqKusV|MSOX(&%tji*4nQW$5zgAQF;^8`L!_^(tI<=tcebWlvMi?W2Vpk) z%)Z^|NUG@oqUJ{<=J=qeJWl-x^mQU2N3zqjz4tq**wcE65OP(1JG89XrXBm*2$3~T zIM@QDTo7)9J2*4gb<{Ki&b}Ie`8`5t9k5ddC~z(i7?Vssx*MDAY3mw}rfHATEcWYJ z?QtvB)e`YMA#B8r1&q;3bu&nDnMu};igajZ8EdXDC*ce;q)XPVaaZ1R51P`ro(M!8 z0wFopmrV0U2{`grAo|je=Hbt8*m@uoXqI`O(fZ}0+ziVu|4>c2HCitKZPrKfQky@v z|8aG@1~{WOA@AtXBXv!du?9WK){}-(_3h;ex{^pM1JDcz_D6D3_ll2OXK1+w^D;Bp zHd|S$35ei&GP$s8yHq}J`A&6(PC{QPw+SIf`^>CAcYyTu2I&!hQ_0S=RF?6Dj^j?} zC?*DWLeL&Em`8@9EcxG5sRs+8dj&GwJN^9Z^mERj*HCt5NZ!=}vBq9kmAZvAwjcqz zg%*$RLw$)OX`fNp90eqOS*7h)DhqpvK&*B%#L8qfXwytMqU(aJ*9^ zhWTv29TS!*d!|2;-YcYRNergR6ahF-`|P>B#yHJK(m^6Q-Zz-z?+piC&ba-1VQwnd z+dhvK-UZUZaj5DhhVzY8BZEk0P+9KF0FMEq z-*}PEj1Pla28lnfMP(M0K`S?AiT?Dbl)-i+60z)Q!^VJ_fir_!mH{)9`}4MA#}4~% z3~IY{=>lwm#qwtc*$hZ8zx;Ch5nlW=3%g;%2I$tU+dr&DWLYvZX51K@bNypwWhLb0 z@z2pu8v_bvd>bRUEvuxiAoN0G;A!E=?VxpjVUF{t_0d3axf5`nOxCF`67ebl@G;Bu z?X#RvSF%|eZ|t%%$ei{G++ncy4Q|Cr#kCvE7lT{xpriuQLKa zaZBE~hdQ}+w47XgqOc7<@1L?Pu16xkv4@~~gddwxSxIg8qh2hf{JbC=)8BaIaXnj+ z$tbGN&1JBgcZ^zuB=-8TC(+pcb|jjOGX$B^6^j_K@VUx=tSz7#XUXC@lfQc4z6HFk z-(}f@>(0#YQh3$+58r)Y?#%HUc@5vJMT==gMaN$I%&Q;2d zMlT1jxw#g|lz#8^5*avF>*V61yk=~GbOeLjx7U}>?9ln>P_ry|k{{y|jd3)NX;l!k z5?LFo6yHzTKOQtI!O$y_!x146t)?-cz2YOKJEmPb-0$B%mM#k+uMLnKeNe*A3{qnN zMbH?rgw1knpHhtRN)+Oaf^1ytf7Z%rQ5*}P$)NjU+6_4Fou>$f7~w1~4x%+uDoc1A zOH)%AbS)*rwXdadHAM)_K_jR8tZDg9I>#tAR!W+l-!2u!ld65ytBim@7uOr{*c{|4 zGZKKhkd`Z$#sB>C&)t@JJ?;h&*-0U0b`PRu@vXD4F#SjwM@Z*kHrtBE)oq60c$DTL zpPA+Nmc+cX1>$uQrIKet5Lx% zS_QY>t6+GxxW2B=o~xQp(8`=DP=9Vvo-T~w zc&=)e9!rFdHBd9%x(M4?EHOtVy_sD*W__4`c4EojppZiyq8GX}IBrQ?UFHB>XM|bE z_r>NVYiPl>dx*4)Yp0`ex{OE{K9m;e9%R04%czKmsq_wIk%FVD+@X{*P4-EAK z&$%l@&;?f3ZTu}(Ew4Pl-*;k;&bJu5*PE4bx4Sq5~xQ0CfLW@lM; z%-@IHXJ$oN9?T$?rM=Ala$|WUv#(q~SW;4ASs<U>!>d{9Z4ZC*jveHbhD`fVHK>~wpW_G!8?Jxg3pPxYh_n#SF zX0=wYUTxpYi+q+(w`kGA0%-=$yrAd*=YDcOxUp25ua}vwMhR{cYAq6e1zLYVQl4R? zcvN`M9)!6{lXyyimyIX~3Zzeb_h-1_6hlHgyOXT0&k zEG_@Xl40K1;W}`hdp@}R=%bJ9^X$)4W?|W6%4cpHf?F;T;PL{l*X70%eV$`1Yv#?T ze>B&)jG!^KCUD!B?nYBznnvK)8-X;qWmbTWFb^2ge=7|{va7s<^iu|J3` z=M~;^0q{XVD8P&Rw^+8UB~B-F))WWvFa9uGblJ6U?y9aj`jMAj>(xEjBF}N0sez2l z3p#f05mLMEs)bkv9#K$bDOrD4!?v@TbRFLhwVeemD-wi-Hk&wfE zx2-gm9EvDTGa#q>3;dLfT`dIADSxgN;fhTCKAM>Sd zrLo#!LO3S@sF^+!yQPvkDOAIVglB|$n$5r1=mZHaGLoM5>%jS#n=9!=BlKVo;O(yU zti;CZWKTzl=^*6F!XVoE$G>mgb7WRlvxyEknF7T;1{mzNOe6<;HmN<#?MK6Ym}*IHE@En(S{Bl~&RjLg;${las^2l;bk9u0rVf zh*(ybBW;##J=i=2HGL0`=~5Uv%>0$c)CxqbDh$cl_VY2--w}8cDE)9auim(=f+AAr zdyLU9M)EQ&BeOL|ojufZQNTOl>;{>$)l{goxjHi-K1?Rfnc#}Yc@wH6riVxYy)=m_ zd{4ivpbnWF`9ty#;T%jySd~^%k&tGRF!X+YPO4&MOFLqyA@eXxgc)o*61$Rt z-2^}^?=PvQ6Q!nUQsCk)*_Z~)b_`*d*8bdE3?$4H)!`mKw!kzJ{_&Jw-T>U0Wr_v4eHVj+(QDbSFs1Oz}5g z()TZ}`lU9bsEv@$2GZty6!hWG;*QP~phmdhEa;Mh>Bt~H4xC8_b{O+C^s0xaO7s&OkB0C7}Fw2CvM{GVo?#&I}qexh!|)&u||ZeDj}dJH&I89U!#w{V-C}d9o!m z1Q-GXy9l5~+NFF)@;H)W5CLr~s?Xq#R(gF5!Ua-@%7(u$jbTjwK_C93z%2vJUz%sD zR;{vi<2+AzV~OV`t0j1o=BT5NvcQyqFW0H_^UL#-O{;jb=O2OFH{X2IKHndF@PP%i zJh%BA?7GYwK>uj2v6R0twI*=enC?bXUz$eX*BgNbZpq%gK(MPY$4zIXmQ~XwO`Eg)i8<59e7tY( zUS^lin>b_f;Q2Gg4b1C!^zSNu*vjsYdrmy@)Sg4fPaid~--W+x-m>MmgZuY?=eq8y zJ4W7JHe&p=O?9g7-ulQQb_J=vYudthUR?M1>S%NWXRofEI_JKs{H7hTzC4&+plLE#A|>5^s94EKkLFi+IS;<*Gap$Pw0gPOs&t3@@r+)>Jrc} zNG0{;t{pQr`1gbjKghsz;W`To+Tyz#E7g?};argN>4w?FrExtEz(6GArtKJ`vAV7x zoNI`TMon+{0Eufj1=12C^K5#-^N*a3W9nKd@G_ND3yV8sd~2TvuE#x~S1B;B73T!f z>~ML^Tc8P4B-fps?t5HaY7qMfA)X7jLo0PFiPc?;C@<5>tm@i6u%2Jru>Hr@uG?%d zf@lt)UtzN#&V2=gH@S{{)t5K(d$&|mL@6@?1bkK)l=s_b**e+M3Lx{mUmwk2dvlc; zOPV4^$hpjJa};uA2YcU{u^13QbC##KKwaG4T%9)o*Zf^dv^&}jG~k|Wdd>Qr2o zx?gMfpg7M>=ek5=bc~UDDiS=)(M+7B%kISv(l%uvz~j$)-(cwg03ZNKL_t*jbc|jp zNIq8(!l(T{@t>U8>;T*9zXf8r>v?lSGE5I>euJ%0hx#Nnia=%!c zpPzDkX4V`$GZK+ZzK}%9D>nVe}!}m{Jf&x3S0h}Q7 zu_nA4ByKFsKAiu(xr)M?XaSO0%aKCq=XpnR2uN{iP4d7m^Q1tnJ(wogg(x#pYD^d@7nI2x!ifZLzv+_LPKfgv+Pe)c9We3>m`K+52f!Rx?* z1FbtNgG2_J{BO+QGF!`xE(2vYs$nLHYj+vsGU#NsiEClG@xq!}RtA*}Zg05ZhJP4| z!p2VQ4C_lcSuV`=waohRBAuCL|9G#y`l^+Cat$M!_i%q1__Ab^&&@!U>vEYTW0^Bc zteFjCAk6F*Gr8QZyz)v5dRf}ZMp`~FZwzrjys+O=O-0I>%Rq})wW-rW%IiI)pK9)8 zs3huH0Om`-q-0a2*GEXqjszVWMOIp+E*1dINKq9EEF{o}fMiBEBp>5?_-HltBxSAx zGRdsw&eHa+;K$9?`Wht6t5e1W&w0FSXSAgejkx_sfmlH_!hIM)XksfCs|i3mG{Lvpz9 zBwJQVSAjSjJHqcPuTa;KgnmLNN9NaO*>0|)i;dR51xG&nvt!QD1a47|dl!GUbAI6! z+cuZI*e;k;QJsic*(tZ;ZpX!5e*25P7x(VIr@U+<%ZqQk?v^`NkGyMY+wZ>ldfsi< zUwjMzJhAH0M{_op?s#D7{Hd1}b?bR`$%Zc(G<1FL^^eZa$?b4@uj4vj2>@IywHE*m zKK}e$_dfmj!)Lzr#*1}cGI=W3)U91}?}}YjRe7VP&Aro)2YT$ex5o9q_WVU1J9nA> z!?rE_4c~h7xO+|*GH%K-y?V4C-my!;{LerAh}qQQnTys8z3RIDS+`x=XUY2YAFg#A z=Z&ee@9i;t;&2A!oV?EFSw|N}j=ATt7v5}n+A(=ou(t|d)BL3m-hSl`1FsWc=7&Qm z5XWs(rFXYL%x!2kl#+zvWI<|KK~7fMoj0{eR*R+MJeuDYUx>!MGmXT)py5?NtI!@Z zWhhpV%oZbjuw>=9Ni_&j)M{-$D9TG^$8r>t0=*P8a`vkQhtU{aYf#rE1GRhk|?CfBu_9oAGRp$7^e1{`mNbKLhWfI>Zz!2GQ!6nMlxCfA39n=wNGY}v6% zEMg|FzIKxD*H?uhnXZ2{QM*ZUAZ^x=xuVC!L`~9B(2JYl+C$5eFuPBo6svX;CDqKnN}s(?~{agx+WMeq;qe$9a>!+%O3&o zN&x~%tEUkII}NH^UDx^2^VEryOg>iBF_pJ%%Oi@-Fd_=0ln-;3CuenP6xX={9L3MB zeIArqV^F+PR4)VfpC5L0S3;dFNYoLE50G>}WAuI}BfxdwDRZ^TeQi-RyH@~wSP*g^ zJp9?ZYY64drq&zfyMNo~Jnk(cg1wQPRAf?p-t+xPz=mX2hR&rD0!2SWp*8APBEi5{ zjRD;H*Y>~qlbu<4an0cO=jJl}Ixmpf$mW05_?o}}{(GpatF!K{^^4U1)yM3@oSkCx z^Yhc7n?J;^v&_iyxjS^|@RQ>)d(15C&tLzglkxi*46sC*0dd2|Of|D+ELHw@H){eE zSAzwZZJ_@aIT_bOe z4&44Tk%$r8c2(uy8KWglv%kPABMq5Zk(|K)u%E5)dZC~j z0mW;6WDmbyme3qO6mFr#XpZ+`)@kKS55{MNqQ&osDw{*6!n)W2^Zv48(Q{_!2LF_s+aAQoyvj~C|#tkZ&JM-|+1 z>AA;kE8V!kMkcjr(ek|qo_ML`q|?rdAKSUrO*J(KnR$Hf4==nsX7!4BBmVmSTb=ma z{N4*Mz2=L&ypH;j`XlrL5$Y3(x49W-@>O^cx?Yan^-P!XZpEKV_B4 z!6ZblmO(i<7gMg%962PwU8V`1EXr}xl29Lv0nnSgNaie331*0A=+oky1{trhWPb<6 zg-Xd`eiY2sJ#?h1GXtc6EYFzFA|cn-q}ohWqnApF(SmlqOx8PFYn<$moRpt~_C9Zn z*L8D1-c1P4HGFnTY~&BrHjK9^kJBJReP$iXJA4=4l!LV#tclha=QtKfvXq%XPY^D= zl;6fl*MgVE)pY=PED-&bO_i821f^#H(3ZlWv&gSewxA`cSpID=;LKq#!mR7>?#4 z#KS?C8F<^G)#@^%;W7c{Vcu9EqCi=dUWS0*7Y0*tGxjb^tyZ@g4d-Om$zh#3;U3GjOJ}t4^xq;4@>ok_-gJr3`XD%Wr_HzG zdW0rA-W779U(;FNr~cZ&E=OWMNbzB~9e!!=i6h2?2Y>L{Obft)atcGv2*2+@3LQMe~MmP%ce@ZEqk-cQ}pgz@97SO(%pS3qyxD6iegk zJ|X0ea5mcWr_9JQ27xvtWZ>O;=mRz*%R2>2kJjW+u3KcM|THNSXchE3o&>WVX{*@>Lv zu~=pCe`9L`xBoZZ)uwA|8iD^h0$37LYXX^azR$XC_>o!%YRpOmV)h{Y4YxU=Zqx>@ z5+*sSAg`HSv@?*ABo+yStHXJzfcNs<)XgOIJQA?Rcid&iR|ERaq&Dl1$qQIUg4^a; za)3e62SJYDA4$6yOz3gXuY2_DNuzGNn9c3@HFiNpt!IFSmm;ayl*w(|1y6hUsaNzB z7o2n{0Nlb}F91-;MAhFn?|JN*#~)oc|DG|dJF7eQ{7Z*?w*G@@Jx(}zC0{d>+>py|^WoJV^;L{`1d1 zdFqBsd$a6!dvTAR7a!QWXX#OG+UuzTjx#vkIog2t#@kn&j zcVgGhL>DF)Qe&d7LJ+sqLUK&^pwIfzQ5hL}1)}-5Fc`2bDmTuft#S2A1pGD}lJ{=e zL!FYf-gE=FsW{{;@!57OF(WY?j5nT{IsR00+Epb!Fn?Yqm`=$oBpA$g{@FxRzC zmz%a9=q{X$g{X05Vf$1b=;jLQsDxf9(Y#X-N*Rf8E3NeI2E^Py+%HG4+pzt7W!+U$ z$o|4pV+uNCTBm9TEJk~i0C7`c$XUjH-B59;V}_G4PaFN$hMB$A0UPK{5cnAzg~j94 z{70jv2!ueLIy9$2jWUDSyS33B1CBf0uNyCk>nQ?sb~xyA#EdoSvbnz!2NKfLzBv#_ z!3con;h>w&facm)qxDb(_)|maY3UB{Ty$_^hLICH<)YmbVL7vOB!lNieHPkYYh2GY z#$Y7(uoRpfv_ZmkMyV-9d6}hlKE>5_WWY5@T>zaYd;_qu1YHfJZ_(<|xZ?J$$}F%? zdiQ|9&4oc{A!2G%sI($EOgQ4?I;_2`TXu`Me@snqm6Y=CpE?_>tBnDafbBq-ufjq1 z(+%5e3o=}HHX^<58_bketJ_e+SuKpb-Oro0$BpUX2I&-Kyve?lo`GxzsJV!+H&VZe zz_C)o7)OI_=Llilw@WLNtQzUsOuHjGbV#`$bF)TqMlS~ee+g%&*i2Rs7&6022nojf z6N6RW=s*LWKs-8$`mbFZC>}N^)YVGCIYQ90?B-gsz3y1y%6Wq1GX*)R$e(CjF9RSa z+@NOMzRoVPAg%@y3Q)X7Mjwk3P7x%Rg>#S%?o!Wq%$p{pII5tX80U|DNyWa1kj<7D z&<_=bGSVAWsmx!|J6SDn^qKwAm^TAJw20)Svc}m10a}@XM9>D&eCA8x8%xfuf89-g z{^yK8Rg%8mJLVW|(Uq7~{gl5jh^`mS)B47*4yjU{g(!b@(t;_Meb|Lm`v|JdW4 zi!N<@%dI0v@7`JU?dUsh;2OMWD7VARF8PIh&%gMpwf9UK#*7@Zu)7MvU0*JbZtU~M zN8g@((HY%)0Ki2{)~uU!$>mo~>2-XkuGNV+15mCX+B0qLy|-U}ZU6I52p`$E9uyxT zrSsvU)oWi5<#c-XhRb?!J@I`daryv_S`rZW%+Vo-nV|Q>;ch3t{^8eW4I6ZAzpwts zr9S0xzS+&OjbeRnOIdDomHjyh^}B38*YwmX|Q zZ#DJ9ueTNtz4^-H|MuyJY|_NGp?lx^eDfo_ckbME^@S(1Je!TG?k}zM&H#ba1j=dQ zdRJm*iOS;oUV&H{4oL><=~fok%L&b{NYI`6_pNkfvrKO)0xEgPnd{dcT4N$l%?6Nm`i1)pDdEVyKRDJD%)ieP%&P@C0SgXN65AH@5O7;VH_T0y z$-zR1USj``!@}V<_3};c3=}v`>*Vy}yk?f|w^_bmrjRlF#ld|G_`Mt>q-wmmBrsmo zpcb6RL?B#l0Kf60nWAw$+7R{7Ah&*rhP&@IAI|OQqLaNqMJG`rd+i8Mt*3Hjt-@T1#+V3+JTj-pi}$ zY^~K44bJ4QAzZ(qidqDWngs^Ht#j`2rNGf$bPXu#hlrDW5W95`otdoF!w}69u21&Q zA5C}{0AMx{1b}R$$NL+q4uk@fHQ#8>HKA4}%udHrh(Q8yjPJnAucxwX;kQ6?ZbQ(= z^}vYGJToaKGiZ&*=~6OY9!eQ>j97bg4sI)}sQdred-Lcxife!T-m31AykIsm$ zkY+|QW(^^PKuB1_79as9>^m6myA8H6#>O@n?`98Q0)ZrttnX!gdC5yc^0GZhSd1-c zB(vDk%t*EYZ<40#-updOJv|!dd(Q8K_YxrIr~XHFpYE>iTh%>v>wcCiMXAdJ?M)n8 zjV=MVo1F~rB3e^~vOA)eO_qlM-^2>4mB>pCaqs)hox$gP4P%JZe$?uf=sgMhD>zRW zFF_^Ww+W(6mII*;Lhx^q(s*mGFd0A{&stBj6Z)uq=dY~!7GUmC==};14iexm0;?yJ z2`teCTJtnsKu+!J)l(yFfe@a3@WTT1%XA_Z8ni}UwgQ*$H-#z37wx86x(XAK)Je&N zwjy-SX00gPb0Px1nk;f2i}Ma+ z-@SS~UC$tIDnM&fRvFmZrU5U!YKv81u^he9$6EL1%-;Ic$)-#Z+b+`3O6}8 z>|bxkAOG=BrH(#!P4nxo`metH-yZ`2TM50;9(UeFUwHjLfA+(=pirnx3*e8-QxkkR)`%R4-sD!5nFY(RwM8J`o%XNKI5d(mV0W& zrtZ3b{Zr>&HtyO5Nbp3mu3wy{wJTWSCJu4mCd;L*t&5hja7DD=`LTl3D^pmU95L7_ zo^0E(zpjU3>q+3-O$qNC(aBa7Qvgr4klu6|bh#xT%uu4n9HP~9YcJ%gxZU&^8{V9* zjjgfgTYHq_^1KugRH0feED0UCN~F53udguUm?F=#$OT@-fKNoet-sqQgAVu1Jk)SV zFMI2bP2kp0tjR0}R0kE*&V^&EtM}TrEW{ec+@wLaa@>E^+U~UG%vFGRjuN#h@@;iv zYNr_o0bXptJYW@+-FWUYmwTeF@uYA1=)@pr(c-GxJ;8lS!5>qJ*ao|=EpIMkfg5`u zn0j3Cxb3^;@Sa|{SJ-5eac^0)P~*7BY&MFLe@n+>PJG2ep~29D2)d=AY@sNVE8HZY z&-N?Sgvh(KwX?4YwZFvE__ZU4hfs9u*$b>rw3f+;>i6|k=q!`$^DCzNS?l%bqVL}UU(k&^ECjqkmQrK{=Zwh zsl7cgpUAvpMT}hASvgrLSuTW&Q?>mn#?~VjG+ys}dc%>!v6L{k<;C)W(`@$7vy)}Z zn+8vvfB=<1<_F1|ip`b_E*fWXuU_0ZDttyark)pl!e?P67_%o?(+?ZB{Q-lO4NlIoil9 z+tPIZC$;|hH5Jg7c57_kre2umXczrA4bfD+*f$UacHgh8U;7S ze1D5Ee7pkwt%y3=S_mcUVt>hW%NfGlNG5p0)85EuAJI=;Gm*Z?1pBno?}|`Ug#2pX zCQ0M-y$JC8a&3bTFB1QsEe|BOAJLBad)(GQa{Kp);=nZqBJk0VK$%)HEfA6FbWJ~p zZqr+RV`3Hl0}Amg4RQQ_Y0{XZH7NXEvN-82PR1VqQGE>w?God#3e0yR$PrxVTO0|y zIGB@|wW#@-WOc>2!wF*HI25%AQ694%mr*+{d0HeyhYbV&&Itb4nhTZ!s)|Cjnja-m z3zn=o^Yd3+b@Q-85C2JH+_TrL+$6H!yz%a;7ytNQaLbh!-DmA#UD9EpuR_b)GtEE0 z;PkOB$;|AOF=A*cGQXUxiP_|p?D?_0S&0bNck|xpo^0i6)1UuzPDkh4ZBuXgvYQ}V z)!AM@c&L4A>z^(-ZLCd>=%@er`q2i14e6$_>x$6TDw|lhY!9aH+xOnF%NI;r{;h94 z>!7DCS(=0(A7f8Xi7H27PYN|Z?<#<^R&Vv-tBmK z%1I}k6ts4k8-e%?-}hG>IUJqck`;9_gZLp)@N&7rs}pNdaGny`-fjG^S}$K0mz>

  • {{ label }}
  • diff --git a/client/src/app/search/components/graph-search.component.ts b/client/src/app/search/components/graph-search.component.ts index a710d77e8e..67900606ce 100644 --- a/client/src/app/search/components/graph-search.component.ts +++ b/client/src/app/search/components/graph-search.component.ts @@ -79,7 +79,7 @@ export class GraphSearchComponent implements OnInit, OnDestroy, ModuleAwareCompo map( (legend) => // Keys of the result dict are all lowercase, need to change the first character - // to uppercase to match Neo4j labels + // to uppercase to match ArangoDB labels new Map(Object.entries(legend).map(([label, { color }]) => [label, color])) ), startWith(new Map()) diff --git a/client/src/app/shortest-path/components/route-builder.component.html b/client/src/app/shortest-path/components/route-builder.component.html deleted file mode 100644 index ab0280681e..0000000000 --- a/client/src/app/shortest-path/components/route-builder.component.html +++ /dev/null @@ -1,47 +0,0 @@ -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    - -
    -

    Loading pre-defined queries...

    -
    -
    -
    - - -
    -

    Could not load pre-defined shortest path queries!

    -
    -
    - - -
    -
    -
    -
    diff --git a/client/src/app/shortest-path/components/route-builder.component.scss b/client/src/app/shortest-path/components/route-builder.component.scss deleted file mode 100644 index 357cdccf59..0000000000 --- a/client/src/app/shortest-path/components/route-builder.component.scss +++ /dev/null @@ -1,27 +0,0 @@ -.graph-type-btn-container { - height: 40px; - width: 40px; -} - -.route-builder-container-open { - position: absolute; - width: 400px; - right: 0; - z-index: 2; - transition: right .25s; -} - -.route-builder-container-closed { - position: absolute; - width: 400px; - right: -400px; - z-index: 2; - transition: right .25s; -} - -.toggle-route-builder-button { - height: 60px; - top: 28px; - right: 100%; - position: absolute; -} diff --git a/client/src/app/shortest-path/components/route-builder.component.spec.ts b/client/src/app/shortest-path/components/route-builder.component.spec.ts deleted file mode 100644 index a7884c15cd..0000000000 --- a/client/src/app/shortest-path/components/route-builder.component.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { configureTestSuite } from 'ng-bullet'; - -import { RootStoreModule } from 'app/root-store'; -import { SharedModule } from 'app/shared/shared.module'; - -import { RouteBuilderComponent } from './route-builder.component'; - -describe('RouteBuilderComponent', () => { - let component: RouteBuilderComponent; - let fixture: ComponentFixture; - - configureTestSuite(() => { - TestBed.configureTestingModule({ - imports: [ - RootStoreModule, - SharedModule - ], - declarations: [ RouteBuilderComponent ] - }); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(RouteBuilderComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/client/src/app/shortest-path/components/route-builder.component.ts b/client/src/app/shortest-path/components/route-builder.component.ts deleted file mode 100644 index 22c02806a9..0000000000 --- a/client/src/app/shortest-path/components/route-builder.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core'; - -import { combineLatest, Subscription } from 'rxjs'; - -import { BackgroundTask } from 'app/shared/rxjs/background-task'; - -import { ShortestPathService } from '../services/shortest-path.service'; -import { DisplayType } from './route-display.component'; - -@Component({ - selector: 'app-route-builder', - templateUrl: './route-builder.component.html', - styleUrls: ['./route-builder.component.scss'] -}) -export class RouteBuilderComponent implements OnInit, OnDestroy { - @Output() loadNewQuery: EventEmitter; - @Output() changeDisplayType: EventEmitter; - - loadShortestPathQueries: BackgroundTask<[], any>; - queriesLoadedsub: Subscription; - - routeBuilderContainerClass: string; - - routeBuilderOpen: boolean; - - queries: string[][]; - - constructor( - public shortestPathService: ShortestPathService, - ) { - this.queries = []; - - this.routeBuilderContainerClass = 'route-builder-container-open'; - this.routeBuilderOpen = true; - - this.loadNewQuery = new EventEmitter(); - this.changeDisplayType = new EventEmitter(); - - this.loadShortestPathQueries = new BackgroundTask(() => { - return combineLatest( - this.shortestPathService.getShortestPathQueryList(), - ); - }); - this.queriesLoadedsub = this.loadShortestPathQueries.results$.subscribe(({ - result: [shortestPathQueries], - value: [], - }) => { - this.queries = Object.keys(shortestPathQueries).map(key => [key, shortestPathQueries[key]]); - }); - } - - ngOnInit() { - this.loadNewQuery.emit(0); - this.changeDisplayType.emit('NETWORK'); - this.loadShortestPathQueries.update([]); - } - - ngOnDestroy() { - this.queriesLoadedsub.unsubscribe(); - } - - toggleRouteBuilderOpen() { - this.routeBuilderOpen = !this.routeBuilderOpen; - this.routeBuilderContainerClass = this.routeBuilderOpen ? 'route-builder-container-open' : 'route-builder-container-closed'; - } - - requestQueryLoadFromParent(event: any) { - this.loadNewQuery.emit(Number.parseInt(event.target.value, 10)); - } - - requestChangeDisplayTypeFromParent(type: string) { - this.changeDisplayType.emit(type); - } -} diff --git a/client/src/app/shortest-path/components/route-display.component.html b/client/src/app/shortest-path/components/route-display.component.html deleted file mode 100644 index f0ba2043ec..0000000000 --- a/client/src/app/shortest-path/components/route-display.component.html +++ /dev/null @@ -1,18 +0,0 @@ -
    -
    -
    - -
    -
    - -
    -
    -
    diff --git a/client/src/app/shortest-path/components/route-display.component.scss b/client/src/app/shortest-path/components/route-display.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/client/src/app/shortest-path/components/route-display.component.spec.ts b/client/src/app/shortest-path/components/route-display.component.spec.ts deleted file mode 100644 index e04e8f259d..0000000000 --- a/client/src/app/shortest-path/components/route-display.component.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { configureTestSuite } from 'ng-bullet'; -import { MockComponents } from 'ng-mocks'; - -import { PlotlySankeyDiagramComponent } from 'app/shared/components/plotly-sankey-diagram/plotly-sankey-diagram.component'; -import { VisJsNetworkComponent } from 'app/shared/components/vis-js-network/vis-js-network.component'; - -import { RouteDisplayComponent } from './route-display.component'; - -describe('RouteDisplayComponent', () => { - let component: RouteDisplayComponent; - let fixture: ComponentFixture; - - configureTestSuite(() => { - TestBed.configureTestingModule({ - declarations: [ - RouteDisplayComponent, - MockComponents( - PlotlySankeyDiagramComponent, - VisJsNetworkComponent - ) - ] - }); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(RouteDisplayComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/client/src/app/shortest-path/components/route-display.component.ts b/client/src/app/shortest-path/components/route-display.component.ts deleted file mode 100644 index 43a68748ee..0000000000 --- a/client/src/app/shortest-path/components/route-display.component.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { isNil } from 'lodash-es'; -import { Options } from 'vis-network'; - -import { GraphData } from 'app/interfaces/vis-js.interface'; - -export enum DisplayType { - NETWORK = 'network', - SANKEY = 'sankey' -} - -@Component({ - selector: 'app-route-display', - templateUrl: './route-display.component.html', - styleUrls: ['./route-display.component.scss'] -}) -export class RouteDisplayComponent { - @Input() set displayType(displayType: DisplayType) { - this.currentDisplay = DisplayType[displayType]; - } - @Input() set graphData(graphData: GraphData) { - // Update vis js data - this.networkData = graphData; - - // Update sankey data - this.generateSankeyData(graphData.nodes, graphData.edges); - - // Update legend - this.setupLegend(graphData.nodes); - } - - currentDisplay: string; - - networkConfig: Options; - networkData: GraphData; - - sankeyConfig: any; - sankeyData: any; - - legend: Map; - - constructor() { - this.initVisJsSettings(); - this.initPlotlySankeySettings(); - this.legend = new Map(); - } - - initVisJsSettings() { - // Init vis js network settings - this.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, - }, - }, - }; - - this.networkData = { - nodes: [], - edges: [], - }; - } - - generateSankeyData(nodes: any[], edges: any[]) { - const source = []; - const target = []; - const value = []; - const label = []; - const color = []; - - const nodeIdentityMap = new Map(); - nodes.forEach((node, i) => { - nodeIdentityMap.set(node.id, i); - label.push(node.label); - color.push(node.color.border); - }); - - const seenEdges = new Map(); - edges.forEach(edge => { - const sankeyEdge = [nodeIdentityMap.get(edge.from), nodeIdentityMap.get(edge.to)]; - if (seenEdges.has(sankeyEdge.toString())) { - value[seenEdges.get(sankeyEdge.toString())] += 1; - } else { - source.push(sankeyEdge[0]); - target.push(sankeyEdge[1]); - value.push(1); - seenEdges.set(sankeyEdge.toString(), value.length - 1); - } - }); - - this.sankeyData = { - type: 'sankey', - orientation: 'h', - node: { - arrangement: 'snap', - pad: 15, - thickness: 20, - line: { - color: 'black', - width: 0.5 - }, - label, - color, - }, - - link: { - source, - target, - value - } - }; - } - - initPlotlySankeySettings() { - // Init plotly sankey settings - this.sankeyData = { - type: 'sankey', - orientation: 'h', - node: { - arrangement: 'snap', - pad: 15, - thickness: 20, - line: { - color: 'black', - width: 0.5 - }, - label: [], - color: [], - }, - - link: { - source: [], - target: [], - value: [] - } - }; - - this.sankeyConfig = { - font: { - size: 10 - } - }; - } - - /** - * Given a list of input nodes, generates a Map object representing a node legend. Keys are the label of the nodes, and values are a list - * of colors representing the border and background of the node. - * @param nodes list of node objects - */ - setupLegend(nodes: any) { - nodes.forEach((node) => { - if (!isNil(node.databaseLabel)) { - if (!this.legend.has(node.databaseLabel)) { - this.legend.set(node.databaseLabel, [node.color.border, node.color.background]); - } - } - }); - } - -} diff --git a/client/src/app/shortest-path/containers/route-search.component.html b/client/src/app/shortest-path/containers/route-search.component.html deleted file mode 100644 index 542f90ab00..0000000000 --- a/client/src/app/shortest-path/containers/route-search.component.html +++ /dev/null @@ -1 +0,0 @@ -

    route-search works!

    diff --git a/client/src/app/shortest-path/containers/route-search.component.scss b/client/src/app/shortest-path/containers/route-search.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/client/src/app/shortest-path/containers/route-search.component.spec.ts b/client/src/app/shortest-path/containers/route-search.component.spec.ts deleted file mode 100644 index 7a5354fab2..0000000000 --- a/client/src/app/shortest-path/containers/route-search.component.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { configureTestSuite } from 'ng-bullet'; - -import { RootStoreModule } from 'app/root-store'; - -import { RouteSearchComponent } from './route-search.component'; - -describe('RouteSearchComponent', () => { - let component: RouteSearchComponent; - let fixture: ComponentFixture; - - configureTestSuite(() => { - TestBed.configureTestingModule({ - imports: [ - RootStoreModule - ], - declarations: [ RouteSearchComponent ] - }); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(RouteSearchComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/client/src/app/shortest-path/containers/route-search.component.ts b/client/src/app/shortest-path/containers/route-search.component.ts deleted file mode 100644 index 10d8fa3313..0000000000 --- a/client/src/app/shortest-path/containers/route-search.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-route-search', - templateUrl: './route-search.component.html', - styleUrls: ['./route-search.component.scss'] -}) -export class RouteSearchComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - -} diff --git a/client/src/app/shortest-path/containers/shortest-path.component.html b/client/src/app/shortest-path/containers/shortest-path.component.html deleted file mode 100644 index 58514a26c1..0000000000 --- a/client/src/app/shortest-path/containers/shortest-path.component.html +++ /dev/null @@ -1,20 +0,0 @@ -
    - -
    - -
    - - - -
    - -
    -
    -
    diff --git a/client/src/app/shortest-path/containers/shortest-path.component.scss b/client/src/app/shortest-path/containers/shortest-path.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/client/src/app/shortest-path/containers/shortest-path.component.spec.ts b/client/src/app/shortest-path/containers/shortest-path.component.spec.ts deleted file mode 100644 index 01988d548c..0000000000 --- a/client/src/app/shortest-path/containers/shortest-path.component.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { configureTestSuite } from 'ng-bullet'; -import { MockComponents } from 'ng-mocks'; - -import { RootStoreModule } from 'app/root-store'; -import { SharedModule } from 'app/shared/shared.module'; - -import { RouteBuilderComponent } from '../components/route-builder.component'; -import { RouteDisplayComponent } from '../components/route-display.component'; -import { ShortestPathComponent } from './shortest-path.component'; - -describe('ShortestPathComponent', () => { - let component: ShortestPathComponent; - let fixture: ComponentFixture; - - configureTestSuite(() => { - TestBed.configureTestingModule({ - imports: [ - RootStoreModule, - SharedModule, - ], - declarations: [ - ShortestPathComponent, - MockComponents( - RouteBuilderComponent, - RouteDisplayComponent, - ), - ] - }); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(ShortestPathComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/client/src/app/shortest-path/containers/shortest-path.component.ts b/client/src/app/shortest-path/containers/shortest-path.component.ts deleted file mode 100644 index 9fa38e6a88..0000000000 --- a/client/src/app/shortest-path/containers/shortest-path.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, OnDestroy } from '@angular/core'; - -import { combineLatest, Subscription } from 'rxjs'; - -import { GraphData } from 'app/interfaces/vis-js.interface'; -import { BackgroundTask } from 'app/shared/rxjs/background-task'; - -import { ShortestPathService } from '../services/shortest-path.service'; - - -@Component({ - selector: 'app-shortest-path', - templateUrl: './shortest-path.component.html', - styleUrls: ['./shortest-path.component.scss'] -}) -export class ShortestPathComponent implements OnDestroy { - - loadTask: BackgroundTask<[], any>; - shortestPathLoadedSub: Subscription; - - loadedQuery: number; - displayType: string; - graphData: GraphData; - - constructor( - public shortestPathService: ShortestPathService, - ) { - this.loadTask = new BackgroundTask(() => { - return combineLatest( - this.shortestPathService.getShortestPathQueryResult(this.loadedQuery), - ); - }); - this.shortestPathLoadedSub = this.loadTask.results$.subscribe(({ - result: [shortestPathResult], - value: [], - }) => { - this.graphData = { - nodes: shortestPathResult.nodes, - edges: shortestPathResult.edges, - }; - }); - } - - ngOnDestroy() { - this.shortestPathLoadedSub.unsubscribe(); - } - - changeDisplayType(type: string) { - this.displayType = type; - } - - loadNewQuery(query: number) { - this.graphData = null; - this.loadedQuery = query; - this.loadTask.update([]); - } -} diff --git a/client/src/app/shortest-path/services/shortest-path.service.ts b/client/src/app/shortest-path/services/shortest-path.service.ts deleted file mode 100644 index 84a4ba0337..0000000000 --- a/client/src/app/shortest-path/services/shortest-path.service.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; - -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; - -import { AuthenticationService } from 'app/auth/services/authentication.service'; -import { AbstractService } from 'app/shared/services/abstract-service'; - -@Injectable({ - providedIn: 'root' -}) -export class ShortestPathService extends AbstractService { - readonly kgAPI = '/api/knowledge-graph'; - - constructor(auth: AuthenticationService, http: HttpClient) { - super(auth, http); - } - - getShortestPathQueryResult(queryId: number): Observable { - return this.http.get<{result: any}>( - `${this.kgAPI}/shortest-path-query/${queryId}`, { - ...this.getHttpOptions(true), - } - ).pipe( - map((resp: any) => resp.result), - ); - } - - getShortestPathQueryList(): Observable { - return this.http.get<{result: Map}>( - `${this.kgAPI}/shortest-path-query-list`, { - ...this.getHttpOptions(true), - } - ).pipe( - map((resp: any) => resp.result), - ); - } -} diff --git a/client/src/app/shortest-path/shortest-path.module.ts b/client/src/app/shortest-path/shortest-path.module.ts deleted file mode 100644 index 13801d1634..0000000000 --- a/client/src/app/shortest-path/shortest-path.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { SharedModule } from 'app/shared/shared.module'; - -import { ShortestPathComponent } from './containers/shortest-path.component'; -import { RouteSearchComponent } from './containers/route-search.component'; -import { RouteBuilderComponent } from './components/route-builder.component'; -import { RouteDisplayComponent } from './components/route-display.component'; - -const components = [ - ShortestPathComponent, - RouteSearchComponent, - RouteBuilderComponent, - RouteDisplayComponent, -]; - -@NgModule({ - declarations: [...components], - imports: [ - CommonModule, - SharedModule, - ] -}) -export class ShortestPathModule { } diff --git a/deployment b/deployment deleted file mode 160000 index 0f1943080f..0000000000 --- a/deployment +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0f1943080f4dd462a64535248e2f63ede809faa2 diff --git a/docker-compose.ci-test.yml b/docker-compose.ci-test.yml index dec5adbd8c..2a85d2aae5 100644 --- a/docker-compose.ci-test.yml +++ b/docker-compose.ci-test.yml @@ -2,11 +2,11 @@ version: "3.8" x-appserver: &appserver + build: + context: appserver + dockerfile: Dockerfile image: lifelike.azurecr.io/kg-appserver:${GITHUB_HASH} environment: - - NEO4J_HOST=neo4j - - NEO4J_AUTH=neo4j/password - - NEO4J_PORT=7687 - FLASK_DEBUG=1 - FLASK_ENV=development - FLASK_APP=app @@ -33,7 +33,6 @@ x-appserver: &appserver depends_on: - postgres - elasticsearch - - neo4j - redis - arangodb @@ -52,13 +51,6 @@ services: environment: - POSTGRES_PASSWORD=postgres - neo4j: - image: neo4j:4.4-community - restart: on-failure - environment: - - NEO4J_AUTH=neo4j/password - - NEO4JLABS_PLUGINS=["apoc", "n10s"] - elasticsearch: image: ghcr.io/sbrg/lifelike-elasticsearch:latest restart: on-failure diff --git a/docker-compose.override.yml b/docker-compose.override.yml index ca4ec289d8..2df05883fb 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -2,8 +2,6 @@ version: "3.8" x-appserver: &appserver build: ./appserver - env_file: - - azure-secrets.env environment: # Log Services - FORMAT_AS_JSON=false diff --git a/docker/Makefile b/docker/Makefile index 1ca4de303e..44cc20abe2 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -3,7 +3,7 @@ DOCKER_REGISTRY:=us.gcr.io/able-goods-221820 # Base Docker Compose command -------------------------------------------------- # docker-compose.yml -> Base services containers -# docker-compose.services.yml -> Third party services (PostgreSQL, Neo4j, Elasticsearch, Redis) +# docker-compose.services.yml -> Third party services (PostgreSQL, ArangoDB, Elasticsearch, Redis) # docker-compose.dev.yml -> Override base services for local development COMPOSE_COMMAND=docker-compose -p lifelike \ -f ${DOCKER_DIR}/docker-compose.yml \ diff --git a/docker/README.md b/docker/README.md index 0296ad16ba..bc35a8cf69 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,3 +1,5 @@ + + # Getting Started with Lifelike using Docker Docker is an easy way to get started with Lifelike. @@ -50,7 +52,7 @@ The stack definition is divided into three Docker Compose files: ```tree ├── docker-compose.yml --> Base core services ├── docker-compose.dev.yml --> Overrides base core services for local development and debugging. -└── docker-compose.services.yml --> Adds third party services (PostgreSQL, Neo4j, Elasticsearch, Redis) +└── docker-compose.services.yml --> Adds third party services (PostgreSQL, ArangoDB, Elasticsearch, Redis) ``` You may combine them as you need and/or add your own `docker-compose.override.yml` to override any configuration. (this file will be ignored by Git) diff --git a/docker/diagram.svg b/docker/diagram.svg index e9b292e909..e3ddfdb2bf 100644 --- a/docker/diagram.svg +++ b/docker/diagram.svg @@ -3,7 +3,7 @@ entity appserver-->cache-invalidatorelasticsearchfrontendneo4jarangodbpdfparserpostgresredisdepends ondepends ondepends ondepends ondepends ondepends ondepends ondepends ondepends ondepends on \ No newline at end of file +--> diff --git a/docker/docker-compose.services.yml b/docker/docker-compose.services.yml index 1b18dcbfbf..ceae580e7c 100644 --- a/docker/docker-compose.services.yml +++ b/docker/docker-compose.services.yml @@ -5,7 +5,7 @@ version: "3.8" services: # PostgreSQL database postgres: - image: postgres:13 + image: postgres:11 restart: unless-stopped container_name: postgres environment: @@ -18,45 +18,52 @@ services: test: ["CMD", "pg_isready", "-U", "postgres", "-q"] start_period: 10s - ## Neo4j graph database - neo4j: - image: neo4j:4.4-community - restart: unless-stopped - container_name: neo4j + ## ArangoDB graph database + arangodb: + build: + # Note that this Dockerfile simply adds a user directory and installs the helper scripts into it, and then executes the default arango + # entrypoint as normal. + context: ../arangodb + dockerfile: Dockerfile + container_name: arangodb environment: - - NEO4J_AUTH=neo4j/password - - NEO4JLABS_PLUGINS=["apoc"] + ARANGO_ROOT_PASSWORD: password + LIFELIKE_DB_NAME: lifelike ports: - - 7687:7687 - - 7474:7474 + - 8529:8529 volumes: - - neo4j:/var/lib/neo4j/data - healthcheck: - test: ["CMD", "wget", "localhost:7474", "-O", "-"] - start_period: 1m + - ../arangodb/bin:/home/dbuser/bin # the /home/dbuser directory is setup in the Dockerfile + - ../arangodb/data:/var/lib/arangodb3 + - ../arangodb/apps:/var/lib/arangodb3-apps ## Ekasticsearch search engine elasticsearch: - image: ghcr.io/sbrg/lifelike-elasticsearch:7.16.3 - restart: unless-stopped container_name: elasticsearch + build: + dockerfile: Dockerfile + context: ../elasticsearch environment: - discovery.type=single-node + - http.max_content_length=200mb #allow 200mb of content to be sent for indexing - bootstrap.memory_lock=true - ports: - - 9200 + - xpack.graph.enabled=false + - xpack.watcher.enabled=false + - xpack.license.self_generated.type=basic volumes: - - elasticsearch:/usr/share/elasticsearch/data + - ../elasticsearch:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 + ports: + - "9200:9200" + - "9300:9300" healthcheck: test: ["CMD", "curl", "-f", "localhost:9200/_cluster/health"] start_period: 1m redis: - image: redis:alpine + image: redis:6-alpine restart: unless-stopped container_name: redis ports: @@ -68,34 +75,43 @@ services: environment: - POSTGRES_HOST=postgres - POSTGRES_PASSWORD=postgres - - NEO4J_HOST=neo4j - - NEO4J_AUTH=neo4j/password + # Arango + - ARANGO_HOST=http://arangodb:8529 + - ARANGO_USERNAME=root + - ARANGO_PASSWORD=password + - ARANGO_DB_NAME=lifelike - ELASTICSEARCH_URL=http://elasticsearch:9200 - REDIS_HOST=redis depends_on: - postgres - - neo4j + - arangodb - elasticsearch statistical-enrichment: environment: - - NEO4J_HOST=neo4j - - NEO4J_AUTH=neo4j/password + # Arango + - ARANGO_HOST=http://arangodb:8529 + - ARANGO_USERNAME=root + - ARANGO_PASSWORD=password + - ARANGO_DB_NAME=lifelike - REDIS_HOST=redis depends_on: - - neo4j + - arangodb - redis cache-invalidator: environment: - - NEO4J_HOST=neo4j - - NEO4J_AUTH=neo4j/password + # Arango + - ARANGO_HOST=http://arangodb:8529 + - ARANGO_USERNAME=root + - ARANGO_PASSWORD=password + - ARANGO_DB_NAME=lifelike - REDIS_HOST=redis depends_on: - - neo4j + - arangodb - redis volumes: postgres: - neo4j: + arangodb: elasticsearch: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 556013ab1b..48dd0de11d 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -3,7 +3,9 @@ version: "3.8" services: ## Frontend web server frontend: - image: ghcr.io/sbrg/lifelike-frontend:${FRONTEND_IMAGE_TAG:-latest} + build: + context: ../client + dockerfile: Dockerfile restart: unless-stopped container_name: frontend environment: @@ -15,7 +17,9 @@ services: ## Backend application server appserver: - image: ghcr.io/sbrg/lifelike-appserver:${APPSERVER_IMAGE_TAG:-latest} + build: + context: ../appserver + dockerfile: Dockerfile restart: unless-stopped container_name: appserver ports: @@ -43,7 +47,9 @@ services: ## Statistical enrichment service statistical-enrichment: - image: ghcr.io/sbrg/lifelike-statistical-enrichment:${STATISTICAL_ENRICHMENT_IMAGE_TAG:-latest} + build: + context: ../statistical-enrichment + dockerfile: Dockerfile restart: unless-stopped container_name: statistical-enrichment ports: @@ -51,7 +57,9 @@ services: # Cache invalidator service cache-invalidator: - image: ghcr.io/sbrg/lifelike-cache-invalidator:${CACHE_INVALIDATOR_IMAGE_TAG:-latest} + build: + context: ../cache-invalidator + dockerfile: Dockerfile restart: unless-stopped container_name: cache-invalidator diff --git a/docs/wiki/development/general-introduction.md b/docs/wiki/development/general-introduction.md index 919c4609ec..d64d279805 100644 --- a/docs/wiki/development/general-introduction.md +++ b/docs/wiki/development/general-introduction.md @@ -101,7 +101,7 @@ For `$container_name`, you have a choice of: docker compose exec pgdatabase psql -U postgres -h pgdatabase -d postgres ``` -### Neo4j +### ArangoDB ```sh docker compose exec database cypher-shell -u neo4j diff --git a/docs/wiki/elk/introduction.md b/docs/wiki/elk/introduction.md index 05f64707f0..901a30c5c2 100644 --- a/docs/wiki/elk/introduction.md +++ b/docs/wiki/elk/introduction.md @@ -7,8 +7,6 @@ - To seed LMDB data to Kibana: ```bash -./deployment/kibana.sh -a None -# or docker compose exec appserver python neo4japp/services/annotations/index_annotations.py -a ``` diff --git a/graph-db/docker-compose.yml b/graph-db/docker-compose.yml index 04adee3783..ca11a7fb66 100644 --- a/graph-db/docker-compose.yml +++ b/graph-db/docker-compose.yml @@ -1,25 +1,27 @@ version: "3.8" +# Hasn't been migrated to Arango - not working + services: - neo4j: - image: neo4j:4.4-community + arangodb: + image: arangodb:4.4-community restart: on-failure environment: - - NEO4J_AUTH=neo4j/password - - NEO4JLABS_PLUGINS=["apoc"] - - NEO4J_dbms.unmanaged_extension_classes=n10s.endpoint=/rdf # for the neosemantics-4.3.0.0.jar + - ARANGODB_AUTH=arangodb/password + - ARANGODBLABS_PLUGINS=["apoc"] + - ARANGODB_dbms.unmanaged_extension_classes=n10s.endpoint=/rdf # for the neosemantics-4.3.0.0.jar ports: - 7687:7687 - 7474:7474 volumes: - - neo4j:/var/lib/neo4j/data + - arangodb:/var/lib/arangodb/data migrator: build: context: migrator environment: - - NEO4J_HOST=neo4j - - NEO4J_PASSWORD=password + - ARANGODB_HOST=arangodb + - ARANGODB_PASSWORD=password - CHANGELOG_FILE=lifelike-graph/changelog-master.xml - DATAFILES_PREFIX=stage - LOG_LEVEL=debug @@ -29,9 +31,9 @@ services: - ./changelog:/liquibase/changelog - ./tmp:/tmp depends_on: - - neo4j + - arangodb links: - - neo4j + - arangodb volumes: - neo4j: {} + arangodb: {} diff --git a/graph-db/docs/reactome/Reactome GDS.ipynb b/graph-db/docs/reactome/Reactome GDS.ipynb index 71a35cdb79..e0ced77a15 100644 --- a/graph-db/docs/reactome/Reactome GDS.ipynb +++ b/graph-db/docs/reactome/Reactome GDS.ipynb @@ -92,9 +92,9 @@ "source": [ "load_dotenv() # These params are set in .env file\n", "\n", - "URI = os.getenv(\"NEO4J_URI\")\n", - "AUTH = (os.getenv(\"NEO4J_USER\"), os.getenv(\"NEO4J_PASSWORD\"))\n", - "DATABASE = os.getenv(\"NEO4J_DATABASE\")\n", + "URI = os.getenv(\"ARANGODB_URI\")\n", + "AUTH = (os.getenv(\"ARANGODB_USER\"), os.getenv(\"ARANGODB_PASSWORD\"))\n", + "DATABASE = os.getenv(\"ARANGODB_DATABASE\")\n", "\n", "driver = GraphDatabase.driver(URI, auth=AUTH)\n", "with driver as session:\n", diff --git a/graph-db/migrator/Dockerfile b/graph-db/migrator/Dockerfile index 2f15ee818e..0348bc17b9 100644 --- a/graph-db/migrator/Dockerfile +++ b/graph-db/migrator/Dockerfile @@ -20,23 +20,23 @@ RUN mvn -B clean package -DskipTests FROM liquibase/liquibase:$LIQUIBASE_IMAGE_TAG LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike -ARG LIQUIBASE_NEO4J_VERSION=4.7.1.3 -ARG NEO4J_JDBC_VERSION=4.0.5 +ARG LIQUIBASE_ARANGODB_VERSION=4.7.1.3 +ARG ARANGODB_JDBC_VERSION=4.0.5 -# Install liquibase-neo4j extension -RUN lpm update && lpm add --global liquibase-neo4j@$LIQUIBASE_NEO4J_VERSION +# Install liquibase-arangodb extension +RUN lpm update && lpm add --global liquibase-arangodb@$LIQUIBASE_ARANGODB_VERSION -# Download Neo4j JDBC driver -ADD --chown=liquibase:liquibase https://github.com/neo4j-contrib/neo4j-jdbc/releases/download/${NEO4J_JDBC_VERSION}/neo4j-jdbc-driver-${NEO4J_JDBC_VERSION}.jar lib/ +# Download ArangoDB JDBC driver +ADD --chown=liquibase:liquibase https://github.com/arangodb-contrib/arangodb-jdbc/releases/download/${ARANGODB_JDBC_VERSION}/arangodb-jdbc-driver-${ARANGODB_JDBC_VERSION}.jar lib/ # Copy JAR from build stage COPY --from=build --chown=liquibase:liquibase /target/graphdb-migrator-*.jar ./lib -# Neo4j database configuration -ENV NEO4J_HOST= -ENV NEO4J_USERNAME=neo4j -ENV NEO4J_PASSWORD=neo4j -ENV NEO4J_DATABASE=neo4j +# ArangoDB database configuration +ENV ARANGODB_HOST= +ENV ARANGODB_USERNAME=arangodb +ENV ARANGODB_PASSWORD=arangodb +ENV ARANGODB_DATABASE=arangodb # Master changelog file. e.g. lifelike-graph/changelog-master.xml ENV CHANGELOG_FILE= diff --git a/graph-db/migrator/README.md b/graph-db/migrator/README.md index 2e019af219..edcdb210c6 100644 --- a/graph-db/migrator/README.md +++ b/graph-db/migrator/README.md @@ -1,6 +1,8 @@ +# Legacy - not used anymore + # Lifelike Graph DB migrator -Liquibase based migrator for Neo4j +Liquibase based migrator for ArangoDB ## Run with Docker @@ -9,8 +11,8 @@ To run migrations from Lifelike Docker registry latest image, you can run the fo ```bash # Update using bundled changelog files docker run --rm \ - --env NEO4J_HOST=neo4j:7687 \ - --env NEO4J_PASSWORD=password \ + --env ARANGODB_HOST=neo4j:7687 \ + --env ARANGODB_PASSWORD=password \ --env AZURE_ACCOUNT_STORAGE_NAME=lifelike \ --env AZURE_ACCOUNT_STORAGE_KEY= \ --env CHANGELOG_DIR=lifelike-graph \ @@ -28,10 +30,10 @@ docket run --rm \ | Variable | Default | Comment | | -------------------------- | -------------- | ----------------------------------- | | CHANGELOG_DIR | lifelike-graph | Master changelog directory path | -| NEO4J_HOST | | Host and port of Neo4j instance | -| NEO4J_USERNAME | neo4j | Neo4j authentication username | -| NEO4J_PASSWORD | password | Neo4j authentication password | -| NEO4J_DATABASE | neo4j | Neo4j target database | +| ARANGODB_HOST | | Host and port of ArangoDB instance | +| ARANGODB_USERNAME | neo4j | ArangoDB authentication username | +| ARANGODB_PASSWORD | password | ArangoDB authentication password | +| ARANGODB_DATABASE | neo4j | ArangoDB target database | | STORAGE_TYPE | azure | Remote storage type to get TSV data | | AZURE_ACCOUNT_STORAGE_NAME | | Azure Storage Account Name | | AZURE_ACCOUNT_STORAGE_KEY | | Azure Storage Key | @@ -42,5 +44,5 @@ docket run --rm \ | Argument | Default value | Comment | | ----------------------- | ------------- | ------- | | LIQUIBASE_IMAGE_TAG | 4.6 | Tag of the [Liquibase Docker image](https://hub.docker.com/r/liquibase/liquibase/tags) to use | -| LIQUIBASE_NEO4J_VERSION | 4.6.2 | [Liquibase-Neo4j plugin](https://github.com/liquibase/liquibase-neo4j) version to install | -| NEO4J_JDBC_VERSION | 4.0.5 | Neo4j JDBC driver version | +| LIQUIBASE_ARANGODB_VERSION | 4.6.2 | [Liquibase-ArangoDB plugin](https://github.com/liquibase/liquibase-neo4j) version to install | +| ARANGODB_JDBC_VERSION | 4.0.5 | ArangoDB JDBC driver version | diff --git a/graph-db/migrator/docker-entrypoint.sh b/graph-db/migrator/docker-entrypoint.sh index 01c4e0149c..1b7b5095ab 100755 --- a/graph-db/migrator/docker-entrypoint.sh +++ b/graph-db/migrator/docker-entrypoint.sh @@ -13,12 +13,12 @@ else liquibase "$@" else ## Validate envrioment variables - if [ -z "$NEO4J_HOST" ]; then - echo "NEO4J_HOST environment variable is not set. Please set it to the hostname or IP address of the Neo4j server." + if [ -z "$ARANGODB_HOST" ]; then + echo "ARANGODB_HOST environment variable is not set. Please set it to the hostname or IP address of the ArangoDB server." exit 1 - elif [[ "$NEO4J_HOST" != *":"* ]]; then + elif [[ "$ARANGODB_HOST" != *":"* ]]; then ## If no port is specified, use the default one - NEO4J_HOST="$NEO4J_HOST:7687" + ARANGODB_HOST="$ARANGODB_HOST:7687" fi if [ "$STORAGE_TYPE" != "azure" ]; then echo "STORAGE_TYPE environment is set to an invalid valie. `azure` is currently only supported." @@ -33,21 +33,21 @@ else exit 1 fi - ## Wait until Neo4j is available - /wait-for-it.sh "$NEO4J_HOST" --timeout=600 -- echo "Neo4j is up" + ## Wait until ArangoDB is available + /wait-for-it.sh "$ARANGODB_HOST" --timeout=600 -- echo "ArangoDB is up" ## Include standard defaultsFile liquibase \ - --url="jdbc:neo4j:bolt://$NEO4J_HOST?database=${NEO4J_DATABASE:-neo4j}" \ - --username="$NEO4J_USERNAME" \ - --password="$NEO4J_PASSWORD" \ + --url="jdbc:neo4j:bolt://$ARANGODB_HOST?database=${ARANGODB_DATABASE:-neo4j}" \ + --username="$ARANGODB_USERNAME" \ + --password="$ARANGODB_PASSWORD" \ --changelog-file="$CHANGELOG_FILE" \ --log-level="$LOG_LEVEL" \ --defaults-file=/liquibase/liquibase.docker.properties \ "$@" \ - -Dneo4jHost="bolt://$NEO4J_HOST" \ - -Dneo4jCredentials="$NEO4J_USERNAME,$NEO4J_PASSWORD" \ - -Dneo4jDatabase="${NEO4J_DATABASE:-neo4j}" \ + -Dneo4jHost="bolt://$ARANGODB_HOST" \ + -Dneo4jCredentials="$ARANGODB_USERNAME,$ARANGODB_PASSWORD" \ + -Dneo4jDatabase="${ARANGODB_DATABASE:-neo4j}" \ -DazureStorageName="$AZURE_ACCOUNT_STORAGE_NAME" \ -DazureStorageKey="$AZURE_ACCOUNT_STORAGE_KEY" \ -DlocalSaveFileDir=/tmp \ diff --git a/helm/lifelike/Chart.lock b/helm/lifelike/Chart.lock index d89a3eebfc..b93530d606 100644 --- a/helm/lifelike/Chart.lock +++ b/helm/lifelike/Chart.lock @@ -2,9 +2,9 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami version: 11.0.4 -- name: neo4j - repository: https://neo4j-contrib.github.io/neo4j-helm - version: 4.4.3 +- name: kube-arangodb + repository: https://github.com/arangodb/kube-arangodb + version: 1.2.39 - name: elasticsearch repository: https://helm.elastic.co version: 7.16.3 diff --git a/helm/lifelike/Chart.yaml b/helm/lifelike/Chart.yaml index ee409bf66f..e69ad794cc 100644 --- a/helm/lifelike/Chart.yaml +++ b/helm/lifelike/Chart.yaml @@ -25,10 +25,10 @@ dependencies: repository: https://charts.bitnami.com/bitnami version: 11.0.4 condition: postgresql.enabled - - name: neo4j + - name: kube-arangodb version: 4.4.3 - repository: https://neo4j-contrib.github.io/neo4j-helm - condition: neo4j.enabled + repository: https://github.com/arangodb/kube-arangodb + condition: 1.2.39 - name: elasticsearch version: 7.16.3 repository: https://helm.elastic.co diff --git a/helm/lifelike/README.md b/helm/lifelike/README.md index 25051e94bc..6fa2107749 100644 --- a/helm/lifelike/README.md +++ b/helm/lifelike/README.md @@ -22,7 +22,7 @@ Kubernetes: `>=1.20.0-0` | https://charts.bitnami.com/bitnami | postgresql | 11.0.4 | | https://charts.bitnami.com/bitnami | redis | 16.2.0 | | https://helm.elastic.co | elasticsearch | 7.16.3 | -| https://neo4j-contrib.github.io/neo4j-helm | neo4j | 4.4.3 | +| https://github.com/arangodb/kube-arangodb | kube-arangodb | 1.2.39 | ## Values @@ -40,11 +40,11 @@ Kubernetes: `>=1.20.0-0` | statisticalEnrichment | object | `{"image":{"repository":"ghcr.io/sbrg/lifelike-statistical-enrichment","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":5000,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | | pdfparser | object | `{"autoScaling":{"enabled":false,"maxReplicas":4,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"image":{"repository":"ghcr.io/sbrg/lifelike-pdfparser","tag":"latest"},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":7600,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | | postgresqlExternal | object | `{"database":"postgres","existingSecret":"","host":"postgres.local","password":"password","port":5432,"user":"postgres"}` | ---------------------------------------------------------------------------- | -| neo4jExternal.host | string | `"neo4j.local"` | | -| neo4jExternal.port | int | `7687` | | -| neo4jExternal.user | string | `"neo4j"` | | -| neo4jExternal.password | string | `"password"` | | -| neo4jExternal.database | string | `"neo4j"` | | +| arangodbExternal.host | string | `"arangodb.local"` | | +| arangodbExternal.port | int | `7687` | | +| arangodbExternal.user | string | `"arangodb"` | | +| arangodbExternal.password | string | `"password"` | | +| arangodbExternal.database | string | `"arangodb"` | | | redisExternal.host | string | `"redis.local"` | | | redisExternal.port | int | `6379` | | | redisExternal.password | string | `""` | | @@ -55,7 +55,7 @@ Kubernetes: `>=1.20.0-0` | elasticsearchExternal.ssl | bool | `false` | | | postgresql | object | `{"auth":{"database":"database","postgresPassword":"password"},"enabled":true}` | ---------------------------------------------------------------------------- | | postgresql.enabled | bool | `true` | Set to false to disable automatic deployment of PostgreSQL | -| neo4j | object | `{"core":{"numberOfServers":1,"persistentVolume":{"size":"100Gi"},"standalone":true},"enabled":true,"imageTag":"4.4.3-community","neo4jPassword":"password"}` | ---------------------------------------------------------------------------- | +| arangodb | object | `{"core":{"numberOfServers":1,"persistentVolume":{"size":"100Gi"},"standalone":true},"enabled":true,"imageTag":"4.4.3-community","arangodbPassword":"password"}` | ---------------------------------------------------------------------------- | | elasticsearch | object | `{"enabled":true,"esConfig":{"elasticsearch.yml":"node.store.allow_mmap: false\n"},"fullnameOverride":"elasticsearch","image":"ghcr.io/sbrg/lifelike-elasticsearch","imageTag":"7.16.3","volumeClaimTemplate":{"resources":{"requests":{"storage":"30Gi"}}}}` | ---------------------------------------------------------------------------- | | redis | object | `{"auth":{"password":"password"},"commonConfiguration":"# Disable persistence to disk\nsave \"\"\n# Disable AOF https://redis.io/topics/persistence#append-only-file\nappendonly no","enabled":true,"master":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}},"replica":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}}}` | ---------------------------------------------------------------------------- | diff --git a/helm/lifelike/examples/external-db.yaml b/helm/lifelike/examples/external-db.yaml index 69fbebdb47..edeb47c4fc 100644 --- a/helm/lifelike/examples/external-db.yaml +++ b/helm/lifelike/examples/external-db.yaml @@ -1,6 +1,6 @@ ## This is an example values files for installing Lifelike Helm chart ## connecting to external existing database services -## instead of installing the embedded subcharts (postgres, neo4j and elasticsearch) +## instead of installing the embedded subcharts (postgres, arangodb and elasticsearch) # Disable the embedded PostgreSQL subchart @@ -14,14 +14,14 @@ postgresqlExternal: database: postgres password: password -# Disable embedded Neo4j subchart -neo4j: +# Disable embedded ArangoDB subchart +arangodb: enabled: false -# Configure external Neo4j database -neo4jExternal: - host: neo4j.local +# Configure external ArangoDB database +arangodbExternal: + host: arangodb.local port: 7687 - user: neo4j + user: arangodb password: password # Disable embedded Elasticsearch subchart diff --git a/helm/lifelike/templates/_helpers.tpl b/helm/lifelike/templates/_helpers.tpl index 7823c85cb0..09defdf5ea 100644 --- a/helm/lifelike/templates/_helpers.tpl +++ b/helm/lifelike/templates/_helpers.tpl @@ -163,18 +163,18 @@ Set postgres secretKey {{/* ---------------------------------------------------------------------- */}} -{{/* Neo4J */}} +{{/* ArangoDB */}} {{/* ---------------------------------------------------------------------- */}} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). */}} -{{- define "lifelike.neo4j.fullname" -}} -{{- if .Values.neo4j.fullnameOverride -}} -{{- .Values.neo4j.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- define "lifelike.arangodb.fullname" -}} +{{- if .Values.arangodb.fullnameOverride -}} +{{- .Values.arangodb.fullnameOverride | trunc 63 | trimSuffix "-" -}} {{- else -}} -{{- $name := default "neo4j" .Values.neo4j.nameOverride -}} +{{- $name := default "arangodb" .Values.arangodb.nameOverride -}} {{- if contains $name .Release.Name -}} {{- .Release.Name | trunc 63 | trimSuffix "-" -}} {{- else -}} @@ -184,57 +184,57 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this {{- end -}} {{/* -Return the Neo4j hostname +Return the ArangoDB hostname */}} -{{- define "lifelike.neo4jHost" -}} -{{- if .Values.neo4j.enabled }} - {{- printf "%s" (include "lifelike.neo4j.fullname" .) -}} +{{- define "lifelike.arangodbHost" -}} +{{- if .Values.arangodb.enabled }} + {{- printf "%s" (include "lifelike.arangodb.fullname" .) -}} {{- else -}} - {{- printf "%s" .Values.neo4jExternal.host -}} + {{- printf "%s" .Values.arangodbExternal.host -}} {{- end -}} {{- end -}} {{/* -Return the Neo4j port +Return the ArangoDB port */}} -{{- define "lifelike.neo4jPort" -}} -{{- if .Values.neo4j.enabled }} +{{- define "lifelike.arangodbPort" -}} +{{- if .Values.arangodb.enabled }} {{- printf "7687" -}} {{- else -}} - {{- .Values.neo4jExternal.port -}} + {{- .Values.arangodbExternal.port -}} {{- end -}} {{- end -}} {{/* -Return the Neo4j user +Return the ArangoDB user */}} -{{- define "lifelike.neo4jUser" -}} -{{- if .Values.neo4j.enabled }} - {{- printf "neo4j" -}} +{{- define "lifelike.arangodbUser" -}} +{{- if .Values.arangodb.enabled }} + {{- printf "arangodb" -}} {{- else -}} - {{- printf "%s" .Values.neo4jExternal.user -}} + {{- printf "%s" .Values.arangodbExternal.user -}} {{- end -}} {{- end -}} {{/* -Return the Neo4j password +Return the ArangoDB password */}} -{{- define "lifelike.neo4jPassword" -}} -{{- if .Values.neo4j.enabled }} - {{- printf "%s" .Values.neo4j.neo4jPassword -}} +{{- define "lifelike.arangodbPassword" -}} +{{- if .Values.arangodb.enabled }} + {{- printf "%s" .Values.arangodb.arangodbPassword -}} {{- else -}} - {{- printf "%s" .Values.neo4jExternal.password -}} + {{- printf "%s" .Values.arangodbExternal.password -}} {{- end -}} {{- end -}} {{/* -Return the Neo4j database name +Return the ArangoDB database name */}} -{{- define "lifelike.neo4jDatabase" -}} -{{- if .Values.neo4j.enabled }} - {{- default "neo4j" .Values.neo4j.defaultDatabase -}} +{{- define "lifelike.arangodbDatabase" -}} +{{- if .Values.arangodb.enabled }} + {{- default "arangodb" .Values.arangodb.defaultDatabase -}} {{- else -}} - {{- default "neo4j" .Values.neo4jExternal.database -}} + {{- default "arangodb" .Values.arangodbExternal.database -}} {{- end -}} {{- end -}} @@ -282,7 +282,7 @@ Return the Elasticsearch port {{- end -}} {{/* -Return the Neo4j user +Return the ArangoDB user */}} {{- define "lifelike.elasticsearchUser" -}} {{- if .Values.elasticsearch.enabled }} @@ -472,17 +472,17 @@ PostgreSQL environment variables helper {{/* -Neo4j environment variables helper +ArangoDB environment variables helper */}} -{{- define "lifelike.neo4jEnv" -}} -- name: NEO4J_HOST - value: {{ template "lifelike.neo4jHost" . }} -- name: NEO4J_PORT - value: {{ include "lifelike.neo4jPort" . | quote }} -- name: NEO4J_AUTH - value: {{ template "lifelike.neo4jUser" . }}/{{ template "lifelike.neo4jPassword" . }} -- name: NEO4J_DB - value: {{ template "lifelike.neo4jDatabase" . }} +{{- define "lifelike.arangodbEnv" -}} +- name: ARANGODB_HOST + value: {{ template "lifelike.arangodbHost" . }} +- name: ARANGODB_PORT + value: {{ include "lifelike.arangodbPort" . | quote }} +- name: ARANGODB_AUTH + value: {{ template "lifelike.arangodbUser" . }}/{{ template "lifelike.arangodbPassword" . }} +- name: ARANGODB_DB + value: {{ template "lifelike.arangodbDatabase" . }} {{- end -}} diff --git a/helm/lifelike/templates/api/deployment.yaml b/helm/lifelike/templates/api/deployment.yaml index 3b2f5dc0cd..38b09da121 100644 --- a/helm/lifelike/templates/api/deployment.yaml +++ b/helm/lifelike/templates/api/deployment.yaml @@ -47,14 +47,14 @@ spec: - --port={{ template "lifelike.postgresqlPort" . }} - --timeout={{ default 30 .Values.api.dbWaiter.timeoutSeconds }} {{- end }} - {{- if .Values.neo4j.enabled }} - - name: wait-for-neo4j + {{- if .Values.arangodb.enabled }} + - name: wait-for-arangodb image: {{ .Values.api.dbWaiter.image.repository }}:{{ .Values.api.dbWaiter.image.tag }} imagePullPolicy: {{ default "IfNotPresent" .Values.api.dbWaiter.image.imagePullPolicy }} command: - /wait-for-it.sh - - --host={{ template "lifelike.neo4jHost" . }} - - --port={{ template "lifelike.neo4jPort" . }} + - --host={{ template "lifelike.arangodbHost" . }} + - --port={{ template "lifelike.arangodbPort" . }} - --timeout={{ default 30 .Values.api.dbWaiter.timeoutSeconds }} {{- end }} - name: migrate-db diff --git a/helm/lifelike/values.schema.json b/helm/lifelike/values.schema.json index 9fc39fb453..84cd16eeca 100644 --- a/helm/lifelike/values.schema.json +++ b/helm/lifelike/values.schema.json @@ -363,7 +363,7 @@ } } }, - "neo4j": { + "arangodb": { "type": "object", "properties": { "core": { @@ -391,12 +391,12 @@ "imageTag": { "type": "string" }, - "neo4jPassword": { + "arangodbPassword": { "type": "string" } } }, - "neo4jExternal": { + "arangodbExternal": { "type": "object", "properties": { "database": { diff --git a/helm/lifelike/values.yaml b/helm/lifelike/values.yaml index 915f62b3f6..aed8f642e8 100644 --- a/helm/lifelike/values.yaml +++ b/helm/lifelike/values.yaml @@ -207,7 +207,7 @@ statisticalEnrichment: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 - + service: type: ClusterIP port: 5000 @@ -282,13 +282,13 @@ postgresqlExternal: ## -- Read password from an existing secret, must contain key "postgres-password" existingSecret: "" -## -- External Neo4j connection details, ignored if neo4j.enabled is set to true -neo4jExternal: - host: neo4j.local +## -- External ArangoDB connection details, ignored if arangodb.enabled is set to true +arangodbExternal: + host: arangodb.local port: 7687 - user: neo4j + user: arangodb password: password - database: neo4j + database: arangodb ## -- External Redis connection details, ignored if redis.enabled is set to true @@ -328,19 +328,19 @@ postgresql: database: database # ------------------------------------------------------------------------------ -# Neo4j database +# ArangoDB database # ------------------------------------------------------------------------------ -## -- Embedded Neo4j subchart deployment -## -- See all available values: https://github.com/neo4j-contrib/neo4j-helm/blob/master/values.yaml -neo4j: - ## -- Set to false to disable automatic deployment of Neo4j +## -- Embedded ArangoDB subchart deployment +## -- See all available values: https://github.com/arangodb-contrib/arangodb-helm/blob/master/values.yaml +arangodb: + ## -- Set to false to disable automatic deployment of ArangoDB enabled: true imageTag: 4.4.3-community - ## -- Neo4j password - neo4jPassword: password + ## -- ArangoDB password + arangodbPassword: password core: ## -- Whether to deploy a standalone server or a replicated cluster diff --git a/keycloak b/keycloak deleted file mode 160000 index 738310c786..0000000000 --- a/keycloak +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 738310c786fafb5b1f2f15c3c313e8cb535fe287 diff --git a/lifelike-oss b/lifelike-oss deleted file mode 160000 index 034c727d7c..0000000000 --- a/lifelike-oss +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 034c727d7c5cafbfdcc022fb0ffdadc727b2fdca diff --git a/makefile b/makefile index d0adea1d44..a6d04e8ddf 100644 --- a/makefile +++ b/makefile @@ -1,19 +1,6 @@ APPSERVER_PATH=./appserver -ANSIBLE_PATH=./deployment/ansible LMDB_PATH = $(APPSERVER_PATH)/neo4japp/services/annotations/lmdb -# Fetches the password to unlock Ansible vault files -ansible-secrets: - az storage blob download --account-name lifelike --container-name lifelike-secrets --name .vault_secrets_pw --file $(ANSIBLE_PATH)/.vault_secrets_pw --auth-mode login - -# Fetches the credentials (env file) for Azure services -azure-secrets: - az storage blob download --account-name lifelike --container-name lifelike-secrets --name azure-secrets.env --file ./azure-secrets.env --auth-mode login - -# Log into azure container registry -container-login: - az acr login --name lifelike - # Fetches the LMDB files needed to run the application lmdb: docker compose up -d appserver @@ -22,7 +9,7 @@ lmdb: # Sets up everything you need to run the application # Mostly used for first time dev environment setup -init: ansible-secrets azure-secrets container-login githooks docker-build lmdb +init: githooks docker-build lmdb # Sets up commit hooks for linting githooks: @@ -32,11 +19,11 @@ docker-build: docker compose build # Runs enough containers for the application to function -docker-run: azure-secrets container-login lmdb +docker-run: lmdb docker compose up -d # Runs additional containers such as Kibana/Logstash/Filebeat -docker-run-all: azure-secrets container-login lmdb +docker-run-all: lmdb docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.middleware.yml up -d docker-stop: diff --git a/statistical-enrichment/Dockerfile b/statistical-enrichment/Dockerfile index a9e34baaf2..0bbc5c830d 100644 --- a/statistical-enrichment/Dockerfile +++ b/statistical-enrichment/Dockerfile @@ -1,7 +1,7 @@ # ======================================== # Base image # ======================================== -FROM python:3.10-slim as base +FROM python:3.8-slim as base ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 @@ -45,11 +45,11 @@ USER app # Copy application code COPY --chown=app . . -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_SCHEME=bolt +# ArangoDB configuration +ENV ARANGODB_HOST='' +ENV ARANGODB_PORT='' +ENV ARANGODB_AUTH='' +ENV ARANGODB_SCHEME='' # Redis cache configuration ENV REDIS_HOST=redis diff --git a/website b/website deleted file mode 160000 index 81ad65ebf3..0000000000 --- a/website +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 81ad65ebf32776cbcfff37f40fc10c540fc7074f From 1a575221bdffeec71ef477f37fd5fc3043867ce3 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 16:48:21 +0200 Subject: [PATCH 04/23] fix worflow --- .github/workflows/annotate-code-style.yml | 3 +- .github/workflows/sonar.yml | 63 ----------------------- 2 files changed, 2 insertions(+), 64 deletions(-) delete mode 100644 .github/workflows/sonar.yml diff --git a/.github/workflows/annotate-code-style.yml b/.github/workflows/annotate-code-style.yml index ada29e894f..d9f7773507 100644 --- a/.github/workflows/annotate-code-style.yml +++ b/.github/workflows/annotate-code-style.yml @@ -49,7 +49,8 @@ jobs: steps: - uses: actions/checkout@v3 with: - token: ${{ secrets.ACTION_TOKEN }} + # Set ACTION_TOKEN to re-run this action after autofix + token: ${{ secrets.ACTION_TOKEN || secrets.GITHUB_TOKEN }} - name: Annotate code style uses: wearerequired/lint-action@v2 diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml deleted file mode 100644 index e0bf8c0361..0000000000 --- a/.github/workflows/sonar.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Sonarqube code analysis - -on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened] - workflow_dispatch: - inputs: - application: - required: false - type: choice - default: "" - description: Specific application to analyze - options: - - "" - - Appserver - - Frontend - -jobs: - sonarqube: - name: Quality of ${{ matrix.name }} - strategy: - fail-fast: false - matrix: - include: - - name: appserver - path: appserver - extraArgs: > - -Dsonar.tests=tests/ - -Dsonar.exclusions=tests/** - - name: frontend - path: client - - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - # Check if code was changed in project path - - name: Check code changes - uses: marceloprado/has-changed-path@v1 - if: github.event_name != 'workflow_dispatch' - id: changed - with: - paths: ${{ matrix.path }} - - # Scan if code was changed or if workflow was triggered manually - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - if: steps.changed.outputs.changed == 'true' || github.event.inputs.application == matrix.name || github.event.inputs.application == '' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_ORGANIZATION: lifelike - with: - projectBaseDir: ${{ matrix.path }} - args: > - -Dsonar.organization=${{ env.SONAR_ORGANIZATION }} - -Dsonar.projectKey=${{ env.SONAR_ORGANIZATION }}-${{ matrix.name }} - -Dsonar.projectName=${{ matrix.name }} - ${{ matrix.extraArgs }} From fa9ce04db73867e1aee705eb856cc7c2d43f346a Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 16:54:28 +0200 Subject: [PATCH 05/23] fix integration check workflow --- appserver/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 7b1380edd7..0582b7fdb5 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -37,7 +37,7 @@ LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike # Install runtime system dependencies RUN apt-get update \ - && apt-get install -y libmagic-dev graphviz libgraphviz-dev curl \ + && apt-get install -y postgresql libmagic-dev graphviz libgraphviz-dev curl \ && apt-get clean # Copy Python virtual environment From f90a93d98b1f72593dce14b8de5df24c5d7e7a02 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 16:58:14 +0200 Subject: [PATCH 06/23] fix style --- .github/workflows/browserstack.yml | 23 +- .github/workflows/codeql-analysis.yml | 58 +- .prettierrc | 6 +- README.md | 34 +- appserver/Pipfile.lock | 60 +- docker/README.md | 6 +- graph-db/extractor/Pipfile.lock | 4 +- graph-db/extractor/docs/biocyc/spec.md | 396 ++--- graph-db/extractor/docs/kegg/kegg_spec.md | 81 +- .../docs/literature/literature_spec.md | 34 +- .../docs/mesh/mesh_rdf_data_model.md | 63 +- graph-db/extractor/docs/ncbi/taxonomy_spec.md | 93 +- .../other/scripts for LMDB annotation file.md | 33 +- .../extractor/src/biocyc/data_sources.json | 42 +- graph-db/migrator/README.md | 18 +- helm/lifelike/README.md | 81 +- helm/lifelike/examples/external-db.yaml | 1 - helm/lifelike/values.schema.json | 1372 ++++++++--------- helm/lifelike/values.yaml | 21 +- statistical-enrichment/Pipfile.lock | 8 +- tests/cypress/browserstack.json | 16 +- .../cypress/integration/projects.spec.js | 28 +- .../cypress/cypress/integration/tabs.spec.js | 20 +- tests/cypress/cypress/support/commands.js | 32 +- tests/cypress/cypress/support/index.js | 4 +- 25 files changed, 1245 insertions(+), 1289 deletions(-) diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml index f7719bf92a..584381005b 100644 --- a/.github/workflows/browserstack.yml +++ b/.github/workflows/browserstack.yml @@ -1,4 +1,4 @@ -name: 'BrowserStack Test' +name: "BrowserStack Test" on: workflow_dispatch: inputs: @@ -9,31 +9,30 @@ on: jobs: browserstack: - name: 'BrowserStack Tests' + name: "BrowserStack Tests" runs-on: ubuntu-latest steps: - - - name: 'BrowserStack Env Setup' # Invokes the setup-env action + - name: "BrowserStack Env Setup" # Invokes the setup-env action uses: browserstack/github-actions/setup-env@master with: - username: ${{ secrets.BROWSERSTACK_USERNAME }} + username: ${{ secrets.BROWSERSTACK_USERNAME }} access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} project-name: lifelike - - name: 'Checkout the repository' + - name: "Checkout the repository" uses: actions/checkout@v2 - - name: 'Install BrowserStack Cypress CLI' + - name: "Install BrowserStack Cypress CLI" run: npm install -g browserstack-cypress-cli - + - name: Run BrowserStack tests working-directory: ./tests/cypress run: browserstack-cypress run - - name: 'Running test on BrowserStack' # Invokes the actual test script that would run on BrowserStack browsers - run: node index.js # See sample test script above + - name: "Running test on BrowserStack" # Invokes the actual test script that would run on BrowserStack browsers + run: node index.js # See sample test script above - - name: 'BrowserStackLocal Stop' # Terminating the BrowserStackLocal tunnel connection + - name: "BrowserStackLocal Stop" # Terminating the BrowserStackLocal tunnel connection uses: browserstack/github-actions/setup-local@master with: - local-testing: stop \ No newline at end of file + local-testing: stop diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 659c4fde62..7d2fa1ede2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ main ] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [ main ] + branches: [main] schedule: - - cron: '15 12 * * 1' + - cron: "15 12 * * 1" jobs: analyze: @@ -32,39 +32,39 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python', 'javascript' ] + language: ["python", "javascript"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://git.io/codeql-language-support steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.prettierrc b/.prettierrc index 19f2eb490a..e2c9ad1e39 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ singleQuote: true jsxSingleQuote: true overrides: - - files: ["*.yml", "*.yaml"] - options: - singleQuote: false + - files: ['*.yml', '*.yaml'] + options: + singleQuote: false diff --git a/README.md b/README.md index 29cbaf7fff..2640590ab8 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,15 @@ Visualizations are a powerful way to help you to understand the relationships be Lifelike currently provides the following built-in visualization types: -- Maps -- Enrichment tables -- Sankey diagrams -- Pathway Browser +- Maps +- Enrichment tables +- Sankey diagrams +- Pathway Browser ### Other features -- Multi-user collaborative workbench -- Powerful search engine +- Multi-user collaborative workbench +- Powerful search engine ## Common development operations @@ -111,20 +111,20 @@ Lifelike is a distributed system comprised of the following components: ### Core services -- **[Appserver](appserver)**. Backend API service, written in Python using the the Flask framework. -- **[Client](client)**. Frontend Single Page Application, written in Typescript using the Angular framework. -- **[Statistical enrichment](statistical-enrichment)**. Statistics generation microservice, written in Python using the the Flask framework. -- **[Cache invalidator](cache-invalidator)**. Recurrent task runner for bulk large computations and cache data management, written in Python. -- **[Graph data migrator](graph-db)**. Utility service for migrating and versioning knowledge graph database, using the Liquibase database migration tool. +- **[Appserver](appserver)**. Backend API service, written in Python using the the Flask framework. +- **[Client](client)**. Frontend Single Page Application, written in Typescript using the Angular framework. +- **[Statistical enrichment](statistical-enrichment)**. Statistics generation microservice, written in Python using the the Flask framework. +- **[Cache invalidator](cache-invalidator)**. Recurrent task runner for bulk large computations and cache data management, written in Python. +- **[Graph data migrator](graph-db)**. Utility service for migrating and versioning knowledge graph database, using the Liquibase database migration tool. ### Backing services -- **PostgreSQL** as a RDBMS. -- **ArangoDB** as a graph database. -- **Elasticsearch** as a full-text search engine. -- **Redis** as a key-value cache store. -- **PDFParser** as a document parsing library. -- **Sendgrid** as an email messaging service. +- **PostgreSQL** as a RDBMS. +- **ArangoDB** as a graph database. +- **Elasticsearch** as a full-text search engine. +- **Redis** as a key-value cache store. +- **PDFParser** as a document parsing library. +- **Sendgrid** as an email messaging service. ## License diff --git a/appserver/Pipfile.lock b/appserver/Pipfile.lock index 0280160e85..2c0207aadf 100644 --- a/appserver/Pipfile.lock +++ b/appserver/Pipfile.lock @@ -145,9 +145,7 @@ "version": "==4.12.3" }, "bioc": { - "hashes": [ - "sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10" - ], + "hashes": ["sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10"], "index": "pypi", "markers": "python_version >= '3.6'", "version": "==1.3.7" @@ -329,9 +327,7 @@ "version": "==2.1.0" }, "elastic-apm": { - "extras": [ - "flask" - ], + "extras": ["flask"], "hashes": [ "sha256:1861183c5ba3b46df66e111ba27877dbe8aaa8842777c1f0627c7fb1b65ed249", "sha256:7a5e430658196c9ebcf4530e780268b0dfe2ba2c25041549ee54d9fb8650c418" @@ -612,9 +608,7 @@ "version": "==1.0.5" }, "httpretty": { - "hashes": [ - "sha256:e53c927c4d3d781a0761727f1edfad64abef94e828718e12b672a678a8b3e0b5" - ], + "hashes": ["sha256:e53c927c4d3d781a0761727f1edfad64abef94e828718e12b672a678a8b3e0b5"], "index": "pypi", "markers": "python_version >= '3'", "version": "==1.0.5" @@ -636,16 +630,12 @@ "version": "==2.10" }, "intervaltree": { - "hashes": [ - "sha256:902b1b88936918f9b2a19e0e5eb7ccb430ae45cde4f39ea4b36932920d33952d" - ], + "hashes": ["sha256:902b1b88936918f9b2a19e0e5eb7ccb430ae45cde4f39ea4b36932920d33952d"], "index": "pypi", "version": "==3.1.0" }, "ipy": { - "hashes": [ - "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a" - ], + "hashes": ["sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"], "index": "pypi", "version": "==1.1" }, @@ -996,9 +986,7 @@ "version": "==0.22.3" }, "memory-profiler": { - "hashes": [ - "sha256:01385ac0fec944fcf7969814ec4406c6d8a9c66c079d09276723c5a7680f44e5" - ], + "hashes": ["sha256:01385ac0fec944fcf7969814ec4406c6d8a9c66c079d09276723c5a7680f44e5"], "index": "pypi", "markers": "python_version >= '3.4'", "version": "==0.58.0" @@ -1119,9 +1107,7 @@ "version": "==3.0.7" }, "ordered-set": { - "hashes": [ - "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95" - ], + "hashes": ["sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95"], "markers": "python_version >= '3.5'", "version": "==4.0.2" }, @@ -1590,9 +1576,7 @@ "version": "==2.4.7" }, "pypdf4": { - "hashes": [ - "sha256:7c932441146d205572f96254d53c79ea2c30c9e11df55a5cf87e056c7b3d7f89" - ], + "hashes": ["sha256:7c932441146d205572f96254d53c79ea2c30c9e11df55a5cf87e056c7b3d7f89"], "index": "pypi", "version": "==1.27.0" }, @@ -1630,9 +1614,7 @@ "version": "==3.3.7" }, "python-json-logger": { - "hashes": [ - "sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398" - ], + "hashes": ["sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398"], "index": "pypi", "markers": "python_version >= '3.4'", "version": "==2.0.1" @@ -1721,9 +1703,7 @@ "version": "==3.5.2" }, "requests": { - "extras": [ - "socks" - ], + "extras": ["socks"], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" @@ -1885,9 +1865,7 @@ "version": "==1.3.23" }, "sqlalchemy-searchable": { - "hashes": [ - "sha256:597de9d1356e8a0a8b3be7be892adee422e7419603f25c40a7ab5c16bd75f77d" - ], + "hashes": ["sha256:597de9d1356e8a0a8b3be7be892adee422e7419603f25c40a7ab5c16bd75f77d"], "index": "pypi", "version": "==1.2.0" }, @@ -1900,9 +1878,7 @@ "version": "==0.41.2" }, "starkbank-ecdsa": { - "hashes": [ - "sha256:9399c3371b899d4a235b68a1ed7919d202fbf024bd2c863ae8ebdad343c2a63a" - ], + "hashes": ["sha256:9399c3371b899d4a235b68a1ed7919d202fbf024bd2c863ae8ebdad343c2a63a"], "version": "==2.2.0" }, "statsmodels": { @@ -1934,9 +1910,7 @@ "version": "==0.12.2" }, "svg-stack": { - "hashes": [ - "sha256:552d0958db5533ca2d1e541c06e60bbbf05a44eac164a1d89fd4361bbd0eb22d" - ], + "hashes": ["sha256:552d0958db5533ca2d1e541c06e60bbbf05a44eac164a1d89fd4361bbd0eb22d"], "index": "pypi", "version": "==0.1.0" }, @@ -2171,9 +2145,7 @@ "version": "==3.9.2" }, "flake8-obey-import-goat": { - "hashes": [ - "sha256:2e4c7be21b96dda72e903c21de16ff928e11fccdf9427889bfb7ccf4610f6072" - ], + "hashes": ["sha256:2e4c7be21b96dda72e903c21de16ff928e11fccdf9427889bfb7ccf4610f6072"], "index": "pypi", "markers": "python_version >= '3.9'", "version": "==0.1.1" @@ -2261,9 +2233,7 @@ "version": "==3.5.2" }, "requests": { - "extras": [ - "socks" - ], + "extras": ["socks"], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" diff --git a/docker/README.md b/docker/README.md index bc35a8cf69..daa9263be4 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,12 +1,10 @@ - - # Getting Started with Lifelike using Docker Docker is an easy way to get started with Lifelike. ## Prerequisites -- [Docker](https://www.docker.com/get-started) +- [Docker](https://www.docker.com/get-started) ## Run locally @@ -21,7 +19,7 @@ make up ```text Building and running containers... -This may take a while if running for the first time. +This may take a while if running for the first time. [+] Running 13/13 ⠿ Network lifelike Created diff --git a/graph-db/extractor/Pipfile.lock b/graph-db/extractor/Pipfile.lock index a3a04f09d3..da00e845e9 100644 --- a/graph-db/extractor/Pipfile.lock +++ b/graph-db/extractor/Pipfile.lock @@ -263,9 +263,7 @@ "version": "==0.7.1" }, "neo4j": { - "hashes": [ - "sha256:06b12daa8fa6bf133abc8c4f35451748a2ee6dc207c52790304a8e12c997ce65" - ], + "hashes": ["sha256:06b12daa8fa6bf133abc8c4f35451748a2ee6dc207c52790304a8e12c997ce65"], "index": "pypi", "version": "==4.4.5" }, diff --git a/graph-db/extractor/docs/biocyc/spec.md b/graph-db/extractor/docs/biocyc/spec.md index 2d957a937f..60debcf44c 100644 --- a/graph-db/extractor/docs/biocyc/spec.md +++ b/graph-db/extractor/docs/biocyc/spec.md @@ -1,226 +1,230 @@ # BioCyc Spec for Knowledge Graph -The BioCyc database collection is an assortment of organism specific Pathway/ Genome Databases (PGDBs). They provide -reference to genome and metabolic pathway information for thousands of organisms. -Download site: https://brg-files.ai.sri.com/public/dist/. Search for the specific organism data for download. + +The BioCyc database collection is an assortment of organism specific Pathway/ Genome Databases (PGDBs). They provide +reference to genome and metabolic pathway information for thousands of organisms. +Download site: https://brg-files.ai.sri.com/public/dist/. Search for the specific organism data for download. Currently we loaded the following databases: -- EcoCyc: Escherichia coli K-12 substr. MG1655 (tax_id 511145) -http://brg-files.ai.sri.com/public/dist/ecoli.tar.gz -- HumanCyc: Homo sapiens (tax_id 9606) -http://brg-files.ai.sri.com/public/dist/human.tar.gz +- EcoCyc: Escherichia coli K-12 substr. MG1655 (tax_id 511145) + http://brg-files.ai.sri.com/public/dist/ecoli.tar.gz + +- HumanCyc: Homo sapiens (tax_id 9606) + http://brg-files.ai.sri.com/public/dist/human.tar.gz -- YeastCyc: Saccharomyces cerevisiae S288C (tax_id 559292) -http://brg-files.ai.sri.com/public/dist/yeastcyc.tar.gz +- YeastCyc: Saccharomyces cerevisiae S288C (tax_id 559292) + http://brg-files.ai.sri.com/public/dist/yeastcyc.tar.gz -- PseudomonasCyc: for Pseudomonas putida KT2440 (tax_id 160488) -http://brg-files.ai.sri.com/public/dist/pput160488cyc.tar.gz +- PseudomonasCyc: for Pseudomonas putida KT2440 (tax_id 160488) + http://brg-files.ai.sri.com/public/dist/pput160488cyc.tar.gz -- MetaCyc: MetaCyc is a curated database of experimentally elucidated metabolic pathways from all domains of life. -MetaCyc contains pathways involved in both primary and secondary metabolism, as well as associated metabolites, reactions, -enzymes, and genes. The goal of MetaCyc is to catalog the universe of metabolism by storing a representative sample of each experimentally elucidated pathway -https://brg-files.ai.sri.com/public/dist/meta.tar.gz +- MetaCyc: MetaCyc is a curated database of experimentally elucidated metabolic pathways from all domains of life. + MetaCyc contains pathways involved in both primary and secondary metabolism, as well as associated metabolites, reactions, + enzymes, and genes. The goal of MetaCyc is to catalog the universe of metabolism by storing a representative sample of each experimentally elucidated pathway + https://brg-files.ai.sri.com/public/dist/meta.tar.gz -In Lifelike graph database, each node in BioCyc was labeled as db_BioCyc, and nodes for each biocyc database was -labeled as additional database name, such as db_EcoCyc, db_HumanCyc. Therefore for any EcoCyc, there are 3 labels: +In Lifelike graph database, each node in BioCyc was labeled as db_BioCyc, and nodes for each biocyc database was +labeled as additional database name, such as db_EcoCyc, db_HumanCyc. Therefore for any EcoCyc, there are 3 labels: db_BioCyc, db_EcoCyc and the entity name (e.g. Gene, Protein) -### Graph database schema for BioCyc +### Graph database schema for BioCyc + ![](biocyc_graphmodel.png) -#### Node labels and attributes: +#### Node labels and attributes: + id has the same value for biocyc_id, and displayName and pathways attributes were added post-loading for annotation -| Node Label | Attribute | Source | -|:-----|:-----------|:-| -| BioCycClass | biocyc_id | UNIQUE-ID | -| BioCycClass | data_source |"BioCyc" | -| BioCycClass | displayName | =coalesce(name, biocyc_id) | -| BioCycClass | id | =biocyc_id | -| BioCycClass | name | COMMON-NAME | -| BioCycClass | synonyms | SYNONYMS | -| Compound | abbrev_name | ABBREV-NAME | -| Compound | biocyc_id | UNIQUE-ID | -| Compound | data_source | "BioCyc" | -| Compound | displayName | =coalesce(name, biocyc_id) | -| Compound | id | =biocyc_id | -| Compound | inchi_key | INCHI-KEY
    remove leading 'InChIKey='| -| Compound | name | COMMON-NAME
    strip HTML tags and remove leading 'a ' and 'an ' | -| Compound | inchi | INCHI | -| Compound | smiles | SMILES | -| DNABindingSite | abs_center_pos | ABS-CENTER-POS | -| DNABindingSite | biocyc_id | UNIQUE-ID | -| DNABindingSite | data_source |"BioCyc" | -| DNABindingSite | description | | -| DNABindingSite | displayName | =protein displayName + ' BS' of proteins linked to the DNABindingSite through Regulation

    else

    =coalesce(name, biocyc_id) -| DNABindingSite | id | =biocyc_id | -| DNABindingSite | site_length | SITE-LENGTH | -| EnzReaction | biocyc_id | UNIQUE-ID | -| EnzReaction | data_source |"BioCyc" | -| EnzReaction | description | | -| EnzReaction | displayName | = name + gene(s) that encodes the enzyme| -| EnzReaction | id | =biocyc_id | -| EnzReaction | name | COMMON-NAME | -| EnzReaction | synonyms | SYNONYMS | -| Gene | accession | ACCESSION-1 | -| Gene | biocyc_id | UNIQUE-ID | -| Gene | data_source |"BioCyc" | -| Gene | description | | -| Gene | displayName | =coalesce(name, biocyc_id) | -| Gene | id | =biocyc_id | -| Gene | left_end_position | LEFT-END-POSITION | -| Gene | name | COMMON-NAME | -| Gene | pathways | =set_gene_property_for_enrichment()| -| Gene | right_end_position | RIGHT-END-POSITION | -| Gene | strand | TRANSCRIPTION-DIRECTION | -| Gene | synonyms | SYNONYMS | -| Pathway | biocyc_id | UNIQUE-ID | -| Pathway | data_source |"BioCyc" | -| Pathway | displayName | =coalesce(name, biocyc_id) | -| Pathway | id | =biocyc_id | -| Pathway | name | COMMON-NAME | -| Pathway | synonyms | SYNONYMS | -| Promoter | biocyc_id | UNIQUE-ID | -| Promoter | data_source |"BioCyc" | -| Promoter | description | | -| Promoter | displayName | =coalesce(name, biocyc_id) | -| Promoter | id | =biocyc_id | -| Promoter | name | COMMON-NAME | -| Promoter | pos_1 | ABSOLUTE-PLUS-1-POS | -| Promoter | strand | TRANSCRIPTION-DIRECTION | -| Promoter | synonyms | SYNONYMS | -| Protein | abbrev_name | ABBREV-NAME | -| Protein | biocyc_id | UNIQUE-ID | -| Protein | data_source |"BioCyc" | -| Protein | description | | -| Protein | displayName | =coalesce(name, biocyc_id) | -| Protein | id | =biocyc_id | -| Protein | molecular_weight_kd | MOLECULAR-WEIGHT-KD | -| Protein | name | COMMON-NAM | -| Protein | pi | PI | -| Protein | synonyms | SYNONYMS | -| Protein | location | LOCATIONS | -| Protein | GO | GO-TERMS | -| RNA | abbrev_name | ABBREV-NAME | -| RNA | biocyc_id | UNIQUE-ID | -| RNA | data_source |"BioCyc" | -| RNA | description | | -| RNA | displayName | =coalesce(name, biocyc_id) | -| RNA | id | =biocyc_id | -| RNA | location | LOCATIONS | -| RNA | name | COMMON-NAME -| Reaction | biocyc_id | UNIQUE-ID | -| Reaction | data_source |"BioCyc" | -| Reaction | description | | -| Reaction | displayName | =coalesce(ec_number, name, biocyc_id) | -| Reaction | ec_number | EC-NUMBER | -| Reaction | id | =biocyc_id | -| Reaction | name | COMMON-NAME | -| Reaction | other_name | SYSTEMATIC-NAME | -| Reaction | direction | REACTION-DIRECTION | -| Reaction | location | RXN-LOCATIONS | -| Reaction | synonyms | SYNONYMS | -| Regulation | biocyc_id | UNIQUE-ID | -| Regulation | data_source |"BioCyc" | -| Regulation | displayName | ? | -| Regulation | id | =biocyc_id | -| Regulation | mechanism | MECHANISM | -| Regulation | mode | MODE | -| Regulation | type | | -| Terminator | biocyc_id | UNIQUE-ID | -| Terminator | data_source |"BioCyc" | -| Terminator | displayName | =coalesce(name, biocyc_id) | -| Terminator | description | | -| Terminator | id | =biocyc_id | -| Terminator | left_end_position | LEFT-END-POSITION | -| Terminator | right_end_position | RIGHT-END-POSITION | -| TranscriptionUnit | biocyc_id | UNIQUE-ID | -| TranscriptionUnit | data_source |"BioCyc" | -| TranscriptionUnit | description | | -| TranscriptionUnit | displayName | | -| TranscriptionUnit | id | =biocyc_id | -| TranscriptionUnit | name | COMMON-NAME | +| Node Label | Attribute | Source | +| :---------------- | :------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| BioCycClass | biocyc_id | UNIQUE-ID | +| BioCycClass | data_source | "BioCyc" | +| BioCycClass | displayName | =coalesce(name, biocyc_id) | +| BioCycClass | id | =biocyc_id | +| BioCycClass | name | COMMON-NAME | +| BioCycClass | synonyms | SYNONYMS | +| Compound | abbrev_name | ABBREV-NAME | +| Compound | biocyc_id | UNIQUE-ID | +| Compound | data_source | "BioCyc" | +| Compound | displayName | =coalesce(name, biocyc_id) | +| Compound | id | =biocyc_id | +| Compound | inchi_key | INCHI-KEY
    remove leading 'InChIKey=' | +| Compound | name | COMMON-NAME
    strip HTML tags and remove leading 'a ' and 'an ' | +| Compound | inchi | INCHI | +| Compound | smiles | SMILES | +| DNABindingSite | abs_center_pos | ABS-CENTER-POS | +| DNABindingSite | biocyc_id | UNIQUE-ID | +| DNABindingSite | data_source | "BioCyc" | +| DNABindingSite | description | | +| DNABindingSite | displayName | =protein displayName + ' BS' of proteins linked to the DNABindingSite through Regulation

    else

    =coalesce(name, biocyc_id) | +| DNABindingSite | id | =biocyc_id | +| DNABindingSite | site_length | SITE-LENGTH | +| EnzReaction | biocyc_id | UNIQUE-ID | +| EnzReaction | data_source | "BioCyc" | +| EnzReaction | description | | +| EnzReaction | displayName | = name + gene(s) that encodes the enzyme | +| EnzReaction | id | =biocyc_id | +| EnzReaction | name | COMMON-NAME | +| EnzReaction | synonyms | SYNONYMS | +| Gene | accession | ACCESSION-1 | +| Gene | biocyc_id | UNIQUE-ID | +| Gene | data_source | "BioCyc" | +| Gene | description | | +| Gene | displayName | =coalesce(name, biocyc_id) | +| Gene | id | =biocyc_id | +| Gene | left_end_position | LEFT-END-POSITION | +| Gene | name | COMMON-NAME | +| Gene | pathways | =set_gene_property_for_enrichment() | +| Gene | right_end_position | RIGHT-END-POSITION | +| Gene | strand | TRANSCRIPTION-DIRECTION | +| Gene | synonyms | SYNONYMS | +| Pathway | biocyc_id | UNIQUE-ID | +| Pathway | data_source | "BioCyc" | +| Pathway | displayName | =coalesce(name, biocyc_id) | +| Pathway | id | =biocyc_id | +| Pathway | name | COMMON-NAME | +| Pathway | synonyms | SYNONYMS | +| Promoter | biocyc_id | UNIQUE-ID | +| Promoter | data_source | "BioCyc" | +| Promoter | description | | +| Promoter | displayName | =coalesce(name, biocyc_id) | +| Promoter | id | =biocyc_id | +| Promoter | name | COMMON-NAME | +| Promoter | pos_1 | ABSOLUTE-PLUS-1-POS | +| Promoter | strand | TRANSCRIPTION-DIRECTION | +| Promoter | synonyms | SYNONYMS | +| Protein | abbrev_name | ABBREV-NAME | +| Protein | biocyc_id | UNIQUE-ID | +| Protein | data_source | "BioCyc" | +| Protein | description | | +| Protein | displayName | =coalesce(name, biocyc_id) | +| Protein | id | =biocyc_id | +| Protein | molecular_weight_kd | MOLECULAR-WEIGHT-KD | +| Protein | name | COMMON-NAM | +| Protein | pi | PI | +| Protein | synonyms | SYNONYMS | +| Protein | location | LOCATIONS | +| Protein | GO | GO-TERMS | +| RNA | abbrev_name | ABBREV-NAME | +| RNA | biocyc_id | UNIQUE-ID | +| RNA | data_source | "BioCyc" | +| RNA | description | | +| RNA | displayName | =coalesce(name, biocyc_id) | +| RNA | id | =biocyc_id | +| RNA | location | LOCATIONS | +| RNA | name | COMMON-NAME | +| Reaction | biocyc_id | UNIQUE-ID | +| Reaction | data_source | "BioCyc" | +| Reaction | description | | +| Reaction | displayName | =coalesce(ec_number, name, biocyc_id) | +| Reaction | ec_number | EC-NUMBER | +| Reaction | id | =biocyc_id | +| Reaction | name | COMMON-NAME | +| Reaction | other_name | SYSTEMATIC-NAME | +| Reaction | direction | REACTION-DIRECTION | +| Reaction | location | RXN-LOCATIONS | +| Reaction | synonyms | SYNONYMS | +| Regulation | biocyc_id | UNIQUE-ID | +| Regulation | data_source | "BioCyc" | +| Regulation | displayName | ? | +| Regulation | id | =biocyc_id | +| Regulation | mechanism | MECHANISM | +| Regulation | mode | MODE | +| Regulation | type | | +| Terminator | biocyc_id | UNIQUE-ID | +| Terminator | data_source | "BioCyc" | +| Terminator | displayName | =coalesce(name, biocyc_id) | +| Terminator | description | | +| Terminator | id | =biocyc_id | +| Terminator | left_end_position | LEFT-END-POSITION | +| Terminator | right_end_position | RIGHT-END-POSITION | +| TranscriptionUnit | biocyc_id | UNIQUE-ID | +| TranscriptionUnit | data_source | "BioCyc" | +| TranscriptionUnit | description | | +| TranscriptionUnit | displayName | | +| TranscriptionUnit | id | =biocyc_id | +| TranscriptionUnit | name | COMMON-NAME | #### Node outgoing relationships -| StartNode | Relationship | EndNode | Cardinality | -|-----:|-----------:|-----:|-----------:| -| Class | CHEBI_LINK | Chemical | 1 | -| Class | COMPONENT_OF | Protein | + | -| Class | CONSUMED_BY | Reaction | + | -| Class | HAS_SYNONYM | Synonym | + | -| Class | REGULATES | Regulation | + | -| Class | TYPE_OF | Class | + | -| Compound | CHEBI_LINK | Chemical | 1 | -| Compound | COMPONENT_OF | Protein | + | -| Compound | CONSUMED_BY | Reaction | + | -| Compound | HAS_SYNONYM | Synonym | + | -| Compound | REGULATES | Regulation | + | -| Compound | TYPE_OF | Class | + | -| DNABindingSite | ELEMENT_OF | TranscriptionUnit | 1 | -| EnzReaction | CATALYZES | Reaction | 1 | -| EnzReaction | HAS_SYNONYM | Synonym | + | -| Gene | ELEMENT_OF | TranscriptionUnit | 1 | -| Gene | ENCODES | Protein | 1 | -| Gene | ENCODES | RNA | 1 | -| Gene | HAS_SYNONYM | Synonym | + | -| Gene | IS | db_NCBI Gene | 1 | -| Pathway | HAS_SYNONYM | Synonym | + | -| Pathway | IN_PATHWAY | Pathway | 1 | -| Pathway | TYPE_OF | Class | + | -| Promoter | ELEMENT_OF | TranscriptionUnit | 1 | -| Promoter | HAS_SYNONYM | Synonym | + | -| Protein | CATALYZES | EnzReaction | + | -| Protein | COMPONENT_OF | Protein | + | -| Protein | CONSUMED_BY | Reaction | + | -| Protein | GO_LINK | db_GO | + | -| Protein | HAS_SYNONYM | Synonym | + | -| Protein | MODIFIED_TO | Protein | + | -| Protein | REGULATES | Regulation | + | -| Protein | TYPE_OF | Class | + | -| RNA | COMPONENT_OF | Protein | + | -| RNA | CONSUMED_BY | Reaction | + | -| RNA | HAS_SYNONYM | Synonym | + | -| RNA | MODIFIED_TO | RNA | + | -| RNA | REGULATES | Regulation | + | -| RNA | TYPE_OF | Class | + | -| Reaction | ENZYME_LINK | EC_Number | + | -| Reaction | HAS_SYNONYM | Synonym | + | -| Reaction | IN_PATHWAY | Pathway | + | -| Reaction | PRODUCES | Class | + | -| Reaction | PRODUCES | Compound | + | -| Reaction | PRODUCES | Protein | + | -| Reaction | TYPE_OF | Class | + | -| Regulation | BINDS | DNABindingSite | 1 | -| Regulation | REGULATES | EnzReaction | 1 | -| Regulation | REGULATES | Gene | 1 | -| Regulation | REGULATES | Promoter | 1 | -| Regulation | REGULATES | Protein | 1 | -| Regulation | REGULATES | Reaction | 1 | -| Regulation | REGULATES | Terminator | 1 | -| Regulation | REGULATES | TranscriptionUnit | 1 | -| Regulation | TYPE_OF | Class | + | -| Terminator | ELEMENT_OF | TranscriptionUnit | 1 | -| TranscriptionUnit | HAS_SYNONYM | Synonym | + | - +| StartNode | Relationship | EndNode | Cardinality | +| ----------------: | -----------: | ----------------: | ----------: | +| Class | CHEBI_LINK | Chemical | 1 | +| Class | COMPONENT_OF | Protein | + | +| Class | CONSUMED_BY | Reaction | + | +| Class | HAS_SYNONYM | Synonym | + | +| Class | REGULATES | Regulation | + | +| Class | TYPE_OF | Class | + | +| Compound | CHEBI_LINK | Chemical | 1 | +| Compound | COMPONENT_OF | Protein | + | +| Compound | CONSUMED_BY | Reaction | + | +| Compound | HAS_SYNONYM | Synonym | + | +| Compound | REGULATES | Regulation | + | +| Compound | TYPE_OF | Class | + | +| DNABindingSite | ELEMENT_OF | TranscriptionUnit | 1 | +| EnzReaction | CATALYZES | Reaction | 1 | +| EnzReaction | HAS_SYNONYM | Synonym | + | +| Gene | ELEMENT_OF | TranscriptionUnit | 1 | +| Gene | ENCODES | Protein | 1 | +| Gene | ENCODES | RNA | 1 | +| Gene | HAS_SYNONYM | Synonym | + | +| Gene | IS | db_NCBI Gene | 1 | +| Pathway | HAS_SYNONYM | Synonym | + | +| Pathway | IN_PATHWAY | Pathway | 1 | +| Pathway | TYPE_OF | Class | + | +| Promoter | ELEMENT_OF | TranscriptionUnit | 1 | +| Promoter | HAS_SYNONYM | Synonym | + | +| Protein | CATALYZES | EnzReaction | + | +| Protein | COMPONENT_OF | Protein | + | +| Protein | CONSUMED_BY | Reaction | + | +| Protein | GO_LINK | db_GO | + | +| Protein | HAS_SYNONYM | Synonym | + | +| Protein | MODIFIED_TO | Protein | + | +| Protein | REGULATES | Regulation | + | +| Protein | TYPE_OF | Class | + | +| RNA | COMPONENT_OF | Protein | + | +| RNA | CONSUMED_BY | Reaction | + | +| RNA | HAS_SYNONYM | Synonym | + | +| RNA | MODIFIED_TO | RNA | + | +| RNA | REGULATES | Regulation | + | +| RNA | TYPE_OF | Class | + | +| Reaction | ENZYME_LINK | EC_Number | + | +| Reaction | HAS_SYNONYM | Synonym | + | +| Reaction | IN_PATHWAY | Pathway | + | +| Reaction | PRODUCES | Class | + | +| Reaction | PRODUCES | Compound | + | +| Reaction | PRODUCES | Protein | + | +| Reaction | TYPE_OF | Class | + | +| Regulation | BINDS | DNABindingSite | 1 | +| Regulation | REGULATES | EnzReaction | 1 | +| Regulation | REGULATES | Gene | 1 | +| Regulation | REGULATES | Promoter | 1 | +| Regulation | REGULATES | Protein | 1 | +| Regulation | REGULATES | Reaction | 1 | +| Regulation | REGULATES | Terminator | 1 | +| Regulation | REGULATES | TranscriptionUnit | 1 | +| Regulation | TYPE_OF | Class | + | +| Terminator | ELEMENT_OF | TranscriptionUnit | 1 | +| TranscriptionUnit | HAS_SYNONYM | Synonym | + | ### Scripts to run after biocyc data updated + 1. add protein synonyms for uniprot (see biocyc_protein_synonyms_for_uniprot.md) 2. set displayname and description 3. set data sources + ``` match(n:db_BioCyc) set n.data_source='BioCyc' ``` -### Set PseudomonasCyc genes as Master genes for Lifelike searching and annotations +### Set PseudomonasCyc genes as Master genes for Lifelike searching and annotations + Since Pseudomonas putida KT2440 (taxID 160488) genes do not have NCBI gene links for now, we need to set Pseudomoas genes as Master gene. -Once NCBI integrated those genes, the steps can be removed -- Follow the steps described in file 'Label_biocyc_genes_as_master.md' to update neo4j -- Generate LMDB annotation file if PseudomonasCyc updated, and handle to Binh. +Once NCBI integrated those genes, the steps can be removed + +- Follow the steps described in file 'Label_biocyc_genes_as_master.md' to update neo4j +- Generate LMDB annotation file if PseudomonasCyc updated, and handle to Binh. + ``` src/biocyc/LMDB_annotation.generate_pseudomonas_genelist_for_LMDB ``` - - - - diff --git a/graph-db/extractor/docs/kegg/kegg_spec.md b/graph-db/extractor/docs/kegg/kegg_spec.md index 9fee066ba2..5fcb682a1c 100644 --- a/graph-db/extractor/docs/kegg/kegg_spec.md +++ b/graph-db/extractor/docs/kegg/kegg_spec.md @@ -5,64 +5,69 @@ broadly categorized into systems information, genomic information, chemical information, and health information. The database names and the corresponding subdirectory names on this FTP site are as follows: -#### Systems information - - KEGG PATHWAY: pathway, xml; KEGG pathway maps - - KEGG BRITE: brite; BRITE functional hierarchies - - KEGG MODULE: module; KEGG modules - #### Genomic information - - KEGG ORTHOLOGY (KO) genes KO functional orthologs - - KEGG GENOME genes KEGG organisms (complete genomes) - - KEGG GENES genes Gene catalogs of KEGG organisms - - KEGG SSDB GENES sequence similarity - #### Chemical information - - KEGG COMPOUND ligand Metabolites and other small molecules - - KEGG GLYCAN ligand Glycans - - KEGG REACTION ligand Biochemical reactions - - KEGG RCLASS ligand Reaction class - - KEGG ENZYME ligand Enzyme nomenclature - #### Health information - - KEGG NETWORK medicus Disease-related network elements - - KEGG VARIANT medicus Human gene variants - - KEGG DISEASE medicus Human diseases - - KEGG DRUG medicus Drugs - - KEGG DGROUP medicus Drug groups - - KEGG ENVIRON medicus Crude drugs and health-related substances +#### Systems information + +- KEGG PATHWAY: pathway, xml; KEGG pathway maps +- KEGG BRITE: brite; BRITE functional hierarchies +- KEGG MODULE: module; KEGG modules + +#### Genomic information + +- KEGG ORTHOLOGY (KO) genes KO functional orthologs +- KEGG GENOME genes KEGG organisms (complete genomes) +- KEGG GENES genes Gene catalogs of KEGG organisms +- KEGG SSDB GENES sequence similarity + +#### Chemical information + +- KEGG COMPOUND ligand Metabolites and other small molecules +- KEGG GLYCAN ligand Glycans +- KEGG REACTION ligand Biochemical reactions +- KEGG RCLASS ligand Reaction class +- KEGG ENZYME ligand Enzyme nomenclature + +#### Health information + +- KEGG NETWORK medicus Disease-related network elements +- KEGG VARIANT medicus Human gene variants +- KEGG DISEASE medicus Human diseases +- KEGG DRUG medicus Drugs +- KEGG DGROUP medicus Drug groups +- KEGG ENVIRON medicus Crude drugs and health-related substances ## KEGG Pathway Maps #### Pathway Types + - metabolic - non-metabolic -#### Reference pathway map: +#### Reference pathway map: + - linked to KO entries (K numbers) - linked to Enzyme entries (EC numbers) - linked to Reaction entries (R numbers) #### Organism-specific map: + - linked to GENES entries (gene ids) ## Download Data -KEGG database download is not free. Check Vincenzo for license information. + +KEGG database download is not free. Check Vincenzo for license information. url: ftp://ftp.kegg.net + #### Files needed for current KG: -- genes/ko/ko (in ko.tar.gz) -- genes/genes_ncbi-geneid.list (from genes/links/genes_ncbi-geneid.list.gz) -- pathway/pathway.list -- pathway/links/pathway_ko.list (links.tar.gz) -- pathway/links/pathway_genome.list (links.tar.gz) + +- genes/ko/ko (in ko.tar.gz) +- genes/genes_ncbi-geneid.list (from genes/links/genes_ncbi-geneid.list.gz) +- pathway/pathway.list +- pathway/links/pathway_ko.list (links.tar.gz) +- pathway/links/pathway_genome.list (links.tar.gz) ## KEGG KG Schema + The current kegg kg was used for annotation only. KEGG data has rich information about reactions, enzymes and pathways and their assocations with diseases and drugs. Additional information could be loaded in the future. ![](KEGG_kg_nodes.png) - - - - - - - - - diff --git a/graph-db/extractor/docs/literature/literature_spec.md b/graph-db/extractor/docs/literature/literature_spec.md index 17baeb5618..158c3d6e23 100644 --- a/graph-db/extractor/docs/literature/literature_spec.md +++ b/graph-db/extractor/docs/literature/literature_spec.md @@ -1,9 +1,10 @@ # Zenodo Literature Data Set -- paper: https://zenodo.org/record/3459420#.XfAH6JNKiBu -- download the files to folder $BASE_DATA_DIR/download/literature/. Make sure to get the latest version (Sept 24, 2019). +- paper: https://zenodo.org/record/3459420#.XfAH6JNKiBu +- download the files to folder $BASE_DATA_DIR/download/literature/. Make sure to get the latest version (Sept 24, 2019). + +Download all the part-i-_.txt.gz and part-ii-_-with-themes.txt.gz files -Download all the part-i-*.txt.gz and part-ii-*-with-themes.txt.gz files ```bash > cd graph-db/extraction/data/download/literature > ./download.sh @@ -14,23 +15,24 @@ Download all the part-i-*.txt.gz and part-ii-*-with-themes.txt.gz files ![](img/LiteratureGraphDiagram_new.png) The relationship 'PREDICTS' changed to 'INDICATES' -## Old parser link: +## Old parser link: + https://github.com/SBRG/graphdb_prototypes/blob/master/src/loader/literature/literature_data_parser.py The parser may need to update to reflect the new schema. + 1. The old gene, chemical and disease only have one column for the id's. Since Literature data will be in separate domain in the new schema. -Those files will need the following properties: [id, synonyms, id_source], where id need to remove the prefix (MESH, CHEBI etc) so that -it would be easier to create the 'mapped_to' links. id', and the prefix can be stored as 'id_source'. -2. Since the literature sentence would use different names (as entry_text in INDICATES), -you may need to set the name field later (after mapped to reference Gene, Chemical or Disease). I would suggest to put all the 'entry_text' into -'synonyms' property, and separate the terms using |. -3. After literature data loaded (all nodes for db_Literature), use cypher to create the MAPPED_TO relationships, then based on the -mapped entity, set literature entity name. If a literature entity could be mapped, choose the first term in the synonyms as its name. + Those files will need the following properties: [id, synonyms, id_source], where id need to remove the prefix (MESH, CHEBI etc) so that + it would be easier to create the 'mapped_to' links. id', and the prefix can be stored as 'id_source'. +2. Since the literature sentence would use different names (as entry_text in INDICATES), + you may need to set the name field later (after mapped to reference Gene, Chemical or Disease). I would suggest to put all the 'entry_text' into + 'synonyms' property, and separate the terms using |. +3. After literature data loaded (all nodes for db_Literature), use cypher to create the MAPPED_TO relationships, then based on the + mapped entity, set literature entity name. If a literature entity could be mapped, choose the first term in the synonyms as its name. 4. Make sure to check the current database properties for Association and Snippet and INDICATES, and put the data into the correct output file. -The current parser output files were for the old data schema. -5. If you load data into a brand-new database, make sure to create constraints first (for snippet id, association id, LiteratureEntity id). -Otherwise, the merge and relationships creation will be very very slow + The current parser output files were for the old data schema. +5. If you load data into a brand-new database, make sure to create constraints first (for snippet id, association id, LiteratureEntity id). + Otherwise, the merge and relationships creation will be very very slow 6. snippet_id = pmid + sentence_num (refectoring query: SET n.id = p.pmid + '-' + n.sentence_num) -7. association_id = entry1_id + entry2_id + type (refectoring query: SET a.id = n1.id + '-' + n2.id + '-' + a.type) +7. association_id = entry1_id + entry2_id + type (refectoring query: SET a.id = n1.id + '-' + n2.id + '-' + a.type) 8. Don't forget to use eid instead of id - diff --git a/graph-db/extractor/docs/mesh/mesh_rdf_data_model.md b/graph-db/extractor/docs/mesh/mesh_rdf_data_model.md index de7130bf9a..3bdedce350 100644 --- a/graph-db/extractor/docs/mesh/mesh_rdf_data_model.md +++ b/graph-db/extractor/docs/mesh/mesh_rdf_data_model.md @@ -1,53 +1,66 @@ # MeSH Data Model (RDF imported database, not Lifelike) -### Descriptors -https://hhs.github.io/meshrdf/descriptors -MeSH headings, used to index citations in the NLM MEDLINE database and to describe the subjects for NLM Catalog + +### Descriptors + +https://hhs.github.io/meshrdf/descriptors +MeSH headings, used to index citations in the NLM MEDLINE database and to describe the subjects for NLM Catalog records. Subclss of Descriptors: -- TopicalDescriptor -- PublicationType -- CheckTag -- GeographicalDescriptor -### Qualifiers +- TopicalDescriptor +- PublicationType +- CheckTag +- GeographicalDescriptor + +### Qualifiers + A MeSH subheading, used to give additional context to a Descriptor. -MeSH has rules governing which Qualifiers can be used with a given Descriptor, +MeSH has rules governing which Qualifiers can be used with a given Descriptor, as well as which Qualifers cannot be used with a given Descriptor (pairs) ### Descriptor-Qualifier Pairs + https://hhs.github.io/meshrdf/descriptor-qualifier-pairs -- Qualifiers comprise a set of 83 terms used to add more specificity to descriptors. -- Each Descriptor has a set of Allowable Qualifiers -- Example: - - Descriptor (D015242, Ofloxacin) and one of its Allowable Qualifiers (Q000008, administration & dosage) - -### Supplementary Concept Records (SCR) + +- Qualifiers comprise a set of 83 terms used to add more specificity to descriptors. +- Each Descriptor has a set of Allowable Qualifiers +- Example: + - Descriptor (D015242, Ofloxacin) and one of its Allowable Qualifiers (Q000008, administration & dosage) + +### Supplementary Concept Records (SCR) + https://hhs.github.io/meshrdf/scrs There are four sub-classes: SCR_Chemical SCR_Disease SCR_Organism SCR_Protocol - + ### Concepts -https://hhs.github.io/meshrdf/concepts + +https://hhs.github.io/meshrdf/concepts A MeSH Concept represents a unit of meaning, all assigned ‘M’ identifiers. -- Each MeSH record consists of one or more Concepts -- Each Concept consists in one or more synonymous terms -- Collections of concepts are placed into MeSH Descriptor for topic search and retrieval + +- Each MeSH record consists of one or more Concepts +- Each Concept consists in one or more synonymous terms +- Collections of concepts are placed into MeSH Descriptor for topic search and retrieval ### Terms -https://hhs.github.io/meshrdf/terms + +https://hhs.github.io/meshrdf/terms A term is a human readable name used by a MeSH Concept. Within a MeSH concept, terms are strictly synonymous ### Tree Numbers + https://hhs.github.io/meshrdf/tree-numbers -MeSH descriptors are organized into 16 categories, each of which is further divided into sub-categories to assist in more specific classification of a descriptor. -- These hierarchical categories and subcategories are identified by MeSH tree numbers. -- A given MeSH descriptor often has more than one tree number assigned to it, meaning that it fits into the category hierarchies in multiple places. +MeSH descriptors are organized into 16 categories, each of which is further divided into sub-categories to assist in more specific classification of a descriptor. + +- These hierarchical categories and subcategories are identified by MeSH tree numbers. +- A given MeSH descriptor often has more than one tree number assigned to it, meaning that it fits into the category hierarchies in multiple places. Example: B03, B03.660, B03.660.075, B03.660.075.090.344 ## Mesh Neo4j Graph Model (RDF imported graph) -![](img/mesh_rdf_model.png) \ No newline at end of file + +![](img/mesh_rdf_model.png) diff --git a/graph-db/extractor/docs/ncbi/taxonomy_spec.md b/graph-db/extractor/docs/ncbi/taxonomy_spec.md index af864e5b58..4249adfd27 100644 --- a/graph-db/extractor/docs/ncbi/taxonomy_spec.md +++ b/graph-db/extractor/docs/ncbi/taxonomy_spec.md @@ -1,40 +1,45 @@ # NCBI Taxonomy -The NCBI Taxonomy database (http://www.ncbi.nlm.nih.gov/taxonomy) is the standard nomenclature and classification repository -for the International Nucleotide Sequence Database Collaboration (INSDC), comprising the GenBank, ENA (EMBL) and DDBJ databases. +The NCBI Taxonomy database (http://www.ncbi.nlm.nih.gov/taxonomy) is the standard nomenclature and classification repository +for the International Nucleotide Sequence Database Collaboration (INSDC), comprising the GenBank, ENA (EMBL) and DDBJ databases. It includes organism names and taxonomic lineages for each of the sequences represented in the INSDC's nucleotide and protein -sequence databases (reference: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3245000/). +sequence databases (reference: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3245000/). #### Top lavel taxonomy: -- Archaea -- Bacteria -- Eukaryota -- Viruses -- Other: Other artificial sequences -- Unclassified -The organism classification should include the first 4 catagories, and remove taxnomy with name "environmental samples". +- Archaea +- Bacteria +- Eukaryota +- Viruses +- Other: Other artificial sequences +- Unclassified + +The organism classification should include the first 4 catagories, and remove taxnomy with name "environmental samples". NCBI taxonomy download link: https://ftp.ncbi.nlm.nih.gov/pub/taxonomy/new_taxdump/ -#### NCBI Taxonomy Nodes in KG: -- Labels: [db_NCBI, Taxonomy] -- Node Properties: - - id: tax_id - - name: scientific name - - rank: In biological classification, taxonomic rank is the relative level of a group of organisms (a taxon) in a taxonomic hierarchy. - Examples of taxonomic ranks are species, genus, family, order, class, phylum, kingdom, domain, etc. - - species_id: species tax_id, only for organism with rank as species or below species - - data_source: NCBI Taxonomy - +#### NCBI Taxonomy Nodes in KG: + +- Labels: [db_NCBI, Taxonomy] +- Node Properties: + - id: tax_id + - name: scientific name + - rank: In biological classification, taxonomic rank is the relative level of a group of organisms (a taxon) in a taxonomic hierarchy. + Examples of taxonomic ranks are species, genus, family, order, class, phylum, kingdom, domain, etc. + - species_id: species tax_id, only for organism with rank as species or below species + - data_source: NCBI Taxonomy + #### Taxonomy parser improvement -- The current parser could be rewritten using pandas. -- Currently the data were parsed and written into files. The parser then used the output file to load data. The output -files could be eliminated and neo4j data loading could be done using the parsed data directly + +- The current parser could be rewritten using pandas. +- Currently the data were parsed and written into files. The parser then used the output file to load data. The output + files could be eliminated and neo4j data loading could be done using the parsed data directly #### Additional synonyms for strains (no rank, children nodes under species) (LL-1802) -combined all synonyms from species as string, and added as synonym for children nodes. This could help children nodes search -using a species synonym which is not part of strain synonym. Not sure if we need to update this for each taxnomy updates. + +combined all synonyms from species as string, and added as synonym for children nodes. This could help children nodes search +using a species synonym which is not part of strain synonym. Not sure if we need to update this for each taxnomy updates. + ``` match (n:Taxonomy) where n.rank='species' and (()-[:HAS_PARENT]->(n)) with n match (n)-[:HAS_SYNONYM]->(s) with n, collect(s.name) as syns @@ -45,37 +50,21 @@ using a species synonym which is not part of strain synonym. Not sure if we need with t, synonym, [s in syns where not synonym contains s] as syns where size(syns)>0 with t, apoc.text.join([synonym] + syns, '|') as syn where size(syn) < 9000 merge (s:Synonym {name:syn}) - merge (t)-[:HAS_SYNONYM {type:'combined terms'}]->(s) + merge (t)-[:HAS_SYNONYM {type:'combined terms'}]->(s) ``` #### LMDB Annotation file + In the LMDB file, set the species' tax_id as the default strain id so that any searching for the species will map to the default strain -| Strain tax_id | strain_name | species_id | species_name | -|:------ |: ---------- |: --------- |: ----------- | -| 367830 | Staphylococcus aureus subsp. aureus USA300 | 46170 | Staphylococcus aureus subsp. aureus | -| 367830 | Staphylococcus aureus subsp. aureus USA300 | 1280 | Staphylococcus aureus | -| 511145 | Escherichia coli str. K-12 substr. MG1655 | 83333 | Escherichia coli K-12 | -| 511145 | Escherichia coli str. K-12 substr. MG1655 | 562 | Escherichia coli | -| 272563 | Clostridioides difficile 630 | 1496 | Clostridioides difficile | -| 208964 | Pseudomonas aeruginosa PAO1 | 287 | Pseudomonas aeruginosa | -| 559292 | Saccharomyces cerevisiae S288C | 4932 | Saccharomyces cerevisiae | +| Strain tax_id | strain_name | species_id | species_name | +| :------------ | :----------------------------------------- | :--------- | :---------------------------------- | +| 367830 | Staphylococcus aureus subsp. aureus USA300 | 46170 | Staphylococcus aureus subsp. aureus | +| 367830 | Staphylococcus aureus subsp. aureus USA300 | 1280 | Staphylococcus aureus | +| 511145 | Escherichia coli str. K-12 substr. MG1655 | 83333 | Escherichia coli K-12 | +| 511145 | Escherichia coli str. K-12 substr. MG1655 | 562 | Escherichia coli | +| 272563 | Clostridioides difficile 630 | 1496 | Clostridioides difficile | +| 208964 | Pseudomonas aeruginosa PAO1 | 287 | Pseudomonas aeruginosa | +| 559292 | Saccharomyces cerevisiae S288C | 4932 | Saccharomyces cerevisiae | See taxonomy_LMDB_annotation.py to generate LMDB annotation file - - - - - - - - - - - - - - - - - diff --git a/graph-db/extractor/docs/other/scripts for LMDB annotation file.md b/graph-db/extractor/docs/other/scripts for LMDB annotation file.md index 7f13448719..bc9610de9d 100644 --- a/graph-db/extractor/docs/other/scripts for LMDB annotation file.md +++ b/graph-db/extractor/docs/other/scripts for LMDB annotation file.md @@ -1,25 +1,22 @@ # Scripts for generating LMDB annotation files (LL-3389) ### Generate LMDB annotation list for the following entities -- Gene: NCBI genes and Psueodmonas genes -- Protein: Uniprot protein -- Chemical: ChEBI chemicals -- Compound: Biocyc Compound -- Taxnomy: NCBI taxonomy -- Disease: MeSH -- Food: MeSH -- Anatomy: MeSH -- Phenomena: MeSH +- Gene: NCBI genes and Psueodmonas genes +- Protein: Uniprot protein +- Chemical: ChEBI chemicals +- Compound: Biocyc Compound +- Taxnomy: NCBI taxonomy +- Disease: MeSH +- Food: MeSH +- Anatomy: MeSH +- Phenomena: MeSH ### Python files -- ncbi/gene_LMDB_annotation.py -- ncbi/taxonomy_LMDB_annotation.py -- chebi/chebi_LMDB_annotation.py -- mesh/mesh_LMDB_annotation.py (Disease, Food, Anatomy, Phenomena) -- uniprot/uniprot_LMDB_annotation.py (Protein) -- biocyc/biocyc_LMDB_annotaiton.py (Compound, Gene) - - - +- ncbi/gene_LMDB_annotation.py +- ncbi/taxonomy_LMDB_annotation.py +- chebi/chebi_LMDB_annotation.py +- mesh/mesh_LMDB_annotation.py (Disease, Food, Anatomy, Phenomena) +- uniprot/uniprot_LMDB_annotation.py (Protein) +- biocyc/biocyc_LMDB_annotaiton.py (Compound, Gene) diff --git a/graph-db/extractor/src/biocyc/data_sources.json b/graph-db/extractor/src/biocyc/data_sources.json index c42fab9f74..76ee770860 100644 --- a/graph-db/extractor/src/biocyc/data_sources.json +++ b/graph-db/extractor/src/biocyc/data_sources.json @@ -1,22 +1,22 @@ [ - { - "name": "PseudomonasCyc", - "file": "pput160488cyc.tar.gz" - }, - { - "name": "YeastCyc", - "file": "yeast.tar.gz" - }, - { - "name": "EcoCyc", - "file": "ecoli.tar.gz" - }, - { - "name": "HumanCyc", - "file": "human.tar.gz" - }, - { - "name": "MetaCyc", - "file": "meta.tar.gz" - } -] \ No newline at end of file + { + "name": "PseudomonasCyc", + "file": "pput160488cyc.tar.gz" + }, + { + "name": "YeastCyc", + "file": "yeast.tar.gz" + }, + { + "name": "EcoCyc", + "file": "ecoli.tar.gz" + }, + { + "name": "HumanCyc", + "file": "human.tar.gz" + }, + { + "name": "MetaCyc", + "file": "meta.tar.gz" + } +] diff --git a/graph-db/migrator/README.md b/graph-db/migrator/README.md index edcdb210c6..b9aca9040f 100644 --- a/graph-db/migrator/README.md +++ b/graph-db/migrator/README.md @@ -30,10 +30,10 @@ docket run --rm \ | Variable | Default | Comment | | -------------------------- | -------------- | ----------------------------------- | | CHANGELOG_DIR | lifelike-graph | Master changelog directory path | -| ARANGODB_HOST | | Host and port of ArangoDB instance | -| ARANGODB_USERNAME | neo4j | ArangoDB authentication username | -| ARANGODB_PASSWORD | password | ArangoDB authentication password | -| ARANGODB_DATABASE | neo4j | ArangoDB target database | +| ARANGODB_HOST | | Host and port of ArangoDB instance | +| ARANGODB_USERNAME | neo4j | ArangoDB authentication username | +| ARANGODB_PASSWORD | password | ArangoDB authentication password | +| ARANGODB_DATABASE | neo4j | ArangoDB target database | | STORAGE_TYPE | azure | Remote storage type to get TSV data | | AZURE_ACCOUNT_STORAGE_NAME | | Azure Storage Account Name | | AZURE_ACCOUNT_STORAGE_KEY | | Azure Storage Key | @@ -41,8 +41,8 @@ docket run --rm \ ### Docker build arguments -| Argument | Default value | Comment | -| ----------------------- | ------------- | ------- | -| LIQUIBASE_IMAGE_TAG | 4.6 | Tag of the [Liquibase Docker image](https://hub.docker.com/r/liquibase/liquibase/tags) to use | -| LIQUIBASE_ARANGODB_VERSION | 4.6.2 | [Liquibase-ArangoDB plugin](https://github.com/liquibase/liquibase-neo4j) version to install | -| ARANGODB_JDBC_VERSION | 4.0.5 | ArangoDB JDBC driver version | +| Argument | Default value | Comment | +| -------------------------- | ------------- | --------------------------------------------------------------------------------------------- | +| LIQUIBASE_IMAGE_TAG | 4.6 | Tag of the [Liquibase Docker image](https://hub.docker.com/r/liquibase/liquibase/tags) to use | +| LIQUIBASE_ARANGODB_VERSION | 4.6.2 | [Liquibase-ArangoDB plugin](https://github.com/liquibase/liquibase-neo4j) version to install | +| ARANGODB_JDBC_VERSION | 4.0.5 | ArangoDB JDBC driver version | diff --git a/helm/lifelike/README.md b/helm/lifelike/README.md index 6fa2107749..041ba87563 100644 --- a/helm/lifelike/README.md +++ b/helm/lifelike/README.md @@ -17,47 +17,48 @@ helm install lifelike lifelike/lifelike Kubernetes: `>=1.20.0-0` -| Repository | Name | Version | -|------------|------|---------| -| https://charts.bitnami.com/bitnami | postgresql | 11.0.4 | -| https://charts.bitnami.com/bitnami | redis | 16.2.0 | -| https://helm.elastic.co | elasticsearch | 7.16.3 | -| https://github.com/arangodb/kube-arangodb | kube-arangodb | 1.2.39 | +| Repository | Name | Version | +| ----------------------------------------- | ------------- | ------- | +| https://charts.bitnami.com/bitnami | postgresql | 11.0.4 | +| https://charts.bitnami.com/bitnami | redis | 16.2.0 | +| https://helm.elastic.co | elasticsearch | 7.16.3 | +| https://github.com/arangodb/kube-arangodb | kube-arangodb | 1.2.39 | ## Values -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| ingress | object | `{"annotations":{},"className":"","enabled":false,"hostname":"lifelike.local","tls":[]}` | --------------------------------------------------------------------------- | -| api | object | `{"autoScaling":{"enabled":false,"maxReplicas":4,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"dbWaiter":{"image":{"imagePullPolicy":"IfNotPresent","repository":"willwill/wait-for-it","tag":"latest"},"timeoutSeconds":30},"extraEnv":{"INITIAL_ADMIN_EMAIL":"admin@example.com"},"extraVolumeMounts":[],"extraVolumes":[],"image":{"repository":"ghcr.io/sbrg/lifelike-appserver","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/meta","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"lmdb":{"loadEnabled":false},"podSecurityContext":{"runAsUser":0},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/meta","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{"requests":{"ephemeral-storage":"8Gi"}},"secret":"secret","service":{"port":5000,"type":"ClusterIP"},"strategyType":"RollingUpdate"}` | ---------------------------------------------------------------------------- | -| api.extraEnv | object | `{"INITIAL_ADMIN_EMAIL":"admin@example.com"}` | Extra environment variables to pass to the appserver | -| api.lmdb.loadEnabled | bool | `false` | Load LMDB data from storage when initializing | -| api.replicaCount | int | `1` | Number of replicas running the appserver | -| api.autoScaling.enabled | bool | `false` | If enabled, value at api.replicaCount will be ignored | -| api.strategyType | string | `"RollingUpdate"` | if using some PV that does not support readWriteMany, set this to 'Recreate' | -| api.resources | object | `{"requests":{"ephemeral-storage":"8Gi"}}` | Optional resources requests and limits | -| frontend | object | `{"autoScaling":{"enabled":false,"maxReplicas":5,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"image":{"repository":"ghcr.io/sbrg/lifelike-frontend","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":80,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | -| statisticalEnrichment | object | `{"image":{"repository":"ghcr.io/sbrg/lifelike-statistical-enrichment","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":5000,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | -| pdfparser | object | `{"autoScaling":{"enabled":false,"maxReplicas":4,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"image":{"repository":"ghcr.io/sbrg/lifelike-pdfparser","tag":"latest"},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":7600,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | -| postgresqlExternal | object | `{"database":"postgres","existingSecret":"","host":"postgres.local","password":"password","port":5432,"user":"postgres"}` | ---------------------------------------------------------------------------- | -| arangodbExternal.host | string | `"arangodb.local"` | | -| arangodbExternal.port | int | `7687` | | -| arangodbExternal.user | string | `"arangodb"` | | -| arangodbExternal.password | string | `"password"` | | -| arangodbExternal.database | string | `"arangodb"` | | -| redisExternal.host | string | `"redis.local"` | | -| redisExternal.port | int | `6379` | | -| redisExternal.password | string | `""` | | -| elasticsearchExternal.host | string | `"elasticsearch.local"` | | -| elasticsearchExternal.port | int | `9200` | | -| elasticsearchExternal.user | string | `""` | | -| elasticsearchExternal.password | string | `""` | | -| elasticsearchExternal.ssl | bool | `false` | | -| postgresql | object | `{"auth":{"database":"database","postgresPassword":"password"},"enabled":true}` | ---------------------------------------------------------------------------- | -| postgresql.enabled | bool | `true` | Set to false to disable automatic deployment of PostgreSQL | -| arangodb | object | `{"core":{"numberOfServers":1,"persistentVolume":{"size":"100Gi"},"standalone":true},"enabled":true,"imageTag":"4.4.3-community","arangodbPassword":"password"}` | ---------------------------------------------------------------------------- | -| elasticsearch | object | `{"enabled":true,"esConfig":{"elasticsearch.yml":"node.store.allow_mmap: false\n"},"fullnameOverride":"elasticsearch","image":"ghcr.io/sbrg/lifelike-elasticsearch","imageTag":"7.16.3","volumeClaimTemplate":{"resources":{"requests":{"storage":"30Gi"}}}}` | ---------------------------------------------------------------------------- | -| redis | object | `{"auth":{"password":"password"},"commonConfiguration":"# Disable persistence to disk\nsave \"\"\n# Disable AOF https://redis.io/topics/persistence#append-only-file\nappendonly no","enabled":true,"master":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}},"replica":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}}}` | ---------------------------------------------------------------------------- | - ----------------------------------------------- +| Key | Type | Default | Description | +| ------------------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| ingress | object | `{"annotations":{},"className":"","enabled":false,"hostname":"lifelike.local","tls":[]}` | --------------------------------------------------------------------------- | +| api | object | `{"autoScaling":{"enabled":false,"maxReplicas":4,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"dbWaiter":{"image":{"imagePullPolicy":"IfNotPresent","repository":"willwill/wait-for-it","tag":"latest"},"timeoutSeconds":30},"extraEnv":{"INITIAL_ADMIN_EMAIL":"admin@example.com"},"extraVolumeMounts":[],"extraVolumes":[],"image":{"repository":"ghcr.io/sbrg/lifelike-appserver","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/meta","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"lmdb":{"loadEnabled":false},"podSecurityContext":{"runAsUser":0},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/meta","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{"requests":{"ephemeral-storage":"8Gi"}},"secret":"secret","service":{"port":5000,"type":"ClusterIP"},"strategyType":"RollingUpdate"}` | ---------------------------------------------------------------------------- | +| api.extraEnv | object | `{"INITIAL_ADMIN_EMAIL":"admin@example.com"}` | Extra environment variables to pass to the appserver | +| api.lmdb.loadEnabled | bool | `false` | Load LMDB data from storage when initializing | +| api.replicaCount | int | `1` | Number of replicas running the appserver | +| api.autoScaling.enabled | bool | `false` | If enabled, value at api.replicaCount will be ignored | +| api.strategyType | string | `"RollingUpdate"` | if using some PV that does not support readWriteMany, set this to 'Recreate' | +| api.resources | object | `{"requests":{"ephemeral-storage":"8Gi"}}` | Optional resources requests and limits | +| frontend | object | `{"autoScaling":{"enabled":false,"maxReplicas":5,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"image":{"repository":"ghcr.io/sbrg/lifelike-frontend","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":80,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | +| statisticalEnrichment | object | `{"image":{"repository":"ghcr.io/sbrg/lifelike-statistical-enrichment","tag":""},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/healthz","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":5000,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | +| pdfparser | object | `{"autoScaling":{"enabled":false,"maxReplicas":4,"minReplicas":2,"targetCPUUtilizationPercentage":80,"targetMemoryUtilizationPercentage":80},"image":{"repository":"ghcr.io/sbrg/lifelike-pdfparser","tag":"latest"},"livenessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"readinessProbe":{"enabled":true,"failureThreshold":20,"initialDelaySeconds":20,"path":"/","periodSeconds":10,"successThreshold":1,"timeoutSeconds":10},"replicaCount":1,"resources":{},"service":{"port":7600,"type":"ClusterIP"}}` | ---------------------------------------------------------------------------- | +| postgresqlExternal | object | `{"database":"postgres","existingSecret":"","host":"postgres.local","password":"password","port":5432,"user":"postgres"}` | ---------------------------------------------------------------------------- | +| arangodbExternal.host | string | `"arangodb.local"` | | +| arangodbExternal.port | int | `7687` | | +| arangodbExternal.user | string | `"arangodb"` | | +| arangodbExternal.password | string | `"password"` | | +| arangodbExternal.database | string | `"arangodb"` | | +| redisExternal.host | string | `"redis.local"` | | +| redisExternal.port | int | `6379` | | +| redisExternal.password | string | `""` | | +| elasticsearchExternal.host | string | `"elasticsearch.local"` | | +| elasticsearchExternal.port | int | `9200` | | +| elasticsearchExternal.user | string | `""` | | +| elasticsearchExternal.password | string | `""` | | +| elasticsearchExternal.ssl | bool | `false` | | +| postgresql | object | `{"auth":{"database":"database","postgresPassword":"password"},"enabled":true}` | ---------------------------------------------------------------------------- | +| postgresql.enabled | bool | `true` | Set to false to disable automatic deployment of PostgreSQL | +| arangodb | object | `{"core":{"numberOfServers":1,"persistentVolume":{"size":"100Gi"},"standalone":true},"enabled":true,"imageTag":"4.4.3-community","arangodbPassword":"password"}` | ---------------------------------------------------------------------------- | +| elasticsearch | object | `{"enabled":true,"esConfig":{"elasticsearch.yml":"node.store.allow_mmap: false\n"},"fullnameOverride":"elasticsearch","image":"ghcr.io/sbrg/lifelike-elasticsearch","imageTag":"7.16.3","volumeClaimTemplate":{"resources":{"requests":{"storage":"30Gi"}}}}` | ---------------------------------------------------------------------------- | +| redis | object | `{"auth":{"password":"password"},"commonConfiguration":"# Disable persistence to disk\nsave \"\"\n# Disable AOF https://redis.io/topics/persistence#append-only-file\nappendonly no","enabled":true,"master":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}},"replica":{"extraFlags":["--maxmemory-policy allkeys-lru"],"persistence":{"enabled":false}}}` | ---------------------------------------------------------------------------- | + +--- + Autogenerated from chart metadata using [helm-docs v1.7.0](https://github.com/norwoodj/helm-docs/releases/v1.7.0) diff --git a/helm/lifelike/examples/external-db.yaml b/helm/lifelike/examples/external-db.yaml index edeb47c4fc..082e943463 100644 --- a/helm/lifelike/examples/external-db.yaml +++ b/helm/lifelike/examples/external-db.yaml @@ -2,7 +2,6 @@ ## connecting to external existing database services ## instead of installing the embedded subcharts (postgres, arangodb and elasticsearch) - # Disable the embedded PostgreSQL subchart postgresql: enabled: false diff --git a/helm/lifelike/values.schema.json b/helm/lifelike/values.schema.json index 84cd16eeca..f160f50409 100644 --- a/helm/lifelike/values.schema.json +++ b/helm/lifelike/values.schema.json @@ -1,723 +1,723 @@ { - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": { - "api": { - "type": "object", - "properties": { - "autoScaling": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "maxReplicas": { - "type": "integer" - }, - "minReplicas": { - "type": "integer" - }, - "targetCPUUtilizationPercentage": { - "type": "integer" - }, - "targetMemoryUtilizationPercentage": { - "type": "integer" - } - } - }, - "dbWaiter": { - "type": "object", - "properties": { - "image": { - "type": "object", - "properties": { - "imagePullPolicy": { - "type": "string" - }, - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "extraEnv": { - "type": "object", - "properties": { - "INITIAL_ADMIN_EMAIL": { - "type": "string" - } - } - }, - "extraVolumeMounts": { - "type": "array" - }, - "extraVolumes": { - "type": "array" - }, - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "livenessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "lmdb": { - "type": "object", - "properties": { - "loadEnabled": { - "type": "boolean" - } - } - }, - "podSecurityContext": { - "type": "object", - "properties": { - "runAsUser": { - "type": "integer" - } - } - }, - "readinessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "replicaCount": { - "type": "integer" - }, - "resources": { - "type": "object", - "properties": { - "requests": { - "type": "object", - "properties": { - "ephemeral-storage": { - "type": "string" - } - } - } - } - }, - "secret": { - "type": "string" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "type": { - "type": "string" - } - } - }, - "strategyType": { - "type": "string" - } + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "api": { + "type": "object", + "properties": { + "autoScaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + }, + "targetMemoryUtilizationPercentage": { + "type": "integer" } + } }, - "elasticsearch": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "esConfig": { - "type": "object", - "properties": { - "elasticsearch.yml": { - "type": "string" - } - } - }, - "fullnameOverride": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imageTag": { - "type": "string" - }, - "volumeClaimTemplate": { - "type": "object", - "properties": { - "resources": { - "type": "object", - "properties": { - "requests": { - "type": "object", - "properties": { - "storage": { - "type": "string" - } - } - } - } - } - } + "dbWaiter": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "imagePullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" } + } + }, + "timeoutSeconds": { + "type": "integer" } + } }, - "elasticsearchExternal": { - "type": "object", - "properties": { - "host": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "ssl": { - "type": "boolean" - }, - "user": { - "type": "string" - } + "extraEnv": { + "type": "object", + "properties": { + "INITIAL_ADMIN_EMAIL": { + "type": "string" } + } }, - "frontend": { - "type": "object", - "properties": { - "autoScaling": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "maxReplicas": { - "type": "integer" - }, - "minReplicas": { - "type": "integer" - }, - "targetCPUUtilizationPercentage": { - "type": "integer" - }, - "targetMemoryUtilizationPercentage": { - "type": "integer" - } - } - }, - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "livenessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "readinessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "replicaCount": { - "type": "integer" - }, - "resources": { - "type": "object" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "type": { - "type": "string" - } - } - } + "extraVolumeMounts": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" } + } }, - "ingress": { - "type": "object", - "properties": { - "annotations": { - "type": "object" - }, - "className": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "hostname": { - "type": "string" - }, - "tls": { - "type": "array" - } + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" } + } }, - "arangodb": { - "type": "object", - "properties": { - "core": { - "type": "object", - "properties": { - "numberOfServers": { - "type": "integer" - }, - "persistentVolume": { - "type": "object", - "properties": { - "size": { - "type": "string" - } - } - }, - "standalone": { - "type": "boolean" - } - } - }, - "enabled": { - "type": "boolean" - }, - "imageTag": { - "type": "string" - }, - "arangodbPassword": { - "type": "string" - } + "lmdb": { + "type": "object", + "properties": { + "loadEnabled": { + "type": "boolean" } + } }, - "arangodbExternal": { - "type": "object", - "properties": { - "database": { - "type": "string" - }, - "host": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "user": { - "type": "string" - } + "podSecurityContext": { + "type": "object", + "properties": { + "runAsUser": { + "type": "integer" } + } }, - "pdfparser": { - "type": "object", - "properties": { - "autoScaling": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "maxReplicas": { - "type": "integer" - }, - "minReplicas": { - "type": "integer" - }, - "targetCPUUtilizationPercentage": { - "type": "integer" - }, - "targetMemoryUtilizationPercentage": { - "type": "integer" - } - } - }, - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "livenessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "readinessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "replicaCount": { - "type": "integer" - }, - "resources": { - "type": "object" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "type": { - "type": "string" - } - } + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "ephemeral-storage": { + "type": "string" } + } + } + } + }, + "secret": { + "type": "string" + }, + "service": { + "type": "object", + "properties": { + "port": { + "type": "integer" + }, + "type": { + "type": "string" } + } + }, + "strategyType": { + "type": "string" + } + } + }, + "elasticsearch": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "esConfig": { + "type": "object", + "properties": { + "elasticsearch.yml": { + "type": "string" + } + } + }, + "fullnameOverride": { + "type": "string" + }, + "image": { + "type": "string" + }, + "imageTag": { + "type": "string" }, - "postgresql": { - "type": "object", - "properties": { - "auth": { - "type": "object", - "properties": { - "database": { - "type": "string" - }, - "postgresPassword": { - "type": "string" - } + "volumeClaimTemplate": { + "type": "object", + "properties": { + "resources": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "storage": { + "type": "string" } - }, - "enabled": { - "type": "boolean" + } } + } } + } + } + } + }, + "elasticsearchExternal": { + "type": "object", + "properties": { + "host": { + "type": "string" }, - "postgresqlExternal": { - "type": "object", - "properties": { - "database": { - "type": "string" - }, - "existingSecret": { - "type": "string" - }, - "host": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "user": { - "type": "string" + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "ssl": { + "type": "boolean" + }, + "user": { + "type": "string" + } + } + }, + "frontend": { + "type": "object", + "properties": { + "autoScaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + }, + "targetMemoryUtilizationPercentage": { + "type": "integer" + } + } + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "service": { + "type": "object", + "properties": { + "port": { + "type": "integer" + }, + "type": { + "type": "string" + } + } + } + } + }, + "ingress": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "className": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "hostname": { + "type": "string" + }, + "tls": { + "type": "array" + } + } + }, + "arangodb": { + "type": "object", + "properties": { + "core": { + "type": "object", + "properties": { + "numberOfServers": { + "type": "integer" + }, + "persistentVolume": { + "type": "object", + "properties": { + "size": { + "type": "string" } + } + }, + "standalone": { + "type": "boolean" } + } }, - "redis": { - "type": "object", - "properties": { - "auth": { - "type": "object", - "properties": { - "password": { - "type": "string" - } - } - }, - "commonConfiguration": { - "type": "string" - }, + "enabled": { + "type": "boolean" + }, + "imageTag": { + "type": "string" + }, + "arangodbPassword": { + "type": "string" + } + } + }, + "arangodbExternal": { + "type": "object", + "properties": { + "database": { + "type": "string" + }, + "host": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "user": { + "type": "string" + } + } + }, + "pdfparser": { + "type": "object", + "properties": { + "autoScaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + }, + "targetMemoryUtilizationPercentage": { + "type": "integer" + } + } + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "service": { + "type": "object", + "properties": { + "port": { + "type": "integer" + }, + "type": { + "type": "string" + } + } + } + } + }, + "postgresql": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "database": { + "type": "string" + }, + "postgresPassword": { + "type": "string" + } + } + }, + "enabled": { + "type": "boolean" + } + } + }, + "postgresqlExternal": { + "type": "object", + "properties": { + "database": { + "type": "string" + }, + "existingSecret": { + "type": "string" + }, + "host": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "user": { + "type": "string" + } + } + }, + "redis": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + } + }, + "commonConfiguration": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "master": { + "type": "object", + "properties": { + "extraFlags": { + "type": "array", + "items": { + "type": "string" + } + }, + "persistence": { + "type": "object", + "properties": { "enabled": { - "type": "boolean" - }, - "master": { - "type": "object", - "properties": { - "extraFlags": { - "type": "array", - "items": { - "type": "string" - } - }, - "persistence": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - } - } - }, - "replica": { - "type": "object", - "properties": { - "extraFlags": { - "type": "array", - "items": { - "type": "string" - } - }, - "persistence": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - } - } + "type": "boolean" } + } } + } }, - "redisExternal": { - "type": "object", - "properties": { - "host": { - "type": "string" - }, - "password": { - "type": "string" - }, - "port": { - "type": "integer" + "replica": { + "type": "object", + "properties": { + "extraFlags": { + "type": "array", + "items": { + "type": "string" + } + }, + "persistence": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" } + } } + } + } + } + }, + "redisExternal": { + "type": "object", + "properties": { + "host": { + "type": "string" }, - "statisticalEnrichment": { - "type": "object", - "properties": { - "image": { - "type": "object", - "properties": { - "repository": { - "type": "string" - }, - "tag": { - "type": "string" - } - } - }, - "livenessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "readinessProbe": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "failureThreshold": { - "type": "integer" - }, - "initialDelaySeconds": { - "type": "integer" - }, - "path": { - "type": "string" - }, - "periodSeconds": { - "type": "integer" - }, - "successThreshold": { - "type": "integer" - }, - "timeoutSeconds": { - "type": "integer" - } - } - }, - "replicaCount": { - "type": "integer" - }, - "resources": { - "type": "object" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "type": { - "type": "string" - } - } - } + "password": { + "type": "string" + }, + "port": { + "type": "integer" + } + } + }, + "statisticalEnrichment": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "service": { + "type": "object", + "properties": { + "port": { + "type": "integer" + }, + "type": { + "type": "string" } + } } + } } + } } diff --git a/helm/lifelike/values.yaml b/helm/lifelike/values.yaml index aed8f642e8..cb6cfbb1fa 100644 --- a/helm/lifelike/values.yaml +++ b/helm/lifelike/values.yaml @@ -11,7 +11,8 @@ ingress: className: "" ## -- Ingress annotations - annotations: {} + annotations: + {} # cert-manager.io/cluster-issuer: letsencrypt-prod # nginx.ingress.kubernetes.io/proxy-body-size: "0" @@ -21,7 +22,6 @@ ingress: # hosts: # - lifelike.local - # ------------------------------------------------------------------------------ # API (appserver) # ------------------------------------------------------------------------------ @@ -136,7 +136,8 @@ frontend: targetMemoryUtilizationPercentage: 80 ## -- Optional resources requests and limits - resources: {} + resources: + {} # requests: # cpu: 500m # memory: 2000Mi @@ -180,7 +181,8 @@ statisticalEnrichment: replicaCount: 1 ## -- Optional resources requests and limits - resources: {} + resources: + {} # requests: # cpu: 500m # memory: 2000Mi @@ -212,7 +214,6 @@ statisticalEnrichment: type: ClusterIP port: 5000 - # ------------------------------------------------------------------------------ # PDF Parser # ------------------------------------------------------------------------------ @@ -234,7 +235,8 @@ pdfparser: targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 - resources: {} + resources: + {} # requests: # cpu: 500m # memory: 2000Mi @@ -266,7 +268,6 @@ pdfparser: type: ClusterIP port: 7600 - # ------------------------------------------------------------------------------ # External services # ------------------------------------------------------------------------------ @@ -290,14 +291,12 @@ arangodbExternal: password: password database: arangodb - ## -- External Redis connection details, ignored if redis.enabled is set to true redisExternal: host: redis.local port: 6379 password: "" - ## -- External Elasticsearch connection details, ignored if elasticsearch.enabled is set to true elasticsearchExternal: host: elasticsearch.local @@ -306,14 +305,12 @@ elasticsearchExternal: password: "" ssl: false - # ---------------------------------------------------------------------------- # # # # Subcharts # # # # ---------------------------------------------------------------------------- # - # ------------------------------------------------------------------------------ # PostgreSQL database # ------------------------------------------------------------------------------ @@ -351,7 +348,6 @@ arangodb: ## -- Size of the persistent volume for each server size: 100Gi - # ------------------------------------------------------------------------------ # Elasticsearch # ------------------------------------------------------------------------------ @@ -379,7 +375,6 @@ elasticsearch: requests: storage: 30Gi - # ------------------------------------------------------------------------------ # Redis (cache) # ------------------------------------------------------------------------------ diff --git a/statistical-enrichment/Pipfile.lock b/statistical-enrichment/Pipfile.lock index ec732d59cd..ea8f8149ae 100644 --- a/statistical-enrichment/Pipfile.lock +++ b/statistical-enrichment/Pipfile.lock @@ -364,9 +364,7 @@ "version": "==2.1.0" }, "elastic-apm": { - "extras": [ - "flask" - ], + "extras": ["flask"], "hashes": [ "sha256:5d5cbe0c04d9c00303422f1f4e5bb5b4f0a5cc4dddd53f399db9a16fa8289367", "sha256:c78937e44ece380e6fc98b7292cdf28eaf68917d723cef585efaa083168b3b84" @@ -1884,9 +1882,7 @@ "version": "==0.770" }, "mypy-extensions": { - "hashes": [ - "sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd" - ], + "hashes": ["sha256:c8b707883a96efe9b4bb3aaf0dcc07e7e217d7d8368eec4db4049ee9e142f4fd"], "markers": "python_version >= '2.7'", "version": "==0.4.4" }, diff --git a/tests/cypress/browserstack.json b/tests/cypress/browserstack.json index 63cfda5015..ecfddafeaa 100644 --- a/tests/cypress/browserstack.json +++ b/tests/cypress/browserstack.json @@ -7,23 +7,17 @@ { "os": "OS X Big Sur", "browser": "chrome", - "versions": [ - "latest" - ] + "versions": ["latest"] }, { "os": "Windows 10", "browser": "chrome", - "versions": [ - "latest" - ] + "versions": ["latest"] }, { "os": "OS X Big Sur", "browser": "firefox", - "versions": [ - "latest" - ] + "versions": ["latest"] } ], "run_settings": { @@ -36,8 +30,6 @@ "project_name": "Lifelike App", "build_name": "DEMO environment", "parallels": "1", - "system_env_vars": [ - "PERCY_TOKEN" - ] + "system_env_vars": ["PERCY_TOKEN"] } } diff --git a/tests/cypress/cypress/integration/projects.spec.js b/tests/cypress/cypress/integration/projects.spec.js index de0251e03c..1bc8490f37 100644 --- a/tests/cypress/cypress/integration/projects.spec.js +++ b/tests/cypress/cypress/integration/projects.spec.js @@ -1,43 +1,43 @@ /// -const projectName = Cypress.env("existing_project_name") || "CAG-Center"; +const projectName = Cypress.env('existing_project_name') || 'CAG-Center'; -describe("Projects", () => { +describe('Projects', () => { beforeEach(() => { - cy.loginByPassword(Cypress.env("auth_email"), Cypress.env("auth_password")); + cy.loginByPassword(Cypress.env('auth_email'), Cypress.env('auth_password')); }); - it("shows project list", () => { - cy.clickMenuItem("Workbench"); - cy.getActiveTab().contains("h1", "File Browser"); + it('shows project list', () => { + cy.clickMenuItem('Workbench'); + cy.getActiveTab().contains('h1', 'File Browser'); // Should have a list of projects - cy.get("app-browser-project-list .tile a").should("have.length.above", 10); + cy.get('app-browser-project-list .tile a').should('have.length.above', 10); cy.screenshot(); cy.percySnapshot(); }); - it("shows project files", () => { + it('shows project files', () => { cy.visit(`/projects/${projectName}`); // Should have a list of files - cy.get("app-object-list tr").should("have.length.above", 10); + cy.get('app-object-list tr').should('have.length.above', 10); cy.screenshot(); cy.percySnapshot(); }); - it("shows project entity cloud", () => { + it('shows project entity cloud', () => { cy.visit(`/projects/${projectName}`); // Should have a list of files - cy.get("[ngbtooltip='Entity Cloud'").should("be.visible").click(); - cy.contains("button", "For entire project").click(); + cy.get("[ngbtooltip='Entity Cloud'").should('be.visible').click(); + cy.contains('button', 'For entire project').click(); // There should be more that 10 entities in the word cluud - cy.get("app-word-cloud svg text", { timeout: 60000 }) - .should("have.length.above", 10) + cy.get('app-word-cloud svg text', { timeout: 60000 }) + .should('have.length.above', 10) .wait(2000); cy.screenshot(); diff --git a/tests/cypress/cypress/integration/tabs.spec.js b/tests/cypress/cypress/integration/tabs.spec.js index 1c542c70b5..64fcff3d4c 100644 --- a/tests/cypress/cypress/integration/tabs.spec.js +++ b/tests/cypress/cypress/integration/tabs.spec.js @@ -1,25 +1,25 @@ -describe("Navigation bugs", function () { +describe('Navigation bugs', function () { beforeEach(() => { - cy.loginByPassword(Cypress.env("auth_email"), Cypress.env("auth_password")); + cy.loginByPassword(Cypress.env('auth_email'), Cypress.env('auth_password')); }); - it("Displays tabs content after returning to workbench", function () { - const fbLabel = "File Browser"; - const kgLabel = "Knowledge Graph Statistics"; + it('Displays tabs content after returning to workbench', function () { + const fbLabel = 'File Browser'; + const kgLabel = 'Knowledge Graph Statistics'; cy.log('Click on "File Browser" tab 5 times'); Cypress._.times(5, () => cy.clickMenuItem(fbLabel)); - cy.getActiveTab().contains("h1", fbLabel); + cy.getActiveTab().contains('h1', fbLabel); cy.screenshot(); cy.log(`Navigating away to ${kgLabel} section`); cy.clickMenuItem(kgLabel); - cy.contains(".module-title", kgLabel).should("be.visible"); + cy.contains('.module-title', kgLabel).should('be.visible'); cy.screenshot(); - cy.log("Navigate back to the Workbench tab"); - cy.clickMenuItem("Workbench"); - cy.getActiveTab().contains("h1", fbLabel); + cy.log('Navigate back to the Workbench tab'); + cy.clickMenuItem('Workbench'); + cy.getActiveTab().contains('h1', fbLabel); cy.screenshot(); }); }); diff --git a/tests/cypress/cypress/support/commands.js b/tests/cypress/cypress/support/commands.js index 1a7ee33c9e..06d79adfb2 100644 --- a/tests/cypress/cypress/support/commands.js +++ b/tests/cypress/cypress/support/commands.js @@ -11,31 +11,29 @@ // // -- This is a parent command -- // Cypress.Commands.add('login', (email, password) => { ... }) -Cypress.Commands.add("loginByPassword", (email, password) => { +Cypress.Commands.add('loginByPassword', (email, password) => { cy.log(`Logging in as ${email}`); - cy.request("POST", Cypress.env("auth_login_url"), { email, password }).then( - ({ body }) => { - cy.debug(`Login response: ${JSON.stringify(body)}`); - const { accessToken, refreshToken, user } = body; - const auth = { loggedIn: true, targetUrl: "/", user }; - window.localStorage.setItem("auth", JSON.stringify(auth)); - window.localStorage.setItem("authId", user.id); - window.localStorage.setItem("expires_at", accessToken.exp); - window.localStorage.setItem("access_jwt", accessToken.token); - window.localStorage.setItem("refresh_jwt", refreshToken.token); - } - ); + cy.request('POST', Cypress.env('auth_login_url'), { email, password }).then(({ body }) => { + cy.debug(`Login response: ${JSON.stringify(body)}`); + const { accessToken, refreshToken, user } = body; + const auth = { loggedIn: true, targetUrl: '/', user }; + window.localStorage.setItem('auth', JSON.stringify(auth)); + window.localStorage.setItem('authId', user.id); + window.localStorage.setItem('expires_at', accessToken.exp); + window.localStorage.setItem('access_jwt', accessToken.token); + window.localStorage.setItem('refresh_jwt', refreshToken.token); + }); // Navigate to workbench - return cy.visit("/workspaces/local"); + return cy.visit('/workspaces/local'); }); -Cypress.Commands.add("clickMenuItem", (item) => { +Cypress.Commands.add('clickMenuItem', (item) => { return cy.get(`[ngbtooltip="${item}`).click(); }); -Cypress.Commands.add("getActiveTab", () => { - return cy.get('[ng-reflect-active="true"]').should("be.visible"); +Cypress.Commands.add('getActiveTab', () => { + return cy.get('[ng-reflect-active="true"]').should('be.visible'); }); // // diff --git a/tests/cypress/cypress/support/index.js b/tests/cypress/cypress/support/index.js index 60136d2333..0c15558213 100644 --- a/tests/cypress/cypress/support/index.js +++ b/tests/cypress/cypress/support/index.js @@ -13,10 +13,10 @@ // https://on.cypress.io/configuration // *********************************************************** -import "@percy/cypress"; +import '@percy/cypress'; // Import commands.js using ES2015 syntax: -import "./commands"; +import './commands'; // Alternatively you can use CommonJS syntax: // require('./commands') From dc2be19d75dec640b938ab600c7b9bb82e6b18a9 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 16:59:09 +0200 Subject: [PATCH 07/23] fix integration check workflow --- appserver/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 0582b7fdb5..c51b677562 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -37,7 +37,7 @@ LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike # Install runtime system dependencies RUN apt-get update \ - && apt-get install -y postgresql libmagic-dev graphviz libgraphviz-dev curl \ + && apt-get install -y postgresql-client libmagic-dev graphviz libgraphviz-dev curl \ && apt-get clean # Copy Python virtual environment From af47f1578ad95f05d10dcd88d7436df607d52de9 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 17:05:29 +0200 Subject: [PATCH 08/23] fix integration check workflow --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 05d76760b0..04e7b6e358 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -25,7 +25,7 @@ jobs: run: echo "GITHUB_HASH=${{ github.sha }}" >> .env - name: Migration Integrity Check - run: ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver bin/migration-integrity-check + run: ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps --entrypoint "bin/migration-integrity-check" appserver - name: Linting and code style run: |- From e9932978237f9a9b4676c772906e738c0d5340fa Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 17:09:42 +0200 Subject: [PATCH 09/23] fix integration check workflow --- .github/workflows/integration-tests.yml | 2 +- appserver/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 04e7b6e358..05d76760b0 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -25,7 +25,7 @@ jobs: run: echo "GITHUB_HASH=${{ github.sha }}" >> .env - name: Migration Integrity Check - run: ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps --entrypoint "bin/migration-integrity-check" appserver + run: ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver bin/migration-integrity-check - name: Linting and code style run: |- diff --git a/appserver/Dockerfile b/appserver/Dockerfile index c51b677562..8e02189003 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -130,4 +130,4 @@ HEALTHCHECK --start-period=30s \ CMD curl -f localhost:$PORT/meta || exit 1 RUN chmod +x bin/startup.sh -ENTRYPOINT ["bin/startup.sh"] +CMD ["bin/startup.sh"] From 254f224b19eb91a2dae02abb5f7fe05294075c30 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 17:36:19 +0200 Subject: [PATCH 10/23] trigger deployment webhook from reppo --- .github/workflows/call_webhook.yml | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/call_webhook.yml diff --git a/.github/workflows/call_webhook.yml b/.github/workflows/call_webhook.yml new file mode 100644 index 0000000000..dbc9125e2c --- /dev/null +++ b/.github/workflows/call_webhook.yml @@ -0,0 +1,41 @@ +name: Trigger Target Workflow + +on: + workflow_dispatch: + secrets: + WEBHOOK_TOKEN: + required: true + push: + branches: + - master + +jobs: + trigger: + runs-on: ubuntu-latest + + steps: + - name: Trigger Webhook + run: | + # Set the required variables + repo_owner="biosustain" + repo_name="lifelike-infrastructure" + load=$( + cat< Date: Wed, 3 Apr 2024 17:47:35 +0200 Subject: [PATCH 11/23] fix integration check workflow --- .github/workflows/integration-tests.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 05d76760b0..449b0cab16 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -24,14 +24,20 @@ jobs: - name: Create environment variable to pass in GitHub hash for Docker Compose run: echo "GITHUB_HASH=${{ github.sha }}" >> .env + - name: Build Docker image + id: build + run: | + ${{ env.DOCKER_COMPOSE_CMD }} build --build-arg DEV=True appserver + echo "image_hash=$(docker images | awk '{print $1}' | awk 'NR==2')" > $GITHUB_OUTPUT + - name: Migration Integrity Check - run: ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver bin/migration-integrity-check + run: docker run ${{ steps.build.outputs.image_hash }} bin/migration-integrity-check - name: Linting and code style run: |- - ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver flake8 . - ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver mypy . - ${{ env.DOCKER_COMPOSE_CMD }} run --no-deps appserver pycodestyle . + docker run ${{ steps.build.outputs.image_hash }} flake8 . + docker run ${{ steps.build.outputs.image_hash }} mypy . + docker run ${{ steps.build.outputs.image_hash }} pycodestyle . - name: Bring up containers and wait for webserver to be ready timeout-minutes: 10 From ba2b26776b86fbeaf8542ec4b2b22632f1d6d2ae Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 17:52:52 +0200 Subject: [PATCH 12/23] fix integration check workflow --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 449b0cab16..968e149b25 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -28,7 +28,7 @@ jobs: id: build run: | ${{ env.DOCKER_COMPOSE_CMD }} build --build-arg DEV=True appserver - echo "image_hash=$(docker images | awk '{print $1}' | awk 'NR==2')" > $GITHUB_OUTPUT + echo "image_hash=$(docker images | awk '{print $3}' | awk 'NR==2')" > $GITHUB_OUTPUT - name: Migration Integrity Check run: docker run ${{ steps.build.outputs.image_hash }} bin/migration-integrity-check From 9122efbb345c2043bdb2e41e5f4987b09a89610f Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 17:53:19 +0200 Subject: [PATCH 13/23] fix integration check workflow --- .github/workflows/integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 968e149b25..52e359569f 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -28,7 +28,7 @@ jobs: id: build run: | ${{ env.DOCKER_COMPOSE_CMD }} build --build-arg DEV=True appserver - echo "image_hash=$(docker images | awk '{print $3}' | awk 'NR==2')" > $GITHUB_OUTPUT + echo "image_hash=$(docker images | awk '{print $3}' | awk 'NR==2')" | tee $GITHUB_OUTPUT - name: Migration Integrity Check run: docker run ${{ steps.build.outputs.image_hash }} bin/migration-integrity-check From 3bbad10841d192b5f211ed544b1193e699d47b58 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 18:04:20 +0200 Subject: [PATCH 14/23] fix integration check workflow --- appserver/bin/migration-integrity-check | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/bin/migration-integrity-check b/appserver/bin/migration-integrity-check index 0d626b97de..ea6144c9ff 100755 --- a/appserver/bin/migration-integrity-check +++ b/appserver/bin/migration-integrity-check @@ -5,7 +5,7 @@ echo "Checking migration integrity..." # Start in appserver directory __dir__="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd ${__dir__}/../migrations +cd ${__dir__}/migrations head_count=$(alembic heads | wc -l) From 7066fd0739aba83c7be51864c6f1ed297e475288 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 18:29:21 +0200 Subject: [PATCH 15/23] fix integration check workflow --- appserver/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 8e02189003..d4ef53a5bd 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -26,7 +26,7 @@ COPY Pipfile Pipfile.lock ./ # Install Python dependencies ARG DEV -RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) +RUN pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) # ======================================== From 5554f008bbafbe19e670228c4d904a86be397d8b Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 18:33:02 +0200 Subject: [PATCH 16/23] fallback to old dockerfile --- appserver/Dockerfile | 149 +++++++++---------------------------------- 1 file changed, 30 insertions(+), 119 deletions(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index d4ef53a5bd..45652a4d32 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -1,133 +1,44 @@ -# ======================================== -# Base image -# ======================================== -FROM python:3.9-slim as base - -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONFAULTHANDLER 1 +FROM fedora:33 as base +LABEL app=kg-prototypes +# Install dependencies +RUN dnf install htop postgresql graphviz python-pip python3-devel vim net-tools which -y \ + && dnf groupinstall 'Development Tools' -y \ + && dnf clean packages RUN pip install pipenv +ENV N4J_USER n4j +ENV N4J_HOME /home/$N4J_USER +ENV UID 1000 +ENV GID 1000 -# ======================================== -# Build dependencies stage -# ======================================== -FROM base as build-deps - -# Install build dependencies -RUN apt-get update \ - && apt-get install -y liblmdb-dev python3-dev libxml2-dev libxslt-dev build-essential \ - && apt-get clean - -# Copy Pipfiles -COPY Pipfile Pipfile.lock ./ - -# Install Python dependencies -ARG DEV -RUN pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) - - -# ======================================== -# Runtime stage -# ======================================== -FROM base -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - -# Install runtime system dependencies -RUN apt-get update \ - && apt-get install -y postgresql-client libmagic-dev graphviz libgraphviz-dev curl \ - && apt-get clean - -# Copy Python virtual environment -COPY --from=build-deps /.venv /.venv -ENV PATH="/.venv/bin:$PATH" - -# Set user and workdir -WORKDIR /app -RUN useradd -m -d /app app -USER app - -# Copy application code -COPY --chown=app . . - -# Set to 1 to automatically apply any pending DB migrations at startup -ENV MIGRATE_DB= - -# Create an initial admin user -ENV INITIAL_ADMIN_EMAIL= - -# LMDB database volume -ENV LMDB_DATA_DIR=/lmdb -VOLUME /lmdb - -# LMDB download cloud storage -# ENV AZURE_ACCOUNT_STORAGE_NAME= -# ENV AZURE_ACCOUNT_STORAGE_KEY= - -# JWT Authendication -ENV JWT_SECRET=secret - -# Base URL of this app, reachable by external services -ENV APPSERVER_URL=http://localhost:5000 - -# Base URL of the frontend app, for link generation -ENV FRONTEND_URL=http://localhost:4242 - -# PostgreSQL configuration -ENV POSTGRES_HOST=postgres -ENV POSTGRES_PORT=5432 -ENV POSTGRES_USER=postgres -ENV POSTGRES_PASSWORD=postgres -ENV POSTGRES_DB=postgres - -# ArangoDB configuration -ENV ARANGODB_HOST=arangodb -ENV ARANGODB_PORT=7687 -ENV ARANGODB_AUTH=arangodb/password -ENV ARANGODB_DATABASE=arangodb -ENV ARANGODB_SCHEME=bolt - -# Elasticsearch configuration -ENV ELASTICSEARCH_URL=http://elasticsearch:9200 -ENV ELASTICSEARCH_FILE_INDEX=file - -# Statistical enrichment service -ENV STATISTICAL_ENRICHMENT_URL=http://statistical-enrichment:5000 - -# PDFParser service -ENV PDFPARSER_URL=http://pdfparser:7600 +# User and group creation +RUN groupadd -g $GID $N4J_USER && \ + useradd -u $UID -g $GID -G wheel --create-home --home-dir $N4J_HOME --shell /bin/bash $N4J_USER -# NLP Processing service -ENV NLP_URL=https://nlp-api.lifelike.bio/v1/predict -ENV NLP_SECRET=secret +WORKDIR $N4J_HOME -# Mailserver configuration -ENV FROM_EMAIL=lifelike@example.com +# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache +COPY --chown=1000:1000 Pipfile . +COPY --chown=1000:1000 Pipfile.lock . +RUN pipenv install --dev --deploy --system -# Sendgrid integration -ENV SENDGRID_API_KEY= +# ...then copy everything else +COPY --chown=1000:1000 . . -# Optional Sentry logging configuration -ENV SENTRY_DSN= +# TODO: We should consider breaking this apart into dev and prod +# builds, so we don't build unnecessary packages -# Optional Elastic APM configuration. -# To enable, at least ELASTIC_APM_SERVER_URL must be set -# Other available variables: https://www.elastic.co/guide/en/apm/agent/python/master/configuration.html -ENV ELASTIC_APM_SERVER_URL= -ENV ELASTIC_APM_SERVICE_NAME=appserver +# Don't lose stdin, stdout and stderr output due to buffering +ENV PYTHONUNBUFFERED 1 +ENV PYTHONPATH $N4J_HOME -# Flask env (development, testing, production) -ENV FLASK_ENV=production +# Set Python3 as the default when running "python" +RUN echo 'alias python=python3' >> ~/.bashrc && source ~/.bashrc -# Listen port -ENV PORT=5000 -EXPOSE $PORT +USER $N4J_USER -# Health check by requesting system info to /meta endpoint -HEALTHCHECK --start-period=30s \ - CMD curl -f localhost:$PORT/meta || exit 1 +# Setup flask application environment vars +ENV MAX_ALLOWED_LOGIN_FAILURES 6 -RUN chmod +x bin/startup.sh CMD ["bin/startup.sh"] From 430c7e8779a9cacab9635cf48dcfdecc81334857 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 19:09:53 +0200 Subject: [PATCH 17/23] fallback to old dockerfile --- appserver/Dockerfile | 2 +- appserver/Pipfile | 3 +- appserver/Pipfile.lock | 1896 +++++++++++++---------- appserver/bin/migration-integrity-check | 2 +- 4 files changed, 1082 insertions(+), 821 deletions(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 45652a4d32..d2e572feb9 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -41,4 +41,4 @@ USER $N4J_USER # Setup flask application environment vars ENV MAX_ALLOWED_LOGIN_FAILURES 6 -CMD ["bin/startup.sh"] +CMD [ "bin/startup.sh" ] diff --git a/appserver/Pipfile b/appserver/Pipfile index 6b16e584b0..b1286c1a99 100644 --- a/appserver/Pipfile +++ b/appserver/Pipfile @@ -53,6 +53,7 @@ paramiko = "==2.7.2" google-cloud-storage = "==1.36.1" fastjsonschema = "==2.15.0" marshmallow-dataclass = "==8.3.1" +marshmallow-enum = "==1.5.1" deepdiff = "==5.2.3" timeflake = "==0.3.3" scipy = "==1.6.1" @@ -60,6 +61,7 @@ statsmodels = "==0.12.2" sqlalchemy = "==1.3.23" azure-storage-file = "==2.1.0" azure-storage-blob = "==12.8.0" +neo4j = "==4.2.1" python-magic = "==0.4.22" httpretty = "==1.0.5" sendgrid = "==6.7.0" @@ -77,7 +79,6 @@ openai = "*" types-cachetools = "*" mypy = "==0.981" pyyaml = "==6.0.1" -marshmallow-enum = "*" [requires] python_version = "3.9" diff --git a/appserver/Pipfile.lock b/appserver/Pipfile.lock index 2c0207aadf..7647f4ee56 100644 --- a/appserver/Pipfile.lock +++ b/appserver/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "723e0fba23007871efc048ff1ab5a6333defdd4688df64ab94c5cca1c6e8bb34" + "sha256": "e8e18968eada4f4eba2a7ea35293b9f680b6e0a10413292556849adaa5ea1a61" }, "pipfile-spec": 6, "requires": { @@ -16,45 +16,138 @@ ] }, "default": { - "alembic": { - "hashes": [ - "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43", - "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595" + "aiohttp": { + "hashes": [ + "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14", + "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391", + "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2", + "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e", + "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9", + "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd", + "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4", + "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b", + "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41", + "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567", + "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275", + "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54", + "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a", + "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef", + "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99", + "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da", + "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4", + "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e", + "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699", + "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04", + "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719", + "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131", + "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e", + "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f", + "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd", + "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f", + "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e", + "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1", + "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed", + "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4", + "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1", + "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777", + "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531", + "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b", + "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab", + "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8", + "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074", + "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc", + "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643", + "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01", + "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36", + "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24", + "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654", + "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d", + "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241", + "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51", + "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f", + "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2", + "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15", + "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf", + "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b", + "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71", + "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05", + "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52", + "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3", + "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6", + "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a", + "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519", + "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a", + "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333", + "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6", + "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d", + "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57", + "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c", + "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9", + "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea", + "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332", + "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5", + "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622", + "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71", + "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb", + "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a", + "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff", + "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945", + "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480", + "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6", + "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9", + "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd", + "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f", + "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a", + "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a", + "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949", + "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc", + "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75", + "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f", + "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10", + "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f" ], - "markers": "python_version >= '3.8'", - "version": "==1.13.1" + "markers": "python_version >= '3.6'", + "version": "==3.8.4" }, - "annotated-types": { + "aiosignal": { "hashes": [ - "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43", - "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d" + "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", + "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" ], - "markers": "python_version >= '3.8'", - "version": "==0.6.0" + "markers": "python_version >= '3.7'", + "version": "==1.3.1" }, - "anyio": { + "alembic": { "hashes": [ - "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", - "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" + "sha256:6880dec4f28dd7bd999d2ed13fbe7c9d4337700a44d11a524c0ce0c59aaf0dbd", + "sha256:e8a6ff9f3b1887e1fed68bfb8fb9a000d8f61c21bdcc85b67bb9f87fcbc4fce3" ], - "markers": "python_version >= '3.8'", - "version": "==4.3.0" + "markers": "python_version >= '3.7'", + "version": "==1.9.2" }, "apispec": { "hashes": [ - "sha256:b5b22f5dba6cc69bd90e1075de20ae3d27b310a6250c66b0271aa50615eee72d", - "sha256:c0846f8eaa5119c46b2ecfe9bc24ed19dba8845f8655d00b51ddd296a10ea4cb" + "sha256:d97f0ae9c65133185b9ed9c5be1a434eb85627dfa33c4c53cabda122256c1b67", + "sha256:e76d80b739edef4be213092a6384ad7fd933ba7d64f6d5a0aff8d4da1bef7887" ], - "markers": "python_version >= '3.8'", - "version": "==6.6.0" + "markers": "python_version >= '3.7'", + "version": "==6.0.2" }, "appnope": { "hashes": [ - "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", - "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" + "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24", + "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e" ], "markers": "sys_platform == 'darwin'", - "version": "==0.1.4" + "version": "==0.1.3" + }, + "async-timeout": { + "hashes": [ + "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", + "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + ], + "markers": "python_version >= '3.6'", + "version": "==4.0.2" }, "attrs": { "hashes": [ @@ -62,7 +155,6 @@ "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "azure-common": { @@ -74,11 +166,11 @@ }, "azure-core": { "hashes": [ - "sha256:26273a254131f84269e8ea4464f3560c731f29c0c1f69ac99010845f239c1a8f", - "sha256:7c5ee397e48f281ec4dd773d67a0a47a0962ed6fa833036057f9ea067f688e74" + "sha256:986bfd8687889782d79481d4c5d0af04ab4a18ca2f210364804a88e4eaa1586a", + "sha256:df306e6e4abc145610ca6744aef943129a6fd7a11977e56731f69ac0e00724f9" ], "markers": "python_version >= '3.7'", - "version": "==1.30.1" + "version": "==1.26.2" }, "azure-storage-blob": { "hashes": [ @@ -133,29 +225,30 @@ "sha256:ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.1.7" }, "beautifulsoup4": { "hashes": [ - "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", - "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed" + "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39", + "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106" ], "markers": "python_full_version >= '3.6.0'", - "version": "==4.12.3" + "version": "==4.11.2" }, "bioc": { - "hashes": ["sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10"], + "hashes": [ + "sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10", + "sha256:a63dcc76a791b7db58d273422791e9909d0524ddd26e332be5467d7fa2e81a0a" + ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==1.3.7" }, "blinker": { "hashes": [ - "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", - "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" + "sha256:1eb563df6fdbc39eeddc177d953203f99f097e9bf0e2b8f9f3cf18b6ca425e36", + "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462" ], - "version": "==1.7.0" + "version": "==1.5" }, "cachetools": { "hashes": [ @@ -167,69 +260,80 @@ }, "certifi": { "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" ], "markers": "python_version >= '3.6'", - "version": "==2024.2.2" + "version": "==2022.12.7" }, "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" + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" }, "chardet": { "hashes": [ @@ -239,51 +343,123 @@ "markers": "python_version >= '3.1'", "version": "==4.0.0" }, + "charset-normalizer": { + "hashes": [ + "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", + "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", + "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", + "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", + "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", + "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", + "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", + "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", + "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", + "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", + "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", + "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", + "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", + "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", + "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", + "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", + "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", + "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", + "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", + "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", + "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", + "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", + "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", + "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", + "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", + "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", + "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", + "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", + "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", + "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", + "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", + "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", + "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", + "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", + "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", + "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", + "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", + "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", + "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", + "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", + "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", + "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", + "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", + "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", + "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", + "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", + "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", + "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", + "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", + "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", + "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", + "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", + "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", + "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", + "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", + "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", + "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", + "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", + "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", + "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", + "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", + "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", + "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", + "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", + "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", + "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", + "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", + "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", + "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", + "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", + "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", + "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", + "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", + "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", + "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.1.0" + }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", + "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.3" }, "cryptography": { "hashes": [ - "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", - "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", - "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", - "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", - "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", - "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", - "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", - "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", - "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", - "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", - "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", - "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", - "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", - "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", - "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", - "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", - "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", - "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", - "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", - "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", - "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", - "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", - "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", - "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", - "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", - "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", - "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", - "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", - "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", - "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", - "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", - "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" + "sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b", + "sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f", + "sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190", + "sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f", + "sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f", + "sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb", + "sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c", + "sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773", + "sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72", + "sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8", + "sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717", + "sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9", + "sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856", + "sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96", + "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288", + "sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39", + "sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e", + "sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce", + "sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1", + "sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de", + "sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df", + "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf", + "sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458" ], - "markers": "python_version >= '3.7'", - "version": "==42.0.5" + "markers": "python_version >= '3.6'", + "version": "==39.0.0" }, "decorator": { "hashes": [ @@ -299,41 +475,34 @@ "sha256:ae2cb98353309f93fbfdda4d77adb08fb303314d836bb6eac3d02ed71a10b40e" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==5.2.3" }, - "distro": { - "hashes": [ - "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", - "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2" - ], - "markers": "python_version >= '3.6'", - "version": "==1.9.0" - }, "docutils": { "hashes": [ - "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", - "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" + "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", + "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" ], "markers": "python_version >= '3.7'", - "version": "==0.20.1" + "version": "==0.19" }, "ecs-logging": { "hashes": [ - "sha256:02581a56b7fc6cbae2de121a4a398ba3bd73d7bb2d67cd029a8a03df0b144098", - "sha256:222cc158d4331157d128bc903629010f7724eab8ba4b642efbffd0cb482f4cde" + "sha256:34567bda91534a480f12117c30e1aac78489cc9a0ace172014d80f3d1e29c85b", + "sha256:543ed7b634901aee465fddf70f52b6fdbd35e825e7cbcae2e664d7dfdff2f859" ], "markers": "python_version >= '3.6'", - "version": "==2.1.0" + "version": "==2.0.2" }, "elastic-apm": { - "extras": ["flask"], + "extras": [ + "flask" + ], "hashes": [ - "sha256:1861183c5ba3b46df66e111ba27877dbe8aaa8842777c1f0627c7fb1b65ed249", - "sha256:7a5e430658196c9ebcf4530e780268b0dfe2ba2c25041549ee54d9fb8650c418" + "sha256:815ee9838f6db2db3ee83a31b8ff36ff291aac03c6ed24534280ced45a9cb3dc", + "sha256:d672e51ef2dffa1a08d814e6b47d8d17144256d887dbc1734b2b9ce298f1208b" ], - "markers": "python_version >= '3.6' and python_version < '4'", - "version": "==6.21.4.post8347027212" + "index": "pypi", + "version": "==6.13.2" }, "elasticsearch": { "hashes": [ @@ -341,7 +510,6 @@ "sha256:f4bb05cfe55cf369bdcb4d86d0129d39d66a91fd9517b13cd4e4231fbfcf5c81" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", "version": "==7.6.0" }, "et-xmlfile": { @@ -352,14 +520,6 @@ "markers": "python_version >= '3.6'", "version": "==1.1.0" }, - "exceptiongroup": { - "hashes": [ - "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", - "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" - ], - "markers": "python_version < '3.11'", - "version": "==1.2.0" - }, "fastjsonschema": { "hashes": [ "sha256:b3da206676f8b4906debf6a17b650b858c92cb304cbe0c8aa81799bde6a6b858", @@ -370,11 +530,11 @@ }, "filelock": { "hashes": [ - "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb", - "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546" + "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de", + "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d" ], - "markers": "python_version >= '3.8'", - "version": "==3.13.3" + "markers": "python_version >= '3.7'", + "version": "==3.9.0" }, "flask": { "hashes": [ @@ -382,7 +542,6 @@ "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.1.2" }, "flask-apispec": { @@ -427,7 +586,9 @@ }, "flask-migrate": { "hashes": [ + "sha256:4dc4a5cce8cbbb06b8dc963fd86cf8136bd7d875aabe2d840302ea739b243732", "sha256:8626af845e6071ef80c70b0dc16d373f761c981f0ad61bb143a529cab649e725", + "sha256:a69d508c2e09d289f6e55a417b3b8c7bfe70e640f53d2d9deb0d056a384f37ee", "sha256:c1601dfd46b9204233935e5d73473cd7fa959db7a4b0e894c7aa7a9e8aeebf0e" ], "index": "pypi", @@ -439,9 +600,88 @@ "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.4" }, + "frozenlist": { + "hashes": [ + "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c", + "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f", + "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a", + "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784", + "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27", + "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d", + "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3", + "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678", + "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a", + "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483", + "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8", + "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf", + "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99", + "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c", + "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48", + "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5", + "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56", + "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e", + "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1", + "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401", + "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4", + "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e", + "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649", + "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a", + "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d", + "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0", + "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6", + "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d", + "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b", + "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6", + "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf", + "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef", + "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7", + "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842", + "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba", + "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420", + "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b", + "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d", + "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332", + "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936", + "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816", + "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91", + "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420", + "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448", + "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411", + "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4", + "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32", + "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b", + "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0", + "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530", + "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669", + "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7", + "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1", + "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5", + "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce", + "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4", + "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e", + "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2", + "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d", + "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9", + "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642", + "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0", + "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703", + "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb", + "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1", + "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13", + "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab", + "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38", + "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb", + "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb", + "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81", + "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8", + "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd", + "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.3" + }, "gdown": { "hashes": [ "sha256:5ce3db0aeda54f46caacb2df86f31c3e3ecd17c355689e6456d85fb528ba9749", @@ -480,7 +720,6 @@ "sha256:e3227abe57122370df02f00b8a6d78da6d41a0df4e6864b7f65a3a4ae673a8a7" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.36.1" }, "google-crc32c": { @@ -567,11 +806,11 @@ }, "googleapis-common-protos": { "hashes": [ - "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e", - "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632" + "sha256:c727251ec025947d545184ba17e3578840fc3a24a0516a020479edab660457df", + "sha256:ca3befcd4580dab6ad49356b46bf165bb68ff4b32389f028f1abd7c10ab9519a" ], "markers": "python_version >= '3.7'", - "version": "==1.63.0" + "version": "==1.58.0" }, "graphviz": { "hashes": [ @@ -579,7 +818,6 @@ "sha256:60acbeee346e8c14555821eab57dbf68a169e6c10bce40e83c1bf44f63a62a01" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.13.2" }, "gunicorn": { @@ -588,39 +826,15 @@ "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c" ], "index": "pypi", - "markers": "python_version >= '3.4'", "version": "==20.0.4" }, - "h11": { - "hashes": [ - "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", - "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" - ], - "markers": "python_version >= '3.7'", - "version": "==0.14.0" - }, - "httpcore": { + "httpretty": { "hashes": [ - "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", - "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + "sha256:e53c927c4d3d781a0761727f1edfad64abef94e828718e12b672a678a8b3e0b5" ], - "markers": "python_version >= '3.8'", - "version": "==1.0.5" - }, - "httpretty": { - "hashes": ["sha256:e53c927c4d3d781a0761727f1edfad64abef94e828718e12b672a678a8b3e0b5"], "index": "pypi", - "markers": "python_version >= '3'", "version": "==1.0.5" }, - "httpx": { - "hashes": [ - "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", - "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5" - ], - "markers": "python_version >= '3.8'", - "version": "==0.27.0" - }, "idna": { "hashes": [ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", @@ -630,12 +844,16 @@ "version": "==2.10" }, "intervaltree": { - "hashes": ["sha256:902b1b88936918f9b2a19e0e5eb7ccb430ae45cde4f39ea4b36932920d33952d"], + "hashes": [ + "sha256:902b1b88936918f9b2a19e0e5eb7ccb430ae45cde4f39ea4b36932920d33952d" + ], "index": "pypi", "version": "==3.1.0" }, "ipy": { - "hashes": ["sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"], + "hashes": [ + "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a" + ], "index": "pypi", "version": "==1.1" }, @@ -645,7 +863,6 @@ "sha256:cbb2ef3d5961d44e6a963b9817d4ea4e1fa2eb589c371a470fed14d8d40cbd6a" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==7.19.0" }, "isodate": { @@ -661,16 +878,15 @@ "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==2.0.1" }, "jedi": { "hashes": [ - "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", - "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" + "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e", + "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612" ], "markers": "python_version >= '3.6'", - "version": "==0.19.1" + "version": "==0.18.2" }, "jinja2": { "hashes": [ @@ -678,16 +894,15 @@ "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==3.0.3" }, "jsonlines": { "hashes": [ - "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74", - "sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55" + "sha256:2579cb488d96f815b0eb81629e3e6b0332da0962a18fa3532958f7ba14a5c37f", + "sha256:632f5e38f93dfcb1ac8c4e09780b92af3a55f38f26e7c47ae85109d420b6ad39" ], - "markers": "python_version >= '3.8'", - "version": "==4.0.0" + "markers": "python_version >= '3.6'", + "version": "==3.1.0" }, "lmdb": { "hashes": [ @@ -719,245 +934,158 @@ }, "lxml": { "hashes": [ - "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04", - "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0", - "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739", - "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a", - "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1", - "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218", - "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9", - "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188", - "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138", - "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585", - "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637", - "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe", - "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d", - "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1", - "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095", - "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9", - "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81", - "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57", - "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536", - "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a", - "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052", - "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01", - "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98", - "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433", - "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1", - "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f", - "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4", - "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b", - "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6", - "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8", - "sha256:3e183c6e3298a2ed5af9d7a356ea823bccaab4ec2349dc9ed83999fd289d14d5", - "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306", - "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5", - "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f", - "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4", - "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be", - "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919", - "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af", - "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66", - "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1", - "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af", - "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec", - "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b", - "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289", - "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a", - "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d", - "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102", - "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9", - "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc", - "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45", - "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa", - "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a", - "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c", - "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461", - "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708", - "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca", - "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd", - "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913", - "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da", - "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0", - "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5", - "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5", - "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96", - "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41", - "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3", - "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456", - "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c", - "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867", - "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0", - "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213", - "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619", - "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240", - "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c", - "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377", - "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b", - "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c", - "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54", - "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b", - "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53", - "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029", - "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6", - "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885", - "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94", - "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134", - "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8", - "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9", - "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863", - "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b", - "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806", - "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11", - "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9", - "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817", - "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95", - "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8", - "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc", - "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47", - "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b", - "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0", - "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a", - "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f", - "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56", - "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef", - "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851", - "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7", - "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62", - "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4", - "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a", - "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c", - "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533", - "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e", - "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a", - "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3", - "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b", - "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4", - "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0", - "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d", - "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3", - "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5", - "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534", - "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4", - "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144", - "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd", - "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd", - "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860", - "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704", - "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8", - "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d", - "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9", - "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f", - "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad", - "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc", - "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510", - "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937", - "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a", - "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460", - "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85", - "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86", - "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0", - "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246", - "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7", - "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa", - "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08", - "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270", - "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a", - "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169", - "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e", - "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75", - "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd", - "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354", - "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c", - "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1", - "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb", - "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f", - "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef" + "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7", + "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726", + "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03", + "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140", + "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a", + "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05", + "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03", + "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419", + "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", + "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e", + "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67", + "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50", + "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894", + "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf", + "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947", + "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1", + "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd", + "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3", + "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92", + "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3", + "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457", + "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74", + "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf", + "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1", + "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4", + "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975", + "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5", + "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe", + "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7", + "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1", + "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2", + "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409", + "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f", + "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f", + "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5", + "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24", + "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e", + "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4", + "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a", + "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c", + "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de", + "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f", + "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b", + "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5", + "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7", + "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a", + "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c", + "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9", + "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e", + "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab", + "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941", + "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5", + "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45", + "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7", + "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892", + "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746", + "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c", + "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53", + "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe", + "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184", + "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38", + "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df", + "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9", + "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b", + "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2", + "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0", + "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda", + "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b", + "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5", + "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380", + "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33", + "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8", + "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1", + "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889", + "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9", + "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f", + "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c" ], - "markers": "python_version >= '3.6'", - "version": "==5.2.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.9.2" }, "mako": { "hashes": [ - "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e", - "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c" + "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", + "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" ], - "markers": "python_version >= '3.8'", - "version": "==1.3.2" + "markers": "python_version >= '3.7'", + "version": "==1.2.4" }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", + "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", + "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", + "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", + "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", + "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", + "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", + "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", + "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", + "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", + "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", + "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", + "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", + "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", + "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", + "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", + "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", + "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", + "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", + "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", + "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", + "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", + "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", + "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", + "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", + "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", + "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", + "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", + "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", + "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", + "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", + "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", + "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", + "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", + "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", + "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", + "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", + "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", + "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", + "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", + "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", + "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", + "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", + "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", + "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", + "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", + "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", + "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", + "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", + "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" ], "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "version": "==2.1.2" }, "marshmallow": { "hashes": [ - "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3", - "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633" + "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78", + "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b" ], - "markers": "python_version >= '3.8'", - "version": "==3.21.1" + "markers": "python_version >= '3'", + "version": "==3.19.0" }, "marshmallow-dataclass": { "hashes": [ @@ -965,7 +1093,6 @@ "sha256:835e6aef758f9b107ab9623d37e0ebbd6e586fb8f4172281a47dd90a69ceda38" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==8.3.1" }, "marshmallow-enum": { @@ -982,13 +1109,13 @@ "sha256:dde9e20bcb710e9e59f765a38e3d6d17f1b2d6b4320cbdc2cea0f6b57f70d08c" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==0.22.3" }, "memory-profiler": { - "hashes": ["sha256:01385ac0fec944fcf7969814ec4406c6d8a9c66c079d09276723c5a7680f44e5"], + "hashes": [ + "sha256:01385ac0fec944fcf7969814ec4406c6d8a9c66c079d09276723c5a7680f44e5" + ], "index": "pypi", - "markers": "python_version >= '3.4'", "version": "==0.58.0" }, "msrest": { @@ -999,6 +1126,86 @@ "markers": "python_version >= '3.6'", "version": "==0.7.1" }, + "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": { "hashes": [ "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", @@ -1027,58 +1234,55 @@ "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==0.981" }, "mypy-extensions": { "hashes": [ - "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", - "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" ], - "markers": "python_version >= '3.5'", - "version": "==1.0.0" + "version": "==0.4.3" + }, + "neo4j": { + "hashes": [ + "sha256:b6c49fbd60426e268ed4afbd414766444fe70aee1ac0376a0c871d75526b8251" + ], + "index": "pypi", + "version": "==4.2.1" }, "numpy": { "hashes": [ - "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", - "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", - "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", - "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", - "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", - "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", - "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", - "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", - "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", - "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", - "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", - "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", - "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", - "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", - "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", - "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", - "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", - "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", - "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", - "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", - "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", - "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", - "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", - "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", - "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", - "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", - "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", - "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", - "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", - "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", - "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", - "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", - "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", - "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", - "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", - "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" - ], - "markers": "python_version >= '3.9'", - "version": "==1.26.4" + "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9", + "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398", + "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7", + "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2", + "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954", + "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6", + "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032", + "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36", + "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c", + "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8", + "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7", + "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f", + "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700", + "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086", + "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7", + "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2", + "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9", + "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407", + "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2", + "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36", + "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566", + "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1", + "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e", + "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51", + "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1", + "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d", + "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf", + "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7" + ], + "markers": "python_version < '3.10'", + "version": "==1.24.1" }, "oauthlib": { "hashes": [ @@ -1090,12 +1294,11 @@ }, "openai": { "hashes": [ - "sha256:58922c785d167458b46e3c76e7b1bc2306f313ee9b71791e84cbf590abe160f2", - "sha256:77ef3db6110071f7154859e234250fb945a36554207a30a4491092eadb73fcb5" + "sha256:2483095c7db1eee274cebac79e315a986c4e55207bb4fa7b82d185b3a2ed9536", + "sha256:e0a7c2f7da26bdbe5354b03c6d4b82a2f34bd4458c7a17ae1a7092c3e397e03c" ], "index": "pypi", - "markers": "python_full_version >= '3.7.1'", - "version": "==1.16.1" + "version": "==0.27.8" }, "openpyxl": { "hashes": [ @@ -1103,54 +1306,70 @@ "sha256:6456a3b472e1ef0facb1129f3c6ef00713cebf62e736cd7a75bcc3247432f251" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==3.0.7" }, "ordered-set": { - "hashes": ["sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95"], + "hashes": [ + "sha256:ba93b2df055bca202116ec44b9bead3df33ea63a7d5827ff8e16738b97f33a95" + ], "markers": "python_version >= '3.5'", "version": "==4.0.2" }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", + "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" ], "markers": "python_version >= '3.7'", - "version": "==24.0" + "version": "==23.0" }, "pandas": { "hashes": [ + "sha256:02f1e8f71cd994ed7fcb9a35b6ddddeb4314822a0e09a9c5b2d278f8cb5d4096", + "sha256:13f75fb18486759da3ff40f5345d9dd20e7d78f2a39c5884d013456cec9876f0", "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813", "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792", + "sha256:35b670b0abcfed7cad76f2834041dcf7ae47fd9b22b63622d67cdc933d79f453", "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406", "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373", "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328", + "sha256:4c73f373b0800eb3062ffd13d4a7a2a6d522792fa6eb204d67a4fad0a40f03dc", "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996", "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf", + "sha256:5759edf0b686b6f25a5d4a447ea588983a33afc8a0081a0954184a4a87fd0dd7", + "sha256:5a7cf6044467c1356b2b49ef69e50bf4d231e773c3ca0558807cdba56b76820b", "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6", "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7", "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc", + "sha256:69c5d920a0b2a9838e677f78f4dde506b95ea8e4d30da25859db6469ded84fa8", "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1", "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23", "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a", + "sha256:8778a5cc5a8437a561e3276b85367412e10ae9fff07db1eed986e427d9a674f8", "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51", "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572", "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31", + "sha256:9871ef5ee17f388f1cb35f76dc6106d40cb8165c562d573470672f4cdefa59ef", + "sha256:9c31d52f1a7dd2bb4681d9f62646c7aa554f19e8e9addc17e8b1b20011d7522d", "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5", "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a", + "sha256:ab8173a8efe5418bbe50e43f321994ac6673afc5c7c4839014cf6401bbdd0705", + "sha256:ae961f1f0e270f1e4e2273f6a539b2ea33248e0e3a11ffb479d757918a5e03a9", + "sha256:b3c4f93fcb6e97d993bf87cdd917883b7dab7d20c627699f360a8fb49e9e0b91", "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003", "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d", "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354", "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee", "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa", + "sha256:c9410ce8a3dee77653bc0684cfa1535a7f9c291663bd7ad79e39f5ab58f67ab3", "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0", "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9", "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae", - "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc" + "sha256:f69e0f7b7c09f1f612b1f8f59e2df72faa8a6b41c5a436dde5b615aaf948f107", + "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc", + "sha256:faa42a78d1350b02a7d2f0dbe3c80791cf785663d6997891549d0f86dc49125e" ], "index": "pypi", - "markers": "python_version >= '3.8'", "version": "==1.5.3" }, "paramiko": { @@ -1171,10 +1390,10 @@ }, "patsy": { "hashes": [ - "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6", - "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb" + "sha256:7eb5349754ed6aa982af81f636479b1b8db9d5b1a6e957a6016ec0534b5c86b7", + "sha256:bdc18001875e319bc91c812c1eb6a10be4bb13cb81eb763f466179dca3b67277" ], - "version": "==0.5.6" + "version": "==0.5.3" }, "pdfminer-six": { "hashes": [ @@ -1182,16 +1401,15 @@ "sha256:f5ab6aae4999c1460aa569c716cde75c1585e3f4f2e3fcaf6c950696937d1741" ], "index": "pypi", - "markers": "python_version >= '3.4'", "version": "==20200402" }, "pexpect": { "hashes": [ - "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", - "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" + "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", + "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" ], "markers": "sys_platform != 'win32'", - "version": "==4.9.0" + "version": "==4.8.0" }, "pickleshare": { "hashes": [ @@ -1243,55 +1461,55 @@ "sha256:ff04c373477723430dce2e9d024c708a047d44cf17166bf16e604b379bf0ca14" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==8.3.1" }, "prompt-toolkit": { "hashes": [ - "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d", - "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6" + "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63", + "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.43" + "markers": "python_full_version >= '3.6.2'", + "version": "==3.0.36" }, "protobuf": { "hashes": [ - "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4", - "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8", - "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c", - "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d", - "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4", - "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa", - "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c", - "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019", - "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", - "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c", - "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2" - ], - "markers": "python_version >= '3.8'", - "version": "==4.25.3" + "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30", + "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b", + "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc", + "sha256:299ea899484ee6f44604deb71f424234f654606b983cb496ea2a53e3c63ab791", + "sha256:3d164928ff0727d97022957c2b849250ca0e64777ee31efd7d6de2e07c494717", + "sha256:6ab80df09e3208f742c98443b6166bcb70d65f52cfeb67357d52032ea1ae9bec", + "sha256:78a28c9fa223998472886c77042e9b9afb6fe4242bd2a2a5aced88e3f4422aa7", + "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab", + "sha256:89f9149e4a0169cddfc44c74f230d7743002e3aa0b9472d8c28f0388102fc4c2", + "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5", + "sha256:b135410244ebe777db80298297a97fbb4c862c881b4403b71bac9d4107d61fd1", + "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462", + "sha256:d1736130bce8cf131ac7957fa26880ca19227d4ad68b4888b3be0dea1f95df97", + "sha256:f45460f9ee70a0ec1b6694c6e4e348ad2019275680bd68a1d9314b8c7e01e574" + ], + "markers": "python_version >= '3.7'", + "version": "==4.21.12" }, "psutil": { "hashes": [ - "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d", - "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73", - "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8", - "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2", - "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e", - "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36", - "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7", - "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c", - "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee", - "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421", - "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf", - "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81", - "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0", - "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631", - "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4", - "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8" + "sha256:149555f59a69b33f056ba1c4eb22bb7bf24332ce631c44a319cec09f876aaeff", + "sha256:16653106f3b59386ffe10e0bad3bb6299e169d5327d3f187614b1cb8f24cf2e1", + "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62", + "sha256:3ff89f9b835100a825b14c2808a106b6fdcc4b15483141482a12c725e7f78549", + "sha256:54c0d3d8e0078b7666984e11b12b88af2db11d11249a8ac8920dd5ef68a66e08", + "sha256:54d5b184728298f2ca8567bf83c422b706200bcbbfafdc06718264f9393cfeb7", + "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e", + "sha256:68908971daf802203f3d37e78d3f8831b6d1014864d7a85937941bb35f09aefe", + "sha256:6b92c532979bafc2df23ddc785ed116fced1f492ad90a6830cf24f4d1ea27d24", + "sha256:852dd5d9f8a47169fe62fd4a971aa07859476c2ba22c2254d4a1baa4e10b95ad", + "sha256:9120cd39dca5c5e1c54b59a41d205023d436799b1c8c4d3ff71af18535728e94", + "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8", + "sha256:efeae04f9516907be44904cc7ce08defb6b665128992a56957abc9b61dca94b7", + "sha256:fd8522436a6ada7b4aad6638662966de0d61d241cb821239b2ae7013d41a43d4" ], - "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.8" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==5.9.4" }, "psycopg2-binary": { "hashes": [ @@ -1299,13 +1517,18 @@ "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425", "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f", "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0", + "sha256:040234f8a4a8dfd692662a8308d78f63f31a97e1c42d2480e5e6810c48966a29", "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460", "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41", "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85", + "sha256:086f7e89ec85a6704db51f68f0dcae432eff9300809723a6e8782c41c2f48e03", "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd", + "sha256:18ca813fdb17bc1db73fe61b196b05dd1ca2165b884dd5ec5568877cabf9b039", + "sha256:19dc39616850342a2a6db70559af55b22955f86667b5f652f40c0e99253d9881", "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0", "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd", "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147", + "sha256:2166e770cb98f02ed5ee2b0b569d40db26788e0bf2ec3ae1a0d864ea6f1d8309", "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c", "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903", "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba", @@ -1313,41 +1536,65 @@ "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577", "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c", "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7", + "sha256:3a2522b1d9178575acee4adf8fd9f979f9c0449b00b4164bb63c3475ea6528ed", + "sha256:3aa773580f85a28ffdf6f862e59cb5a3cc7ef6885121f2de3fca8d6ada4dbf3b", + "sha256:3b5deaa3ee7180585a296af33e14c9b18c218d148e735c7accf78130765a47e3", "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867", "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2", + "sha256:407af6d7e46593415f216c7f56ba087a9a42bd6dc2ecb86028760aa45b802bd7", "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9", "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff", "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a", "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302", "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1", + "sha256:4c3c09fb674401f630626310bcaf6cd6285daf0d5e4c26d6e55ca26a2734e39b", + "sha256:4c6717962247445b4f9e21c962ea61d2e884fc17df5ddf5e35863b016f8a1f03", "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79", + "sha256:50446fae5681fc99f87e505d4e77c9407e683ab60c555ec302f9ac9bffa61103", + "sha256:5057669b6a66aa9ca118a2a860159f0ee3acf837eda937bdd2a64f3431361a2d", "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835", "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42", "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e", "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61", + "sha256:5dd90c5438b4f935c9d01fcbad3620253da89d19c1f5fca9158646407ed7df35", "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32", "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68", + "sha256:659c815b5b8e2a55193ede2795c1e2349b8011497310bb936da7d4745652823b", "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1", + "sha256:69b13fdf12878b10dc6003acc8d0abf3ad93e79813fd5f3812497c1c9fb9be49", "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60", "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8", "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b", "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a", + "sha256:7a1cb80e35e1ccea3e11a48afe65d38744a0e0bde88795cc56a4d05b6e4f9d70", "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec", "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5", "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2", "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16", + "sha256:7e6e3c52e6732c219c07bd97fff6c088f8df4dae3b79752ee3a817e6f32e177e", "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5", + "sha256:7f42a8490c4fe854325504ce7a6e4796b207960dabb2cbafe3c3959cb00d1d7e", + "sha256:84156313f258eafff716b2961644a4483a9be44a5d43551d554844d15d4d224e", + "sha256:8578d6b8192e4c805e85f187bc530d0f52ba86c39172e61cd51f68fddd648103", + "sha256:890167d5091279a27e2505ff0e1fb273f8c48c41d35c5b92adbf4af80e6b2ed6", "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6", "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1", "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503", + "sha256:98e10634792ac0e9e7a92a76b4991b44c2325d3e7798270a808407355e7bb0a1", + "sha256:9aadff9032e967865f9778485571e93908d27dab21d0fdfdec0ca779bb6f8ad9", "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b", "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d", + "sha256:9f24f383a298a0c0f9b3113b982e21751a8ecde6615494a3f1470eb4a9d70e9e", "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28", "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4", "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5", + "sha256:a73021b44813b5c84eda4a3af5826dd72356a900bac9bd9dd1f0f81ee1c22c2f", "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5", "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e", + "sha256:afd96845e12638d2c44d213d4810a08f4dc4a563f9a98204b7428e567014b1cd", + "sha256:b73ddf033d8cd4cc9dfed6324b1ad2a89ba52c410ef6877998422fcb9c23e3a8", "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f", + "sha256:b8f490f5fad1767a1331df1259763b3bad7d7af12a75b950c2843ba319b2415f", "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636", "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d", "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64", @@ -1361,14 +1608,16 @@ "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91", "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c", "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24", + "sha256:dbc5cd56fff1a6152ca59445178652756f4e509f672e49ccdf3d79c1043113a4", "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee", "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d", "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b", "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935", + "sha256:eac8a3499754790187bb00574ab980df13e754777d346f85e0ff6df929bcd964", + "sha256:eaed1c65f461a959284649e37b5051224f4db6ebdc84e40b5e65f2986f101a08", "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==2.9.5" }, "ptyprocess": { @@ -1380,166 +1629,87 @@ }, "pyasn1": { "hashes": [ - "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c", - "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473" - ], - "markers": "python_version >= '3.8'", - "version": "==0.6.0" + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" }, "pyasn1-modules": { "hashes": [ - "sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6", - "sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b" - ], - "markers": "python_version >= '3.8'", - "version": "==0.4.0" + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" }, "pycparser": { "hashes": [ - "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", - "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" ], - "markers": "python_version >= '3.8'", - "version": "==2.22" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.21" }, "pycryptodome": { "hashes": [ - "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690", - "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7", - "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4", - "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd", - "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5", - "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc", - "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818", - "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab", - "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d", - "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a", - "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25", - "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091", - "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea", - "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a", - "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c", - "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72", - "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9", - "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6", - "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044", - "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04", - "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c", - "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e", - "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f", - "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b", - "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4", - "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33", - "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f", - "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e", - "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a", - "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2", - "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3", - "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128" + "sha256:0198fe96c22f7bc31e7a7c27a26b2cec5af3cf6075d577295f4850856c77af32", + "sha256:0e45d2d852a66ecfb904f090c3f87dc0dfb89a499570abad8590f10d9cffb350", + "sha256:1047ac2b9847ae84ea454e6e20db7dcb755a81c1b1631a879213d2b0ad835ff2", + "sha256:13b3e610a2f8938c61a90b20625069ab7a77ccea20d65a9a0f926cc0cc1314b1", + "sha256:1fc16c80a5da8231fd1f953a7b8dfeb415f68120248e8d68383c5c2c4b18708c", + "sha256:265bfcbbf20d58e6871ce695a7a08aac9b41a0553060d9c05363abd6f3391bdd", + "sha256:2bf2a270906a02b7b255e1a0d7b3aea4f06b3983c51ddec1673c380e0dff5b30", + "sha256:47c71a0347847b747ba1349767b16cde049bc36f21654eb09cc82306ef5fdcf8", + "sha256:48d99869d58f3979d72f6fa0c50f48d16f14973bc4a3adb0ce3b8325fdd7e223", + "sha256:4d950ed2a887905b3fa709b86be5a163e26e1b174703ed59d34eb6832f213222", + "sha256:54d807314c66785c69cd25425933d4bd4c23547a593cdcf49d962fa3e0081336", + "sha256:58172080cbfaee724067a3c017add6a1a3cc167bbc8478dc5f2e5f45fa658763", + "sha256:5df582f2112dd72331de7e567837e136a9629181a8ab69ef8949e4bc294a0b99", + "sha256:6016269bb56caf0327f6d42e7bad1247e08b78407446dff562240c65f85d5a5e", + "sha256:63165fbdc247450017eb9ef04cfe15cb3a72ca48ffcc3a3b75b08c0340bf3647", + "sha256:69adf32522b75968e1cbf25b5d83e87c04cd9a55610ce1e4a19012e58e7e4023", + "sha256:856ebf822d08d754af62c22e2b93626509a72773214f92db1551e2b68d9e2a1b", + "sha256:95069fd9e2813668a2713a1efcc65cc26d2c7e741401ac46628f1ec957511f1b", + "sha256:b12a88566a98617b1a34b4e5a805dff2da98d83fc74262aff3c3d724d0f525d6", + "sha256:c69e19afc734b2a17b9d78b7bcb544aabd5a52ff628e14283b6e9404d27d0517", + "sha256:c82e3bc1e70dde153b0956bffe20a15715a1fe3e00bc23e88d6973eda4505944", + "sha256:d1daec4d31bb00918e4e178297ac6ca6f86ec4c851ba584770533ece554d29e2", + "sha256:d67a2d2fe344953e4572a7d30668cceb516b04287b8638170d562065e53ee2e0", + "sha256:dab9359cc295160ba96738ba4912c675181c84bfdf413e5c0621cf00b7deeeaa", + "sha256:e061311b02cefb17ea93d4a5eb1ad36dca4792037078b43e15a653a0a4478ead", + "sha256:e750a21d8a265b1f9bfb1a28822995ea33511ba7db5e2b55f41fb30781d0d073" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.20.0" - }, - "pydantic": { - "hashes": [ - "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6", - "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5" - ], - "markers": "python_version >= '3.8'", - "version": "==2.6.4" - }, - "pydantic-core": { - "hashes": [ - "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a", - "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed", - "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979", - "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff", - "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5", - "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45", - "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340", - "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad", - "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23", - "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6", - "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7", - "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241", - "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda", - "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187", - "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba", - "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c", - "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2", - "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c", - "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132", - "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf", - "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972", - "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db", - "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade", - "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4", - "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8", - "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f", - "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9", - "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48", - "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec", - "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d", - "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9", - "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb", - "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4", - "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89", - "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c", - "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9", - "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da", - "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac", - "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b", - "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf", - "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e", - "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137", - "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1", - "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b", - "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8", - "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e", - "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053", - "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01", - "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe", - "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd", - "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805", - "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183", - "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8", - "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99", - "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820", - "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074", - "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256", - "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8", - "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975", - "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad", - "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e", - "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca", - "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df", - "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b", - "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a", - "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a", - "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721", - "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a", - "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f", - "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2", - "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97", - "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6", - "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed", - "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc", - "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1", - "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe", - "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120", - "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f", - "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a" - ], - "markers": "python_version >= '3.8'", - "version": "==2.16.3" + "version": "==3.16.0" }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", + "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.6'", + "version": "==2.14.0" }, "pyjwt": { "hashes": [ @@ -1547,7 +1717,6 @@ "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==2.1.0" }, "pynacl": { @@ -1572,11 +1741,12 @@ "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], "index": "pypi", - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "pypdf4": { - "hashes": ["sha256:7c932441146d205572f96254d53c79ea2c30c9e11df55a5cf87e056c7b3d7f89"], + "hashes": [ + "sha256:7c932441146d205572f96254d53c79ea2c30c9e11df55a5cf87e056c7b3d7f89" + ], "index": "pypi", "version": "==1.27.0" }, @@ -1594,16 +1764,15 @@ "sha256:bb7cdd55776f5cf613e4bb9f0f0aba70b60408b964ec7c13b37f69b215acbbe8" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==7.5.2" }, "python-dateutil": { "hashes": [ - "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", - "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.9.0.post0" + "version": "==2.8.2" }, "python-http-client": { "hashes": [ @@ -1614,9 +1783,10 @@ "version": "==3.3.7" }, "python-json-logger": { - "hashes": ["sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398"], + "hashes": [ + "sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398" + ], "index": "pypi", - "markers": "python_version >= '3.4'", "version": "==2.0.1" }, "python-magic": { @@ -1625,21 +1795,18 @@ "sha256:ca884349f2c92ce830e3f498c5b7c7051fe2942c3ee4332f65213b8ebff15a62" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.4.22" }, "pytz": { "hashes": [ - "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", - "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" + "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0", + "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a" ], - "version": "==2024.1" + "version": "==2022.7.1" }, "pyyaml": { "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", @@ -1647,10 +1814,7 @@ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", @@ -1658,15 +1822,11 @@ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", @@ -1679,9 +1839,7 @@ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", @@ -1690,7 +1848,6 @@ "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==6.0.1" }, "redis": { @@ -1699,34 +1856,31 @@ "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.2" }, "requests": { - "extras": ["socks"], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.25.1" }, "requests-oauthlib": { "hashes": [ - "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", - "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" ], - "markers": "python_version >= '3.4'", - "version": "==2.0.0" + "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" + "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7", + "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.0.0" + "version": "==0.10.1" }, "rq": { "hashes": [ @@ -1734,7 +1888,6 @@ "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a" ], "index": "pypi", - "markers": "python_version >= '3.5'", "version": "==1.10.1" }, "rsa": { @@ -1768,7 +1921,6 @@ "sha256:f46dd15335e8a320b0fb4685f58b7471702234cba8bb3442b69a3e1dc329c345" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==1.6.1" }, "sendgrid": { @@ -1777,16 +1929,15 @@ "sha256:74b0dcf9a79188948f61f456bd1bf67ffa676a5d388aba1c76bff516566d7084" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==6.7.0" }, "setuptools": { "hashes": [ - "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", - "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" + "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab", + "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6" ], - "markers": "python_version >= '3.8'", - "version": "==69.2.0" + "markers": "python_version >= '3.7'", + "version": "==66.0.0" }, "six": { "hashes": [ @@ -1796,14 +1947,6 @@ "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:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", - "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" - }, "sortedcontainers": { "hashes": [ "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", @@ -1813,11 +1956,11 @@ }, "soupsieve": { "hashes": [ - "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", - "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7" + "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", + "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d" ], - "markers": "python_version >= '3.8'", - "version": "==2.5" + "markers": "python_version >= '3.6'", + "version": "==2.3.2.post1" }, "sqlalchemy": { "hashes": [ @@ -1861,24 +2004,27 @@ "sha256:fdd2ed7395df8ac2dbb10cefc44737b66c6a5cd7755c92524733d7a443e5b7e2" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.3.23" }, "sqlalchemy-searchable": { - "hashes": ["sha256:597de9d1356e8a0a8b3be7be892adee422e7419603f25c40a7ab5c16bd75f77d"], + "hashes": [ + "sha256:597de9d1356e8a0a8b3be7be892adee422e7419603f25c40a7ab5c16bd75f77d" + ], "index": "pypi", "version": "==1.2.0" }, "sqlalchemy-utils": { "hashes": [ - "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e", - "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990" + "sha256:9da26a9b20c6979167772ba5dc2a1d01265648f18c82995f082279a399ea308b", + "sha256:b37240917d81c14fe1b6e5096a402bace472b179121384e47c10d854dbf5af92" ], - "markers": "python_version >= '3.7'", - "version": "==0.41.2" + "markers": "python_version ~= '3.6'", + "version": "==0.39.0" }, "starkbank-ecdsa": { - "hashes": ["sha256:9399c3371b899d4a235b68a1ed7919d202fbf024bd2c863ae8ebdad343c2a63a"], + "hashes": [ + "sha256:9399c3371b899d4a235b68a1ed7919d202fbf024bd2c863ae8ebdad343c2a63a" + ], "version": "==2.2.0" }, "statsmodels": { @@ -1906,11 +2052,12 @@ "sha256:f61f33f64760a22100b6b146217823f73cfedd251c9bdbd58453ca94e63326c7" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==0.12.2" }, "svg-stack": { - "hashes": ["sha256:552d0958db5533ca2d1e541c06e60bbbf05a44eac164a1d89fd4361bbd0eb22d"], + "hashes": [ + "sha256:552d0958db5533ca2d1e541c06e60bbbf05a44eac164a1d89fd4361bbd0eb22d" + ], "index": "pypi", "version": "==0.1.0" }, @@ -1932,66 +2079,64 @@ }, "tqdm": { "hashes": [ - "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", - "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" + "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4", + "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1" ], - "markers": "python_version >= '3.7'", - "version": "==4.66.2" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.64.1" }, "traitlets": { "hashes": [ - "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9", - "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80" + "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b", + "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861" ], - "markers": "python_version >= '3.8'", - "version": "==5.14.2" + "markers": "python_version >= '3.7'", + "version": "==5.8.1" }, "types-cachetools": { "hashes": [ - "sha256:27c982cdb9cf3fead8b0089ee6b895715ecc99dac90ec29e2cab56eb1aaf4199", - "sha256:98c069dc7fc087b1b061703369c80751b0a0fc561f6fb072b554e5eee23773a0" + "sha256:67fa46d51a650896770aee0ba80f0e61dc4a7d1373198eec1bc0622263eaa256", + "sha256:c0c5fa00199017d974c935bf043c467d5204e4f835141e489b48765b5ac1d960" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==5.3.0.7" + "version": "==5.3.0.5" }, "typing-extensions": { "hashes": [ - "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", - "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" + "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", + "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" ], - "markers": "python_version >= '3.8'", - "version": "==4.10.0" + "markers": "python_version >= '3.7'", + "version": "==4.4.0" }, "typing-inspect": { "hashes": [ - "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", - "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78" + "sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188", + "sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d" ], - "version": "==0.9.0" + "version": "==0.8.0" }, "urllib3": { "hashes": [ - "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", - "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], "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" + "version": "==1.26.14" }, "validators": { "hashes": [ - "sha256:4a70757730619a2c0788aa3c60ba1680372173237c445571586cdef02e37223b", - "sha256:bc0d93d874a363bde9e61b7e31dd274fef168ec057ecb8118edc96c161a89285" + "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a" ], - "markers": "python_version >= '3.8'", - "version": "==0.27.0" + "markers": "python_version >= '3.4'", + "version": "==0.20.0" }, "wcwidth": { "hashes": [ - "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", - "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" + "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", + "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" ], - "version": "==0.2.13" + "version": "==0.2.6" }, "webargs": { "hashes": [ @@ -2007,7 +2152,6 @@ "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.16.0" }, "wrapt": { @@ -2018,30 +2162,23 @@ "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", - "sha256:2020f391008ef874c6d9e208b24f28e31bcb85ccff4f335f15a3251d222b92d9", "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", - "sha256:240b1686f38ae665d1b15475966fe0472f78e71b1b4903c143a842659c8e4cb9", "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", - "sha256:26046cd03936ae745a502abf44dac702a5e6880b2b01c29aea8ddf3353b68224", "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", - "sha256:2feecf86e1f7a86517cab34ae6c2f081fd2d0dac860cb0c0ded96d799d20b335", "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", - "sha256:358fe87cc899c6bb0ddc185bf3dbfa4ba646f05b1b0b9b5a27c2cb92c2cea204", "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", - "sha256:49ef582b7a1152ae2766557f0550a9fcbf7bbd76f43fbdc94dd3bf07cc7168be", "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", - "sha256:6447e9f3ba72f8e2b985a1da758767698efa72723d5b59accefd716e9e8272bf", "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", @@ -2064,10 +2201,8 @@ "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", - "sha256:a9008dad07d71f68487c91e96579c8567c98ca4c3881b9b113bc7b33e9fd78b8", "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", - "sha256:acae32e13a4153809db37405f5eba5bac5fbe2e2ba61ab227926a22901051c0a", "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", @@ -2082,7 +2217,6 @@ "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", - "sha256:ecee4132c6cd2ce5308e21672015ddfed1ff975ad0ac8d27168ea82e71413f55", "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" @@ -2093,11 +2227,92 @@ "xlsxwriter": { "hashes": [ "sha256:1239958b12da12be6abf05b32f64ff162eb75fff0fdf00d901ca0f46dc0557cf", + "sha256:828b3285fc95105f5b1946a6a015b31cf388bd5378fdc6604e4d1b7839df2e77", + "sha256:82a3b0e73e3913483da23791d1a25e4d2dbb3837d1be4129473526b9a270a5cc", "sha256:d79dadac9dcbff3c24281764b052b46bcdb391f3184f337c4c4e6ed8d2738d7d" ], "index": "pypi", - "markers": "python_version >= '3.6'", "version": "==3.0.7" + }, + "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" } }, "develop": { @@ -2107,16 +2322,15 @@ "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "certifi": { "hashes": [ - "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", - "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" ], "markers": "python_version >= '3.6'", - "version": "==2024.2.2" + "version": "==2022.12.7" }, "chardet": { "hashes": [ @@ -2132,7 +2346,6 @@ "sha256:ca516f86181f85615cd8210854b43acbe7b1f37ed8a082c5557749c73f2f0dd3" ], "index": "pypi", - "markers": "python_version >= '3.7' and python_version < '4.0'", "version": "==1.8.1" }, "flake8": { @@ -2141,13 +2354,13 @@ "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.9.2" }, "flake8-obey-import-goat": { - "hashes": ["sha256:2e4c7be21b96dda72e903c21de16ff928e11fccdf9427889bfb7ccf4610f6072"], + "hashes": [ + "sha256:2e4c7be21b96dda72e903c21de16ff928e11fccdf9427889bfb7ccf4610f6072" + ], "index": "pypi", - "markers": "python_version >= '3.9'", "version": "==0.1.1" }, "idna": { @@ -2167,19 +2380,56 @@ }, "more-itertools": { "hashes": [ - "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", - "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" + "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41", + "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab" ], - "markers": "python_version >= '3.8'", - "version": "==10.2.0" + "markers": "python_version >= '3.7'", + "version": "==9.0.0" + }, + "mypy": { + "hashes": [ + "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", + "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", + "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", + "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", + "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", + "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", + "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", + "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", + "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", + "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", + "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", + "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", + "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", + "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", + "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", + "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", + "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", + "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", + "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", + "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", + "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", + "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", + "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", + "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" + ], + "index": "pypi", + "version": "==0.981" + }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" }, "packaging": { "hashes": [ - "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" + "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", + "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" ], "markers": "python_version >= '3.7'", - "version": "==24.0" + "version": "==23.0" }, "pluggy": { "hashes": [ @@ -2203,7 +2453,6 @@ "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.7.0" }, "pyflakes": { @@ -2220,7 +2469,6 @@ "sha256:ff615c761e25eb25df19edddc0b970302d2a9091fbce0e7213298d85fb61fef6" ], "index": "pypi", - "markers": "python_version >= '3.5'", "version": "==5.3.5" }, "redis": { @@ -2229,17 +2477,14 @@ "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.2" }, "requests": { - "extras": ["socks"], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.25.1" }, "responses": { @@ -2248,16 +2493,15 @@ "sha256:b82502eb5f09a0289d8e209e7bad71ef3978334f56d09b444253d5ad67bf5253" ], "index": "pypi", - "markers": "python_version >= '3.7'", "version": "==0.21.0" }, "setuptools": { "hashes": [ - "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", - "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" + "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab", + "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6" ], - "markers": "python_version >= '3.8'", - "version": "==69.2.0" + "markers": "python_version >= '3.7'", + "version": "==66.0.0" }, "six": { "hashes": [ @@ -2274,6 +2518,14 @@ ], "version": "==2.4.0" }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.2" + }, "types-cryptography": { "hashes": [ "sha256:09cc53f273dd4d8c29fa7ad11fefd9b734126d467960162397bc5e3e604dea75", @@ -2313,20 +2565,28 @@ "index": "pypi", "version": "==2.25.8" }, + "typing-extensions": { + "hashes": [ + "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", + "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" + ], + "markers": "python_version >= '3.7'", + "version": "==4.4.0" + }, "urllib3": { "hashes": [ - "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", - "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0" + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" ], "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" + "version": "==1.26.14" }, "wcwidth": { "hashes": [ - "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", - "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" + "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", + "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" ], - "version": "==0.2.13" + "version": "==0.2.6" } } } diff --git a/appserver/bin/migration-integrity-check b/appserver/bin/migration-integrity-check index ea6144c9ff..0d626b97de 100755 --- a/appserver/bin/migration-integrity-check +++ b/appserver/bin/migration-integrity-check @@ -5,7 +5,7 @@ echo "Checking migration integrity..." # Start in appserver directory __dir__="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd ${__dir__}/migrations +cd ${__dir__}/../migrations head_count=$(alembic heads | wc -l) From f38cf54cbf08d7d6469d5d480a2b0b63e8c5c4d8 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 4 Apr 2024 07:33:55 +0000 Subject: [PATCH 18/23] Fix code style issues with Black --- .../src/biocyc/base_data_file_parser.py | 164 ++++++++++++++---- .../extractor/src/common/liquibase_utils.py | 55 ++++-- .../src/ncbi/ncbi_taxonomy_liquibase.py | 51 +++++- 3 files changed, 208 insertions(+), 62 deletions(-) diff --git a/graph-db/extractor/src/biocyc/base_data_file_parser.py b/graph-db/extractor/src/biocyc/base_data_file_parser.py index 93771b86bf..1419035717 100644 --- a/graph-db/extractor/src/biocyc/base_data_file_parser.py +++ b/graph-db/extractor/src/biocyc/base_data_file_parser.py @@ -16,8 +16,18 @@ class BaseDataFileParser(BaseParser): """ Base parser for Biocyc .dat files. """ - def __init__(self, base_data_dir: str, biocyc_dbname, tar_file, datafile_name, entity_name, attr_names:dict, rel_names:dict, - db_link_sources: dict=None): + + def __init__( + self, + base_data_dir: str, + biocyc_dbname, + tar_file, + datafile_name, + entity_name, + attr_names: dict, + rel_names: dict, + db_link_sources: dict = None, + ): """ :param base_data_dir: the data file base directory, that is the parent folder for 'download' :param biocyc_dbname: biocyc database name, eg. DB_ECOCYC, DB_HUMANCYC @@ -32,7 +42,7 @@ def __init__(self, base_data_dir: str, biocyc_dbname, tar_file, datafile_name, e self.input_zip = os.path.join(self.download_dir, tar_file) self.db_output_dir = os.path.join(self.output_dir, biocyc_dbname.lower()) self.datafile = datafile_name - self.node_labels = [NODE_BIOCYC, 'db_' + biocyc_dbname, entity_name] + self.node_labels = [NODE_BIOCYC, 'db_' + biocyc_dbname, entity_name] self.entity_name = entity_name self.attr_name_map = attr_names self.rel_name_map = rel_names @@ -41,10 +51,10 @@ def __init__(self, base_data_dir: str, biocyc_dbname, tar_file, datafile_name, e self.version = '' self.logger = logging.getLogger(__name__) - def create_synonym_rels(self)->bool: + def create_synonym_rels(self) -> bool: return False - def get_db_version(self, tar:TarFile): + def get_db_version(self, tar: TarFile): """ find the latest version of data in the tar file. Sometimes a tar file has multiple version data. :param tar: @@ -65,7 +75,10 @@ def parse_data_file(self): self.version = self.get_db_version(tar) self.logger.info(f'Database file version: "{self.version}"') for tarinfo in tar: - if tarinfo.name.endswith('/'+ self.datafile) and self.version in tarinfo.name: + if ( + tarinfo.name.endswith('/' + self.datafile) + and self.version in tarinfo.name + ): self.logger.info('Parse ' + tarinfo.name) utf8reader = codecs.getreader('ISO-8859-1') f = utf8reader(tar.extractfile(tarinfo.name)) @@ -74,7 +87,9 @@ def parse_data_file(self): prev_line_is_comment = False for line in f: line = biocyc_utils.cleanhtml(line) - node, prev_line_is_comment = self.parse_line(line, node, nodes, prev_line_is_comment) + node, prev_line_is_comment = self.parse_line( + line, node, nodes, prev_line_is_comment + ) return nodes def parse_line(self, line, node, nodes, prev_line_is_comment): @@ -85,7 +100,12 @@ def parse_line(self, line, node, nodes, prev_line_is_comment): # add data source property node.add_attribute(PROP_DATA_SOURCE, DB_BIOCYC, "str") - if node and PROP_COMMENT in self.attr_name_map and prev_line_is_comment and line.startswith('/'): + if ( + node + and PROP_COMMENT in self.attr_name_map + and prev_line_is_comment + and line.startswith('/') + ): line = line[1:].strip() node.add_attribute(PROP_COMMENT, line, 'str') elif node: @@ -97,7 +117,9 @@ def parse_line(self, line, node, nodes, prev_line_is_comment): else: prev_line_is_comment = True if attr in self.attr_name_map: - prop_name, data_type = biocyc_utils.get_property_name_type(attr, self.attr_name_map) + prop_name, data_type = biocyc_utils.get_property_name_type( + attr, self.attr_name_map + ) node.add_attribute(prop_name, val, data_type) if attr == UNIQUE_ID: node.add_attribute(PROP_ID, val, data_type) @@ -109,7 +131,11 @@ def parse_line(self, line, node, nodes, prev_line_is_comment): db_name = tokens[0].lstrip('(') reference_id = tokens[1].strip(')').strip('"') add_prefix = tokens[1] - self.add_dblink(node, db_name, reference_id, ) + self.add_dblink( + node, + db_name, + reference_id, + ) else: rel_type = self.rel_name_map.get(attr) node.add_edge_type(rel_type, val) @@ -117,20 +143,26 @@ def parse_line(self, line, node, nodes, prev_line_is_comment): self.logger.error('line:', line) return node, prev_line_is_comment - def add_dblink(self, node:NodeData, db_name, reference_id): + def add_dblink(self, node: NodeData, db_name, reference_id): link_node = NodeData(NODE_DBLINK, PROP_REF_ID) if reference_id.startswith(db_name): - reference_id = reference_id[len(db_name)+1:] # remove db prefix + reference_id = reference_id[len(db_name) + 1 :] # remove db prefix link_node.update_attribute(PROP_REF_ID, reference_id) link_node.update_attribute(PROP_DB_NAME, db_name) node.add_edge(node, link_node, REL_DBLINKS) def create_indexes(self, database: Database): - database.create_index(self.entity_name, PROP_ID, f"index_{self.entity_name.lower}_id") - database.create_index(self.entity_name, PROP_BIOCYC_ID, f"index_{self.entity_name.lower}_biocycid") - database.create_index(self.entity_name, PROP_NAME, f"index_{self.entity_name.lower}_name") + database.create_index( + self.entity_name, PROP_ID, f"index_{self.entity_name.lower}_id" + ) + database.create_index( + self.entity_name, PROP_BIOCYC_ID, f"index_{self.entity_name.lower}_biocycid" + ) + database.create_index( + self.entity_name, PROP_NAME, f"index_{self.entity_name.lower}_name" + ) - def update_nodes_in_graphdb(self, nodes:[], database:Database, etl_load_id: str): + def update_nodes_in_graphdb(self, nodes: [], database: Database, etl_load_id: str): """ Load or update nodes in KG. This can also be called for initial loading. :param nodes: list of nodes @@ -145,10 +177,17 @@ def update_nodes_in_graphdb(self, nodes:[], database:Database, etl_load_id: str) for node in nodes: rows.append(node.to_dict()) attrs = self.attrs + [PROP_ID, PROP_DATA_SOURCE] - query = get_update_nodes_query(NODE_BIOCYC, PROP_BIOCYC_ID, attrs, self.node_labels, etl_load_id=etl_load_id, return_node_count=True) + query = get_update_nodes_query( + NODE_BIOCYC, + PROP_BIOCYC_ID, + attrs, + self.node_labels, + etl_load_id=etl_load_id, + return_node_count=True, + ) return database.load_data_from_rows(query, rows, return_node_count=True) - def add_edges_to_graphdb(self, nodes:[], database:Database, etl_load_id): + def add_edges_to_graphdb(self, nodes: [], database: Database, etl_load_id): no_of_created_nodes = 0 no_of_updated_nodes = 0 no_of_created_relations = 0 @@ -161,7 +200,7 @@ def add_edges_to_graphdb(self, nodes:[], database:Database, etl_load_id): id = node.get_attribute(PROP_BIOCYC_ID) synonyms = node.get_synonym_set() for syn in synonyms: - synonym_list.append({PROP_BIOCYC_ID:id, PROP_NAME: syn}) + synonym_list.append({PROP_BIOCYC_ID: id, PROP_NAME: syn}) for edge in node.edges: from_id = edge.source.get_attribute(edge.source.id_attr) to_id = edge.dest.get_attribute(edge.dest.id_attr) @@ -173,7 +212,9 @@ def add_edges_to_graphdb(self, nodes:[], database:Database, etl_load_id): if db_name in self.db_link_sources: if db_name not in db_link_dict: db_link_dict[db_name] = [] - db_link_dict[db_name].append({'from_id': from_id, 'to_id': to_id}) + db_link_dict[db_name].append( + {'from_id': from_id, 'to_id': to_id} + ) else: if rel not in entity_rel_dict: entity_rel_dict[rel] = [] @@ -181,48 +222,95 @@ def add_edges_to_graphdb(self, nodes:[], database:Database, etl_load_id): if synonym_list: self.logger.info('Add synonyms') - query = get_create_synonym_relationships_query(NODE_BIOCYC, PROP_BIOCYC_ID, PROP_BIOCYC_ID, PROP_NAME, [], etl_load_id=etl_load_id, return_node_count=True) + query = get_create_synonym_relationships_query( + NODE_BIOCYC, + PROP_BIOCYC_ID, + PROP_BIOCYC_ID, + PROP_NAME, + [], + etl_load_id=etl_load_id, + return_node_count=True, + ) self.logger.debug(query) - node_count, result_counters = database.load_data_from_rows(query, synonym_list, return_node_count=True) + node_count, result_counters = database.load_data_from_rows( + query, synonym_list, return_node_count=True + ) no_of_created_nodes += result_counters.nodes_created - no_of_updated_nodes += (node_count - result_counters.nodes_created) + no_of_updated_nodes += node_count - result_counters.nodes_created for rel in entity_rel_dict.keys(): self.logger.info('Add relationship ' + rel) - query = get_create_relationships_query(NODE_BIOCYC, PROP_BIOCYC_ID, 'from_id', - NODE_BIOCYC, PROP_BIOCYC_ID, 'to_id', rel, etl_load_id=etl_load_id, return_node_count=True) + query = get_create_relationships_query( + NODE_BIOCYC, + PROP_BIOCYC_ID, + 'from_id', + NODE_BIOCYC, + PROP_BIOCYC_ID, + 'to_id', + rel, + etl_load_id=etl_load_id, + return_node_count=True, + ) self.logger.debug(query) - node_count, result_counters = database.load_data_from_rows(query, entity_rel_dict[rel], return_node_count=True) + node_count, result_counters = database.load_data_from_rows( + query, entity_rel_dict[rel], return_node_count=True + ) no_of_created_relations += result_counters.relationships_created - no_of_updated_relations += (node_count - result_counters.relationships_created) + no_of_updated_relations += ( + node_count - result_counters.relationships_created + ) - _no_of_created_relations, _no_of_updated_relations = self.add_dblinks_to_graphdb(db_link_dict, database, etl_load_id) + ( + _no_of_created_relations, + _no_of_updated_relations, + ) = self.add_dblinks_to_graphdb(db_link_dict, database, etl_load_id) no_of_created_relations += _no_of_created_relations no_of_updated_relations += _no_of_updated_relations - return no_of_created_nodes, no_of_updated_nodes, no_of_created_relations, no_of_updated_relations + return ( + no_of_created_nodes, + no_of_updated_nodes, + no_of_created_relations, + no_of_updated_relations, + ) - def add_dblinks_to_graphdb(self, db_link_dict:dict, database:Database, etl_load_id): + def add_dblinks_to_graphdb( + self, db_link_dict: dict, database: Database, etl_load_id + ): no_of_created_relations = 0 no_of_updated_relations = 0 for db_name in db_link_dict.keys(): - self.logger.info('Add DB Link relationship to ' + db_name ) + self.logger.info('Add DB Link relationship to ' + db_name) dest_label = 'db_' + db_name rel = db_name.upper() + '_LINK' - query = get_create_relationships_query(NODE_BIOCYC, PROP_BIOCYC_ID, 'from_id', - dest_label, PROP_ID, 'to_id', rel, etl_load_id=etl_load_id, return_node_count=True) + query = get_create_relationships_query( + NODE_BIOCYC, + PROP_BIOCYC_ID, + 'from_id', + dest_label, + PROP_ID, + 'to_id', + rel, + etl_load_id=etl_load_id, + return_node_count=True, + ) self.logger.debug(query) - node_count, result_counters = database.load_data_from_rows(query, db_link_dict[db_name], return_node_count=True) + node_count, result_counters = database.load_data_from_rows( + query, db_link_dict[db_name], return_node_count=True + ) no_of_created_relations += result_counters.relationships_created - no_of_updated_relations += (node_count - result_counters.relationships_created) + no_of_updated_relations += ( + node_count - result_counters.relationships_created + ) return no_of_created_relations, no_of_updated_relations - def write_entity_data_files(self, nodes:[]): + def write_entity_data_files(self, nodes: []): os.makedirs(self.db_output_dir, 0o777, True) self.logger.info(f'Writing {self.entity_name} files') - with open(os.path.join(self.db_output_dir, self.entity_name.lower() + '.tsv'), 'w') as f: + with open( + os.path.join(self.db_output_dir, self.entity_name.lower() + '.tsv'), 'w' + ) as f: attrs = [PROP_ID] + [PROP_DATA_SOURCE] + self.attrs f.write('\t'.join(attrs) + '\n') f.writelines(NodeData.get_entity_data_rows(nodes, attrs)) - diff --git a/graph-db/extractor/src/common/liquibase_utils.py b/graph-db/extractor/src/common/liquibase_utils.py index e8ca87bd64..97b73a198a 100644 --- a/graph-db/extractor/src/common/liquibase_utils.py +++ b/graph-db/extractor/src/common/liquibase_utils.py @@ -31,12 +31,16 @@ def get_changelog_template(): class ChangeLog: def __init__(self, author: str, change_id_prefix: str): if not change_id_prefix: - raise ValueError('The argument change_id_prefix must not be null or empty string') + raise ValueError( + 'The argument change_id_prefix must not be null or empty string' + ) try: int(change_id_prefix.split('-')[1]) except Exception: - raise ValueError('The argument change_id_prefix must be the JIRA card number; e.g LL-1234') + raise ValueError( + 'The argument change_id_prefix must be the JIRA card number; e.g LL-1234' + ) self.author = author self.id_prefix = change_id_prefix self.file_prefix = f'jira-{change_id_prefix}-' @@ -72,15 +76,26 @@ def create_changelog_str(self): template = get_template(sql_template) # liquibase doesn't like the `<` character self.cypher = self.cypher.replace('<', '<') - return template.render(change_id=self.id, author=self.author, change_comment=self.comment, cypher_query=self.cypher) + return template.render( + change_id=self.id, + author=self.author, + change_comment=self.comment, + cypher_query=self.cypher, + ) class CustomChangeSet(ChangeSet): - def __init__(self, id, author, comment, cypher, - filename:str, - handler="edu.ucsd.sbrg.FileQueryHandler", - filetype='TSV', - startrow=1): + def __init__( + self, + id, + author, + comment, + cypher, + filename: str, + handler="edu.ucsd.sbrg.FileQueryHandler", + filetype='TSV', + startrow=1, + ): ChangeSet.__init__(self, id, author, comment, cypher) self.handler = handler self.filename = filename.replace('.tsv', '.zip') @@ -89,9 +104,17 @@ def __init__(self, id, author, comment, cypher, def create_changelog_str(self): template = get_template(custom_template) - return template.render(change_id=self.id, change_comment=self.comment, author=self.author, - handler_class=self.handler, cypher_query=self.cypher, data_file=self.filename, - start_at=self.start_at, file_type=self.filetype, params=CUSTOM_PARAMS) + return template.render( + change_id=self.id, + change_comment=self.comment, + author=self.author, + handler_class=self.handler, + cypher_query=self.cypher, + data_file=self.filename, + start_at=self.start_at, + file_type=self.filetype, + params=CUSTOM_PARAMS, + ) def generate_sql_changelog_file(id, author, comment, cypher, outfile): @@ -104,7 +127,9 @@ def generate_sql_changelog_file(id, author, comment, cypher, outfile): if __name__ == '__main__': cypher = 'match(n:Gene)-[r]-(:Gene) where r.score < 0.4 delete r;' comment = 'Remove ecocyc-plus string relationships with 0.4 threshold. After the update, create ecocyc-plus-10012021.dump file' - outfile = os.path.join('../../../migration/liquibase/ecocyc-plus/ecocyc-plus changelog-0010.xml') - generate_sql_changelog_file('LL-3702 cut string rels with threshold', 'robin cai', - comment, - cypher, outfile) + outfile = os.path.join( + '../../../migration/liquibase/ecocyc-plus/ecocyc-plus changelog-0010.xml' + ) + generate_sql_changelog_file( + 'LL-3702 cut string rels with threshold', 'robin cai', comment, cypher, outfile + ) diff --git a/graph-db/extractor/src/ncbi/ncbi_taxonomy_liquibase.py b/graph-db/extractor/src/ncbi/ncbi_taxonomy_liquibase.py index 72d628be25..e30d0aa70e 100644 --- a/graph-db/extractor/src/ncbi/ncbi_taxonomy_liquibase.py +++ b/graph-db/extractor/src/ncbi/ncbi_taxonomy_liquibase.py @@ -9,6 +9,7 @@ # reference to this directory directory = os.path.realpath(os.path.dirname(__file__)) + class NcbiTaxonomyChangeLog(ChangeLog): def __init__(self, author: str, change_id_prefix: str): super().__init__(author, change_id_prefix) @@ -28,8 +29,12 @@ def load_ncbi_taxonomy_nodes(self): if self.id_prefix: id = f'{self.id_prefix} {id}' comment = 'Load NCBI taxonomy nodes' - query = get_create_update_nodes_query(NODE_TAXONOMY, PROP_ID, NODE_ATTRS, [NODE_NCBI], datasource='NCBI Taxonomy') - changeset = CustomChangeSet(id, self.author, comment, query, f'{self.file_prefix}{NCBI_TAXONOMY_FILE}') + query = get_create_update_nodes_query( + NODE_TAXONOMY, PROP_ID, NODE_ATTRS, [NODE_NCBI], datasource='NCBI Taxonomy' + ) + changeset = CustomChangeSet( + id, self.author, comment, query, f'{self.file_prefix}{NCBI_TAXONOMY_FILE}' + ) self.change_sets.append(changeset) def load_ncbi_taxonomy_synonym_rels(self): @@ -37,8 +42,16 @@ def load_ncbi_taxonomy_synonym_rels(self): if self.id_prefix: id = f'{self.id_prefix} {id}' comment = 'Load NCBI gene taxonomy relationship' - query = get_create_synonym_relationships_query(NODE_TAXONOMY, PROP_ID, PROP_ID, PROP_NAME, [PROP_TYPE]) - changeset = CustomChangeSet(id, self.author, comment, query, f'{self.file_prefix}{NCBI_TAXONOMY_SYNONYM_FILE}') + query = get_create_synonym_relationships_query( + NODE_TAXONOMY, PROP_ID, PROP_ID, PROP_NAME, [PROP_TYPE] + ) + changeset = CustomChangeSet( + id, + self.author, + comment, + query, + f'{self.file_prefix}{NCBI_TAXONOMY_SYNONYM_FILE}', + ) self.change_sets.append(changeset) def load_ncbi_taxonomy_parent_rels(self): @@ -50,7 +63,9 @@ def load_ncbi_taxonomy_parent_rels(self): CALL apoc.periodic.iterate( 'MATCH (n:Taxonomy), (m:Taxonomy) WHERE m.prop = n.parent_id RETURN n, m', 'MERGE (n)-[:HAS_PARENT]->(m)', {batchSize:5000}) - """.replace('prop', PROP_ID) + """.replace( + 'prop', PROP_ID + ) changeset = ChangeSet(id, self.author, comment, query) self.change_sets.append(changeset) @@ -65,10 +80,28 @@ def set_species_id(self): def create_indexes(self): queries = [] - queries.append(get_create_constraint_query(NODE_TAXONOMY, PROP_ID, 'constraint_taxonomy_id') + ';') - queries.append(get_create_constraint_query(NODE_SYNONYM, PROP_NAME, 'constraint_synonym_name') + ';') - queries.append(get_create_index_query(NODE_TAXONOMY, PROP_NAME, 'index_taxonomy_name') + ';') - queries.append(get_create_index_query(NODE_TAXONOMY, 'species_id', 'index_taxonomy_speciesid') + ';') + queries.append( + get_create_constraint_query( + NODE_TAXONOMY, PROP_ID, 'constraint_taxonomy_id' + ) + + ';' + ) + queries.append( + get_create_constraint_query( + NODE_SYNONYM, PROP_NAME, 'constraint_synonym_name' + ) + + ';' + ) + queries.append( + get_create_index_query(NODE_TAXONOMY, PROP_NAME, 'index_taxonomy_name') + + ';' + ) + queries.append( + get_create_index_query( + NODE_TAXONOMY, 'species_id', 'index_taxonomy_speciesid' + ) + + ';' + ) return queries def add_index_change_set(self): From ca6ba50a6d8b5778365ce04f27fdf278816e3a6c Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Thu, 4 Apr 2024 09:52:23 +0200 Subject: [PATCH 19/23] fix style issues --- docs/wiki/binderhub/config-prod.yaml | 6 +++--- docs/wiki/binderhub/config-stg.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/wiki/binderhub/config-prod.yaml b/docs/wiki/binderhub/config-prod.yaml index c62ea40f9a..104523d47a 100644 --- a/docs/wiki/binderhub/config-prod.yaml +++ b/docs/wiki/binderhub/config-prod.yaml @@ -111,18 +111,18 @@ ingress: storage: capacity: 10Gi dynamic: - pvcNameTemplate: claim-{username}{servername} + pvcNameTemplate: 'claim-{username}{servername}' storageAccessModes: - ReadWriteOnce storageClass: standard - volumeNameTemplate: volume-{username}{servername} + volumeNameTemplate: 'volume-{username}{servername}' extraLabels: {} extraVolumeMounts: [] extraVolumes: [] homeMountPath: /home/jovyan static: pvcName: null - subPath: "{username}" + subPath: '{username}' type: none uid: 1000 diff --git a/docs/wiki/binderhub/config-stg.yaml b/docs/wiki/binderhub/config-stg.yaml index 3fc8f025ec..503346afe6 100644 --- a/docs/wiki/binderhub/config-stg.yaml +++ b/docs/wiki/binderhub/config-stg.yaml @@ -111,18 +111,18 @@ ingress: storage: capacity: 10Gi dynamic: - pvcNameTemplate: claim-{username}{servername} + pvcNameTemplate: 'claim-{username}{servername}' storageAccessModes: - ReadWriteOnce storageClass: standard - volumeNameTemplate: volume-{username}{servername} + volumeNameTemplate: 'volume-{username}{servername}' extraLabels: {} extraVolumeMounts: [] extraVolumes: [] homeMountPath: /home/jovyan static: pvcName: null - subPath: "{username}" + subPath: '{username}' type: none uid: 1000 From 87d23569056391ac72022e2eaeea1dd4099eab37 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Thu, 4 Apr 2024 10:05:30 +0200 Subject: [PATCH 20/23] having duplicate fix style comments --- .github/workflows/annotate-code-style.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/annotate-code-style.yml b/.github/workflows/annotate-code-style.yml index d9f7773507..7420fd73e2 100644 --- a/.github/workflows/annotate-code-style.yml +++ b/.github/workflows/annotate-code-style.yml @@ -72,15 +72,8 @@ jobs: - name: Inform how to run autofix if: failure() && (github.event_name == 'pull_request') - uses: actions/github-script@v6 - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: "Code style issues has been found - [AUTOFIX](${{ env.AUTOFIX_URL }})" - }) + run: | + echo "Code style issues has been found - [AUTOFIX]($AUTOFIX_URL)" | tee $GITHUB_STEP_SUMMARY - name: Client linting autofix if: github.event.inputs.autoFix && github.event.inputs.tslintAutoFix From f2aa33bb14155c1c3548f50a46ac81d7db90f02b Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Thu, 4 Apr 2024 10:36:03 +0200 Subject: [PATCH 21/23] fix styling issues --- .prettierignore | 98 ++++++++++++++++++++++++++++ docs/wiki/binderhub/config-prod.yaml | 28 ++++---- docs/wiki/binderhub/config-stg.yaml | 38 +++++------ 3 files changed, 131 insertions(+), 33 deletions(-) create mode 100755 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100755 index 0000000000..5e74be90bf --- /dev/null +++ b/.prettierignore @@ -0,0 +1,98 @@ +helm/lifelike/templates +**/*.lock + +# -------------- +# Gitignore file +# -------------- + +# liinting +/**/.husky + +# Python +__pycache__/ +*.pyc +env/ +.cache/ +.python_history +.ipython/ +.mypy_cache/ + +# compiled output +dist/ +/**/*.pyc + +# System Files +.DS_Store +Thumbs.db +.bash_history +.local/ +.run + +# IDE - VSCode +.vscode/ + +# ignore db files +neo4j/data/* +neo4j/import/* +neo4j/logs/* +neo4j/plugins/* + +postgres/ +!postgres/.gitkeep + +# ignore node_modules +client/node_modules +esdata/ +node_modules/ + +# ignore copy +deployment/kg-prototypes +# terraform files +terraform.tfstate.* +.terraform/ +# The terraform Gcloud service account +terraform-gcloud.json + +# .env Files (to protect secrets) +*.env +*.env.* + +# IDE - IntelliJ +.idea/ +/*.iml +.run + +#virtual environments +.venv/ +venv/ +outputs/ + +# LMDB files +appserver/neo4japp/services/annotations/**/*.mdb +appserver/neo4japp/services/annotations/**/*.mdb.old +appserver/neo4japp/services/annotations/datasets/**/*.csv +appserver/neo4japp/services/annotations/datasets/**/*.tsv + +# profiler results +appserver/profilers/results/ + +# nlp pdfs +appserver/neo4japp/services/annotations/nlp_data_output/pdfs/*.pdf +appserver/neo4japp/services/annotations/nlp_data_output/annotations/*.json +appserver/neo4japp/services/annotations/nlp_data_output/*.txt + +# Backups +*.backup + +# gcloud service accounts +*ansible_service_account* + +# ansible secrets +.vault_secrets_pw + +# Arango volumes +arangodb/data/* +arangodb/apps/* + +# Arango seed data +arangodb/bin/seed_data diff --git a/docs/wiki/binderhub/config-prod.yaml b/docs/wiki/binderhub/config-prod.yaml index 104523d47a..c52802059f 100644 --- a/docs/wiki/binderhub/config-prod.yaml +++ b/docs/wiki/binderhub/config-prod.yaml @@ -12,11 +12,11 @@ config: ingress: annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod + cert-manager.io/cluster-issuer: letsencrypt-prod kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" enabled: true - hosts: + hosts: - binder.lifelike.bio https: enabled: true @@ -71,17 +71,17 @@ jupyterhub: oauth_redirect_uri: https://binder.lifelike.bio/oauth_callback ingress: annotations: - cert-manager.io/cluster-issuer: letsencrypt-prod + cert-manager.io/cluster-issuer: letsencrypt-prod kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" - enabled: true - hosts: - - jupyter.lifelike.bio - pathType: Prefix - tls: - - hosts: - - jupyter.lifelike.bio - secretName: jupyter-lifelike-bio-tls + enabled: true + hosts: + - jupyter.lifelike.bio + pathType: Prefix + tls: + - hosts: + - jupyter.lifelike.bio + secretName: jupyter-lifelike-bio-tls proxy: https: enabled: true @@ -111,18 +111,18 @@ ingress: storage: capacity: 10Gi dynamic: - pvcNameTemplate: 'claim-{username}{servername}' + pvcNameTemplate: "claim-{username}{servername}" storageAccessModes: - ReadWriteOnce storageClass: standard - volumeNameTemplate: 'volume-{username}{servername}' + volumeNameTemplate: "volume-{username}{servername}" extraLabels: {} extraVolumeMounts: [] extraVolumes: [] homeMountPath: /home/jovyan static: pvcName: null - subPath: '{username}' + subPath: "{username}" type: none uid: 1000 diff --git a/docs/wiki/binderhub/config-stg.yaml b/docs/wiki/binderhub/config-stg.yaml index 503346afe6..8ede42a160 100644 --- a/docs/wiki/binderhub/config-stg.yaml +++ b/docs/wiki/binderhub/config-stg.yaml @@ -12,7 +12,7 @@ config: ingress: annotations: - cert-manager.io/cluster-issuer: letsencrypt-stg + cert-manager.io/cluster-issuer: letsencrypt-stg kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" enabled: true @@ -22,7 +22,7 @@ config: enabled: true type: letsencrypt pathType: Prefix - tls: + tls: - hosts: - binder.lifelike.bio secretName: binder-lifelike-bio-tls @@ -70,22 +70,22 @@ jupyterhub: oauth_no_confirm: true oauth_redirect_uri: https://binder.lifelike.bio/oauth_callback ingress: - annotations: - cert-manager.io/cluster-issuer: letsencrypt-stg - kubernetes.io/ingress.class: nginx - kubernetes.io/tls-acme: "true" + annotations: + cert-manager.io/cluster-issuer: letsencrypt-stg + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" enabled: true - hosts: - - jupyter.lifelike.bio - pathType: Prefix - tls: - - hosts: - - jupyter.lifelike.bio - secretName: jupyter-lifelike-bio-tls + hosts: + - jupyter.lifelike.bio + pathType: Prefix + tls: + - hosts: + - jupyter.lifelike.bio + secretName: jupyter-lifelike-bio-tls proxy: - https: - enabled: true - type: letsencrypt + https: + enabled: true + type: letsencrypt rbac: enabled: true scheduling: @@ -111,18 +111,18 @@ ingress: storage: capacity: 10Gi dynamic: - pvcNameTemplate: 'claim-{username}{servername}' + pvcNameTemplate: "claim-{username}{servername}" storageAccessModes: - ReadWriteOnce storageClass: standard - volumeNameTemplate: 'volume-{username}{servername}' + volumeNameTemplate: "volume-{username}{servername}" extraLabels: {} extraVolumeMounts: [] extraVolumes: [] homeMountPath: /home/jovyan static: pvcName: null - subPath: '{username}' + subPath: "{username}" type: none uid: 1000 From 48d3b9a6642a783919dfcec3a190846d89e68105 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Thu, 4 Apr 2024 10:38:29 +0200 Subject: [PATCH 22/23] fix styling issues --- docs/wiki/keycloak-deployment/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wiki/keycloak-deployment/config.yml b/docs/wiki/keycloak-deployment/config.yml index ddf4811786..38470194ca 100644 --- a/docs/wiki/keycloak-deployment/config.yml +++ b/docs/wiki/keycloak-deployment/config.yml @@ -1,7 +1,7 @@ affinity: {} args: [] auth: - adminPassword: ***REMOVED*** + adminPassword: '***REMOVED***' adminUser: admin existingSecret: "" passwordSecretKey: "" From 2247923946a2d33e1a6682828ecd3855eb726dfe Mon Sep 17 00:00:00 2001 From: Lint Action Date: Thu, 4 Apr 2024 08:41:45 +0000 Subject: [PATCH 23/23] Fix code style issues with Prettier --- docs/wiki/keycloak-deployment/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/wiki/keycloak-deployment/config.yml b/docs/wiki/keycloak-deployment/config.yml index 38470194ca..c35296e5c6 100644 --- a/docs/wiki/keycloak-deployment/config.yml +++ b/docs/wiki/keycloak-deployment/config.yml @@ -1,7 +1,7 @@ affinity: {} args: [] auth: - adminPassword: '***REMOVED***' + adminPassword: "***REMOVED***" adminUser: admin existingSecret: "" passwordSecretKey: ""

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 literal 0 HcmV?d00001 diff --git a/docs/wiki/README.md b/docs/wiki/README.md new file mode 100644 index 0000000000..70fb17a96c --- /dev/null +++ b/docs/wiki/README.md @@ -0,0 +1,159 @@ +# Architecture overview + +![Architecture overview diagram](Architecture overview.drawio.png) +NOTE: The diagram is created with [draw.io](https://draw.io), this is editable version (copy of diagram has been embedded into the file). + +# Service functional groups + +## Authentication + +Authentication related code is deposited in Front-end and appserver. Additionally, in publish enviroment keycloak is used as OAuth2 provider. + +## Annotation + +Annotation steps rely on Front-end, appserver, pdfparser, redis, postgress and graph database. +Only two types of files are annotateble: PDF and enrichment table. + +In principle annotation pipeline works as follows for PDF files: + +1. Front-end sends request to appserver to annotate file. +2. Appserver sends request to pdfparser to extract words and their locations. +3. Load core annotation terms into LMDB +4. Load annotation inclusions from graph database +5. Load annotation exclusions from postgress +6. Search for match between words and annotation terms +7. Matches are structured into json annotation structure +8. JSON annotation structure save to postgress is scheduled to redis queque + 1. Worker process reads annotation structure from redis queque and saves it to postgress +9. Appserver returns response (to request from pt. 1) with annotation structure +10. Front-end renders annotations + +In case of enrichment table, the process is similar: + +1. Front-end sends request to appserver to annotate enrichment table. +2. Enrichment table is stringified to text +3. Appserver sends request to pdfparser to extract words from text and their locations. +4. Load core annotation terms into LMDB +5. Load annotation inclusions from graph database +6. Load annotation exclusions from postgress +7. Search for match between words and annotation terms +8. Matches are structured into json annotation structure +9. JSON annotation structure save to postgress is scheduled to redis queque + 1. Worker process reads annotation structure from redis queque and saves it to postgress +10. annotation structure is translated into json table structure containing xml snippets for annotations +11. Appserver returns response (to request from pt. 1) with json table structure containing xml snippets for annotations +12. Front-end overwrites enrichment table with xml snippets for annotations +13. Front-end renders annotations +14. Front-end sends request to appserver to save enrichment table +15. Appserver schedules saving enrichment table to postgress + 15.1. Worker process reads enrichment table from redis queque and saves it to postgress + +## Search/Indexing + +Search and indexing steps rely on Front-end, appserver, postgress and elasticsearch. + +In appserver code upon each modification to file: + +1. Redis queque task is scheduled to reindex file + 1. Worker process reads file content from redis queque + 2. File content is parsed into text + 3. Text is send to elasticsearch for indexing + +In case of search request is simply send to elasticsearch and results are returned to front-end. + +## Enrichment (table) + +Enrichment table relies on Front-end, appserver, postgress and graph database. + +1. Front-end sends request to appserver to enrich gene list. +2. Appserver sends request to graph database to get related gene information. +3. Appserver returns response (to request from pt. 1) with gene information. +4. Front-end composes request from step 1 and gene information into enrichment file. +5. Front-end sends request to appserver to save enrichment file. +6. Front-end send annotation request. + +## Statistical enrichment + +Statistical enrichment relies on Front-end, appserver, redis, graph database and statistical enrichment container. + +1. Front-end sends request to appserver to perform statistical enrichment. +2. Appserver forwards request to statistical enrichment container to perform statistical enrichment. +3. Statistical enrichment checks if any part of input data or whole request is in redis cache. +4. In case of cache hit, statistical enrichment returns results from cache. + Alternatively, we query missing input data from graph database and perform statistical enrichment (caching both intermidiate steps and final results). +5. Statistical enrichment returns results to appserver. +6. Appserver returns results to front-end. +7. Front-end renders results. + +# Services in detail + +## Front-end + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/client) +[Source code welcome page](https://github.com/SBRG/lifelike-website) + +Frontend (Typescript, Angular, Bootstrap) + +## Appserver + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/appserver) +Only endpoint for frontend / core logic + +runs postgres migrations on start + +Converts text entities to annotations + +Parse file contents for elastic search + updates elasticsearch indexes + +## PDF parser + +[Source code](https://github.com/SBRG/pdfparse) +[Source code pdfbox2](https://github.com/SBRG/pdfbox2) + +Extract text blocks from pdf/text + +## Elasticsearch + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/elasticsearch) + +## Graph database + +[Source code neo4j](https://github.com/SBRG/kg-prototypes/tree/master/neo4j) +[Source code arango](https://github.com/SBRG/kg-prototypes/tree/master/arango) + +Graphdatabase for knowledge and annotation exclusions (inclusions are in Postgres) + +## Keycloak + +[Source code](https://github.com/SBRG/lifelike-keycloak) + +## Cache-invalidator + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/cache-invalidator) +Cron like service recalculating common and expensive cache values in timely manner. + +## Redis + +Used for cache, task queue. + +## Postgress + +Main db containing users, files, annotations etc. + +## Elasticsearch + +Hold logs, metrics, indexed file contents + +## Logstash + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/logstash) + +## Metricbeat + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/metricbeat) +save docker metrics to elastic + +## Filebeat + +[Source code](https://github.com/SBRG/kg-prototypes/tree/master/filebeat) +save docker logs to elastic diff --git a/docs/wiki/binderhub/cluster-issuer-prod.yaml b/docs/wiki/binderhub/cluster-issuer-prod.yaml index ee2a1306ac..a902e81e9e 100644 --- a/docs/wiki/binderhub/cluster-issuer-prod.yaml +++ b/docs/wiki/binderhub/cluster-issuer-prod.yaml @@ -7,7 +7,7 @@ spec: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration - email: e4sanchez@eng.ucsd.edu + email: # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod diff --git a/docs/wiki/binderhub/cluster-issuer-stg.yaml b/docs/wiki/binderhub/cluster-issuer-stg.yaml index b17ef68316..9f7fbac7c1 100644 --- a/docs/wiki/binderhub/cluster-issuer-stg.yaml +++ b/docs/wiki/binderhub/cluster-issuer-stg.yaml @@ -7,7 +7,7 @@ spec: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration - email: e4sanchez@eng.ucsd.edu + email: # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging diff --git a/docs/wiki/binderhub/config-prod.yaml b/docs/wiki/binderhub/config-prod.yaml index 600efb7c29..c62ea40f9a 100644 --- a/docs/wiki/binderhub/config-prod.yaml +++ b/docs/wiki/binderhub/config-prod.yaml @@ -1,90 +1,136 @@ config: BinderHub: auth_enabled: true - hub_url: https://jupyter-demo.lifelike.bio + cors_allow_origin: "*" + hub_url: https://jupyter.lifelike.bio + image_prefix: lifelikebinderhub.azurecr.io/binderhub/notebooks- use_registry: true - image_prefix: gcr.io/able-goods-221820/binderhub-demo GitHubRepoProvider: access_token: # Get this value from our existing Binderhub release (you can find it in the helm chart) banned_specs: - ^(?!SBRG/|\.).* -service: - type: ClusterIP - -jupyterhub: - proxy: - service: - type: ClusterIP - https: - enabled: true - type: letsencrypt ingress: - enabled: true - hosts: - - jupyter-demo.lifelike.bio annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" - cert-manager.io/cluster-issuer: letsencrypt-prod - tls: - - secretName: jupyter-demo-lifelike-bio-tls + enabled: true hosts: - - jupyter-demo.lifelike.bio + - binder.lifelike.bio + https: + enabled: true + type: letsencrypt + pathType: Prefix + tls: + - hosts: + - binder.lifelike.bio + secretName: binder-lifelike-bio-tls + +imageCleaner: + # Turning this off as it does not seem to work on AKS with this version of DinD + enabled: false + +jupyterhub: cull: - # Since we're using authenticated users, don't cull them. We would set this to true if we were using temp users. + concurrency: 10 + enabled: true + every: 600 + maxAge: 86400 + removeNamedServers: false + timeout: 1200 users: false - timeout: 1800 - removeNamedServers: true hub: allowNamedServers: true - namedServerLimitPerUser: 5 - shutdownOnLogout: true - redirectToServer: false config: BinderSpawner: auth_enabled: true - JupyterHub: - authenticator_class: google - Authenticator: - allowed_users: - - e4sanchez@@eng.ucsd.edu # Ethan - # You can add more users here + cors_allow_origin: "*" GoogleOAuthenticator: + admin_users: + - e4sanchez@ucsd.edu + allow_existing_users: true client_id: # Get this value from the Google Cloud Console client_secret: # Get this value from the Google Cloud Console - oauth_callback_url: https://jupyter-demo.lifelike.bio/hub/oauth_callback + hosted_domain: + - ucsd.edu + - biosustain.dtu.dk login_service: Google + oauth_callback_url: https://jupyter.lifelike.bio/hub/oauth_callback + JupyterHub: + admin_access: true + authenticator_class: google + consecutiveFailureLimit: 5 + namedServerLimitPerUser: 5 services: binder: + admin: true + apiToken: null oauth_client_id: service-binderhub oauth_no_confirm: true - oauth_redirect_uri: "https://binder-demo.lifelike.bio/oauth_callback" - loadRoles: - user: - scopes: - - self - - "access:services" - singleuser: - # to make notebook servers aware of hub - cmd: jupyterhub-singleuser - + oauth_redirect_uri: https://binder.lifelike.bio/oauth_callback ingress: - enabled: true - https: - enabled: true - type: letsencrypt - hosts: - - binder-demo.lifelike.bio annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" - cert-manager.io/cluster-issuer: letsencrypt-prod - tls: - - secretName: binder-demo-lifelike-bio-tls + enabled: true hosts: - - binder-demo.lifelike.bio + - jupyter.lifelike.bio + pathType: Prefix + tls: + - hosts: + - jupyter.lifelike.bio + secretName: jupyter-lifelike-bio-tls + proxy: + https: + enabled: true + type: letsencrypt + rbac: + enabled: true + scheduling: + userScheduler: + # Turning this off per: https://discourse.jupyter.org/t/singleuser-pods-stuck-in-pending/6349/11 + enabled: false + singleuser: + cmd: jupyterhub-singleuser + cpu: + guarantee: 0.1 + limit: 1 + defaultUrl: /lab + extraEnv: + # Set any required environment variables here, for example: + ARANGO_PASSWORD: you-real-password + image: + # Very important this is present, the singleuser pods need credentials to pull the Jupyterhub image + pullSecrets: [bindercred] + memory: + guarantee: 256M + limit: 40G + startTimeout: 300 + storage: + capacity: 10Gi + dynamic: + pvcNameTemplate: claim-{username}{servername} + storageAccessModes: + - ReadWriteOnce + storageClass: standard + volumeNameTemplate: volume-{username}{servername} + extraLabels: {} + extraVolumeMounts: [] + extraVolumes: [] + homeMountPath: /home/jovyan + static: + pvcName: null + subPath: "{username}" + type: none + uid: 1000 + +# Docker is not a supported runtime on AKS, so we must use DinD +dind: + enabled: true registry: - password: # You can find this defined in the existing deployment - url: https://gcr.io + url: # Get this from the desired Azure Container Registry + username: # Get this from the desired Azure Container Registry + password: # Get this from the desired Azure Container Registry diff --git a/docs/wiki/binderhub/config-stg.yaml b/docs/wiki/binderhub/config-stg.yaml index ade6611806..3fc8f025ec 100644 --- a/docs/wiki/binderhub/config-stg.yaml +++ b/docs/wiki/binderhub/config-stg.yaml @@ -1,90 +1,136 @@ config: BinderHub: auth_enabled: true - hub_url: https://jupyter-demo.lifelike.bio + cors_allow_origin: "*" + hub_url: https://jupyter.lifelike.bio + image_prefix: lifelikebinderhub.azurecr.io/binderhub/notebooks- use_registry: true - image_prefix: gcr.io/able-goods-221820/binderhub-demo GitHubRepoProvider: access_token: # Get this value from our existing Binderhub release (you can find it in the helm chart) banned_specs: - ^(?!SBRG/|\.).* -service: - type: ClusterIP - -jupyterhub: - proxy: - service: - type: ClusterIP - https: - enabled: true - type: letsencrypt ingress: - enabled: true - hosts: - - jupyter-demo.lifelike.bio annotations: + cert-manager.io/cluster-issuer: letsencrypt-stg kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" - cert-manager.io/cluster-issuer: letsencrypt-staging + enabled: true + hosts: + - binder.lifelike.bio + https: + enabled: true + type: letsencrypt + pathType: Prefix tls: - - secretName: jupyter-demo-lifelike-bio-tls - hosts: - - jupyter-demo.lifelike.bio + - hosts: + - binder.lifelike.bio + secretName: binder-lifelike-bio-tls + +imageCleaner: + # Turning this off as it does not seem to work on AKS with this version of DinD + enabled: false + +jupyterhub: cull: - # Since we're using authenticated users, don't cull them. We would set this to true if we were using temp users. + concurrency: 10 + enabled: true + every: 600 + maxAge: 86400 + removeNamedServers: false + timeout: 1200 users: false - timeout: 1800 - removeNamedServers: true hub: allowNamedServers: true - namedServerLimitPerUser: 5 - shutdownOnLogout: true - redirectToServer: false config: BinderSpawner: auth_enabled: true - JupyterHub: - authenticator_class: google - Authenticator: - allowed_users: - - e4sanchez@@eng.ucsd.edu # Ethan - # You can add more users here + cors_allow_origin: "*" GoogleOAuthenticator: + admin_users: + - e4sanchez@ucsd.edu + allow_existing_users: true client_id: # Get this value from the Google Cloud Console client_secret: # Get this value from the Google Cloud Console - oauth_callback_url: https://jupyter-demo.lifelike.bio/hub/oauth_callback + hosted_domain: + - ucsd.edu + - biosustain.dtu.dk login_service: Google + oauth_callback_url: https://jupyter.lifelike.bio/hub/oauth_callback + JupyterHub: + admin_access: true + authenticator_class: google + consecutiveFailureLimit: 5 + namedServerLimitPerUser: 5 services: binder: + admin: true + apiToken: null oauth_client_id: service-binderhub oauth_no_confirm: true - oauth_redirect_uri: "https://binder-demo.lifelike.bio/oauth_callback" - loadRoles: - user: - scopes: - - self - - "access:services" - singleuser: - # to make notebook servers aware of hub - cmd: jupyterhub-singleuser - + oauth_redirect_uri: https://binder.lifelike.bio/oauth_callback ingress: + annotations: + cert-manager.io/cluster-issuer: letsencrypt-stg + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" enabled: true + hosts: + - jupyter.lifelike.bio + pathType: Prefix + tls: + - hosts: + - jupyter.lifelike.bio + secretName: jupyter-lifelike-bio-tls + proxy: https: enabled: true type: letsencrypt - hosts: - - binder-demo.lifelike.bio - annotations: - kubernetes.io/ingress.class: nginx - kubernetes.io/tls-acme: "true" - cert-manager.io/cluster-issuer: letsencrypt-staging - tls: - - secretName: binder-demo-lifelike-bio-tls - hosts: - - binder-demo.lifelike.bio + rbac: + enabled: true + scheduling: + userScheduler: + # Turning this off per: https://discourse.jupyter.org/t/singleuser-pods-stuck-in-pending/6349/11 + enabled: false + singleuser: + cmd: jupyterhub-singleuser + cpu: + guarantee: 0.1 + limit: 1 + defaultUrl: /lab + extraEnv: + # Set any required environment variables here, for example: + ARANGO_PASSWORD: you-real-password + image: + # Very important this is present, the singleuser pods need credentials to pull the Jupyterhub image + pullSecrets: [bindercred] + memory: + guarantee: 256M + limit: 40G + startTimeout: 300 + storage: + capacity: 10Gi + dynamic: + pvcNameTemplate: claim-{username}{servername} + storageAccessModes: + - ReadWriteOnce + storageClass: standard + volumeNameTemplate: volume-{username}{servername} + extraLabels: {} + extraVolumeMounts: [] + extraVolumes: [] + homeMountPath: /home/jovyan + static: + pvcName: null + subPath: "{username}" + type: none + uid: 1000 + +# Docker is not a supported runtime on AKS, so we must use DinD +dind: + enabled: true registry: - password: # You can find this defined in the existing deployment - url: https://gcr.io + url: # Get this from the desired Azure Container Registry + username: # Get this from the desired Azure Container Registry + password: # Get this from the desired Azure Container Registry diff --git a/docs/wiki/binderhub/ingress-nginx.yaml b/docs/wiki/binderhub/ingress-nginx.yaml index c5fcd5d3b2..367c4d88c5 100644 --- a/docs/wiki/binderhub/ingress-nginx.yaml +++ b/docs/wiki/binderhub/ingress-nginx.yaml @@ -2,6 +2,13 @@ ## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml controller: + # Set any nginx configurations here + config: { "proxy-body-size": "15m", "proxy-read-timeout": "15m", "proxy-send-timeout": "15m" } + service: + annotations: + # It is critical that this annotation is present, otherwise the ingress pods may fail to start! + service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/healthz" + # -- Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer - loadBalancerIP: + loadBalancerIP: diff --git a/docs/wiki/binderhub/setup-binderhub.md b/docs/wiki/binderhub/setup-binderhub.md index 36fa9e178c..98ccc6735c 100644 --- a/docs/wiki/binderhub/setup-binderhub.md +++ b/docs/wiki/binderhub/setup-binderhub.md @@ -12,28 +12,32 @@ - [Install cert-manager](#install-cert-manager) - [Create a Temporary Certificate Issuer](#create-a-temporary-certificate-issuer) - [Add and Install Ingress NGINX](#add-and-install-ingress-nginx) - - [Optional: Add a Config Map for the NGINX Proxy](#optional-add-a-config-map-for-the-nginx-proxy) +- [Create Container Registry Login Secret](#create-container-registry-login-secret) - [Install Binderhub](#install-binderhub) - [Verify SSL Certs are Created](#verify-ssl-certs-are-created) - [Additional Configurations](#additional-configurations) ## Introduction -This guide will walk you through the process of creating a brand-new Binderhub cluster on Google Cloud. The example configuration files can also be used for other cloud services. +This guide will walk you through the process of creating a brand new Binderhub cluster on Microsoft Azure. -If you do not have a Google Cloud account or project, you can create one by following the instructions [here](https://cloud.google.com/resource-manager/docs/creating-managing-projects). +If you do not have a Azure account or project, you can create one [here](https://azure.microsoft.com/en-us/free). -The guide also primarily uses the Google Cloud Console Terminal, so you do not need to worry about navigating around the GUI to the various resources we create. +This guide primarily uses the web browser Azure Portal to create and manage resources, but you may also use the Azure CLI instead. -If you want to install the Google Cloud CLI on your machine, consult this [guide](https://cloud.google.com/sdk/docs/install). +If you want to install the Azure CLI on your machine, consult this [guide](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli). + +You will also need to install the Kubernetes CLI in order to create some resources on the cluster. You can find instructions on how to install the CLI [here](https://kubernetes.io/docs/tasks/tools/) Finally, we will be using [Helm](https://helm.sh/) to create several Kubernetes resources. Please install Helm locally if you wish to follow this guide on a local terminal. +You may also consider installing [Lens](https://k8slens.dev/), an IDE specifically for connecting to Kubernetes clusters and viewing/managing their resources. This is not required to follow this guide, but it can be an invaluable tool for debugging any issues that may arise. + ## Caveats These intructions assume you will be using the configuration files provided alongside the guide. This will enable a few additional features not included in a vanilla BinderHub deployment. -Most notably, user authentication will be turned on, with Google as the OAuth provider. If you do not require any authentication (highly discouraged), you can use the config-with-no-auth.yaml file instead of the recommended config-stg.yaml and config-prod.yaml. +Most notably, user authentication will be turned on, with Google as the OAuth provider. Also, do note the `GithubRepoProvider` property under the top-level `config` mapping. This is currently configured to ONLY ALLOW Github repositories from within the SBRG organization to be used with the BinderHub deployment. @@ -41,24 +45,17 @@ Finally, recognize that some of the values in the BinderHub configuration may ne ## Create the Cluster -First, create the cluster we will install Binderhub on to: +First, we need to create the cluster we will install Binderhub on to. Please follow the guide [here](https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-portal?tabs=azure-cli) for general instructions on how to do so. -```bash -gcloud container clusters create \ - --machine-type n1-standard-2 \ - --num-nodes 2 \ - --zone us-central1 \ - --cluster-version latest \ - -``` +**_However_**, please use the following settings for your cluster, instead of the defaults: -Next, set the admin role binding for your Google Cloud account. This will ensure you're able to make changes to the cluster we've just created: - -```bash -kubectl create clusterrolebinding cluster-admin-binding \ - --clusterrole=cluster-admin \ - --user= -``` +- **Kubernetes version**: 1.26.10 + - This is a confirmed working version of AKS with the version of Binderhub we will be using. +- **Authentication and Authorization**: Local accounts with Kubernetes RBAC +- **Network Policy**: None + - Any other setting may cause issues with the Nginx load balancer. Use another setting at your own risk! +- **Network type (plugin)**: Kubenet + - This will likely be the default, but ensure that it is set to the correct value. Other values have not been validated with the existing Binderhub configuration! ### Create a Namespace for the Binderhub Resources @@ -76,17 +73,15 @@ Before we install Binderhub, we will first install a load balancer to handle req ### Reserve a Static IP Address -The load balancer will need a static IP so we can be certain the address won't change. You can reserve a static IP on Google Cloud with the following command: +The load balancer will need a static IP so we can be certain the address won't change. You can reserve a static IP on Azure by following [these](https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/create-public-ip-portal?tabs=option-1-create-public-ip-standard) instructions. -```bash -gcloud compute addresses create --region us-central1 -``` - -You can name the IP address whatever you want, but use something descriptive like "lifelike-binderhub-proxy". If you'd like a more in-depth explanation of how to reserve a static IP, please follow the [official guide](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address). +You can name the IP address whatever you want, but use something descriptive like "lifelike-binderhub-proxy". ### Configure DNS with the Static IP -Registering a domain name is beyond the scope of this guide, but you will need a domain to use for an authenticated Binderhub server. If you are using Google Cloud, DNS zones can be configured under: Networking > Network Services > Cloud DNS. +Registering a domain name is beyond the scope of this guide, but you will need a domain to use for an authenticated Binderhub server. + +Note that for the Lifelike project we are currently using Google Cloud for our DNS nameservers. DNS zones in Google Cloud can be configured under: Networking > Network Services > Cloud DNS. If you are using a different cloud provider, DNS management will likely be found under a networking resource. Very minimally, you will need to create two new zone standards (most likely A records) for both the BinderHub server and the Jupyterhub server. For example, for the Lifelike project we have the "lifelike.bio" DNS zone, with A records for "binder.lifelike.bio" and "jupyter.lifelike.bio" pointing at the IP address "35.188.33.138". This means that the domains "binder.lifelike.bio" and "jupyter.lifelike.bio" refers to the IP address "35.188.33.138", which itself identifies the load balancer server. @@ -136,7 +131,7 @@ helm install ingress-nginx/ingress-nginx --namesp This will take a few moments. Note that you can name your ingress-nginx installation anything you want, but consider a descriptive name like "binderhub-ingress-nginx". Also, be sure to apply a custom configuration with the `-f` flag as in the example above. Minimally, your config file should include a definition for the load balancer IP. -See the "ingress-nginx.yaml" example file included in the same directory as this guide. +See the "ingress-nginx.yaml" example file included in the same directory as this guide. Please pay careful attention to the comments in this file! Omission of any properties within the config may lead to undesired behavior from the ingress. To check on the status of the ingress-nginx controller, you can run the following command: @@ -148,24 +143,26 @@ You should see something like the following: ```bash NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE -binderhub-ingress-nginx-controller LoadBalancer 10.4.7.240 35.188.33.138 80:32402/TCP,443:32177/TCP 9d +binderhub-ingress-nginx-controller LoadBalancer 10.4.7.240 80:32402/TCP,443:32177/TCP 9d ``` If the `EXTERNAL-IP` column is empty, give the load balancer a few more moments to initialize. If it remains empty, you may have forgotten to specify a load balancer IP, or the IP may be unavailable. It should be the IP adress we reserved earlier. -### Optional: Add a Config Map for the NGINX Proxy +## Create Container Registry Login Secret + +There is one more step before we install Binderhub. We have to create a Kubernetes secret resource for our cluster pods to pull/push container images from our container registry. Note that this is not normally required for Binderhub deployments, but seems to be a side effect of running Binderhub using Docker-in-Docker, which is required on Azure Kubernetes. -It's likely that you will want to specify some non-default configurations for the nginx proxy. To do this, you simply need to add a [configmap](https://kubernetes.io/docs/concepts/configuration/configmap/) resource: +To create the secret, run the following command: ```bash -kubectl apply -f your-nginx-configmap.yaml +kubectl create secret docker-registry --docker-server= --docker-username= --docker-password= -n binderhub ``` -An example has been included in the same directory as this guide. +Note the credentials we provide to the command. These can be found in the configuration for your container registry. Also note that in our example config files for Binderhub `secret-name` is expected to be "bindercred". ## Install Binderhub -Now that we have installed the NGINX controller, we can install the binderhub helm chart. First, let's make sure we have access to it. Add the helm repo if you don't have it already: +Now that we have installed the NGINX controller and created a secret credenential for our container registry, we can install the binderhub helm chart. First, let's make sure we have access to it. Add the helm repo if you don't have it already: ```bash helm repo add jupyterhub https://jupyterhub.github.io/helm-chart @@ -180,12 +177,14 @@ helm repo update Finally, let's install Binderhub. Note that we specify a few special flags in the install command: `--version` and `-f`. ```bash -helm install jupyterhub/binderhub --version=1.0.0-0.dev.git.3128.h52ffd88 --namespace=binderhub -f config-stg.yaml +helm install jupyterhub/binderhub --version=0.2.0-n886.h4169712 --namespace=binderhub -f config-stg.yaml ``` It may take a few moments for this command to complete. -You can find a list of Binderhub releases [here](https://hub.jupyter.org/helm-chart/#development-releases-binderhub). Simply copy the version you want to install, e.g. "1.0.0-0.dev.git.3128.h52ffd88", which is the version we use in the example command. +You can find a list of Binderhub releases [here](https://hub.jupyter.org/helm-chart/#development-releases-binderhub). Simply copy the version you want to install, e.g. "0.2.0-n886.h4169712", which is the version we use in the example command. + +It is **crucial** that you use this version of Binderhub! Any other version is untested and may not work with the current configuration files! `-f` lets us specify configuration values via a yaml file. In the example, we use a file named "config-stg.yaml". See the example file of the same name in the same folder as this guide. @@ -214,7 +213,7 @@ Notice the file "cluster-issuer-prod.yaml". See the file of the same name in the Then, upgrade our BinderHub deployment to use this new cluster issuer: ```bash -helm upgrade lifelike-binderhub jupyterhub/binderhub --version=1.0.0-0.dev.git.3128.h52ffd88 --namespace=lifelike-binderhub -f config-prod.yaml +helm upgrade lifelike-binderhub jupyterhub/binderhub --version=0.2.0-n886.h4169712 --namespace=lifelike-binderhub -f config-prod.yaml ``` Congratulations! Your BinderHub deployment is complete! Verify the production certificates are indeed working by returning to your BinderHub in a web browser. Also, try creating a notebook with your favorite Github repository. If you are eventually redirected to the JupyterHub page, you've successfully deployed BinderHub! diff --git a/filebeat/Dockerfile b/filebeat/Dockerfile index 620fa44ab1..57f0b14800 100644 --- a/filebeat/Dockerfile +++ b/filebeat/Dockerfile @@ -1,8 +1,7 @@ FROM docker.elastic.co/beats/filebeat:7.11.1 LABEL app=kg-prototypes -ARG CONFIG_FILE=filebeat.yml -COPY config/${CONFIG_FILE} /usr/share/filebeat/filebeat.yml +COPY config/filebeat.yml /usr/share/filebeat/filebeat.yml USER root RUN chown root:filebeat /usr/share/filebeat/filebeat.yml USER filebeat diff --git a/filebeat/config/filebeat.yml b/filebeat/config/filebeat.yml index 8ed9b8330d..6f79273a13 100644 --- a/filebeat/config/filebeat.yml +++ b/filebeat/config/filebeat.yml @@ -4,7 +4,7 @@ filebeat.autodiscover: templates: - condition: contains: - docker.container.image: kg-webserver + docker.container.image: ${WEBSERVER_IMAGE:kg-webserver} config: - type: docker containers.ids: @@ -23,7 +23,7 @@ filebeat.autodiscover: templates: - condition: contains: - docker.container.image: kg-appserver + docker.container.image: ${APPSERVER_IMAGE:kg-appserver} config: - type: container paths: @@ -37,4 +37,5 @@ processors: host: "unix:///var/run/docker.sock" output.logstash: - hosts: ["logstash:5044"] + hosts: + - ${LOGSTASH_OUTPUT_HOST:logstash:5044} diff --git a/graph-db/.gitignore b/graph-db/.gitignore index 11b80917c1..6d500b20d9 100644 --- a/graph-db/.gitignore +++ b/graph-db/.gitignore @@ -1,2 +1,142 @@ docker-compose.override.yml tmp/ +.DS_Store + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# PyCharm +.idea/ + +.vscode/settings.json +.vscode/launch.json + +# shaded POM file +dependency-reduced-pom.xml diff --git a/graph-db/README.md b/graph-db/README.md index e69de29bb2..46cc693008 100644 --- a/graph-db/README.md +++ b/graph-db/README.md @@ -0,0 +1,5 @@ +## graph-db + +`extraction`: Python code that extracts data from various sources; e.g KEGG, BioCyc, etc + +`migration`: Liquibase migration for the graph-db diff --git a/logstash/.dockerignore b/logstash/.dockerignore new file mode 100644 index 0000000000..1d1fe94df4 --- /dev/null +++ b/logstash/.dockerignore @@ -0,0 +1 @@ +Dockerfile \ No newline at end of file diff --git a/statistical-enrichment/Dockerfile b/statistical-enrichment/Dockerfile index a9e34baaf2..6503159e4f 100644 --- a/statistical-enrichment/Dockerfile +++ b/statistical-enrichment/Dockerfile @@ -1,80 +1,34 @@ -# ======================================== -# Base image -# ======================================== -FROM python:3.10-slim as base +FROM python:3.8-buster +LABEL app=kg-prototypes -ENV LANG C.UTF-8 -ENV LC_ALL C.UTF-8 -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONFAULTHANDLER 1 - -RUN pip install pipenv - - -# ======================================== -# Build dependencies stage -# ======================================== -FROM base as build-deps - -# Copy Pipfiles -COPY Pipfile Pipfile.lock ./ - -# Install Python dependencies -ARG DEV -RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) +ENV _USER user +ENV _HOME /home/$_USER +ENV UID 1000 +ENV GID 1000 +# Root acces only if in root group +RUN echo "auth required pam_wheel.so" >> /etc/pam.d/su -# ======================================== -# Runtime stage -# ======================================== -FROM base -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - -# Install curl for self healthchecks -RUN apt-get update && apt-get install -y curl && apt-get clean - -# Copy Python virtual environment -COPY --from=build-deps /.venv /.venv -ENV PATH="/.venv/bin:$PATH" - -# Set user and working directory -WORKDIR /app -RUN useradd -m -d /app app -USER app - -# Copy application code -COPY --chown=app . . +# Install dependencies +RUN pip install pipenv -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_SCHEME=bolt +# 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 -# Redis cache configuration -ENV REDIS_HOST=redis -ENV REDIS_PORT=6379 -ENV REDIS_PASSWORD=password -ENV REDIS_DB=0 +WORKDIR $_HOME -# Default TTL for cache -ENV CACHE_TTL=86400 +# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache +COPY --chown=$UID:$GID Pipfile . +COPY --chown=$UID:$GID Pipfile.lock . -# Optional Elastic APM configuration. -# To enable, at least ELASTIC_APM_SERVER_URL must be set -# Other available variables: https://www.elastic.co/guide/en/apm/agent/python/master/configuration.html -ENV ELASTIC_APM_SERVER_URL= -ENV ELASTIC_APM_SERVICE_NAME=statistical-enrichment +RUN pipenv install --dev --deploy --system -# Flask env [development, testing, production] -ENV FLASK_ENV=production +ENV FLASK_APP=statistical_enrichment -# Listen port -ENV PORT=5000 -EXPOSE $PORT +COPY --chown=$UID:$GID . . -# Healtcheck -HEALTHCHECK --start-period=15s \ - CMD curl -f localhost:$PORT/healthz || exit 1 +USER $_USER -CMD bin/startup.sh +CMD [ "bin/startup.sh" ] From 175f13502cd15014bf9f299c3f443c4d1a27a762 Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 14:35:43 +0200 Subject: [PATCH 02/23] try using opensource dockerfiles --- appserver/Dockerfile | 151 ++++++++++++++++++++++++------ cache-invalidator/Dockerfile | 75 ++++++++++----- client/Dockerfile | 86 ++++++----------- statistical-enrichment/Dockerfile | 92 +++++++++++++----- 4 files changed, 271 insertions(+), 133 deletions(-) diff --git a/appserver/Dockerfile b/appserver/Dockerfile index d2e572feb9..66b2431483 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -1,44 +1,133 @@ -FROM fedora:33 as base -LABEL app=kg-prototypes +# ======================================== +# Base image +# ======================================== +FROM python:3.10-slim as base + +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONFAULTHANDLER 1 -# Install dependencies -RUN dnf install htop postgresql graphviz python-pip python3-devel vim net-tools which -y \ - && dnf groupinstall 'Development Tools' -y \ - && dnf clean packages RUN pip install pipenv -ENV N4J_USER n4j -ENV N4J_HOME /home/$N4J_USER -ENV UID 1000 -ENV GID 1000 -# User and group creation -RUN groupadd -g $GID $N4J_USER && \ - useradd -u $UID -g $GID -G wheel --create-home --home-dir $N4J_HOME --shell /bin/bash $N4J_USER +# ======================================== +# Build dependencies stage +# ======================================== +FROM base as build-deps + +# Install build dependencies +RUN apt-get update \ + && apt-get install -y liblmdb-dev python3-dev libxml2-dev libxslt-dev build-essential \ + && apt-get clean + +# Copy Pipfiles +COPY Pipfile Pipfile.lock ./ + +# Install Python dependencies +ARG DEV +RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) + + +# ======================================== +# Runtime stage +# ======================================== +FROM base +LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike + +# Install runtime system dependencies +RUN apt-get update \ + && apt-get install -y libmagic-dev graphviz libgraphviz-dev curl \ + && apt-get clean + +# Copy Python virtual environment +COPY --from=build-deps /.venv /.venv +ENV PATH="/.venv/bin:$PATH" + +# Set user and workdir +WORKDIR /app +RUN useradd -m -d /app app +USER app + +# Copy application code +COPY --chown=app . . + +# Set to 1 to automatically apply any pending DB migrations at startup +ENV MIGRATE_DB= + +# Create an initial admin user +ENV INITIAL_ADMIN_EMAIL= + +# LMDB database volume +ENV LMDB_DATA_DIR=/lmdb +VOLUME /lmdb + +# LMDB download cloud storage +# ENV AZURE_ACCOUNT_STORAGE_NAME= +# ENV AZURE_ACCOUNT_STORAGE_KEY= + +# JWT Authendication +ENV JWT_SECRET=secret + +# Base URL of this app, reachable by external services +ENV APPSERVER_URL=http://localhost:5000 + +# Base URL of the frontend app, for link generation +ENV FRONTEND_URL=http://localhost:4242 + +# PostgreSQL configuration +ENV POSTGRES_HOST=postgres +ENV POSTGRES_PORT=5432 +ENV POSTGRES_USER=postgres +ENV POSTGRES_PASSWORD=postgres +ENV POSTGRES_DB=postgres + +# Neo4j configuration +ENV NEO4J_HOST=neo4j +ENV NEO4J_PORT=7687 +ENV NEO4J_AUTH=neo4j/password +ENV NEO4J_DATABASE=neo4j +ENV NEO4J_SCHEME=bolt + +# Elasticsearch configuration +ENV ELASTICSEARCH_URL=http://elasticsearch:9200 +ENV ELASTICSEARCH_FILE_INDEX=file + +# Statistical enrichment service +ENV STATISTICAL_ENRICHMENT_URL=http://statistical-enrichment:5000 + +# PDFParser service +ENV PDFPARSER_URL=http://pdfparser:7600 -WORKDIR $N4J_HOME +# NLP Processing service +ENV NLP_URL=https://nlp-api.lifelike.bio/v1/predict +ENV NLP_SECRET=secret -# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache -COPY --chown=1000:1000 Pipfile . -COPY --chown=1000:1000 Pipfile.lock . -RUN pipenv install --dev --deploy --system +# Mailserver configuration +ENV FROM_EMAIL=lifelike@example.com -# ...then copy everything else -COPY --chown=1000:1000 . . +# Sendgrid integration +ENV SENDGRID_API_KEY= -# TODO: We should consider breaking this apart into dev and prod -# builds, so we don't build unnecessary packages +# Optional Sentry logging configuration +ENV SENTRY_DSN= -# Don't lose stdin, stdout and stderr output due to buffering -ENV PYTHONUNBUFFERED 1 -ENV PYTHONPATH $N4J_HOME +# Optional Elastic APM configuration. +# To enable, at least ELASTIC_APM_SERVER_URL must be set +# Other available variables: https://www.elastic.co/guide/en/apm/agent/python/master/configuration.html +ENV ELASTIC_APM_SERVER_URL= +ENV ELASTIC_APM_SERVICE_NAME=appserver -# Set Python3 as the default when running "python" -RUN echo 'alias python=python3' >> ~/.bashrc && source ~/.bashrc +# Flask env (development, testing, production) +ENV FLASK_ENV=production -USER $N4J_USER +# Listen port +ENV PORT=5000 +EXPOSE $PORT -# Setup flask application environment vars -ENV MAX_ALLOWED_LOGIN_FAILURES 6 +# Health check by requesting system info to /meta endpoint +HEALTHCHECK --start-period=30s \ + CMD curl -f localhost:$PORT/meta || exit 1 -CMD [ "bin/startup.sh" ] +RUN chmod +x bin/docker-entrypoint.sh +ENTRYPOINT ["bin/docker-entrypoint.sh"] diff --git a/cache-invalidator/Dockerfile b/cache-invalidator/Dockerfile index 7a94eac270..33f146b5ba 100644 --- a/cache-invalidator/Dockerfile +++ b/cache-invalidator/Dockerfile @@ -1,33 +1,64 @@ +# ======================================== +# Base image +# ======================================== FROM python:3.10-slim as base -LABEL app=kg-prototypes -# Install dependencies -RUN apt-get update && apt-get install -y curl && apt-get clean +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONFAULTHANDLER 1 + RUN pip install pipenv -ENV APP_USER lifelike -ENV APP_HOME /home/$APP_USER -ENV UID 1000 -ENV GID 1000 -# User and group creation -RUN groupadd -g $GID $APP_USER && \ - useradd -u $UID -g $GID -G sudo --create-home --home-dir $APP_HOME --shell /bin/bash $APP_USER +# ======================================== +# Build dependencies stage +# ======================================== +FROM base as build-deps + +# Copy Pipfiles +COPY Pipfile Pipfile.lock ./ + +# Install Python dependencies +ARG DEV +RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) + + +# ======================================== +# Runtime stage +# ======================================== +FROM base +LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike + +# Copy Python virtual environment +COPY --from=build-deps /.venv /.venv +ENV PATH="/.venv/bin:$PATH" + +# Set user and working directory +WORKDIR /app +RUN useradd -m -d /app app +USER app -WORKDIR $APP_HOME +# Copy application code +COPY --chown=app main.py ./ -# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache -COPY --chown=1000:1000 Pipfile . -COPY --chown=1000:1000 Pipfile.lock . -RUN pipenv install --deploy --dev --system +# Neo4j configuration +ENV NEO4J_HOST=neo4j +ENV NEO4J_PORT=7687 +ENV NEO4J_AUTH=neo4j/password +ENV NEO4J_SCHEME=bolt +ENV NEO4J_DATABASE=neo4j -# ...then copy everything else -COPY --chown=1000:1000 . . +# Redis cache configuration +ENV REDIS_HOST=redis +ENV REDIS_PORT=6379 +ENV REDIS_PASSWORD=password +ENV REDIS_DB=0 -# Don't lose stdin, stdout and stderr output due to buffering -ENV PYTHONUNBUFFERED 1 -ENV PYTHONPATH $APP_HOME +# Default TTL for cache +ENV CACHE_TTL=86400 -USER $APP_USER +# Logging level +ENV LOG_LEVEL=INFO -CMD [ "bin/startup.sh" ] +CMD ["python", "main.py"] diff --git a/client/Dockerfile b/client/Dockerfile index af7fe9281b..268192f7ce 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,20 +1,5 @@ ARG NODE_IMAGE_TAG=node:14 -# ======================================== -# Landing page -# ======================================== -FROM $NODE_IMAGE_TAG as landing-build -WORKDIR /app - -# Install dependencies -COPY landing/package.json landing/yarn.lock ./ -RUN yarn install - -# Build landing page -COPY landing ./ -RUN yarn build - - # ================================================================== # Angular app dependencies by default used for local development # ================================================================== @@ -23,71 +8,58 @@ WORKDIR /app # Install dependencies COPY package.json yarn.lock ./ -RUN yarn install +ARG YARN_INSTALL_OPTS +RUN yarn install ${YARN_INSTALL_OPTS} + +ENV ENVIRONMENT_CONFIG development -# build time arguments for Angular environment -ARG ANGULAR_CONFIG=development -ARG CLIENT_VERSION=undefined -# default enviroment presets -ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG # ======================================== # Angular app bundle build # ======================================== FROM angular-deps as angular-build -# build time arguments for Angular environment -ARG ANGULAR_CONFIG=production -ARG CLIENT_VERSION=undefined - # Copy the code and build the app bundle COPY src ./src COPY tslint ./tslint COPY e2e ./e2e COPY *.json browserslist ./ -RUN sed -i "s/__VERSION__/${CLIENT_VERSION}/" src/environments/environment.ts -RUN yarn build --configuration=$ANGULAR_CONFIG --aot --output-path=dist + +ARG ANGULAR_CONFIG=production +ENV NODE_OPTIONS=--max-old-space-size=4096 +RUN yarn build --configuration=$ANGULAR_CONFIG --output-path=dist + +# When targeting this image stage, run angulat dev server +EXPOSE 4200 +HEALTHCHECK --interval=5m --timeout=10s \ + CMD curl -f localhost:4200 || exit 1 +CMD yarn dev-start + # ======================================== # Runtime stage - NGINX # ======================================== -FROM nginx:1.25.1 -LABEL app=kg-prototypes -WORKDIR /usr/share/nginx/html +FROM nginx:1.21 +LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike -# URL to proxy requests to /api -ENV APPSERVER_UPSTREAM http://appserver:5000 - -# Whether to run the app in prod mode -ENV PRODUCTION_MODE true - -# Whether we are running with valid KEGG license -ENV KEGG_ENABLED false +WORKDIR /usr/share/nginx/html -# Whether to run the app with oauth login -ENV OAUTH_ENABLED false +# Copy built assets +COPY --from=angular-build /app/dist ./ -# OAuth issuer discovert URL -ENV OAUTH_ISSUER "" +# Copy nginx configuraiton template +COPY nginx.conf /etc/nginx/templates/default.conf.template -# Client ID of the OAuth application -ENV OAUTH_CLIENT_ID "" +# appserver URL to proxy /api requests +ENV APPSERVER_URL http://appserver:5000 # List of space delimited list of non-stantdard MIME types # which are known to benefit from gzip compression (text based content) ENV GZIP_EXTRA_TYPES text/tsv vnd.lifelike.document/bioc vnd.lifelike.document/enrichment-table vnd.lifelike.document/graph vnd.lifelike.document/map -# build time argument for Angular environment -ARG ANGULAR_CONFIG=production - -# default enviroment presets -ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG - -# Copy nginx configuraiton template -COPY nginx.conf /etc/nginx/templates/default.conf.template - -# Copy built assets -COPY --from=landing-build /app/dist ./ -COPY --from=angular-build /app/dist ./ +# Runtime environment configuration preset +ENV ENVIRONMENT_CONFIG production -EXPOSE 80 +# Listen port +ENV PORT 80 +EXPOSE $PORT diff --git a/statistical-enrichment/Dockerfile b/statistical-enrichment/Dockerfile index 6503159e4f..a9e34baaf2 100644 --- a/statistical-enrichment/Dockerfile +++ b/statistical-enrichment/Dockerfile @@ -1,34 +1,80 @@ -FROM python:3.8-buster -LABEL app=kg-prototypes +# ======================================== +# Base image +# ======================================== +FROM python:3.10-slim as base -ENV _USER user -ENV _HOME /home/$_USER -ENV UID 1000 -ENV GID 1000 +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONFAULTHANDLER 1 -# Root acces only if in root group -RUN echo "auth required pam_wheel.so" >> /etc/pam.d/su - -# Install dependencies RUN pip install pipenv -# 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 +# ======================================== +# Build dependencies stage +# ======================================== +FROM base as build-deps + +# Copy Pipfiles +COPY Pipfile Pipfile.lock ./ + +# Install Python dependencies +ARG DEV +RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy $(if [ "$DEV" ]; then echo --dev; fi) + + +# ======================================== +# Runtime stage +# ======================================== +FROM base +LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike + +# Install curl for self healthchecks +RUN apt-get update && apt-get install -y curl && apt-get clean + +# Copy Python virtual environment +COPY --from=build-deps /.venv /.venv +ENV PATH="/.venv/bin:$PATH" + +# Set user and working directory +WORKDIR /app +RUN useradd -m -d /app app +USER app + +# Copy application code +COPY --chown=app . . + +# Neo4j configuration +ENV NEO4J_HOST=neo4j +ENV NEO4J_PORT=7687 +ENV NEO4J_AUTH=neo4j/password +ENV NEO4J_SCHEME=bolt + +# Redis cache configuration +ENV REDIS_HOST=redis +ENV REDIS_PORT=6379 +ENV REDIS_PASSWORD=password +ENV REDIS_DB=0 -# Copy Pipfiles and install dependencies FIRST to better apply Docker layer cache -COPY --chown=$UID:$GID Pipfile . -COPY --chown=$UID:$GID Pipfile.lock . +# Default TTL for cache +ENV CACHE_TTL=86400 -RUN pipenv install --dev --deploy --system +# Optional Elastic APM configuration. +# To enable, at least ELASTIC_APM_SERVER_URL must be set +# Other available variables: https://www.elastic.co/guide/en/apm/agent/python/master/configuration.html +ENV ELASTIC_APM_SERVER_URL= +ENV ELASTIC_APM_SERVICE_NAME=statistical-enrichment -ENV FLASK_APP=statistical_enrichment +# Flask env [development, testing, production] +ENV FLASK_ENV=production -COPY --chown=$UID:$GID . . +# Listen port +ENV PORT=5000 +EXPOSE $PORT -USER $_USER +# Healtcheck +HEALTHCHECK --start-period=15s \ + CMD curl -f localhost:$PORT/healthz || exit 1 -CMD [ "bin/startup.sh" ] +CMD bin/startup.sh From 2d08c7ab2aedd5ab3686bd7deaccca3b6d59796d Mon Sep 17 00:00:00 2001 From: Dominik Mariusz Maszczyk Date: Wed, 3 Apr 2024 16:44:51 +0200 Subject: [PATCH 03/23] get rid of legacy/unussed code --- .github/actions/ansible/Dockerfile | 10 - .github/actions/ansible/action.yml | 33 - .github/actions/ansible/entrypoint.sh | 62 - .github/actions/cloud-sql-backup/action.yml | 43 - .github/actions/cloud-sql-restore/action.yml | 29 - .github/actions/docker-publish.yml | 67 - .github/labeler.yml | 3 - .github/workflows/backup-tests.yml | 284 --- .../workflows/cloud-sql-backup-ondemand.yml | 36 - .github/workflows/deployment-az-public.yml | 21 - .github/workflows/deployment-az-staging.yml | 20 - .github/workflows/deployment-az.yml | 111 - .github/workflows/deployment-contabo-ucsd.yml | 20 - .github/workflows/deployment-contabo.yml | 113 - .github/workflows/deployment-gcp-demo.yml | 21 - .github/workflows/deployment-gcp-prod.yml | 23 - .github/workflows/deployment-gcp-public.yml | 22 - .github/workflows/deployment-gcp-qa.yml | 22 - .github/workflows/deployment-gcp-staging.yml | 22 - .github/workflows/deployment-gcp.yml | 159 -- .github/workflows/docker.yml | 69 - .github/workflows/graphdb-migrate.yml | 84 - .github/workflows/integration-tests.yml | 11 - .github/workflows/traefik-az.yml | 18 - .github/workflows/traefik.yml | 46 - .gitignore | 2 +- .gitmodules | 13 - README.md | 2 +- appserver/Dockerfile | 18 +- appserver/Pipfile | 3 +- appserver/Pipfile.lock | 1852 ++++++++--------- appserver/bin/docker-entrypoint.sh | 43 - appserver/bin/startup.sh | 2 +- appserver/bin/wait-for-neo4j | 16 - appserver/config.py | 6 - .../neo4japp/data_transfer_objects/search.py | 4 +- .../neo4japp/services/annotations/README.md | 4 +- cache-invalidator/Dockerfile | 14 +- cache-invalidator/Pipfile.lock | 179 +- client/Dockerfile | 76 +- .../node-details.component.html | 2 +- .../components/graph-search.component.ts | 2 +- .../components/route-builder.component.html | 47 - .../components/route-builder.component.scss | 27 - .../route-builder.component.spec.ts | 33 - .../components/route-builder.component.ts | 74 - .../components/route-display.component.html | 18 - .../components/route-display.component.scss | 0 .../route-display.component.spec.ts | 36 - .../components/route-display.component.ts | 191 -- .../containers/route-search.component.html | 1 - .../containers/route-search.component.scss | 0 .../containers/route-search.component.spec.ts | 31 - .../containers/route-search.component.ts | 15 - .../containers/shortest-path.component.html | 20 - .../containers/shortest-path.component.scss | 0 .../shortest-path.component.spec.ts | 42 - .../containers/shortest-path.component.ts | 57 - .../services/shortest-path.service.ts | 39 - .../app/shortest-path/shortest-path.module.ts | 25 - deployment | 1 - docker-compose.ci-test.yml | 14 +- docker-compose.override.yml | 2 - docker/Makefile | 2 +- docker/README.md | 4 +- docker/diagram.svg | 18 +- docker/docker-compose.services.yml | 76 +- docker/docker-compose.yml | 16 +- docs/wiki/development/general-introduction.md | 2 +- docs/wiki/elk/introduction.md | 2 - graph-db/docker-compose.yml | 24 +- graph-db/docs/reactome/Reactome GDS.ipynb | 6 +- graph-db/migrator/Dockerfile | 22 +- graph-db/migrator/README.md | 20 +- graph-db/migrator/docker-entrypoint.sh | 24 +- helm/lifelike/Chart.lock | 6 +- helm/lifelike/Chart.yaml | 6 +- helm/lifelike/README.md | 14 +- helm/lifelike/examples/external-db.yaml | 14 +- helm/lifelike/templates/_helpers.tpl | 80 +- helm/lifelike/templates/api/deployment.yaml | 8 +- helm/lifelike/values.schema.json | 6 +- helm/lifelike/values.yaml | 26 +- keycloak | 1 - lifelike-oss | 1 - makefile | 19 +- statistical-enrichment/Dockerfile | 12 +- website | 1 - 88 files changed, 1236 insertions(+), 3434 deletions(-) delete mode 100644 .github/actions/ansible/Dockerfile delete mode 100644 .github/actions/ansible/action.yml delete mode 100755 .github/actions/ansible/entrypoint.sh delete mode 100644 .github/actions/cloud-sql-backup/action.yml delete mode 100644 .github/actions/cloud-sql-restore/action.yml delete mode 100644 .github/actions/docker-publish.yml delete mode 100644 .github/workflows/backup-tests.yml delete mode 100644 .github/workflows/cloud-sql-backup-ondemand.yml delete mode 100644 .github/workflows/deployment-az-public.yml delete mode 100644 .github/workflows/deployment-az-staging.yml delete mode 100644 .github/workflows/deployment-az.yml delete mode 100644 .github/workflows/deployment-contabo-ucsd.yml delete mode 100644 .github/workflows/deployment-contabo.yml delete mode 100644 .github/workflows/deployment-gcp-demo.yml delete mode 100644 .github/workflows/deployment-gcp-prod.yml delete mode 100644 .github/workflows/deployment-gcp-public.yml delete mode 100644 .github/workflows/deployment-gcp-qa.yml delete mode 100644 .github/workflows/deployment-gcp-staging.yml delete mode 100644 .github/workflows/deployment-gcp.yml delete mode 100644 .github/workflows/docker.yml delete mode 100644 .github/workflows/graphdb-migrate.yml delete mode 100644 .github/workflows/traefik-az.yml delete mode 100644 .github/workflows/traefik.yml delete mode 100755 appserver/bin/docker-entrypoint.sh delete mode 100755 appserver/bin/wait-for-neo4j delete mode 100644 client/src/app/shortest-path/components/route-builder.component.html delete mode 100644 client/src/app/shortest-path/components/route-builder.component.scss delete mode 100644 client/src/app/shortest-path/components/route-builder.component.spec.ts delete mode 100644 client/src/app/shortest-path/components/route-builder.component.ts delete mode 100644 client/src/app/shortest-path/components/route-display.component.html delete mode 100644 client/src/app/shortest-path/components/route-display.component.scss delete mode 100644 client/src/app/shortest-path/components/route-display.component.spec.ts delete mode 100644 client/src/app/shortest-path/components/route-display.component.ts delete mode 100644 client/src/app/shortest-path/containers/route-search.component.html delete mode 100644 client/src/app/shortest-path/containers/route-search.component.scss delete mode 100644 client/src/app/shortest-path/containers/route-search.component.spec.ts delete mode 100644 client/src/app/shortest-path/containers/route-search.component.ts delete mode 100644 client/src/app/shortest-path/containers/shortest-path.component.html delete mode 100644 client/src/app/shortest-path/containers/shortest-path.component.scss delete mode 100644 client/src/app/shortest-path/containers/shortest-path.component.spec.ts delete mode 100644 client/src/app/shortest-path/containers/shortest-path.component.ts delete mode 100644 client/src/app/shortest-path/services/shortest-path.service.ts delete mode 100644 client/src/app/shortest-path/shortest-path.module.ts delete mode 160000 deployment delete mode 160000 keycloak delete mode 160000 lifelike-oss delete mode 160000 website diff --git a/.github/actions/ansible/Dockerfile b/.github/actions/ansible/Dockerfile deleted file mode 100644 index ad9558dbc7..0000000000 --- a/.github/actions/ansible/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM alpine:3.19.0 -LABEL app=kg-prototypes - -ENV ANSIBLE_HOST_KEY_CHECKING=False - -RUN apk add ansible python3-dev gcc openssh-client - -COPY entrypoint.sh ./entrypoint.sh - -ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/.github/actions/ansible/action.yml b/.github/actions/ansible/action.yml deleted file mode 100644 index 1dc81d1b02..0000000000 --- a/.github/actions/ansible/action.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Ansible Runner -description: Runs Ansible Playbooks using Github Actions - -inputs: - workspace_dir: - description: Root directory of the Ansible workspace. - required: true - playbook_file_path: - description: Playook path relative to the workspace directory. - required: true - inventory_file_path: - description: Inventory path relative to the workspace directory - required: true - ssh_key: - description: SSH key for remote Ansible connections - required: false - vault_password: - description: Password used for Ansible vault encrypted files - required: false - options: - description: Additional options for Ansible playbook - required: false - -runs: - using: docker - image: Dockerfile - args: - - ${{ inputs.workspace_dir }} - - ${{ inputs.playbook_file_path }} - - ${{ inputs.inventory_file_path }} - - ${{ inputs.ssh_key }} - - ${{ inputs.vault_password }} - - ${{ inputs.options }} diff --git a/.github/actions/ansible/entrypoint.sh b/.github/actions/ansible/entrypoint.sh deleted file mode 100755 index f3da85a0ed..0000000000 --- a/.github/actions/ansible/entrypoint.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -set -e - -export WORKSPACE_DIR= -if [ ! -z "$INPUT_WORKSPACE_DIR" ] -then - WORKSPACE_DIR="${INPUT_WORKSPACE_DIR}" -else - echo "No working space directory specified." -fi - -export PLAYBOOK_FILE_PATH= -if [ ! -z "$INPUT_PLAYBOOK_FILE_PATH" ] -then - PLAYBOOK_FILE_PATH="${INPUT_PLAYBOOK_FILE_PATH}" -else - echo "No playbook specified." -fi - -export INVENTORY_FILE_PATH= -if [ ! -z "$INPUT_INVENTORY_FILE_PATH" ] -then - INVENTORY_FILE_PATH="-i ${INPUT_INVENTORY_FILE_PATH}" -else - echo "No inventory specified." -fi - -export SSH_KEY= -if [ ! -z "$INPUT_SSH_KEY" ] -then - mkdir ~/.ssh - echo "$INPUT_SSH_KEY" > ~/.ssh/ansible - chmod 0600 ~/.ssh/ansible - tilde=~ - SSH_KEY_PATH="${tilde}/.ssh/ansible" - SSH_KEY="--key-file ${SSH_KEY_PATH}" -else - echo "No SSH key specified." -fi - -export VAULT_PASSWORD= -if [ ! -z "$INPUT_VAULT_PASSWORD" ] -then - echo "$INPUT_VAULT_PASSWORD" > ~/.vault_secrets_pw - tilde=~ - VAULT_PASSWORD_PATH="${tilde}/.vault_secrets_pw" - VAULT_PASSWORD="--vault-password-file ${VAULT_PASSWORD_PATH}" -else - echo "No vault password specified." -fi - -export OPTIONS= -if [ ! -z "$INPUT_OPTIONS" ] -then - OPTIONS=$(echo "${INPUT_OPTIONS}" | tr "\n" " ") -fi - -cd ${WORKSPACE_DIR} -echo "Running command..." -echo ansible-playbook ${PLAYBOOK_FILE_PATH} ${INVENTORY_FILE_PATH} ${SSH_KEY} ${VAULT_PASSWORD} ${OPTIONS} -ansible-playbook ${PLAYBOOK_FILE_PATH} ${INVENTORY_FILE_PATH} ${SSH_KEY} ${VAULT_PASSWORD} ${OPTIONS} diff --git a/.github/actions/cloud-sql-backup/action.yml b/.github/actions/cloud-sql-backup/action.yml deleted file mode 100644 index 9199899ced..0000000000 --- a/.github/actions/cloud-sql-backup/action.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Cloud SQL backup -description: Backup a Google Cloud SQL instance - -inputs: - gcp_credentials: - description: Google Cloud Platform credentials - required: true - cloud_sql_instance_name: - description: Google Cloud SQL instance name - required: true - backup_description: - description: Backup description - required: false - default: "" - -outputs: - backup_id: - description: Google Cloud SQL backup ID - value: ${{ steps.fetch-backup-id.outputs.backup_id }} - -runs: - using: composite - steps: - - id: auth - uses: google-github-actions/auth@v0 - with: - credentials_json: "${{ inputs.gcp_credentials }}" - - - uses: google-github-actions/setup-gcloud@v0 - - - run: | - gcloud sql backups create \ - --instance="${{ inputs.cloud_sql_instance_name }}" \ - --description="${{ inputs.backup_description }}" - shell: bash - - - id: fetch-backup-id - run: | - echo ::set-output name=backup_id::$( \ - gcloud sql backups list \ - --instance="${{ inputs.cloud_sql_instance_name }}" \ - --format=json --limit 1 | jq -r ".[0].selfLink" ) - shell: bash diff --git a/.github/actions/cloud-sql-restore/action.yml b/.github/actions/cloud-sql-restore/action.yml deleted file mode 100644 index 7d78d1d270..0000000000 --- a/.github/actions/cloud-sql-restore/action.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Cloud SQL restore -description: Restore a Google Cloud SQL instance backup - -inputs: - gcp_credentials: - description: Google Cloud Platform credentials - required: true - cloud_sql_backup_id: - description: Google Cloud SQL backup ID to restore - required: true - cloud_sql_restore_instance: - description: Google Cloud SQL instance name to restore backup into - required: true - -runs: - using: composite - steps: - - id: auth - uses: google-github-actions/auth@v0 - with: - credentials_json: "${{ inputs.gcp_credentials }}" - - - uses: google-github-actions/setup-gcloud@v0 - - - run: | - gcloud sql backups restore \ - --restore-instance="${{ inputs.cloud_sql_restore_instance }}" \ - ${{ inputs.cloud_sql_backup_id }} - shell: bash diff --git a/.github/actions/docker-publish.yml b/.github/actions/docker-publish.yml deleted file mode 100644 index 580dd94672..0000000000 --- a/.github/actions/docker-publish.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: 'Docker build and publish' -description: 'Builds and publishes a Docker image into a Docker registry.' - -inputs: - registry: - description: 'Server address of the Docker registry' - default: lifelike.azurecr.io - required: false - image: - description: 'Docker image' - required: true - username: - description: 'Username to log in to a Docker registry' - default: ${{ secrets.AZURE_CR_USERNAME }} - required: false - password: - description: 'Password or PAT to log in to a Docker registry' - default: ${{ secrets.AZURE_CR_PASSWORD }} - required: false - dockerfile: - description: 'Dockerfile to use for building the image' - required: false - default: './Dockerfile' - context: - description: 'Docker build context' - required: false - default: '.' - push: - description: 'Whether to push the image to the registry' - required: false - default: 'true' - -runs: - using: 'composite' - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Docker meta - id: docker_meta - uses: crazy-max/ghaction-docker-meta@v1 - with: - images: ${{ inputs.image }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Login to DockerHub - if: github.event_name != 'pull_request' && inputs.username != '' && inputs.password != '' - uses: docker/login-action@v1 - with: - username: ${{ inputs.username }} - password: ${{ inputs.password }} - - - name: Build and push - uses: docker/build-push-action@v2 - with: - file: ${{ inputs.dockerfile }} - context: ${{ inputs.context }} - tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} - push: ${{ inputs.push }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/labeler.yml b/.github/labeler.yml index debee6d781..c19e1e9fb8 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -37,6 +37,3 @@ docker: workflow: - .github/* - .github/**/* - -infrastructure: - - deployment diff --git a/.github/workflows/backup-tests.yml b/.github/workflows/backup-tests.yml deleted file mode 100644 index 18e7b9c516..0000000000 --- a/.github/workflows/backup-tests.yml +++ /dev/null @@ -1,284 +0,0 @@ -name: Database backups tests - -on: - workflow_dispatch: - inputs: - force: - description: Force backup tests to run even for backups already tested - type: boolean - default: false - required: false - schedule: - # Run once a week on sunday at 00:00 - - cron: "0 1 * * 0" - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: false - -jobs: - get-sql-instances: - name: List Cloud SQL instances - runs-on: ubuntu-latest - outputs: - instances: ${{ steps.instances.outputs.json }} - steps: - - uses: actions/checkout@v3 - - - name: Authenticate to Google Cloud - uses: google-github-actions/auth@v0 - id: auth - with: - credentials_json: "${{ secrets.GCE_SA_KEY }}" - - - name: Set up Cloud SDK - uses: google-github-actions/setup-gcloud@v0 - - - name: Get all Cloud SQL instances - id: instances - run: | - INSTANCES=$( \ - gcloud sql instances list \ - --format="value(name.list())" \ - --filter="labels.test-backups=true" \ - | jq -R -s -c 'split("\n") | map(select(.!=""))') - echo ::set-output name=json::$INSTANCES - - restore-and-test: - needs: get-sql-instances - runs-on: ubuntu-latest - continue-on-error: true - strategy: - matrix: - instance: ${{ fromJSON(needs.get-sql-instances.outputs.instances) }} - type: ["AUTOMATED", "ON_DEMAND"] - steps: - - uses: actions/checkout@v3 - - - name: Authenticate to Google Cloud - uses: google-github-actions/auth@v0 - id: auth - with: - credentials_json: "${{ secrets.GCE_SA_KEY }}" - - - name: "Set up Cloud SDK" - uses: google-github-actions/setup-gcloud@v0 - with: - install_components: beta - - - name: Get latest ${{ matrix.type }} backup ID - id: get-backup - run: | - BACKUP=$( \ - gcloud sql backups list \ - --instance="${{ matrix.instance }}" \ - --filter="status=SUCCESSFUL AND type=${{ matrix.type }}" \ - --format="value(id, startTime)" --sort-by="-startTime" \ - | head -n 1) - echo ::set-output name=id::$(echo $BACKUP | cut -d' ' -f1) - echo ::set-output name=date::$(echo $BACKUP | cut -d' ' -f2) - - - name: Retrieve previous results artifact, if any - id: download-artifact - uses: dawidd6/action-download-artifact@v2 - with: - name: backup-test-results-${{ steps.get-backup.outputs.id }} - search_artifacts: true - if_no_artifact_found: ignore - - - name: Check if backup exists and hasn't been tested before - uses: actions/github-script@v6 - with: - script: | - if (!'${{ steps.get-backup.outputs.id }}') { - core.warning('Skipping. No backup found of type ${{ matrix.type }} for Cloud SQL instance: {{ matrix.instance }}') - } else if (!core.getInput('force') && (await (await glob.create('results.txt')).glob()).length > 0) { - core.notice('Skipping. Backup ${{ steps.get-backup.outputs.id }} has already been tested.') - } else { - core.exportVariable('PROCEED', 'true') - } - - - name: Get instance details - if: ${{ env.PROCEED == 'true' }} - id: instance-details - run: | - INSTANCE=$( \ - gcloud sql instances describe \ - --format="value(databaseVersion, settings.tier, region, project)" \ - ${{ matrix.instance }}) - echo ::set-output name=version::$(echo $INSTANCE | cut -d' ' -f1) - echo ::set-output name=tier::$(echo $INSTANCE | cut -d' ' -f2) - echo ::set-output name=region::$(echo $INSTANCE | cut -d' ' -f3) - echo ::set-output name=project::$(echo $INSTANCE | cut -d' ' -f4) - - - name: Create temporary Cloud SQL instance - if: ${{ env.PROCEED == 'true' }} - id: create-temp-instance - run: | - TEMP_INSTANCE_NAME=$(echo "temp-${{ matrix.instance }}-${{ matrix.type }}-${{ github.run_id }}" | sed 's/_/-/g' | awk '{print tolower($0)}') - gcloud beta sql instances create "$TEMP_INSTANCE_NAME" \ - --database-version=${{ steps.instance-details.outputs.version }} \ - --tier=${{ steps.instance-details.outputs.tier }} \ - --region=${{ steps.instance-details.outputs.region }} \ - --labels="temp-instance=true,workflow-run=${{ github.run_id }}" - echo ::set-output name=temp_instance_name::$TEMP_INSTANCE_NAME - - - name: Restore backup into temporary instance - if: ${{ env.PROCEED == 'true' }} - run: | - gcloud sql backups restore --quiet \ - --restore-instance=${{ steps.create-temp-instance.outputs.temp_instance_name }} \ - --backup-instance=${{ matrix.instance }} \ - ${{ steps.get-backup.outputs.id }} - - - name: Reset postgres password - if: ${{ env.PROCEED == 'true' }} - run: | - gcloud sql users set-password \ - --instance=${{ steps.create-temp-instance.outputs.temp_instance_name }} \ - --password=password postgres - - - uses: mattes/gce-cloudsql-proxy-action@v1 - if: ${{ env.PROCEED == 'true' }} - with: - creds: ${{ secrets.GCE_SA_KEY }} - instance: ${{ steps.instance-details.outputs.project }}:${{ steps.instance-details.outputs.region }}:${{ steps.create-temp-instance.outputs.temp_instance_name }} - - - name: Setup PostgreSQL client - if: ${{ env.PROCEED == 'true' }} - run: | - sudo apt-get update - sudo apt-get install --yes --no-install-recommends postgresql-client - - - name: Query temporary instance - if: ${{ env.PROCEED == 'true' }} - env: - PGPASSWORD: password - PGHOST: localhost - run: | - cat < queries.sql - -- ------------------------------------------------------------ - -- Count stats - -- ------------------------------------------------------------ - WITH tbl AS - (SELECT table_schema,TABLE_NAME - FROM information_schema.tables - WHERE TABLE_NAME not like 'pg_%' - AND table_schema in ('public')) - SELECT TABLE_NAME, (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', table_schema, TABLE_NAME), FALSE, TRUE, '')))[1]::text::int AS rows - FROM tbl - ORDER BY rows DESC; - -- ------------------------------------------------------------ - -- Alembic - -- ------------------------------------------------------------ - SELECT version_num as current_alembic_version FROM alembic_version; - -- ------------------------------------------------------------ - -- Date stats - -- ------------------------------------------------------------ - CREATE OR REPLACE FUNCTION get_min_max_modified_date() - RETURNS TABLE (table_name text, - max_modified_daye timestamp, - min_modified_daye timestamp) - LANGUAGE plpgsql - AS \$\$ - DECLARE - r record; - BEGIN - FOR r IN - SELECT i.table_name, i.table_schema - FROM information_schema.tables i - WHERE i.table_name in ( - SELECT c.table_name - FROM information_schema.columns c - WHERE c.table_schema = 'public' - AND c.column_name = 'modified_date' - GROUP BY c.table_name - ) - LOOP - execute format ( - 'SELECT min(modified_date) FROM %I.%I', - r.table_schema, r.table_name - ) INTO min_modified_daye; - execute format ( - 'SELECT max(modified_date) FROM %I.%I', - r.table_schema, r.table_name - ) INTO max_modified_daye; - table_name := r.table_name; - RETURN next; - END LOOP; - END - \$\$; - SELECT * FROM get_min_max_modified_date(); - EOF - - # Query the restored database - psql -U postgres -d postgres -f queries.sql > results.txt - - # Export results to variable - echo "RESULTS<> $GITHUB_ENV - echo $(cat results.txt) >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - results=$(> $GITHUB_STEP_SUMMARY - ## Backup details - - - Cloud SQL instance name: **${{ matrix.instance }}** - - Backup date: **${{ steps.get-backup.outputs.date }}** - - Backup type: **${{ matrix.type }}** - - Backup ID: **${{ steps.get-backup.outputs.id }}** - - Workflow run ID: [**${{ github.run_id }}**](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - - ## Results - \`\`\` - $results - \`\`\` - EOF - - - name: Upload results artifact - if: ${{ env.PROCEED == 'true' }} - uses: actions/upload-artifact@v3 - with: - name: backup-test-results-${{ steps.get-backup.outputs.id }} - path: results.txt - retention-days: 90 - - - name: Delete temporary instance - if: ${{ env.PROCEED == 'true' }} - run: | - gcloud sql instances delete --quiet \ - ${{ steps.create-temp-instance.outputs.temp_instance_name }} - - - name: Notify results by email - if: ${{ env.PROCEED == 'true' }} - uses: licenseware/send-email-notification@v1 - with: - api-key: "***REMOVED***" - # api-key: ${{ secrets.SENDGRID_API_KEY }} - from-email: no-reply@lifelike.bio - to-email: darede@biosustain.dtu.dk - # to-email: ${{ secrets.BACKUP_TEST_NOTIFY_EMAILS }} - subject: "Lifelike DB backup test passed for ${{ matrix.instance }} - ${{ matrix.type }}" - markdown-body: | - # Lifelike PostgreSQL backup test results - - ## Test result: ✅ PASSED - - ## Details - - - Cloud SQL instance name: **${{ matrix.instance }}** - - Backup date: **${{ steps.get-backup.outputs.date }}** - - Backup type: **${{ matrix.type }}** - - Backup ID: **${{ steps.get-backup.outputs.id }}** - - Workflow run ID: [**${{ github.run_id }}**](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - - ## Database queries - - ``` - $(cat results.txt) - ``` - - --- - - See the workflow run [at GitHub](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). diff --git a/.github/workflows/cloud-sql-backup-ondemand.yml b/.github/workflows/cloud-sql-backup-ondemand.yml deleted file mode 100644 index 890dc9461e..0000000000 --- a/.github/workflows/cloud-sql-backup-ondemand.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Backup Cloud SQL on-demand - -on: - workflow_dispatch: - inputs: - cloud_sql_instance_name: - description: Google Cloud SQL instance name - required: true - type: string - backup_description: - description: Backup description - required: false - default: On-demand backup from GitHub workflow - type: string - secrets: - GCE_SA_KEY: - required: true - -jobs: - backup: - name: Backup Cloud SQL instance - runs-on: ubuntu-latest - outputs: - backup_id: ${{ steps.backup.outputs.backup_id }} - - steps: - - uses: actions/checkout@v3 - - name: Create a new Clod SQL instance backup - id: backup - uses: ./.github/actions/cloud-sql-backup - with: - gcp_credentials: "${{ secrets.GCE_SA_KEY }}" - cloud_sql_instance_name: "${{ github.event.inputs.cloud_sql_instance_name }}" - backup_description: "${{ github.event.inputs.backup_description }}" - - run: | - echo "## Backup created: ${{ steps.backup.outputs.backup_id }}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/deployment-az-public.yml b/.github/workflows/deployment-az-public.yml deleted file mode 100644 index 0347495991..0000000000 --- a/.github/workflows/deployment-az-public.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Azure Public Deployment - -on: - workflow_dispatch: - push: - tags: [public] - branches: [public/**] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-az.yml - with: - environment_name: public - client_config: production - cloud_sql_instance_name: lifelike-public - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-az-staging.yml b/.github/workflows/deployment-az-staging.yml deleted file mode 100644 index d7e2c2525e..0000000000 --- a/.github/workflows/deployment-az-staging.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Azure Staging Deployment - -on: - workflow_dispatch: - push: - tags: [staging-az] - branches: [staging-az/**] - -jobs: - call-deployment-az: - uses: ./.github/workflows/deployment-az.yml - with: - environment_name: staging-az - client_config: production - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-az.yml b/.github/workflows/deployment-az.yml deleted file mode 100644 index f2cb12a9bd..0000000000 --- a/.github/workflows/deployment-az.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: Lifelike Azure deployment - -on: - workflow_call: - inputs: - environment_name: - description: Environment name (prod, staging, qa or demo) - required: true - type: string - client_config: - description: Client Runtime configuration preset - required: true - default: production - type: string - container_registry: - description: Container registry name - required: false - default: lifelike.azurecr.io - type: string - secrets: - CONTAINER_REGISTRY_USERNAME: - required: true - CONTAINER_REGISTRY_PASSWORD: - required: true - VAULT_PASSWORD: - required: true - SSH_KEY: - required: true - INFRA_PAT: - required: true - -jobs: - # ------------------------------------------------------------- - # JOB: Build Docker images - # ------------------------------------------------------------- - build: - name: Build - runs-on: ubuntu-latest - strategy: - matrix: - include: - - image: kg-webserver - path: ./client - build_extra_args: --build-arg ANGULAR_CONFIG=${{ inputs.client_config }} --build-arg CLIENT_VERSION=${{ github.sha }} - - image: kg-appserver - path: ./appserver - - image: kg-cache-service - path: ./cache-invalidator - - image: kg-statistical-enrichment - path: ./statistical-enrichment - - image: filebeat - path: ./filebeat - - image: metricbeat - path: ./metricbeat - - steps: - - uses: actions/checkout@v3 - - name: Build and push ${{ matrix.image }} image - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ${{ matrix.path }} - image_name: ${{ matrix.image }} - image_tag: ${{ github.sha }},${{ inputs.environment_name }},latest - build_extra_args: ${{ matrix.build_extra_args }} - registry: ${{ inputs.container_registry }} - username: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} - password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} - dockerfile: ./Dockerfile - - # ------------------------------------------------------------- - # JOB: Deploy to AZ environment using Ansible playbook - # pointed by the Git submodule: /deployment - # ------------------------------------------------------------- - deploy: - name: Deploy - needs: - - build - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - token: ${{ secrets.INFRA_PAT }} - submodules: recursive - - - name: Set git metadata - id: git-meta - run: | - echo ::set-output name=commit_timestamp::$(git log -1 --format=%cI) - echo ::set-output name=build_number::$(git rev-list --count HEAD) - echo ::set-output name=build_version::$(echo "${GITHUB_REF#refs/*/}") - - - name: Run Ansible deployment action - uses: ./.github/actions/ansible - with: - workspace_dir: deployment/ansible - playbook_file_path: playbooks/deploy-azure.yml - inventory_file_path: inventories/hosts-az.yml - vault_password: ${{ secrets.VAULT_PASSWORD }} - ssh_key: ${{ secrets.SSH_KEY }} - options: | - --extra-vars environment_name=${{ inputs.environment_name }} - --extra-vars client_config=${{ inputs.client_config }} - --extra-vars docker_img_hash=${{ github.sha }} - --extra-vars git_timestamp=${{ steps.git-meta.outputs.commit_timestamp }} - --extra-vars app_build_number=${{ steps.git-meta.outputs.build_number }} - --extra-vars app_version=${{ steps.git-meta.outputs.build_version }} - --extra-vars github_run_id=${{ github.run_id }} - --user ansible - --verbose diff --git a/.github/workflows/deployment-contabo-ucsd.yml b/.github/workflows/deployment-contabo-ucsd.yml deleted file mode 100644 index 2251acc3ee..0000000000 --- a/.github/workflows/deployment-contabo-ucsd.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Contabo UCSD Deployment - -on: - workflow_dispatch: - push: - tags: [ucsd] - branches: [ucsd/**] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-contabo.yml - with: - environment_name: ucsd - client_config: production - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-contabo.yml b/.github/workflows/deployment-contabo.yml deleted file mode 100644 index 041064b423..0000000000 --- a/.github/workflows/deployment-contabo.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: Lifelike Contabo deployment - -on: - workflow_call: - inputs: - environment_name: - description: Environment name - required: true - type: string - client_config: - description: Client Runtime configuration preset - required: true - default: production - type: string - container_registry: - description: Container registry name - required: false - default: lifelike.azurecr.io - type: string - secrets: - CONTAINER_REGISTRY_USERNAME: - required: true - CONTAINER_REGISTRY_PASSWORD: - required: true - VAULT_PASSWORD: - required: true - SSH_KEY: - required: true - GCP_CREDENTIALS: - required: true - INFRA_PAT: - required: true - -jobs: - # ------------------------------------------------------------- - # JOB: Build Docker images - # ------------------------------------------------------------- - build: - name: Build - runs-on: ubuntu-latest - strategy: - matrix: - include: - - image: kg-webserver - path: ./client - build_extra_args: --build-arg ANGULAR_CONFIG=${{ inputs.client_config }} --build-arg CLIENT_VERSION=${{ github.sha }} - - image: kg-appserver - path: ./appserver - - image: kg-cache-service - path: ./cache-invalidator - - image: kg-statistical-enrichment - path: ./statistical-enrichment - - image: filebeat - path: ./filebeat - - image: metricbeat - path: ./metricbeat - - steps: - - uses: actions/checkout@v3 - - name: Build and push ${{ matrix.image }} image - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ${{ matrix.path }} - image_name: ${{ matrix.image }} - image_tag: ${{ github.sha }},${{ inputs.environment_name }},latest - build_extra_args: ${{ matrix.build_extra_args }} - registry: ${{ inputs.container_registry }} - username: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} - password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} - dockerfile: ./Dockerfile - - # ------------------------------------------------------------- - # JOB: Deploy to Contabo environment using Ansible playbook - # pointed by the Git submodule: /deployment - # ------------------------------------------------------------- - deploy: - name: Deploy - needs: - - build - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - token: ${{ secrets.INFRA_PAT }} - submodules: recursive - - - name: Set git metadata - id: git-meta - run: | - echo ::set-output name=commit_timestamp::$(git log -1 --format=%cI) - echo ::set-output name=build_number::$(git rev-list --count HEAD) - echo ::set-output name=build_version::$(echo "${GITHUB_REF#refs/*/}") - - - name: Run Ansible deployment action - uses: ./.github/actions/ansible - with: - workspace_dir: deployment/ansible - playbook_file_path: playbooks/deploy-contabo.yml - inventory_file_path: inventories/hosts-contabo.yml - vault_password: ${{ secrets.VAULT_PASSWORD }} - ssh_key: ${{ secrets.SSH_KEY }} - options: | - --extra-vars environment_name=${{ inputs.environment_name }} - --extra-vars client_config=${{ inputs.client_config }} - --extra-vars docker_img_hash=${{ github.sha }} - --extra-vars git_timestamp=${{ steps.git-meta.outputs.commit_timestamp }} - --extra-vars app_build_number=${{ steps.git-meta.outputs.build_number }} - --extra-vars app_version=${{ steps.git-meta.outputs.build_version }} - --extra-vars github_run_id=${{ github.run_id }} - --user ansible - --verbose diff --git a/.github/workflows/deployment-gcp-demo.yml b/.github/workflows/deployment-gcp-demo.yml deleted file mode 100644 index b673c5c93d..0000000000 --- a/.github/workflows/deployment-gcp-demo.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: GCP Demo Deployment - -on: - workflow_dispatch: - push: - tags: [demo] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-gcp.yml - with: - environment_name: demo - client_config: demo - cloud_sql_instance_name: kg-demo - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - GCP_CREDENTIALS: ${{ secrets.GCE_SA_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-gcp-prod.yml b/.github/workflows/deployment-gcp-prod.yml deleted file mode 100644 index 4d86fab703..0000000000 --- a/.github/workflows/deployment-gcp-prod.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: GCP Prod Deployment - -on: - workflow_dispatch: - release: - types: [released] - push: - tags: [prod] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-gcp.yml - with: - environment_name: prod - client_config: production - cloud_sql_instance_name: lifelike-prod - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - GCP_CREDENTIALS: ${{ secrets.GCE_SA_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-gcp-public.yml b/.github/workflows/deployment-gcp-public.yml deleted file mode 100644 index cfaf35aa95..0000000000 --- a/.github/workflows/deployment-gcp-public.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: GCP Public Deployment - -on: - workflow_dispatch: - push: - tags: [public] - branches: [public/**] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-gcp.yml - with: - environment_name: public - client_config: production - cloud_sql_instance_name: lifelike-public - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - GCP_CREDENTIALS: ${{ secrets.GCE_SA_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-gcp-qa.yml b/.github/workflows/deployment-gcp-qa.yml deleted file mode 100644 index af46d79f4e..0000000000 --- a/.github/workflows/deployment-gcp-qa.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: GCP QA Deployment - -on: - workflow_dispatch: - push: - branches: [master] - tags: [qa] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-gcp.yml - with: - environment_name: qa - client_config: qa - cloud_sql_instance_name: lifelike-qa - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - GCP_CREDENTIALS: ${{ secrets.GCE_SA_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-gcp-staging.yml b/.github/workflows/deployment-gcp-staging.yml deleted file mode 100644 index f90e923c57..0000000000 --- a/.github/workflows/deployment-gcp-staging.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: GCP Staging Deployment - -on: - workflow_dispatch: - push: - tags: [staging] - branches: [staging/**] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/deployment-gcp.yml - with: - environment_name: staging - client_config: staging - cloud_sql_instance_name: kg-staging - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - CONTAINER_REGISTRY_USERNAME: ${{ secrets.AZURE_CR_USERNAME }} - CONTAINER_REGISTRY_PASSWORD: ${{ secrets.AZURE_CR_PASSWORD }} - GCP_CREDENTIALS: ${{ secrets.GCE_SA_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/deployment-gcp.yml b/.github/workflows/deployment-gcp.yml deleted file mode 100644 index a5ab0c6ce9..0000000000 --- a/.github/workflows/deployment-gcp.yml +++ /dev/null @@ -1,159 +0,0 @@ -name: Lifelike GCP deployment - -on: - workflow_call: - inputs: - environment_name: - description: Environment nme (prod, staging, qa or demo) - required: true - type: string - client_config: - description: Client Runtime configuration preset - required: true - default: production - type: string - container_registry: - description: Container registry name - required: false - default: lifelike.azurecr.io - type: string - cloud_sql_instance_name: - description: Google Cloud SQL instance name - required: true - type: string - cloud_sql_force_backup: - description: Backup before deploying even if no migrations need to be run - required: false - default: false - type: boolean - secrets: - CONTAINER_REGISTRY_USERNAME: - required: true - CONTAINER_REGISTRY_PASSWORD: - required: true - VAULT_PASSWORD: - required: true - SSH_KEY: - required: true - GCP_CREDENTIALS: - required: true - INFRA_PAT: - required: true - -jobs: - # ------------------------------------------------------------- - # JOB: Build Docker images - # ------------------------------------------------------------- - build: - name: Build - runs-on: ubuntu-latest - strategy: - matrix: - include: - - image: kg-webserver - path: ./client - build_extra_args: --build-arg ANGULAR_CONFIG=${{ inputs.client_config }} --build-arg CLIENT_VERSION=${{ github.sha }} - - image: kg-appserver - path: ./appserver - - image: kg-cache-service - path: ./cache-invalidator - - image: kg-statistical-enrichment - path: ./statistical-enrichment - - image: filebeat - path: ./filebeat - - image: metricbeat - path: ./metricbeat - - steps: - - uses: actions/checkout@v3 - - name: Build and push ${{ matrix.image }} image - uses: whoan/docker-build-with-cache-action@v5 - with: - context: ${{ matrix.path }} - image_name: ${{ matrix.image }} - image_tag: ${{ github.sha }},${{ inputs.environment_name }},latest - build_extra_args: ${{ matrix.build_extra_args }} - registry: ${{ inputs.container_registry }} - username: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} - password: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} - dockerfile: ./Dockerfile - - # --------------------------------------------- - # JOB: Backup DB - # --------------------------------------------- - cloud-sql-backup: - name: Backup Cloud SQL instance - needs: build - outputs: - backup_id: ${{ steps.backup.outputs.backup_id }} - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Create a new Clod SQL instance backup - id: backup - uses: ./.github/actions/cloud-sql-backup - with: - gcp_credentials: "${{ secrets.GCP_CREDENTIALS }}" - cloud_sql_instance_name: "${{ inputs.cloud_sql_instance_name }}" - backup_description: "Automated backup from GitHub workflow. Run ID: ${{ github.run_id }}" - - # ------------------------------------------------------------- - # JOB: Deploy to GCP environment using Ansible playbook - # pointed by the Git submodule: /deployment - # ------------------------------------------------------------- - deploy: - name: Deploy - needs: - - build - - cloud-sql-backup - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - token: ${{ secrets.INFRA_PAT }} - submodules: recursive - - - name: Set git metadata - id: git-meta - run: | - echo ::set-output name=commit_timestamp::$(git log -1 --format=%cI) - echo ::set-output name=build_number::$(git rev-list --count HEAD) - echo ::set-output name=build_version::$(echo "${GITHUB_REF#refs/*/}") - - - name: Authenticate to GCP - id: auth - uses: google-github-actions/auth@v0 - with: - credentials_json: "${{ secrets.GCP_CREDENTIALS }}" - - uses: google-github-actions/setup-gcloud@v0 - - - name: Get Cloud SQL instance private IP address - id: database-host - run: | - echo ::set-output name=ip_address::$( \ - gcloud sql instances describe --format=json \ - ${{ inputs.cloud_sql_instance_name }} \ - | jq -r '.ipAddresses[] | select(.type == "PRIVATE").ipAddress') - - - name: Run Ansible deployment action - uses: ./.github/actions/ansible - with: - workspace_dir: deployment/ansible - playbook_file_path: playbooks/deploy-gcloud.yml - inventory_file_path: inventories/hosts.yml - vault_password: ${{ secrets.VAULT_PASSWORD }} - ssh_key: ${{ secrets.SSH_KEY }} - options: | - --extra-vars environment_name=${{ inputs.environment_name }} - --extra-vars client_config=${{ inputs.client_config }} - --extra-vars docker_img_hash=${{ github.sha }} - --extra-vars git_timestamp=${{ steps.git-meta.outputs.commit_timestamp }} - --extra-vars app_build_number=${{ steps.git-meta.outputs.build_number }} - --extra-vars app_version=${{ steps.git-meta.outputs.build_version }} - --extra-vars github_run_id=${{ github.run_id }} - --extra-vars postgres_host=${{ steps.database-host.outputs.ip_address }} - --user ansible - -vvvv diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index ac173f1076..0000000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Docker images - -on: - push: - branches: - - main - tags: - - v* - pull_request: - branches: - - main -env: - REGISTRY: ghcr.io - REPOSITORY: ${{ github.repository }} - -jobs: - publish-images: - name: Publish ${{ matrix.name }} Docker image - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - name: appserver - path: appserver - - name: frontend - path: client - # - name: elasticsearch - # path: docker - # file: docker/elasticsearch.Dockerfile - # - name: Grap data migrator - # path: graph-db - # image: lifelike-graph-db - - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Log in to the Container registry - uses: docker/login-action@v1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v3 - with: - images: ${{ env.REGISTRY }}/${{ env.REPOSITORY }}-${{ matrix.name }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor - - - name: Build and push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}-${{ matrix.name }} image - uses: docker/build-push-action@v2 - with: - context: ${{ matrix.path }} - file: ${{ matrix.file }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - push: true diff --git a/.github/workflows/graphdb-migrate.yml b/.github/workflows/graphdb-migrate.yml deleted file mode 100644 index de9d842f48..0000000000 --- a/.github/workflows/graphdb-migrate.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Grpah DB Migrate - -on: - workflow_dispatch: - inputs: - neo4j_host: - description: Neo4j target host - type: string - required: true - neo4j_username: - description: Neo4j username - type: string - required: true - default: neo4j - neo4j_password: - description: Neo4j password - type: string - required: true - log_level: - description: Log level - type: choice - required: true - default: info - options: - - debug - - info - - warn - - error - release_lock: - description: Release any present lock before executing - type: boolean - required: true - default: true - datafiles_prefix: - description: Prefix of the datafiles in remote storage (stage/prod) - type: choice - required: true - default: stage - options: - - stage - - prod - chunk_size: - description: Liquibase transaction chunk size - type: string - required: true - default: '2000' - changelog: - description: Path to the changelog file - type: string - required: true - default: 'lifelike-graph/changelog-master.xml' - migrator_image_tag: - description: Tag of the graphdb-migrator image to use - type: string - required: true - default: latest - -jobs: - migrate: - name: Migrate Neo4j DB - runs-on: self-hosted - timeout-minutes: 360 - container: - image: ghcr.io/sbrg/lifelike-graphdb-migrator:${{ github.event.inputs.migrator_image_tag }} - options: --user root - env: - NEO4J_HOST: ${{ github.event.inputs.neo4j_host }} - NEO4J_USERNAME: ${{ github.event.inputs.neo4j_username }} - NEO4J_PASSWORD: ${{ github.event.inputs.neo4j_password }} - LOG_LEVEL: ${{ github.event.inputs.log_level }} - CHANGELOG_FILE: ${{ github.event.inputs.changelog }} - DATAFILES_PREFIX: ${{ github.event.inputs.datafiles_prefix }} - AZURE_ACCOUNT_STORAGE_KEY: ${{ secrets.AZURE_ACCOUNT_STORAGE_KEY }} - AZURE_ACCOUNT_STORAGE_NAME: ${{ secrets.AZURE_ACCOUNT_STORAGE_NAME }} - CHUNK_SIZE: ${{ github.event.inputs.chunk_size }} - steps: - - uses: actions/checkout@v2 - - name: Copy changelog files - run: cp -rp graph-db/changelog/* /liquibase/changelog/ - - name: Release previous lock - if: ${{ github.event.inputs.release_lock }} - run: /docker-entrypoint.sh releaseLocks - - name: Run Liquibase migrations - run: /docker-entrypoint.sh update diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b100f06f55..05d76760b0 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -21,17 +21,6 @@ jobs: - uses: actions/checkout@v3 - - name: Build appserver image - uses: whoan/docker-build-with-cache-action@v5 - with: - username: ${{ secrets.AZURE_CR_USERNAME }} - password: ${{ secrets.AZURE_CR_PASSWORD }} - registry: lifelike.azurecr.io - image_name: kg-appserver - image_tag: ${{ github.sha }} - context: ./appserver - dockerfile: ./Dockerfile - - name: Create environment variable to pass in GitHub hash for Docker Compose run: echo "GITHUB_HASH=${{ github.sha }}" >> .env diff --git a/.github/workflows/traefik-az.yml b/.github/workflows/traefik-az.yml deleted file mode 100644 index 2eca1579eb..0000000000 --- a/.github/workflows/traefik-az.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Azure Traefik deployment - -on: - workflow_dispatch: - push: - tags: [traefik-az] - branches: [traefik-az/**] - -jobs: - call-deployment-gcp: - uses: ./.github/workflows/traefik.yml - with: - playbook_path: playbooks/proxy-azure.yml - inventory_path: inventories/hosts-az.yml - secrets: - VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT }} - SSH_KEY: ${{ secrets.ANSIBLE_PRIVATE_SSH_KEY }} - INFRA_PAT: ${{ secrets.INFRA_PAT }} diff --git a/.github/workflows/traefik.yml b/.github/workflows/traefik.yml deleted file mode 100644 index e5c6367820..0000000000 --- a/.github/workflows/traefik.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Lifelike Traefik deployment - -on: - workflow_call: - inputs: - playbook_path: - description: File path to Ansible playbook - required: true - type: string - inventory_path: - description: File path to Ansible inventory - required: true - type: string - secrets: - VAULT_PASSWORD: - required: true - SSH_KEY: - required: true - INFRA_PAT: - required: true - -jobs: - deploy: - name: Deploy - needs: - - build - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - token: ${{ secrets.INFRA_PAT }} - submodules: recursive - - - name: Run Ansible deployment action - uses: ./.github/actions/ansible - with: - workspace_dir: deployment/ansible - playbook_file_path: ${{ inputs.playbook_path }} - inventory_file_path: ${{ inputs.inventory_path }} - vault_password: ${{ secrets.VAULT_PASSWORD }} - ssh_key: ${{ secrets.SSH_KEY }} - options: | - --user ansible - --verbose diff --git a/.gitignore b/.gitignore index 62a9d48bb5..1147a0ce50 100755 --- a/.gitignore +++ b/.gitignore @@ -88,4 +88,4 @@ arangodb/data/* arangodb/apps/* # Arango seed data -arangodb/bin/seed_data \ No newline at end of file +arangodb/bin/seed_data diff --git a/.gitmodules b/.gitmodules index 98bab4898e..e69de29bb2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,13 +0,0 @@ -[submodule "lifelike-oss"] - path = lifelike-oss - url = https://github.com/SBRG/lifelike -[submodule "keycloak"] - path = keycloak - url = https://github.com/SBRG/lifelike-keycloak -[submodule "website"] - path = website - url = https://github.com/SBRG/lifelike-website -[submodule "deployment"] - path = deployment - url = git@github.com:SBRG/lifelike-infra.git - branch = ansible diff --git a/README.md b/README.md index f5abb35137..29cbaf7fff 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ Lifelike is a distributed system comprised of the following components: ### Backing services - **PostgreSQL** as a RDBMS. -- **Neo4j** as a graph database. +- **ArangoDB** as a graph database. - **Elasticsearch** as a full-text search engine. - **Redis** as a key-value cache store. - **PDFParser** as a document parsing library. diff --git a/appserver/Dockerfile b/appserver/Dockerfile index 66b2431483..7b1380edd7 100644 --- a/appserver/Dockerfile +++ b/appserver/Dockerfile @@ -1,7 +1,7 @@ # ======================================== # Base image # ======================================== -FROM python:3.10-slim as base +FROM python:3.9-slim as base ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 @@ -82,12 +82,12 @@ ENV POSTGRES_USER=postgres ENV POSTGRES_PASSWORD=postgres ENV POSTGRES_DB=postgres -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_DATABASE=neo4j -ENV NEO4J_SCHEME=bolt +# ArangoDB configuration +ENV ARANGODB_HOST=arangodb +ENV ARANGODB_PORT=7687 +ENV ARANGODB_AUTH=arangodb/password +ENV ARANGODB_DATABASE=arangodb +ENV ARANGODB_SCHEME=bolt # Elasticsearch configuration ENV ELASTICSEARCH_URL=http://elasticsearch:9200 @@ -129,5 +129,5 @@ EXPOSE $PORT HEALTHCHECK --start-period=30s \ CMD curl -f localhost:$PORT/meta || exit 1 -RUN chmod +x bin/docker-entrypoint.sh -ENTRYPOINT ["bin/docker-entrypoint.sh"] +RUN chmod +x bin/startup.sh +ENTRYPOINT ["bin/startup.sh"] diff --git a/appserver/Pipfile b/appserver/Pipfile index b1286c1a99..6b16e584b0 100644 --- a/appserver/Pipfile +++ b/appserver/Pipfile @@ -53,7 +53,6 @@ paramiko = "==2.7.2" google-cloud-storage = "==1.36.1" fastjsonschema = "==2.15.0" marshmallow-dataclass = "==8.3.1" -marshmallow-enum = "==1.5.1" deepdiff = "==5.2.3" timeflake = "==0.3.3" scipy = "==1.6.1" @@ -61,7 +60,6 @@ statsmodels = "==0.12.2" sqlalchemy = "==1.3.23" azure-storage-file = "==2.1.0" azure-storage-blob = "==12.8.0" -neo4j = "==4.2.1" python-magic = "==0.4.22" httpretty = "==1.0.5" sendgrid = "==6.7.0" @@ -79,6 +77,7 @@ openai = "*" types-cachetools = "*" mypy = "==0.981" pyyaml = "==6.0.1" +marshmallow-enum = "*" [requires] python_version = "3.9" diff --git a/appserver/Pipfile.lock b/appserver/Pipfile.lock index 7647f4ee56..0280160e85 100644 --- a/appserver/Pipfile.lock +++ b/appserver/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e8e18968eada4f4eba2a7ea35293b9f680b6e0a10413292556849adaa5ea1a61" + "sha256": "723e0fba23007871efc048ff1ab5a6333defdd4688df64ab94c5cca1c6e8bb34" }, "pipfile-spec": 6, "requires": { @@ -16,138 +16,45 @@ ] }, "default": { - "aiohttp": { - "hashes": [ - "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14", - "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391", - "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2", - "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e", - "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9", - "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd", - "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4", - "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b", - "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41", - "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567", - "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275", - "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54", - "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a", - "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef", - "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99", - "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da", - "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4", - "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e", - "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699", - "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04", - "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719", - "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131", - "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e", - "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f", - "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd", - "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f", - "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e", - "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1", - "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed", - "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4", - "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1", - "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777", - "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531", - "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b", - "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab", - "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8", - "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074", - "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc", - "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643", - "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01", - "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36", - "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24", - "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654", - "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d", - "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241", - "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51", - "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f", - "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2", - "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15", - "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf", - "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b", - "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71", - "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05", - "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52", - "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3", - "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6", - "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a", - "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519", - "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a", - "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333", - "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6", - "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d", - "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57", - "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c", - "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9", - "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea", - "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332", - "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5", - "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622", - "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71", - "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb", - "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a", - "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff", - "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945", - "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480", - "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6", - "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9", - "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd", - "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f", - "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a", - "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a", - "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949", - "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc", - "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75", - "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f", - "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10", - "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f" + "alembic": { + "hashes": [ + "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43", + "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595" ], - "markers": "python_version >= '3.6'", - "version": "==3.8.4" + "markers": "python_version >= '3.8'", + "version": "==1.13.1" }, - "aiosignal": { + "annotated-types": { "hashes": [ - "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", - "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" + "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43", + "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d" ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "markers": "python_version >= '3.8'", + "version": "==0.6.0" }, - "alembic": { + "anyio": { "hashes": [ - "sha256:6880dec4f28dd7bd999d2ed13fbe7c9d4337700a44d11a524c0ce0c59aaf0dbd", - "sha256:e8a6ff9f3b1887e1fed68bfb8fb9a000d8f61c21bdcc85b67bb9f87fcbc4fce3" + "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", + "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" ], - "markers": "python_version >= '3.7'", - "version": "==1.9.2" + "markers": "python_version >= '3.8'", + "version": "==4.3.0" }, "apispec": { "hashes": [ - "sha256:d97f0ae9c65133185b9ed9c5be1a434eb85627dfa33c4c53cabda122256c1b67", - "sha256:e76d80b739edef4be213092a6384ad7fd933ba7d64f6d5a0aff8d4da1bef7887" + "sha256:b5b22f5dba6cc69bd90e1075de20ae3d27b310a6250c66b0271aa50615eee72d", + "sha256:c0846f8eaa5119c46b2ecfe9bc24ed19dba8845f8655d00b51ddd296a10ea4cb" ], - "markers": "python_version >= '3.7'", - "version": "==6.0.2" + "markers": "python_version >= '3.8'", + "version": "==6.6.0" }, "appnope": { "hashes": [ - "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24", - "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e" + "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", + "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" ], "markers": "sys_platform == 'darwin'", - "version": "==0.1.3" - }, - "async-timeout": { - "hashes": [ - "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", - "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" - ], - "markers": "python_version >= '3.6'", - "version": "==4.0.2" + "version": "==0.1.4" }, "attrs": { "hashes": [ @@ -155,6 +62,7 @@ "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "azure-common": { @@ -166,11 +74,11 @@ }, "azure-core": { "hashes": [ - "sha256:986bfd8687889782d79481d4c5d0af04ab4a18ca2f210364804a88e4eaa1586a", - "sha256:df306e6e4abc145610ca6744aef943129a6fd7a11977e56731f69ac0e00724f9" + "sha256:26273a254131f84269e8ea4464f3560c731f29c0c1f69ac99010845f239c1a8f", + "sha256:7c5ee397e48f281ec4dd773d67a0a47a0962ed6fa833036057f9ea067f688e74" ], "markers": "python_version >= '3.7'", - "version": "==1.26.2" + "version": "==1.30.1" }, "azure-storage-blob": { "hashes": [ @@ -225,30 +133,31 @@ "sha256:ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==3.1.7" }, "beautifulsoup4": { "hashes": [ - "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39", - "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106" + "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", + "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed" ], "markers": "python_full_version >= '3.6.0'", - "version": "==4.11.2" + "version": "==4.12.3" }, "bioc": { "hashes": [ - "sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10", - "sha256:a63dcc76a791b7db58d273422791e9909d0524ddd26e332be5467d7fa2e81a0a" + "sha256:278a4f6956b08c1297bfeae05958f5482a569104dd1a50c6abede17dfcfdbe10" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==1.3.7" }, "blinker": { "hashes": [ - "sha256:1eb563df6fdbc39eeddc177d953203f99f097e9bf0e2b8f9f3cf18b6ca425e36", - "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462" + "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", + "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" ], - "version": "==1.5" + "version": "==1.7.0" }, "cachetools": { "hashes": [ @@ -260,80 +169,69 @@ }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2024.2.2" }, "cffi": { "hashes": [ - "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", - "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", - "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", - "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", - "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", - "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", - "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", - "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", - "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", - "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", - "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", - "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", - "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", - "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", - "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", - "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", - "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", - "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", - "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", - "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", - "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", - "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", - "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", - "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", - "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", - "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", - "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", - "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", - "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", - "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", - "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", - "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", - "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", - "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", - "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", - "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", - "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", - "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", - "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", - "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", - "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", - "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", - "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", - "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", - "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", - "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", - "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", - "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", - "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", - "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", - "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", - "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", - "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", - "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", - "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", - "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", - "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", - "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", - "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", - "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", - "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", - "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", - "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", - "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" - ], - "version": "==1.15.1" + "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" }, "chardet": { "hashes": [ @@ -343,123 +241,51 @@ "markers": "python_version >= '3.1'", "version": "==4.0.0" }, - "charset-normalizer": { - "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.1.0" - }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.7" }, "cryptography": { "hashes": [ - "sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b", - "sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f", - "sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190", - "sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f", - "sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f", - "sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb", - "sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c", - "sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773", - "sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72", - "sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8", - "sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717", - "sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9", - "sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856", - "sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96", - "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288", - "sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39", - "sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e", - "sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce", - "sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1", - "sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de", - "sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df", - "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf", - "sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458" + "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", + "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", + "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", + "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", + "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", + "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", + "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", + "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", + "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", + "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", + "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", + "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", + "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", + "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", + "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", + "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", + "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", + "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", + "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", + "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", + "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", + "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", + "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", + "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", + "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", + "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", + "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", + "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", + "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", + "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", + "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", + "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" ], - "markers": "python_version >= '3.6'", - "version": "==39.0.0" + "markers": "python_version >= '3.7'", + "version": "==42.0.5" }, "decorator": { "hashes": [ @@ -475,34 +301,43 @@ "sha256:ae2cb98353309f93fbfdda4d77adb08fb303314d836bb6eac3d02ed71a10b40e" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==5.2.3" }, + "distro": { + "hashes": [ + "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", + "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2" + ], + "markers": "python_version >= '3.6'", + "version": "==1.9.0" + }, "docutils": { "hashes": [ - "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", - "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" + "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", + "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" ], "markers": "python_version >= '3.7'", - "version": "==0.19" + "version": "==0.20.1" }, "ecs-logging": { "hashes": [ - "sha256:34567bda91534a480f12117c30e1aac78489cc9a0ace172014d80f3d1e29c85b", - "sha256:543ed7b634901aee465fddf70f52b6fdbd35e825e7cbcae2e664d7dfdff2f859" + "sha256:02581a56b7fc6cbae2de121a4a398ba3bd73d7bb2d67cd029a8a03df0b144098", + "sha256:222cc158d4331157d128bc903629010f7724eab8ba4b642efbffd0cb482f4cde" ], "markers": "python_version >= '3.6'", - "version": "==2.0.2" + "version": "==2.1.0" }, "elastic-apm": { "extras": [ "flask" ], "hashes": [ - "sha256:815ee9838f6db2db3ee83a31b8ff36ff291aac03c6ed24534280ced45a9cb3dc", - "sha256:d672e51ef2dffa1a08d814e6b47d8d17144256d887dbc1734b2b9ce298f1208b" + "sha256:1861183c5ba3b46df66e111ba27877dbe8aaa8842777c1f0627c7fb1b65ed249", + "sha256:7a5e430658196c9ebcf4530e780268b0dfe2ba2c25041549ee54d9fb8650c418" ], - "index": "pypi", - "version": "==6.13.2" + "markers": "python_version >= '3.6' and python_version < '4'", + "version": "==6.21.4.post8347027212" }, "elasticsearch": { "hashes": [ @@ -510,6 +345,7 @@ "sha256:f4bb05cfe55cf369bdcb4d86d0129d39d66a91fd9517b13cd4e4231fbfcf5c81" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'", "version": "==7.6.0" }, "et-xmlfile": { @@ -520,6 +356,14 @@ "markers": "python_version >= '3.6'", "version": "==1.1.0" }, + "exceptiongroup": { + "hashes": [ + "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", + "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68" + ], + "markers": "python_version < '3.11'", + "version": "==1.2.0" + }, "fastjsonschema": { "hashes": [ "sha256:b3da206676f8b4906debf6a17b650b858c92cb304cbe0c8aa81799bde6a6b858", @@ -530,11 +374,11 @@ }, "filelock": { "hashes": [ - "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de", - "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d" + "sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb", + "sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546" ], - "markers": "python_version >= '3.7'", - "version": "==3.9.0" + "markers": "python_version >= '3.8'", + "version": "==3.13.3" }, "flask": { "hashes": [ @@ -542,6 +386,7 @@ "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.1.2" }, "flask-apispec": { @@ -586,9 +431,7 @@ }, "flask-migrate": { "hashes": [ - "sha256:4dc4a5cce8cbbb06b8dc963fd86cf8136bd7d875aabe2d840302ea739b243732", "sha256:8626af845e6071ef80c70b0dc16d373f761c981f0ad61bb143a529cab649e725", - "sha256:a69d508c2e09d289f6e55a417b3b8c7bfe70e640f53d2d9deb0d056a384f37ee", "sha256:c1601dfd46b9204233935e5d73473cd7fa959db7a4b0e894c7aa7a9e8aeebf0e" ], "index": "pypi", @@ -600,88 +443,9 @@ "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.4" }, - "frozenlist": { - "hashes": [ - "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c", - "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f", - "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a", - "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784", - "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27", - "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d", - "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3", - "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678", - "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a", - "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483", - "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8", - "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf", - "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99", - "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c", - "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48", - "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5", - "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56", - "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e", - "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1", - "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401", - "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4", - "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e", - "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649", - "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a", - "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d", - "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0", - "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6", - "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d", - "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b", - "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6", - "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf", - "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef", - "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7", - "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842", - "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba", - "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420", - "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b", - "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d", - "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332", - "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936", - "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816", - "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91", - "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420", - "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448", - "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411", - "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4", - "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32", - "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b", - "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0", - "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530", - "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669", - "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7", - "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1", - "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5", - "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce", - "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4", - "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e", - "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2", - "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d", - "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9", - "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642", - "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0", - "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703", - "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb", - "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1", - "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13", - "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab", - "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38", - "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb", - "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb", - "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81", - "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8", - "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd", - "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.3" - }, "gdown": { "hashes": [ "sha256:5ce3db0aeda54f46caacb2df86f31c3e3ecd17c355689e6456d85fb528ba9749", @@ -720,6 +484,7 @@ "sha256:e3227abe57122370df02f00b8a6d78da6d41a0df4e6864b7f65a3a4ae673a8a7" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.36.1" }, "google-crc32c": { @@ -806,11 +571,11 @@ }, "googleapis-common-protos": { "hashes": [ - "sha256:c727251ec025947d545184ba17e3578840fc3a24a0516a020479edab660457df", - "sha256:ca3befcd4580dab6ad49356b46bf165bb68ff4b32389f028f1abd7c10ab9519a" + "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e", + "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632" ], "markers": "python_version >= '3.7'", - "version": "==1.58.0" + "version": "==1.63.0" }, "graphviz": { "hashes": [ @@ -818,6 +583,7 @@ "sha256:60acbeee346e8c14555821eab57dbf68a169e6c10bce40e83c1bf44f63a62a01" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.13.2" }, "gunicorn": { @@ -826,15 +592,41 @@ "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c" ], "index": "pypi", + "markers": "python_version >= '3.4'", "version": "==20.0.4" }, + "h11": { + "hashes": [ + "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", + "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" + }, + "httpcore": { + "hashes": [ + "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", + "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" + ], + "markers": "python_version >= '3.8'", + "version": "==1.0.5" + }, "httpretty": { "hashes": [ "sha256:e53c927c4d3d781a0761727f1edfad64abef94e828718e12b672a678a8b3e0b5" ], "index": "pypi", + "markers": "python_version >= '3'", "version": "==1.0.5" }, + "httpx": { + "hashes": [ + "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", + "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5" + ], + "markers": "python_version >= '3.8'", + "version": "==0.27.0" + }, "idna": { "hashes": [ "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", @@ -863,6 +655,7 @@ "sha256:cbb2ef3d5961d44e6a963b9817d4ea4e1fa2eb589c371a470fed14d8d40cbd6a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==7.19.0" }, "isodate": { @@ -878,15 +671,16 @@ "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.0.1" }, "jedi": { "hashes": [ - "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e", - "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612" + "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", + "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" ], "markers": "python_version >= '3.6'", - "version": "==0.18.2" + "version": "==0.19.1" }, "jinja2": { "hashes": [ @@ -894,15 +688,16 @@ "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.0.3" }, "jsonlines": { "hashes": [ - "sha256:2579cb488d96f815b0eb81629e3e6b0332da0962a18fa3532958f7ba14a5c37f", - "sha256:632f5e38f93dfcb1ac8c4e09780b92af3a55f38f26e7c47ae85109d420b6ad39" + "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74", + "sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55" ], - "markers": "python_version >= '3.6'", - "version": "==3.1.0" + "markers": "python_version >= '3.8'", + "version": "==4.0.0" }, "lmdb": { "hashes": [ @@ -934,158 +729,245 @@ }, "lxml": { "hashes": [ - "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7", - "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726", - "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03", - "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140", - "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a", - "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05", - "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03", - "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419", - "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", - "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e", - "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67", - "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50", - "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894", - "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf", - "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947", - "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1", - "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd", - "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3", - "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92", - "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3", - "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457", - "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74", - "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf", - "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1", - "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4", - "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975", - "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5", - "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe", - "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7", - "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1", - "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2", - "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409", - "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f", - "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f", - "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5", - "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24", - "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e", - "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4", - "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a", - "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c", - "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de", - "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f", - "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b", - "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5", - "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7", - "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a", - "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c", - "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9", - "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e", - "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab", - "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941", - "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5", - "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45", - "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7", - "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892", - "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746", - "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c", - "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53", - "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe", - "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184", - "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38", - "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df", - "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9", - "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b", - "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2", - "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0", - "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda", - "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b", - "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5", - "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380", - "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33", - "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8", - "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1", - "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889", - "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9", - "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f", - "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c" + "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04", + "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0", + "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739", + "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a", + "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1", + "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218", + "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9", + "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188", + "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138", + "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585", + "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637", + "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe", + "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d", + "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1", + "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095", + "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9", + "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81", + "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57", + "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536", + "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a", + "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052", + "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01", + "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98", + "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433", + "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1", + "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f", + "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4", + "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b", + "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6", + "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8", + "sha256:3e183c6e3298a2ed5af9d7a356ea823bccaab4ec2349dc9ed83999fd289d14d5", + "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306", + "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5", + "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f", + "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4", + "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be", + "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919", + "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af", + "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66", + "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1", + "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af", + "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec", + "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b", + "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289", + "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a", + "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d", + "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102", + "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9", + "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc", + "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45", + "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa", + "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a", + "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c", + "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461", + "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708", + "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca", + "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd", + "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913", + "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da", + "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0", + "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5", + "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5", + "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96", + "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41", + "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3", + "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456", + "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c", + "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867", + "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0", + "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213", + "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619", + "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240", + "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c", + "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377", + "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b", + "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c", + "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54", + "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b", + "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53", + "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029", + "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6", + "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885", + "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94", + "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134", + "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8", + "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9", + "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863", + "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b", + "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806", + "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11", + "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9", + "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817", + "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95", + "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8", + "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc", + "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47", + "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b", + "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0", + "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a", + "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f", + "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56", + "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef", + "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851", + "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7", + "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62", + "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4", + "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a", + "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c", + "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533", + "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e", + "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a", + "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3", + "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b", + "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4", + "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0", + "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d", + "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3", + "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5", + "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534", + "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4", + "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144", + "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd", + "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd", + "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860", + "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704", + "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8", + "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d", + "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9", + "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f", + "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad", + "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc", + "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510", + "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937", + "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a", + "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460", + "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85", + "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86", + "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0", + "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246", + "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7", + "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa", + "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08", + "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270", + "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a", + "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169", + "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e", + "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75", + "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd", + "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354", + "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c", + "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1", + "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb", + "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f", + "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.9.2" + "markers": "python_version >= '3.6'", + "version": "==5.2.1" }, "mako": { "hashes": [ - "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", - "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" + "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e", + "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c" ], - "markers": "python_version >= '3.7'", - "version": "==1.2.4" + "markers": "python_version >= '3.8'", + "version": "==1.3.2" }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.5" }, "marshmallow": { "hashes": [ - "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78", - "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b" + "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3", + "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633" ], - "markers": "python_version >= '3'", - "version": "==3.19.0" + "markers": "python_version >= '3.8'", + "version": "==3.21.1" }, "marshmallow-dataclass": { "hashes": [ @@ -1093,6 +975,7 @@ "sha256:835e6aef758f9b107ab9623d37e0ebbd6e586fb8f4172281a47dd90a69ceda38" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==8.3.1" }, "marshmallow-enum": { @@ -1109,6 +992,7 @@ "sha256:dde9e20bcb710e9e59f765a38e3d6d17f1b2d6b4320cbdc2cea0f6b57f70d08c" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==0.22.3" }, "memory-profiler": { @@ -1116,6 +1000,7 @@ "sha256:01385ac0fec944fcf7969814ec4406c6d8a9c66c079d09276723c5a7680f44e5" ], "index": "pypi", + "markers": "python_version >= '3.4'", "version": "==0.58.0" }, "msrest": { @@ -1126,86 +1011,6 @@ "markers": "python_version >= '3.6'", "version": "==0.7.1" }, - "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": { "hashes": [ "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", @@ -1234,55 +1039,58 @@ "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==0.981" }, "mypy-extensions": { "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "neo4j": { - "hashes": [ - "sha256:b6c49fbd60426e268ed4afbd414766444fe70aee1ac0376a0c871d75526b8251" + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" ], - "index": "pypi", - "version": "==4.2.1" + "markers": "python_version >= '3.5'", + "version": "==1.0.0" }, "numpy": { "hashes": [ - "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9", - "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398", - "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7", - "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2", - "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954", - "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6", - "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032", - "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36", - "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c", - "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8", - "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7", - "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f", - "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700", - "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086", - "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7", - "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2", - "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9", - "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407", - "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2", - "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36", - "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566", - "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1", - "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e", - "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51", - "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1", - "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d", - "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf", - "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7" - ], - "markers": "python_version < '3.10'", - "version": "==1.24.1" + "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", + "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", + "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", + "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", + "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", + "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", + "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", + "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", + "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", + "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", + "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", + "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", + "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", + "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", + "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", + "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", + "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", + "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", + "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", + "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", + "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", + "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", + "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", + "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", + "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", + "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", + "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", + "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", + "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", + "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", + "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", + "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", + "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", + "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", + "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", + "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" + ], + "markers": "python_version >= '3.9'", + "version": "==1.26.4" }, "oauthlib": { "hashes": [ @@ -1294,11 +1102,12 @@ }, "openai": { "hashes": [ - "sha256:2483095c7db1eee274cebac79e315a986c4e55207bb4fa7b82d185b3a2ed9536", - "sha256:e0a7c2f7da26bdbe5354b03c6d4b82a2f34bd4458c7a17ae1a7092c3e397e03c" + "sha256:58922c785d167458b46e3c76e7b1bc2306f313ee9b71791e84cbf590abe160f2", + "sha256:77ef3db6110071f7154859e234250fb945a36554207a30a4491092eadb73fcb5" ], "index": "pypi", - "version": "==0.27.8" + "markers": "python_full_version >= '3.7.1'", + "version": "==1.16.1" }, "openpyxl": { "hashes": [ @@ -1306,6 +1115,7 @@ "sha256:6456a3b472e1ef0facb1129f3c6ef00713cebf62e736cd7a75bcc3247432f251" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.0.7" }, "ordered-set": { @@ -1317,59 +1127,44 @@ }, "packaging": { "hashes": [ - "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", - "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.0" + "version": "==24.0" }, "pandas": { "hashes": [ - "sha256:02f1e8f71cd994ed7fcb9a35b6ddddeb4314822a0e09a9c5b2d278f8cb5d4096", - "sha256:13f75fb18486759da3ff40f5345d9dd20e7d78f2a39c5884d013456cec9876f0", "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813", "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792", - "sha256:35b670b0abcfed7cad76f2834041dcf7ae47fd9b22b63622d67cdc933d79f453", "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406", "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373", "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328", - "sha256:4c73f373b0800eb3062ffd13d4a7a2a6d522792fa6eb204d67a4fad0a40f03dc", "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996", "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf", - "sha256:5759edf0b686b6f25a5d4a447ea588983a33afc8a0081a0954184a4a87fd0dd7", - "sha256:5a7cf6044467c1356b2b49ef69e50bf4d231e773c3ca0558807cdba56b76820b", "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6", "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7", "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc", - "sha256:69c5d920a0b2a9838e677f78f4dde506b95ea8e4d30da25859db6469ded84fa8", "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1", "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23", "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a", - "sha256:8778a5cc5a8437a561e3276b85367412e10ae9fff07db1eed986e427d9a674f8", "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51", "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572", "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31", - "sha256:9871ef5ee17f388f1cb35f76dc6106d40cb8165c562d573470672f4cdefa59ef", - "sha256:9c31d52f1a7dd2bb4681d9f62646c7aa554f19e8e9addc17e8b1b20011d7522d", "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5", "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a", - "sha256:ab8173a8efe5418bbe50e43f321994ac6673afc5c7c4839014cf6401bbdd0705", - "sha256:ae961f1f0e270f1e4e2273f6a539b2ea33248e0e3a11ffb479d757918a5e03a9", - "sha256:b3c4f93fcb6e97d993bf87cdd917883b7dab7d20c627699f360a8fb49e9e0b91", "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003", "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d", "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354", "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee", "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa", - "sha256:c9410ce8a3dee77653bc0684cfa1535a7f9c291663bd7ad79e39f5ab58f67ab3", "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0", "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9", "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae", - "sha256:f69e0f7b7c09f1f612b1f8f59e2df72faa8a6b41c5a436dde5b615aaf948f107", - "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc", - "sha256:faa42a78d1350b02a7d2f0dbe3c80791cf785663d6997891549d0f86dc49125e" + "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==1.5.3" }, "paramiko": { @@ -1390,10 +1185,10 @@ }, "patsy": { "hashes": [ - "sha256:7eb5349754ed6aa982af81f636479b1b8db9d5b1a6e957a6016ec0534b5c86b7", - "sha256:bdc18001875e319bc91c812c1eb6a10be4bb13cb81eb763f466179dca3b67277" + "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6", + "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb" ], - "version": "==0.5.3" + "version": "==0.5.6" }, "pdfminer-six": { "hashes": [ @@ -1401,15 +1196,16 @@ "sha256:f5ab6aae4999c1460aa569c716cde75c1585e3f4f2e3fcaf6c950696937d1741" ], "index": "pypi", + "markers": "python_version >= '3.4'", "version": "==20200402" }, "pexpect": { "hashes": [ - "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", - "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", + "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" ], "markers": "sys_platform != 'win32'", - "version": "==4.8.0" + "version": "==4.9.0" }, "pickleshare": { "hashes": [ @@ -1461,55 +1257,55 @@ "sha256:ff04c373477723430dce2e9d024c708a047d44cf17166bf16e604b379bf0ca14" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==8.3.1" }, "prompt-toolkit": { "hashes": [ - "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63", - "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305" + "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d", + "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6" ], - "markers": "python_full_version >= '3.6.2'", - "version": "==3.0.36" + "markers": "python_full_version >= '3.7.0'", + "version": "==3.0.43" }, "protobuf": { "hashes": [ - "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30", - "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b", - "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc", - "sha256:299ea899484ee6f44604deb71f424234f654606b983cb496ea2a53e3c63ab791", - "sha256:3d164928ff0727d97022957c2b849250ca0e64777ee31efd7d6de2e07c494717", - "sha256:6ab80df09e3208f742c98443b6166bcb70d65f52cfeb67357d52032ea1ae9bec", - "sha256:78a28c9fa223998472886c77042e9b9afb6fe4242bd2a2a5aced88e3f4422aa7", - "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab", - "sha256:89f9149e4a0169cddfc44c74f230d7743002e3aa0b9472d8c28f0388102fc4c2", - "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5", - "sha256:b135410244ebe777db80298297a97fbb4c862c881b4403b71bac9d4107d61fd1", - "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462", - "sha256:d1736130bce8cf131ac7957fa26880ca19227d4ad68b4888b3be0dea1f95df97", - "sha256:f45460f9ee70a0ec1b6694c6e4e348ad2019275680bd68a1d9314b8c7e01e574" - ], - "markers": "python_version >= '3.7'", - "version": "==4.21.12" + "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4", + "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8", + "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c", + "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d", + "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4", + "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa", + "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c", + "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019", + "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", + "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c", + "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2" + ], + "markers": "python_version >= '3.8'", + "version": "==4.25.3" }, "psutil": { "hashes": [ - "sha256:149555f59a69b33f056ba1c4eb22bb7bf24332ce631c44a319cec09f876aaeff", - "sha256:16653106f3b59386ffe10e0bad3bb6299e169d5327d3f187614b1cb8f24cf2e1", - "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62", - "sha256:3ff89f9b835100a825b14c2808a106b6fdcc4b15483141482a12c725e7f78549", - "sha256:54c0d3d8e0078b7666984e11b12b88af2db11d11249a8ac8920dd5ef68a66e08", - "sha256:54d5b184728298f2ca8567bf83c422b706200bcbbfafdc06718264f9393cfeb7", - "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e", - "sha256:68908971daf802203f3d37e78d3f8831b6d1014864d7a85937941bb35f09aefe", - "sha256:6b92c532979bafc2df23ddc785ed116fced1f492ad90a6830cf24f4d1ea27d24", - "sha256:852dd5d9f8a47169fe62fd4a971aa07859476c2ba22c2254d4a1baa4e10b95ad", - "sha256:9120cd39dca5c5e1c54b59a41d205023d436799b1c8c4d3ff71af18535728e94", - "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8", - "sha256:efeae04f9516907be44904cc7ce08defb6b665128992a56957abc9b61dca94b7", - "sha256:fd8522436a6ada7b4aad6638662966de0d61d241cb821239b2ae7013d41a43d4" + "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d", + "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73", + "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8", + "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2", + "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e", + "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36", + "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7", + "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c", + "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee", + "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421", + "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf", + "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81", + "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0", + "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631", + "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4", + "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==5.9.4" + "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.8" }, "psycopg2-binary": { "hashes": [ @@ -1517,18 +1313,13 @@ "sha256:01ad49d68dd8c5362e4bfb4158f2896dc6e0c02e87b8a3770fc003459f1a4425", "sha256:024030b13bdcbd53d8a93891a2cf07719715724fc9fee40243f3bd78b4264b8f", "sha256:02551647542f2bf89073d129c73c05a25c372fc0a49aa50e0de65c3c143d8bd0", - "sha256:040234f8a4a8dfd692662a8308d78f63f31a97e1c42d2480e5e6810c48966a29", "sha256:043a9fd45a03858ff72364b4b75090679bd875ee44df9c0613dc862ca6b98460", "sha256:05b3d479425e047c848b9782cd7aac9c6727ce23181eb9647baf64ffdfc3da41", "sha256:0775d6252ccb22b15da3b5d7adbbf8cfe284916b14b6dc0ff503a23edb01ee85", - "sha256:086f7e89ec85a6704db51f68f0dcae432eff9300809723a6e8782c41c2f48e03", "sha256:1764546ffeaed4f9428707be61d68972eb5ede81239b46a45843e0071104d0dd", - "sha256:18ca813fdb17bc1db73fe61b196b05dd1ca2165b884dd5ec5568877cabf9b039", - "sha256:19dc39616850342a2a6db70559af55b22955f86667b5f652f40c0e99253d9881", "sha256:1e491e6489a6cb1d079df8eaa15957c277fdedb102b6a68cfbf40c4994412fd0", "sha256:212757ffcecb3e1a5338d4e6761bf9c04f750e7d027117e74aa3cd8a75bb6fbd", "sha256:215d6bf7e66732a514f47614f828d8c0aaac9a648c46a831955cb103473c7147", - "sha256:2166e770cb98f02ed5ee2b0b569d40db26788e0bf2ec3ae1a0d864ea6f1d8309", "sha256:25382c7d174c679ce6927c16b6fbb68b10e56ee44b1acb40671e02d29f2fce7c", "sha256:2abccab84d057723d2ca8f99ff7b619285d40da6814d50366f61f0fc385c3903", "sha256:2d964eb24c8b021623df1c93c626671420c6efadbdb8655cb2bd5e0c6fa422ba", @@ -1536,65 +1327,41 @@ "sha256:2ef892cabdccefe577088a79580301f09f2a713eb239f4f9f62b2b29cafb0577", "sha256:33e632d0885b95a8b97165899006c40e9ecdc634a529dca7b991eb7de4ece41c", "sha256:3520d7af1ebc838cc6084a3281145d5cd5bdd43fdef139e6db5af01b92596cb7", - "sha256:3a2522b1d9178575acee4adf8fd9f979f9c0449b00b4164bb63c3475ea6528ed", - "sha256:3aa773580f85a28ffdf6f862e59cb5a3cc7ef6885121f2de3fca8d6ada4dbf3b", - "sha256:3b5deaa3ee7180585a296af33e14c9b18c218d148e735c7accf78130765a47e3", "sha256:3d790f84201c3698d1bfb404c917f36e40531577a6dda02e45ba29b64d539867", "sha256:3fc33295cfccad697a97a76dec3f1e94ad848b7b163c3228c1636977966b51e2", - "sha256:407af6d7e46593415f216c7f56ba087a9a42bd6dc2ecb86028760aa45b802bd7", "sha256:422e3d43b47ac20141bc84b3d342eead8d8099a62881a501e97d15f6addabfe9", "sha256:426c2ae999135d64e6a18849a7d1ad0e1bd007277e4a8f4752eaa40a96b550ff", "sha256:46512486be6fbceef51d7660dec017394ba3e170299d1dc30928cbedebbf103a", "sha256:46850a640df62ae940e34a163f72e26aca1f88e2da79148e1862faaac985c302", "sha256:484405b883630f3e74ed32041a87456c5e0e63a8e3429aa93e8714c366d62bd1", - "sha256:4c3c09fb674401f630626310bcaf6cd6285daf0d5e4c26d6e55ca26a2734e39b", - "sha256:4c6717962247445b4f9e21c962ea61d2e884fc17df5ddf5e35863b016f8a1f03", "sha256:4e7904d1920c0c89105c0517dc7e3f5c20fb4e56ba9cdef13048db76947f1d79", - "sha256:50446fae5681fc99f87e505d4e77c9407e683ab60c555ec302f9ac9bffa61103", - "sha256:5057669b6a66aa9ca118a2a860159f0ee3acf837eda937bdd2a64f3431361a2d", "sha256:56b2957a145f816726b109ee3d4e6822c23f919a7d91af5a94593723ed667835", "sha256:5c6527c8efa5226a9e787507652dd5ba97b62d29b53c371a85cd13f957fe4d42", "sha256:5cbc554ba47ecca8cd3396ddaca85e1ecfe3e48dd57dc5e415e59551affe568e", "sha256:5d28ecdf191db558d0c07d0f16524ee9d67896edf2b7990eea800abeb23ebd61", - "sha256:5dd90c5438b4f935c9d01fcbad3620253da89d19c1f5fca9158646407ed7df35", "sha256:5fc447058d083b8c6ac076fc26b446d44f0145308465d745fba93a28c14c9e32", "sha256:63e318dbe52709ed10d516a356f22a635e07a2e34c68145484ed96a19b0c4c68", - "sha256:659c815b5b8e2a55193ede2795c1e2349b8011497310bb936da7d4745652823b", "sha256:68d81a2fe184030aa0c5c11e518292e15d342a667184d91e30644c9d533e53e1", - "sha256:69b13fdf12878b10dc6003acc8d0abf3ad93e79813fd5f3812497c1c9fb9be49", "sha256:6e63814ec71db9bdb42905c925639f319c80e7909fb76c3b84edc79dadef8d60", "sha256:6f8a9bcab7b6db2e3dbf65b214dfc795b4c6b3bb3af922901b6a67f7cb47d5f8", "sha256:70831e03bd53702c941da1a1ad36c17d825a24fbb26857b40913d58df82ec18b", "sha256:74eddec4537ab1f701a1647214734bc52cee2794df748f6ae5908e00771f180a", - "sha256:7a1cb80e35e1ccea3e11a48afe65d38744a0e0bde88795cc56a4d05b6e4f9d70", "sha256:7b3751857da3e224f5629400736a7b11e940b5da5f95fa631d86219a1beaafec", "sha256:7cf1d44e710ca3a9ce952bda2855830fe9f9017ed6259e01fcd71ea6287565f5", "sha256:7d07f552d1e412f4b4e64ce386d4c777a41da3b33f7098b6219012ba534fb2c2", "sha256:7d88db096fa19d94f433420eaaf9f3c45382da2dd014b93e4bf3215639047c16", - "sha256:7e6e3c52e6732c219c07bd97fff6c088f8df4dae3b79752ee3a817e6f32e177e", "sha256:7ee3095d02d6f38bd7d9a5358fcc9ea78fcdb7176921528dd709cc63f40184f5", - "sha256:7f42a8490c4fe854325504ce7a6e4796b207960dabb2cbafe3c3959cb00d1d7e", - "sha256:84156313f258eafff716b2961644a4483a9be44a5d43551d554844d15d4d224e", - "sha256:8578d6b8192e4c805e85f187bc530d0f52ba86c39172e61cd51f68fddd648103", - "sha256:890167d5091279a27e2505ff0e1fb273f8c48c41d35c5b92adbf4af80e6b2ed6", "sha256:902844f9c4fb19b17dfa84d9e2ca053d4a4ba265723d62ea5c9c26b38e0aa1e6", "sha256:937880290775033a743f4836aa253087b85e62784b63fd099ee725d567a48aa1", "sha256:95076399ec3b27a8f7fa1cc9a83417b1c920d55cf7a97f718a94efbb96c7f503", - "sha256:98e10634792ac0e9e7a92a76b4991b44c2325d3e7798270a808407355e7bb0a1", - "sha256:9aadff9032e967865f9778485571e93908d27dab21d0fdfdec0ca779bb6f8ad9", "sha256:9c38d3869238e9d3409239bc05bc27d6b7c99c2a460ea337d2814b35fb4fea1b", "sha256:9e32cedc389bcb76d9f24ea8a012b3cb8385ee362ea437e1d012ffaed106c17d", - "sha256:9f24f383a298a0c0f9b3113b982e21751a8ecde6615494a3f1470eb4a9d70e9e", "sha256:9ffdc51001136b699f9563b1c74cc1f8c07f66ef7219beb6417a4c8aaa896c28", "sha256:a0adef094c49f242122bb145c3c8af442070dc0e4312db17e49058c1702606d4", "sha256:a36a0e791805aa136e9cbd0ffa040d09adec8610453ee8a753f23481a0057af5", - "sha256:a73021b44813b5c84eda4a3af5826dd72356a900bac9bd9dd1f0f81ee1c22c2f", "sha256:a7e518a0911c50f60313cb9e74a169a65b5d293770db4770ebf004245f24b5c5", "sha256:af0516e1711995cb08dc19bbd05bec7dbdebf4185f68870595156718d237df3e", - "sha256:afd96845e12638d2c44d213d4810a08f4dc4a563f9a98204b7428e567014b1cd", - "sha256:b73ddf033d8cd4cc9dfed6324b1ad2a89ba52c410ef6877998422fcb9c23e3a8", "sha256:b8104f709590fff72af801e916817560dbe1698028cd0afe5a52d75ceb1fce5f", - "sha256:b8f490f5fad1767a1331df1259763b3bad7d7af12a75b950c2843ba319b2415f", "sha256:b911dfb727e247340d36ae20c4b9259e4a64013ab9888ccb3cbba69b77fd9636", "sha256:b9a794cef1d9c1772b94a72eec6da144c18e18041d294a9ab47669bc77a80c1d", "sha256:b9c33d4aef08dfecbd1736ceab8b7b3c4358bf10a0121483e5cd60d3d308cc64", @@ -1608,16 +1375,14 @@ "sha256:d4c7b3a31502184e856df1f7bbb2c3735a05a8ce0ade34c5277e1577738a5c91", "sha256:d892bfa1d023c3781a3cab8dd5af76b626c483484d782e8bd047c180db590e4c", "sha256:dbc332beaf8492b5731229a881807cd7b91b50dbbbaf7fe2faf46942eda64a24", - "sha256:dbc5cd56fff1a6152ca59445178652756f4e509f672e49ccdf3d79c1043113a4", "sha256:dc85b3777068ed30aff8242be2813038a929f2084f69e43ef869daddae50f6ee", "sha256:e59137cdb970249ae60be2a49774c6dfb015bd0403f05af1fe61862e9626642d", "sha256:e67b3c26e9b6d37b370c83aa790bbc121775c57bfb096c2e77eacca25fd0233b", "sha256:e72c91bda9880f097c8aa3601a2c0de6c708763ba8128006151f496ca9065935", - "sha256:eac8a3499754790187bb00574ab980df13e754777d346f85e0ff6df929bcd964", - "sha256:eaed1c65f461a959284649e37b5051224f4db6ebdc84e40b5e65f2986f101a08", "sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.9.5" }, "ptyprocess": { @@ -1629,87 +1394,166 @@ }, "pyasn1": { "hashes": [ - "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", - "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", - "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", - "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", - "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", - "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", - "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", - "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", - "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", - "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", - "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", - "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", - "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" - ], - "version": "==0.4.8" + "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c", + "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473" + ], + "markers": "python_version >= '3.8'", + "version": "==0.6.0" }, "pyasn1-modules": { "hashes": [ - "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", - "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", - "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", - "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", - "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", - "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", - "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", - "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", - "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", - "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", - "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", - "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", - "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" - ], - "version": "==0.2.8" + "sha256:831dbcea1b177b28c9baddf4c6d1013c24c3accd14a1873fffaa6a2e905f17b6", + "sha256:be04f15b66c206eed667e0bb5ab27e2b1855ea54a842e5037738099e8ca4ae0b" + ], + "markers": "python_version >= '3.8'", + "version": "==0.4.0" }, "pycparser": { "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.21" + "markers": "python_version >= '3.8'", + "version": "==2.22" }, "pycryptodome": { "hashes": [ - "sha256:0198fe96c22f7bc31e7a7c27a26b2cec5af3cf6075d577295f4850856c77af32", - "sha256:0e45d2d852a66ecfb904f090c3f87dc0dfb89a499570abad8590f10d9cffb350", - "sha256:1047ac2b9847ae84ea454e6e20db7dcb755a81c1b1631a879213d2b0ad835ff2", - "sha256:13b3e610a2f8938c61a90b20625069ab7a77ccea20d65a9a0f926cc0cc1314b1", - "sha256:1fc16c80a5da8231fd1f953a7b8dfeb415f68120248e8d68383c5c2c4b18708c", - "sha256:265bfcbbf20d58e6871ce695a7a08aac9b41a0553060d9c05363abd6f3391bdd", - "sha256:2bf2a270906a02b7b255e1a0d7b3aea4f06b3983c51ddec1673c380e0dff5b30", - "sha256:47c71a0347847b747ba1349767b16cde049bc36f21654eb09cc82306ef5fdcf8", - "sha256:48d99869d58f3979d72f6fa0c50f48d16f14973bc4a3adb0ce3b8325fdd7e223", - "sha256:4d950ed2a887905b3fa709b86be5a163e26e1b174703ed59d34eb6832f213222", - "sha256:54d807314c66785c69cd25425933d4bd4c23547a593cdcf49d962fa3e0081336", - "sha256:58172080cbfaee724067a3c017add6a1a3cc167bbc8478dc5f2e5f45fa658763", - "sha256:5df582f2112dd72331de7e567837e136a9629181a8ab69ef8949e4bc294a0b99", - "sha256:6016269bb56caf0327f6d42e7bad1247e08b78407446dff562240c65f85d5a5e", - "sha256:63165fbdc247450017eb9ef04cfe15cb3a72ca48ffcc3a3b75b08c0340bf3647", - "sha256:69adf32522b75968e1cbf25b5d83e87c04cd9a55610ce1e4a19012e58e7e4023", - "sha256:856ebf822d08d754af62c22e2b93626509a72773214f92db1551e2b68d9e2a1b", - "sha256:95069fd9e2813668a2713a1efcc65cc26d2c7e741401ac46628f1ec957511f1b", - "sha256:b12a88566a98617b1a34b4e5a805dff2da98d83fc74262aff3c3d724d0f525d6", - "sha256:c69e19afc734b2a17b9d78b7bcb544aabd5a52ff628e14283b6e9404d27d0517", - "sha256:c82e3bc1e70dde153b0956bffe20a15715a1fe3e00bc23e88d6973eda4505944", - "sha256:d1daec4d31bb00918e4e178297ac6ca6f86ec4c851ba584770533ece554d29e2", - "sha256:d67a2d2fe344953e4572a7d30668cceb516b04287b8638170d562065e53ee2e0", - "sha256:dab9359cc295160ba96738ba4912c675181c84bfdf413e5c0621cf00b7deeeaa", - "sha256:e061311b02cefb17ea93d4a5eb1ad36dca4792037078b43e15a653a0a4478ead", - "sha256:e750a21d8a265b1f9bfb1a28822995ea33511ba7db5e2b55f41fb30781d0d073" + "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690", + "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7", + "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4", + "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd", + "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5", + "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc", + "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818", + "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab", + "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d", + "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a", + "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25", + "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091", + "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea", + "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a", + "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c", + "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72", + "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9", + "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6", + "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044", + "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04", + "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c", + "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e", + "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f", + "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b", + "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4", + "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33", + "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f", + "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e", + "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a", + "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2", + "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3", + "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.16.0" + "version": "==3.20.0" + }, + "pydantic": { + "hashes": [ + "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6", + "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5" + ], + "markers": "python_version >= '3.8'", + "version": "==2.6.4" + }, + "pydantic-core": { + "hashes": [ + "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a", + "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed", + "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979", + "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff", + "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5", + "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45", + "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340", + "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad", + "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23", + "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6", + "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7", + "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241", + "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda", + "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187", + "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba", + "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c", + "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2", + "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c", + "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132", + "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf", + "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972", + "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db", + "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade", + "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4", + "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8", + "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f", + "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9", + "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48", + "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec", + "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d", + "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9", + "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb", + "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4", + "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89", + "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c", + "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9", + "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da", + "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac", + "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b", + "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf", + "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e", + "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137", + "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1", + "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b", + "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8", + "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e", + "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053", + "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01", + "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe", + "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd", + "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805", + "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183", + "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8", + "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99", + "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820", + "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074", + "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256", + "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8", + "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975", + "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad", + "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e", + "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca", + "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df", + "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b", + "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a", + "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a", + "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721", + "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a", + "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f", + "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2", + "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97", + "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6", + "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed", + "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc", + "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1", + "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe", + "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120", + "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f", + "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a" + ], + "markers": "python_version >= '3.8'", + "version": "==2.16.3" }, "pygments": { "hashes": [ - "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297", - "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717" + "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", + "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" + "markers": "python_version >= '3.7'", + "version": "==2.17.2" }, "pyjwt": { "hashes": [ @@ -1717,6 +1561,7 @@ "sha256:fba44e7898bbca160a2b2b501f492824fc8382485d3a6f11ba5d0c1937ce6130" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==2.1.0" }, "pynacl": { @@ -1741,6 +1586,7 @@ "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" ], "index": "pypi", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.4.7" }, "pypdf4": { @@ -1764,15 +1610,16 @@ "sha256:bb7cdd55776f5cf613e4bb9f0f0aba70b60408b964ec7c13b37f69b215acbbe8" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==7.5.2" }, "python-dateutil": { "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" + "version": "==2.9.0.post0" }, "python-http-client": { "hashes": [ @@ -1787,6 +1634,7 @@ "sha256:f26eea7898db40609563bed0a7ca11af12e2a79858632706d835a0f961b7d398" ], "index": "pypi", + "markers": "python_version >= '3.4'", "version": "==2.0.1" }, "python-magic": { @@ -1795,18 +1643,21 @@ "sha256:ca884349f2c92ce830e3f498c5b7c7051fe2942c3ee4332f65213b8ebff15a62" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.4.22" }, "pytz": { "hashes": [ - "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0", - "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a" + "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", + "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" ], - "version": "==2022.7.1" + "version": "==2024.1" }, "pyyaml": { "hashes": [ + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", @@ -1814,7 +1665,10 @@ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", @@ -1822,11 +1676,15 @@ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", @@ -1839,7 +1697,9 @@ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", @@ -1848,6 +1708,7 @@ "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==6.0.1" }, "redis": { @@ -1856,31 +1717,36 @@ "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.2" }, "requests": { + "extras": [ + "socks" + ], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.25.1" }, "requests-oauthlib": { "hashes": [ - "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", - "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", + "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.1" + "markers": "python_version >= '3.4'", + "version": "==2.0.0" }, "requests-toolbelt": { "hashes": [ - "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7", - "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d" + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.1" + "version": "==1.0.0" }, "rq": { "hashes": [ @@ -1888,6 +1754,7 @@ "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==1.10.1" }, "rsa": { @@ -1921,6 +1788,7 @@ "sha256:f46dd15335e8a320b0fb4685f58b7471702234cba8bb3442b69a3e1dc329c345" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.6.1" }, "sendgrid": { @@ -1929,15 +1797,16 @@ "sha256:74b0dcf9a79188948f61f456bd1bf67ffa676a5d388aba1c76bff516566d7084" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==6.7.0" }, "setuptools": { "hashes": [ - "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab", - "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6" + "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", + "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" ], - "markers": "python_version >= '3.7'", - "version": "==66.0.0" + "markers": "python_version >= '3.8'", + "version": "==69.2.0" }, "six": { "hashes": [ @@ -1947,6 +1816,14 @@ "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:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, "sortedcontainers": { "hashes": [ "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", @@ -1956,11 +1833,11 @@ }, "soupsieve": { "hashes": [ - "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", - "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d" + "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", + "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7" ], - "markers": "python_version >= '3.6'", - "version": "==2.3.2.post1" + "markers": "python_version >= '3.8'", + "version": "==2.5" }, "sqlalchemy": { "hashes": [ @@ -2004,6 +1881,7 @@ "sha256:fdd2ed7395df8ac2dbb10cefc44737b66c6a5cd7755c92524733d7a443e5b7e2" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.3.23" }, "sqlalchemy-searchable": { @@ -2015,11 +1893,11 @@ }, "sqlalchemy-utils": { "hashes": [ - "sha256:9da26a9b20c6979167772ba5dc2a1d01265648f18c82995f082279a399ea308b", - "sha256:b37240917d81c14fe1b6e5096a402bace472b179121384e47c10d854dbf5af92" + "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e", + "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990" ], - "markers": "python_version ~= '3.6'", - "version": "==0.39.0" + "markers": "python_version >= '3.7'", + "version": "==0.41.2" }, "starkbank-ecdsa": { "hashes": [ @@ -2052,6 +1930,7 @@ "sha256:f61f33f64760a22100b6b146217823f73cfedd251c9bdbd58453ca94e63326c7" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==0.12.2" }, "svg-stack": { @@ -2079,64 +1958,66 @@ }, "tqdm": { "hashes": [ - "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4", - "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1" + "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", + "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==4.64.1" + "markers": "python_version >= '3.7'", + "version": "==4.66.2" }, "traitlets": { "hashes": [ - "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b", - "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861" + "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9", + "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80" ], - "markers": "python_version >= '3.7'", - "version": "==5.8.1" + "markers": "python_version >= '3.8'", + "version": "==5.14.2" }, "types-cachetools": { "hashes": [ - "sha256:67fa46d51a650896770aee0ba80f0e61dc4a7d1373198eec1bc0622263eaa256", - "sha256:c0c5fa00199017d974c935bf043c467d5204e4f835141e489b48765b5ac1d960" + "sha256:27c982cdb9cf3fead8b0089ee6b895715ecc99dac90ec29e2cab56eb1aaf4199", + "sha256:98c069dc7fc087b1b061703369c80751b0a0fc561f6fb072b554e5eee23773a0" ], "index": "pypi", - "version": "==5.3.0.5" + "markers": "python_version >= '3.7'", + "version": "==5.3.0.7" }, "typing-extensions": { "hashes": [ - "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", - "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" + "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", + "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], - "markers": "python_version >= '3.7'", - "version": "==4.4.0" + "markers": "python_version >= '3.8'", + "version": "==4.10.0" }, "typing-inspect": { "hashes": [ - "sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188", - "sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d" + "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f", + "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78" ], - "version": "==0.8.0" + "version": "==0.9.0" }, "urllib3": { "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + "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.14" + "version": "==1.26.18" }, "validators": { "hashes": [ - "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a" + "sha256:4a70757730619a2c0788aa3c60ba1680372173237c445571586cdef02e37223b", + "sha256:bc0d93d874a363bde9e61b7e31dd274fef168ec057ecb8118edc96c161a89285" ], - "markers": "python_version >= '3.4'", - "version": "==0.20.0" + "markers": "python_version >= '3.8'", + "version": "==0.27.0" }, "wcwidth": { "hashes": [ - "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", - "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", + "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" ], - "version": "==0.2.6" + "version": "==0.2.13" }, "webargs": { "hashes": [ @@ -2152,6 +2033,7 @@ "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.16.0" }, "wrapt": { @@ -2162,23 +2044,30 @@ "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", + "sha256:2020f391008ef874c6d9e208b24f28e31bcb85ccff4f335f15a3251d222b92d9", "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", + "sha256:240b1686f38ae665d1b15475966fe0472f78e71b1b4903c143a842659c8e4cb9", "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", + "sha256:26046cd03936ae745a502abf44dac702a5e6880b2b01c29aea8ddf3353b68224", "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", + "sha256:2feecf86e1f7a86517cab34ae6c2f081fd2d0dac860cb0c0ded96d799d20b335", "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", + "sha256:358fe87cc899c6bb0ddc185bf3dbfa4ba646f05b1b0b9b5a27c2cb92c2cea204", "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", + "sha256:49ef582b7a1152ae2766557f0550a9fcbf7bbd76f43fbdc94dd3bf07cc7168be", "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", + "sha256:6447e9f3ba72f8e2b985a1da758767698efa72723d5b59accefd716e9e8272bf", "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", @@ -2201,8 +2090,10 @@ "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", + "sha256:a9008dad07d71f68487c91e96579c8567c98ca4c3881b9b113bc7b33e9fd78b8", "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", + "sha256:acae32e13a4153809db37405f5eba5bac5fbe2e2ba61ab227926a22901051c0a", "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", @@ -2217,6 +2108,7 @@ "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", + "sha256:ecee4132c6cd2ce5308e21672015ddfed1ff975ad0ac8d27168ea82e71413f55", "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" @@ -2227,92 +2119,11 @@ "xlsxwriter": { "hashes": [ "sha256:1239958b12da12be6abf05b32f64ff162eb75fff0fdf00d901ca0f46dc0557cf", - "sha256:828b3285fc95105f5b1946a6a015b31cf388bd5378fdc6604e4d1b7839df2e77", - "sha256:82a3b0e73e3913483da23791d1a25e4d2dbb3837d1be4129473526b9a270a5cc", "sha256:d79dadac9dcbff3c24281764b052b46bcdb391f3184f337c4c4e6ed8d2738d7d" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==3.0.7" - }, - "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" } }, "develop": { @@ -2322,15 +2133,16 @@ "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==20.3.0" }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2024.2.2" }, "chardet": { "hashes": [ @@ -2346,6 +2158,7 @@ "sha256:ca516f86181f85615cd8210854b43acbe7b1f37ed8a082c5557749c73f2f0dd3" ], "index": "pypi", + "markers": "python_version >= '3.7' and python_version < '4.0'", "version": "==1.8.1" }, "flake8": { @@ -2354,6 +2167,7 @@ "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.9.2" }, "flake8-obey-import-goat": { @@ -2361,6 +2175,7 @@ "sha256:2e4c7be21b96dda72e903c21de16ff928e11fccdf9427889bfb7ccf4610f6072" ], "index": "pypi", + "markers": "python_version >= '3.9'", "version": "==0.1.1" }, "idna": { @@ -2380,56 +2195,19 @@ }, "more-itertools": { "hashes": [ - "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41", - "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab" - ], - "markers": "python_version >= '3.7'", - "version": "==9.0.0" - }, - "mypy": { - "hashes": [ - "sha256:06e1eac8d99bd404ed8dd34ca29673c4346e76dd8e612ea507763dccd7e13c7a", - "sha256:2ee3dbc53d4df7e6e3b1c68ac6a971d3a4fb2852bf10a05fda228721dd44fae1", - "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0", - "sha256:64e1f6af81c003f85f0dfed52db632817dabb51b65c0318ffbf5ff51995bbb08", - "sha256:6e35d764784b42c3e256848fb8ed1d4292c9fc0098413adb28d84974c095b279", - "sha256:6ee196b1d10b8b215e835f438e06965d7a480f6fe016eddbc285f13955cca659", - "sha256:756fad8b263b3ba39e4e204ee53042671b660c36c9017412b43af210ddee7b08", - "sha256:77f8fcf7b4b3cc0c74fb33ae54a4cd00bb854d65645c48beccf65fa10b17882c", - "sha256:794f385653e2b749387a42afb1e14c2135e18daeb027e0d97162e4b7031210f8", - "sha256:8ad21d4c9d3673726cf986ea1d0c9fb66905258709550ddf7944c8f885f208be", - "sha256:8e8e49aa9cc23aa4c926dc200ce32959d3501c4905147a66ce032f05cb5ecb92", - "sha256:9f362470a3480165c4c6151786b5379351b790d56952005be18bdbdd4c7ce0ae", - "sha256:a16a0145d6d7d00fbede2da3a3096dcc9ecea091adfa8da48fa6a7b75d35562d", - "sha256:ad77c13037d3402fbeffda07d51e3f228ba078d1c7096a73759c9419ea031bf4", - "sha256:b6ede64e52257931315826fdbfc6ea878d89a965580d1a65638ef77cb551f56d", - "sha256:c9e0efb95ed6ca1654951bd5ec2f3fa91b295d78bf6527e026529d4aaa1e0c30", - "sha256:ce65f70b14a21fdac84c294cde75e6dbdabbcff22975335e20827b3b94bdbf49", - "sha256:d1debb09043e1f5ee845fa1e96d180e89115b30e47c5d3ce53bc967bab53f62d", - "sha256:e178eaffc3c5cd211a87965c8c0df6da91ed7d258b5fc72b8e047c3771317ddb", - "sha256:e1acf62a8c4f7c092462c738aa2c2489e275ed386320c10b2e9bff31f6f7e8d6", - "sha256:e53773073c864d5f5cec7f3fc72fbbcef65410cde8cc18d4f7242dea60dac52e", - "sha256:eb3978b191b9fa0488524bb4ffedf2c573340e8c2b4206fc191d44c7093abfb7", - "sha256:f64d2ce043a209a297df322eb4054dfbaa9de9e8738291706eaafda81ab2b362", - "sha256:fa38f82f53e1e7beb45557ff167c177802ba7b387ad017eab1663d567017c8ee" - ], - "index": "pypi", - "version": "==0.981" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + "sha256:686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "sha256:8fccb480c43d3e99a00087634c06dd02b0d50fbf088b380de5a41a015ec239e1" ], - "version": "==0.4.3" + "markers": "python_version >= '3.8'", + "version": "==10.2.0" }, "packaging": { "hashes": [ - "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2", - "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.0" + "version": "==24.0" }, "pluggy": { "hashes": [ @@ -2453,6 +2231,7 @@ "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.7.0" }, "pyflakes": { @@ -2469,6 +2248,7 @@ "sha256:ff615c761e25eb25df19edddc0b970302d2a9091fbce0e7213298d85fb61fef6" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==5.3.5" }, "redis": { @@ -2477,14 +2257,19 @@ "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.2" }, "requests": { + "extras": [ + "socks" + ], "hashes": [ "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.25.1" }, "responses": { @@ -2493,15 +2278,16 @@ "sha256:b82502eb5f09a0289d8e209e7bad71ef3978334f56d09b444253d5ad67bf5253" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==0.21.0" }, "setuptools": { "hashes": [ - "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab", - "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6" + "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", + "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" ], - "markers": "python_version >= '3.7'", - "version": "==66.0.0" + "markers": "python_version >= '3.8'", + "version": "==69.2.0" }, "six": { "hashes": [ @@ -2518,14 +2304,6 @@ ], "version": "==2.4.0" }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, "types-cryptography": { "hashes": [ "sha256:09cc53f273dd4d8c29fa7ad11fefd9b734126d467960162397bc5e3e604dea75", @@ -2565,28 +2343,20 @@ "index": "pypi", "version": "==2.25.8" }, - "typing-extensions": { - "hashes": [ - "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", - "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" - ], - "markers": "python_version >= '3.7'", - "version": "==4.4.0" - }, "urllib3": { "hashes": [ - "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", - "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + "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.14" + "version": "==1.26.18" }, "wcwidth": { "hashes": [ - "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", - "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", + "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" ], - "version": "==0.2.6" + "version": "==0.2.13" } } } diff --git a/appserver/bin/docker-entrypoint.sh b/appserver/bin/docker-entrypoint.sh deleted file mode 100755 index feb2d11530..0000000000 --- a/appserver/bin/docker-entrypoint.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -## This scripts serves as the Docker entrypoint. -## If any command is specified, it runs it as is, -## else, it runs the appserver Flask application. - -set -e - -if [ "$1" ]; then - ## A command is specified, then run it. - exec "$@" -else - if [ "$MIGRATE_DB" ]; then - ## If $MIGRATE_DB is set, wait for PostgreSQL and run any required migrations. - while ! curl $POSTGRES_HOST:$POSTGRES_PORT 2>&1 | grep '52'; do - echo "Waiting for PostgreSQL to be available in $POSTGRES_HOST:$POSTGRES_PORT" - sleep 5; - done - echo "PostreSQL is ready. Executing DB migrations now" - flask db upgrade --x-arg data_migrate="True" - echo "Finished executing DB migrations" - fi - - ## Create initial user if $INITIAL_ADMIN_EMAIL is set. - if [ "$INITIAL_ADMIN_EMAIL" ]; then - echo "Trying to create initial admin user: $INITIAL_ADMIN_EMAIL" - flask create-user "Admin" "$INITIAL_ADMIN_EMAIL" > /dev/null 2>&1 || true - flask set-role "$INITIAL_ADMIN_EMAIL" "admin" > /dev/null 2>&1 || true - fi - - ## Run the Flask appserver app, using the built-in development Flask server, - ## or gunicron WSGI server if the $FLASK_ENV is not set to development. - if [ "${FLASK_ENV}" = "development" ]; then - flask run -h 0.0.0.0 -p ${PORT:-5000} - else - gunicorn \ - -b 0.0.0.0:${PORT:-5000} \ - --workers=${GUNICORN_WORKERS:-9} \ - --threads=${GUNICORN_THREADS:-10} \ - --timeout=${GUNICORN_TIMEOUT:-300} \ - --max-requests=${GUNICORN_MAX_REQUESTS:-120} \ - app:app - fi -fi diff --git a/appserver/bin/startup.sh b/appserver/bin/startup.sh index 87179382d4..53c67775f1 100755 --- a/appserver/bin/startup.sh +++ b/appserver/bin/startup.sh @@ -8,7 +8,7 @@ if [ "${FLASK_ENV}" = "development" ] && [ "${FLASK_APP_CONFIG}" = "Development" __dir__="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # wait for postgres timeout 300 ${__dir__}/wait-for-postgres - # wait for neo4j + # wait for arangodb timeout 300 ${__dir__}/wait-for-arango #wait for elastic timeout 300 ${__dir__}/wait-for-elastic diff --git a/appserver/bin/wait-for-neo4j b/appserver/bin/wait-for-neo4j deleted file mode 100755 index c85c5339b8..0000000000 --- a/appserver/bin/wait-for-neo4j +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -echo "Waiting for Neo4J" - -NEO4J_STATUS="000" - -until [ "$NEO4J_STATUS" = "200" ] -do - NEO4J_STATUS=`curl -s -o /dev/null -I -w "%{http_code}" http://${NEO4J_HOST}:7474` - echo "Status of Neo4J: $NEO4J_STATUS" - sleep 2 -done - -# Run command | https://docs.docker.com/compose/startup-order/ ->&2 echo "Neo4j started - executing command" -exec $@ diff --git a/appserver/config.py b/appserver/config.py index 3f01a758f0..c094e85bb1 100644 --- a/appserver/config.py +++ b/appserver/config.py @@ -29,12 +29,6 @@ class Base: POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD') POSTGRES_DB = os.environ.get('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', 'root') ARANGO_PASSWORD = os.environ.get('ARANGO_PASSWORD', 'password') diff --git a/appserver/neo4japp/data_transfer_objects/search.py b/appserver/neo4japp/data_transfer_objects/search.py index f5ee549bdc..018b767158 100644 --- a/appserver/neo4japp/data_transfer_objects/search.py +++ b/appserver/neo4japp/data_transfer_objects/search.py @@ -8,7 +8,7 @@ @attr.s(frozen=True) class FTSQueryRecord(CamelDictMixin): - """Single record from a full text query in Neo4j""" + """Single record from a full text query in ArangoDB""" node: GraphNode = attr.ib() @@ -36,7 +36,7 @@ class FTSReferenceRecord(FTSQueryRecord): @attr.s(frozen=True) class FTSResult(CamelDictMixin): - """Paginated results for a full text search query in Neo4j""" + """Paginated results for a full text search query in ArangoDB""" query: str = attr.ib() nodes: List[FTSQueryRecord] = attr.ib() diff --git a/appserver/neo4japp/services/annotations/README.md b/appserver/neo4japp/services/annotations/README.md index 71ab2d16d1..be769a411b 100644 --- a/appserver/neo4japp/services/annotations/README.md +++ b/appserver/neo4japp/services/annotations/README.md @@ -146,9 +146,9 @@ A global inclusion/exclusion is **both** a local and a global. Local inclusions/exclusions are stored in Postgres, as well as global exclusions. The locals are saved in the `files` table, while the globals are in `global_list`. -The global inclusions are stored in Neo4j under the label `:GlobalInclusion` if they do not map to any existing nodes, otherwise use that existing node and create a new synonym relationship with it. +The global inclusions are stored in ArangoDB under the label `:GlobalInclusion` if they do not map to any existing nodes, otherwise use that existing node and create a new synonym relationship with it. -Because we do not curate before they're added to Neo4j, a user can potentially create a bad global inclusion. To correctly delete, we need the property `original_entity_types` so we don't accidentally delete the wrong thing. See https://sbrgsoftware.atlassian.net/browse/LL-3625 for more information. +Because we do not curate before they're added to ArangoDB, a user can potentially create a bad global inclusion. To correctly delete, we need the property `original_entity_types` so we don't accidentally delete the wrong thing. See https://sbrgsoftware.atlassian.net/browse/LL-3625 for more information. ## NLP Service diff --git a/cache-invalidator/Dockerfile b/cache-invalidator/Dockerfile index 33f146b5ba..1c52bb3e62 100644 --- a/cache-invalidator/Dockerfile +++ b/cache-invalidator/Dockerfile @@ -1,7 +1,7 @@ # ======================================== # Base image # ======================================== -FROM python:3.10-slim as base +FROM python:3.11-slim as base ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 @@ -42,12 +42,12 @@ USER app # Copy application code COPY --chown=app main.py ./ -# Neo4j configuration -ENV NEO4J_HOST=neo4j -ENV NEO4J_PORT=7687 -ENV NEO4J_AUTH=neo4j/password -ENV NEO4J_SCHEME=bolt -ENV NEO4J_DATABASE=neo4j +# ArangoDB configuration +ENV ARANGODB_HOST=arangodb +ENV ARANGODB_PORT=7687 +ENV ARANGODB_AUTH=arangodb/password +ENV ARANGODB_SCHEME=bolt +ENV ARANGODB_DATABASE=arangodb # Redis cache configuration ENV REDIS_HOST=redis diff --git a/cache-invalidator/Pipfile.lock b/cache-invalidator/Pipfile.lock index e95b37a95e..12972e9c28 100644 --- a/cache-invalidator/Pipfile.lock +++ b/cache-invalidator/Pipfile.lock @@ -18,42 +18,123 @@ "default": { "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" + "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" }, "idna": { "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", + "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" ], "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "neo4j": { - "hashes": [ - "sha256:b6c49fbd60426e268ed4afbd414766444fe70aee1ac0376a0c871d75526b8251" - ], - "index": "pypi", - "version": "==4.2.1" + "version": "==3.6" }, "pyjwt": { "hashes": [ - "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd", - "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14" + "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", + "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" ], "markers": "python_version >= '3.7'", - "version": "==2.6.0" + "version": "==2.8.0" }, "python-arango": { "hashes": [ @@ -61,54 +142,49 @@ "sha256:bb7cdd55776f5cf613e4bb9f0f0aba70b60408b964ec7c13b37f69b215acbbe8" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==7.5.2" }, - "pytz": { - "hashes": [ - "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7", - "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c" - ], - "version": "==2022.1" - }, "redis": { "hashes": [ "sha256:2ef11f489003f151777c064c5dbc6653dfb9f3eade159bcadc524619fddc2242", "sha256:6d65e84bc58091140081ee9d9c187aab0480097750fac44239307a3bdf0b1251" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==3.5.2" }, "requests": { "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], - "markers": "python_version >= '3.7' and python_version < '4'", - "version": "==2.28.1" + "markers": "python_version >= '3.7'", + "version": "==2.31.0" }, "requests-toolbelt": { "hashes": [ - "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7", - "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d" + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.1" + "version": "==1.0.0" }, "setuptools": { "hashes": [ - "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54", - "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" + "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", + "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" ], - "markers": "python_version >= '3.7'", - "version": "==65.6.3" + "markers": "python_version >= '3.8'", + "version": "==69.2.0" }, "urllib3": { "hashes": [ - "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", - "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], - "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.13" + "markers": "python_version >= '3.8'", + "version": "==2.2.1" } }, "develop": { @@ -139,14 +215,16 @@ "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==0.942" }, "mypy-extensions": { "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" ], - "version": "==0.4.3" + "markers": "python_version >= '3.5'", + "version": "==1.0.0" }, "pycodestyle": { "hashes": [ @@ -154,6 +232,7 @@ "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.7.0" }, "tomli": { @@ -166,11 +245,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42", - "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2" + "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", + "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.1" + "markers": "python_version >= '3.8'", + "version": "==4.10.0" } } } diff --git a/client/Dockerfile b/client/Dockerfile index 268192f7ce..b15603ee86 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,5 +1,20 @@ ARG NODE_IMAGE_TAG=node:14 +# ======================================== +# Landing page +# ======================================== +FROM $NODE_IMAGE_TAG as landing-build +WORKDIR /app + +# Install dependencies +COPY landing/package.json landing/yarn.lock ./ +RUN yarn install + +# Build landing page +COPY landing ./ +RUN yarn build + + # ================================================================== # Angular app dependencies by default used for local development # ================================================================== @@ -11,23 +26,28 @@ COPY package.json yarn.lock ./ ARG YARN_INSTALL_OPTS RUN yarn install ${YARN_INSTALL_OPTS} -ENV ENVIRONMENT_CONFIG development - +# build time arguments for Angular environment +ARG ANGULAR_CONFIG=development +ARG CLIENT_VERSION=undefined +# default enviroment presets +ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG # ======================================== # Angular app bundle build # ======================================== FROM angular-deps as angular-build +# build time arguments for Angular environment +ARG ANGULAR_CONFIG=production +ARG CLIENT_VERSION=undefined + # Copy the code and build the app bundle COPY src ./src COPY tslint ./tslint COPY e2e ./e2e COPY *.json browserslist ./ - -ARG ANGULAR_CONFIG=production -ENV NODE_OPTIONS=--max-old-space-size=4096 -RUN yarn build --configuration=$ANGULAR_CONFIG --output-path=dist +RUN sed -i "s/__VERSION__/${CLIENT_VERSION}/" src/environments/environment.ts +RUN yarn build --configuration=$ANGULAR_CONFIG --aot --output-path=dist # When targeting this image stage, run angulat dev server EXPOSE 4200 @@ -39,27 +59,43 @@ CMD yarn dev-start # ======================================== # Runtime stage - NGINX # ======================================== -FROM nginx:1.21 -LABEL org.opencontainers.image.source https://github.com/SBRG/lifelike - +FROM nginx:1.25.1 +LABEL app=kg-prototypes WORKDIR /usr/share/nginx/html -# Copy built assets -COPY --from=angular-build /app/dist ./ +# URL to proxy requests to /api +ENV APPSERVER_UPSTREAM http://appserver:5000 -# Copy nginx configuraiton template -COPY nginx.conf /etc/nginx/templates/default.conf.template +# Whether to run the app in prod mode +ENV PRODUCTION_MODE true + +# Whether we are running with valid KEGG license +ENV KEGG_ENABLED false -# appserver URL to proxy /api requests -ENV APPSERVER_URL http://appserver:5000 +# Whether to run the app with oauth login +ENV OAUTH_ENABLED false + +# OAuth issuer discovert URL +ENV OAUTH_ISSUER "" + +# Client ID of the OAuth application +ENV OAUTH_CLIENT_ID "" # List of space delimited list of non-stantdard MIME types # which are known to benefit from gzip compression (text based content) ENV GZIP_EXTRA_TYPES text/tsv vnd.lifelike.document/bioc vnd.lifelike.document/enrichment-table vnd.lifelike.document/graph vnd.lifelike.document/map -# Runtime environment configuration preset -ENV ENVIRONMENT_CONFIG production +# build time argument for Angular environment +ARG ANGULAR_CONFIG=production + +# default enviroment presets +ENV ENVIRONMENT_CONFIG $ANGULAR_CONFIG + +# Copy nginx configuraiton template +COPY nginx.conf /etc/nginx/templates/default.conf.template + +# Copy built assets +COPY --from=landing-build /app/dist ./ +COPY --from=angular-build /app/dist ./ -# Listen port -ENV PORT 80 -EXPOSE $PORT +EXPOSE 80 diff --git a/client/src/app/sankey/components/entity-details/node-details.component.html b/client/src/app/sankey/components/entity-details/node-details.component.html index bd2780277c..20a49aafbc 100644 --- a/client/src/app/sankey/components/entity-details/node-details.component.html +++ b/client/src/app/sankey/components/entity-details/node-details.component.html @@ -69,7 +69,7 @@ - +