sync/wptfyi.py (100 lines of code) (raw):
import requests
import time
from urllib import parse
WPT_FYI_BASE = "https://wpt.fyi/api/"
STAGING_HOST = "staging.wpt.fyi"
class Url:
def __init__(self, initial_url):
if initial_url:
parts = parse.urlsplit(initial_url)
self.scheme = parts.scheme
self.host = parts.netloc
self.path = parts.path
self.query = parse.parse_qsl(parts.query, keep_blank_values=True)
self.fragment = parts.fragment
else:
self.scheme = ""
self.host = ""
self.path = ""
self.query = []
self.fragment = ""
def scheme(self, value):
self.scheme = value
return self
def host(self, value):
self.host = value
return self
def path(self, value):
self.path = value
return self
def add_path(self, value):
self.path = parse.urljoin(self.path, value)
return self
def query(self, value):
self.query = value
return self
def add_query(self, name, value):
self.query.append((name, value))
return self
def fragment(self, value):
self.fragment = value
return self
def build(self):
return parse.urlunsplit((self.scheme,
self.host,
self.path,
parse.urlencode(self.query),
self.fragment))
def get_runs(sha=None, pr=None, max_count=None, labels=None, staging=False):
url = Url(WPT_FYI_BASE + "runs")
if staging:
url.host = STAGING_HOST
for name, value in [("sha", sha), ("pr", pr), ("max-count", max_count)]:
if value is not None:
url.add_query(name, value)
if labels:
for item in labels:
url.add_query("label", item)
resp = requests.get(url.build())
resp.raise_for_status()
return resp.json()
def get_results(run_ids, test=None, query=None, staging=False):
url = Url(WPT_FYI_BASE + "search")
if staging:
url.host = STAGING_HOST
body = {
"run_ids": run_ids
}
if query is not None:
body["q"] = query
# A 422 status means that the data isn't in the cache, so retry
retry = 0
timeout = 10
while retry < 5:
resp = requests.post(url.build(), json=body)
if resp.status_code != 422:
break
time.sleep(timeout)
retry += 1
timeout *= 1.5
resp.raise_for_status()
return resp.json()
def get_metadata(products, link, staging=False):
url = Url(WPT_FYI_BASE + "metadata")
if staging:
url.host = STAGING_HOST
if isinstance(products, str):
url.add_query("product", products)
else:
for product in products:
url.add_query("product", product)
resp = requests.get(url.build())
resp.raise_for_status()
if link is not None:
data = {}
for test, values in resp.json().items():
link_values = [item for item in values if link in item["url"]]
if link_values:
data[test] = link_values
else:
data = resp.json()
return data