From b0ed430869d25a26b5fa6548d396845258003ccb Mon Sep 17 00:00:00 2001 From: nutrina Date: Tue, 10 Oct 2023 12:01:00 +0300 Subject: [PATCH] 1646 lambda (#401) * fix(infra): change destination for public scores & config of cloudfront * fix(api,infra): fix bug in and removed acl from task exporting scores * feat(infra,api): add dockerfile for AWS lambda * feat(load-test): adjustments for running submit-passport as lambda * feat(infra): forgot to add lambda function * feat(infra,api): update readme in the load_test folder * feat(api): adding lambda to ci and building lambda * chore(infra): wip lambda build * fix(infra): succesfully building image * feat(lambdas): wip submit passport lambda auth and rate limiting with tests * feat(api): moves submit passport lambda adds logger * chore(infra): add image from ci * fix(ci): lambda ecr * fix(ci): aws_lambda * fix(infra): fix docker file build * fix(infra): adjust docker file to point at module, add requirements.txt * fix(api): fix build for lambda image * chore(api): test lambda rate limiting and auth * chore(api): rename submit-passport module and cleanup * chore(api): add lambda testing readme * fix(api): fix module resolution for pytest * fix(ci): update ECR name * feat(infra): move lambda definition to service and add to prod * chore(ci): add comments and correct ECR name alias * chore(ci): add lambda to prod ci * fix(infra): build image uri using pulumi * fix(infra): use private ECR image for lambda * fix(infra): login to private ECR * fix(ci): update ECR to private * fix(ci): region * fix(ci): use env for image url * fix(ci): name image using env variable * fix(ci): update region * fix(ci): hard code us-west-2 * fix(api): update how x-api-key is parsed and validated * fix(api): fix parsing of body request * chore(api, ci): fix test and prod ci * fix(api): remove rate limiting test due to conflict * chore(infra): add v2 endpoint * feat(api): fix tests, remove unused request handler --------- Co-authored-by: schultztimothy Co-authored-by: Aminah Burch --- .github/workflows/api-promote-prod.yml | 52 +- .github/workflows/api-promote-staging.yml | 50 +- api/Dockerfile.python3.11 | 53 + api/aws_lambdas/Readme.md | 47 + api/aws_lambdas/__init__.py | 0 api/aws_lambdas/docker-compose-lambda.yml | 74 ++ api/aws_lambdas/submit_passport/Dockerfile | 40 + api/aws_lambdas/submit_passport/__init__.py | 0 .../submit_passport/submit_passport.py | 84 ++ .../submit_passport/tests/__init__.py | 0 .../tests/test_submit_passport_lambda.py | 112 ++ api/registry/api/utils.py | 1 + api/registry/api/v1.py | 16 +- infra/lib/scorer/service.ts | 162 ++- infra/prod/index.ts | 11 + infra/staging/index.ts | 28 +- load_tests/README.md | 5 + load_tests/stats.ipynb | 1059 +++++++++++++++++ 18 files changed, 1774 insertions(+), 20 deletions(-) create mode 100644 api/Dockerfile.python3.11 create mode 100644 api/aws_lambdas/Readme.md create mode 100644 api/aws_lambdas/__init__.py create mode 100644 api/aws_lambdas/docker-compose-lambda.yml create mode 100644 api/aws_lambdas/submit_passport/Dockerfile create mode 100644 api/aws_lambdas/submit_passport/__init__.py create mode 100644 api/aws_lambdas/submit_passport/submit_passport.py create mode 100644 api/aws_lambdas/submit_passport/tests/__init__.py create mode 100644 api/aws_lambdas/submit_passport/tests/test_submit_passport_lambda.py create mode 100644 load_tests/stats.ipynb diff --git a/.github/workflows/api-promote-prod.yml b/.github/workflows/api-promote-prod.yml index f35e08200..9b6ff338a 100644 --- a/.github/workflows/api-promote-prod.yml +++ b/.github/workflows/api-promote-prod.yml @@ -196,9 +196,56 @@ jobs: outputs: dockerTag: ${{ steps.vars.outputs.sha_short }} + build-submit-passport-lambda: + environment: Staging + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.commit }} + + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Declare some variables + id: vars + shell: bash + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_STAGING }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_STAGING }} + aws-region: us-west-2 + + - name: Login to Amazon ECR Private + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build, tag, and push image to Amazon ECR + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: submit-passport-lambdas + IMAGE_TAG: ${{ steps.vars.outputs.sha_short }} + run: | + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f api/aws_lambdas/submit_passport/Dockerfile ./api/ + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + + outputs: + dockerTag: ${{ steps.vars.outputs.sha_short }} + deploy-production: environment: Production - needs: [test, build-api, build-verifier, build-indexer] + needs: + [ + test, + build-api, + build-verifier, + build-indexer, + build-submit-passport-lambda, + ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -246,7 +293,8 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} DOCKER_GTC_PASSPORT_SCORER_IMAGE: public.ecr.aws/c8n6v8e9/passport-scorer:${{ needs.build-api.outputs.dockerTag }} DOCKER_GTC_PASSPORT_VERIFIER_IMAGE: public.ecr.aws/c8n6v8e9/passport-verifier:${{ needs.build-verifier.outputs.dockerTag }} - DOCKER_GTC_PASSPORT_INDEXER_IMAGE: public.ecr.aws/t1g3k9q8/passport-indexer:${{ needs.build-indexer.outputs.dockerTag }} + DOCKER_GTC_PASSPORT_INDEXER_IMAGE: public.ecr.aws/c8n6v8e9/passport-indexer:${{ needs.build-indexer.outputs.dockerTag }} + DOCKER_GTC_SUBMIT_PASSPORT_LAMBDA_IMAGE: ${{secrets.PRIVATE_ECR_URL}}:${{ needs.build-submit-passport-lambda.outputs.dockerTag }} ROUTE_53_ZONE: ${{ secrets.ROUTE53_ZONE_ID }} ROUTE_53_ZONE_FOR_PUBLIC_DATA: ${{ secrets.ROUTE_53_ZONE_FOR_PUBLIC_DATA }} DOMAIN: ${{ secrets.DOMAIN }} diff --git a/.github/workflows/api-promote-staging.yml b/.github/workflows/api-promote-staging.yml index 72c1ed337..24cc38987 100644 --- a/.github/workflows/api-promote-staging.yml +++ b/.github/workflows/api-promote-staging.yml @@ -121,6 +121,46 @@ jobs: outputs: dockerTag: ${{ steps.vars.outputs.sha_short }} + build-submit-passport-lambda: + environment: Staging + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.commit }} + + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Declare some variables + id: vars + shell: bash + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_STAGING }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_STAGING }} + aws-region: us-west-2 + + - name: Login to Amazon ECR Private + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build, tag, and push image to Amazon ECR + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: submit-passport-lambdas + IMAGE_TAG: ${{ steps.vars.outputs.sha_short }} + run: | + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f api/aws_lambdas/submit_passport/Dockerfile ./api/ + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + + outputs: + dockerTag: ${{ steps.vars.outputs.sha_short }} + build-indexer: environment: Staging runs-on: ubuntu-latest @@ -204,7 +244,14 @@ jobs: deploy-staging: environment: Staging - needs: [test, build-api, build-verifier, build-indexer] + needs: + [ + test, + build-api, + build-verifier, + build-indexer, + build-submit-passport-lambda, + ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -256,6 +303,7 @@ jobs: DOCKER_GTC_PASSPORT_SCORER_IMAGE: public.ecr.aws/t1g3k9q8/passport-scorer:${{ needs.build-api.outputs.dockerTag }} DOCKER_GTC_PASSPORT_VERIFIER_IMAGE: public.ecr.aws/t1g3k9q8/passport-verifier:${{ needs.build-verifier.outputs.dockerTag }} DOCKER_GTC_PASSPORT_INDEXER_IMAGE: public.ecr.aws/t1g3k9q8/passport-indexer:${{ needs.build-indexer.outputs.dockerTag }} + DOCKER_GTC_SUBMIT_PASSPORT_LAMBDA_IMAGE: ${{secrets.PRIVATE_ECR_URL}}:${{ needs.build-submit-passport-lambda.outputs.dockerTag }} ROUTE_53_ZONE: ${{ secrets.ROUTE53_ZONE_ID }} ROUTE_53_ZONE_FOR_PUBLIC_DATA: ${{ secrets.ROUTE_53_ZONE_FOR_PUBLIC_DATA }} DOMAIN: ${{ secrets.DOMAIN_STAGING }} diff --git a/api/Dockerfile.python3.11 b/api/Dockerfile.python3.11 new file mode 100644 index 000000000..bf8df2930 --- /dev/null +++ b/api/Dockerfile.python3.11 @@ -0,0 +1,53 @@ + +# https://pipenv.pypa.io/en/latest/basics/#pipenv-and-docker-containers +FROM public.ecr.aws/lambda/python:3.11 AS base + + +######################################################### +# Builder +######################################################### +FROM base AS builder + +RUN pip install pipenv + +# Tell pipenv to create venv in the current directory +ENV PIPENV_VENV_IN_PROJECT=1 + +ADD Pipfile.lock /usr/src/ + +WORKDIR /usr/src + + +# NOTE: If you install binary packages required for a python module, you need +# to install them again in the runtime. For example, if you need to install pycurl +# you need to have pycurl build dependencies libcurl4-gnutls-dev and libcurl3-gnutls +# In the runtime container you need only libcurl3-gnutls + +# RUN apt install -y libcurl3-gnutls libcurl4-gnutls-dev +# RUN /root/.local/bin/pipenv lock + +RUN pipenv requirements > requirements.txt +# RUN /usr/src/.venv/bin/python -c "import django; print(django.__version__)" +# RUN ls /usr/src/.venv/lib/ + +######################################################### +# Runtime +######################################################### +FROM base AS runtime + +# RUN mkdir -v /usr/src/venv + +COPY --from=builder /usr/src/requirements.txt ${LAMBDA_TASK_ROOT} +COPY . ${LAMBDA_TASK_ROOT} + + +WORKDIR ${LAMBDA_TASK_ROOT} + +RUN pip install -r requirements.txt +RUN python -c "import django; print(f\"\n{'*' * 40}\n* DJANGO VERSION: {django.__version__ : <21}*\n{'*' * 40}\n\")" +# ENV PATH="/usr/src/.venv/bin/:${PATH}" + + +RUN STATIC_ROOT=${LAMBDA_TASK_ROOT}/static SECRET_KEY=secret_is_irelevent_here CERAMIC_CACHE_SCORER_ID=1 DATABASE_URL=sqlite:////dunmmy_db.sqlite3 python manage.py collectstatic --noinput + +CMD [ "lambda_function.handler" ] \ No newline at end of file diff --git a/api/aws_lambdas/Readme.md b/api/aws_lambdas/Readme.md new file mode 100644 index 000000000..924b8e403 --- /dev/null +++ b/api/aws_lambdas/Readme.md @@ -0,0 +1,47 @@ +# Testing the Application Locally with Docker + +## 1. Building the Docker Image + +First, navigate to the passport-scorer root directory. Then, execute the command below to build the Docker image: + +```bash +docker build --platform linux/amd64 -t docker-image:test -f ./api/aws_lambdas/submit_passport/Dockerfile ./api +``` + +## 2. Running the Docker Image + +Once you've successfully built the image, you can run it. Ensure you point to the location of your running PostgreSQL instance. In this context, the database is running in another Docker container: + +```bash +docker run -e DATABASE_URL=postgres://passport_scorer:passport_scorer_pwd@host.docker.internal:5432/passport_scorer -p 8080:8080 docker-image:test +``` + +### 3. Making Curl Requests + +After you have your application up and running, you can test its endpoints using `curl`. Use the command below to make a request to the instance: + +````markdown +```bash +curl -X 'POST' \ + 'http://localhost:8080/2015-03-31/functions/function/invocations' \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "requestContext": { + "elb": { + "targetGroupArn": "arn" + } + }, + "httpMethod": "POST", + "path": "/registry/submit-passport", + "queryStringParameters": {}, + "headers": {add necessary headers here}, + "body": "{\"address\":\"0x868asAe3B27asdF475e41FAdDF9F0cf97fDB71fC\",\"community\":\"24\"}", + "isBase64Encoded": false +}' +``` +```` + +``` + +``` diff --git a/api/aws_lambdas/__init__.py b/api/aws_lambdas/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/aws_lambdas/docker-compose-lambda.yml b/api/aws_lambdas/docker-compose-lambda.yml new file mode 100644 index 000000000..32fbf6b52 --- /dev/null +++ b/api/aws_lambdas/docker-compose-lambda.yml @@ -0,0 +1,74 @@ +version: "3.9" # optional since v1.27.0 +services: + # redis: + # image: redis + # restart: unless-stopped + # ports: + # - 6379:6379 + + api: + build: + context: ./api/aws_lambdas/submit-passport + dockerfile: Dockerfile + + ports: + - "127.0.0.1:8000:8000" + - 8080:8080 + + volumes: + - ./api:/var/task + + environment: + - CELERY_BROKER_URL=redis://redis:6379/0 + - CERAMIC_CACHE_CACAO_VALIDATION_URL=http://verifier:8001/verify + - CERAMIC_CACHE_SCORER_ID=1 + - DATABASE_URL=postgres://passport_scorer:passport_scorer_pwd@postgres:5432/passport_scorer + + # command: uvicorn scorer.asgi:application --reload --host 0.0.0.0 --port 8002 + # command: uvicorn scorer.asgi:application --host 0.0.0.0 --port 8002 --backlog 5000 --workers 6 --log-level debug + # command: gunicorn -w 8 -t 60 -k uvicorn.workers.UvicornWorker --worker-connections 5000 scorer.asgi:application -b 0.0.0.0:8002 + # command: gunicorn -w 4 -t 60 -k uvicorn.workers.UvicornWorker scorer.asgi:application -b 0.0.0.0:8002 + + # worker: + # build: api + # volumes: + # - ./api:/app + # environment: + # - CELERY_BROKER_URL=redis://redis:6379/0 + # - CERAMIC_CACHE_SCORER_ID=1 + # command: celery -A scorer worker -Q score_passport_passport,score_registry_passport -l DEBUG + + # interface: + # build: + # context: ./interface + # dockerfile: Dockerfile + + # ports: + # - 3001:3001 + + # volumes: + # - ./interface:/app + # - /app/node_modules + # - /app/.next + + # command: yarn dev + + verifier: + build: verifier + + postgres: + image: postgres:12.3-alpine + restart: unless-stopped + + environment: + POSTGRES_USER: passport_scorer + POSTGRES_PASSWORD: passport_scorer_pwd + POSTGRES_DB: passport_scorer + PGDATA: /db_data + + command: postgres -c 'max_connections=2000' + volumes: + - ./postgres_db_data:/db_data + + ports: + - 5432:5432 diff --git a/api/aws_lambdas/submit_passport/Dockerfile b/api/aws_lambdas/submit_passport/Dockerfile new file mode 100644 index 000000000..2e099c411 --- /dev/null +++ b/api/aws_lambdas/submit_passport/Dockerfile @@ -0,0 +1,40 @@ + +# https://pipenv.pypa.io/en/latest/basics/#pipenv-and-docker-containers +FROM public.ecr.aws/lambda/python:3.11 AS base + + +######################################################### +# Builder +######################################################### +FROM base AS builder + +RUN pip install pipenv + +# Tell pipenv to create venv in the current directory +ENV PIPENV_VENV_IN_PROJECT=1 + +ADD Pipfile.lock /usr/src/ + +WORKDIR /usr/src + +RUN pipenv requirements > requirements.txt + +######################################################### +# Runtime +######################################################### +FROM base AS runtime + +COPY --from=builder /usr/src/requirements.txt ${LAMBDA_TASK_ROOT} +COPY ./ ${LAMBDA_TASK_ROOT} + + +WORKDIR ${LAMBDA_TASK_ROOT} + +RUN pip install -r requirements.txt + +RUN python -c "import django; print(f\"\n{'*' * 40}\n* DJANGO VERSION: {django.__version__ : <21}*\n{'*' * 40}\n\")" + + +RUN STATIC_ROOT=${LAMBDA_TASK_ROOT}/static SECRET_KEY=secret_is_irelevent_here CERAMIC_CACHE_SCORER_ID=1 DATABASE_URL=sqlite:////dunmmy_db.sqlite3 python manage.py collectstatic --noinput + +CMD [ "aws_lambdas.submit_passport.submit_passport.handler" ] diff --git a/api/aws_lambdas/submit_passport/__init__.py b/api/aws_lambdas/submit_passport/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/aws_lambdas/submit_passport/submit_passport.py b/api/aws_lambdas/submit_passport/submit_passport.py new file mode 100644 index 000000000..50d5ef505 --- /dev/null +++ b/api/aws_lambdas/submit_passport/submit_passport.py @@ -0,0 +1,84 @@ +""" +This module provides a handler to manage API requests in AWS Lambda. +""" + +import logging +import os + +from django.http import HttpRequest +from django_ratelimit.exceptions import Ratelimited + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "scorer.settings") +os.environ.setdefault("CERAMIC_CACHE_SCORER_ID", "1") + +import json + +import django +from django.conf import settings + +logger = logging.getLogger(__name__) + +# settings.configure(DEBUG=True) +django.setup() + + +from registry.api.utils import ApiKey, check_rate_limit +from registry.api.v1 import SubmitPassportPayload, handle_submit_passport +from registry.exceptions import Unauthorized + +# Now this script or any imported module can use any part of Django it needs. +# from myapp import models + + +def lambda_to_django_request(api_key): + """ + Convert a Lambda event into a Django HttpRequest object. + """ + request = HttpRequest() + request.META["X-Api-Key"] = api_key + + return request + + +def handler(event, _context): + """ + Handles the incoming events and translates them into Django's context. + """ + try: + logger.info("Received event: %s", event) + api_key = event["headers"].get("x-api-key", "") + # Authenticate + api_key_instance = ApiKey() + request = lambda_to_django_request(api_key) + user_account = api_key_instance.authenticate(request, api_key) + + # rate limit + check_rate_limit(request) + + body = json.loads(event["body"]) + if user_account: + ret = handle_submit_passport(SubmitPassportPayload(**body), user_account) + return { + "statusCode": 200, + "statusDescription": "200 OK", + "isBase64Encoded": False, + "headers": {"Content-Type": "application/json"}, + "body": ret.json(), + } + + except (Unauthorized, Ratelimited) as e: + status, message = { + Unauthorized: (403, "

Unauthorized

"), + Ratelimited: ( + 429, + "

You have been rate limited. Please try again later.

", + ), + }.get(type(e), (400, "

An error has occurred

")) + logger.exception("Error occurred when attempting to submit passport: %s", e) + return { + "statusCode": status, + "statusDescription": str(e), + "isBase64Encoded": False, + "headers": {"Content-Type": "text/html"}, + "body": message, + } diff --git a/api/aws_lambdas/submit_passport/tests/__init__.py b/api/aws_lambdas/submit_passport/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/aws_lambdas/submit_passport/tests/test_submit_passport_lambda.py b/api/aws_lambdas/submit_passport/tests/test_submit_passport_lambda.py new file mode 100644 index 000000000..6cf068035 --- /dev/null +++ b/api/aws_lambdas/submit_passport/tests/test_submit_passport_lambda.py @@ -0,0 +1,112 @@ +import json + +import pytest +from account.models import AccountAPIKey +from django.test import override_settings +from registry.api import v1 +from scorer.test.conftest import ( + scorer_account, + scorer_api_key, + scorer_community_with_binary_scorer, + scorer_user, +) + +from ..submit_passport import handler + +# Sample mock event +sample_event = { + "headers": {"x-api-key": "sample_key"}, + "body": '{"some_key": "some_value"}', +} + +pytestmark = pytest.mark.django_db + + +def make_test_event(api_key, address, community_id): + """ + Creates a mock event for testing purposes. + """ + return { + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:515520736917:targetgroup/testTargetGroup-e050da0/c8f86571a77b9bc5" + } + }, + "httpMethod": "POST", + "path": "/registry/submit-passport", + "queryStringParameters": {}, + "headers": { + "content-length": "73", + "content-type": "application/json", + "host": "api.staging.scorer.gitcoin.co", + "user-agent": "k6/0.46.0 (https://k6.io/)", + "x-amzn-trace-id": "Root=1-650373d8-19455f7f1bfd3c6f0fc3f323", + "x-api-key": api_key, + "x-forwarded-for": "164.90.200.92", + "x-forwarded-port": "443", + "x-forwarded-proto": "https", + }, + "body": json.dumps({"address": address, "community": community_id}), + "isBase64Encoded": False, + } + + +def test_successful_authentication( + scorer_api_key, scorer_account, scorer_community_with_binary_scorer +): + """ + Tests that authentication is successful given correct credentials. + """ + event = make_test_event( + scorer_api_key, scorer_account.address, scorer_community_with_binary_scorer.id + ) + + response = handler(event, None) + + assert response is not None + assert ( + response["body"] + == '{"address": "0xb81c935d01e734b3d8bb233f5c4e1d72dbc30f6c", "score": null, "status": "PROCESSING", "last_score_timestamp": null, "evidence": null, "error": null, "stamp_scores": null}' + ) + assert response["statusCode"] == 200 + + +def test_unsucessfull_auth(scorer_account, scorer_community_with_binary_scorer): + """ + Tests that authentication fails given incorrect credentials. + """ + event = make_test_event( + "bad_key", scorer_account.address, scorer_community_with_binary_scorer.id + ) + + response = handler(event, None) + + assert response is not None + assert response["statusCode"] == 403 + + +# Conflicting with other rate limiting tests +# @override_settings(RATELIMIT_ENABLE=True) +# def test_rate_limiting( +# scorer_api_key, scorer_account, scorer_community_with_binary_scorer +# ): +# """ +# Tests that rate limiting works as expected. +# """ +# (_, secret) = AccountAPIKey.objects.create_key( +# account=scorer_account, +# name="Token for user 1", +# rate_limit="3/30seconds", +# ) +# event = make_test_event( +# secret, scorer_account.address, scorer_community_with_binary_scorer.id +# ) + +# for _ in range(3): +# response = handler(event, None) +# assert response is not None +# assert response["statusCode"] == 200 + +# rate_limit = handler(event, None) +# assert rate_limit is not None +# assert rate_limit["statusCode"] == 429 diff --git a/api/registry/api/utils.py b/api/registry/api/utils.py index deaeef4a0..000d5a3ff 100644 --- a/api/registry/api/utils.py +++ b/api/registry/api/utils.py @@ -31,6 +31,7 @@ def authenticate(self, request, key): # if X-API-Key was not specified in the header read the HTTP_AUTHORIZATION # and try to load the tey from there auth_header = request.META.get("HTTP_AUTHORIZATION", "") + if not auth_header: raise Unauthorized() diff --git a/api/registry/api/v1.py b/api/registry/api/v1.py index f44b5e665..2fb7f3596 100644 --- a/api/registry/api/v1.py +++ b/api/registry/api/v1.py @@ -19,14 +19,6 @@ from ninja_extra.exceptions import APIException from pydantic import BaseModel from registry.api import common -from registry.api.utils import ( - ApiKey, - aapi_key, - check_rate_limit, - community_requires_signature, - get_scorer_id, - with_read_db, -) from registry.api.schema import ( CursorPaginatedHistoricalScoreResponse, CursorPaginatedScoreResponse, @@ -39,6 +31,14 @@ StampDisplayResponse, SubmitPassportPayload, ) +from registry.api.utils import ( + ApiKey, + aapi_key, + check_rate_limit, + community_requires_signature, + get_scorer_id, + with_read_db, +) from registry.atasks import ascore_passport from registry.exceptions import ( InternalServerErrorException, diff --git a/infra/lib/scorer/service.ts b/infra/lib/scorer/service.ts index 338ba8dc2..cd5086ab7 100644 --- a/infra/lib/scorer/service.ts +++ b/infra/lib/scorer/service.ts @@ -1,12 +1,14 @@ import { LogGroup } from "@pulumi/aws/cloudwatch/logGroup"; import { Role } from "@pulumi/aws/iam/role"; import * as awsx from "@pulumi/awsx"; -import { Input, interpolate } from "@pulumi/pulumi"; +import { Input, Output, interpolate } from "@pulumi/pulumi"; import { TargetGroup, ListenerRule } from "@pulumi/aws/lb"; import * as aws from "@pulumi/aws"; import { Cluster } from "@pulumi/aws/ecs"; import { Topic } from "@pulumi/aws/sns"; +import { Listener } from "@pulumi/aws/alb"; +import { SecurityGroup } from "@pulumi/aws/ec2"; let SCORER_SERVER_SSM_ARN = `${process.env["SCORER_SERVER_SSM_ARN"]}`; @@ -599,3 +601,161 @@ export function createIndexerService( }, }); } + +// TODO: make more generic to be used for other lambdas +export function buildLambdaFn( + httpsListener: Listener, + imageUri: string, + privateSubnetSecurityGroup: SecurityGroup, + vpcPrivateSubnetIds: Output, + environment: { name: string; value: Input }[] +) { + const lambdaTargetGroup = new aws.lb.TargetGroup("lambdaTargetGroup", { + targetType: "lambda", + }); + const example = new aws.cloudwatch.LogGroup("example", { + retentionInDays: 14, + }); + const lambdaLoggingPolicyDocument = aws.iam.getPolicyDocument({ + statements: [ + { + effect: "Allow", + actions: [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents", + ], + resources: ["arn:aws:logs:*:*:*"], + }, + ], + }); + const lambdaEc2PolicyDocument = aws.iam.getPolicyDocument({ + statements: [ + { + effect: "Allow", + actions: [ + "ec2:DescribeNetworkInterfaces", + "ec2:CreateNetworkInterface", + "ec2:DeleteNetworkInterface", + "ec2:DescribeInstances", + "ec2:AttachNetworkInterface", + ], + resources: ["*"], + }, + ], + }); + + const lambdaLoggingPolicy = new aws.iam.Policy("lambdaLoggingPolicy", { + path: "/", + description: "IAM policy for logging from a lambda", + policy: lambdaLoggingPolicyDocument.then( + (lambdaLoggingPolicyDocument) => lambdaLoggingPolicyDocument.json + ), + }); + + const lambdaEc2Policy = new aws.iam.Policy("lambdaEc2Policy", { + path: "/", + description: "IAM policy for logging from a lambda", + policy: lambdaEc2PolicyDocument.then( + (lambdaEc2PolicyDocument) => lambdaEc2PolicyDocument.json + ), + }); + + const assumeRole = aws.iam.getPolicyDocument({ + statements: [ + { + effect: "Allow", + principals: [ + { + type: "Service", + identifiers: ["lambda.amazonaws.com"], + }, + ], + actions: ["sts:AssumeRole"], + }, + ], + }); + + const iamForLambda = new aws.iam.Role("iamForLambda", { + assumeRolePolicy: assumeRole.then((assumeRole) => assumeRole.json), + }); + + const lambdaLogs = new aws.iam.RolePolicyAttachment("lambdaLogs", { + role: iamForLambda.name, + policyArn: lambdaLoggingPolicy.arn, + }); + + const lambdaEc2 = new aws.iam.RolePolicyAttachment("lambdaEc2", { + role: iamForLambda.name, + policyArn: lambdaEc2Policy.arn, + }); + + const submitPassportFunction = new aws.lambda.Function( + "submitPassportFunction", + { + vpcConfig: { + // vpcId: vpc.vpcId, + securityGroupIds: [privateSubnetSecurityGroup.id], // TODO: shall we create it's own security group ??? + subnetIds: vpcPrivateSubnetIds, + }, + packageType: "Image", + role: iamForLambda.arn, + + imageUri, + timeout: 30, + memorySize: 1024, + environment: { + variables: environment.reduce( + ( + acc: { [key: string]: Input }, + e: { name: string; value: Input } + ) => { + acc[e.name] = e.value; + return acc; + }, + {} + ), + }, + }, + { + dependsOn: [lambdaLogs, lambdaEc2], + } + ); + + const withLb = new aws.lambda.Permission("withLb", { + action: "lambda:InvokeFunction", + function: submitPassportFunction.name, + principal: "elasticloadbalancing.amazonaws.com", + sourceArn: lambdaTargetGroup.arn, + }); + + const lambdaTargetGroupAttachment = new aws.lb.TargetGroupAttachment( + "testTargetGroupAttachment", + { + targetGroupArn: lambdaTargetGroup.arn, + targetId: submitPassportFunction.arn, + }, + { + dependsOn: [withLb], + } + ); + + const targetPassportRule = new ListenerRule(`lrule-lambda`, { + tags: { name: "lambda rule" }, + listenerArn: httpsListener.arn, + priority: 1000, + actions: [ + { + type: "forward", + targetGroupArn: lambdaTargetGroup.arn, + }, + ], + conditions: [ + { + pathPattern: { + values: ["/registry/submit-passport", "/registry/v2/submit-passport"], + }, + }, + ], + }); +} diff --git a/infra/prod/index.ts b/infra/prod/index.ts index d4520ff81..5ba424443 100644 --- a/infra/prod/index.ts +++ b/infra/prod/index.ts @@ -5,6 +5,7 @@ import * as awsx from "@pulumi/awsx"; import { ScorerEnvironmentConfig, ScorerService, + buildLambdaFn, createIndexerService, createScoreExportBucketAndDomain, createScorerECSService, @@ -1355,3 +1356,13 @@ createIndexerService( privateSubnetSecurityGroup, workerRole ); + +export const dockerGtcSubmitPassportLambdaImage = `${process.env["DOCKER_GTC_SUBMIT_PASSPORT_LAMBDA_IMAGE"]}`; + +buildLambdaFn( + httpsListener, + dockerGtcSubmitPassportLambdaImage, + privateSubnetSecurityGroup, + vpcPrivateSubnetIds, + environment +); diff --git a/infra/staging/index.ts b/infra/staging/index.ts index efbd40f7d..57adb628c 100644 --- a/infra/staging/index.ts +++ b/infra/staging/index.ts @@ -1,10 +1,12 @@ import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as awsx from "@pulumi/awsx"; +import { TargetGroup, ListenerRule } from "@pulumi/aws/lb"; import { ScorerEnvironmentConfig, ScorerService, + buildLambdaFn, createIndexerService, createScoreExportBucketAndDomain, createScorerECSService, @@ -457,12 +459,22 @@ const scorerServiceRegistrySubmitPassport = createScorerECSService( { ...baseScorerServiceConfig, listenerRulePriority: 2500, - httpListenerRulePaths: ["/registry/submit-passport"], + httpListenerRulePaths: ["/registry/submit-passport-old"], targetGroup: targetGroupRegistrySubmitPassport, }, envConfig ); +export const dockerGtcSubmitPassportLambdaImage = `${process.env["DOCKER_GTC_SUBMIT_PASSPORT_LAMBDA_IMAGE"]}`; + +buildLambdaFn( + httpsListener, + dockerGtcSubmitPassportLambdaImage, + privateSubnetSecurityGroup, + vpcPrivateSubnetIds, + environment +); + ////////////////////////////////////////////////////////////// // Set up the Celery Worker Service ////////////////////////////////////////////////////////////// @@ -1186,10 +1198,10 @@ const exportVals = createScoreExportBucketAndDomain( ); // TODO: remove once prod is verified to be working -createIndexerService( - indexerRdsConnectionUrl, - cluster, - vpc, - privateSubnetSecurityGroup, - workerRole -); +// createIndexerService( +// indexerRdsConnectionUrl, +// cluster, +// vpc, +// privateSubnetSecurityGroup, +// workerRole +// ); diff --git a/load_tests/README.md b/load_tests/README.md index c4b52b8d8..e0c59865d 100644 --- a/load_tests/README.md +++ b/load_tests/README.md @@ -45,6 +45,11 @@ Run locally like: or `k6 run -e SCORER_API_KEY= -e SCORER_ID= script.js` +To output results / stats in a CSV file, run k6 with the `--out` like: +`k6 run -e SCORER_API_KEY='iE7QwgX9.rx9XIXdkPwZUYAHditFMgFVKvDp428OH' -e SCORER_ID=24 --vus 10 --duration 120s --out csv=k6_metrics.csv script.js` + +You can then use the `stats.ipynb` to analyse the results frm the `k6_metrics.csv` (after the run). + ## In cloud First make sure to set the environment variables: https://k6.io/docs/cloud/manage/environment-variables/ diff --git a/load_tests/stats.ipynb b/load_tests/stats.ipynb new file mode 100644 index 000000000..e00d01b5e --- /dev/null +++ b/load_tests/stats.ipynb @@ -0,0 +1,1059 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For exporting to PDF:\n", + "```bash\n", + "apt-get install pandoc \n", + "```\n", + "\n", + "Install dependencies:\n", + "```bash\n", + "pip install bokeh\n", + "pip install jupyter_bokeh\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"ea6fd51c-1ed5-40fc-b373-d0a9e02e5ece\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.1.1.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\nif (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"ea6fd51c-1ed5-40fc-b373-d0a9e02e5ece\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
metric_nametimestampmetric_valuecheckerrorerror_codeexpected_responsegroupmethodnameprotoscenarioservicestatussubprototls_versionurlextra_tagsmetadata
0vus2023-09-22 09:09:140.000000NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1vus_max2023-09-22 09:09:1417.000000NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
2vus2023-09-22 09:09:150.000000NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
3vus_max2023-09-22 09:09:1536.000000NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
4vus2023-09-22 09:09:160.000000NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
............................................................
1481075iteration_duration2023-09-22 09:20:2023005.156282NaNNaNNaNNaNNaNNaNNaNNaNdefaultNaNNaNNaNNaNNaNNaNNaN
1481076iterations2023-09-22 09:20:201.000000NaNNaNNaNNaNNaNNaNNaNNaNdefaultNaNNaNNaNNaNNaNNaNNaN
1481077data_sent2023-09-22 09:20:200.000000NaNNaNNaNNaN::teardownNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1481078data_received2023-09-22 09:20:200.000000NaNNaNNaNNaN::teardownNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1481079iteration_duration2023-09-22 09:20:200.005893NaNNaNNaNNaN::teardownNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
\n", + "

1481080 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " metric_name timestamp metric_value check error \\\n", + "0 vus 2023-09-22 09:09:14 0.000000 NaN NaN \n", + "1 vus_max 2023-09-22 09:09:14 17.000000 NaN NaN \n", + "2 vus 2023-09-22 09:09:15 0.000000 NaN NaN \n", + "3 vus_max 2023-09-22 09:09:15 36.000000 NaN NaN \n", + "4 vus 2023-09-22 09:09:16 0.000000 NaN NaN \n", + "... ... ... ... ... ... \n", + "1481075 iteration_duration 2023-09-22 09:20:20 23005.156282 NaN NaN \n", + "1481076 iterations 2023-09-22 09:20:20 1.000000 NaN NaN \n", + "1481077 data_sent 2023-09-22 09:20:20 0.000000 NaN NaN \n", + "1481078 data_received 2023-09-22 09:20:20 0.000000 NaN NaN \n", + "1481079 iteration_duration 2023-09-22 09:20:20 0.005893 NaN NaN \n", + "\n", + " error_code expected_response group method name proto scenario \\\n", + "0 NaN NaN NaN NaN NaN NaN NaN \n", + "1 NaN NaN NaN NaN NaN NaN NaN \n", + "2 NaN NaN NaN NaN NaN NaN NaN \n", + "3 NaN NaN NaN NaN NaN NaN NaN \n", + "4 NaN NaN NaN NaN NaN NaN NaN \n", + "... ... ... ... ... ... ... ... \n", + "1481075 NaN NaN NaN NaN NaN NaN default \n", + "1481076 NaN NaN NaN NaN NaN NaN default \n", + "1481077 NaN NaN ::teardown NaN NaN NaN NaN \n", + "1481078 NaN NaN ::teardown NaN NaN NaN NaN \n", + "1481079 NaN NaN ::teardown NaN NaN NaN NaN \n", + "\n", + " service status subproto tls_version url extra_tags metadata \n", + "0 NaN NaN NaN NaN NaN NaN NaN \n", + "1 NaN NaN NaN NaN NaN NaN NaN \n", + "2 NaN NaN NaN NaN NaN NaN NaN \n", + "3 NaN NaN NaN NaN NaN NaN NaN \n", + "4 NaN NaN NaN NaN NaN NaN NaN \n", + "... ... ... ... ... ... ... ... \n", + "1481075 NaN NaN NaN NaN NaN NaN NaN \n", + "1481076 NaN NaN NaN NaN NaN NaN NaN \n", + "1481077 NaN NaN NaN NaN NaN NaN NaN \n", + "1481078 NaN NaN NaN NaN NaN NaN NaN \n", + "1481079 NaN NaN NaN NaN NaN NaN NaN \n", + "\n", + "[1481080 rows x 19 columns]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from bokeh.plotting import figure, show\n", + "from bokeh.io import output_notebook\n", + "\n", + "filename = \"./2023_09_22 002 k6_metrics.csv\"\n", + "df = pd.read_csv(filename, low_memory=False)\n", + "df[\"timestamp\"] = pd.to_datetime(df.timestamp, unit='s')\n", + "\n", + "output_notebook()\n", + "\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['vus', 'vus_max', 'data_sent', 'data_received',\n", + " 'iteration_duration', 'http_reqs', 'http_req_duration',\n", + " 'http_req_blocked', 'http_req_connecting',\n", + " 'http_req_tls_handshaking', 'http_req_sending', 'http_req_waiting',\n", + " 'http_req_receiving', 'http_req_failed', 'checks', 'iterations'],\n", + " dtype=object)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.metric_name.unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['metric_name', 'timestamp', 'metric_value', 'check', 'error',\n", + " 'error_code', 'expected_response', 'group', 'method', 'name', 'proto',\n", + " 'scenario', 'service', 'status', 'subproto', 'tls_version', 'url',\n", + " 'extra_tags', 'metadata'],\n", + " dtype='object')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
metric_nametimestampmetric_valuecheckerrorerror_codeexpected_responsegroupnameprotoscenarioservicesubprototls_versionextra_tagsmetadata
statusurlmethod
0.0https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulkPATCH777777077777707707700000
200.0https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulkPATCH10745910745910745900010745901074591074591074590010745900
https://api.staging.scorer.gitcoin.co/registry/submit-passportPOST274032740327403000274030274032740327403002740300
500.0https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulkPATCH1111110011110111111001100
502.0https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulkPATCH2065206520650020652065020652065206500206500
\n", + "
" + ], + "text/plain": [ + " metric_name \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " timestamp \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " metric_value \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " check \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " error \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " error_code \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " expected_response \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " group \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " name \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " proto \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " scenario \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 77 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " service \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " subproto \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " tls_version \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 107459 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 27403 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 11 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 2065 \n", + "\n", + " extra_tags \\\n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "\n", + " metadata \n", + "status url method \n", + "0.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "200.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + " https://api.staging.scorer.gitcoin.co/registry/... POST 0 \n", + "500.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 \n", + "502.0 https://api.staging.scorer.gitcoin.co/ceramic-c... PATCH 0 " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[df.metric_name == \"http_reqs\"].groupby(by=[\"status\", \"url\", \"method\"]).count()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n const docs_json = {\"aa2ccc60-d68d-48ee-a20b-6106abd51525\":{\"version\":\"3.1.1\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1001\",\"attributes\":{\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1002\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1003\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1015\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1017\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1004\",\"attributes\":{\"text\":\"Duration (status == 200)\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1090\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1084\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1085\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1086\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AACbdMKreEIAgNl0wqt4QgAAGHXCq3hCAIBWdcKreEIAAJV1wqt4QgCA03XCq3hCAAASdsKreEIAgFB2wqt4QgAAj3bCq3hCAIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hCAAC8rcKreEIAgPqtwqt4QgAAOa7Cq3hCAIB3rsKreEIAALauwqt4QgCA9K7Cq3hCAAAzr8KreEIAgHGvwqt4QgAAsK/Cq3hCAIDur8KreEIAAC2wwqt4QgCAa7DCq3hCAACqsMKreEIAgOiwwqt4QgAAJ7HCq3hCAIBlscKreEIAAKSxwqt4QgCA4rHCq3hCAAAhssKreEIAgF+ywqt4QgAAnrLCq3hCAIDcssKreEIAABuzwqt4QgCAWbPCq3hCAACYs8KreEIAgNazwqt4QgAAFbTCq3hCAIBTtMKreEIAAJK0wqt4QgCA0LTCq3hCAAAPtcKreEIAgE21wqt4QgAAjLXCq3hCAIDKtcKreEIAAAm2wqt4QgCAR7bCq3hCAACGtsKreEIAgMS2wqt4QgAAA7fCq3hCAIBBt8KreEIAAIC3wqt4QgCAvrfCq3hCAAD9t8KreEIAgDu4wqt4QgAAerjCq3hCAIC4uMKreEIAAPe4wqt4QgCANbnCq3hCAAB0ucKreEIAgLK5wqt4QgAA8bnCq3hCAIAvusKreEIAAG66wqt4QgCArLrCq3hCAADrusKreEIAgCm7wqt4QgAAaLvCq3hCAICmu8KreEIAAOW7wqt4QgCAI7zCq3hCAABivMKreEIAgKC8wqt4QgAA37zCq3hCAIAdvcKreEIAAFy9wqt4QgCAmr3Cq3hCAADZvcKreEIAgBe+wqt4QgAAVr7Cq3hCAICUvsKreEIAANO+wqt4QgCAEb/Cq3hCAABQv8KreEIAgI6/wqt4QgAAzb/Cq3hCAIALwMKreEIAAErAwqt4QgCAiMDCq3hCAADHwMKreEIAgAXBwqt4QgAARMHCq3hCAICCwcKreEIAAMHBwqt4QgCA/8HCq3hCAAA+wsKreEIAgHzCwqt4QgAAu8LCq3hCAID5wsKreEIAADjDwqt4QgCAdsPCq3hCAAC1w8KreEIAgPPDwqt4QgAAMsTCq3hCAIBwxMKreEIAAK/Ewqt4QgCA7cTCq3hCAAAsxcKreEIAgGrFwqt4QgAAqcXCq3hCAIDnxcKreEIAACbGwqt4QgCAZMbCq3hCAACjxsKreEIAgOHGwqt4QgAAIMfCq3hCAIBex8KreEIAAJ3Hwqt4QgCA28fCq3hCAAAayMKreEIAgFjIwqt4QgAAl8jCq3hCAIDVyMKreEIAABTJwqt4QgCAUsnCq3hCAACRycKreEIAgM/Jwqt4QgAADsrCq3hCAIBMysKreEIAAIvKwqt4QgCAycrCq3hCAAAIy8KreEIAgEbLwqt4QgAAhcvCq3hCAIDDy8KreEIAAALMwqt4QgCAQMzCq3hCAAB/zMKreEIAgL3Mwqt4QgAA/MzCq3hCAIA6zcKreEIAAHnNwqt4QgCAt83Cq3hCAAD2zcKreEIAgDTOwqt4QgAAc87Cq3hCAICxzsKreEIAAPDOwqt4QgCALs/Cq3hCAABtz8KreEIAgKvPwqt4QgAA6s/Cq3hCAIAo0MKreEIAAGfQwqt4QgCApdDCq3hCAADk0MKreEIAgCLRwqt4QgAAYdHCq3hCAICf0cKreEIAAN7Rwqt4QgCAHNLCq3hCAABb0sKreEIAgJnSwqt4QgAA2NLCq3hCAIAW08KreEIAAFXTwqt4QgCAk9PCq3hCAADS08KreEIAgBDUwqt4QgAAT9TCq3hCAICN1MKreEIAAMzUwqt4QgCACtXCq3hCAABJ1cKreEIAgIfVwqt4QgAAxtXCq3hCAIAE1sKreEIAAEPWwqt4QgCAgdbCq3hCAADA1sKreEIAgP7Wwqt4QgAAPdfCq3hCAIB718KreEIAALrXwqt4QgCA+NfCq3hCAAA32MKreEIAgHXYwqt4QgAAtNjCq3hCAIDy2MKreEIAADHZwqt4QgCAb9nCq3hCAACu2cKreEIAgOzZwqt4QgAAK9rCq3hCAIBp2sKreEIAAKjawqt4QgCA5trCq3hCAAAl28KreEIAgGPbwqt4QgAAotvCq3hCAIDg28KreEIAAB/cwqt4QgCAXdzCq3hCAACc3MKreEIAgNrcwqt4QgAAGd3Cq3hCAIBX3cKreEIAAJbdwqt4QgCA1N3Cq3hCAAAT3sKreEIAgFHewqt4QgAAkN7Cq3hCAIDO3sKreEIAAA3fwqt4QgCAS9/Cq3hCAACK38KreEIAgMjfwqt4QgAAB+DCq3hCAIBF4MKreEIAAITgwqt4QgCAwuDCq3hCAAAB4cKreEIAgD/hwqt4QgAAfuHCq3hCAIC84cKreEIAAPvhwqt4QgCAOeLCq3hCAAB44sKreEIAgLbiwqt4QgAA9eLCq3hCAIAz48KreEIAAHLjwqt4QgCAsOPCq3hCAADv48KreEIAgC3kwqt4QgAAbOTCq3hCAICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4Qg==\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1091\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1092\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1087\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"blue\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1088\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"blue\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1089\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"blue\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1101\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1095\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1096\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1097\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AACbdMKreEIAgNl0wqt4QgAAGHXCq3hCAIBWdcKreEIAAJV1wqt4QgCA03XCq3hCAAASdsKreEIAgFB2wqt4QgAAj3bCq3hCAIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hCAAC8rcKreEIAgPqtwqt4QgAAOa7Cq3hCAIB3rsKreEIAALauwqt4QgCA9K7Cq3hCAAAzr8KreEIAgHGvwqt4QgAAsK/Cq3hCAIDur8KreEIAAC2wwqt4QgCAa7DCq3hCAACqsMKreEIAgOiwwqt4QgAAJ7HCq3hCAIBlscKreEIAAKSxwqt4QgCA4rHCq3hCAAAhssKreEIAgF+ywqt4QgAAnrLCq3hCAIDcssKreEIAABuzwqt4QgCAWbPCq3hCAACYs8KreEIAgNazwqt4QgAAFbTCq3hCAIBTtMKreEIAAJK0wqt4QgCA0LTCq3hCAAAPtcKreEIAgE21wqt4QgAAjLXCq3hCAIDKtcKreEIAAAm2wqt4QgCAR7bCq3hCAACGtsKreEIAgMS2wqt4QgAAA7fCq3hCAIBBt8KreEIAAIC3wqt4QgCAvrfCq3hCAAD9t8KreEIAgDu4wqt4QgAAerjCq3hCAIC4uMKreEIAAPe4wqt4QgCANbnCq3hCAAB0ucKreEIAgLK5wqt4QgAA8bnCq3hCAIAvusKreEIAAG66wqt4QgCArLrCq3hCAADrusKreEIAgCm7wqt4QgAAaLvCq3hCAICmu8KreEIAAOW7wqt4QgCAI7zCq3hCAABivMKreEIAgKC8wqt4QgAA37zCq3hCAIAdvcKreEIAAFy9wqt4QgCAmr3Cq3hCAADZvcKreEIAgBe+wqt4QgAAVr7Cq3hCAICUvsKreEIAANO+wqt4QgCAEb/Cq3hCAABQv8KreEIAgI6/wqt4QgAAzb/Cq3hCAIALwMKreEIAAErAwqt4QgCAiMDCq3hCAADHwMKreEIAgAXBwqt4QgAARMHCq3hCAICCwcKreEIAAMHBwqt4QgCA/8HCq3hCAAA+wsKreEIAgHzCwqt4QgAAu8LCq3hCAID5wsKreEIAADjDwqt4QgCAdsPCq3hCAAC1w8KreEIAgPPDwqt4QgAAMsTCq3hCAIBwxMKreEIAAK/Ewqt4QgCA7cTCq3hCAAAsxcKreEIAgGrFwqt4QgAAqcXCq3hCAIDnxcKreEIAACbGwqt4QgCAZMbCq3hCAACjxsKreEIAgOHGwqt4QgAAIMfCq3hCAIBex8KreEIAAJ3Hwqt4QgCA28fCq3hCAAAayMKreEIAgFjIwqt4QgAAl8jCq3hCAIDVyMKreEIAABTJwqt4QgCAUsnCq3hCAACRycKreEIAgM/Jwqt4QgAADsrCq3hCAIBMysKreEIAAIvKwqt4QgCAycrCq3hCAAAIy8KreEIAgEbLwqt4QgAAhcvCq3hCAIDDy8KreEIAAALMwqt4QgCAQMzCq3hCAAB/zMKreEIAgL3Mwqt4QgAA/MzCq3hCAIA6zcKreEIAAHnNwqt4QgCAt83Cq3hCAAD2zcKreEIAgDTOwqt4QgAAc87Cq3hCAICxzsKreEIAAPDOwqt4QgCALs/Cq3hCAABtz8KreEIAgKvPwqt4QgAA6s/Cq3hCAIAo0MKreEIAAGfQwqt4QgCApdDCq3hCAADk0MKreEIAgCLRwqt4QgAAYdHCq3hCAICf0cKreEIAAN7Rwqt4QgCAHNLCq3hCAABb0sKreEIAgJnSwqt4QgAA2NLCq3hCAIAW08KreEIAAFXTwqt4QgCAk9PCq3hCAADS08KreEIAgBDUwqt4QgAAT9TCq3hCAICN1MKreEIAAMzUwqt4QgCACtXCq3hCAABJ1cKreEIAgIfVwqt4QgAAxtXCq3hCAIAE1sKreEIAAEPWwqt4QgCAgdbCq3hCAADA1sKreEIAgP7Wwqt4QgAAPdfCq3hCAIB718KreEIAALrXwqt4QgCA+NfCq3hCAAA32MKreEIAgHXYwqt4QgAAtNjCq3hCAIDy2MKreEIAADHZwqt4QgCAb9nCq3hCAACu2cKreEIAgOzZwqt4QgAAK9rCq3hCAIBp2sKreEIAAKjawqt4QgCA5trCq3hCAAAl28KreEIAgGPbwqt4QgAAotvCq3hCAIDg28KreEIAAB/cwqt4QgCAXdzCq3hCAACc3MKreEIAgNrcwqt4QgAAGd3Cq3hCAIBX3cKreEIAAJbdwqt4QgCA1N3Cq3hCAAAT3sKreEIAgFHewqt4QgAAkN7Cq3hCAIDO3sKreEIAAA3fwqt4QgCAS9/Cq3hCAACK38KreEIAgMjfwqt4QgAAB+DCq3hCAIBF4MKreEIAAITgwqt4QgCAwuDCq3hCAAAB4cKreEIAgD/hwqt4QgAAfuHCq3hCAIC84cKreEIAAPvhwqt4QgCAOeLCq3hCAAB44sKreEIAgLbiwqt4QgAA9eLCq3hCAIAz48KreEIAAHLjwqt4QgCAsOPCq3hCAADv48KreEIAgC3kwqt4QgAAbOTCq3hCAICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4Qg==\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1102\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1103\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1098\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1099\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1100\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1111\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1105\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1106\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1107\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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AAB44sKreEIAgLbiwqt4QgAA9eLCq3hCAIAz48KreEIAAHLjwqt4QgCAsOPCq3hCAADv48KreEIAgC3kwqt4QgAAbOTCq3hCAICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4Qg==\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1112\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1113\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1108\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1109\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1110\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"green\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1121\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1115\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1116\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1117\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hC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AICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4QgAAggrDq3hC\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1122\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1123\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1118\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"purple\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1119\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"purple\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1120\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"purple\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1131\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1125\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1126\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1127\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hC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AICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4QgAAggrDq3hC\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1132\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1133\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1128\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1129\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1130\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1141\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1135\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1136\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1137\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hC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AICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4QgAAggrDq3hC\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1142\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1143\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1138\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"teal\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1139\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"teal\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1140\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"teal\",\"line_alpha\":0.2,\"line_width\":2}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1006\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1069\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1070\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1071\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1072\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1073\"},{\"type\":\"object\",\"name\":\"HoverTool\",\"id\":\"p1074\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"CrosshairTool\",\"id\":\"p1075\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1062\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1063\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1065\"},\"axis_label\":\"y\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1064\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"DatetimeAxis\",\"id\":\"p1019\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"DatetimeTicker\",\"id\":\"p1020\",\"attributes\":{\"num_minor_ticks\":5,\"tickers\":[{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1021\",\"attributes\":{\"num_minor_ticks\":0,\"mantissas\":[1,2,5],\"max_interval\":500.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1022\",\"attributes\":{\"num_minor_ticks\":0,\"base\":60,\"mantissas\":[1,2,5,10,15,20,30],\"min_interval\":1000.0,\"max_interval\":1800000.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1023\",\"attributes\":{\"num_minor_ticks\":0,\"base\":24,\"mantissas\":[1,2,4,6,8,12],\"min_interval\":3600000.0,\"max_interval\":43200000.0}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1024\",\"attributes\":{\"days\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1025\",\"attributes\":{\"days\":[1,4,7,10,13,16,19,22,25,28]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1026\",\"attributes\":{\"days\":[1,8,15,22]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1027\",\"attributes\":{\"days\":[1,15]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1028\",\"attributes\":{\"months\":[0,1,2,3,4,5,6,7,8,9,10,11]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1029\",\"attributes\":{\"months\":[0,2,4,6,8,10]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1030\",\"attributes\":{\"months\":[0,4,8]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1031\",\"attributes\":{\"months\":[0,6]}},{\"type\":\"object\",\"name\":\"YearsTicker\",\"id\":\"p1032\"}]}},\"formatter\":{\"type\":\"object\",\"name\":\"DatetimeTickFormatter\",\"id\":\"p1034\"},\"axis_label\":\"x\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1033\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1061\",\"attributes\":{\"axis\":{\"id\":\"p1019\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1068\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1062\"}}},{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p1093\",\"attributes\":{\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1094\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"min - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p1090\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1104\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"max - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p1101\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1114\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"mean - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p1111\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1124\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"min - https://api.staging.scorer.gitcoin.co/registry/submit-passport\"},\"renderers\":[{\"id\":\"p1121\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1134\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"max - https://api.staging.scorer.gitcoin.co/registry/submit-passport\"},\"renderers\":[{\"id\":\"p1131\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1144\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"mean - https://api.staging.scorer.gitcoin.co/registry/submit-passport\"},\"renderers\":[{\"id\":\"p1141\"}]}}]}}],\"frame_width\":1500}}],\"callbacks\":{\"type\":\"map\"}}};\n const render_items = [{\"docid\":\"aa2ccc60-d68d-48ee-a20b-6106abd51525\",\"roots\":{\"p1001\":\"a97f43be-a73a-4abc-871c-3fd3af0604aa\"},\"root_ids\":[\"p1001\"]}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1001" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "df_duration = df[df.metric_name == \"http_req_duration\"]\n", + "\n", + "dft = df_duration.set_index(\"timestamp\")\n", + "\n", + "dfts = dft.groupby(by=[\"url\", \"status\"]).resample(\"s\").agg({\n", + " \"metric_value\": [\"min\", \"max\", \"mean\", \"count\"]\n", + "})\n", + "\n", + "dfts.reset_index(inplace=True)\n", + "dfts.set_index(\"timestamp\", inplace=True)\n", + "\n", + "colors = [\n", + " \"blue\",\n", + " \"red\",\n", + " \"green\",\n", + " \"purple\",\n", + " \"orange\",\n", + " \"teal\",\n", + " \"pink\",\n", + " \"yellow\",\n", + " \"cyan\",\n", + " \"maroon\",\n", + " \"olive\",\n", + " \"navy\",\n", + " \"magenta\",\n", + " \"brown\",\n", + " \"slate gray\",\n", + " \"forest green\",\n", + " \"lavender\",\n", + " \"coral\",\n", + " \"turquoise\",\n", + " \"gold\"\n", + "]\n", + "\n", + "\n", + "color = iter(colors)\n", + "p = figure(title=\"Duration (status == 200)\", x_axis_label='x', y_axis_label='y', frame_width=1500,\n", + " tools=\"pan,wheel_zoom,box_zoom,reset,hover,crosshair\",\n", + " x_axis_type=\"datetime\")\n", + "\n", + "for idx, ((url, status), group) in enumerate(dfts.groupby(by=[\"url\", \"status\"])):\n", + " if int(status) == 200:\n", + " p.line(group.index, group[\"metric_value\"][\"min\"], legend_label=f\"min - {url}\", line_width=2, color=next(color))\n", + " p.line(group.index, group[\"metric_value\"][\"max\"], legend_label=f\"max - {url}\", line_width=2, color=next(color))\n", + " p.line(group.index, group[\"metric_value\"][\"mean\"], legend_label=f\"mean - {url}\", line_width=2, color=next(color))\n", + "\n", + "\n", + "show(p)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n const docs_json = {\"3cbe3f6d-7cf6-4d89-9f66-e8e488512671\":{\"version\":\"3.1.1\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1547\",\"attributes\":{\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1548\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1549\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1561\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1563\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1550\",\"attributes\":{\"text\":\"Req / second (status == 200)\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1636\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1630\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1631\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1632\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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AAB44sKreEIAgLbiwqt4QgAA9eLCq3hCAIAz48KreEIAAHLjwqt4QgCAsOPCq3hCAADv48KreEIAgC3kwqt4QgAAbOTCq3hCAICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4Qg==\"},\"shape\":[614],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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\"},\"shape\":[614],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1637\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1638\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1633\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1634\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1635\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"red\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p1647\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p1641\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p1642\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p1643\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIDNdsKreEIAAAx3wqt4QgCASnfCq3hCAACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hC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AICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4QgAAlAfDq3hCAIDSB8OreEIAABEIw6t4QgCATwjDq3hCAACOCMOreEIAgMwIw6t4QgAACwnDq3hCAIBJCcOreEIAAIgJw6t4QgCAxgnDq3hCAAAFCsOreEIAgEMKw6t4QgAAggrDq3hC\"},\"shape\":[606],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"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TwAAAEAAAABIAAAASQAAAEkAAABBAAAAQQAAAEkAAABJAAAASQAAAD4AAABGAAAASAAAAEIAAABGAAAAPwAAADYAAABKAAAAQgAAAFMAAAA5AAAARwAAAEkAAABNAAAASwAAAFMAAABGAAAANQAAAEYAAABGAAAARgAAAFQAAABBAAAAPwAAAEQAAAA/AAAATgAAADoAAABSAAAASQAAAE4AAAA+AAAAQAAAAD8AAABJAAAASgAAACYAAABGAAAARAAAAFEAAABNAAAAPwAAAFkAAAA2AAAATgAAAD8AAABMAAAAUQAAAEYAAABKAAAAPgAAAEAAAABEAAAAVAAAAE0AAAA/AAAAPgAAAFcAAABAAAAARQAAAEEAAAA9AAAATQAAAD0AAABNAAAATAAAACwAAAA5AAAATQAAAE4AAAA9AAAASwAAADkAAABOAAAARwAAAFAAAABQAAAAPgAAAEkAAABIAAAANwAAAFIAAAA/AAAAQgAAAEoAAABAAAAARAAAAEcAAABAAAAATAAAAD8AAABJAAAASwAAAEIAAABBAAAAOwAAAFYAAABCAAAASwAAAEgAAAAzAAAARgAAAEYAAABEAAAAQQAAAEsAAABBAAAATQAAAD0AAAA6AAAAVwAAAEQAAAA5AAAATAAAAD8AAABBAAAAQgAAAE0AAABKAAAARwAAAEUAAABHAAAAPwAAAFUAAAA6AAAASAAAACUAAABQAAAAQwAAAEgAAABNAAAAUwAAAD8AAABVAAAAVwAAAGoAAABcAAAASAAAACwAAAAnAAAAKAAAACUAAAA0AAAAMAAAADsAAAAMAAAA\"},\"shape\":[606],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p1648\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p1649\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1644\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1645\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p1646\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"orange\",\"line_alpha\":0.2,\"line_width\":2}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1552\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p1615\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p1616\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p1617\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p1618\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p1619\"},{\"type\":\"object\",\"name\":\"HoverTool\",\"id\":\"p1620\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"CrosshairTool\",\"id\":\"p1621\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p1608\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p1609\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p1611\"},\"axis_label\":\"y\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1610\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"DatetimeAxis\",\"id\":\"p1565\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"DatetimeTicker\",\"id\":\"p1566\",\"attributes\":{\"num_minor_ticks\":5,\"tickers\":[{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1567\",\"attributes\":{\"num_minor_ticks\":0,\"mantissas\":[1,2,5],\"max_interval\":500.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1568\",\"attributes\":{\"num_minor_ticks\":0,\"base\":60,\"mantissas\":[1,2,5,10,15,20,30],\"min_interval\":1000.0,\"max_interval\":1800000.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1569\",\"attributes\":{\"num_minor_ticks\":0,\"base\":24,\"mantissas\":[1,2,4,6,8,12],\"min_interval\":3600000.0,\"max_interval\":43200000.0}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1570\",\"attributes\":{\"days\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1571\",\"attributes\":{\"days\":[1,4,7,10,13,16,19,22,25,28]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1572\",\"attributes\":{\"days\":[1,8,15,22]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1573\",\"attributes\":{\"days\":[1,15]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1574\",\"attributes\":{\"months\":[0,1,2,3,4,5,6,7,8,9,10,11]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1575\",\"attributes\":{\"months\":[0,2,4,6,8,10]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1576\",\"attributes\":{\"months\":[0,4,8]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p1577\",\"attributes\":{\"months\":[0,6]}},{\"type\":\"object\",\"name\":\"YearsTicker\",\"id\":\"p1578\"}]}},\"formatter\":{\"type\":\"object\",\"name\":\"DatetimeTickFormatter\",\"id\":\"p1580\"},\"axis_label\":\"x\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p1579\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1607\",\"attributes\":{\"axis\":{\"id\":\"p1565\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p1614\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p1608\"}}},{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p1639\",\"attributes\":{\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1640\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"200 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p1636\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p1650\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"200 - https://api.staging.scorer.gitcoin.co/registry/submit-passport\"},\"renderers\":[{\"id\":\"p1647\"}]}}]}}],\"frame_width\":1500}}],\"callbacks\":{\"type\":\"map\"}}};\n const render_items = [{\"docid\":\"3cbe3f6d-7cf6-4d89-9f66-e8e488512671\",\"roots\":{\"p1547\":\"fa9485a8-2af0-4568-9863-2f2d5625ad44\"},\"root_ids\":[\"p1547\"]}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1547" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "df_duration = df[df.metric_name == \"http_req_duration\"]\n", + "\n", + "dft = df_duration.set_index(\"timestamp\")\n", + "\n", + "dfts = dft.groupby(by=[\"url\", \"status\"]).resample(\"s\").agg({\n", + " \"metric_value\": [\"min\", \"max\", \"mean\", \"count\"]\n", + "})\n", + "\n", + "dfts.reset_index(inplace=True)\n", + "dfts.set_index(\"timestamp\", inplace=True)\n", + "\n", + "colors = [\n", + " \"blue\",\n", + " \"red\",\n", + " \"green\",\n", + " \"purple\",\n", + " \"orange\",\n", + " \"teal\",\n", + " \"pink\",\n", + " \"yellow\",\n", + " \"cyan\",\n", + " \"maroon\",\n", + " \"olive\",\n", + " \"navy\",\n", + " \"magenta\",\n", + " \"brown\",\n", + " \"slate gray\",\n", + " \"forest green\",\n", + " \"lavender\",\n", + " \"coral\",\n", + " \"turquoise\",\n", + " \"gold\"\n", + "]\n", + "\n", + "\n", + "p = figure(title=\"Req / second (status == 200)\", x_axis_label='x', y_axis_label='y', frame_width=1500,\n", + " tools=\"pan,wheel_zoom,box_zoom,reset,hover,crosshair\",\n", + " x_axis_type=\"datetime\")\n", + "\n", + "for idx, ((url, status), group) in enumerate(dfts.groupby(by=[\"url\", \"status\"])):\n", + " if int(status) == 200:\n", + " p.line(group.index, group[\"metric_value\"][\"count\"], legend_label=f\"{int(status)} - {url}\", line_width=2, color=colors[idx])\n", + "\n", + "\n", + "show(p)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk: 77\n", + "200 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk: 107459\n", + "500 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk: 11\n", + "502 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk: 2065\n", + "200 - https://api.staging.scorer.gitcoin.co/registry/submit-passport: 27403\n", + " 200 134862\n", + " non - 200 2153\n", + " % success 0.9842863920008759\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n const docs_json = {\"1b7bbff9-74a8-43e6-8ab7-943aa43fd8b6\":{\"version\":\"3.1.1\",\"title\":\"Bokeh Application\",\"defs\":[],\"roots\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p1975\",\"attributes\":{\"x_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1976\"},\"y_range\":{\"type\":\"object\",\"name\":\"DataRange1d\",\"id\":\"p1977\"},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1989\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p1991\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p1978\",\"attributes\":{\"text\":\"Req / second (status != 200)\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2064\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2058\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2059\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2060\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIANlsKreEIAAEyWwqt4QgCAipbCq3hCAADJlsKreEIAgAeXwqt4QgAARpfCq3hCAICEl8KreEIAAMOXwqt4QgCAAZjCq3hCAABAmMKreEIAgH6Ywqt4QgAAvZjCq3hCAID7mMKreEIAADqZwqt4QgCAeJnCq3hCAAC3mcKreEIAgPWZwqt4QgAANJrCq3hCAIBymsKreEIAALGawqt4QgCA75rCq3hCAAAum8KreEIAgGybwqt4QgAAq5vCq3hCAIDpm8KreEIAACicwqt4QgCAZpzCq3hCAAClnMKreEIAgOOcwqt4QgAAIp3Cq3hCAIBgncKreEIAAJ+dwqt4QgCA3Z3Cq3hCAAAcnsKreEIAgFqewqt4QgAAmZ7Cq3hCAIDXnsKreEIAABafwqt4QgCAVJ/Cq3hCAACTn8KreEIAgNGfwqt4QgAAEKDCq3hCAIBOoMKreEIAAI2gwqt4QgCAy6DCq3hCAAAKocKreEIAgEihwqt4QgAAh6HCq3hCAIDFocKreEIAAASiwqt4QgCAQqLCq3hCAACBosKreEIAgL+iwqt4QgAA/qLCq3hCAIA8o8KreEIAAHujwqt4QgCAuaPCq3hCAAD4o8KreEIAgDakwqt4QgAAdaTCq3hCAICzpMKreEIAAPKkwqt4QgCAMKXCq3hCAABvpcKreEIAgK2lwqt4QgAA7KXCq3hCAIAqpsKreEIAAGmmwqt4QgCAp6bCq3hCAADmpsKreEIAgCSnwqt4QgAAY6fCq3hCAIChp8KreEIAAOCnwqt4QgCAHqjCq3hCAABdqMKreEIAgJuowqt4QgAA2qjCq3hCAIAYqcKreEIAAFepwqt4QgCAlanCq3hCAADUqcKreEIAgBKqwqt4QgAAUarCq3hCAICPqsKreEIAAM6qwqt4QgCADKvCq3hCAABLq8KreEIAgImrwqt4QgAAyKvCq3hCAIAGrMKreEIAAEWswqt4QgCAg6zCq3hCAADCrMKreEIAgACtwqt4QgAAP63Cq3hCAIB9rcKreEIAALytwqt4QgCA+q3Cq3hCAAA5rsKreEIAgHeuwqt4QgAAtq7Cq3hCAID0rsKreEIAADOvwqt4QgCAca/Cq3hCAACwr8KreEIAgO6vwqt4QgAALbDCq3hCAIBrsMKreEIAAKqwwqt4QgCA6LDCq3hCAAAnscKreEIAgGWxwqt4QgAApLHCq3hCAIDiscKreEIAACGywqt4QgCAX7LCq3hCAACessKreEIAgNyywqt4QgAAG7PCq3hCAIBZs8KreEIAAJizwqt4QgCA1rPCq3hCAAAVtMKreEIAgFO0wqt4QgAAkrTCq3hCAIDQtMKreEIAAA+1wqt4QgCATbXCq3hCAACMtcKreEIAgMq1wqt4QgAACbbCq3hCAIBHtsKreEIAAIa2wqt4QgCAxLbCq3hCAAADt8KreEIAgEG3wqt4QgAAgLfCq3hCAIC+t8KreEIAAP23wqt4QgCAO7jCq3hCAAB6uMKreEIAgLi4wqt4QgAA97jCq3hCAIA1ucKreEIAAHS5wqt4QgCAsrnCq3hCAADxucKreEIAgC+6wqt4QgAAbrrCq3hCAICsusKreEIAAOu6wqt4QgCAKbvCq3hCAABou8KreEIAgKa7wqt4QgAA5bvCq3hCAIAjvMKreEIAAGK8wqt4QgCAoLzCq3hCAADfvMKreEIAgB29wqt4QgAAXL3Cq3hCAICavcKreEIAANm9wqt4QgCAF77Cq3hCAABWvsKreEIAgJS+wqt4QgAA077Cq3hCAIARv8KreEIAAFC/wqt4QgCAjr/Cq3hCAADNv8KreEIAgAvAwqt4QgAASsDCq3hCAICIwMKreEIAAMfAwqt4QgCABcHCq3hCAABEwcKreEIAgILBwqt4QgAAwcHCq3hCAID/wcKreEIAAD7Cwqt4QgCAfMLCq3hCAAC7wsKreEIAgPnCwqt4QgAAOMPCq3hCAIB2w8KreEIAALXDwqt4QgCA88PCq3hCAAAyxMKreEIAgHDEwqt4QgAAr8TCq3hCAIDtxMKreEIAACzFwqt4QgCAasXCq3hCAACpxcKreEIAgOfFwqt4QgAAJsbCq3hCAIBkxsKreEIAAKPGwqt4QgCA4cbCq3hCAAAgx8KreEIAgF7Hwqt4QgAAncfCq3hCAIDbx8KreEIAABrIwqt4QgCAWMjCq3hCAACXyMKreEIAgNXIwqt4QgAAFMnCq3hCAIBSycKreEIAAJHJwqt4QgCAz8nCq3hCAAAOysKreEIAgEzKwqt4QgAAi8rCq3hCAIDJysKreEIAAAjLwqt4QgCARsvCq3hCAACFy8KreEIAgMPLwqt4QgAAAszCq3hCAIBAzMKreEIAAH/Mwqt4QgCAvczCq3hCAAD8zMKreEIAgDrNwqt4QgAAec3Cq3hCAIC3zcKreEIAAPbNwqt4QgCANM7Cq3hCAABzzsKreEIAgLHOwqt4QgAA8M7Cq3hCAIAuz8KreEIAAG3Pwqt4QgCAq8/Cq3hCAADqz8KreEIAgCjQwqt4QgAAZ9DCq3hCAICl0MKreEIAAOTQwqt4QgCAItHCq3hCAABh0cKreEIAgJ/Rwqt4QgAA3tHCq3hCAIAc0sKreEIAAFvSwqt4QgCAmdLCq3hCAADY0sKreEIAgBbTwqt4QgAAVdPCq3hCAICT08KreEIAANLTwqt4QgCAENTCq3hCAABP1MKreEIAgI3Uwqt4QgAAzNTCq3hCAIAK1cKreEIAAEnVwqt4QgCAh9XCq3hCAADG1cKreEIAgATWwqt4QgAAQ9bCq3hCAICB1sKreEIAAMDWwqt4QgCA/tbCq3hCAAA918KreEIAgHvXwqt4QgAAutfCq3hCAID418KreEIAADfYwqt4QgCAddjCq3hCAAC02MKreEIAgPLYwqt4QgAAMdnCq3hCAIBv2cKreEIAAK7Zwqt4QgCA7NnCq3hCAAAr2sKreEIAgGnawqt4QgAAqNrCq3hCAIDm2sKreEIAACXbwqt4QgCAY9vCq3hCAACi28KreEIAgODbwqt4QgAAH9zCq3hCAIBd3MKreEIAAJzcwqt4QgCA2tzCq3hCAAAZ3cKreEIAgFfdwqt4QgAAlt3Cq3hCAIDU3cKreEIAABPewqt4QgCAUd7Cq3hCAACQ3sKreEIAgM7ewqt4QgAADd/Cq3hCAIBL38KreEIAAIrfwqt4QgCAyN/Cq3hCAAAH4MKreEIAgEXgwqt4QgAAhODCq3hCAIDC4MKreEI=\"},\"shape\":[307],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAEAAAAAAAAAAAAAAAEAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAgAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAIAAAAAAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAAgAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAACAAAAAQAAAAMAAAAAAAAAAAAAAAIAAAABAAAAAQAAAAIAAAABAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA==\"},\"shape\":[307],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2065\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2066\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2061\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2062\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2063\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2075\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2069\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2070\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2071\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AIAYqcKreEIAAFepwqt4QgCAlanCq3hCAADUqcKreEIAgBKqwqt4QgAAUarCq3hCAICPqsKreEIAAM6qwqt4QgCADKvCq3hCAABLq8KreEIAgImrwqt4QgAAyKvCq3hCAIAGrMKreEIAAEWswqt4QgCAg6zCq3hCAADCrMKreEIAgACtwqt4QgAAP63Cq3hCAIB9rcKreEIAALytwqt4QgCA+q3Cq3hCAAA5rsKreEIAgHeuwqt4QgAAtq7Cq3hCAID0rsKreEIAADOvwqt4QgCAca/Cq3hCAACwr8KreEIAgO6vwqt4QgAALbDCq3hCAIBrsMKreEIAAKqwwqt4QgCA6LDCq3hCAAAnscKreEIAgGWxwqt4QgAApLHCq3hCAIDiscKreEIAACGywqt4QgCAX7LCq3hCAACessKreEIAgNyywqt4QgAAG7PCq3hCAIBZs8KreEIAAJizwqt4QgCA1rPCq3hCAAAVtMKreEIAgFO0wqt4QgAAkrTCq3hCAIDQtMKreEIAAA+1wqt4QgCATbXCq3hCAACMtcKreEIAgMq1wqt4QgAACbbCq3hCAIBHtsKreEIAAIa2wqt4QgCAxLbCq3hCAAADt8KreEIAgEG3wqt4QgAAgLfCq3hCAIC+t8KreEIAAP23wqt4QgCAO7jCq3hCAAB6uMKreEIAgLi4wqt4QgAA97jCq3hCAIA1ucKreEIAAHS5wqt4QgCAsrnCq3hCAADxucKreEIAgC+6wqt4QgAAbrrCq3hCAICsusKreEIAAOu6wqt4QgCAKbvCq3hCAABou8KreEIAgKa7wqt4QgAA5bvCq3hCAIAjvMKreEIAAGK8wqt4QgCAoLzCq3hCAADfvMKreEIAgB29wqt4QgAAXL3Cq3hCAICavcKreEIAANm9wqt4QgCAF77Cq3hCAABWvsKreEIAgJS+wqt4QgAA077Cq3hCAIARv8KreEIAAFC/wqt4QgCAjr/Cq3hCAADNv8KreEIAgAvAwqt4QgAASsDCq3hCAICIwMKreEIAAMfAwqt4QgCABcHCq3hCAABEwcKreEIAgILBwqt4QgAAwcHCq3hCAID/wcKreEIAAD7Cwqt4QgCAfMLCq3hCAAC7wsKreEIAgPnCwqt4QgAAOMPCq3hCAIB2w8KreEIAALXDwqt4QgCA88PCq3hCAAAyxMKreEIAgHDEwqt4QgAAr8TCq3hCAIDtxMKreEIAACzFwqt4QgCAasXCq3hCAACpxcKreEIAgOfFwqt4QgAAJsbCq3hCAIBkxsKreEIAAKPGwqt4QgCA4cbCq3hCAAAgx8KreEIAgF7Hwqt4QgAAncfCq3hCAIDbx8KreEIAABrIwqt4QgCAWMjCq3hCAACXyMKreEIAgNXIwqt4QgAAFMnCq3hCAIBSycKreEIAAJHJwqt4QgCAz8nCq3hCAAAOysKreEIAgEzKwqt4QgAAi8rCq3hCAIDJysKreEIAAAjLwqt4QgCARsvCq3hCAACFy8KreEIAgMPLwqt4QgAAAszCq3hCAIBAzMKreEIAAH/Mwqt4QgCAvczCq3hCAAD8zMKreEIAgDrNwqt4QgAAec3Cq3hCAIC3zcKreEIAAPbNwqt4QgCANM7Cq3hCAABzzsKreEIAgLHOwqt4QgAA8M7Cq3hCAIAuz8KreEIAAG3Pwqt4QgCAq8/Cq3hCAADqz8KreEIAgCjQwqt4QgAAZ9DCq3hCAICl0MKreEIAAOTQwqt4QgCAItHCq3hCAABh0cKreEIAgJ/Rwqt4QgAA3tHCq3hCAIAc0sKreEIAAFvSwqt4QgCAmdLCq3hCAADY0sKreEIAgBbTwqt4QgAAVdPCq3hCAICT08KreEIAANLTwqt4QgCAENTCq3hCAABP1MKreEIAgI3Uwqt4QgAAzNTCq3hCAIAK1cKreEIAAEnVwqt4QgCAh9XCq3hCAADG1cKreEIAgATWwqt4QgAAQ9bCq3hCAICB1sKreEIAAMDWwqt4QgCA/tbCq3hCAAA918KreEIAgHvXwqt4QgAAutfCq3hCAID418KreEIAADfYwqt4QgCAddjCq3hCAAC02MKreEIAgPLYwqt4QgAAMdnCq3hCAIBv2cKreEIAAK7Zwqt4QgCA7NnCq3hCAAAr2sKreEIAgGnawqt4QgAAqNrCq3hCAIDm2sKreEIAACXbwqt4QgCAY9vCq3hCAACi28KreEIAgODbwqt4QgAAH9zCq3hCAIBd3MKreEIAAJzcwqt4QgCA2tzCq3hCAAAZ3cKreEIAgFfdwqt4QgAAlt3Cq3hCAIDU3cKreEIAABPewqt4QgCAUd7Cq3hCAACQ3sKreEIAgM7ewqt4QgAADd/Cq3hCAIBL38KreEIAAIrfwqt4QgCAyN/Cq3hCAAAH4MKreEIAgEXgwqt4QgAAhODCq3hCAIDC4MKreEIAAAHhwqt4QgCAP+HCq3hCAAB+4cKreEIAgLzhwqt4QgAA++HCq3hCAIA54sKreEIAAHjiwqt4QgCAtuLCq3hCAAD14sKreEIAgDPjwqt4QgAAcuPCq3hCAICw48KreEIAAO/jwqt4QgCALeTCq3hCAABs5MKreEIAgKrkwqt4QgAA6eTCq3hCAIAn5cKreEIAAGblwqt4QgCApOXCq3hCAADj5cKreEIAgCHmwqt4QgAAYObCq3hCAICe5sKreEIAAN3mwqt4QgCAG+fCq3hCAABa58KreEIAgJjnwqt4QgAA1+fCq3hCAIAV6MKreEIAAFTowqt4QgCAkujCq3hCAADR6MKreEIAgA/pwqt4QgAATunCq3hCAICM6cKreEIAAMvpwqt4QgCACerCq3hCAABI6sKreEIAgIbqwqt4QgAAxerCq3hCAIAD68KreEIAAELrwqt4QgCAgOvCq3hCAAC/68KreEIAgP3rwqt4QgAAPOzCq3hCAIB67MKreEIAALnswqt4QgCA9+zCq3hCAAA27cKreEIAgHTtwqt4QgAAs+3Cq3hCAIDx7cKreEIAADDuwqt4QgCAbu7Cq3hCAACt7sKreEIAgOvuwqt4QgAAKu/Cq3hCAIBo78KreEIAAKfvwqt4QgCA5e/Cq3hCAAAk8MKreEIAgGLwwqt4QgAAofDCq3hCAIDf8MKreEIAAB7xwqt4QgCAXPHCq3hCAACb8cKreEIAgNnxwqt4QgAAGPLCq3hCAIBW8sKreEIAAJXywqt4QgCA0/LCq3hCAAAS88KreEIAgFDzwqt4QgAAj/PCq3hCAIDN88KreEIAAAz0wqt4QgCASvTCq3hCAACJ9MKreEIAgMf0wqt4QgAABvXCq3hCAIBE9cKreEIAAIP1wqt4QgCAwfXCq3hCAAAA9sKreEIAgD72wqt4QgAAffbCq3hCAIC79sKreEIAAPr2wqt4QgCAOPfCq3hCAAB398KreEIAgLX3wqt4QgAA9PfCq3hCAIAy+MKreEIAAHH4wqt4QgCAr/jCq3hCAADu+MKreEIAgCz5wqt4QgAAa/nCq3hCAICp+cKreEIAAOj5wqt4QgCAJvrCq3hCAABl+sKreEIAgKP6wqt4QgAA4vrCq3hCAIAg+8KreEIAAF/7wqt4Qg==\"},\"shape\":[338],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA=\"},\"shape\":[338],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2076\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2077\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2072\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2073\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2074\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.2,\"line_width\":2}}}},{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2085\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2079\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2080\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2081\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AACJd8KreEIAgMd3wqt4QgAABnjCq3hCAIBEeMKreEIAAIN4wqt4QgCAwXjCq3hCAAAAecKreEIAgD55wqt4QgAAfXnCq3hCAIC7ecKreEIAAPp5wqt4QgCAOHrCq3hCAAB3esKreEIAgLV6wqt4QgAA9HrCq3hCAIAye8KreEIAAHF7wqt4QgCAr3vCq3hCAADue8KreEIAgCx8wqt4QgAAa3zCq3hCAICpfMKreEIAAOh8wqt4QgCAJn3Cq3hCAABlfcKreEIAgKN9wqt4QgAA4n3Cq3hCAIAgfsKreEIAAF9+wqt4QgCAnX7Cq3hCAADcfsKreEIAgBp/wqt4QgAAWX/Cq3hCAICXf8KreEIAANZ/wqt4QgCAFIDCq3hCAABTgMKreEIAgJGAwqt4QgAA0IDCq3hCAIAOgcKreEIAAE2Bwqt4QgCAi4HCq3hCAADKgcKreEIAgAiCwqt4QgAAR4LCq3hCAICFgsKreEIAAMSCwqt4QgCAAoPCq3hCAABBg8KreEIAgH+Dwqt4QgAAvoPCq3hCAID8g8KreEIAADuEwqt4QgCAeYTCq3hCAAC4hMKreEIAgPaEwqt4QgAANYXCq3hCAIBzhcKreEIAALKFwqt4QgCA8IXCq3hCAAAvhsKreEIAgG2Gwqt4QgAArIbCq3hCAIDqhsKreEIAACmHwqt4QgCAZ4fCq3hCAACmh8KreEIAgOSHwqt4QgAAI4jCq3hCAIBhiMKreEIAAKCIwqt4QgCA3ojCq3hCAAAdicKreEIAgFuJwqt4QgAAmonCq3hCAIDYicKreEIAABeKwqt4QgCAVYrCq3hCAACUisKreEIAgNKKwqt4QgAAEYvCq3hCAIBPi8KreEIAAI6Lwqt4QgCAzIvCq3hCAAALjMKreEIAgEmMwqt4QgAAiIzCq3hCAIDGjMKreEIAAAWNwqt4QgCAQ43Cq3hCAACCjcKreEIAgMCNwqt4QgAA/43Cq3hCAIA9jsKreEIAAHyOwqt4QgCAuo7Cq3hCAAD5jsKreEIAgDePwqt4QgAAdo/Cq3hCAIC0j8KreEIAAPOPwqt4QgCAMZDCq3hCAABwkMKreEIAgK6Qwqt4QgAA7ZDCq3hCAIArkcKreEIAAGqRwqt4QgCAqJHCq3hCAADnkcKreEIAgCWSwqt4QgAAZJLCq3hCAICiksKreEIAAOGSwqt4QgCAH5PCq3hCAABek8KreEIAgJyTwqt4QgAA25PCq3hCAIAZlMKreEIAAFiUwqt4QgCAlpTCq3hCAADVlMKreEIAgBOVwqt4QgAAUpXCq3hCAICQlcKreEIAAM+Vwqt4QgCADZbCq3hCAABMlsKreEIAgIqWwqt4QgAAyZbCq3hCAIAHl8KreEIAAEaXwqt4QgCAhJfCq3hCAADDl8KreEIAgAGYwqt4QgAAQJjCq3hCAIB+mMKreEIAAL2Ywqt4QgCA+5jCq3hCAAA6mcKreEIAgHiZwqt4QgAAt5nCq3hCAID1mcKreEIAADSawqt4QgCAcprCq3hCAACxmsKreEIAgO+awqt4QgAALpvCq3hCAIBsm8KreEIAAKubwqt4QgCA6ZvCq3hCAAAonMKreEIAgGacwqt4QgAApZzCq3hCAIDjnMKreEIAACKdwqt4QgCAYJ3Cq3hCAACfncKreEIAgN2dwqt4QgAAHJ7Cq3hCAIBansKreEIAAJmewqt4QgCA157Cq3hCAAAWn8KreEIAgFSfwqt4QgAAk5/Cq3hCAIDRn8KreEIAABCgwqt4QgCATqDCq3hCAACNoMKreEIAgMugwqt4QgAACqHCq3hCAIBIocKreEIAAIehwqt4QgCAxaHCq3hCAAAEosKreEIAgEKiwqt4QgAAgaLCq3hCAIC/osKreEIAAP6iwqt4QgCAPKPCq3hCAAB7o8KreEIAgLmjwqt4QgAA+KPCq3hCAIA2pMKreEIAAHWkwqt4QgCAs6TCq3hCAADypMKreEIAgDClwqt4QgAAb6XCq3hCAICtpcKreEIAAOylwqt4QgCAKqbCq3hCAABppsKreEIAgKemwqt4QgAA5qbCq3hCAIAkp8KreEIAAGOnwqt4QgCAoafCq3hCAADgp8KreEIAgB6owqt4QgAAXajCq3hCAICbqMKreEIAANqowqt4QgCAGKnCq3hCAABXqcKreEIAgJWpwqt4QgAA1KnCq3hCAIASqsKreEIAAFGqwqt4QgCAj6rCq3hCAADOqsKreEIAgAyrwqt4QgAAS6vCq3hCAICJq8KreEIAAMirwqt4QgCABqzCq3hCAABFrMKreEIAgIOswqt4QgAAwqzCq3hCAIAArcKreEIAAD+twqt4QgCAfa3Cq3hCAAC8rcKreEIAgPqtwqt4QgAAOa7Cq3hCAIB3rsKreEIAALauwqt4QgCA9K7Cq3hCAAAzr8KreEIAgHGvwqt4QgAAsK/Cq3hCAIDur8KreEIAAC2wwqt4QgCAa7DCq3hCAACqsMKreEIAgOiwwqt4QgAAJ7HCq3hCAIBlscKreEIAAKSxwqt4QgCA4rHCq3hCAAAhssKreEIAgF+ywqt4QgAAnrLCq3hCAIDcssKreEIAABuzwqt4QgCAWbPCq3hCAACYs8KreEIAgNazwqt4QgAAFbTCq3hCAIBTtMKreEIAAJK0wqt4QgCA0LTCq3hCAAAPtcKreEIAgE21wqt4QgAAjLXCq3hCAIDKtcKreEIAAAm2wqt4QgCAR7bCq3hCAACGtsKreEIAgMS2wqt4QgAAA7fCq3hCAIBBt8KreEIAAIC3wqt4QgCAvrfCq3hCAAD9t8KreEIAgDu4wqt4QgAAerjCq3hCAIC4uMKreEIAAPe4wqt4QgCANbnCq3hCAAB0ucKreEIAgLK5wqt4QgAA8bnCq3hCAIAvusKreEIAAG66wqt4QgCArLrCq3hCAADrusKreEIAgCm7wqt4QgAAaLvCq3hCAICmu8KreEIAAOW7wqt4QgCAI7zCq3hCAABivMKreEIAgKC8wqt4QgAA37zCq3hCAIAdvcKreEIAAFy9wqt4QgCAmr3Cq3hCAADZvcKreEIAgBe+wqt4QgAAVr7Cq3hCAICUvsKreEIAANO+wqt4QgCAEb/Cq3hCAABQv8KreEIAgI6/wqt4QgAAzb/Cq3hCAIALwMKreEIAAErAwqt4QgCAiMDCq3hCAADHwMKreEIAgAXBwqt4QgAARMHCq3hCAICCwcKreEIAAMHBwqt4QgCA/8HCq3hCAAA+wsKreEIAgHzCwqt4QgAAu8LCq3hCAID5wsKreEIAADjDwqt4QgCAdsPCq3hCAAC1w8KreEIAgPPDwqt4QgAAMsTCq3hCAIBwxMKreEIAAK/Ewqt4QgCA7cTCq3hCAAAsxcKreEIAgGrFwqt4QgAAqcXCq3hCAIDnxcKreEIAACbGwqt4QgCAZMbCq3hCAACjxsKreEIAgOHGwqt4QgAAIMfCq3hCAIBex8KreEIAAJ3Hwqt4QgCA28fCq3hCAAAayMKreEIAgFjIwqt4QgAAl8jCq3hCAIDVyMKreEIAABTJwqt4QgCAUsnCq3hCAACRycKreEIAgM/Jwqt4QgAADsrCq3hCAIBMysKreEIAAIvKwqt4QgCAycrCq3hCAAAIy8KreEIAgEbLwqt4QgAAhcvCq3hCAIDDy8KreEIAAALMwqt4QgCAQMzCq3hCAAB/zMKreEIAgL3Mwqt4QgAA/MzCq3hCAIA6zcKreEIAAHnNwqt4QgCAt83Cq3hCAAD2zcKreEIAgDTOwqt4QgAAc87Cq3hCAICxzsKreEIAAPDOwqt4QgCALs/Cq3hCAABtz8KreEIAgKvPwqt4QgAA6s/Cq3hCAIAo0MKreEIAAGfQwqt4QgCApdDCq3hCAADk0MKreEIAgCLRwqt4QgAAYdHCq3hCAICf0cKreEIAAN7Rwqt4QgCAHNLCq3hCAABb0sKreEIAgJnSwqt4QgAA2NLCq3hCAIAW08KreEIAAFXTwqt4QgCAk9PCq3hCAADS08KreEIAgBDUwqt4QgAAT9TCq3hCAICN1MKreEIAAMzUwqt4QgCACtXCq3hCAABJ1cKreEIAgIfVwqt4QgAAxtXCq3hCAIAE1sKreEIAAEPWwqt4QgCAgdbCq3hCAADA1sKreEIAgP7Wwqt4QgAAPdfCq3hCAIB718KreEIAALrXwqt4QgCA+NfCq3hCAAA32MKreEIAgHXYwqt4QgAAtNjCq3hCAIDy2MKreEIAADHZwqt4QgCAb9nCq3hCAACu2cKreEIAgOzZwqt4QgAAK9rCq3hCAIBp2sKreEIAAKjawqt4QgCA5trCq3hCAAAl28KreEIAgGPbwqt4QgAAotvCq3hCAIDg28KreEIAAB/cwqt4QgCAXdzCq3hCAACc3MKreEIAgNrcwqt4QgAAGd3Cq3hCAIBX3cKreEIAAJbdwqt4QgCA1N3Cq3hCAAAT3sKreEIAgFHewqt4QgAAkN7Cq3hCAIDO3sKreEIAAA3fwqt4QgCAS9/Cq3hCAACK38KreEIAgMjfwqt4QgAAB+DCq3hCAIBF4MKreEIAAITgwqt4QgCAwuDCq3hCAAAB4cKreEIAgD/hwqt4QgAAfuHCq3hCAIC84cKreEIAAPvhwqt4QgCAOeLCq3hCAAB44sKreEIAgLbiwqt4QgAA9eLCq3hCAIAz48KreEIAAHLjwqt4QgCAsOPCq3hCAADv48KreEIAgC3kwqt4QgAAbOTCq3hCAICq5MKreEIAAOnkwqt4QgCAJ+XCq3hCAABm5cKreEIAgKTlwqt4QgAA4+XCq3hCAIAh5sKreEIAAGDmwqt4QgCAnubCq3hCAADd5sKreEIAgBvnwqt4QgAAWufCq3hCAICY58KreEIAANfnwqt4QgCAFejCq3hCAABU6MKreEIAgJLowqt4QgAA0ejCq3hCAIAP6cKreEIAAE7pwqt4QgCAjOnCq3hCAADL6cKreEIAgAnqwqt4QgAASOrCq3hCAICG6sKreEIAAMXqwqt4QgCAA+vCq3hCAABC68KreEIAgIDrwqt4QgAAv+vCq3hCAID968KreEIAADzswqt4QgCAeuzCq3hCAAC57MKreEIAgPfswqt4QgAANu3Cq3hCAIB07cKreEIAALPtwqt4QgCA8e3Cq3hCAAAw7sKreEIAgG7uwqt4QgAAre7Cq3hCAIDr7sKreEIAACrvwqt4QgCAaO/Cq3hCAACn78KreEIAgOXvwqt4QgAAJPDCq3hCAIBi8MKreEIAAKHwwqt4QgCA3/DCq3hCAAAe8cKreEIAgFzxwqt4QgAAm/HCq3hCAIDZ8cKreEIAABjywqt4QgCAVvLCq3hCAACV8sKreEIAgNPywqt4QgAAEvPCq3hCAIBQ88KreEIAAI/zwqt4QgCAzfPCq3hCAAAM9MKreEIAgEr0wqt4QgAAifTCq3hCAIDH9MKreEIAAAb1wqt4QgCARPXCq3hCAACD9cKreEIAgMH1wqt4QgAAAPbCq3hCAIA+9sKreEIAAH32wqt4QgCAu/bCq3hCAAD69sKreEIAgDj3wqt4QgAAd/fCq3hCAIC198KreEIAAPT3wqt4QgCAMvjCq3hCAABx+MKreEIAgK/4wqt4QgAA7vjCq3hCAIAs+cKreEIAAGv5wqt4QgCAqfnCq3hCAADo+cKreEIAgCb6wqt4QgAAZfrCq3hCAICj+sKreEIAAOL6wqt4QgCAIPvCq3hCAABf+8KreEIAgJ37wqt4QgAA3PvCq3hCAIAa/MKreEIAAFn8wqt4QgCAl/zCq3hCAADW/MKreEIAgBT9wqt4QgAAU/3Cq3hCAICR/cKreEIAAND9wqt4QgCADv7Cq3hCAABN/sKreEIAgIv+wqt4QgAAyv7Cq3hCAIAI/8KreEIAAEf/wqt4QgCAhf/Cq3hCAADE/8KreEIAgAIAw6t4QgAAQQDDq3hCAIB/AMOreEIAAL4Aw6t4QgCA/ADDq3hCAAA7AcOreEIAgHkBw6t4QgAAuAHDq3hCAID2AcOreEIAADUCw6t4QgCAcwLDq3hCAACyAsOreEIAgPACw6t4QgAALwPDq3hCAIBtA8OreEIAAKwDw6t4QgCA6gPDq3hCAAApBMOreEIAgGcEw6t4QgAApgTDq3hCAIDkBMOreEIAACMFw6t4QgCAYQXDq3hCAACgBcOreEIAgN4Fw6t4QgAAHQbDq3hCAIBbBsOreEIAAJoGw6t4QgCA2AbDq3hCAAAXB8OreEIAgFUHw6t4Qg==\"},\"shape\":[590],\"dtype\":\"float64\",\"order\":\"little\"}],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAACeAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAABAAAAAQAAANkBAAAHAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAwAAAAEAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAACAAAAAQAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAAAAABAAAAAAAAAAEAAAACAAAAAAAAAAEAAAABAAAAAgAAAAEAAAADAAAAAAAAAAIAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAIAAAA=\"},\"shape\":[590],\"dtype\":\"int32\",\"order\":\"little\"}]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2086\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2087\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2082\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_width\":2}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2083\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_width\":2}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"Line\",\"id\":\"p2084\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"y\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":\"#1f77b4\",\"line_alpha\":0.2,\"line_width\":2}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p1980\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2043\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2044\"},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2045\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2046\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"bottom_units\":\"canvas\",\"top_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2047\"},{\"type\":\"object\",\"name\":\"HoverTool\",\"id\":\"p2048\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"CrosshairTool\",\"id\":\"p2049\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2036\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2037\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2039\"},\"axis_label\":\"y\",\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2038\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"DatetimeAxis\",\"id\":\"p1993\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"DatetimeTicker\",\"id\":\"p1994\",\"attributes\":{\"num_minor_ticks\":5,\"tickers\":[{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1995\",\"attributes\":{\"num_minor_ticks\":0,\"mantissas\":[1,2,5],\"max_interval\":500.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1996\",\"attributes\":{\"num_minor_ticks\":0,\"base\":60,\"mantissas\":[1,2,5,10,15,20,30],\"min_interval\":1000.0,\"max_interval\":1800000.0}},{\"type\":\"object\",\"name\":\"AdaptiveTicker\",\"id\":\"p1997\",\"attributes\":{\"num_minor_ticks\":0,\"base\":24,\"mantissas\":[1,2,4,6,8,12],\"min_interval\":3600000.0,\"max_interval\":43200000.0}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1998\",\"attributes\":{\"days\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p1999\",\"attributes\":{\"days\":[1,4,7,10,13,16,19,22,25,28]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p2000\",\"attributes\":{\"days\":[1,8,15,22]}},{\"type\":\"object\",\"name\":\"DaysTicker\",\"id\":\"p2001\",\"attributes\":{\"days\":[1,15]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p2002\",\"attributes\":{\"months\":[0,1,2,3,4,5,6,7,8,9,10,11]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p2003\",\"attributes\":{\"months\":[0,2,4,6,8,10]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p2004\",\"attributes\":{\"months\":[0,4,8]}},{\"type\":\"object\",\"name\":\"MonthsTicker\",\"id\":\"p2005\",\"attributes\":{\"months\":[0,6]}},{\"type\":\"object\",\"name\":\"YearsTicker\",\"id\":\"p2006\"}]}},\"formatter\":{\"type\":\"object\",\"name\":\"DatetimeTickFormatter\",\"id\":\"p2008\"},\"axis_label\":\"x\",\"major_label_orientation\":0.7853981633974483,\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2007\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2035\",\"attributes\":{\"axis\":{\"id\":\"p1993\"}}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2042\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2036\"}}},{\"type\":\"object\",\"name\":\"Legend\",\"id\":\"p2067\",\"attributes\":{\"items\":[{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p2068\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"0 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p2064\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p2078\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"500 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p2075\"}]}},{\"type\":\"object\",\"name\":\"LegendItem\",\"id\":\"p2088\",\"attributes\":{\"label\":{\"type\":\"value\",\"value\":\"502 - https://api.staging.scorer.gitcoin.co/ceramic-cache/stamps/bulk\"},\"renderers\":[{\"id\":\"p2085\"}]}}]}}],\"frame_width\":1500}}],\"callbacks\":{\"type\":\"map\"}}};\n const render_items = [{\"docid\":\"1b7bbff9-74a8-43e6-8ab7-943aa43fd8b6\",\"roots\":{\"p1975\":\"abb16959-99a8-441b-afa1-9120de46a6b5\"},\"root_ids\":[\"p1975\"]}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "p1975" + } + }, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "from math import pi\n", + "from bokeh.models import DatetimeTickFormatter\n", + "df_duration = df[df.metric_name == \"http_req_duration\"]\n", + "\n", + "dft = df_duration.set_index(\"timestamp\")\n", + "\n", + "# dfts = dft.groupby(by=[\"url\"]).resample(\"1Min\").agg({\n", + "# \"metric_value\": [\"min\", \"max\", \"mean\", \"count\"]\n", + "# })\n", + "\n", + "dfts = dft.groupby(by=[\"url\", \"status\"]).resample(\"s\").agg({\n", + " \"metric_value\": [\"min\", \"max\", \"mean\", \"count\"]\n", + "})\n", + "\n", + "dfts.reset_index(inplace=True)\n", + "dfts.set_index(\"timestamp\", inplace=True)\n", + "\n", + "colors = [\n", + " \"blue\",\n", + " \"red\",\n", + " \"green\",\n", + " \"purple\",\n", + " \"orange\",\n", + " \"teal\",\n", + " \"pink\",\n", + " \"yellow\",\n", + " \"cyan\",\n", + " \"maroon\",\n", + " \"olive\",\n", + " \"navy\",\n", + " \"magenta\",\n", + " \"brown\",\n", + " \"slate gray\",\n", + " \"forest green\",\n", + " \"lavender\",\n", + " \"coral\",\n", + " \"turquoise\",\n", + " \"gold\"\n", + "]\n", + "\n", + "p = figure(title=\"Req / second (status != 200)\", x_axis_label='x', y_axis_label='y', frame_width=1500,\n", + " tools=\"pan,wheel_zoom,box_zoom,reset,hover,crosshair\",\n", + " x_axis_type=\"datetime\")\n", + "\n", + "p.xaxis.major_label_orientation = pi/4\n", + "\n", + "sum_200 = 0\n", + "sum_non_200 = 0\n", + "for idx, ((url, status), group) in enumerate(dfts.groupby(by=[\"url\", \"status\"])):\n", + " # print(url)\n", + " # print(status)\n", + " # print(group)\n", + " print(f\"{int(status)} - {url}: \", group[\"metric_value\"][\"count\"].sum())\n", + " if int(status) != 200:\n", + " p.line(group.index, group[\"metric_value\"][\"count\"], legend_label=f\"{int(status)} - {url}\", line_width=2)\n", + " sum_non_200 += group[\"metric_value\"][\"count\"].sum()\n", + " else:\n", + " sum_200 += group[\"metric_value\"][\"count\"].sum()\n", + "\n", + "print(f\" 200 \", sum_200)\n", + "print(f\" non - 200 \", sum_non_200)\n", + "print(f\" % success \", float(sum_200) / (sum_non_200 + sum_200))\n", + "\n", + "show(p)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}