code: def calculate_at_hash(access_token, hash_alg):
      
      hash_digest = hash_alg(access_token.encode('utf-8')).digest()
      cut_at = int(len(hash_digest) / 2)
      truncated = hash_digest[:cut_at]
      at_hash = base64url_encode(truncated)
      return at_hash.decode('utf-8')
docs: Helper method for calculating an access token
      hash, as described in http://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken
  
      Its value is the base64url encoding of the left-most half of the hash of the octets
      of the ASCII representation of the access_token value, where the hash algorithm
      used is the hash algorithm used in the alg Header Parameter of the ID Token's JOSE
      Header. For instance, if the alg is RS256, hash the access_token value with SHA-256,
      then take the left-most 128 bits and base64url encode them. The at_hash value is a
      case sensitive string.
  
      Args:
          access_token (str): An access token string.
          hash_alg (callable): A callable returning a hash object, e.g. hashlib.sha256