def METHOD_NAME(path, payload, call_count=1, requests_impl=requests):
    """Send a request to the server and return the parsed JSON response."""
    # it's polite to self-identify this "bot"
    delphi_url = "https://delphi.cmu.edu/index.html"
    user_agent = f"Mozilla/5.0 (compatible; delphibot/1.0; +{delphi_url})"
    # the FluSurv AMF server
    flusurv_url = "https://gis.cdc.gov/GRASP/Flu3/" + path
    # request headers
    headers = {
        "Accept-Encoding": "gzip",
        "User-Agent": user_agent,
    }
    if payload is not None:
        headers["Content-Type"] = "application/json;charset=UTF-8"
    # send the request and read the response
    if payload is None:
        method = requests_impl.get
        data = None
    else:
        method = requests_impl.post
        data = json.dumps(payload)
    resp = method(flusurv_url, headers=headers, data=data)
    # check the HTTP status code
    if resp.status_code == 500 and call_count <= 2:
        # the server often fails with this status, so wait and retry
        delay = 10 * call_count
        print(f"got status {int(resp.status_code)}, will retry in {int(delay)} sec...")
        time.sleep(delay)
        return METHOD_NAME(path, payload, call_count=call_count + 1)
    elif resp.status_code != 200:
        raise Exception(["status code != 200", resp.status_code])
    # check response mime type
    if "application/json" not in resp.headers.get("Content-Type", ""):
        raise Exception("response is not json")
    # return the decoded json object
    return resp.json()