<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def webpush(subscription_info, data=None, vapid_private_key=None, vapid_claims=None, content_encoding="aes128gcm", curl=False, timeout=None, ttl=0):
 """ One call solution to endcode and send `data` to the endpoint contained in `subscription_info` using optional VAPID auth headers. in example: .. code-block:: python from pywebpush import python webpush( subscription_info={ "endpoint": "https://push.example.com/v1/abcd", }, data="Mary had a little lamb, with a nice mint jelly", vapid_private_key="path/to/key.pem", vapid_claims={"sub": "YourNameHere@example.com"} ) No additional method call is required. Any non-success will throw a `WebPushException`. :param subscription_info: Provided by the client call :type subscription_info: dict :param data: Serialized data to send :type data: str :param vapid_private_key: Vapid instance or path to vapid private key PEM \ or encoded str :type vapid_private_key: Union[Vapid, str] :param vapid_claims: Dictionary of claims ('sub' required) :type vapid_claims: dict :param content_encoding: Optional content type string :type content_encoding: str :param curl: Return as "curl" string instead of sending :type curl: bool :param timeout: POST requests timeout :type timeout: float or tuple :param ttl: Time To Live :type ttl: int :return requests.Response or string """

    vapid_headers = None
    if vapid_claims:
        if not vapid_claims.get('aud'):
            url = urlparse(subscription_info.get('endpoint'))
            aud = "{}://{}".format(url.scheme, url.netloc)
            vapid_claims['aud'] = aud
        if not vapid_claims.get('exp'):
            # encryption lives for 12 hours
            vapid_claims['exp'] = int(time.time()) + (12 * 60 * 60)
        if not vapid_private_key:
            raise WebPushException("VAPID dict missing 'private_key'")
        if isinstance(vapid_private_key, Vapid):
            vv = vapid_private_key
        elif os.path.isfile(vapid_private_key):
            # Presume that key from file is handled correctly by
            # py_vapid.
            vv = Vapid.from_file(
                private_key_file=vapid_private_key)  # pragma no cover
        else:
            vv = Vapid.from_string(private_key=vapid_private_key)
        vapid_headers = vv.sign(vapid_claims)
    response = WebPusher(subscription_info).send(
        data,
        vapid_headers,
        ttl=ttl,
        content_encoding=content_encoding,
        curl=curl,
        timeout=timeout,
    )
    if not curl and response.status_code > 202:
        raise WebPushException("Push failed: {} {}".format(
            response.status_code, response.reason),
            response=response)
    return response