Last active
December 11, 2024 19:38
-
-
Save adamsilverstein/20fbb28b6db2c280089b79b9fadb2ca1 to your computer and use it in GitHub Desktop.
WPP Metrics Tracking colab
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/adamsilverstein/20fbb28b6db2c280089b79b9fadb2ca1/wpp-metrics-tracking.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "KcAZ2RHCg_Ze" | |
}, | |
"source": [ | |
"# WPP Tracking\n", | |
"\n", | |
"Track CWV metric pass rate and feature adoption metrics across initiatives." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Setup" | |
], | |
"metadata": { | |
"id": "4G2WkwMPzxbT" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"project_id = 'wpp-research'" | |
], | |
"metadata": { | |
"id": "YhCtDqb8AEcY" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "qTmLBxDxBAZL" | |
}, | |
"source": [ | |
"### Provide your credentials to the runtime" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "SeTJb51SKs_W", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "1dbe1889-3919-4c00-f7eb-dfe6f9fe85cb" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Authenticated\n" | |
] | |
} | |
], | |
"source": [ | |
"from google.colab import auth\n", | |
"auth.authenticate_user()\n", | |
"print('Authenticated')\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "goQQ96EDKs_7" | |
}, | |
"source": [ | |
"### Declare the Cloud project ID which will be used throughout this notebook\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from google.cloud.bigquery import magics\n", | |
"# Update with your own Google Cloud Platform project name\n", | |
"magics.context.project = project_id" | |
], | |
"metadata": { | |
"id": "YdTgQYtSoOoE" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"### Add a helper to get the latest dataset" | |
], | |
"metadata": { | |
"id": "yV85Ec6A9FED" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from datetime import datetime, timedelta\n", | |
"\n", | |
"def get_first_of_previous_month():\n", | |
" today = datetime.now()\n", | |
" first_day_previous_month = datetime(today.year, today.month - 1, 1) if today.month > 1 else datetime(today.year - 1, 12, 1)\n", | |
" return first_day_previous_month.strftime('%Y_%m_%d')\n", | |
"\n", | |
"latest_dataset = get_first_of_previous_month() # eg. \"2023_06_01\" - datasets are updated monthly, indicate the latest" | |
], | |
"metadata": { | |
"id": "stNLljYnR355" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "UMKGkkZEPVRu" | |
}, | |
"source": [ | |
"### Enable data table display" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"id": "LMNA-vBHPyHz" | |
}, | |
"outputs": [], | |
"source": [ | |
"%load_ext google.colab.data_table" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from google.colab import data_table\n", | |
"data_table.enable_dataframe_formatter()" | |
], | |
"metadata": { | |
"id": "JlBfb2k3JpRS" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Helper Functions\n", | |
"\n", | |
"Define helper functions that are used repeatedly throughout the colab.\n", | |
"\n", | |
"`query_cwv_for_technology_over_dates` - Calculate CWV metrics over time for technology\n" | |
], | |
"metadata": { | |
"id": "7Zntzp87Q0_y" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"### Helper to show CWV metrics over time for technology" | |
], | |
"metadata": { | |
"id": "6X4dlDq8ukqL" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from google.cloud import bigquery\n", | |
"from datetime import datetime, timedelta\n", | |
"\n", | |
"client = bigquery.Client(project=project_id)\n", | |
"\n", | |
"def query_cwv_for_technology_over_dates(technology, from_date=None, to_date=None):\n", | |
" \"\"\"\n", | |
" Queries Core Web Vitals metrics from HTTP Archive for a specific technology\n", | |
" over the past 12 months.\n", | |
"\n", | |
" Args:\n", | |
" technology (str): The technology to filter by (e.g., 'React').\n", | |
" from_date (str, optional): The start date in YYYY_MM_DD format.\n", | |
" to_date (str, optional): The end date in YYYY_MM_DD format.\n", | |
" Returns:\n", | |
" A BigQuery query result object containing CWV data.\n", | |
" \"\"\"\n", | |
" # set to_date if not passed\n", | |
" if not to_date:\n", | |
" to_date = latest_dataset\n", | |
"\n", | |
" # set from date if not passed\n", | |
" if not from_date:\n", | |
" from_date = (datetime.strptime(to_date, '%Y_%m_%d').date() - timedelta(days=365)).strftime('%Y_%m_%d')\n", | |
"\n", | |
"\n", | |
" query = f\"\"\"\n", | |
"CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good / (good + needs_improvement + poor) >= 0.75\n", | |
" );\n", | |
"\n", | |
" CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good + needs_improvement + poor > 0\n", | |
" );\n", | |
" WITH sites_using_technology AS (\n", | |
" SELECT\n", | |
" page AS origin,\n", | |
" client AS device,\n", | |
" date,\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = '{technology}'\n", | |
" AND date BETWEEN PARSE_DATE('%Y_%m_%d', '{from_date}') AND PARSE_DATE('%Y_%m_%d', '{to_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" GROUP BY\n", | |
" page, device, date\n", | |
" ),\n", | |
" cwv_metrics_for_origins AS (\n", | |
" SELECT\n", | |
" cwvs.date AS date,\n", | |
" sites_using_technology.origin AS origin,\n", | |
" # Device phone or tablet as mobile, otherwise desktop.\n", | |
" IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', 'desktop') AS device,\n", | |
" IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp,\n", | |
" IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp,\n", | |
" IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls,\n", | |
" IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls,\n", | |
" IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp,\n", | |
" IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp,\n", | |
" (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND IS_GOOD(small_cls, medium_cls, large_cls) AND IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_cwv\n", | |
" FROM\n", | |
" `chrome-ux-report.materialized.device_summary` AS cwvs\n", | |
" JOIN\n", | |
" sites_using_technology\n", | |
" ON (\n", | |
" sites_using_technology.origin = CONCAT(cwvs.origin, '/') AND\n", | |
" sites_using_technology.date = cwvs.date AND\n", | |
" sites_using_technology.device = IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', cwvs.device)\n", | |
" )\n", | |
" WHERE\n", | |
" cwvs.date BETWEEN PARSE_DATE('%Y_%m_%d', '{from_date}') AND PARSE_DATE('%Y_%m_%d', '{to_date}' )\n", | |
" AND cwvs.device IN ('desktop', 'tablet', 'phone')\n", | |
"\n", | |
" ),\n", | |
"\n", | |
"\n", | |
" cwvs_by_date AS (\n", | |
" SELECT\n", | |
" date,\n", | |
" device,\n", | |
" COUNT(DISTINCT origin) AS origins,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cwv), COUNTIF(any_lcp AND any_cls)) AS pct_eligible_origins_with_good_cwv,\n", | |
" SAFE_DIVIDE(COUNTIF(good_lcp), COUNTIF(any_lcp)) AS pct_eligible_origins_with_good_lcp,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cls), COUNTIF(any_cls)) AS pct_eligible_origins_with_good_cls,\n", | |
" SAFE_DIVIDE(COUNTIF(good_inp), COUNTIF(any_inp)) AS pct_eligible_origins_with_good_inp\n", | |
" FROM\n", | |
" cwv_metrics_for_origins\n", | |
" GROUP BY\n", | |
" date, device\n", | |
" ORDER BY\n", | |
" date, device\n", | |
" )\n", | |
" SELECT * FROM cwvs_by_date\n", | |
" \"\"\"\n", | |
"\n", | |
" query_job = client.query(query)\n", | |
" return query_job.result() # Return the results of the query\n", | |
"\n", | |
"# Restrict the query to on the from and to dates, and to the specified from and to versions\n", | |
"def query_cwv_for_technology_compare_dates_by_version(technology, from_date, to_date, from_version, to_version):\n", | |
" \"\"\"\n", | |
" Queries Core Web Vitals metrics from HTTP Archive for a specific technology\n", | |
" over the past 12 months.\n", | |
"\n", | |
" Args:\n", | |
" technology (str): The technology to filter by (e.g., 'React').\n", | |
" from_date (str): The start date in YYYY_MM_DD format.\n", | |
" to_date (str): The end date in YYYY_MM_DD format.\n", | |
" from_version (str): The start version.\n", | |
" to_version (str): The end version.\n", | |
" Returns:\n", | |
" A BigQuery query result object containing CWV data.\n", | |
" \"\"\"\n", | |
" # set to_date if not passed\n", | |
" if not to_date:\n", | |
" to_date = latest_dataset\n", | |
"\n", | |
" # set from date if not passed\n", | |
" if not from_date:\n", | |
" from_date = (datetime.strptime(to_date, '%Y_%m_%d').date() - timedelta(days=365)).strftime('%Y_%m_%d')\n", | |
"\n", | |
"\n", | |
" query = f\"\"\"\n", | |
"CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good / (good + needs_improvement + poor) >= 0.75\n", | |
" );\n", | |
"\n", | |
" CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good + needs_improvement + poor > 0\n", | |
" );\n", | |
" WITH sites_using_technology AS (\n", | |
" SELECT\n", | |
" page AS origin,\n", | |
" client AS device,\n", | |
" date,\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = '{technology}'\n", | |
" AND (\n", | |
" ( date = PARSE_DATE('%Y_%m_%d', '{from_date}') AND REGEXP_EXTRACT(JSON_EXTRACT( JSON_EXTRACT(payload, '$._detected_apps'),'$.{technology}'),r'(\\\\d.\\\\d+.\\\\d+).*') = '{from_version}' ) OR\n", | |
" ( date = PARSE_DATE('%Y_%m_%d', '{to_date}' ) AND REGEXP_EXTRACT(JSON_EXTRACT( JSON_EXTRACT(payload, '$._detected_apps'),'$.{technology}'),r'(\\\\d.\\\\d+.\\\\d+).*') = '{to_version}' )\n", | |
" )\n", | |
" AND is_root_page = TRUE\n", | |
" GROUP BY\n", | |
" page, device, date\n", | |
" ),\n", | |
" cwv_metrics_for_origins AS (\n", | |
" SELECT\n", | |
" cwvs.date AS date,\n", | |
" sites_using_technology.origin AS origin,\n", | |
" # Device phone or tablet as mobile, otherwise desktop.\n", | |
" IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', cwvs.device) AS device,\n", | |
" IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp,\n", | |
" IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp,\n", | |
" IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls,\n", | |
" IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls,\n", | |
" IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp,\n", | |
" IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp,\n", | |
" (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND IS_GOOD(small_cls, medium_cls, large_cls) AND IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_cwv\n", | |
" FROM\n", | |
" `chrome-ux-report.materialized.device_summary` AS cwvs\n", | |
" JOIN\n", | |
" sites_using_technology\n", | |
" ON (\n", | |
" sites_using_technology.origin = CONCAT(cwvs.origin, '/') AND\n", | |
" sites_using_technology.date = cwvs.date AND\n", | |
" sites_using_technology.device = IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', cwvs.device)\n", | |
" )\n", | |
" WHERE\n", | |
" cwvs.date BETWEEN PARSE_DATE('%Y_%m_%d', '{from_date}') AND PARSE_DATE('%Y_%m_%d', '{to_date}' )\n", | |
" AND cwvs.device IN ('desktop', 'tablet', 'phone')\n", | |
" # Restrict to sites that are in both dates\n", | |
" AND CONCAT(cwvs.origin, '/') IN (\n", | |
" SELECT\n", | |
" origin\n", | |
" FROM\n", | |
" sites_using_technology\n", | |
" GROUP BY\n", | |
" origin\n", | |
" HAVING\n", | |
" COUNT(*) = 2\n", | |
" )\n", | |
" ),\n", | |
"\n", | |
"\n", | |
" cwvs_by_date AS (\n", | |
" SELECT\n", | |
" date,\n", | |
" device,\n", | |
" COUNT(DISTINCT origin) AS origins,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cwv), COUNTIF(any_lcp AND any_cls)) AS pct_eligible_origins_with_good_cwv,\n", | |
" SAFE_DIVIDE(COUNTIF(good_lcp), COUNTIF(any_lcp)) AS pct_eligible_origins_with_good_lcp,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cls), COUNTIF(any_cls)) AS pct_eligible_origins_with_good_cls,\n", | |
" SAFE_DIVIDE(COUNTIF(good_inp), COUNTIF(any_inp)) AS pct_eligible_origins_with_good_inp\n", | |
" FROM\n", | |
" cwv_metrics_for_origins\n", | |
" GROUP BY\n", | |
" date, device\n", | |
" ORDER BY\n", | |
" date, device\n", | |
" )\n", | |
" SELECT * FROM cwvs_by_date\n", | |
" \"\"\"\n", | |
"\n", | |
" query_job = client.query(query)\n", | |
" return query_job.result() # Return the results of the query" | |
], | |
"metadata": { | |
"id": "zxFgf3WUQ5IA" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Feature performance analysis helpers" | |
], | |
"metadata": { | |
"id": "_59x7rfyWRYO" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `after_date` with feature active.\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"# This limit is used throughout, adjust to increase sample or speed.\n", | |
"limit = 50000\n", | |
"\n", | |
"\n", | |
"# Get sites with the feature active on a specific date\n", | |
"def get_sites_with_feature_active(generator_tag, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND getFeature(payload, '{generator_tag}') != \"\"\n", | |
"\n", | |
"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" active_sites_df = client.query(active_sites_query).to_dataframe()\n", | |
" return active_sites_df" | |
], | |
"metadata": { | |
"id": "ntnEK4tkv7Y1" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"### Get sites with features active" | |
], | |
"metadata": { | |
"id": "bC13eOJnR__7" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `after_date` with feature active.\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"# This limit is used throughout, adjust to increase sample or speed.\n", | |
"limit = 50000\n", | |
"\n", | |
"\n", | |
"# Get sites with the feature active on a specific date\n", | |
"def get_sites_with_features_active(generator_tag1, generator_tag2, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND getFeature(payload, '{generator_tag1}') != \"\"\n", | |
" AND getFeature(payload, '{generator_tag2}') != \"\"\n", | |
"\n", | |
"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" active_sites_df = client.query(active_sites_query).to_dataframe()\n", | |
" return active_sites_df" | |
], | |
"metadata": { | |
"id": "Gh97AHI8QqPY" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `after_date` with feature *not* active.\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"\n", | |
"# Get sites with the feature active on a specific date\n", | |
"def get_sites_with_feature_inactive(generator_tag, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" inactive_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND getFeature(payload, '{generator_tag}') = \"\"\n", | |
"\n", | |
"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" inactive_sites_df = client.query(inactive_sites_query).to_dataframe()\n", | |
" return inactive_sites_df" | |
], | |
"metadata": { | |
"id": "Pqejonkx4rU2" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `after_date` with feature *not* active.\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"\n", | |
"# Get sites with the feature active on a specific date\n", | |
"def get_sites_with_features_inactive(generator_tag1, generator_tag2, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" inactive_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND getFeature(payload, '{generator_tag1}') = \"\"\n", | |
" AND getFeature(payload, '{generator_tag2}') = \"\"\n", | |
"\n", | |
"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" inactive_sites_df = client.query(inactive_sites_query).to_dataframe()\n", | |
" return inactive_sites_df" | |
], | |
"metadata": { | |
"id": "I9SXaAtfn3ga" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Helpers to compare before and after, minus baseline" | |
], | |
"metadata": { | |
"id": "O6jI1ChWXOJs" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `before_date` with feature active.\n", | |
"#@markdown Ideally, this should be 0.\n", | |
"\n", | |
"# Calculate how many of the sites where the feature was active at the after_date\n", | |
"# did not have the feature active at the before_date\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"\n", | |
"# Get sites from a list with the feature not active on a specific date\n", | |
"def get_active_sites_also_active_at_before_date(generator_tag, before_date, existing_sites):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
"\n", | |
" # Extract the origins from the existing_sites dataframe as a comma separated list\n", | |
" existing_sites_list = ', '.join(f\"'{origin}'\" for origin in existing_sites['origin'])\n", | |
"\n", | |
"\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
"\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{before_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND page IN ({existing_sites_list})\n", | |
" AND getFeature(payload, '{generator_tag}') != \"\"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" active_sites_df = client.query(active_sites_query).to_dataframe()\n", | |
" return active_sites_df" | |
], | |
"metadata": { | |
"id": "u-VvZMmfSBJ8" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get sites at `before_date` with feature active.\n", | |
"#@markdown Ideally, this should be 0.\n", | |
"\n", | |
"# Calculate how many of the sites where the feature was active at the after_date\n", | |
"# did not have the feature active at the before_date\n", | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"\n", | |
"# Get sites from a list with the feature not active on a specific date\n", | |
"def get_active_sites_also_active_at_before_date_features(generator_tag1, generator_tag2, before_date, existing_sites):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
"\n", | |
" # Extract the origins from the existing_sites dataframe as a comma separated list\n", | |
" existing_sites_list = ', '.join(f\"'{origin}'\" for origin in existing_sites['origin'])\n", | |
"\n", | |
"\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING, generator_tag STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith(generator_tag));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" page AS origin\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
"\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y-%m-%d', '{before_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" AND client = 'mobile'\n", | |
" AND page IN ({existing_sites_list})\n", | |
" AND getFeature(payload, '{generator_tag1}') != \"\"\n", | |
" AND getFeature(payload, '{generator_tag2}') != \"\"\n", | |
" LIMIT {limit}\n", | |
" \"\"\"\n", | |
"\n", | |
" active_sites_df = client.query(active_sites_query).to_dataframe()\n", | |
" return active_sites_df" | |
], | |
"metadata": { | |
"id": "i2DT6JXgPlDO" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [], | |
"metadata": { | |
"id": "iqE8_d5kKddc" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get CWV changes for a set of sites between before and after dates\n", | |
"#@markdown\n", | |
"#@markdown Note: sites_df is a dataframe with an origin column containing the URLs.\n", | |
"#@markdown\n", | |
"#@markdown Returns:\n", | |
"#@markdown * pct_eligible_origins_with_good_cwv_change\n", | |
"#@markdown * pct_eligible_origins_with_good_lcp_change\n", | |
"#@markdown * pct_eligible_origins_with_good_cls_change\n", | |
"#@markdown * pct_eligible_origins_with_good_inp_change\n", | |
"#@markdown\n", | |
"\n", | |
"\n", | |
"\n", | |
"import pdb\n", | |
"# Get the CWV change before/after for sites\n", | |
"def get_cwv_change_before_after(sites_df, before_date, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 0. Ensure the 'temp_dataset' dataset exists, or create it\n", | |
" dataset_id = f\"{project_id}.temp_dataset\"\n", | |
" try:\n", | |
" client.get_dataset(dataset_id) # Check if dataset exists\n", | |
" except NotFound:\n", | |
" dataset = bigquery.Dataset(dataset_id)\n", | |
" dataset.location = \"US\" # Set the location (adjust if needed)\n", | |
" client.create_dataset(dataset)\n", | |
"\n", | |
" # 1. Create a temporary table with the list of origins\n", | |
" schema = [bigquery.SchemaField(\"origin\", \"STRING\")]\n", | |
" job_config = bigquery.LoadJobConfig(schema=schema)\n", | |
" job = client.load_table_from_dataframe(sites_df, f\"{project_id}.temp_dataset.origins\", job_config=job_config)\n", | |
" job.result() # Wait for the job to complete\n", | |
"\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 2. Collect CWV Data and Calculate Baselines\n", | |
" cwv_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good / (good + needs_improvement + poor) >= 0.75\n", | |
" );\n", | |
"\n", | |
" CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good + needs_improvement + poor > 0\n", | |
" );\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" date,\n", | |
" COUNT(DISTINCT origin) AS origins,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cwv), COUNTIF(any_lcp AND any_cls)) AS pct_eligible_origins_with_good_cwv,\n", | |
" SAFE_DIVIDE(COUNTIF(good_lcp), COUNTIF(any_lcp)) AS pct_eligible_origins_with_good_lcp,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cls), COUNTIF(any_cls)) AS pct_eligible_origins_with_good_cls,\n", | |
" SAFE_DIVIDE(COUNTIF(good_inp), COUNTIF(any_inp)) AS pct_eligible_origins_with_good_inp\n", | |
" FROM\n", | |
" (\n", | |
" SELECT\n", | |
" date AS date,\n", | |
" origin,\n", | |
" # Device phone or tablet as mobile, otherwise desktop.\n", | |
" IF(device = 'phone' OR device = 'tablet', 'mobile', device) AS device,\n", | |
" IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp,\n", | |
" IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp,\n", | |
" IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls,\n", | |
" IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls,\n", | |
" IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp,\n", | |
" IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp,\n", | |
" (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND IS_GOOD(small_cls, medium_cls, large_cls) AND IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_cwv\n", | |
" FROM\n", | |
" `chrome-ux-report.materialized.device_summary` AS cwvs\n", | |
" WHERE\n", | |
" (\n", | |
" date = PARSE_DATE('%Y-%m-%d', '{before_date}') OR\n", | |
" date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" )\n", | |
" AND cwvs.device IN ('desktop', 'tablet', 'phone')\n", | |
" # Restrict to sites that are in both dates\n", | |
" AND CONCAT(cwvs.origin, '/') IN (SELECT origin FROM `{project_id}.temp_dataset.origins`)\n", | |
" )\n", | |
" GROUP BY\n", | |
" date\n", | |
" ORDER BY\n", | |
" date\n", | |
" \"\"\"\n", | |
"\n", | |
" cwv_data = client.query(cwv_query).to_dataframe()\n", | |
"\n", | |
" # select the data from the after_date (by date column)\n", | |
" cwv_after = cwv_data[cwv_data['date'] == pd.to_datetime(after_date)]\n", | |
" cwv_before = cwv_data[cwv_data['date'] == pd.to_datetime(before_date)]\n", | |
"\n", | |
" # subtract the 'pct_eligible_origins_with_good_cwv' value at cwv_before from cwv_after\n", | |
" pct_eligible_origins_with_good_cwv_change = cwv_after['pct_eligible_origins_with_good_cwv'].values[0] - cwv_before['pct_eligible_origins_with_good_cwv'].values[0]\n", | |
" pct_eligible_origins_with_good_lcp_change = cwv_after['pct_eligible_origins_with_good_lcp'].values[0] - cwv_before['pct_eligible_origins_with_good_lcp'].values[0]\n", | |
" pct_eligible_origins_with_good_cls_change = cwv_after['pct_eligible_origins_with_good_cls'].values[0] - cwv_before['pct_eligible_origins_with_good_cls'].values[0]\n", | |
" pct_eligible_origins_with_good_inp_change = cwv_after['pct_eligible_origins_with_good_inp'].values[0] - cwv_before['pct_eligible_origins_with_good_inp'].values[0]\n", | |
"\n", | |
" # 3. Clean up: Delete the temporary table (optional but good practice)\n", | |
" client.delete_table(f\"{project_id}.temp_dataset.origins\")\n", | |
"\n", | |
" return [\n", | |
" pct_eligible_origins_with_good_cwv_change,\n", | |
" pct_eligible_origins_with_good_lcp_change,\n", | |
" pct_eligible_origins_with_good_cls_change,\n", | |
" pct_eligible_origins_with_good_inp_change\n", | |
" ]" | |
], | |
"metadata": { | |
"id": "WVcPDbM75Sz_" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"### Breakout by device" | |
], | |
"metadata": { | |
"id": "nmMTyZvMKRgw" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Get CWV changes for a set of sites between before and after dates\n", | |
"#@markdown ### Broken out by device\n", | |
"#@markdown `get_cwv_change_before_after_by_device`\n", | |
"#@markdown\n", | |
"#@markdown Note: sites_df is a dataframe with an origin column containing the URLs.\n", | |
"#@markdown\n", | |
"#@markdown Returns:\n", | |
"#@markdown * pct_eligible_origins_with_good_cwv_change_mobile\n", | |
"#@markdown * pct_eligible_origins_with_good_cwv_change_mobile,\n", | |
"#@markdown * pct_eligible_origins_with_good_lcp_change_mobile,\n", | |
"#@markdown * pct_eligible_origins_with_good_cls_change_mobile,\n", | |
"#@markdown * pct_eligible_origins_with_good_inp_change_mobile,\n", | |
"#@markdown * pct_eligible_origins_with_good_cwv_change_desktop,\n", | |
"#@markdown * pct_eligible_origins_with_good_lcp_change_desktop,\n", | |
"#@markdown * pct_eligible_origins_with_good_cls_change_desktop,\n", | |
"#@markdown * pct_eligible_origins_with_good_inp_change_desktop\n", | |
"\n" | |
], | |
"metadata": { | |
"id": "heT91UXwKUWi" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"\n", | |
"import pdb\n", | |
"# Get the CWV change before/after for sites\n", | |
"def get_cwv_change_before_after_by_device(sites_df, before_date, after_date):\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 0. Ensure the 'temp_dataset' dataset exists, or create it\n", | |
" dataset_id = f\"{project_id}.temp_dataset\"\n", | |
" try:\n", | |
" client.get_dataset(dataset_id) # Check if dataset exists\n", | |
" except NotFound:\n", | |
" dataset = bigquery.Dataset(dataset_id)\n", | |
" dataset.location = \"US\" # Set the location (adjust if needed)\n", | |
" client.create_dataset(dataset)\n", | |
"\n", | |
" # 1. Create a temporary table with the list of origins\n", | |
" schema = [bigquery.SchemaField(\"origin\", \"STRING\")]\n", | |
" job_config = bigquery.LoadJobConfig(schema=schema)\n", | |
" job = client.load_table_from_dataframe(sites_df, f\"{project_id}.temp_dataset.origins\", job_config=job_config)\n", | |
" job.result() # Wait for the job to complete\n", | |
"\n", | |
" client = bigquery.Client(project=project_id)\n", | |
" # 2. Collect CWV Data and Calculate Baselines\n", | |
" cwv_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good / (good + needs_improvement + poor) >= 0.75\n", | |
" );\n", | |
"\n", | |
" CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good + needs_improvement + poor > 0\n", | |
" );\n", | |
"\n", | |
"\n", | |
" SELECT\n", | |
" date,\n", | |
" device,\n", | |
" COUNT(DISTINCT origin) AS origins,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cwv), COUNTIF(any_lcp AND any_cls)) AS pct_eligible_origins_with_good_cwv,\n", | |
" SAFE_DIVIDE(COUNTIF(good_lcp), COUNTIF(any_lcp)) AS pct_eligible_origins_with_good_lcp,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cls), COUNTIF(any_cls)) AS pct_eligible_origins_with_good_cls,\n", | |
" SAFE_DIVIDE(COUNTIF(good_inp), COUNTIF(any_inp)) AS pct_eligible_origins_with_good_inp\n", | |
" FROM\n", | |
" (\n", | |
" SELECT\n", | |
" date AS date,\n", | |
" origin,\n", | |
" # Device phone or tablet as mobile, otherwise desktop.\n", | |
" IF(device = 'phone' OR device = 'tablet', 'mobile', device) AS device,\n", | |
" IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp,\n", | |
" IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp,\n", | |
" IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls,\n", | |
" IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls,\n", | |
" IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp,\n", | |
" IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp,\n", | |
" (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND IS_GOOD(small_cls, medium_cls, large_cls) AND IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_cwv\n", | |
" FROM\n", | |
" `chrome-ux-report.materialized.device_summary` AS cwvs\n", | |
" WHERE\n", | |
" (\n", | |
" date = PARSE_DATE('%Y-%m-%d', '{before_date}') OR\n", | |
" date = PARSE_DATE('%Y-%m-%d', '{after_date}' )\n", | |
" )\n", | |
" AND cwvs.device IN ('desktop', 'tablet', 'phone')\n", | |
" # Restrict to sites that are in both dates\n", | |
" AND CONCAT(cwvs.origin, '/') IN (SELECT origin FROM `{project_id}.temp_dataset.origins`)\n", | |
" )\n", | |
" GROUP BY\n", | |
" date, device\n", | |
" ORDER BY\n", | |
" date\n", | |
" \"\"\"\n", | |
"\n", | |
" cwv_data = client.query(cwv_query).to_dataframe()\n", | |
"\n", | |
" # select the data from the after_date (by date and device columns)\n", | |
" # mobile data\n", | |
" cwv_after_mobile = cwv_data[(cwv_data['date'] == pd.to_datetime(after_date)) & (cwv_data['device'] == 'mobile')]\n", | |
" cwv_before_mobile = cwv_data[(cwv_data['date'] == pd.to_datetime(before_date)) & (cwv_data['device'] == 'mobile')]\n", | |
"\n", | |
" # desktop data\n", | |
" cwv_after_desktop = cwv_data[(cwv_data['date'] == pd.to_datetime(after_date)) & (cwv_data['device'] == 'desktop')]\n", | |
" cwv_before_desktop = cwv_data[(cwv_data['date'] == pd.to_datetime(before_date)) & (cwv_data['device'] == 'desktop')]\n", | |
"\n", | |
"\n", | |
" # subtract the 'pct_eligible_origins_with_good_cwv' value at cwv_before from cwv_after\n", | |
" pct_eligible_origins_with_good_cwv_change_mobile = cwv_after_mobile['pct_eligible_origins_with_good_cwv'].values[0] - cwv_before_mobile['pct_eligible_origins_with_good_cwv'].values[0]\n", | |
" pct_eligible_origins_with_good_lcp_change_mobile = cwv_after_mobile['pct_eligible_origins_with_good_lcp'].values[0] - cwv_before_mobile['pct_eligible_origins_with_good_lcp'].values[0]\n", | |
" pct_eligible_origins_with_good_cls_change_mobile = cwv_after_mobile['pct_eligible_origins_with_good_cls'].values[0] - cwv_before_mobile['pct_eligible_origins_with_good_cls'].values[0]\n", | |
" pct_eligible_origins_with_good_inp_change_mobile = cwv_after_mobile['pct_eligible_origins_with_good_inp'].values[0] - cwv_before_mobile['pct_eligible_origins_with_good_inp'].values[0]\n", | |
"\n", | |
" pct_eligible_origins_with_good_cwv_change_desktop = cwv_after_desktop['pct_eligible_origins_with_good_cwv'].values[0] - cwv_before_desktop['pct_eligible_origins_with_good_cwv'].values[0]\n", | |
" pct_eligible_origins_with_good_lcp_change_desktop = cwv_after_desktop['pct_eligible_origins_with_good_lcp'].values[0] - cwv_before_desktop['pct_eligible_origins_with_good_lcp'].values[0]\n", | |
" pct_eligible_origins_with_good_cls_change_desktop = cwv_after_desktop['pct_eligible_origins_with_good_cls'].values[0] - cwv_before_desktop['pct_eligible_origins_with_good_cls'].values[0]\n", | |
" pct_eligible_origins_with_good_inp_change_desktop = cwv_after_desktop['pct_eligible_origins_with_good_inp'].values[0] - cwv_before_desktop['pct_eligible_origins_with_good_inp'].values[0]\n", | |
"\n", | |
" # 3. Clean up: Delete the temporary table (optional but good practice)\n", | |
" client.delete_table(f\"{project_id}.temp_dataset.origins\")\n", | |
"\n", | |
" return [\n", | |
" pct_eligible_origins_with_good_cwv_change_mobile,\n", | |
" pct_eligible_origins_with_good_lcp_change_mobile,\n", | |
" pct_eligible_origins_with_good_cls_change_mobile,\n", | |
" pct_eligible_origins_with_good_inp_change_mobile,\n", | |
" pct_eligible_origins_with_good_cwv_change_desktop,\n", | |
" pct_eligible_origins_with_good_lcp_change_desktop,\n", | |
" pct_eligible_origins_with_good_cls_change_desktop,\n", | |
" pct_eligible_origins_with_good_inp_change_desktop,\n", | |
" cwv_before_mobile,\n", | |
" cwv_after_mobile,\n", | |
" cwv_before_desktop,\n", | |
" cwv_after_desktop\n", | |
" ]" | |
], | |
"metadata": { | |
"id": "EkvnjJrKOH5O" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Calculate impact minus baseline\n", | |
"\n", | |
"# calculate the impact by subracting the baseline from the change\n", | |
"def calculate_feature_impact(change, baseline):\n", | |
" cwv_change = change[0] - baseline[0]\n", | |
" lcp_change = change[1] - baseline[1]\n", | |
" cls_change = change[2] - baseline[2]\n", | |
" inp_change = change[3] - baseline[3]\n", | |
" return {\n", | |
" 'pct_good_cwv_change': \"{:.2%}\".format(cwv_change),\n", | |
" 'pct_good_lcp_change': \"{:.2%}\".format(lcp_change),\n", | |
" 'pct_good_cls_change': \"{:.2%}\".format(cls_change),\n", | |
" 'pct_good_inp_change': \"{:.2%}\".format(inp_change)\n", | |
" }" | |
], | |
"metadata": { | |
"id": "gF8s3t5L6Vjg" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Calculate impact minus baseline by device\n", | |
"\n", | |
"# calculate the impact by subracting the baseline from the change\n", | |
"def calculate_feature_impact_by_device(change, baseline):\n", | |
" cwv_change_mobile = change[0] - baseline[0]\n", | |
" lcp_change_mobile = change[1] - baseline[1]\n", | |
" cls_change_mobile = change[2] - baseline[2]\n", | |
" inp_change_mobile = change[3] - baseline[3]\n", | |
" cwv_change_desktop = change[4] - baseline[4]\n", | |
" lcp_change_desktop = change[5] - baseline[5]\n", | |
" cls_change_desktop = change[6] - baseline[6]\n", | |
" inp_change_desktop = change[7] - baseline[7]\n", | |
" return {\n", | |
" 'pct_good_cwv_change_mobile': \"{:.2%}\".format(cwv_change_mobile),\n", | |
" 'pct_good_lcp_change_mobile': \"{:.2%}\".format(lcp_change_mobile),\n", | |
" 'pct_good_cls_change_mobile': \"{:.2%}\".format(cls_change_mobile),\n", | |
" 'pct_good_inp_change_mobile': \"{:.2%}\".format(inp_change_mobile),\n", | |
" 'pct_good_cwv_change_desktop': \"{:.2%}\".format(cwv_change_desktop),\n", | |
" 'pct_good_lcp_change_desktop': \"{:.2%}\".format(lcp_change_desktop),\n", | |
" 'pct_good_cls_change_desktop': \"{:.2%}\".format(cls_change_desktop),\n", | |
" 'pct_good_inp_change_desktop': \"{:.2%}\".format(inp_change_desktop)\n", | |
" }" | |
], | |
"metadata": { | |
"id": "1Dh14Oa1Pb2-" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Measure feature performance impact minus baseline\n", | |
"#@markdown\n", | |
"#@markdown ### Note:\n", | |
"#@markdown * This helper combines device data.\n", | |
"def query_cwv_compare_feature_to_baseline(generator_tag, before_date, after_date):\n", | |
" active_sites = get_sites_with_feature_active(generator_tag, after_date)\n", | |
" count_active_sites = active_sites.count()\n", | |
" inactive_sites = get_sites_with_feature_inactive(generator_tag, after_date)\n", | |
" count_inactive_sites = inactive_sites.count()\n", | |
"\n", | |
" # Count feature active sites that were also feature active at the before date.\n", | |
" active_at_from_date = get_active_sites_also_active_at_before_date(generator_tag, before_date, active_sites)\n", | |
" count_active_at_from_date = active_at_from_date.count()\n", | |
"\n", | |
" # Calculate the percentage of count_active_at_from_date (which might be 0 so use safe divide)\n", | |
" if count_active_sites['origin'] > 0:\n", | |
" also_active_at_before = (count_active_at_from_date['origin'] / count_active_sites['origin']) * 100\n", | |
" else:\n", | |
" also_active_at_before = 0\n", | |
"\n", | |
" # Calculate CWV change\n", | |
" cwv_changes_active_sites = get_cwv_change_before_after(active_sites, before_date, after_date )\n", | |
" cwv_changes_inactive_sites = get_cwv_change_before_after(inactive_sites, before_date, after_date )\n", | |
"\n", | |
" final_results = calculate_feature_impact(cwv_changes_active_sites, cwv_changes_inactive_sites)\n", | |
" final_results['feature_active_sites'] = count_active_sites['origin']\n", | |
" final_results['feature_inactive_sites'] = count_inactive_sites['origin']\n", | |
" final_results['also_active_at_before'] = \"{:.2%}\".format(also_active_at_before)\n", | |
"\n", | |
" return final_results" | |
], | |
"metadata": { | |
"id": "JL0yN8uu76cq" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Measure feature performance impact minus baseline\n", | |
"#@markdown ### Breakout by device\n", | |
"def query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date):\n", | |
" active_sites = get_sites_with_feature_active(generator_tag, after_date)\n", | |
" count_active_sites = active_sites.count()\n", | |
" inactive_sites = get_sites_with_feature_inactive(generator_tag, after_date)\n", | |
" count_inactive_sites = inactive_sites.count()\n", | |
"\n", | |
" # Count feature active sites that were also feature active at the before date.\n", | |
" active_at_from_date = get_active_sites_also_active_at_before_date(generator_tag, before_date, active_sites)\n", | |
" count_active_at_from_date = active_at_from_date.count()\n", | |
"\n", | |
" # Calculate the percentage of count_active_at_from_date (which might be 0 so use safe divide)\n", | |
" if count_active_sites['origin'] > 0:\n", | |
" also_active_at_before = (count_active_at_from_date['origin'] / count_active_sites['origin']) * 100\n", | |
" else:\n", | |
" also_active_at_before = 0\n", | |
"\n", | |
" # Calculate CWV change\n", | |
" cwv_changes_active_sites = get_cwv_change_before_after_by_device(active_sites, before_date, after_date )\n", | |
" cwv_changes_inactive_sites = get_cwv_change_before_after_by_device(inactive_sites, before_date, after_date )\n", | |
"\n", | |
" final_results = calculate_feature_impact_by_device(cwv_changes_active_sites, cwv_changes_inactive_sites)\n", | |
" final_results['feature_active_sites'] = count_active_sites['origin']\n", | |
" final_results['feature_inactive_sites'] = count_inactive_sites['origin']\n", | |
" final_results['also_active_at_before'] = \"{:.2%}\".format(also_active_at_before)\n", | |
" final_results['before_date'] = before_date\n", | |
" final_results['after_date'] = after_date\n", | |
" final_results['generator_tag'] = generator_tag\n", | |
" final_results['cwv_changes_active_sites'] = cwv_changes_active_sites\n", | |
" final_results['cwv_changes_inactive_sites'] = cwv_changes_inactive_sites\n", | |
"\n", | |
" return final_results" | |
], | |
"metadata": { | |
"id": "UqtzgMvZSpiE" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ## Measure feature performance impact minus baseline\n", | |
"#@markdown ### Breakout by device\n", | |
"def query_cwv_compare_feature_to_baseline_by_device_multiple_tags(generator_tag1, generator_tag2, before_date, after_date):\n", | |
"\n", | |
" active_sites = get_sites_with_features_active(generator_tag1, generator_tag2, after_date)\n", | |
" count_active_sites = active_sites.count()\n", | |
" inactive_sites = get_sites_with_features_inactive(generator_tag1, generator_tag2, after_date)\n", | |
" count_inactive_sites = inactive_sites.count()\n", | |
"\n", | |
" # Count feature active sites that were also feature active at the before date.\n", | |
" active_at_from_date = get_active_sites_also_active_at_before_date_features(generator_tag1, generator_tag2, before_date, active_sites)\n", | |
" count_active_at_from_date = active_at_from_date.count()\n", | |
"\n", | |
" # Calculate the percentage of count_active_at_from_date (which might be 0 so use safe divide)\n", | |
" if count_active_sites['origin'] > 0:\n", | |
" also_active_at_before = (count_active_at_from_date['origin'] / count_active_sites['origin']) * 100\n", | |
" else:\n", | |
" also_active_at_before = 0\n", | |
"\n", | |
" # Calculate CWV change\n", | |
" cwv_changes_active_sites = get_cwv_change_before_after_by_device(active_sites, before_date, after_date )\n", | |
" cwv_changes_inactive_sites = get_cwv_change_before_after_by_device(inactive_sites, before_date, after_date )\n", | |
"\n", | |
" final_results = calculate_feature_impact_by_device(cwv_changes_active_sites, cwv_changes_inactive_sites)\n", | |
" final_results['feature_active_sites'] = count_active_sites['origin']\n", | |
" final_results['feature_inactive_sites'] = count_inactive_sites['origin']\n", | |
" final_results['also_active_at_before'] = \"{:.2%}\".format(also_active_at_before)\n", | |
" final_results['before_date'] = before_date\n", | |
" final_results['after_date'] = after_date\n", | |
" final_results['generator_tag1'] = generator_tag1\n", | |
" final_results['generator_tag2'] = generator_tag2\n", | |
" final_results['cwv_changes_active_sites'] = cwv_changes_active_sites\n", | |
" final_results['cwv_changes_inactive_sites'] = cwv_changes_inactive_sites\n", | |
"\n", | |
" return final_results" | |
], | |
"metadata": { | |
"id": "zRWWFk1jQOMd" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Helper use examples" | |
], | |
"metadata": { | |
"id": "tRAH6Wr0moIo" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"elementor_data = query_cwv_for_technology_over_dates('Elementor')\n", | |
"elementor_data.to_dataframe()" | |
], | |
"metadata": { | |
"id": "whbQMo9ia6HY", | |
"outputId": "578f5c37-ce5d-4716-f756-552a56c27347", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 304 | |
} | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "error", | |
"ename": "KeyboardInterrupt", | |
"evalue": "", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | |
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-31-f6231aad8ad2>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0melementor_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mquery_cwv_for_technology_over_dates\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Elementor'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0melementor_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_dataframe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m<ipython-input-7-5405016ee9ca>\u001b[0m in \u001b[0;36mquery_cwv_for_technology_over_dates\u001b[0;34m(technology, from_date, to_date)\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 102\u001b[0m \u001b[0mquery_job\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 103\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mquery_job\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Return the results of the query\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 104\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 105\u001b[0m \u001b[0;31m# Restrict the query to on the from and to dates, and to the specified from and to versions\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/bigquery/job/query.py\u001b[0m in \u001b[0;36mresult\u001b[0;34m(self, page_size, max_results, retry, timeout, start_index, job_retry)\u001b[0m\n\u001b[1;32m 1674\u001b[0m \u001b[0;31m# Since is_job_done() calls jobs.getQueryResults, which is a\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1675\u001b[0m \u001b[0;31m# long-running API, don't delay the next request at all.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1676\u001b[0;31m \u001b[0;32mwhile\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mis_job_done\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1677\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1678\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/api_core/retry/retry_unary.py\u001b[0m in \u001b[0;36mretry_wrapped_func\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 291\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_initial\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maximum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmultiplier\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_multiplier\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 292\u001b[0m )\n\u001b[0;32m--> 293\u001b[0;31m return retry_target(\n\u001b[0m\u001b[1;32m 294\u001b[0m \u001b[0mtarget\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 295\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_predicate\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/api_core/retry/retry_unary.py\u001b[0m in \u001b[0;36mretry_target\u001b[0;34m(target, predicate, sleep_generator, timeout, on_error, exception_factory, **kwargs)\u001b[0m\n\u001b[1;32m 142\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msleep\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msleep_generator\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 144\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtarget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 145\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0minspect\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misawaitable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_ASYNC_RETRY_WARNING\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/bigquery/job/query.py\u001b[0m in \u001b[0;36mis_job_done\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1643\u001b[0m \u001b[0;31m# jobs.getQueryResults hangs as long as it can to ensure we\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1644\u001b[0m \u001b[0;31m# know when the query has finished as soon as possible.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1645\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_reload_query_results\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mretry\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mretry\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mreload_query_results_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1646\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1647\u001b[0m \u001b[0;31m# Even if the query is finished now according to\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/bigquery/job/query.py\u001b[0m in \u001b[0;36m_reload_query_results\u001b[0;34m(self, retry, timeout, page_size)\u001b[0m\n\u001b[1;32m 1441\u001b[0m \u001b[0mtransport_timeout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1442\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1443\u001b[0;31m self._query_results = self._client._get_query_results(\n\u001b[0m\u001b[1;32m 1444\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjob_id\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1445\u001b[0m \u001b[0mretry\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/bigquery/client.py\u001b[0m in \u001b[0;36m_get_query_results\u001b[0;34m(self, job_id, retry, project, timeout_ms, location, timeout, page_size)\u001b[0m\n\u001b[1;32m 2022\u001b[0m \u001b[0;31m# QueryJob.result()). So we don't need to poll here.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2023\u001b[0m \u001b[0mspan_attributes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m\"path\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mpath\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2024\u001b[0;31m resource = self._call_api(\n\u001b[0m\u001b[1;32m 2025\u001b[0m \u001b[0mretry\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2026\u001b[0m \u001b[0mspan_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"BigQuery.getQueryResults\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/bigquery/client.py\u001b[0m in \u001b[0;36m_call_api\u001b[0;34m(self, retry, span_name, span_attributes, job_ref, headers, **kwargs)\u001b[0m\n\u001b[1;32m 831\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mspan_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mattributes\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mspan_attributes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjob_ref\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mjob_ref\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 832\u001b[0m ):\n\u001b[0;32m--> 833\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 834\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 835\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/api_core/retry/retry_unary.py\u001b[0m in \u001b[0;36mretry_wrapped_func\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 291\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_initial\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_maximum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmultiplier\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_multiplier\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 292\u001b[0m )\n\u001b[0;32m--> 293\u001b[0;31m return retry_target(\n\u001b[0m\u001b[1;32m 294\u001b[0m \u001b[0mtarget\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 295\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_predicate\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/api_core/retry/retry_unary.py\u001b[0m in \u001b[0;36mretry_target\u001b[0;34m(target, predicate, sleep_generator, timeout, on_error, exception_factory, **kwargs)\u001b[0m\n\u001b[1;32m 142\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0msleep\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msleep_generator\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 144\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtarget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 145\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0minspect\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misawaitable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_ASYNC_RETRY_WARNING\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/_http/__init__.py\u001b[0m in \u001b[0;36mapi_request\u001b[0;34m(self, method, path, query_params, data, content_type, headers, api_base_url, api_version, expect_json, _target_object, timeout, extra_api_info)\u001b[0m\n\u001b[1;32m 480\u001b[0m \u001b[0mcontent_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"application/json\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 481\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 482\u001b[0;31m response = self._make_request(\n\u001b[0m\u001b[1;32m 483\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 484\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/_http/__init__.py\u001b[0m in \u001b[0;36m_make_request\u001b[0;34m(self, method, url, data, content_type, headers, target_object, timeout, extra_api_info)\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"User-Agent\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muser_agent\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 341\u001b[0;31m return self._do_request(\n\u001b[0m\u001b[1;32m 342\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtarget_object\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 343\u001b[0m )\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/cloud/_http/__init__.py\u001b[0m in \u001b[0;36m_do_request\u001b[0;34m(self, method, url, headers, data, target_object, timeout)\u001b[0m\n\u001b[1;32m 377\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0mreturns\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mThe\u001b[0m \u001b[0mHTTP\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 378\u001b[0m \"\"\"\n\u001b[0;32m--> 379\u001b[0;31m return self.http.request(\n\u001b[0m\u001b[1;32m 380\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 381\u001b[0m )\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/google/auth/transport/requests.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, data, headers, max_allowed_time, timeout, **kwargs)\u001b[0m\n\u001b[1;32m 539\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 540\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mTimeoutGuard\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mremaining_time\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mguard\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 541\u001b[0;31m response = super(AuthorizedSession, self).request(\n\u001b[0m\u001b[1;32m 542\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 543\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/requests/sessions.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m 587\u001b[0m }\n\u001b[1;32m 588\u001b[0m \u001b[0msend_kwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msettings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 589\u001b[0;31m \u001b[0mresp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprep\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0msend_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 590\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 591\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/requests/sessions.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m 701\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 702\u001b[0m \u001b[0;31m# Send the request\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 703\u001b[0;31m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0madapter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 704\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 705\u001b[0m \u001b[0;31m# Total elapsed time of the request (approximately)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/requests/adapters.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 665\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 666\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 667\u001b[0;31m resp = conn.urlopen(\n\u001b[0m\u001b[1;32m 668\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 669\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/urllib3/connectionpool.py\u001b[0m in \u001b[0;36murlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[0m\n\u001b[1;32m 787\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 788\u001b[0m \u001b[0;31m# Make the request on the HTTPConnection object\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 789\u001b[0;31m response = self._make_request(\n\u001b[0m\u001b[1;32m 790\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 791\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/urllib3/connectionpool.py\u001b[0m in \u001b[0;36m_make_request\u001b[0;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[0m\n\u001b[1;32m 534\u001b[0m \u001b[0;31m# Receive the response from the server\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 535\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 536\u001b[0;31m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetresponse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 537\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mBaseSSLError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mOSError\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 538\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_raise_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout_value\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mread_timeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/urllib3/connection.py\u001b[0m in \u001b[0;36mgetresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 505\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 506\u001b[0m \u001b[0;31m# Get the response from http.client.HTTPConnection\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 507\u001b[0;31m \u001b[0mhttplib_response\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetresponse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 508\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 509\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/http/client.py\u001b[0m in \u001b[0;36mgetresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1373\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1374\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1375\u001b[0;31m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbegin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1376\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mConnectionError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1377\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/http/client.py\u001b[0m in \u001b[0;36mbegin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 316\u001b[0m \u001b[0;31m# read until we get a non-100 response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 317\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 318\u001b[0;31m \u001b[0mversion\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstatus\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreason\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 319\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mstatus\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mCONTINUE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 320\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/http/client.py\u001b[0m in \u001b[0;36m_read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_read_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 279\u001b[0;31m \u001b[0mline\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreadline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_MAXLINE\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"iso-8859-1\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 280\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0m_MAXLINE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 281\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mLineTooLong\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"status line\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/socket.py\u001b[0m in \u001b[0;36mreadinto\u001b[0;34m(self, b)\u001b[0m\n\u001b[1;32m 703\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 704\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 705\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv_into\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 706\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 707\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_timeout_occurred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/ssl.py\u001b[0m in \u001b[0;36mrecv_into\u001b[0;34m(self, buffer, nbytes, flags)\u001b[0m\n\u001b[1;32m 1301\u001b[0m \u001b[0;34m\"non-zero flags not allowed in calls to recv_into() on %s\"\u001b[0m \u001b[0;34m%\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1302\u001b[0m self.__class__)\n\u001b[0;32m-> 1303\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnbytes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuffer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1304\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1305\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv_into\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbuffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnbytes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m/usr/lib/python3.10/ssl.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, len, buffer)\u001b[0m\n\u001b[1;32m 1157\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1158\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mbuffer\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1159\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sslobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuffer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1160\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1161\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sslobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;31mKeyboardInterrupt\u001b[0m: " | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"active_sites = get_sites_with_feature_active('speculation-rules', '2024-11-01')\n", | |
"active_sites.head(5)\n", | |
"\n", | |
"# count active sites\n", | |
"count_active_sites = active_sites.count()\n", | |
"print(count_active_sites)" | |
], | |
"metadata": { | |
"id": "XMUE3rbvwpIr" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"get_sites_with_features_active('embed-optimizer', 'optimization-detective', '2024-09-01')" | |
], | |
"metadata": { | |
"id": "tmX9uC1NQ19C" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"inactive_sites = get_sites_with_feature_inactive('speculation-rules', '2024-08-01')\n", | |
"inactive_sites.head(5)\n", | |
"\n", | |
"# count inactive sites\n", | |
"count_inactive_sites = inactive_sites.count()\n", | |
"print(count_inactive_sites)" | |
], | |
"metadata": { | |
"id": "Sw5e-p6z479N", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "099caf84-dcf3-4d8f-998f-0ba63ec38c76" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"origin 50000\n", | |
"dtype: int64\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"sites = get_sites_with_features_inactive( 'embed-optimizer', 'optimization-detective', '2024-09-01')\n", | |
"sites.head(500)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 669 | |
}, | |
"id": "tOZen3o4Dbw4", | |
"outputId": "bbebd31d-e2f4-4598-edbc-168e4d6b1e78" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
" origin\n", | |
"0 https://mrd.cash/\n", | |
"1 https://www.handipet.org/\n", | |
"2 https://www.mimasaka-no-kuni.jp/\n", | |
"3 https://soundcity.com.ar/\n", | |
"4 https://ciclismoarg.com.ar/\n", | |
".. ...\n", | |
"495 https://ivadi.es/\n", | |
"496 https://meuesquematizado.com.br/\n", | |
"497 https://safemedicinedrop.com/\n", | |
"498 https://visittrollaskagi.is/\n", | |
"499 https://www.plazahyundai.com/\n", | |
"\n", | |
"[500 rows x 1 columns]" | |
], | |
"text/html": [ | |
"\n", | |
" <div id=\"df-ee1862df-8ab7-4db4-9950-0909848343fa\" class=\"colab-df-container\">\n", | |
" <div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>origin</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>https://mrd.cash/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>https://www.handipet.org/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>https://www.mimasaka-no-kuni.jp/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>https://soundcity.com.ar/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>https://ciclismoarg.com.ar/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>...</th>\n", | |
" <td>...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>495</th>\n", | |
" <td>https://ivadi.es/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>496</th>\n", | |
" <td>https://meuesquematizado.com.br/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>497</th>\n", | |
" <td>https://safemedicinedrop.com/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>498</th>\n", | |
" <td>https://visittrollaskagi.is/</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>499</th>\n", | |
" <td>https://www.plazahyundai.com/</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>500 rows × 1 columns</p>\n", | |
"</div>\n", | |
" <div class=\"colab-df-buttons\">\n", | |
"\n", | |
" <div class=\"colab-df-container\">\n", | |
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-ee1862df-8ab7-4db4-9950-0909848343fa')\"\n", | |
" title=\"Convert this dataframe to an interactive table.\"\n", | |
" style=\"display:none;\">\n", | |
"\n", | |
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n", | |
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n", | |
" </svg>\n", | |
" </button>\n", | |
"\n", | |
" <style>\n", | |
" .colab-df-container {\n", | |
" display:flex;\n", | |
" gap: 12px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-convert {\n", | |
" background-color: #E8F0FE;\n", | |
" border: none;\n", | |
" border-radius: 50%;\n", | |
" cursor: pointer;\n", | |
" display: none;\n", | |
" fill: #1967D2;\n", | |
" height: 32px;\n", | |
" padding: 0 0 0 0;\n", | |
" width: 32px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-convert:hover {\n", | |
" background-color: #E2EBFA;\n", | |
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
" fill: #174EA6;\n", | |
" }\n", | |
"\n", | |
" .colab-df-buttons div {\n", | |
" margin-bottom: 4px;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-convert {\n", | |
" background-color: #3B4455;\n", | |
" fill: #D2E3FC;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-convert:hover {\n", | |
" background-color: #434B5C;\n", | |
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
" fill: #FFFFFF;\n", | |
" }\n", | |
" </style>\n", | |
"\n", | |
" <script>\n", | |
" const buttonEl =\n", | |
" document.querySelector('#df-ee1862df-8ab7-4db4-9950-0909848343fa button.colab-df-convert');\n", | |
" buttonEl.style.display =\n", | |
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
"\n", | |
" async function convertToInteractive(key) {\n", | |
" const element = document.querySelector('#df-ee1862df-8ab7-4db4-9950-0909848343fa');\n", | |
" const dataTable =\n", | |
" await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
" [key], {});\n", | |
" if (!dataTable) return;\n", | |
"\n", | |
" const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
" + ' to learn more about interactive tables.';\n", | |
" element.innerHTML = '';\n", | |
" dataTable['output_type'] = 'display_data';\n", | |
" await google.colab.output.renderOutput(dataTable, element);\n", | |
" const docLink = document.createElement('div');\n", | |
" docLink.innerHTML = docLinkHtml;\n", | |
" element.appendChild(docLink);\n", | |
" }\n", | |
" </script>\n", | |
" </div>\n", | |
"\n", | |
"\n", | |
"<div id=\"df-55a2c921-c32c-45d2-b681-54f053a9ac56\">\n", | |
" <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-55a2c921-c32c-45d2-b681-54f053a9ac56')\"\n", | |
" title=\"Suggest charts\"\n", | |
" style=\"display:none;\">\n", | |
"\n", | |
"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
" width=\"24px\">\n", | |
" <g>\n", | |
" <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n", | |
" </g>\n", | |
"</svg>\n", | |
" </button>\n", | |
"\n", | |
"<style>\n", | |
" .colab-df-quickchart {\n", | |
" --bg-color: #E8F0FE;\n", | |
" --fill-color: #1967D2;\n", | |
" --hover-bg-color: #E2EBFA;\n", | |
" --hover-fill-color: #174EA6;\n", | |
" --disabled-fill-color: #AAA;\n", | |
" --disabled-bg-color: #DDD;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-quickchart {\n", | |
" --bg-color: #3B4455;\n", | |
" --fill-color: #D2E3FC;\n", | |
" --hover-bg-color: #434B5C;\n", | |
" --hover-fill-color: #FFFFFF;\n", | |
" --disabled-bg-color: #3B4455;\n", | |
" --disabled-fill-color: #666;\n", | |
" }\n", | |
"\n", | |
" .colab-df-quickchart {\n", | |
" background-color: var(--bg-color);\n", | |
" border: none;\n", | |
" border-radius: 50%;\n", | |
" cursor: pointer;\n", | |
" display: none;\n", | |
" fill: var(--fill-color);\n", | |
" height: 32px;\n", | |
" padding: 0;\n", | |
" width: 32px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-quickchart:hover {\n", | |
" background-color: var(--hover-bg-color);\n", | |
" box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
" fill: var(--button-hover-fill-color);\n", | |
" }\n", | |
"\n", | |
" .colab-df-quickchart-complete:disabled,\n", | |
" .colab-df-quickchart-complete:disabled:hover {\n", | |
" background-color: var(--disabled-bg-color);\n", | |
" fill: var(--disabled-fill-color);\n", | |
" box-shadow: none;\n", | |
" }\n", | |
"\n", | |
" .colab-df-spinner {\n", | |
" border: 2px solid var(--fill-color);\n", | |
" border-color: transparent;\n", | |
" border-bottom-color: var(--fill-color);\n", | |
" animation:\n", | |
" spin 1s steps(1) infinite;\n", | |
" }\n", | |
"\n", | |
" @keyframes spin {\n", | |
" 0% {\n", | |
" border-color: transparent;\n", | |
" border-bottom-color: var(--fill-color);\n", | |
" border-left-color: var(--fill-color);\n", | |
" }\n", | |
" 20% {\n", | |
" border-color: transparent;\n", | |
" border-left-color: var(--fill-color);\n", | |
" border-top-color: var(--fill-color);\n", | |
" }\n", | |
" 30% {\n", | |
" border-color: transparent;\n", | |
" border-left-color: var(--fill-color);\n", | |
" border-top-color: var(--fill-color);\n", | |
" border-right-color: var(--fill-color);\n", | |
" }\n", | |
" 40% {\n", | |
" border-color: transparent;\n", | |
" border-right-color: var(--fill-color);\n", | |
" border-top-color: var(--fill-color);\n", | |
" }\n", | |
" 60% {\n", | |
" border-color: transparent;\n", | |
" border-right-color: var(--fill-color);\n", | |
" }\n", | |
" 80% {\n", | |
" border-color: transparent;\n", | |
" border-right-color: var(--fill-color);\n", | |
" border-bottom-color: var(--fill-color);\n", | |
" }\n", | |
" 90% {\n", | |
" border-color: transparent;\n", | |
" border-bottom-color: var(--fill-color);\n", | |
" }\n", | |
" }\n", | |
"</style>\n", | |
"\n", | |
" <script>\n", | |
" async function quickchart(key) {\n", | |
" const quickchartButtonEl =\n", | |
" document.querySelector('#' + key + ' button');\n", | |
" quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n", | |
" quickchartButtonEl.classList.add('colab-df-spinner');\n", | |
" try {\n", | |
" const charts = await google.colab.kernel.invokeFunction(\n", | |
" 'suggestCharts', [key], {});\n", | |
" } catch (error) {\n", | |
" console.error('Error during call to suggestCharts:', error);\n", | |
" }\n", | |
" quickchartButtonEl.classList.remove('colab-df-spinner');\n", | |
" quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n", | |
" }\n", | |
" (() => {\n", | |
" let quickchartButtonEl =\n", | |
" document.querySelector('#df-55a2c921-c32c-45d2-b681-54f053a9ac56 button');\n", | |
" quickchartButtonEl.style.display =\n", | |
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
" })();\n", | |
" </script>\n", | |
"</div>\n", | |
"\n", | |
" </div>\n", | |
" </div>\n" | |
], | |
"application/vnd.google.colaboratory.intrinsic+json": { | |
"type": "dataframe", | |
"variable_name": "sites", | |
"summary": "{\n \"name\": \"sites\",\n \"rows\": 50000,\n \"fields\": [\n {\n \"column\": \"origin\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 50000,\n \"samples\": [\n \"https://lavalamp.com/\",\n \"https://www.ledneonflexarg.com.ar/\",\n \"https://drcinikshop.com/\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}" | |
}, | |
"application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/e523c247d1e24a05/data_table.js\";\n\n const table = window.createDataTable({\n data: [[{\n 'v': 0,\n 'f': \"0\",\n },\n\"https://mrd.cash/\"],\n [{\n 'v': 1,\n 'f': \"1\",\n },\n\"https://www.handipet.org/\"],\n [{\n 'v': 2,\n 'f': \"2\",\n },\n\"https://www.mimasaka-no-kuni.jp/\"],\n [{\n 'v': 3,\n 'f': \"3\",\n },\n\"https://soundcity.com.ar/\"],\n [{\n 'v': 4,\n 'f': \"4\",\n },\n\"https://ciclismoarg.com.ar/\"],\n [{\n 'v': 5,\n 'f': \"5\",\n },\n\"https://www.freigeist-burger.at/\"],\n [{\n 'v': 6,\n 'f': \"6\",\n },\n\"https://first-clinic.jp/\"],\n [{\n 'v': 7,\n 'f': \"7\",\n },\n\"https://www.suntrupkiasouth.com/\"],\n [{\n 'v': 8,\n 'f': \"8\",\n },\n\"https://ov.taigua.cat/\"],\n [{\n 'v': 9,\n 'f': \"9\",\n },\n\"http://www.piscine-quiberon.fr/\"],\n [{\n 'v': 10,\n 'f': \"10\",\n },\n\"https://ferroluzinversiones.com/\"],\n [{\n 'v': 11,\n 'f': \"11\",\n },\n\"https://www.kumsalsohbet.net/\"],\n [{\n 'v': 12,\n 'f': \"12\",\n },\n\"https://gazetasledcza.pl/\"],\n [{\n 'v': 13,\n 'f': \"13\",\n },\n\"https://biology.tcnj.edu/\"],\n [{\n 'v': 14,\n 'f': \"14\",\n },\n\"https://www.hotel-de-brunville.com/\"],\n [{\n 'v': 15,\n 'f': \"15\",\n },\n\"https://tecnordeste.com.br/\"],\n [{\n 'v': 16,\n 'f': \"16\",\n },\n\"https://bigjoeboreholes.co.za/\"],\n [{\n 'v': 17,\n 'f': \"17\",\n },\n\"https://jornadaalimentacao.com.br/\"],\n [{\n 'v': 18,\n 'f': \"18\",\n },\n\"http://escuelaecologica.com.ar/\"],\n [{\n 'v': 19,\n 'f': \"19\",\n },\n\"http://latablederivegauche.com/\"],\n [{\n 'v': 20,\n 'f': \"20\",\n },\n\"https://www.camping-aure-pyrenees.com/\"],\n [{\n 'v': 21,\n 'f': \"21\",\n },\n\"https://hentai2.org/\"],\n [{\n 'v': 22,\n 'f': \"22\",\n },\n\"https://www.hydoll.jp/\"],\n [{\n 'v': 23,\n 'f': \"23\",\n },\n\"https://turbotoyssa.co.za/\"],\n [{\n 'v': 24,\n 'f': \"24\",\n },\n\"https://aldhafrahs-seha.com/\"],\n [{\n 'v': 25,\n 'f': \"25\",\n },\n\"https://newreach.nl/\"],\n [{\n 'v': 26,\n 'f': \"26\",\n },\n\"https://www.thaisakyant.com/\"],\n [{\n 'v': 27,\n 'f': \"27\",\n },\n\"https://techautonews.com/\"],\n [{\n 'v': 28,\n 'f': \"28\",\n },\n\"https://www.aguanteneuquen.com.ar/\"],\n [{\n 'v': 29,\n 'f': \"29\",\n },\n\"https://lapompeya.com/\"],\n [{\n 'v': 30,\n 'f': \"30\",\n },\n\"https://www.topingatlan.net/\"],\n [{\n 'v': 31,\n 'f': \"31\",\n },\n\"https://poslovnikontakt.com/\"],\n [{\n 'v': 32,\n 'f': \"32\",\n },\n\"https://siksvn.com/\"],\n [{\n 'v': 33,\n 'f': \"33\",\n },\n\"https://mrsillucia.com/\"],\n [{\n 'v': 34,\n 'f': \"34\",\n },\n\"https://kidzville.co.za/\"],\n [{\n 'v': 35,\n 'f': \"35\",\n },\n\"https://dancecentre.co.ke/\"],\n [{\n 'v': 36,\n 'f': \"36\",\n },\n\"https://www.gkcuzice.rs/\"],\n [{\n 'v': 37,\n 'f': \"37\",\n },\n\"https://ajurvedamoterims.lt/\"],\n [{\n 'v': 38,\n 'f': \"38\",\n },\n\"https://app.tokoorder.com/\"],\n [{\n 'v': 39,\n 'f': \"39\",\n },\n\"https://unique-hotels.pl/\"],\n [{\n 'v': 40,\n 'f': \"40\",\n },\n\"https://clinicamiguelangelgarcia.com/\"],\n [{\n 'v': 41,\n 'f': \"41\",\n },\n\"https://blog.alyssachan.space/\"],\n [{\n 'v': 42,\n 'f': \"42\",\n },\n\"https://news.kg/\"],\n [{\n 'v': 43,\n 'f': \"43\",\n },\n\"https://www.canoeatl.com/\"],\n [{\n 'v': 44,\n 'f': \"44\",\n },\n\"https://diskanak.bogorkab.go.id/\"],\n [{\n 'v': 45,\n 'f': \"45\",\n },\n\"https://electrogeo.com/\"],\n [{\n 'v': 46,\n 'f': \"46\",\n },\n\"https://www.infinitioflafayette.com/\"],\n [{\n 'v': 47,\n 'f': \"47\",\n },\n\"https://www.mercedes-benz-kelowna.ca/\"],\n [{\n 'v': 48,\n 'f': \"48\",\n },\n\"http://www.istitutobeatogregorio.it/\"],\n [{\n 'v': 49,\n 'f': \"49\",\n },\n\"https://sportskstars.com/\"],\n [{\n 'v': 50,\n 'f': \"50\",\n },\n\"https://de-lijn.com/\"],\n [{\n 'v': 51,\n 'f': \"51\",\n },\n\"https://viktoria-apartments.cz/\"],\n [{\n 'v': 52,\n 'f': \"52\",\n },\n\"https://natureconceptcm.com/\"],\n [{\n 'v': 53,\n 'f': \"53\",\n },\n\"https://programaahora.misiones.gob.ar/\"],\n [{\n 'v': 54,\n 'f': \"54\",\n },\n\"http://mirupak-irk.ru/\"],\n [{\n 'v': 55,\n 'f': \"55\",\n },\n\"https://www.denieuwedriehoek.be/\"],\n [{\n 'v': 56,\n 'f': \"56\",\n },\n\"https://csm.com.co/\"],\n [{\n 'v': 57,\n 'f': \"57\",\n },\n\"https://elcarpinteroloco.com.ar/\"],\n [{\n 'v': 58,\n 'f': \"58\",\n },\n\"https://dhibrahm.com/\"],\n [{\n 'v': 59,\n 'f': \"59\",\n },\n\"https://o2genes.com/\"],\n [{\n 'v': 60,\n 'f': \"60\",\n },\n\"https://saweratownships.com/\"],\n [{\n 'v': 61,\n 'f': \"61\",\n },\n\"https://www.lbk.be/\"],\n [{\n 'v': 62,\n 'f': \"62\",\n },\n\"https://kino.altmkc.ru/\"],\n [{\n 'v': 63,\n 'f': \"63\",\n },\n\"https://malalsham.com/\"],\n [{\n 'v': 64,\n 'f': \"64\",\n },\n\"https://fav3d.com.ar/\"],\n [{\n 'v': 65,\n 'f': \"65\",\n },\n\"https://seguroautoromaze.com.br/\"],\n [{\n 'v': 66,\n 'f': \"66\",\n },\n\"https://prangthip.ac.th/\"],\n [{\n 'v': 67,\n 'f': \"67\",\n },\n\"https://theraj.in/\"],\n [{\n 'v': 68,\n 'f': \"68\",\n },\n\"http://www.alberguemiguelin.com/\"],\n [{\n 'v': 69,\n 'f': \"69\",\n },\n\"http://www.loevkraj.by/\"],\n [{\n 'v': 70,\n 'f': \"70\",\n },\n\"https://newsmile.com.ua/\"],\n [{\n 'v': 71,\n 'f': \"71\",\n },\n\"https://diary.co.id/\"],\n [{\n 'v': 72,\n 'f': \"72\",\n },\n\"https://24ctnaturaloils.com/\"],\n [{\n 'v': 73,\n 'f': \"73\",\n },\n\"http://dayhocblx.com/\"],\n [{\n 'v': 74,\n 'f': \"74\",\n },\n\"https://mens-reson.com/\"],\n [{\n 'v': 75,\n 'f': \"75\",\n },\n\"https://polsrl.com/\"],\n [{\n 'v': 76,\n 'f': \"76\",\n },\n\"https://higiene-seguridad.com.ar/\"],\n [{\n 'v': 77,\n 'f': \"77\",\n },\n\"https://annahl.sch.id/\"],\n [{\n 'v': 78,\n 'f': \"78\",\n },\n\"https://www.corimonpinturas.com/\"],\n [{\n 'v': 79,\n 'f': \"79\",\n },\n\"https://pappkittiugyved.hu/\"],\n [{\n 'v': 80,\n 'f': \"80\",\n },\n\"https://www.ymaoo.cn/\"],\n [{\n 'v': 81,\n 'f': \"81\",\n },\n\"https://wasabill.pk/\"],\n [{\n 'v': 82,\n 'f': \"82\",\n },\n\"https://catorrent.com/\"],\n [{\n 'v': 83,\n 'f': \"83\",\n },\n\"https://www.herbalmedicine.co.il/\"],\n [{\n 'v': 84,\n 'f': \"84\",\n },\n\"https://intuitiveanswers.com/\"],\n [{\n 'v': 85,\n 'f': \"85\",\n },\n\"https://pokerliveupdates.com/\"],\n [{\n 'v': 86,\n 'f': \"86\",\n },\n\"https://spotyagmarket.com/\"],\n [{\n 'v': 87,\n 'f': \"87\",\n },\n\"https://trainvision.es/\"],\n [{\n 'v': 88,\n 'f': \"88\",\n },\n\"https://eromantik.net/\"],\n [{\n 'v': 89,\n 'f': \"89\",\n },\n\"https://therawellness.us/\"],\n [{\n 'v': 90,\n 'f': \"90\",\n },\n\"http://marutomo-sh.co.jp/\"],\n [{\n 'v': 91,\n 'f': \"91\",\n },\n\"https://www.arepe-mrjardinage.fr/\"],\n [{\n 'v': 92,\n 'f': \"92\",\n },\n\"https://frtbme.hu/\"],\n [{\n 'v': 93,\n 'f': \"93\",\n },\n\"https://modernaestofados.com.br/\"],\n [{\n 'v': 94,\n 'f': \"94\",\n },\n\"https://inhalemd.com/\"],\n [{\n 'v': 95,\n 'f': \"95\",\n },\n\"http://www.r-hajime.jp/\"],\n [{\n 'v': 96,\n 'f': \"96\",\n },\n\"https://popup.co.za/\"],\n [{\n 'v': 97,\n 'f': \"97\",\n },\n\"http://biofaceradiologia.com.br/\"],\n [{\n 'v': 98,\n 'f': \"98\",\n },\n\"https://rttravel.rs/\"],\n [{\n 'v': 99,\n 'f': \"99\",\n },\n\"https://esr.com.ar/\"],\n [{\n 'v': 100,\n 'f': \"100\",\n },\n\"https://www.alfafl.com/\"],\n [{\n 'v': 101,\n 'f': \"101\",\n },\n\"https://www.creditoficoufacil.com.br/\"],\n [{\n 'v': 102,\n 'f': \"102\",\n },\n\"https://deklaroen.be/\"],\n [{\n 'v': 103,\n 'f': \"103\",\n },\n\"https://woodflooringireland.ie/\"],\n [{\n 'v': 104,\n 'f': \"104\",\n },\n\"https://www.maxstuder.ch/\"],\n [{\n 'v': 105,\n 'f': \"105\",\n },\n\"https://www.palmbayford.com/\"],\n [{\n 'v': 106,\n 'f': \"106\",\n },\n\"https://www.svenskahudkliniker.se/\"],\n [{\n 'v': 107,\n 'f': \"107\",\n },\n\"https://www.saudiags.com/\"],\n [{\n 'v': 108,\n 'f': \"108\",\n },\n\"https://www.canadafloorsdepot.com/\"],\n [{\n 'v': 109,\n 'f': \"109\",\n },\n\"https://www.bbobbler.com/\"],\n [{\n 'v': 110,\n 'f': \"110\",\n },\n\"https://encometal.com.ar/\"],\n [{\n 'v': 111,\n 'f': \"111\",\n },\n\"https://www.valenciaforestschool.es/\"],\n [{\n 'v': 112,\n 'f': \"112\",\n },\n\"https://onlineprodajanovatelefonija.rs/\"],\n [{\n 'v': 113,\n 'f': \"113\",\n },\n\"https://evo-land.de/\"],\n [{\n 'v': 114,\n 'f': \"114\",\n },\n\"http://www.eqmarriageservice.com/\"],\n [{\n 'v': 115,\n 'f': \"115\",\n },\n\"https://tuah.com.my/\"],\n [{\n 'v': 116,\n 'f': \"116\",\n },\n\"https://apcainsebt.dz/\"],\n [{\n 'v': 117,\n 'f': \"117\",\n },\n\"https://museumexplorer.co.za/\"],\n [{\n 'v': 118,\n 'f': \"118\",\n },\n\"http://difmazatlan.gob.mx/\"],\n [{\n 'v': 119,\n 'f': \"119\",\n },\n\"https://goodnights.in/\"],\n [{\n 'v': 120,\n 'f': \"120\",\n },\n\"https://catolicanet.net/\"],\n [{\n 'v': 121,\n 'f': \"121\",\n },\n\"https://outdoor-styles.com/\"],\n [{\n 'v': 122,\n 'f': \"122\",\n },\n\"https://hanamaru.my/\"],\n [{\n 'v': 123,\n 'f': \"123\",\n },\n\"https://direitotrabalhista.bravoebonatto.com.br/\"],\n [{\n 'v': 124,\n 'f': \"124\",\n },\n\"https://consultoriosmedicos.com.ar/\"],\n [{\n 'v': 125,\n 'f': \"125\",\n },\n\"https://www.bcsd15.org/\"],\n [{\n 'v': 126,\n 'f': \"126\",\n },\n\"https://fideuadegandia.org/\"],\n [{\n 'v': 127,\n 'f': \"127\",\n },\n\"https://wccoa.net/\"],\n [{\n 'v': 128,\n 'f': \"128\",\n },\n\"https://pizza-show.com/\"],\n [{\n 'v': 129,\n 'f': \"129\",\n },\n\"https://www.michaelsvalleygrill.com/\"],\n [{\n 'v': 130,\n 'f': \"130\",\n },\n\"https://szamosituzep.hu/\"],\n [{\n 'v': 131,\n 'f': \"131\",\n },\n\"http://www.cme1.com.br/\"],\n [{\n 'v': 132,\n 'f': \"132\",\n },\n\"https://calisthenicssa.com.au/\"],\n [{\n 'v': 133,\n 'f': \"133\",\n },\n\"https://stellenboschvineyards.co.za/\"],\n [{\n 'v': 134,\n 'f': \"134\",\n },\n\"https://medicine.uniben.edu/\"],\n [{\n 'v': 135,\n 'f': \"135\",\n },\n\"https://idm.edu.vn/\"],\n [{\n 'v': 136,\n 'f': \"136\",\n },\n\"https://hidraliso-loja.com.br/\"],\n [{\n 'v': 137,\n 'f': \"137\",\n },\n\"https://kidsslides.co.za/\"],\n [{\n 'v': 138,\n 'f': \"138\",\n },\n\"https://www.palmspringsmotors.com/\"],\n [{\n 'v': 139,\n 'f': \"139\",\n },\n\"https://jnvkalumni.in/\"],\n [{\n 'v': 140,\n 'f': \"140\",\n },\n\"https://nsagg.ir/\"],\n [{\n 'v': 141,\n 'f': \"141\",\n },\n\"http://medlive.com.br/\"],\n [{\n 'v': 142,\n 'f': \"142\",\n },\n\"https://www.chakhdhoom.co.uk/\"],\n [{\n 'v': 143,\n 'f': \"143\",\n },\n\"https://majajamoneria.com/\"],\n [{\n 'v': 144,\n 'f': \"144\",\n },\n\"https://jonkvorstfoto.wordpress.com/\"],\n [{\n 'v': 145,\n 'f': \"145\",\n },\n\"https://webacademica.com/\"],\n [{\n 'v': 146,\n 'f': \"146\",\n },\n\"https://onethatch.com/\"],\n [{\n 'v': 147,\n 'f': \"147\",\n },\n\"https://paladin.care/\"],\n [{\n 'v': 148,\n 'f': \"148\",\n },\n\"https://www.aquelakombucha.pt/\"],\n [{\n 'v': 149,\n 'f': \"149\",\n },\n\"https://bazaar.lovedog.tw/\"],\n [{\n 'v': 150,\n 'f': \"150\",\n },\n\"https://s-art.co.jp/\"],\n [{\n 'v': 151,\n 'f': \"151\",\n },\n\"https://www.ayvaliktostcu.com/\"],\n [{\n 'v': 152,\n 'f': \"152\",\n },\n\"https://beithamamtak.co.il/\"],\n [{\n 'v': 153,\n 'f': \"153\",\n },\n\"http://thecarenursinghome.com/\"],\n [{\n 'v': 154,\n 'f': \"154\",\n },\n\"https://betongtrangtribm.vn/\"],\n [{\n 'v': 155,\n 'f': \"155\",\n },\n\"http://wordtsar.ca/\"],\n [{\n 'v': 156,\n 'f': \"156\",\n },\n\"https://www.vitalogikum.at/\"],\n [{\n 'v': 157,\n 'f': \"157\",\n },\n\"https://iswim.bialystok.pl/\"],\n [{\n 'v': 158,\n 'f': \"158\",\n },\n\"https://damattaind.com.br/\"],\n [{\n 'v': 159,\n 'f': \"159\",\n },\n\"https://buchtajeziorak.pl/\"],\n [{\n 'v': 160,\n 'f': \"160\",\n },\n\"https://www.southlanddodgechryslerjeep.com/\"],\n [{\n 'v': 161,\n 'f': \"161\",\n },\n\"https://www.wernerhyundai.com/\"],\n [{\n 'v': 162,\n 'f': \"162\",\n },\n\"https://www.kreat.pe/\"],\n [{\n 'v': 163,\n 'f': \"163\",\n },\n\"https://paulismakeup.co/\"],\n [{\n 'v': 164,\n 'f': \"164\",\n },\n\"https://www.feestweekabcoude.nl/\"],\n [{\n 'v': 165,\n 'f': \"165\",\n },\n\"https://www.vimondmateriaux.com/\"],\n [{\n 'v': 166,\n 'f': \"166\",\n },\n\"https://www.affa.no/\"],\n [{\n 'v': 167,\n 'f': \"167\",\n },\n\"https://casaslimache.cl/\"],\n [{\n 'v': 168,\n 'f': \"168\",\n },\n\"https://heartcore-athletics.com/\"],\n [{\n 'v': 169,\n 'f': \"169\",\n },\n\"https://reflux-gyomor-nyombel.hu/\"],\n [{\n 'v': 170,\n 'f': \"170\",\n },\n\"https://streetcc.com/\"],\n [{\n 'v': 171,\n 'f': \"171\",\n },\n\"https://geolearn.in/\"],\n [{\n 'v': 172,\n 'f': \"172\",\n },\n\"https://digitalrajat.io/\"],\n [{\n 'v': 173,\n 'f': \"173\",\n },\n\"https://www.restaurantemugarra.com/\"],\n [{\n 'v': 174,\n 'f': \"174\",\n },\n\"https://megacercos.com/\"],\n [{\n 'v': 175,\n 'f': \"175\",\n },\n\"https://xn--tattoofashionrdovre-87b.dk/\"],\n [{\n 'v': 176,\n 'f': \"176\",\n },\n\"https://jm3yah.com/\"],\n [{\n 'v': 177,\n 'f': \"177\",\n },\n\"https://kvizprof.hu/\"],\n [{\n 'v': 178,\n 'f': \"178\",\n },\n\"https://ideiaspresentes.com/\"],\n [{\n 'v': 179,\n 'f': \"179\",\n },\n\"https://masivoyretail.com/\"],\n [{\n 'v': 180,\n 'f': \"180\",\n },\n\"https://mielite.com/\"],\n [{\n 'v': 181,\n 'f': \"181\",\n },\n\"https://davidwright.com.au/\"],\n [{\n 'v': 182,\n 'f': \"182\",\n },\n\"https://kinkylondonescorts.co.uk/\"],\n [{\n 'v': 183,\n 'f': \"183\",\n },\n\"https://www.uvvg.ro/\"],\n [{\n 'v': 184,\n 'f': \"184\",\n },\n\"http://www.smakiweroniki.pl/\"],\n [{\n 'v': 185,\n 'f': \"185\",\n },\n\"https://premiumhome.com.ar/\"],\n [{\n 'v': 186,\n 'f': \"186\",\n },\n\"https://jcilmglobal.info/\"],\n [{\n 'v': 187,\n 'f': \"187\",\n },\n\"https://www.projectkesher.org.ua/\"],\n [{\n 'v': 188,\n 'f': \"188\",\n },\n\"https://centre.nikkeiplace.org/\"],\n [{\n 'v': 189,\n 'f': \"189\",\n },\n\"https://cursoreparodeplacasinverter.com/\"],\n [{\n 'v': 190,\n 'f': \"190\",\n },\n\"https://www.stick-and-stone-run.de/\"],\n [{\n 'v': 191,\n 'f': \"191\",\n },\n\"https://www.classifiedmoto.com/\"],\n [{\n 'v': 192,\n 'f': \"192\",\n },\n\"https://oralsinsaosebastiao.com.br/\"],\n [{\n 'v': 193,\n 'f': \"193\",\n },\n\"https://mopptex.com/\"],\n [{\n 'v': 194,\n 'f': \"194\",\n },\n\"http://www.torejaras.com/\"],\n [{\n 'v': 195,\n 'f': \"195\",\n },\n\"https://keysfamilybutchershop.com/\"],\n [{\n 'v': 196,\n 'f': \"196\",\n },\n\"https://www.mattzgarage.at/\"],\n [{\n 'v': 197,\n 'f': \"197\",\n },\n\"https://thehimalayanchocolates.com/\"],\n [{\n 'v': 198,\n 'f': \"198\",\n },\n\"https://alghawasnews.com/\"],\n [{\n 'v': 199,\n 'f': \"199\",\n },\n\"https://drcinikshop.com/\"],\n [{\n 'v': 200,\n 'f': \"200\",\n },\n\"https://gortest.com/\"],\n [{\n 'v': 201,\n 'f': \"201\",\n },\n\"https://www.hyundaiofalbany.com/\"],\n [{\n 'v': 202,\n 'f': \"202\",\n },\n\"https://surgenutrition.in/\"],\n [{\n 'v': 203,\n 'f': \"203\",\n },\n\"https://www.pimas.fr/\"],\n [{\n 'v': 204,\n 'f': \"204\",\n },\n\"https://formulat77.com/\"],\n [{\n 'v': 205,\n 'f': \"205\",\n },\n\"http://www.nittaidai-fc.com/\"],\n [{\n 'v': 206,\n 'f': \"206\",\n },\n\"https://www.slot-labo.com/\"],\n [{\n 'v': 207,\n 'f': \"207\",\n },\n\"https://kaltex.global/\"],\n [{\n 'v': 208,\n 'f': \"208\",\n },\n\"http://www.cannes-petit-train.com/\"],\n [{\n 'v': 209,\n 'f': \"209\",\n },\n\"https://abercor.com.ar/\"],\n [{\n 'v': 210,\n 'f': \"210\",\n },\n\"https://travelua.com.ua/\"],\n [{\n 'v': 211,\n 'f': \"211\",\n },\n\"https://talkbitz.com/\"],\n [{\n 'v': 212,\n 'f': \"212\",\n },\n\"https://goelette.ca/\"],\n [{\n 'v': 213,\n 'f': \"213\",\n },\n\"https://caddiesgolf.co.uk/\"],\n [{\n 'v': 214,\n 'f': \"214\",\n },\n\"https://martynasoul.com/\"],\n [{\n 'v': 215,\n 'f': \"215\",\n },\n\"https://www.mercedes-benz-newmarket.ca/\"],\n [{\n 'v': 216,\n 'f': \"216\",\n },\n\"https://clarissaviaggi.com/\"],\n [{\n 'v': 217,\n 'f': \"217\",\n },\n\"https://www.komsem.de/\"],\n [{\n 'v': 218,\n 'f': \"218\",\n },\n\"https://dive-scoop.com/\"],\n [{\n 'v': 219,\n 'f': \"219\",\n },\n\"https://www.mikewhatleyhonda.com/\"],\n [{\n 'v': 220,\n 'f': \"220\",\n },\n\"https://genderparty.top/\"],\n [{\n 'v': 221,\n 'f': \"221\",\n },\n\"https://logomaker.click/\"],\n [{\n 'v': 222,\n 'f': \"222\",\n },\n\"https://belzy27.pl/\"],\n [{\n 'v': 223,\n 'f': \"223\",\n },\n\"https://almanca-begibegi.com/\"],\n [{\n 'v': 224,\n 'f': \"224\",\n },\n\"https://boulder-zone.pl/\"],\n [{\n 'v': 225,\n 'f': \"225\",\n },\n\"https://www.shinzato-saiyou.jp/\"],\n [{\n 'v': 226,\n 'f': \"226\",\n },\n\"https://www.ihrlungenarzt.at/\"],\n [{\n 'v': 227,\n 'f': \"227\",\n },\n\"https://dalma.com.ar/\"],\n [{\n 'v': 228,\n 'f': \"228\",\n },\n\"https://www.welzijncapelle.nl/\"],\n [{\n 'v': 229,\n 'f': \"229\",\n },\n\"https://manastireabodrog.ro/\"],\n [{\n 'v': 230,\n 'f': \"230\",\n },\n\"https://office-keys.nl/\"],\n [{\n 'v': 231,\n 'f': \"231\",\n },\n\"https://ravipharma.in/\"],\n [{\n 'v': 232,\n 'f': \"232\",\n },\n\"https://www.knittel-entsorgung.com/\"],\n [{\n 'v': 233,\n 'f': \"233\",\n },\n\"https://eakces.eu/\"],\n [{\n 'v': 234,\n 'f': \"234\",\n },\n\"https://kcsir.pl/\"],\n [{\n 'v': 235,\n 'f': \"235\",\n },\n\"https://www.trombetabath.com/\"],\n [{\n 'v': 236,\n 'f': \"236\",\n },\n\"https://golkarpedia.com/\"],\n [{\n 'v': 237,\n 'f': \"237\",\n },\n\"https://ww5.cmovies.co/\"],\n [{\n 'v': 238,\n 'f': \"238\",\n },\n\"https://radiointeractivafm.cl/\"],\n [{\n 'v': 239,\n 'f': \"239\",\n },\n\"https://rendeneralpinefood.it/\"],\n [{\n 'v': 240,\n 'f': \"240\",\n },\n\"https://www.centralvalleyauto.com/\"],\n [{\n 'v': 241,\n 'f': \"241\",\n },\n\"https://dragonwhite.com/\"],\n [{\n 'v': 242,\n 'f': \"242\",\n },\n\"https://ekobites.nl/\"],\n [{\n 'v': 243,\n 'f': \"243\",\n },\n\"https://cadmaxxedtech.com/\"],\n [{\n 'v': 244,\n 'f': \"244\",\n },\n\"https://www.panelectronicsindia.com/\"],\n [{\n 'v': 245,\n 'f': \"245\",\n },\n\"https://institutosanvicente.com/\"],\n [{\n 'v': 246,\n 'f': \"246\",\n },\n\"https://cheaperbytheday1.com/\"],\n [{\n 'v': 247,\n 'f': \"247\",\n },\n\"https://www.vegan-wein.at/\"],\n [{\n 'v': 248,\n 'f': \"248\",\n },\n\"https://www.quirk.mercedesdealer.com/\"],\n [{\n 'v': 249,\n 'f': \"249\",\n },\n\"https://projectcalls.com/\"],\n [{\n 'v': 250,\n 'f': \"250\",\n },\n\"https://www.nightvisions.info/\"],\n [{\n 'v': 251,\n 'f': \"251\",\n },\n\"https://www.abbeyshebburn.co.uk/\"],\n [{\n 'v': 252,\n 'f': \"252\",\n },\n\"https://jobs.angelscarehealth.com/\"],\n [{\n 'v': 253,\n 'f': \"253\",\n },\n\"http://vynuogynas.lt/\"],\n [{\n 'v': 254,\n 'f': \"254\",\n },\n\"https://restauranteyoakewangalfafar.es/\"],\n [{\n 'v': 255,\n 'f': \"255\",\n },\n\"https://armtek.com.tr/\"],\n [{\n 'v': 256,\n 'f': \"256\",\n },\n\"https://whitechartskiing.com/\"],\n [{\n 'v': 257,\n 'f': \"257\",\n },\n\"https://achermannsport.ch/\"],\n [{\n 'v': 258,\n 'f': \"258\",\n },\n\"https://www.morrieswestsalemkia.com/\"],\n [{\n 'v': 259,\n 'f': \"259\",\n },\n\"https://alena-energy.com/\"],\n [{\n 'v': 260,\n 'f': \"260\",\n },\n\"https://gaffarbhaiandsons.com/\"],\n [{\n 'v': 261,\n 'f': \"261\",\n },\n\"https://konggaard.dk/\"],\n [{\n 'v': 262,\n 'f': \"262\",\n },\n\"https://www.dara2you.com/\"],\n [{\n 'v': 263,\n 'f': \"263\",\n },\n\"https://www.udrive.nc/\"],\n [{\n 'v': 264,\n 'f': \"264\",\n },\n\"https://acidosalus.com/\"],\n [{\n 'v': 265,\n 'f': \"265\",\n },\n\"https://www.seisamed.com/\"],\n [{\n 'v': 266,\n 'f': \"266\",\n },\n\"https://www.kagudai.co.jp/\"],\n [{\n 'v': 267,\n 'f': \"267\",\n },\n\"https://bioexo.si/\"],\n [{\n 'v': 268,\n 'f': \"268\",\n },\n\"https://medstore.lt/\"],\n [{\n 'v': 269,\n 'f': \"269\",\n },\n\"https://trevoportasejanelas.com.br/\"],\n [{\n 'v': 270,\n 'f': \"270\",\n },\n\"https://mausoleedinromania.ro/\"],\n [{\n 'v': 271,\n 'f': \"271\",\n },\n\"https://styllbaby.com.br/\"],\n [{\n 'v': 272,\n 'f': \"272\",\n },\n\"https://katana-svard.se/\"],\n [{\n 'v': 273,\n 'f': \"273\",\n },\n\"https://ullevi-vikingen-friidrott.se/\"],\n [{\n 'v': 274,\n 'f': \"274\",\n },\n\"https://sejaazzul.com.br/\"],\n [{\n 'v': 275,\n 'f': \"275\",\n },\n\"http://hotelyunost.com/\"],\n [{\n 'v': 276,\n 'f': \"276\",\n },\n\"https://vol.com.ua/\"],\n [{\n 'v': 277,\n 'f': \"277\",\n },\n\"https://redsol.com.ar/\"],\n [{\n 'v': 278,\n 'f': \"278\",\n },\n\"http://diagnosticosalta.com.ar/\"],\n [{\n 'v': 279,\n 'f': \"279\",\n },\n\"https://farmajindris.cz/\"],\n [{\n 'v': 280,\n 'f': \"280\",\n },\n\"https://www.sonnuoctot.com/\"],\n [{\n 'v': 281,\n 'f': \"281\",\n },\n\"http://www.mtbtestcentral.it/\"],\n [{\n 'v': 282,\n 'f': \"282\",\n },\n\"https://www.arterydirect.com.au/\"],\n [{\n 'v': 283,\n 'f': \"283\",\n },\n\"https://pizzalaguna.cz/\"],\n [{\n 'v': 284,\n 'f': \"284\",\n },\n\"https://www.proshield.co.za/\"],\n [{\n 'v': 285,\n 'f': \"285\",\n },\n\"https://www.balletypilatesterapeutico.com/\"],\n [{\n 'v': 286,\n 'f': \"286\",\n },\n\"https://www.mczgroup.it/\"],\n [{\n 'v': 287,\n 'f': \"287\",\n },\n\"https://www.segurototal.com.br/\"],\n [{\n 'v': 288,\n 'f': \"288\",\n },\n\"https://www.profimorava.cz/\"],\n [{\n 'v': 289,\n 'f': \"289\",\n },\n\"https://ellenguajedeladios.com/\"],\n [{\n 'v': 290,\n 'f': \"290\",\n },\n\"https://www.forestclub.md/\"],\n [{\n 'v': 291,\n 'f': \"291\",\n },\n\"https://lumof.ua/\"],\n [{\n 'v': 292,\n 'f': \"292\",\n },\n\"http://aurapharma.com/\"],\n [{\n 'v': 293,\n 'f': \"293\",\n },\n\"https://www.newsundog.com/\"],\n [{\n 'v': 294,\n 'f': \"294\",\n },\n\"https://nryachtclub.ru/\"],\n [{\n 'v': 295,\n 'f': \"295\",\n },\n\"https://fdia.co.za/\"],\n [{\n 'v': 296,\n 'f': \"296\",\n },\n\"https://www.lobstervanhire.co.uk/\"],\n [{\n 'v': 297,\n 'f': \"297\",\n },\n\"https://codero.com.pl/\"],\n [{\n 'v': 298,\n 'f': \"298\",\n },\n\"https://omegaap.com.br/\"],\n [{\n 'v': 299,\n 'f': \"299\",\n },\n\"http://www.kebunrayasriwijaya.com/\"],\n [{\n 'v': 300,\n 'f': \"300\",\n },\n\"http://dtdb.ou.edu.vn/\"],\n [{\n 'v': 301,\n 'f': \"301\",\n },\n\"http://www.lycee-marechal-leclerc.com/\"],\n [{\n 'v': 302,\n 'f': \"302\",\n },\n\"https://careers.opisok.com/\"],\n [{\n 'v': 303,\n 'f': \"303\",\n },\n\"https://prosein.com.ve/\"],\n [{\n 'v': 304,\n 'f': \"304\",\n },\n\"http://chushin-sws.jp/\"],\n [{\n 'v': 305,\n 'f': \"305\",\n },\n\"https://www.instantsushinantes.com/\"],\n [{\n 'v': 306,\n 'f': \"306\",\n },\n\"https://graftoneverest.co.za/\"],\n [{\n 'v': 307,\n 'f': \"307\",\n },\n\"https://thegreatescape.info/\"],\n [{\n 'v': 308,\n 'f': \"308\",\n },\n\"https://www.localseeds.com.au/\"],\n [{\n 'v': 309,\n 'f': \"309\",\n },\n\"https://www.travelcompass.nl/\"],\n [{\n 'v': 310,\n 'f': \"310\",\n },\n\"https://vueltaballenas.com.ar/\"],\n [{\n 'v': 311,\n 'f': \"311\",\n },\n\"http://www.retropedia.radom.pl/\"],\n [{\n 'v': 312,\n 'f': \"312\",\n },\n\"https://metropharma.in/\"],\n [{\n 'v': 313,\n 'f': \"313\",\n },\n\"https://saifleet.co.za/\"],\n [{\n 'v': 314,\n 'f': \"314\",\n },\n\"https://wasidog.com/\"],\n [{\n 'v': 315,\n 'f': \"315\",\n },\n\"https://efoils.cz/\"],\n [{\n 'v': 316,\n 'f': \"316\",\n },\n\"https://astrologis.rs/\"],\n [{\n 'v': 317,\n 'f': \"317\",\n },\n\"https://femme-amsterdam.nl/\"],\n [{\n 'v': 318,\n 'f': \"318\",\n },\n\"http://gorskiogrod.pl/\"],\n [{\n 'v': 319,\n 'f': \"319\",\n },\n\"https://de-la-ghetto-ft-randy-sensacion-del-bloque.playurbano.com/\"],\n [{\n 'v': 320,\n 'f': \"320\",\n },\n\"https://marcacundinamarca.com/\"],\n [{\n 'v': 321,\n 'f': \"321\",\n },\n\"https://camarcosanjuan.org/\"],\n [{\n 'v': 322,\n 'f': \"322\",\n },\n\"https://helicol.com.co/\"],\n [{\n 'v': 323,\n 'f': \"323\",\n },\n\"https://www.dentsoftware.com/\"],\n [{\n 'v': 324,\n 'f': \"324\",\n },\n\"https://reparacionysacrificio.org/\"],\n [{\n 'v': 325,\n 'f': \"325\",\n },\n\"http://donlandsdiner.com/\"],\n [{\n 'v': 326,\n 'f': \"326\",\n },\n\"https://www.globaldutchies.nl/\"],\n [{\n 'v': 327,\n 'f': \"327\",\n },\n\"http://www.douno-ganka.com/\"],\n [{\n 'v': 328,\n 'f': \"328\",\n },\n\"https://fsspx.hr/\"],\n [{\n 'v': 329,\n 'f': \"329\",\n },\n\"https://sexshopamonet.com.ar/\"],\n [{\n 'v': 330,\n 'f': \"330\",\n },\n\"https://blog.noqta.co/\"],\n [{\n 'v': 331,\n 'f': \"331\",\n },\n\"https://klubcf.cz/\"],\n [{\n 'v': 332,\n 'f': \"332\",\n },\n\"https://www.appartamentirizzante.com/\"],\n [{\n 'v': 333,\n 'f': \"333\",\n },\n\"https://umenicestovat.com/\"],\n [{\n 'v': 334,\n 'f': \"334\",\n },\n\"http://www.centrocommercialemercogliano.net/\"],\n [{\n 'v': 335,\n 'f': \"335\",\n },\n\"https://sgbasesoria.com/\"],\n [{\n 'v': 336,\n 'f': \"336\",\n },\n\"https://www.mecansur.com/\"],\n [{\n 'v': 337,\n 'f': \"337\",\n },\n\"https://vitavalka.cz/\"],\n [{\n 'v': 338,\n 'f': \"338\",\n },\n\"https://santtina.co/\"],\n [{\n 'v': 339,\n 'f': \"339\",\n },\n\"https://rpi.chubut.gov.ar/\"],\n [{\n 'v': 340,\n 'f': \"340\",\n },\n\"https://sabapsiena.cultura.gov.it/\"],\n [{\n 'v': 341,\n 'f': \"341\",\n },\n\"https://qe4ferry.com/\"],\n [{\n 'v': 342,\n 'f': \"342\",\n },\n\"https://www.pc55.nl/\"],\n [{\n 'v': 343,\n 'f': \"343\",\n },\n\"https://www.unlistedsharebrokers.com/\"],\n [{\n 'v': 344,\n 'f': \"344\",\n },\n\"https://www.jollysailororford.co.uk/\"],\n [{\n 'v': 345,\n 'f': \"345\",\n },\n\"https://www.discotecaindiana.com/\"],\n [{\n 'v': 346,\n 'f': \"346\",\n },\n\"https://ekm.feb.usk.ac.id/\"],\n [{\n 'v': 347,\n 'f': \"347\",\n },\n\"https://cora.org.mx/\"],\n [{\n 'v': 348,\n 'f': \"348\",\n },\n\"https://www.driveknoxchevy.com/\"],\n [{\n 'v': 349,\n 'f': \"349\",\n },\n\"https://dakpro.be/\"],\n [{\n 'v': 350,\n 'f': \"350\",\n },\n\"https://lutyensdelhi.in/\"],\n [{\n 'v': 351,\n 'f': \"351\",\n },\n\"https://macsforcancer.com/\"],\n [{\n 'v': 352,\n 'f': \"352\",\n },\n\"https://www.tspot.com/\"],\n [{\n 'v': 353,\n 'f': \"353\",\n },\n\"https://www.griassdi-kaiserwinkl.at/\"],\n [{\n 'v': 354,\n 'f': \"354\",\n },\n\"https://repuesteranacional.com/\"],\n [{\n 'v': 355,\n 'f': \"355\",\n },\n\"https://www.yfdberlin.com/\"],\n [{\n 'v': 356,\n 'f': \"356\",\n },\n\"https://www.hablemosdetodo.gob.ar/\"],\n [{\n 'v': 357,\n 'f': \"357\",\n },\n\"https://www.gaumen-schmaus.at/\"],\n [{\n 'v': 358,\n 'f': \"358\",\n },\n\"https://pattentitle.com/\"],\n [{\n 'v': 359,\n 'f': \"359\",\n },\n\"https://10nengo.com/\"],\n [{\n 'v': 360,\n 'f': \"360\",\n },\n\"https://www.sexitive.com/\"],\n [{\n 'v': 361,\n 'f': \"361\",\n },\n\"https://houserauctioneers.com/\"],\n [{\n 'v': 362,\n 'f': \"362\",\n },\n\"https://e-dikbang.sdmpoldajambi.com/\"],\n [{\n 'v': 363,\n 'f': \"363\",\n },\n\"https://www.equipar.com.mx/\"],\n [{\n 'v': 364,\n 'f': \"364\",\n },\n\"https://www.stanmcnabbchevroletcolumbia.com/\"],\n [{\n 'v': 365,\n 'f': \"365\",\n },\n\"http://sauna-frivol.com/\"],\n [{\n 'v': 366,\n 'f': \"366\",\n },\n\"https://hipergas.com.ar/\"],\n [{\n 'v': 367,\n 'f': \"367\",\n },\n\"https://jpsdistribuciones.com.ar/\"],\n [{\n 'v': 368,\n 'f': \"368\",\n },\n\"https://enroute.aircanada.com/\"],\n [{\n 'v': 369,\n 'f': \"369\",\n },\n\"https://casttube.org/\"],\n [{\n 'v': 370,\n 'f': \"370\",\n },\n\"https://smart-info.blog/\"],\n [{\n 'v': 371,\n 'f': \"371\",\n },\n\"https://www.cat-kyushu.co.jp/\"],\n [{\n 'v': 372,\n 'f': \"372\",\n },\n\"https://dragonheng29.com/\"],\n [{\n 'v': 373,\n 'f': \"373\",\n },\n\"https://restaurantedafazendinha.com.br/\"],\n [{\n 'v': 374,\n 'f': \"374\",\n },\n\"https://www.designs4cnc.in/\"],\n [{\n 'v': 375,\n 'f': \"375\",\n },\n\"https://www.primariasebes.ro/\"],\n [{\n 'v': 376,\n 'f': \"376\",\n },\n\"https://evorich.com.sg/\"],\n [{\n 'v': 377,\n 'f': \"377\",\n },\n\"https://a2zeegifts.com/\"],\n [{\n 'v': 378,\n 'f': \"378\",\n },\n\"https://www.gigighirotti.it/\"],\n [{\n 'v': 379,\n 'f': \"379\",\n },\n\"https://www.pacificoaks.edu/\"],\n [{\n 'v': 380,\n 'f': \"380\",\n },\n\"https://www.teamkids.com.au/\"],\n [{\n 'v': 381,\n 'f': \"381\",\n },\n\"https://www.cysnews.cz/\"],\n [{\n 'v': 382,\n 'f': \"382\",\n },\n\"https://www.countryhyundai.com/\"],\n [{\n 'v': 383,\n 'f': \"383\",\n },\n\"https://armyrun.ca/\"],\n [{\n 'v': 384,\n 'f': \"384\",\n },\n\"https://www.femporn.de/\"],\n [{\n 'v': 385,\n 'f': \"385\",\n },\n\"https://anchin.jp/\"],\n [{\n 'v': 386,\n 'f': \"386\",\n },\n\"https://igors.com.br/\"],\n [{\n 'v': 387,\n 'f': \"387\",\n },\n\"https://www.williamshonda.com/\"],\n [{\n 'v': 388,\n 'f': \"388\",\n },\n\"https://telecomlead.com/\"],\n [{\n 'v': 389,\n 'f': \"389\",\n },\n\"https://cgc.energy/\"],\n [{\n 'v': 390,\n 'f': \"390\",\n },\n\"https://tazatech.in/\"],\n [{\n 'v': 391,\n 'f': \"391\",\n },\n\"https://metalinsider.net/\"],\n [{\n 'v': 392,\n 'f': \"392\",\n },\n\"https://naciya.home.cx.ua/\"],\n [{\n 'v': 393,\n 'f': \"393\",\n },\n\"https://www.winitcq.com/\"],\n [{\n 'v': 394,\n 'f': \"394\",\n },\n\"https://www.daikanyamastudio.jp/\"],\n [{\n 'v': 395,\n 'f': \"395\",\n },\n\"http://www.mbfindia.net/\"],\n [{\n 'v': 396,\n 'f': \"396\",\n },\n\"https://www.palmerstoyota.com/\"],\n [{\n 'v': 397,\n 'f': \"397\",\n },\n\"https://monpetitpotager.fr/\"],\n [{\n 'v': 398,\n 'f': \"398\",\n },\n\"https://benecol.ie/\"],\n [{\n 'v': 399,\n 'f': \"399\",\n },\n\"https://100poundsocial.com/\"],\n [{\n 'v': 400,\n 'f': \"400\",\n },\n\"http://lallunadevalencia.com/\"],\n [{\n 'v': 401,\n 'f': \"401\",\n },\n\"https://www.granjaescuelaguresustraiak.com/\"],\n [{\n 'v': 402,\n 'f': \"402\",\n },\n\"https://zbmk.zp.ua/\"],\n [{\n 'v': 403,\n 'f': \"403\",\n },\n\"https://sananda.com.bd/\"],\n [{\n 'v': 404,\n 'f': \"404\",\n },\n\"https://www.toyotaofcorvallis.com/\"],\n [{\n 'v': 405,\n 'f': \"405\",\n },\n\"https://www.cavenderbuickgmcwest.com/\"],\n [{\n 'v': 406,\n 'f': \"406\",\n },\n\"https://pers-upn.com/\"],\n [{\n 'v': 407,\n 'f': \"407\",\n },\n\"https://copba-cs.org.ar/\"],\n [{\n 'v': 408,\n 'f': \"408\",\n },\n\"https://www.djbutikken.com/\"],\n [{\n 'v': 409,\n 'f': \"409\",\n },\n\"https://www.fleurdelisbeach.com/\"],\n [{\n 'v': 410,\n 'f': \"410\",\n },\n\"https://booking.tankodrommilovice.cz/\"],\n [{\n 'v': 411,\n 'f': \"411\",\n },\n\"https://www.elanceluxuryliving.net/\"],\n [{\n 'v': 412,\n 'f': \"412\",\n },\n\"https://multi-medica.pl/\"],\n [{\n 'v': 413,\n 'f': \"413\",\n },\n\"https://eikenhuis.nl/\"],\n [{\n 'v': 414,\n 'f': \"414\",\n },\n\"https://camboauto.com/\"],\n [{\n 'v': 415,\n 'f': \"415\",\n },\n\"https://www.goudatijdmachine.nl/\"],\n [{\n 'v': 416,\n 'f': \"416\",\n },\n\"https://empirescollection.pk/\"],\n [{\n 'v': 417,\n 'f': \"417\",\n },\n\"https://starlivestudio.com/\"],\n [{\n 'v': 418,\n 'f': \"418\",\n },\n\"https://www.edax.hu/\"],\n [{\n 'v': 419,\n 'f': \"419\",\n },\n\"https://www.u-hajku.cz/\"],\n [{\n 'v': 420,\n 'f': \"420\",\n },\n\"https://rpgifting.com/\"],\n [{\n 'v': 421,\n 'f': \"421\",\n },\n\"https://aestimaasset.com/\"],\n [{\n 'v': 422,\n 'f': \"422\",\n },\n\"https://zsvelkeprilepy.cz/\"],\n [{\n 'v': 423,\n 'f': \"423\",\n },\n\"https://elmundodelespectaculo.es/\"],\n [{\n 'v': 424,\n 'f': \"424\",\n },\n\"https://www.parksmotors.com/\"],\n [{\n 'v': 425,\n 'f': \"425\",\n },\n\"https://wagtailcountrypark.co.uk/\"],\n [{\n 'v': 426,\n 'f': \"426\",\n },\n\"https://www.exhighlow-tribe.com/\"],\n [{\n 'v': 427,\n 'f': \"427\",\n },\n\"https://tangobaires.com/\"],\n [{\n 'v': 428,\n 'f': \"428\",\n },\n\"https://www.tautrimas.com/\"],\n [{\n 'v': 429,\n 'f': \"429\",\n },\n\"https://westlands.amaron.ke/\"],\n [{\n 'v': 430,\n 'f': \"430\",\n },\n\"https://surinmobiliariazapala.com.ar/\"],\n [{\n 'v': 431,\n 'f': \"431\",\n },\n\"https://laboratorioesarte.com.ar/\"],\n [{\n 'v': 432,\n 'f': \"432\",\n },\n\"https://santasaude.santacasadeitapeva.org.br/\"],\n [{\n 'v': 433,\n 'f': \"433\",\n },\n\"https://www.marylandjunkyards.com/\"],\n [{\n 'v': 434,\n 'f': \"434\",\n },\n\"http://www.gdknt.ru/\"],\n [{\n 'v': 435,\n 'f': \"435\",\n },\n\"https://www.restaurant-les1separables.com/\"],\n [{\n 'v': 436,\n 'f': \"436\",\n },\n\"https://mariapolislia.com.ar/\"],\n [{\n 'v': 437,\n 'f': \"437\",\n },\n\"http://pureza.rn.gov.br/\"],\n [{\n 'v': 438,\n 'f': \"438\",\n },\n\"https://hocvan.edu.vn/\"],\n [{\n 'v': 439,\n 'f': \"439\",\n },\n\"http://eshodinshikhi.com/\"],\n [{\n 'v': 440,\n 'f': \"440\",\n },\n\"https://www.mh-ordi.at/\"],\n [{\n 'v': 441,\n 'f': \"441\",\n },\n\"https://iyibilgiler.wordpress.com/\"],\n [{\n 'v': 442,\n 'f': \"442\",\n },\n\"https://restaurantrosas.nl/\"],\n [{\n 'v': 443,\n 'f': \"443\",\n },\n\"https://febi.iainpalopo.ac.id/\"],\n [{\n 'v': 444,\n 'f': \"444\",\n },\n\"https://www.wacker1930.de/\"],\n [{\n 'v': 445,\n 'f': \"445\",\n },\n\"https://metropostnews.com/\"],\n [{\n 'v': 446,\n 'f': \"446\",\n },\n\"https://labastiglia.com/\"],\n [{\n 'v': 447,\n 'f': \"447\",\n },\n\"https://rushd.sch.id/\"],\n [{\n 'v': 448,\n 'f': \"448\",\n },\n\"https://laviklinic.co.il/\"],\n [{\n 'v': 449,\n 'f': \"449\",\n },\n\"https://garaz-nowoczesny.pl/\"],\n [{\n 'v': 450,\n 'f': \"450\",\n },\n\"https://nirvanaandspa.com/\"],\n [{\n 'v': 451,\n 'f': \"451\",\n },\n\"https://navarro.gob.ar/\"],\n [{\n 'v': 452,\n 'f': \"452\",\n },\n\"https://www.griffincdjrvaldosta.com/\"],\n [{\n 'v': 453,\n 'f': \"453\",\n },\n\"https://tempo-tv.com/\"],\n [{\n 'v': 454,\n 'f': \"454\",\n },\n\"https://uranai.news/\"],\n [{\n 'v': 455,\n 'f': \"455\",\n },\n\"https://thebroughton.co.uk/\"],\n [{\n 'v': 456,\n 'f': \"456\",\n },\n\"https://www.sutliffvolkswagen.com/\"],\n [{\n 'v': 457,\n 'f': \"457\",\n },\n\"https://togetheralive.be/\"],\n [{\n 'v': 458,\n 'f': \"458\",\n },\n\"https://batutairenginiams.lt/\"],\n [{\n 'v': 459,\n 'f': \"459\",\n },\n\"https://www.thorntonbrothers.net/\"],\n [{\n 'v': 460,\n 'f': \"460\",\n },\n\"https://activehistoryteacher.com/\"],\n [{\n 'v': 461,\n 'f': \"461\",\n },\n\"https://powervacamerica.com/\"],\n [{\n 'v': 462,\n 'f': \"462\",\n },\n\"https://www.goeters.nl/\"],\n [{\n 'v': 463,\n 'f': \"463\",\n },\n\"https://hostys.uprwssp.org/\"],\n [{\n 'v': 464,\n 'f': \"464\",\n },\n\"https://iptvlovers.com/\"],\n [{\n 'v': 465,\n 'f': \"465\",\n },\n\"https://www.radiologie-luton-reims.fr/\"],\n [{\n 'v': 466,\n 'f': \"466\",\n },\n\"https://g2r.com.br/\"],\n [{\n 'v': 467,\n 'f': \"467\",\n },\n\"https://brilliantasmit.staff.unri.ac.id/\"],\n [{\n 'v': 468,\n 'f': \"468\",\n },\n\"https://bad-bunny.flowhot.cc/\"],\n [{\n 'v': 469,\n 'f': \"469\",\n },\n\"https://dearbillypatterns.com/\"],\n [{\n 'v': 470,\n 'f': \"470\",\n },\n\"https://green-card-news.com/\"],\n [{\n 'v': 471,\n 'f': \"471\",\n },\n\"https://devon-tools.ru/\"],\n [{\n 'v': 472,\n 'f': \"472\",\n },\n\"https://www.radirna.cz/\"],\n [{\n 'v': 473,\n 'f': \"473\",\n },\n\"https://carasnortes.com/\"],\n [{\n 'v': 474,\n 'f': \"474\",\n },\n\"https://prodibio.com/\"],\n [{\n 'v': 475,\n 'f': \"475\",\n },\n\"https://idees-store.gr/\"],\n [{\n 'v': 476,\n 'f': \"476\",\n },\n\"https://serenitytalks.com/\"],\n [{\n 'v': 477,\n 'f': \"477\",\n },\n\"https://www.casadeyemanya.com/\"],\n [{\n 'v': 478,\n 'f': \"478\",\n },\n\"https://greenpuddle.net/\"],\n [{\n 'v': 479,\n 'f': \"479\",\n },\n\"http://www.fluirautomacao.com.br/\"],\n [{\n 'v': 480,\n 'f': \"480\",\n },\n\"https://www.ptplusvip.com/\"],\n [{\n 'v': 481,\n 'f': \"481\",\n },\n\"https://medicoop.com.do/\"],\n [{\n 'v': 482,\n 'f': \"482\",\n },\n\"https://www.benevit.at/\"],\n [{\n 'v': 483,\n 'f': \"483\",\n },\n\"https://slaskiecentrumosteopatii.pl/\"],\n [{\n 'v': 484,\n 'f': \"484\",\n },\n\"https://campervanbruno.es/\"],\n [{\n 'v': 485,\n 'f': \"485\",\n },\n\"https://amancialandrealty.com/\"],\n [{\n 'v': 486,\n 'f': \"486\",\n },\n\"https://andes-travel.cl/\"],\n [{\n 'v': 487,\n 'f': \"487\",\n },\n\"https://www.textilesmontecid.com/\"],\n [{\n 'v': 488,\n 'f': \"488\",\n },\n\"https://infinitybouncepark.com/\"],\n [{\n 'v': 489,\n 'f': \"489\",\n },\n\"http://www.motu-yamamoto.com/\"],\n [{\n 'v': 490,\n 'f': \"490\",\n },\n\"https://www.playground-kids.com.ua/\"],\n [{\n 'v': 491,\n 'f': \"491\",\n },\n\"https://lavoixdelesperance.org/\"],\n [{\n 'v': 492,\n 'f': \"492\",\n },\n\"https://www.gbs-mozaiek.be/\"],\n [{\n 'v': 493,\n 'f': \"493\",\n },\n\"https://semi-sa.com.ar/\"],\n [{\n 'v': 494,\n 'f': \"494\",\n },\n\"https://onlinebingo.co.uk/\"],\n [{\n 'v': 495,\n 'f': \"495\",\n },\n\"https://ivadi.es/\"],\n [{\n 'v': 496,\n 'f': \"496\",\n },\n\"https://meuesquematizado.com.br/\"],\n [{\n 'v': 497,\n 'f': \"497\",\n },\n\"https://safemedicinedrop.com/\"],\n [{\n 'v': 498,\n 'f': \"498\",\n },\n\"https://visittrollaskagi.is/\"],\n [{\n 'v': 499,\n 'f': \"499\",\n },\n\"https://www.plazahyundai.com/\"]],\n columns: [[\"number\", \"index\"], [\"string\", \"origin\"]],\n columnOptions: [{\"width\": \"1px\", \"className\": \"index_column\"}],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n\n function appendQuickchartButton(parentElement) {\n let quickchartButtonContainerElement = document.createElement('div');\n quickchartButtonContainerElement.innerHTML = `\n<div id=\"df-1b621b79-a398-4e35-881e-6fbd513a6864\">\n <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-1b621b79-a398-4e35-881e-6fbd513a6864')\"\n title=\"Suggest charts\"\n style=\"display:none;\">\n \n<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n width=\"24px\">\n <g>\n <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n </g>\n</svg>\n </button>\n \n<style>\n .colab-df-quickchart {\n --bg-color: #E8F0FE;\n --fill-color: #1967D2;\n --hover-bg-color: #E2EBFA;\n --hover-fill-color: #174EA6;\n --disabled-fill-color: #AAA;\n --disabled-bg-color: #DDD;\n }\n\n [theme=dark] .colab-df-quickchart {\n --bg-color: #3B4455;\n --fill-color: #D2E3FC;\n --hover-bg-color: #434B5C;\n --hover-fill-color: #FFFFFF;\n --disabled-bg-color: #3B4455;\n --disabled-fill-color: #666;\n }\n\n .colab-df-quickchart {\n background-color: var(--bg-color);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n display: none;\n fill: var(--fill-color);\n height: 32px;\n padding: 0;\n width: 32px;\n }\n\n .colab-df-quickchart:hover {\n background-color: var(--hover-bg-color);\n box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n fill: var(--button-hover-fill-color);\n }\n\n .colab-df-quickchart-complete:disabled,\n .colab-df-quickchart-complete:disabled:hover {\n background-color: var(--disabled-bg-color);\n fill: var(--disabled-fill-color);\n box-shadow: none;\n }\n\n .colab-df-spinner {\n border: 2px solid var(--fill-color);\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n animation:\n spin 1s steps(1) infinite;\n }\n\n @keyframes spin {\n 0% {\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n border-left-color: var(--fill-color);\n }\n 20% {\n border-color: transparent;\n border-left-color: var(--fill-color);\n border-top-color: var(--fill-color);\n }\n 30% {\n border-color: transparent;\n border-left-color: var(--fill-color);\n border-top-color: var(--fill-color);\n border-right-color: var(--fill-color);\n }\n 40% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n border-top-color: var(--fill-color);\n }\n 60% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n }\n 80% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n border-bottom-color: var(--fill-color);\n }\n 90% {\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n }\n }\n</style>\n\n <script>\n async function quickchart(key) {\n const quickchartButtonEl =\n document.querySelector('#' + key + ' button');\n quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n quickchartButtonEl.classList.add('colab-df-spinner');\n try {\n const charts = await google.colab.kernel.invokeFunction(\n 'suggestCharts', [key], {});\n } catch (error) {\n console.error('Error during call to suggestCharts:', error);\n }\n quickchartButtonEl.classList.remove('colab-df-spinner');\n quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n }\n (() => {\n let quickchartButtonEl =\n document.querySelector('#df-1b621b79-a398-4e35-881e-6fbd513a6864 button');\n quickchartButtonEl.style.display =\n google.colab.kernel.accessAllowed ? 'block' : 'none';\n })();\n </script>\n</div>`;\n parentElement.appendChild(quickchartButtonContainerElement);\n }\n\n appendQuickchartButton(table);\n " | |
}, | |
"metadata": {}, | |
"execution_count": 13 | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"previously_not_active = get_active_sites_also_active_at_before_date('speculation-rules', '2024-05-01', active_sites)\n", | |
"previously_not_active.head(5)\n", | |
"\n", | |
"# count active sites\n", | |
"count_previously_not_active = previously_not_active.count()\n", | |
"print(count_previously_not_active)" | |
], | |
"metadata": { | |
"id": "2f60oM9FTQAU", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "937b5fe1-9d08-47fc-a175-d1ceda81a5c4" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"origin 2960\n", | |
"dtype: int64\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"cwv_changes_active_sites = get_cwv_change_before_after(active_sites, '2024-03-01', '2024-08-01' )\n", | |
"print(cwv_changes_active_sites)" | |
], | |
"metadata": { | |
"id": "g7DrwD1Z6kcB", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "f584f309-8303-49e6-ae3a-939f2b864123" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"[0.06232002113378332, 0.06346816102047553, 0.03573906737828336, 0.044142435735356034]\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"cwv_changes_active_sites_by_device = get_cwv_change_before_after_by_device(active_sites, '2024-03-01', '2024-08-01' )\n", | |
"print(cwv_changes_active_sites_by_device)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "Yl99_75aLbMr", | |
"outputId": "ba349d86-1aa2-4d87-8027-556472c1068c" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"[0.07083488781153219, 0.06909267366979688, 0.03922572086938758, 0.08127807033918977, 0.053894219906421015, 0.05999325206027517, 0.026095263217394526, 0.0027941094172748704]\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"cwv_changes_inactive_sites = get_cwv_change_before_after(inactive_sites, '2024-03-01', '2024-08-01' )\n", | |
"print(cwv_changes_inactive_sites)" | |
], | |
"metadata": { | |
"id": "Hv4-fMck7pD6", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "370f9c31-68eb-450f-c691-e5b518de9154" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"[0.03842766935669645, 0.03281879625688, 0.016236264348328477, 0.036834856975053176]\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"cwv_changes_inactive_sites_by_device = get_cwv_change_before_after_by_device(inactive_sites, '2024-03-01', '2024-08-01' )\n", | |
"print(cwv_changes_inactive_sites_by_device)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "ReoWFooEOaFJ", | |
"outputId": "330e1059-3ac9-41e9-8c34-8fd24fe82f6c" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"[0.04525254428354497, 0.03586424508053565, 0.012105841662442773, 0.06688614771352841, 0.030943523718571342, 0.03481560556441132, 0.01572887912168608, 0.0004040350745310173]\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"final_results = calculate_feature_impact(cwv_changes_active_sites, cwv_changes_inactive_sites)\n", | |
"print(final_results)\n" | |
], | |
"metadata": { | |
"id": "9ZgXf5Je9N4x", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "e66ea769-9bca-4b4d-b327-62aa2624d51b" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change': '2.39%', 'pct_good_lcp_change': '3.06%', 'pct_good_cls_change': '1.95%', 'pct_good_inp_change': '0.73%'}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"final_results = calculate_feature_impact_by_device(cwv_changes_active_sites_by_device, cwv_changes_inactive_sites_by_device)\n", | |
"print(final_results)\n" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "20c210b9-a94d-467d-d65d-ff3410e0fed0", | |
"id": "9LPwX7qGP3Uw" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '2.56%', 'pct_good_lcp_change_mobile': '3.32%', 'pct_good_cls_change_mobile': '2.71%', 'pct_good_inp_change_mobile': '1.44%', 'pct_good_cwv_change_desktop': '2.30%', 'pct_good_lcp_change_desktop': '2.52%', 'pct_good_cls_change_desktop': '1.04%', 'pct_good_inp_change_desktop': '0.24%'}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"results = query_cwv_compare_feature_to_baseline( 'speculation-rules', '2024-03-01', '2024-08-01' )\n", | |
"print(results)" | |
], | |
"metadata": { | |
"id": "1fHDFRQVRpfH", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "88d4fef4-3987-489f-c662-412880e9f134" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change': '2.42%', 'pct_good_lcp_change': '3.06%', 'pct_good_cls_change': '1.98%', 'pct_good_inp_change': '0.82%', 'feature_active_sites': 7203, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%'}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"results = query_cwv_compare_feature_to_baseline_by_device( 'speculation-rules', '2024-03-01', '2024-08-01' )\n", | |
"print(results)" | |
], | |
"metadata": { | |
"id": "68oaX4ByWQL5", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "46cbae13-ba83-4ba1-9858-1a018e5ddcbe" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"metadata": { | |
"tags": null | |
}, | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '2.60%', 'pct_good_lcp_change_mobile': '3.39%', 'pct_good_cls_change_mobile': '2.75%', 'pct_good_inp_change_mobile': '1.52%', 'pct_good_cwv_change_desktop': '2.39%', 'pct_good_lcp_change_desktop': '2.55%', 'pct_good_cls_change_desktop': '1.09%', 'pct_good_inp_change_desktop': '0.23%', 'feature_active_sites': 7203, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-08-01', 'generator_tag': 'speculation-rules', 'cwv_changes_active_sites': [0.07083488781153219, 0.06909267366979688, 0.03922572086938758, 0.08127807033918977, 0.053894219906421015, 0.05999325206027517, 0.026095263217394526, 0.0027941094172748704], 'cwv_changes_inactive_sites': [0.04482710642311871, 0.03515486832303927, 0.011717077581957724, 0.06609143742833012, 0.02997313470714902, 0.034507587443841525, 0.015172879563230546, 0.0005163767055975654]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# show results as a table\n", | |
"import pandas as pd\n", | |
"df = pd.DataFrame([results])\n", | |
"df" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 160 | |
}, | |
"id": "ch7RupSn_2Vp", | |
"outputId": "b536443f-07ee-425a-c788-be211957564d" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.google.colaboratory.intrinsic+json": { | |
"summary": "{\n \"name\": \"df\",\n \"rows\": 1,\n \"fields\": [\n {\n \"column\": \"pct_good_cwv_change_mobile\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.60%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_lcp_change_mobile\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"3.39%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_cls_change_mobile\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.75%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_inp_change_mobile\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"1.52%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_cwv_change_desktop\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.39%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_lcp_change_desktop\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2.55%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_cls_change_desktop\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"1.09%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"pct_good_inp_change_desktop\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"0.23%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"feature_active_sites\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 7203,\n \"max\": 7203,\n \"num_unique_values\": 1,\n \"samples\": [\n 7203\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"feature_inactive_sites\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": null,\n \"min\": 50000,\n \"max\": 50000,\n \"num_unique_values\": 1,\n \"samples\": [\n 50000\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"also_active_at_before\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"0.00%\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"before_date\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2024-03-01\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"after_date\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"2024-08-01\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"generator_tag\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 1,\n \"samples\": [\n \"speculation-rules\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"cwv_changes_active_sites\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"cwv_changes_inactive_sites\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}", | |
"type": "dataframe", | |
"variable_name": "df" | |
}, | |
"application/vnd.google.colaboratory.module+javascript": "\n import \"https://ssl.gstatic.com/colaboratory/data_table/54ded79905fc55e4/data_table.js\";\n\n const table = window.createDataTable({\n data: [[{\n 'v': 0,\n 'f': \"0\",\n },\n\"2.60%\",\n\"3.39%\",\n\"2.75%\",\n\"1.52%\",\n\"2.39%\",\n\"2.55%\",\n\"1.09%\",\n\"0.23%\",\n{\n 'v': 7203,\n 'f': \"7203\",\n },\n{\n 'v': 50000,\n 'f': \"50000\",\n },\n\"0.00%\",\n\"2024-03-01\",\n\"2024-08-01\",\n\"speculation-rules\",\n[0.07083488781153219, 0.06909267366979688, 0.03922572086938758, 0.08127807033918977, 0.053894219906421015, 0.05999325206027517, 0.026095263217394526, 0.0027941094172748704],\n[0.04482710642311871, 0.03515486832303927, 0.011717077581957724, 0.06609143742833012, 0.02997313470714902, 0.034507587443841525, 0.015172879563230546, 0.0005163767055975654]]],\n columns: [[\"number\", \"index\"], [\"string\", \"pct_good_cwv_change_mobile\"], [\"string\", \"pct_good_lcp_change_mobile\"], [\"string\", \"pct_good_cls_change_mobile\"], [\"string\", \"pct_good_inp_change_mobile\"], [\"string\", \"pct_good_cwv_change_desktop\"], [\"string\", \"pct_good_lcp_change_desktop\"], [\"string\", \"pct_good_cls_change_desktop\"], [\"string\", \"pct_good_inp_change_desktop\"], [\"number\", \"feature_active_sites\"], [\"number\", \"feature_inactive_sites\"], [\"string\", \"also_active_at_before\"], [\"string\", \"before_date\"], [\"string\", \"after_date\"], [\"string\", \"generator_tag\"], [\"string\", \"cwv_changes_active_sites\"], [\"string\", \"cwv_changes_inactive_sites\"]],\n columnOptions: [{\"width\": \"1px\", \"className\": \"index_column\"}],\n rowsPerPage: 25,\n helpUrl: \"https://colab.research.google.com/notebooks/data_table.ipynb\",\n suppressOutputScrolling: true,\n minimumWidth: undefined,\n });\n\n function appendQuickchartButton(parentElement) {\n let quickchartButtonContainerElement = document.createElement('div');\n quickchartButtonContainerElement.innerHTML = `\n<div id=\"df-0e402274-b5e4-4cea-b901-fdbdd5094abd\">\n <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-0e402274-b5e4-4cea-b901-fdbdd5094abd')\"\n title=\"Suggest charts\"\n style=\"display:none;\">\n \n<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n width=\"24px\">\n <g>\n <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n </g>\n</svg>\n </button>\n \n<style>\n .colab-df-quickchart {\n --bg-color: #E8F0FE;\n --fill-color: #1967D2;\n --hover-bg-color: #E2EBFA;\n --hover-fill-color: #174EA6;\n --disabled-fill-color: #AAA;\n --disabled-bg-color: #DDD;\n }\n\n [theme=dark] .colab-df-quickchart {\n --bg-color: #3B4455;\n --fill-color: #D2E3FC;\n --hover-bg-color: #434B5C;\n --hover-fill-color: #FFFFFF;\n --disabled-bg-color: #3B4455;\n --disabled-fill-color: #666;\n }\n\n .colab-df-quickchart {\n background-color: var(--bg-color);\n border: none;\n border-radius: 50%;\n cursor: pointer;\n display: none;\n fill: var(--fill-color);\n height: 32px;\n padding: 0;\n width: 32px;\n }\n\n .colab-df-quickchart:hover {\n background-color: var(--hover-bg-color);\n box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n fill: var(--button-hover-fill-color);\n }\n\n .colab-df-quickchart-complete:disabled,\n .colab-df-quickchart-complete:disabled:hover {\n background-color: var(--disabled-bg-color);\n fill: var(--disabled-fill-color);\n box-shadow: none;\n }\n\n .colab-df-spinner {\n border: 2px solid var(--fill-color);\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n animation:\n spin 1s steps(1) infinite;\n }\n\n @keyframes spin {\n 0% {\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n border-left-color: var(--fill-color);\n }\n 20% {\n border-color: transparent;\n border-left-color: var(--fill-color);\n border-top-color: var(--fill-color);\n }\n 30% {\n border-color: transparent;\n border-left-color: var(--fill-color);\n border-top-color: var(--fill-color);\n border-right-color: var(--fill-color);\n }\n 40% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n border-top-color: var(--fill-color);\n }\n 60% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n }\n 80% {\n border-color: transparent;\n border-right-color: var(--fill-color);\n border-bottom-color: var(--fill-color);\n }\n 90% {\n border-color: transparent;\n border-bottom-color: var(--fill-color);\n }\n }\n</style>\n\n <script>\n async function quickchart(key) {\n const quickchartButtonEl =\n document.querySelector('#' + key + ' button');\n quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n quickchartButtonEl.classList.add('colab-df-spinner');\n try {\n const charts = await google.colab.kernel.invokeFunction(\n 'suggestCharts', [key], {});\n } catch (error) {\n console.error('Error during call to suggestCharts:', error);\n }\n quickchartButtonEl.classList.remove('colab-df-spinner');\n quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n }\n (() => {\n let quickchartButtonEl =\n document.querySelector('#df-0e402274-b5e4-4cea-b901-fdbdd5094abd button');\n quickchartButtonEl.style.display =\n google.colab.kernel.accessAllowed ? 'block' : 'none';\n })();\n </script>\n</div>`;\n parentElement.appendChild(quickchartButtonContainerElement);\n }\n\n appendQuickchartButton(table);\n ", | |
"text/html": [ | |
"\n", | |
" <div id=\"df-7e2e0d92-cc37-439e-931d-2918003059ee\" class=\"colab-df-container\">\n", | |
" <div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>pct_good_cwv_change_mobile</th>\n", | |
" <th>pct_good_lcp_change_mobile</th>\n", | |
" <th>pct_good_cls_change_mobile</th>\n", | |
" <th>pct_good_inp_change_mobile</th>\n", | |
" <th>pct_good_cwv_change_desktop</th>\n", | |
" <th>pct_good_lcp_change_desktop</th>\n", | |
" <th>pct_good_cls_change_desktop</th>\n", | |
" <th>pct_good_inp_change_desktop</th>\n", | |
" <th>feature_active_sites</th>\n", | |
" <th>feature_inactive_sites</th>\n", | |
" <th>also_active_at_before</th>\n", | |
" <th>before_date</th>\n", | |
" <th>after_date</th>\n", | |
" <th>generator_tag</th>\n", | |
" <th>cwv_changes_active_sites</th>\n", | |
" <th>cwv_changes_inactive_sites</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>2.60%</td>\n", | |
" <td>3.39%</td>\n", | |
" <td>2.75%</td>\n", | |
" <td>1.52%</td>\n", | |
" <td>2.39%</td>\n", | |
" <td>2.55%</td>\n", | |
" <td>1.09%</td>\n", | |
" <td>0.23%</td>\n", | |
" <td>7203</td>\n", | |
" <td>50000</td>\n", | |
" <td>0.00%</td>\n", | |
" <td>2024-03-01</td>\n", | |
" <td>2024-08-01</td>\n", | |
" <td>speculation-rules</td>\n", | |
" <td>[0.07083488781153219, 0.06909267366979688, 0.0...</td>\n", | |
" <td>[0.04482710642311871, 0.03515486832303927, 0.0...</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>\n", | |
" <div class=\"colab-df-buttons\">\n", | |
"\n", | |
" <div class=\"colab-df-container\">\n", | |
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-7e2e0d92-cc37-439e-931d-2918003059ee')\"\n", | |
" title=\"Convert this dataframe to an interactive table.\"\n", | |
" style=\"display:none;\">\n", | |
"\n", | |
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n", | |
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n", | |
" </svg>\n", | |
" </button>\n", | |
"\n", | |
" <style>\n", | |
" .colab-df-container {\n", | |
" display:flex;\n", | |
" gap: 12px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-convert {\n", | |
" background-color: #E8F0FE;\n", | |
" border: none;\n", | |
" border-radius: 50%;\n", | |
" cursor: pointer;\n", | |
" display: none;\n", | |
" fill: #1967D2;\n", | |
" height: 32px;\n", | |
" padding: 0 0 0 0;\n", | |
" width: 32px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-convert:hover {\n", | |
" background-color: #E2EBFA;\n", | |
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
" fill: #174EA6;\n", | |
" }\n", | |
"\n", | |
" .colab-df-buttons div {\n", | |
" margin-bottom: 4px;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-convert {\n", | |
" background-color: #3B4455;\n", | |
" fill: #D2E3FC;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-convert:hover {\n", | |
" background-color: #434B5C;\n", | |
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
" fill: #FFFFFF;\n", | |
" }\n", | |
" </style>\n", | |
"\n", | |
" <script>\n", | |
" const buttonEl =\n", | |
" document.querySelector('#df-7e2e0d92-cc37-439e-931d-2918003059ee button.colab-df-convert');\n", | |
" buttonEl.style.display =\n", | |
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
"\n", | |
" async function convertToInteractive(key) {\n", | |
" const element = document.querySelector('#df-7e2e0d92-cc37-439e-931d-2918003059ee');\n", | |
" const dataTable =\n", | |
" await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
" [key], {});\n", | |
" if (!dataTable) return;\n", | |
"\n", | |
" const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
" + ' to learn more about interactive tables.';\n", | |
" element.innerHTML = '';\n", | |
" dataTable['output_type'] = 'display_data';\n", | |
" await google.colab.output.renderOutput(dataTable, element);\n", | |
" const docLink = document.createElement('div');\n", | |
" docLink.innerHTML = docLinkHtml;\n", | |
" element.appendChild(docLink);\n", | |
" }\n", | |
" </script>\n", | |
" </div>\n", | |
"\n", | |
"\n", | |
" <div id=\"id_82e24f8f-0a87-4fe0-8a91-f56fb2b3a9dd\">\n", | |
" <style>\n", | |
" .colab-df-generate {\n", | |
" background-color: #E8F0FE;\n", | |
" border: none;\n", | |
" border-radius: 50%;\n", | |
" cursor: pointer;\n", | |
" display: none;\n", | |
" fill: #1967D2;\n", | |
" height: 32px;\n", | |
" padding: 0 0 0 0;\n", | |
" width: 32px;\n", | |
" }\n", | |
"\n", | |
" .colab-df-generate:hover {\n", | |
" background-color: #E2EBFA;\n", | |
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
" fill: #174EA6;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-generate {\n", | |
" background-color: #3B4455;\n", | |
" fill: #D2E3FC;\n", | |
" }\n", | |
"\n", | |
" [theme=dark] .colab-df-generate:hover {\n", | |
" background-color: #434B5C;\n", | |
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
" fill: #FFFFFF;\n", | |
" }\n", | |
" </style>\n", | |
" <button class=\"colab-df-generate\" onclick=\"generateWithVariable('df')\"\n", | |
" title=\"Generate code using this dataframe.\"\n", | |
" style=\"display:none;\">\n", | |
"\n", | |
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
" width=\"24px\">\n", | |
" <path d=\"M7,19H8.4L18.45,9,17,7.55,7,17.6ZM5,21V16.75L18.45,3.32a2,2,0,0,1,2.83,0l1.4,1.43a1.91,1.91,0,0,1,.58,1.4,1.91,1.91,0,0,1-.58,1.4L9.25,21ZM18.45,9,17,7.55Zm-12,3A5.31,5.31,0,0,0,4.9,8.1,5.31,5.31,0,0,0,1,6.5,5.31,5.31,0,0,0,4.9,4.9,5.31,5.31,0,0,0,6.5,1,5.31,5.31,0,0,0,8.1,4.9,5.31,5.31,0,0,0,12,6.5,5.46,5.46,0,0,0,6.5,12Z\"/>\n", | |
" </svg>\n", | |
" </button>\n", | |
" <script>\n", | |
" (() => {\n", | |
" const buttonEl =\n", | |
" document.querySelector('#id_82e24f8f-0a87-4fe0-8a91-f56fb2b3a9dd button.colab-df-generate');\n", | |
" buttonEl.style.display =\n", | |
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
"\n", | |
" buttonEl.onclick = () => {\n", | |
" google.colab.notebook.generateWithVariable('df');\n", | |
" }\n", | |
" })();\n", | |
" </script>\n", | |
" </div>\n", | |
"\n", | |
" </div>\n", | |
" </div>\n" | |
], | |
"text/plain": [ | |
" pct_good_cwv_change_mobile pct_good_lcp_change_mobile \\\n", | |
"0 2.60% 3.39% \n", | |
"\n", | |
" pct_good_cls_change_mobile pct_good_inp_change_mobile \\\n", | |
"0 2.75% 1.52% \n", | |
"\n", | |
" pct_good_cwv_change_desktop pct_good_lcp_change_desktop \\\n", | |
"0 2.39% 2.55% \n", | |
"\n", | |
" pct_good_cls_change_desktop pct_good_inp_change_desktop \\\n", | |
"0 1.09% 0.23% \n", | |
"\n", | |
" feature_active_sites feature_inactive_sites also_active_at_before \\\n", | |
"0 7203 50000 0.00% \n", | |
"\n", | |
" before_date after_date generator_tag \\\n", | |
"0 2024-03-01 2024-08-01 speculation-rules \n", | |
"\n", | |
" cwv_changes_active_sites \\\n", | |
"0 [0.07083488781153219, 0.06909267366979688, 0.0... \n", | |
"\n", | |
" cwv_changes_inactive_sites \n", | |
"0 [0.04482710642311871, 0.03515486832303927, 0.0... " | |
] | |
}, | |
"execution_count": 31, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Performance by Feature Queries\n", | |
"\n", | |
"## Notes\n", | |
"* `inactive_to_active_percent` Shows the percent of feature-active sites at the after date that __were also feature-active__ at the before date. Ideally this should be 0, meaning none of the sites had the feature ative at the before date.\n" | |
], | |
"metadata": { | |
"id": "cLMOaWak2-e3" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Speculative Loading" | |
], | |
"metadata": { | |
"id": "KSgLpTio3Dpj" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"latest_dataset = '2024-09-01'" | |
], | |
"metadata": { | |
"id": "6mYeQTz-xkyN" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ### Compare before/after\n", | |
"#@markdown * `before_date`: a date to analyze where the feature is not enabled\n", | |
"#@markdown * `after_date`: a date to analyze where the feature is enabled\n", | |
"#@markdown * `generator`: the generator tag indicating a feature is installed\n", | |
"#@markdown * `inactive_to_active_percent` Shows the percent of feature-active sites at the after date that were also feature-active at the before date.\n", | |
"\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'speculation-rules'\n", | |
"\n", | |
"results_sl = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_sl)" | |
], | |
"metadata": { | |
"id": "QWxVV0iZ3afy", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "5d398dbc-0184-4425-f635-1e6eee110e03" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '2.04%', 'pct_good_lcp_change_mobile': '2.00%', 'pct_good_cls_change_mobile': '2.00%', 'pct_good_inp_change_mobile': '1.33%', 'pct_good_cwv_change_desktop': '2.25%', 'pct_good_lcp_change_desktop': '2.55%', 'pct_good_cls_change_desktop': '1.59%', 'pct_good_inp_change_desktop': '-0.24%', 'feature_active_sites': 9091, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'speculation-rules', 'cwv_changes_active_sites': [0.0709573638372546, 0.05973671280401477, 0.03339427392262129, 0.09929041920330417, 0.05443899666326818, 0.06367646788742376, 0.02837772363253499, -0.0026272786983606577], 'cwv_changes_inactive_sites': [0.050594884631586345, 0.03974626020874489, 0.013417786565544043, 0.08595551937012391, 0.031957622667799446, 0.03816732623091601, 0.012432157707554903, -0.00018933025299994188]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Image Prioitizer" | |
], | |
"metadata": { | |
"id": "vYf6nRjU44pU" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# image-prioritizer\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'image-prioritizer'\n", | |
"\n", | |
"results_ip = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_ip)" | |
], | |
"metadata": { | |
"id": "Vrk1yAp15u1C", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "bfe6b1b2-d9ca-422a-8e28-7c9a2e2e9d5b" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '1.83%', 'pct_good_lcp_change_mobile': '2.63%', 'pct_good_cls_change_mobile': '2.02%', 'pct_good_inp_change_mobile': '1.07%', 'pct_good_cwv_change_desktop': '3.63%', 'pct_good_lcp_change_desktop': '3.64%', 'pct_good_cls_change_desktop': '2.66%', 'pct_good_inp_change_desktop': '-0.46%', 'feature_active_sites': 3057, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-04-01', 'after_date': '2024-09-01', 'generator_tag': 'image-prioritizer', 'cwv_changes_active_sites': [0.06355639390247644, 0.066255044344453, 0.025530920421860004, 0.08869432502523766, 0.06324726213202053, 0.06865713642895399, 0.034364047044162294, -0.004424134395824675], 'cwv_changes_inactive_sites': [0.04529243087001833, 0.039932468951196454, 0.005380117484358293, 0.07796061197519022, 0.02694167020240129, 0.03227752930248928, 0.007753865162267282, 0.00015203821501585946]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Embed Optimizer\n", | |
"\n", | |
"\n" | |
], | |
"metadata": { | |
"id": "Q0OKwj0847rt" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# embed-optimizer\n", | |
"before_date = '2024-07-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'embed-optimizer'\n", | |
"\n", | |
"results_eo = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_eo)" | |
], | |
"metadata": { | |
"id": "Deb8H7gl5qYH", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "94442b25-a59c-47bb-f8dd-3c361d36c04e" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '-5.69%', 'pct_good_lcp_change_mobile': '-4.23%', 'pct_good_cls_change_mobile': '-0.57%', 'pct_good_inp_change_mobile': '0.11%', 'pct_good_cwv_change_desktop': '-0.83%', 'pct_good_lcp_change_desktop': '-4.91%', 'pct_good_cls_change_desktop': '0.91%', 'pct_good_inp_change_desktop': '-0.37%', 'feature_active_sites': 4908, 'feature_inactive_sites': 50000, 'also_active_at_before': '5906.68%', 'before_date': '2024-07-01', 'after_date': '2024-09-01', 'generator_tag': 'embed-optimizer', 'cwv_changes_active_sites': [-0.041306793074358306, -0.031142749330665964, -0.009310373802833838, 0.03288217754941303, -0.00780285351372112, -0.04850123311220522, 0.010024549239471159, -0.005046772644276998], 'cwv_changes_inactive_sites': [0.01555233539948292, 0.011153826487459773, -0.0036123086688277795, 0.03178291363875008, 0.0005148192916936134, 0.0005865276079072279, 0.0008919736799152256, -0.0013168643303140826]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Modern Image Formats" | |
], | |
"metadata": { | |
"id": "U0sMVoPs4_Xh" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# webp-uploads\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'webp-uploads'\n", | |
"\n", | |
"results_mi = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_mi)" | |
], | |
"metadata": { | |
"id": "1tNlKpIU5zVS", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "81a9fd42-9de8-41b9-d1bc-a0491b4efb05" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '1.86%', 'pct_good_lcp_change_mobile': '1.26%', 'pct_good_cls_change_mobile': '2.31%', 'pct_good_inp_change_mobile': '1.57%', 'pct_good_cwv_change_desktop': '2.31%', 'pct_good_lcp_change_desktop': '2.14%', 'pct_good_cls_change_desktop': '1.45%', 'pct_good_inp_change_desktop': '0.15%', 'feature_active_sites': 16148, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-01-01', 'after_date': '2024-09-01', 'generator_tag': 'webp-uploads', 'cwv_changes_active_sites': [0.09053611980768622, 0.06681956845397613, 0.04422785761234971, 0.13775801636582619, 0.053067897464070646, 0.055216839004633256, 0.029493570947297654, 0.003979401208744959], 'cwv_changes_inactive_sites': [0.0719599926198663, 0.05425106123086576, 0.021089317940479635, 0.1220972067245063, 0.030003443405208163, 0.033798004781138036, 0.015025429495077125, 0.002452523250483174]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Enhanced Image Sizes" | |
], | |
"metadata": { | |
"id": "xT4NB_OY5Jld" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# auto-sizes\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'auto-sizes'\n", | |
"\n", | |
"results_is = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_is)" | |
], | |
"metadata": { | |
"id": "2dQQhAFC5mnw", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "2018309b-32bc-422e-a2c4-d79746a4740a" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '0.77%', 'pct_good_lcp_change_mobile': '-0.22%', 'pct_good_cls_change_mobile': '2.33%', 'pct_good_inp_change_mobile': '2.50%', 'pct_good_cwv_change_desktop': '3.02%', 'pct_good_lcp_change_desktop': '1.37%', 'pct_good_cls_change_desktop': '3.14%', 'pct_good_inp_change_desktop': '0.18%', 'feature_active_sites': 5633, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'auto-sizes', 'cwv_changes_active_sites': [0.06442163880919188, 0.048145394148988996, 0.0325715565983854, 0.11997871774408086, 0.06243687002187076, 0.05522724145910157, 0.041617845644969065, 0.001961164045756192], 'cwv_changes_inactive_sites': [0.05675288022675129, 0.05037639877576028, 0.009301400069805288, 0.09498100979108803, 0.03222344332123689, 0.041554902302256336, 0.010225594823027317, 0.00014161616508323593]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Performant Translations" | |
], | |
"metadata": { | |
"id": "SyUbptUIQ-R0" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# performant-translations\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'performant-translations'\n", | |
"\n", | |
"results_is = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_is)" | |
], | |
"metadata": { | |
"id": "RfVL5TDlRA-h" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Web Worker Offloading" | |
], | |
"metadata": { | |
"id": "dFBb2AfYReqb" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# web-worker-offloading\n", | |
"before_date = '2024-07-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'web-worker-offloading'\n", | |
"\n", | |
"results_is = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_is)" | |
], | |
"metadata": { | |
"id": "Y2GyJeDDRg99", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "2ffbe55d-168c-4906-bfac-e281544e2092" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '0.94%', 'pct_good_lcp_change_mobile': '-1.22%', 'pct_good_cls_change_mobile': '5.04%', 'pct_good_inp_change_mobile': '1.29%', 'pct_good_cwv_change_desktop': '0.55%', 'pct_good_lcp_change_desktop': '-1.35%', 'pct_good_cls_change_desktop': '4.56%', 'pct_good_inp_change_desktop': '0.10%', 'feature_active_sites': 601, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-07-01', 'after_date': '2024-11-01', 'generator_tag': 'web-worker-offloading', 'cwv_changes_active_sites': [0.026853975535168162, 0.0001429762897652842, 0.046814342865609704, 0.04866273605058535, 0.005261578120310084, -0.007205877183732334, 0.039323973650941535, 0.000566951860632936, date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"1 2024-07-01 mobile 312 0.275229 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"1 0.412844 0.744118 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"1 0.614458 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"2 2024-11-01 mobile 363 0.302083 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"2 0.412987 0.790932 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"2 0.663121 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"0 2024-07-01 desktop 227 0.37788 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"0 0.53211 0.588496 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"0 0.97191 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"3 2024-11-01 desktop 266 0.383142 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"3 0.524904 0.62782 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"3 0.972477 ], 'cwv_changes_inactive_sites': [0.01742855793811049, 0.012363291471110371, -0.003585737185353821, 0.03574913070510788, -0.00026561188097889987, 0.00628024071174782, -0.006276333951685142, -0.00045329309517982974, date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"1 2024-07-01 mobile 38975 0.390947 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"1 0.536264 0.785201 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"1 0.755696 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"2 2024-11-01 mobile 41797 0.408376 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"2 0.548627 0.781615 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"2 0.791445 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"0 2024-07-01 desktop 31126 0.46937 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"0 0.640656 0.693395 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"0 0.987947 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"3 2024-11-01 desktop 33969 0.469105 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"3 0.646936 0.687118 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"3 0.987494 ]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"latest_dataset = '2024-11-01'" | |
], | |
"metadata": { | |
"id": "GnSlKJqWZRFF" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Embed Optimizer plus Optimization detective\n" | |
], | |
"metadata": { | |
"id": "bYE8yA7d_8dv" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# this will use a slightly different approach because we are looking for sites with two features enabled.\n", | |
"before_date = '2024-07-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag1 = 'optimization-detective'\n", | |
"generator_tag2 = 'embed-optimizer'\n", | |
"\n", | |
"results_is = query_cwv_compare_feature_to_baseline_by_device_multiple_tags(generator_tag1, generator_tag2, before_date, after_date)\n", | |
"print(results_is)\n", | |
"\n" | |
], | |
"metadata": { | |
"id": "huI-O2YMAAuO", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "6c55fe80-7933-45a6-c675-0ae583e33250" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '0.20%', 'pct_good_lcp_change_mobile': '1.09%', 'pct_good_cls_change_mobile': '2.08%', 'pct_good_inp_change_mobile': '-0.48%', 'pct_good_cwv_change_desktop': '4.39%', 'pct_good_lcp_change_desktop': '2.12%', 'pct_good_cls_change_desktop': '3.70%', 'pct_good_inp_change_desktop': '-0.22%', 'feature_active_sites': 3523, 'feature_inactive_sites': 50000, 'also_active_at_before': '1481.69%', 'before_date': '2024-07-01', 'after_date': '2024-11-01', 'generator_tag1': 'optimization-detective', 'generator_tag2': 'embed-optimizer', 'cwv_changes_active_sites': [0.022084835266597713, 0.026946373942071167, 0.014579789123231879, 0.03380411086302515, 0.04506952879183501, 0.031181994226598397, 0.032788667906710534, -0.0035211267605633756, date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"0 2024-07-01 mobile 1715 0.260748 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"0 0.363788 0.719718 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"0 0.694842 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"2 2024-11-01 mobile 2066 0.282833 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"2 0.390735 0.734297 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"2 0.728647 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"1 2024-07-01 desktop 1212 0.323051 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"1 0.479897 0.614108 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"1 0.985915 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"3 2024-11-01 desktop 1456 0.36812 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"3 0.511079 0.646897 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"3 0.982394 ], 'cwv_changes_inactive_sites': [0.020120224450941193, 0.016093714735728737, -0.006181671591478977, 0.038600244501898584, 0.0012012495827020686, 0.009982428443944924, -0.004181185090754269, -0.0013615621774009101, date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"0 2024-07-01 mobile 40668 0.378968 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"0 0.539324 0.77524 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"0 0.733711 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"3 2024-11-01 mobile 43404 0.399088 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"3 0.555418 0.769058 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"3 0.772312 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"1 2024-07-01 desktop 33696 0.468656 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"1 0.643538 0.688438 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"1 0.986965 , date device origins pct_eligible_origins_with_good_cwv \\\n", | |
"2 2024-11-01 desktop 36528 0.469858 \n", | |
"\n", | |
" pct_eligible_origins_with_good_lcp pct_eligible_origins_with_good_cls \\\n", | |
"2 0.653521 0.684257 \n", | |
"\n", | |
" pct_eligible_origins_with_good_inp \n", | |
"2 0.985604 ]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Graveyard" | |
], | |
"metadata": { | |
"id": "BoVOOEMO46eL" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from google.cloud import bigquery\n", | |
"import pandas as pd\n", | |
"\n", | |
"def analyse_performance_impact_of_feature(generator_tag, after_date=None):\n", | |
"\n", | |
" client = bigquery.Client()\n", | |
"\n", | |
" # 1. Identify Active and Non-Active Sites\n", | |
" active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith('$.{{generator}}'));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
" SELECT * FROM\n", | |
" (\n", | |
" SELECT\n", | |
" page AS origin,\n", | |
" client AS device,\n", | |
" date,\n", | |
" getFeature(payload) as feature\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y_%m_%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" )\n", | |
" WHERE feature != \"\"\n", | |
" LIMIT 10000\n", | |
" \"\"\"\n", | |
"\n", | |
" non_active_sites_query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING)\n", | |
" RETURNS STRING\n", | |
" LANGUAGE js\n", | |
" AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith('$.{{generator}}'));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" ''';\n", | |
"\n", | |
" SELECT * FROM\n", | |
" (\n", | |
" SELECT\n", | |
" page AS origin,\n", | |
" client AS device,\n", | |
" date,\n", | |
" getFeature(payload) as feature\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = 'WordPress'\n", | |
" AND date = PARSE_DATE('%Y_%m_%d', '{after_date}' )\n", | |
" AND is_root_page = TRUE\n", | |
" )\n", | |
" WHERE feature = \"\"\n", | |
" LIMIT 10000\n", | |
" \"\"\"\n", | |
"\n", | |
" active_sites_df = client.query(active_sites_query).to_dataframe()\n", | |
" non_active_sites_df = client.query(non_active_sites_query).to_dataframe()\n", | |
"\n", | |
"\n", | |
" # 2. Collect CWV Data and Calculate Baselines\n", | |
" def calculate_cwv_stats(df, active=False):\n", | |
" cwv_metrics = ['largest_contentful_paint', 'first_input_delay', 'cumulative_layout_shift']\n", | |
" all_cwv_data = []\n", | |
"\n", | |
" for _, row in df.iterrows():\n", | |
" for month_offset in range(14): # collect data for the past 14 months\n", | |
" query_date = row['parse_date'] - pd.DateOffset(months=month_offset)\n", | |
" query_string = f\"\"\"\n", | |
"\n", | |
" SELECT origin,\n", | |
" IF(fast_lcp_count IS NOT NULL, fast_lcp_count / (fast_lcp_count + avg_lcp_count + slow_lcp_count), NULL) AS lcp_pass_rate,\n", | |
" IF(fast_fid_count IS NOT NULL, fast_fid_count / (fast_fid_count + avg_fid_count + slow_fid_count), NULL) AS fid_pass_rate,\n", | |
" IF(small_cls_count IS NOT NULL, small_cls_count / (small_cls_count + medium_cls_count + large_cls_count), NULL) AS cls_pass_rate,\n", | |
" IF(good_inp_count IS NOT NULL, good_inp_count / (good_inp_count + ok_inp_count + poor_inp_count), NULL) AS inp_pass_rate\n", | |
" FROM `chrome-ux-report.materialized.device_summary`\n", | |
" WHERE origin = '{row[\"url\"]}'\n", | |
" AND DATE_TRUNC(date, MONTH) = DATE_TRUNC(DATE('{query_date}'), MONTH)\n", | |
" \"\"\"\n", | |
"\n", | |
" cwv_data = client.query(query_string).to_dataframe()\n", | |
" if not cwv_data.empty:\n", | |
" cwv_data['month'] = query_date # include the month for each metric\n", | |
" cwv_data['active'] = active\n", | |
" all_cwv_data.append(cwv_data)\n", | |
"\n", | |
" return pd.concat(all_cwv_data)\n", | |
"\n", | |
" # 3. Identify Feature Activation and Calculate Impact\n", | |
" active_cwv_stats = calculate_cwv_stats(active_sites_df, active=True)\n", | |
" non_active_cwv_stats = calculate_cwv_stats(non_active_sites_df)\n", | |
"\n", | |
" def calculate_feature_impact(active_cwv_stats):\n", | |
" impact_data = []\n", | |
" for url, group in active_cwv_stats.groupby('origin'):\n", | |
" activation_month = group[group['active'] == True]['month'].min()\n", | |
" if activation_month is not pd.NaT:\n", | |
" before_activation = group[group['month'] == activation_month - pd.DateOffset(months=1)]\n", | |
" after_activation = group[group['month'] == activation_month + pd.DateOffset(months=1)]\n", | |
"\n", | |
" if not before_activation.empty and not after_activation.empty:\n", | |
" impact = after_activation.mean() - before_activation.mean()\n", | |
" impact['url'] = url\n", | |
" impact_data.append(impact)\n", | |
"\n", | |
" return pd.DataFrame(impact_data)\n", | |
"\n", | |
" feature_impact_df = calculate_feature_impact(active_cwv_stats)\n", | |
"\n", | |
" return feature_impact_df" | |
], | |
"metadata": { | |
"id": "kD6TC3jpXI2W" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"analyse_performance_impact_of_feature('speculation-rules', '2024_06_01')\n" | |
], | |
"metadata": { | |
"id": "QrL9fImAtqKX" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [], | |
"metadata": { | |
"id": "rDn6hWyywriY" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Example using Speculation Rules" | |
], | |
"metadata": { | |
"id": "CT9vfgXOu0UA" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ### Compare speculation rules before/after\n", | |
"results = query_cwv_compare_feature_to_baseline( 'speculation-rules', '2024-03-01', '2024-06-01' )\n", | |
"print(results)" | |
], | |
"metadata": { | |
"id": "VBtebScA8k-m" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"### Helper to compare feature before / after" | |
], | |
"metadata": { | |
"id": "8o_CYabIgMwI" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Restrict the query to on the from and to dates, and without and with a specific generator tag indicating a feature is active\n", | |
"def query_cwv_compare_dates_by_generator(technology, from_date, to_date, generator):\n", | |
" \"\"\"\n", | |
" Queries Core Web Vitals metrics from HTTP Archive.\n", | |
"\n", | |
" Args:\n", | |
" technology (str): The technology to filter by (e.g., 'WordPress').\n", | |
" from_date (str): The start date in YYYY_MM_DD format.\n", | |
" to_date (str): The end date in YYYY_MM_DD format.\n", | |
" generator (str): The generator tag indicating a feature is installed.\n", | |
" Returns:\n", | |
" A BigQuery query result object containing CWV data.\n", | |
" \"\"\"\n", | |
" # set to_date if not passed\n", | |
" if not to_date:\n", | |
" to_date = latest_dataset\n", | |
"\n", | |
" # set from date if not passed\n", | |
" if not from_date:\n", | |
" from_date = (datetime.strptime(to_date, '%Y_%m_%d').date() - timedelta(days=365)).strftime('%Y_%m_%d')\n", | |
"\n", | |
"\n", | |
" query = f\"\"\"\n", | |
" CREATE TEMP FUNCTION getFeature(payload STRING)\n", | |
"RETURNS STRING\n", | |
"LANGUAGE js\n", | |
"AS '''\n", | |
" try {{\n", | |
" var $ = JSON.parse(payload);\n", | |
" var almanac = JSON.parse($._almanac);\n", | |
" var generators = almanac['meta-nodes'].nodes.find(node => node.name == 'generator' && node.content.startsWith('$.{{generator}}'));\n", | |
" if ( generators.length == 0 ) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
" var content = generators.content;\n", | |
" return content;\n", | |
" }} catch (e) {{\n", | |
" return \"\";\n", | |
" }}\n", | |
"''';\n", | |
"\n", | |
"CREATE TEMP FUNCTION IS_GOOD(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good / (good + needs_improvement + poor) >= 0.75\n", | |
" );\n", | |
"\n", | |
" CREATE TEMP FUNCTION IS_NON_ZERO(good FLOAT64, needs_improvement FLOAT64, poor FLOAT64)\n", | |
" RETURNS BOOL\n", | |
" AS (\n", | |
" good + needs_improvement + poor > 0\n", | |
" );\n", | |
" WITH sites_available_on_from_or_to_date AS (\n", | |
" SELECT\n", | |
" page AS origin,\n", | |
" client AS device,\n", | |
" date,\n", | |
" getFeature(payload) as feature\n", | |
" FROM\n", | |
" `httparchive.all.pages`,\n", | |
" UNNEST(technologies) AS technologies\n", | |
" WHERE\n", | |
" technologies.technology = '{technology}'\n", | |
" AND (\n", | |
" ( date = PARSE_DATE('%Y_%m_%d', '{from_date}') ) OR\n", | |
" ( date = PARSE_DATE('%Y_%m_%d', '{to_date}' ) )\n", | |
" )\n", | |
" AND is_root_page = TRUE\n", | |
"\n", | |
" ),\n", | |
" site_on_to_date_with_feature AS (\n", | |
" SELECT\n", | |
" origin,\n", | |
" device,\n", | |
" date,\n", | |
" feature\n", | |
" FROM sites_available_on_from_or_to_date\n", | |
" WHERE date = PARSE_DATE('%Y_%m_%d', '{to_date}' )\n", | |
" AND feature != \"\"\n", | |
" ),\n", | |
" sites_on_from_date_without_feature AS (\n", | |
" SELECT\n", | |
" origin,\n", | |
" device,\n", | |
" date,\n", | |
" feature\n", | |
" FROM\n", | |
" sites_available_on_from_or_to_date\n", | |
" WHERE\n", | |
" date = PARSE_DATE('%Y_%m_%d', '{from_date}')\n", | |
" AND feature = \"\"\n", | |
" ),\n", | |
" sites_available_for_both_from_and_to AS (\n", | |
" SELECT\n", | |
" sites_available_on_from_or_to_date.origin\n", | |
" FROM\n", | |
" sites_available_on_from_or_to_date\n", | |
" JOIN\n", | |
" sites_on_from_date_without_feature\n", | |
" ON (sites_available_on_from_or_to_date.origin = sites_on_from_date_without_feature.origin)\n", | |
" ),\n", | |
" cwv_metrics_for_origins AS (\n", | |
" SELECT\n", | |
" cwvs.date AS date,\n", | |
" site_on_to_date_with_feature.origin AS origin,\n", | |
" # Device phone or tablet as mobile, otherwise desktop.\n", | |
" IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', cwvs.device) AS device,\n", | |
" IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp,\n", | |
" IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp,\n", | |
" IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls,\n", | |
" IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls,\n", | |
" IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp,\n", | |
" IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp,\n", | |
" (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND IS_GOOD(small_cls, medium_cls, large_cls) AND IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_cwv\n", | |
" FROM\n", | |
" `chrome-ux-report.materialized.device_summary` AS cwvs\n", | |
" JOIN\n", | |
" site_on_to_date_with_feature\n", | |
" ON (\n", | |
" site_on_to_date_with_feature.origin = CONCAT(cwvs.origin, '/') AND\n", | |
" site_on_to_date_with_feature.device = IF(cwvs.device = 'phone' OR cwvs.device = 'tablet', 'mobile', cwvs.device)\n", | |
" )\n", | |
" WHERE\n", | |
" cwvs.date BETWEEN PARSE_DATE('%Y_%m_%d', '{from_date}') AND PARSE_DATE('%Y_%m_%d', '{to_date}' )\n", | |
" AND cwvs.device IN ('desktop', 'tablet', 'phone')\n", | |
" # Restrict to sites that are in both dates\n", | |
" AND CONCAT(cwvs.origin, '/') IN (\n", | |
" SELECT\n", | |
" origin\n", | |
" FROM\n", | |
" sites_available_for_both_from_and_to\n", | |
" )\n", | |
" ),\n", | |
"\n", | |
"\n", | |
" cwvs_by_date AS (\n", | |
" SELECT\n", | |
" date,\n", | |
" device,\n", | |
" COUNT(DISTINCT origin) AS origins,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cwv), COUNTIF(any_lcp AND any_cls)) AS pct_eligible_origins_with_good_cwv,\n", | |
" SAFE_DIVIDE(COUNTIF(good_lcp), COUNTIF(any_lcp)) AS pct_eligible_origins_with_good_lcp,\n", | |
" SAFE_DIVIDE(COUNTIF(good_cls), COUNTIF(any_cls)) AS pct_eligible_origins_with_good_cls,\n", | |
" SAFE_DIVIDE(COUNTIF(good_inp), COUNTIF(any_inp)) AS pct_eligible_origins_with_good_inp\n", | |
" FROM\n", | |
" cwv_metrics_for_origins\n", | |
" GROUP BY\n", | |
" date, device\n", | |
" ORDER BY\n", | |
" date, device\n", | |
" )\n", | |
" SELECT * FROM cwvs_by_date\n", | |
" \"\"\"\n", | |
"\n", | |
" query_job = client.query(query)\n", | |
" return query_job.result() # Return the results of the query" | |
], | |
"metadata": { | |
"id": "uVTvoirMaxIe" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Step By Step testing" | |
], | |
"metadata": { | |
"id": "5R3EB1yo4Y5A" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"generator_tag = 'speculation-rules'\n", | |
"after_date = '2024-06-01'\n", | |
"before_date = '2024-03-01'\n", | |
"\n", | |
"active_sites = get_sites_with_feature_active(generator_tag, after_date)\n", | |
"count_active_sites = active_sites.count()\n", | |
"inactive_sites = get_sites_with_feature_inactive(generator_tag, after_date)\n", | |
"count_inactive_sites = inactive_sites.count()\n" | |
], | |
"metadata": { | |
"id": "TiX_xxi_iv-H" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Count feature active sites that were also feature active at the before date.\n", | |
"print(before_date)\n", | |
"active_at_from_date = get_active_sites_also_active_at_before_date(generator_tag, before_date, active_sites)\n", | |
"count_active_at_from_date = active_at_from_date.count()\n", | |
"\n" | |
], | |
"metadata": { | |
"id": "zWiHNoWla0aS" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"count_active_sites['origin']" | |
], | |
"metadata": { | |
"id": "S88ocl0vvgr6" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Calculate the percentage of count_active_at_from_date (which might be 0)\n", | |
"# Calculate the percentage of count_active_at_from_date (which might be 0 so use safe divide)\n", | |
"if count_active_sites['origin'] > 0:\n", | |
" percent_of_active_sites_also_active_at_from_date = (count_active_at_from_date['origin'] / count_active_sites['origin']) * 100\n", | |
"else:\n", | |
" percent_of_active_sites_also_active_at_from_date = 0\n", | |
"\n", | |
"inactive_to_active_percent = 100 - percent_of_active_sites_also_active_at_from_date;" | |
], | |
"metadata": { | |
"id": "c6_fKLCmvJ9e" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Calculate CWV change\n", | |
"cwv_changes_active_sites = get_cwv_change_before_after(active_sites, before_date, after_date )\n", | |
"cwv_changes_inactive_sites = get_cwv_change_before_after(inactive_sites, before_date, after_date )\n", | |
"\n", | |
"final_results = calculate_feature_impact(cwv_changes_active_sites, cwv_changes_inactive_sites)\n", | |
"final_results['feature_active_sites'] = count_active_sites['origin']\n", | |
"final_results['feature_inactive_sites'] = count_inactive_sites['origin']\n", | |
"final_results['inactive_to_active_percent'] = inactive_to_active_percent\n" | |
], | |
"metadata": { | |
"id": "Y4tpTREfa0SN" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"final_results" | |
], | |
"metadata": { | |
"id": "zj2E6bsda0Gy" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [], | |
"metadata": { | |
"id": "aRkOWFb247PX" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"----" | |
], | |
"metadata": { | |
"id": "yN-yPeZa46y_" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [], | |
"metadata": { | |
"id": "z-1YtLdF46qa" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Performance by Feature Queries from 2024-03-01" | |
], | |
"metadata": { | |
"id": "nuOOxybxdCma" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Speculative Loading" | |
], | |
"metadata": { | |
"id": "ZhClysvodCmb" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"#@markdown ### Compare before/after\n", | |
"#@markdown * `before_date`: a date to analyze where the feature is not enabled\n", | |
"#@markdown * `after_date`: a date to analyze where the feature is enabled\n", | |
"#@markdown * `generator`: the generator tag indicating a feature is installed\n", | |
"\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'speculation-rules'\n", | |
"\n", | |
"results_sl2 = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_sl2)" | |
], | |
"metadata": { | |
"id": "mpMzlYEMdCmb", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "9e7f14b5-99fb-4525-bec3-6561a8880f18" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '1.42%', 'pct_good_lcp_change_mobile': '1.30%', 'pct_good_cls_change_mobile': '2.19%', 'pct_good_inp_change_mobile': '0.56%', 'pct_good_cwv_change_desktop': '2.14%', 'pct_good_lcp_change_desktop': '2.37%', 'pct_good_cls_change_desktop': '1.63%', 'pct_good_inp_change_desktop': '-0.25%', 'feature_active_sites': 9091, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'speculation-rules', 'cwv_changes_active_sites': [0.0709573638372546, 0.05973671280401477, 0.03339427392262129, 0.09929041920330417, 0.05443899666326818, 0.06367646788742376, 0.02837772363253499, -0.0026272786983606577], 'cwv_changes_inactive_sites': [0.0567628587630879, 0.04675857079386847, 0.011511984996228963, 0.09365062821091052, 0.03303288698159201, 0.0399720547958603, 0.012113975978503277, -0.00013179455489875647]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Image Prioitizer" | |
], | |
"metadata": { | |
"id": "hkxRu7zLdCmb" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# image-prioritizer\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'image-prioritizer'\n", | |
"\n", | |
"results_ip2 = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_ip2)" | |
], | |
"metadata": { | |
"id": "TxduuIH2dCmb", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "4a6f3cb0-5dcc-4f7f-f4d0-e23fbee60e13" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '0.07%', 'pct_good_lcp_change_mobile': '0.24%', 'pct_good_cls_change_mobile': '1.99%', 'pct_good_inp_change_mobile': '0.58%', 'pct_good_cwv_change_desktop': '2.98%', 'pct_good_lcp_change_desktop': '1.71%', 'pct_good_cls_change_desktop': '2.74%', 'pct_good_inp_change_desktop': '-0.07%', 'feature_active_sites': 3057, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'image-prioritizer', 'cwv_changes_active_sites': [0.05372470728308859, 0.045826828366386796, 0.031917168837576115, 0.09848436113575865, 0.0579437376094758, 0.05101553940017034, 0.037424997986087116, 0.00018115942028984477], 'cwv_changes_inactive_sites': [0.05306598031955251, 0.04344795680480029, 0.012023500874824844, 0.09271561656330818, 0.028133587541988136, 0.03390036546028041, 0.01006490094309187, 0.0008955579797447211]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Embed Optimizer" | |
], | |
"metadata": { | |
"id": "pxscfkaxdCmb" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# embed-optimizer\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'embed-optimizer'\n", | |
"\n", | |
"results_eo2 = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_eo2)" | |
], | |
"metadata": { | |
"id": "jzUIkzusdCmb", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "03316c6d-9b7d-49d1-d7ee-b02c3be80927" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '-6.71%', 'pct_good_lcp_change_mobile': '-6.99%', 'pct_good_cls_change_mobile': '0.25%', 'pct_good_inp_change_mobile': '-0.26%', 'pct_good_cwv_change_desktop': '2.01%', 'pct_good_lcp_change_desktop': '-7.08%', 'pct_good_cls_change_desktop': '5.58%', 'pct_good_inp_change_desktop': '0.01%', 'feature_active_sites': 4908, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'embed-optimizer', 'cwv_changes_active_sites': [-0.008912738178832036, -0.017832398899997826, 0.013302035749933383, 0.0978406351757094, 0.05156835387437664, -0.030477031089655715, 0.06554045194282965, 0.0013325894195166388], 'cwv_changes_inactive_sites': [0.05813776995746334, 0.05203346729111852, 0.01076988011891955, 0.1004048888519854, 0.03146862294181668, 0.04029451169372489, 0.00971873533213996, 0.0012195856464317645]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Modern Images" | |
], | |
"metadata": { | |
"id": "XFGBFa5QdCmb" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# webp-uploads\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'webp-uploads'\n", | |
"\n", | |
"results_mi2 = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_mi2)" | |
], | |
"metadata": { | |
"id": "RSjCFLw9dCmc", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "9b80c1d2-6511-4578-8bb8-1fc31231a5ab" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '1.53%', 'pct_good_lcp_change_mobile': '0.50%', 'pct_good_cls_change_mobile': '2.53%', 'pct_good_inp_change_mobile': '1.01%', 'pct_good_cwv_change_desktop': '2.67%', 'pct_good_lcp_change_desktop': '2.36%', 'pct_good_cls_change_desktop': '2.13%', 'pct_good_inp_change_desktop': '0.14%', 'feature_active_sites': 16148, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'webp-uploads', 'cwv_changes_active_sites': [0.06732568282636309, 0.0500484400843042, 0.036909719376889694, 0.1028913557761153, 0.05754036788123096, 0.06235835105115772, 0.03277655490922826, 0.001201716738197467], 'cwv_changes_inactive_sites': [0.05201159105926506, 0.04509394431000929, 0.011659601752061821, 0.09280415428856859, 0.030870589794880943, 0.038753358233235335, 0.011429699662780735, -0.00019254586873129753]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Image Sizes" | |
], | |
"metadata": { | |
"id": "GVdW1ccMdCmc" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# auto-sizes\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'auto-sizes'\n", | |
"\n", | |
"results_is2 = query_cwv_compare_feature_to_baseline_by_device(generator_tag, before_date, after_date)\n", | |
"print(results_is2)" | |
], | |
"metadata": { | |
"id": "9EmGXoLLdCmc", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "ad69451e-c86d-4388-ade8-dd18e0e370c8" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"{'pct_good_cwv_change_mobile': '0.95%', 'pct_good_lcp_change_mobile': '0.17%', 'pct_good_cls_change_mobile': '2.26%', 'pct_good_inp_change_mobile': '2.43%', 'pct_good_cwv_change_desktop': '2.96%', 'pct_good_lcp_change_desktop': '1.45%', 'pct_good_cls_change_desktop': '3.11%', 'pct_good_inp_change_desktop': '0.13%', 'feature_active_sites': 5633, 'feature_inactive_sites': 50000, 'also_active_at_before': '0.00%', 'before_date': '2024-03-01', 'after_date': '2024-09-01', 'generator_tag': 'auto-sizes', 'cwv_changes_active_sites': [0.06442163880919188, 0.048145394148988996, 0.0325715565983854, 0.11997871774408086, 0.06243687002187076, 0.05522724145910157, 0.041617845644969065, 0.001961164045756192], 'cwv_changes_inactive_sites': [0.054874468344218774, 0.04648435338003126, 0.009980232692361701, 0.09568983354224359, 0.032824792702341954, 0.0406943834871375, 0.01054937525763644, 0.0007026135858518856]}\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Optimization Detective plus Embed Optimizer" | |
], | |
"metadata": { | |
"id": "Ow3y6ErZbD6x" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# embed-optimizer\n", | |
"before_date = '2024-03-01'\n", | |
"after_date = latest_dataset\n", | |
"generator_tag = 'embed-optimizer'\n", | |
"\n", | |
"results_eo2 = query_cwv_compare_feature_to_baseline_by_device_multiple(generator_tag, generator_tag2, before_date, after_date)\n", | |
"print(results_eo2)" | |
], | |
"metadata": { | |
"id": "ic31QLgGbg7u" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"colab": { | |
"provenance": [], | |
"collapsed_sections": [ | |
"4G2WkwMPzxbT", | |
"BoVOOEMO46eL", | |
"5R3EB1yo4Y5A", | |
"nuOOxybxdCma" | |
], | |
"name": "WPP Metrics Tracking colab", | |
"toc_visible": true, | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"name": "python3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment