cloudendpoints / endpoints-management-python Goto Github PK
View Code? Open in Web Editor NEWA Python library for managing API services using Google's Service Control APIs
License: Apache License 2.0
A Python library for managing API services using Google's Service Control APIs
License: Apache License 2.0
I'm trying to implement service-to-service authentication to Google Cloud Endpoints API using Google Service account, but get the following error.
Cannot decode and verify the auth token. The backend will not be able to retrieve user info (.../lib/endpoints_management/control/wsgi.py:596)
Traceback (most recent call last):
File ".../lib/endpoints_management/control/wsgi.py", line 593, in __call__
service_name)
File ".../lib/endpoints_management/auth/tokens.py", line 81, in authenticate
error)
UnauthenticatedException: (u'Cannot decode the auth token', UnicodeDecodeError('ascii', '\xc9\xad\xbd', 0, 1, 'ordinal not in range(128)'))
Value of auth_token variable passed to self.get_jwt_claims(auth_token) is ya29.ElmlBB1mwIfrsnURUIQg0Nv6v5UPzFR02miD4w_VywMSlWGDstpmmc5vPsmUqt5rCcho797B1HeEOgT0UBQiVfv9dlsfxSMLRf67SGwX0ceK5uTujj4_tSUXog
Looks like endpoints library is trying to decode auth_token as jwt, but auth_token is not jwt. But maybe I'm wrong. Same problem occurs when I'm trying to test API using API Explorer. This happens with the latest endpoints and also with older version.
Here is my API class:
@endpoints.api(
name='myapi',
version='v1',
api_key_required=True,
auth_level=endpoints.AUTH_LEVEL.REQUIRED,
scopes=(
endpoints.EMAIL_SCOPE,
),
)
class MyApi(remote.Service):
...
And this is how i I'm accessing the API:
credentials = ServiceAccountCredentials.from_json_keyfile_dict(
json.loads(json_keyfile_data),
scopes='https://www.googleapis.com/auth/userinfo.email',
)
# credentials = AppAssertionCredentials(
# 'https://www.googleapis.com/auth/userinfo.email',
# )
service = build(
name, version,
http=credentials.authorize(Http()),
discoveryServiceUrl=discovery_url)
...
I met following error when I update google-endpoints-api-management to 1.5.0. With 1.4.0, it works well.
I have no idea that this error is related with endpoints-management-python. But it's reproduced in my production server.
(/base/alloc/tmpfs/dynamic_runtimes/python27/a7637d5531ec9deb_unzipped/python27_lib/versions/1/google/appengine/runtime/wsgi.py:263)
Traceback (most recent call last):
File "/base/alloc/tmpfs/dynamic_runtimes/python27/a7637d5531ec9deb_unzipped/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/alloc/tmpfs/dynamic_runtimes/python27/a7637d5531ec9deb_unzipped/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/base/alloc/tmpfs/dynamic_runtimes/python27/a7637d5531ec9deb_unzipped/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 85, in LoadObject
obj = __import__(path[0])
File "/base/data/home/apps/s~poclcast/2018-02-20r1.407780403414466993/main.py", line 5, in <module>
import endpoints
File "/base/data/home/apps/s~poclcast/2018-02-20r1.407780403414466993/lib/endpoints/__init__.py", line 27, in <module>
from .apiserving import *
File "/base/data/home/apps/s~poclcast/2018-02-20r1.407780403414466993/lib/endpoints/apiserving.py", line 69, in <module>
from . import api_backend_service
ImportError: cannot import name api_backend_service
Environment is
Please let me know if you need more information
ssl.cert expired at Jul 19 21:22:26 2017 GMT, which is now in the past.
When endpoint-management is reaching out to get service config i'm getting a 403, I'm still unsure what i've changed to get this but it doesn't really matter for now. This raises a ServiceConfigException.
This gets caught at the wsgi init layer, but instead of propogating the error it returns a webob.exc.HTTPServiceUnavailable.
What this means is that in my entrypoint file like:
api = endpoints.api_server([MyAPI])
the api
object is now a HTTPServiceUnavailable
object and endpoints tries to route traffic to it ending up with errors that look like:
Traceback (most recent call last):
File "/base/alloc/tmpfs/dynamic_runtimes/python27g/7894e0c59273b2b7/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/apps/f~teg-jamie-testing/listings:20180625t231203.410697777093027702/vendor/webob/exc.py", line 271, in __init__
self.headers.extend(headers)
File "/base/data/home/apps/f~teg-jamie-testing/listings:20180625t231203.410697777093027702/vendor/webob/multidict.py", line 233, in extend
for k, v in other:
TypeError: 'instancemethod' object is not iterable
because the 2nd argument to HTTPServiceUnavailable.__init__
is headers, not start_response
as expected.
I'm not entirely sure what good behaviour here is, it makes sense that this needs to return an error but i really want it to happen before i start serving requests (actually i want to fail the deployment based on it).
My current solution i think is going to be like (pseudo):
_api = endpoints.api_server([MyAPI])
if isinstance(api, webob.exc.Exception):
def fail(environ, start_response):
logging.warning("Failed to start API", exc_info=_api.something())
# return 503 with some actual information
api = fail
else:
api = _api
so that at least I get a traceback that I can debug failures with because the current error tells me nothing.
Thanks
Low(ish) priority, because it doesn't impact functionality, but if possible, the efficiency of MethodRegistry.lookup() in service.py should be improved.
For implementations with multiple paths, lookup() is catching multiple exceptions in cases that aren't exceptional. That's too expensive.
I'm seeing 2ms per iteration on GAE standard.
Currently the endpoints management python code doesn't handle api key restrictions for iOS or Android apps. I don't believe this is supported for other languages either, and I have created a related issue here: https://github.com/googleapis/googleapis/issues/303. I have implemented a fix on a fork of this repo (https://github.com/imeier/endpoints-management-python), and will do a pull request.
Thanks,
Ian
Use retries with backoff. If threading isn't available, just retry on the next request. Return a WSGI application encapsulating this and providing necessary indirection.
Registered template _ah/api/project/v1/endpoint under method post (/base/data/home/apps/s~app/v2.405240549392103317/lib/endpoints_management/control/service.py:240)
I see lots of above debug logs. We have 200+ endpoints and each one of them are showing in single api call logs - which suppresses my actual logs in that single api call logs. This was not the case with old v1.
Please remove this unnecessary or non-interested logs.
Hi,
I'm trying to automate an endpoints + AppEngine deployment. Firstly I push to endpoints, then i have to capture the version that was created and insert that into the env_variables in the app.yaml file before deploying my application. This is a fairly clunky flow.
There are two things I've found here that potentially improve this:
Have AppEngine always use the latest API version: https://cloudplatform.googleblog.com/2018/04/Cloud-Endpoints-introducing-a-new-way-to-manage-API-configuration-rollout.html
Have the library fetch and use the latest version automatically: https://github.com/cloudendpoints/endpoints-management-java/blob/master/endpoints-service-config/src/main/java/com/google/api/config/ServiceConfigSupplier.java#L122-L147 https://cloud.google.com/service-management/reference/rest/v1/services.configs/list
I'm uncertain of how option 1 plays into this, whether it's a requirement for option 2, but it appears that if you don't provide a version to the java library it will simply list the available configurations and use the most recent. This would be extremely useful in automatic deployments.
Is this something we can add to the python library?
My company uses the Cloud Endpoints framework on App Engine. Starting on July 6, 2020, we noticed that this error message appeared in the logs of every endpoint call, and we could no longer see metrics for the endpoints on the Google Cloud console:
reportRequest: <ReportRequest
operations: [<Operation
consumerId: u'<omitted>'
endTime: u'2020-07-20T23:45:48.592065Z'
importance: ImportanceValueValuesEnum(LOW, 0)
labels: <LabelsValue
additionalProperties: [<AdditionalProperty
key: '/status_code'
value: u'0'>, <AdditionalProperty
key: '/protocol'
value: u'HTTP'>, <AdditionalProperty
key: '/response_code'
value: u'200'>, <AdditionalProperty
key: '/response_code_class'
value: u'2xx'>, <AdditionalProperty
key: 'servicecontrol.googleapis.com/user_agent'
value: u'ESP'>, <AdditionalProperty
key: 'serviceruntime.googleapis.com/api_method'
value: u'<omitted>'>, <AdditionalProperty
key: 'serviceruntime.googleapis.com/consumer_project'
value: u'<omitted>'>, <AdditionalProperty
key: 'servicecontrol.googleapis.com/platform'
value: u'GAE Standard'>, <AdditionalProperty
key: 'cloud.googleapis.com/location'
value: u'global'>, <AdditionalProperty
key: 'servicecontrol.googleapis.com/service_agent'
value: u'EF_PYTHON/1.11.0'>, <AdditionalProperty
key: '/error_type'
value: u'2xx'>]>
logEntries: [<LogEntry
name: u'endpoints_log'
severity: SeverityValueValuesEnum(INFO, 2)
structPayload: <StructPayloadValue
additionalProperties: [<AdditionalProperty
key: u'api_method'
value: <JsonValue
string_value: u'<omitted>'>>, <AdditionalProperty
key: u'http_response_code'
value: <JsonValue
integer_value: 200>>, <AdditionalProperty
key: u'producer_project_id'
value: <JsonValue
string_value: u'<omitted>'>>, <AdditionalProperty
key: u'url'
value: <JsonValue
array_value: <JsonArray
entries: [<JsonValue
string_value: u'https'>, <JsonValue
string_value: u'<omitted>'>, <JsonValue
string_value: u'<omitted>'>, <JsonValue
string_value: u''>, <JsonValue
string_value: u'<omitted>'>, <JsonValue
string_value: u''>]>>>, <AdditionalProperty
key: u'timestamp'
value: <JsonValue
double_value: 1595288748.0>>, <AdditionalProperty
key: u'request_latency_in_ms'
value: <JsonValue
double_value: 647.494>>, <AdditionalProperty
key: u'http_method'
value: <JsonValue
string_value: u'GET'>>, <AdditionalProperty
key: u'location'
value: <JsonValue
string_value: u'global'>>, <AdditionalProperty
key: u'response_size'
value: <JsonValue
integer_value: 2442>>]>
timestamp: u'2020-07-20T23:45:48.59435Z'>]
metricValueSets: [<MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/consumer/backend_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.545749
mean: 0.545749
minimum: 0.545749
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/consumer/request_count'
metricValues: [<MetricValue
int64Value: 1>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/consumer/request_overhead_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.101745
mean: 0.101745
minimum: 0.101745
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/consumer/response_sizes'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1.0>
maximum: 2442.0
mean: 2442.0
minimum: 2442.0
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/consumer/total_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.647494
mean: 0.647494
minimum: 0.647494
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/backend_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.545749
mean: 0.545749
minimum: 0.545749
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/by_consumer/backend_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.545749
mean: 0.545749
minimum: 0.545749
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/by_consumer/request_count'
metricValues: [<MetricValue
int64Value: 1>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/by_consumer/request_overhead_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.101745
mean: 0.101745
minimum: 0.101745
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/by_consumer/response_sizes'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1.0>
maximum: 2442.0
mean: 2442.0
minimum: 2442.0
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/by_consumer/total_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.647494
mean: 0.647494
minimum: 0.647494
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/request_count'
metricValues: [<MetricValue
int64Value: 1>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/request_overhead_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.101745
mean: 0.101745
minimum: 0.101745
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/response_sizes'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1.0>
maximum: 2442.0
mean: 2442.0
minimum: 2442.0
sumOfSquaredDeviation: 0.0>>]>, <MetricValueSet
metricName: u'serviceruntime.googleapis.com/api/producer/total_latencies'
metricValues: [<MetricValue
distributionValue: <Distribution
bucketCounts: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
count: 1
exponentialBuckets: <ExponentialBuckets
growthFactor: 10.0
numFiniteBuckets: 8
scale: 1e-06>
maximum: 0.647494
mean: 0.647494
minimum: 0.647494
sumOfSquaredDeviation: 0.0>>]>]
operationId: u'e28c394bd46d450388e25f8dcc31e05f'
operationName: u'<omitted>'
resourceContainers: []
startTime: u'2020-07-20T23:45:48.592065Z'>]>
serviceName: '<omitted>'>
Traceback (most recent call last):
File "<omitted>/endpoints_management/control/client.py", line 470, in _flush_schedule_report_aggregator
transport.services.Report(req)
File "<omitted>/endpoints_management/gen/servicecontrol_v1_client.py", line 237, in Report
config, request, global_params=global_params)
File "<omitted>/apitools/base/py/base_api.py", line 730, in _RunMethod
return self.ProcessHttpResponse(method_config, http_response, request)
File "<omitted>/apitools/base/py/base_api.py", line 736, in ProcessHttpResponse
self.__ProcessHttpResponse(method_config, http_response, request))
File "<omitted>/apitools/base/py/base_api.py", line 603, in __ProcessHttpResponse
http_response, method_config=method_config, request=request)
HttpBadRequestError: HttpError accessing <https://servicecontrol.googleapis.com/v1/services/<omitted>:report?alt=json>: response: <{'status': '400', 'content-length': '677', 'x-xss-protection': '0', 'x-content-type-options': 'nosniff', 'transfer-encoding': 'chunked', 'vary': 'Origin, X-Origin, Referer', 'server': 'ESF', '-content-encoding': 'gzip', 'cache-control': 'private', 'date': 'Mon, 20 Jul 2020 23:45:52 GMT', 'x-frame-options': 'SAMEORIGIN', 'content-type': 'application/json; charset=UTF-8'}>, content <{
"error": {
"code": 400,
"message": "MetricValueSet has value with duplicated signature: metric_name: \"serviceruntime.googleapis.com/api/request_latencies_backend\"\nmetric_values {\n distribution_value {\n count: 1\n mean: 0.545749\n minimum: 0.545749\n maximum: 0.545749\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 1\n bucket_counts: 0\n bucket_counts: 0\n bucket_counts: 0\n exponential_buckets {\n num_finite_buckets: 8\n growth_factor: 10\n scale: 1e-06\n }\n }\n}\n",
"status": "INVALID_ARGUMENT"
}
}
>
The message complains about a metric called serviceruntime.googleapis.com/api/request_latencies_backend
having a duplicate signature, but the library does not send a metric with that name.
I did notice the library sends 3 metrics related to backend latency, that are computed using the same function:
serviceruntime.googleapis.com/api/consumer/backend_latencies
serviceruntime.googleapis.com/api/producer/backend_latencies
serviceruntime.googleapis.com/api/producer/by_consumer/backend_latencies
I made a guess that Google was mapping these three metrics to serviceruntime.googleapis.com/api/request_latencies_backend
, and tried monkeypatching the library to only send one of the three. That fixed the issue and the library was able to send metrics again.
Can anyone confirm if this is a new bug with the library caused by some change Google made internally?
config/service_config.py
uses AppEngineManager
if it detects it's running on appengine. But if GAE_USE_SOCKETS_HTTPLIB
is set true, it should use the regular PoolManager.
The current endpoints-management-python library use <2.0.0 cachetools while the google-cloud package restrict the dependency to >= 2.0.0 so the two is incompatible and therefore cannot be used at the same time currently. Is there any workaround?
I was waiting for using custom domains for 2 years now, after the release of Google CloudEndpoints 2.0, I am still struck because I am using google-api-python-client latest version for quite some time now, which is dependent on using oauth2client 2.0.
I posted regarding this few months ago.
cloudendpoints/endpoints-python#16
this is situation with oauth2client 2.0 and endpoints 2.0
File "default/src/libs/google/api/gen/servicecontrol_v1_messages.py", line 25, in <module> from apitools.base.py import encoding File "default/src/libs/apitools/base/py/__init__.py", line 22, in <module> from apitools.base.py.credentials_lib import * File "default/src/libs/apitools/base/py/credentials_lib.py", line 28, in <module> import oauth2client.gce ImportError: No module named gce
Looking if this would be updates. We are not happy to run the product domain in appspot.com for more than a year, for choosing clound endpoints.
Currently this project is pinned to require oauth2client==3.0.0
, however the most recent version is 4.1.2
. There were security and stability improvements made in this package since 3.0.0
was released. Shouldn't this package be updated to support and use the newest version.
I appreciate that oauth2client
is now deprecated and that going forward this project should favour using google-auth and oauthlib. But until time is found to update this project to use those two libraries, we should at the very least use the latest stable release of oauth2client
?
Thanks!
/base/data/home/apps/s~app/v2.405240549392103317/lib/urllib3/contrib/appengine.py:115: AppEnginePlatformWarning: urllib3 is using URLFetch on Google App Engine sandbox instead of sockets. To use sockets directly instead of URLFetch see https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html. AppEnginePlatformWarning)
This error is from the internal library and I am not interested to see this error then why it is highlighted as an error, please suppress it with a warning or fix the error.
Note:
ESP allows passing an API key using the x-api-key
header but the functionality is lacking in endpoints framework.
urllib3 just upgraded to 1.24 and I believe this is breaking endpointscfg.py. Here is the stacktrace:
python ../lib/endpoints/endpointscfg.py get_openapi_spec main_endpoints.PublicApi --hostname api-dot-${PROJECTFULL} --x-google-api-name
/opt/atlassian/pipelines/agent/build/api/lib/requests/init.py:91: RequestsDependencyWarning: urllib3 (1.24) or chardet (3.0.4) doesn't match a supported version!
RequestsDependencyWarning)
Traceback (most recent call last):
File "../lib/endpoints/endpointscfg.py", line 28, in
from endpoints._endpointscfg_impl import main
File "/opt/atlassian/pipelines/agent/build/api/lib/endpoints/init.py", line 33, in
from .apiserving import *
File "/opt/atlassian/pipelines/agent/build/api/lib/endpoints/apiserving.py", line 71, in
from endpoints_management.control import client as control_client
File "/opt/atlassian/pipelines/agent/build/api/lib/endpoints_management/init.py", line 19, in
from . import auth, config, control, gen
File "/opt/atlassian/pipelines/agent/build/api/lib/endpoints_management/auth/init.py", line 19, in
from . import suppliers, tokens
File "/opt/atlassian/pipelines/agent/build/api/lib/endpoints_management/auth/suppliers.py", line 21, in
from jwkest import jwk
File "/opt/atlassian/pipelines/agent/build/api/lib/jwkest/jwk.py", line 16, in
from requests import request
File "/opt/atlassian/pipelines/agent/build/api/lib/requests/init.py", line 112, in
from . import utils
File "/opt/atlassian/pipelines/agent/build/api/lib/requests/utils.py", line 26, in
from ._internal_utils import to_native_string
File "/opt/atlassian/pipelines/agent/build/api/lib/requests/_internal_utils.py", line 11, in
from .compat import is_py2, builtin_str, str
File "/opt/atlassian/pipelines/agent/build/api/lib/requests/compat.py", line 48, in
from urllib3.packages.ordered_dict import OrderedDict
ImportError: No module named ordered_dict
I sent a request with no API key to an API that requires an API key, and I caught the following error.
( I expected HTTP status code 401, but actually 500 was returned. )
Traceback (most recent call last):
File "/base/data/home/runtimes/python27_experiment/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 267, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/base/data/home/apps/b~gae-service-samples/cloud-endpoints-framework:1.401219152325622663/lib/endpoints_management/control/wsgi.py", line 199, in __call__
return self._application(environ, start_response)
File "/base/data/home/apps/b~gae-service-samples/cloud-endpoints-framework:1.401219152325622663/lib/endpoints_management/control/wsgi.py", line 606, in __call__
response = self._application(environ, start_response)
File "/base/data/home/apps/b~gae-service-samples/cloud-endpoints-framework:1.401219152325622663/lib/endpoints_management/control/wsgi.py", line 282, in __call__
error_msg = self._handle_missing_api_key(app_info, start_response)
File "/base/data/home/apps/b~gae-service-samples/cloud-endpoints-framework:1.401219152325622663/lib/endpoints_management/control/wsgi.py", line 411, in _handle_missing_api_key
start_response(error_msg, [])
File "/base/data/home/runtimes/python27_experiment/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 180, in _StartResponse
(_GetTypeName(status), status))
InvalidResponseError: status must be a str, got 'unicode' (u'401 Method does not allow callers without established identity. Please use an API key or other form of API consumer identity to call this API.')
I think that it is the cause of this error that _handle_missing_api_key() and _handle_check_response() pass the wrong value to start_response().
In the specification of wsgi, start_response() expects str to be passed to the first parameter, but now unicode is passed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.