How to access Google Cloud Endpoints request header in Python and Java - google-app-engine

In the endpoints method, how to access request header information?

Python:
In the endpoint method, self.request_state.headers provides this information.
E.g., self.request_state.headers.get('authorization')
Java:
Add an HttpServletRequest (req) parameter to your endpoint method. The headers are accessible through the method getHeader()
e.g., req.getHeader("Authorization")
See this question

What is working for me in python is the following:
The request I use: http://localhost:8080/api/hello/v1/header?message=Hello World!
python code:
#endpoints.api(name='hello', version='v1', base_path='/api/')
class EchoApi(remote.Service):
#endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='header',
http_method='GET',
name='header')
def header(self, request):
header = request._Message__unrecognized_fields
output_message = header.get(u'message', None)[0]
return EchoResponse(message=output_message)

Related

No api proxy found for service "memcache" GAE unittest2

I'am trying to write tests to my app. I make a simple test case:
def test_put(self):
Result(
id="23738",
target_id="23738",
).put()
and after running, it raises an error:
AssertionError: No api proxy found for service "memcache"
I don't know, how to fix it.
And this is my set_up:
def set_up(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
self.testbed.init_datastore_v3_stub()
self.testbed.init_memcache_stub()
self.testbed.init_user_stub()
and tear_down:
def tear_down(self):
self.testbed.deactivate()
The function names in your code are:
def set_up(self):
...
def tear_down(self):
...
However, according to the Python unittest documentation, the proper names are setUp and tearDown (note the lack of underscore and camelCase).
You can see similar uses of the functions in the AppEngine Python local unit testing documentation.

Error 405 Method not allowed

I am desgining a web app using google app engine and python and
While extracting the form data ie. parameter values using the get request the following error occurs during the runtime:
405 Method Not Allowed
The method GET is not allowed for this resource.
Following is the code:
is the get mothos creating problem or is there any other solution to get parameter values.
class PostBody(webapp2.RequestHandler):
def post(self):
stringContent=cgi.escape(self.request.get('txtLocation'))
stringurl='http://maps.googleapis.com/maps/api/place/textsearch/json?query='|stringContent|'&sensor=false&key=mykey'
result=json.load(urllib.urlopen(stringurl))
self.response.write(result)
Thanks...
Try replacing
def post(self)
by
def get(self)

scrapy how to set referer url

I need to set the referer url, before scraping a site, the site uses refering url based Authentication, so it does not allow me to login if the referer is not valid.
Could someone tell how to do this in Scrapy?
If you want to change the referer in your spider's request, you can change DEFAULT_REQUEST_HEADERS in the settings.py file:
DEFAULT_REQUEST_HEADERS = {
'Referer': 'http://www.google.com'
}
You should do exactly as #warwaruk indicated, below is my example elaboration for a crawl spider:
from scrapy.spiders import CrawlSpider
from scrapy import Request
class MySpider(CrawlSpider):
name = "myspider"
allowed_domains = ["example.com"]
start_urls = [
'http://example.com/foo'
'http://example.com/bar'
'http://example.com/baz'
]
rules = [(...)]
def start_requests(self):
requests = []
for item in self.start_urls:
requests.append(Request(url=item, headers={'Referer':'http://www.example.com/'}))
return requests
def parse_me(self, response):
(...)
This should generate following logs in your terminal:
(...)
[myspider] DEBUG: Crawled (200) <GET http://example.com/foo> (referer: http://www.example.com/)
(...)
[myspider] DEBUG: Crawled (200) <GET http://example.com/bar> (referer: http://www.example.com/)
(...)
[myspider] DEBUG: Crawled (200) <GET http://example.com/baz> (referer: http://www.example.com/)
(...)
Will work same with BaseSpider. In the end start_requests method is BaseSpider method, from which CrawlSpider inherits from.
Documentation explains more options to be set in Request apart from headers, such as: cookies , callback function, priority of the request etc.
Just set Referer url in the Request headers
class scrapy.http.Request(url[, method='GET', body, headers, ...
headers (dict) – the headers of this request. The dict values can be strings (for single valued headers) or lists (for multi-valued headers).
Example:
return Request(url=your_url,
headers={'Referer':'http://your_referer_url'})
Override BaseSpider.start_requests and create there your custom Request passing it your referer header.

flask: error_handler for blueprints

Can error_handler be set for a blueprint?
#blueprint.errorhandler(404)
def page_not_found(error):
return 'This page does not exist', 404
edit:
https://github.com/mitsuhiko/flask/blob/18413ed1bf08261acf6d40f8ba65a98ae586bb29/flask/blueprints.py
you can specify an app wide and a blueprint local error_handler
You can use Blueprint.app_errorhandler method like this:
bp = Blueprint('errors', __name__)
#bp.app_errorhandler(404)
def handle_404(err):
return render_template('404.html'), 404
#bp.app_errorhandler(500)
def handle_500(err):
return render_template('500.html'), 500
errorhandler is a method inherited from Flask, not Blueprint.
If you are using Blueprint, the equivalent is app_errorhandler.
The documentation suggests the following approach:
def app_errorhandler(self, code):
"""Like :meth:`Flask.errorhandler` but for a blueprint. This
handler is used for all requests, even if outside of the blueprint.
"""
Therefore, this should work:
from flask import Blueprint, render_template
USER = Blueprint('user', __name__)
#USER.app_errorhandler(404)
def page_not_found(e):
""" Return error 404 """
return render_template('404.html'), 404
On the other hand, while the approach below did not raise any error for me, it didn't work:
from flask import Blueprint, render_template
USER = Blueprint('user', __name__)
#USER.errorhandler(404)
def page_not_found(e):
""" Return error 404 """
return render_template('404.html'), 404
add error handling at application level using the request proxy object:
from flask import request,jsonify
#app.errorhandler(404)
#app.errorhandler(405)
def _handle_api_error(ex):
if request.path.startswith('/api/'):
return jsonify(ex)
else:
return ex
flask Documentation
I too couldn't get the top rated answer to work, but here's a workaround.
You can use a catch-all at the end of your Blueprint, not sure how robust/recommended it is, but it does work. You could also add different error messages for different methods too.
#blueprint.route('/<path:path>')
def page_not_found(path):
return "Custom failure message"
Surprised others didn't mention miguelgrinberg's excellent tutorial.
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vii-error-handling
I found the sentry framework for error handling (links below). Seems overly complex. not sure of the threshold where it becomes useful.
https://flask.palletsprojects.com/en/1.1.x/errorhandling/
https://docs.sentry.io/platforms/python/guides/flask/
I combined previous excellent answers with the official docs from Flask, section 'Returning API Errors as JSON', in order to provide a more general approach.
Here is a working PoC that you can copy and paste on your registered blueprint API route handler (e.g. app/api/routes.py):
#blueprint.app_errorhandler(HTTPException)
def handle_exception(e):
"""Return JSON instead of HTML for HTTP errors."""
# start with the correct headers and status code from the error
response = e.get_response()
# replace the body with JSON
response.data = json.dumps({
"code": e.code,
"name": e.name,
"description": e.description,
})
response.content_type = "application/json"
return response
Flask doesnt support blueprint level error handlers for 404 and 500 errors. A BluePrint is a leaky abstraction. Its better to use a new WSGI App for this, if you need separate error handlers, this makes more sense.
Also i would recommend not to use flask, it uses globals all over the places, which makes your code difficult to manage if it grows bigger.

Handle webapp2 404 error in requesthandler class method instead of in a function

I'm using the webapp2 framework in Google App Engine (Python). In webapp2 exception handling: exceptions in the WSGI app it's described how to handle 404 errors in a function:
import logging
import webapp2
def handle_404(request, response, exception):
logging.exception(exception)
response.write('Oops! I could swear this page was here!')
response.set_status(404)
def handle_500(request, response, exception):
logging.exception(exception)
response.write('A server error occurred!')
response.set_status(500)
app = webapp2.WSGIApplication([
webapp2.Route('/', handler='handlers.HomeHandler', name='home')
])
app.error_handlers[404] = handle_404
app.error_handlers[500] = handle_500
How can I handle the 404 error in a webapp2.RequestHandler class, in the .get() method of that class?
Edit:
The reason I want to call a RequestHandler is to access the session (request.session). Otherwise I'm not able to pass the current user to the template of the 404 error page. i.e. on the StackOverflow 404 error page you can see your username. I would like to display the username of the current user on my website's 404 error page as well. Is this possible in a function or does it has to be a RequestHandler?
Correct code based on #proppy's answer:
class Webapp2HandlerAdapter(webapp2.BaseHandlerAdapter):
def __call__(self, request, response, exception):
request.route_args = {}
request.route_args['exception'] = exception
handler = self.handler(request, response)
return handler.get()
class Handle404(MyBaseHandler):
def get(self):
self.render(filename="404.html",
page_title="404",
exception=self.request.route_args['exception']
)
app = webapp2.WSGIApplication(urls, debug=True, config=config)
app.error_handlers[404] = Webapp2HandlerAdapter(Handle404)
The calling convention of error handler and request handler callables are different:
error_handlers takes (request, response, exception)
RequestHandler takes (request, response)
You may use something similar to Webapp2HandlerAdapter to adapt a webapp2.RequestHandler to a callable.
class Webapp2HandlerAdapter(BaseHandlerAdapter):
"""An adapter to dispatch a ``webapp2.RequestHandler``.
The handler is constructed then ``dispatch()`` is called.
"""
def __call__(self, request, response):
handler = self.handler(request, response)
return handler.dispatch()
But you would have to sneak the extra exception argument in request route_args.

Resources