Robot Framework ConnectionError Handling Syntax - error-handling

import requests
def make_request():
try:
url = 'https://reqres.in/api/users'
response = requests.get(url)
parsed = response.json()
print(parsed)
except requests.exceptions.ConnectionError:
# 👇️ handle error here or use a `pass` statement
print('connection error occurred')
make_request()
I know how to have try and except block in python using
requests.exceptions.ConnectionError:
but using the same is not syntactically correct in Robot Framework.
I am using the RequestsLibrary in Robot Framework.

Related

Robot Framework handling ConnectionError Message with try and catch

import requests
def make_request():
try:
url = 'https://reqres.in/api/users'
response = requests.get(url)
parsed = response.json()
print(parsed)
except requests.exceptions.ConnectionError:
# 👇️ handle error here or use a `pass` statement
print('connection error occurred')
make_request()
The above code works in python but I need a try and except block in robot framework I am using the RequestsLibrary. Any help is appreciated!

Custom general error handler for Flask API server [duplicate]

Is there a way to add a global catch-all error handler in which I can change the response to a generic JSON response?
I can't use the got_request_exception signal, as it is not allowed to modify the response (http://flask.pocoo.org/docs/0.10/signals/).
In contrast all signal handlers are executed in undefined order and do not modify any data.
I would prefer to not wrap the app.handle_exception function as that feels like internal API. I guess I'm after something like:
#app.errorhandler()
def handle_global_error(e):
return "Global error"
Note the errorhandler does not take any parameters, meaning it would catch all exceptions/status codes which does not have a specific error handler attached to them. I know I can use errorhandler(500) or errorhandler(Exception) to catch exceptions, but if I do abort(409) for example, it will still return a HTML response.
You can use #app.errorhandler(Exception):
Demo (the HTTPException check ensures that the status code is preserved):
from flask import Flask, abort, jsonify
from werkzeug.exceptions import HTTPException
app = Flask('test')
#app.errorhandler(Exception)
def handle_error(e):
code = 500
if isinstance(e, HTTPException):
code = e.code
return jsonify(error=str(e)), code
#app.route('/')
def index():
abort(409)
app.run(port=1234)
Output:
$ http get http://127.0.0.1:1234/
HTTP/1.0 409 CONFLICT
Content-Length: 31
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:54 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "409: Conflict"
}
$ http get http://127.0.0.1:1234/notfound
HTTP/1.0 404 NOT FOUND
Content-Length: 32
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:58 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "404: Not Found"
}
If you also want to override the default HTML exceptions from Flask (so that they also return JSON), add the following before app.run:
from werkzeug.exceptions import default_exceptions
for ex in default_exceptions:
app.register_error_handler(ex, handle_error)
For older Flask versions (<=0.10.1, i.e. any non-git/master version at the moment), add the following code to your application to register the HTTP errors explicitly:
from werkzeug import HTTP_STATUS_CODES
for code in HTTP_STATUS_CODES:
app.register_error_handler(code, handle_error)
This is Flask 0.12 compatible, and a very good solution to the problem (it allows one to render errors in JSON or any other format)
from functools import wraps
from flask import Flask, redirect, jsonify
app = Flask(__name__)
def get_http_exception_handler(app):
"""Overrides the default http exception handler to return JSON."""
handle_http_exception = app.handle_http_exception
#wraps(handle_http_exception)
def ret_val(exception):
exc = handle_http_exception(exception)
return jsonify({'code':exc.code, 'message':exc.description}), exc.code
return ret_val
# Override the HTTP exception handler.
app.handle_http_exception = get_http_exception_handler(app)
https://github.com/pallets/flask/issues/671#issuecomment-12746738
Far from elegant, but the following works for tying all subclasses of HTTPException to a single error handler:
from flask import jsonify
from werkzeug.exceptions import HTTPException
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error='error', code=code)
for cls in HTTPException.__subclasses__():
app.register_error_handler(cls, handle_error)
A cleaner way to implement this in Flask >=0.12 would be to explicitly register the handler for every Werkzeug exception:
from flask import jsonify
from werkzeug.exceptions import HTTPException, default_exceptions
app = Flask('test')
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error='error', code=code)
for exc in default_exceptions:
app.register_error_handler(exc, handle_error)
It is possible to register error handlers for very generic base classes such as HTTPException or even Exception. However, be aware that these will catch more than you might expect.
For example, an error handler for HTTPException might be useful for turning the default HTML errors pages into JSON. However, this handler will trigger for things you don’t cause directly, such as 404 and 405 errors during routing. Be sure to craft your handler carefully so you don’t lose information about the HTTP error.
from flask import Flask, abort, jsonify, json
from werkzeug.exceptions import HTTPException
app = Flask('test')
app.config['JSON_SORT_KEYS'] = False
#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({
"error": {
"code": e.code,
"name": e.name,
"description": e.description,
}
})
print(response.data)
response.content_type = "application/json"
return response
#app.route('/')
def index():
abort(409)
#app.route('/aloha')
def aloha():
abort(400, "I'm not in the mood to talk!")
app.run(port=1234)
output:
An error handler for Exception might seem useful for changing how all errors, even unhandled ones, are presented to the user. However, this is similar to doing except Exception: in Python, it will capture all otherwise unhandled errors, including all HTTP status codes.
In most cases it will be safer to register handlers for more specific exceptions. Since HTTPException instances are valid WSGI responses, you could also pass them through directly.
from werkzeug.exceptions import HTTPException
#app.errorhandler(Exception)
def handle_exception(e):
# pass through HTTP errors
if isinstance(e, HTTPException):
return e
# now you're handling non-HTTP exceptions only
return render_template("500_generic.html", e=e), 500
Error handlers still respect the exception class hierarchy. If you register handlers for both HTTPException and Exception, the Exception handler will not handle HTTPException subclasses because it the HTTPException handler is more specific.
Based on
Plain (non-HTML) error pages in REST api
I wanted to return json without changing any of my code at all, so I just added the following on the top of my code
#app.errorhandler(500)
def error_500(exception):
return jsonify({"error": str(exception)}), 500, {'Content-Type': 'application/json'}
#app.errorhandler(400)
def error_400(exception):
return jsonify({"error": str(exception)}), 400, {'Content-Type': 'application/json'}
If the Exceptions doesn't work, you may try app.register_error_handler (or use app.errorhandler in a non-decorator way)
Source: https://github.com/pallets/flask/issues/1837

Scrapy error: TypeError: __init__() got an unexpected keyword argument 'cb_kwargs'

I use scrapy to parse the site. Scrapy version 2.1.0
when I try to make an additional request:
taglines_request = Request(url=tagline_url,
callback=self.get_tags_and_awards,
cb_kwargs={'item':item, 'awards_url': awards_url})
I get the following error:
TypeError: __init__() got an unexpected keyword argument 'cb_kwargs'
But in the __init __ () method, there is a cb_kwargs parameter. Tell me, please, what could be the problem?
I launch through ScrapyD
I think the problem here is that you are passing cb_kwargs to Request which Request in turn doesn't accept. From what I understand, cb_kwargs is new in Scrapy version 1.7, so you should check again if ScrapyD in your case is working with a version of Scrapy >= 1.7.
Alternatively, to pass data to your callback, you could use Request's meta attribute.
taglines_request = Request(
url=tagline_url,
callback=self.get_tags_and_awards,
meta={
'item':item,
'awards_url': awards_url
}
)
You can then access the data from your response via meta.
def get_tags_and_awards(self, response):
item = response.meta['item']
awards_url = response.meta['awards_url']

create simple api with python to catch post request

I have developed a python plugin which is capable of sending log file in json format
in mm code i have used requests.post(url, data={})
what will be the api structure that catch this data and will be available for
send anywhere with GET request
If you are fairly new to web programming I would suggest using a lightweight framework like Flask. With it you can define custom paths that your server accepts requests on as follows:
from flask import Flask
from flask import request, jsonify
app = Flask(__name__)
log_file = None
#app.route("/api/logfile", methods=['GET', 'POST'])
def post_logfile():
if request.method == 'GET':
if log_file is not None:
return "Log file not instantiated yet", 404
else:
return jsonify(log_file)
elif request.method == 'POST':
log_file = request.form
if log_file is not None:
# log_file variable will have all the information
# from the JSON log file
return "Ok"
else:
return "No data provided", 400
if __name__ == "__main__":
app.run(port=9000)
As you can see, we have a global variable log_file which will be used to store the JSON logfile data, and a function that accepts both POST and GET requests and acts accordingly. If a GET request is sent, it checks if log_file variable is assigned. If so, it returns the log file as a JSON file else it return a 404 error. If a POST request is sent it checks if it has the log file and stores in the log_file variable, making it useful for all subsequent GET requests.
The URL used are:
localhost:9000/api/logfile
And you only need to change the method of the request(e.g. POST or GET)

HttpResponseRedirect' object has no attribute 'client'

Django 1.9.6
I'd like to write some unit test for checking redirection.
Could you help me understand what am I doing wrongly here.
Thank you in advance.
The test:
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.http.request import HttpRequest
from django.contrib.auth.models import User
class GeneralTest(TestCase):
def test_anonymous_user_redirected_to_login_page(self):
user = User(username='anonymous', email='vvv#mail.ru', password='ttrrttrr')
user.is_active = False
request = HttpRequest()
request.user = user
hpv = HomePageView()
response = hpv.get(request)
self.assertRedirects(response, reverse("auth_login"))
The result:
ERROR: test_anonymous_user_redirected_to_login_page (general.tests.GeneralTest)
Traceback (most recent call last):
File "/home/michael/workspace/photoarchive/photoarchive/general/tests.py", line 44, in test_anonymous_user_redirected_to_login_page
self.assertRedirects(response, reverse("auth_login"))
File "/home/michael/workspace/venvs/photoarchive/lib/python3.5/site-packages/django/test/testcases.py", line 326, in assertRedirects
redirect_response = response.client.get(path, QueryDict(query),
AttributeError: 'HttpResponseRedirect' object has no attribute 'client'
Ran 3 tests in 0.953s
What pdb says:
-> self.assertRedirects(response, reverse("auth_login"))
(Pdb) response
<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/accounts/login/">
You need to add a client to the response object. See the updated code below.
from django.test import TestCase, Client
from django.core.urlresolvers import reverse
from django.http.request import HttpRequest
from django.contrib.auth.models import User
class GeneralTest(TestCase):
def test_anonymous_user_redirected_to_login_page(self):
user = User(username='anonymous', email='vvv#mail.ru', password='ttrrttrr')
user.is_active = False
request = HttpRequest()
request.user = user
hpv = HomePageView()
response = hpv.get(request)
response.client = Client()
self.assertRedirects(response, reverse("auth_login"))
Looks like you are directly calling your view's get directly rather than using the built-in Client. When you use the test client, you get your client instance back in the response, presumably for cases such as this where you want to check/fetch a redirect.
One solution would be to use the client to fetch the response from your view. Another is to stick a client in the response as mentioned above.
A third option is tell assertRedirects not to fetch the redirect. There is no need for client if you don't ask the assertion to fetch the redirect. That's done by adding fetch_redirect_response=False to your assertion.