Related
I am working at a simple webpage with Python and Flask and getting this error. I have hit a roadblock and cannot seem to figure out what is wrong with the code.
The error occurs when I am trying to log in. All the other functions work as intended. Once I press the login button the error pops.
The error:
127.0.0.1 - - [23/Oct/2018 17:14:46] "POST /login HTTP/1.1" 500 -
Traceback (most recent call last):
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1816, in full_dispatch_request
return self.finalize_request(rv)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1833, in finalize_request
response = self.process_response(response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2114, in process_response
self.session_interface.save_session(self, ctx.session, response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\sessions.py", line 375, in save_session
val = self.get_signing_serializer(app).dumps(dict(session))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py", line 114, in dumps
payload = want_bytes(self.dump_payload(obj))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\url_safe.py", line 42, in dump_payload
json = super(URLSafeSerializerMixin, self).dump_payload(obj)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py", line 99, in dump_payload
return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\tag.py", line 296, in dumps
return dumps(self.tag(value), separators=(',', ':'))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py", line 179, in dumps
rv = _json.dumps(obj, **kwargs)
File "D:\Programe\Anaconda\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py", line 81, in default
return _json.JSONEncoder.default(self, o)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'OperationalError' is not JSON serializable
Browser error:
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2309,in __call__
def __call__(self, environ, start_response):
"""The WSGI server calls the Flask application object as the
WSGI application. This calls :meth:`wsgi_app` which can be
wrapped to applying middleware."""
return self.wsgi_app(environ, start_response)
def __repr__(self):
return '<%s %r>' % (
self.__class__.__name__,
self.name,
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2295,in wsgi_app
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1741,in handle_exception
# if we want to repropagate the exception, we can attempt to
# raise it with the whole traceback in case we can do that
# (the function was actually called from the except part)
# otherwise, we just raise the error again
if exc_value is e:
reraise(exc_type, exc_value, tb)
else:
raise e
self.log_exception((exc_type, exc_value, tb))
if handler is None:
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\_compat.py",line 35,in reraise
from io import StringIO
def reraise(tp, value, tb=None):
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
implements_to_string = _identity
else:
text_type = unicode
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2292,in wsgi_app
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1816,in full_dispatch_request
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)
def finalize_request(self, rv, from_error_handler=False):
"""Given the return value from a view function this finalizes
the request by converting it into a response and invoking the
postprocessing functions. This is invoked for both normal
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1833,in finalize_request
:internal:
"""
response = self.make_response(rv)
try:
response = self.process_response(response)
request_finished.send(self, response=response)
except Exception:
if not from_error_handler:
raise
self.logger.exception('Request finalizing failed with an '
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2114,in process_response
if None in self.after_request_funcs:
funcs = chain(funcs, reversed(self.after_request_funcs[None]))
for handler in funcs:
response = handler(response)
if not self.session_interface.is_null_session(ctx.session):
self.session_interface.save_session(self, ctx.session, response)
return response
def do_teardown_request(self, exc=_sentinel):
"""Called after the request is dispatched and the response is
returned, right before the request context is popped.
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\sessions.py",line 375,in save_session
httponly = self.get_cookie_httponly(app)
secure = self.get_cookie_secure(app)
samesite = self.get_cookie_samesite(app)
expires = self.get_expiration_time(app, session)
val = self.get_signing_serializer(app).dumps(dict(session))
response.set_cookie(
app.session_cookie_name,
val,
expires=expires,
httponly=httponly,
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py",line 114,in dumps
def dumps(self, obj, salt=None):
"""Returns a signed string serialized with the internal
serializer. The return value can be either a byte or unicode
string depending on the format of the internal serializer.
"""
payload = want_bytes(self.dump_payload(obj))
rv = self.make_signer(salt).sign(payload)
if self.is_text_serializer:
rv = rv.decode("utf-8")
return rv
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\url_safe.py",line 42,in dump_payload
original_error=e,
)
return super(URLSafeSerializerMixin, self).load_payload(json, *args, **kwargs)
def dump_payload(self, obj):
json = super(URLSafeSerializerMixin, self).dump_payload(obj)
is_compressed = False
compressed = zlib.compress(json)
if len(compressed) < (len(json) - 1):
json = compressed
is_compressed = True
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py",line 99,in dump_payload
def dump_payload(self, obj):
"""Dumps the encoded object. The return value is always bytes.
If the internal serializer returns text, the value will be
encoded as UTF-8.
"""
return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
def make_signer(self, salt=None):
"""Creates a new instance of the signer to be used. The default
implementation uses the :class:`.Signer` base class.
"""
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\tag.py",line 296,in dumps
return self.tags[key].to_python(value[key])
def dumps(self, value):
"""Tag the value and dump it to a compact JSON string."""
return dumps(self.tag(value), separators=(',', ':'))
def loads(self, value):
"""Load data from a JSON string and deserialized any tagged objects."""
return loads(value, object_hook=self.untag)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py",line 179,in dumps
default is controlled by the ``JSON_AS_ASCII`` configuration variable
and can be overridden by the simplejson ``ensure_ascii`` parameter.
"""
_dump_arg_defaults(kwargs)
encoding = kwargs.pop('encoding', None)
rv = _json.dumps(obj, **kwargs)
if encoding is not None and isinstance(rv, text_type):
rv = rv.encode(encoding)
return rv
File "D:\Programe\Anaconda\lib\json\__init__.py",line 238,in dumps
cls = JSONEncoder
return cls(
skipkeys=skipkeys, ensure_ascii=ensure_ascii,
check_circular=check_circular, allow_nan=allow_nan, indent=indent,
separators=separators, default=default, sort_keys=sort_keys,
**kw).encode(obj)
_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None)
File "D:\Programe\Anaconda\lib\json\encoder.py",line 199,in encode
else:
return encode_basestring(o)
# This doesn't pass the iterator directly to ''.join() because the
# exceptions aren't as detailed. The list call should be roughly
# equivalent to the PySequence_Fast that ''.join() would do.
chunks = self.iterencode(o, _one_shot=True)
if not isinstance(chunks, (list, tuple)):
chunks = list(chunks)
return ''.join(chunks)
def iterencode(self, o, _one_shot=False):
File "D:\Programe\Anaconda\lib\json\encoder.py",line 257,in iterencode
else:
_iterencode = _make_iterencode(
markers, self.default, _encoder, self.indent, floatstr,
self.key_separator, self.item_separator, self.sort_keys,
self.skipkeys, _one_shot)
return _iterencode(o, 0)
def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
_key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
## HACK: hand-optimized bytecode; turn globals into locals
ValueError=ValueError,
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py",line 81,in default
return http_date(o.timetuple())
if isinstance(o, uuid.UUID):
return str(o)
if hasattr(o, '__html__'):
return text_type(o.__html__())
return _json.JSONEncoder.default(self, o)
class JSONDecoder(_json.JSONDecoder):
"""The default JSON decoder. This one does not change the behavior from
the default simplejson decoder. Consult the :mod:`json` documentation
File "D:\Programe\Anaconda\lib\json\encoder.py",line 180,in default
# Let the base class default method raise the TypeError
return JSONEncoder.default(self, o)
"""
raise TypeError("Object of type '%s' is not JSON serializable" %
o.__class__.__name__)
def encode(self, o):
"""Return a JSON string representation of a Python data structure.
>>> from json.encoder import JSONEncoder
TypeError: Object of type 'OperationalError' is not JSON serializable
The code:
from flask import Flask, render_template, session, redirect,request, flash,
session, url_for
from functools import wraps
import sqlite3
from sqlite3 import Error
import pdb
app = Flask( __name__ )
app.secret_key = "super secret key"
def SQL_Connect(db_file):
try:
conn = sqlite3.connect(db_file)
return conn
except Error as e:
print(e)
return None
# SQL_Create - Create the tables for the SQL database, only needs to be ran once
def SQL_Create(conn):
cur = conn.cursor()
with open('SQL.sql') as fp:
cur.executescript(fp.read())
def SQL_Test(conn):
cur = conn.cursor()
cur.execute("SELECT * FROM users")
rows = cur.fetchall()
for row in rows:
print(row)
def SQL_GetUserByID(conn, id):
cur = conn.cursor()
cur.execute("SELECT firstname FROM users WHERE userid = " + str( id ) )
result = cur.fetchall()
# I am awful code, please fix me
return str( result[0][0] )
def SQL_Threads(conn):
cur = conn.cursor()
cur.execute("SELECT * FROM reviews")
rows = list(cur)
list_of_lists = [list(elem) for elem in rows]
for row in list_of_lists:
AuthorID = row[4]
AuthorName = SQL_GetUserByID(conn, AuthorID )
row[4] = AuthorName
return list_of_lists
def SQL_Load():
database = "database.db"
conn = SQL_Connect(database)
with conn:
# SQL_Create(conn)
SQL_Test(conn)
return conn
#app.route( "/SQL_AddUser", methods=["POST"] )
def SQL_AddUser():
Connection = SQL_Load()
firstname2 = request.form['inputName']
lastname2 = request.form['inputSurname']
email2 = request.form['inputEmail']
password2 = request.form['inputPassword']
cur = Connection.cursor()
cur.execute("INSERT INTO users (firstname, lastname, email, password) VALUES(?, ?, ?, ?)",(firstname2,lastname2,email2,password2))
Connection.commit()
session['logged_in'] = True
session['sessionEmail'] = email2
return render_template("index.html")
#app.route('/index')
#app.route("/")
def index():
Connection = SQL_Load()
LoadReviews = SQL_Threads(Connection)
Title = LoadReviews[0][1]
Date = LoadReviews[0][2]
Rating = LoadReviews[0][3]
Author = LoadReviews[0][4]
Text = LoadReviews[0][5]
return render_template( "index.html", title = Title, date = Date, rating = Rating, author = Author, text = Text )
#app.route('/login', methods=["GET", "POST"])
def login():
error = ''
try:
connection = SQL_Load()
cur = connection.cursor()
if request.method == "POST":
data = cur.execute("SELECT password FROM users WHERE email= (%s)",(request.form['inputEmail']))
if request.form['password'] == data:
session['logged_in'] = True
session['sessionEmail'] = request.form['inputEmail']
flash("You are now logged in")
return redirect(url_for("/"))
else:
error = "Invalid credentials, try again."
return render_template("login.html", error=error)
except Exception as e:
flash(e)
error = "Invalid credentials, try again."
return render_template("login.html", error=error)
#app.route('/register')
def register():
return render_template("register.html")
#app.route("/logout/")
def logout():
if 'logged_in' in session:
session.clear()
flash("You have been logged out!")
return redirect(url_for('index'))
else:
flash("You need to login first")
return redirect(url_for('login'))
if __name__ == "__main__":
app.run(debug=True)
I know that the code is a mess at the moment so sorry for that. I have searched everywhere and no luck.
There appear to be two separate errors in your code, the first is in the sql within the login function and the second is within your error handling code which is why the error message you see bears no relation to the initial error. The first error is in the statement
data = cur.execute("SELECT password FROM users WHERE email= (%s)",(request.form['inputEmail']))
The python sqlite3 module uses ? as a parameter placeholder not %s. The second argument to the execute function also needs to be an iterable, given that there is only a single parameter there needs to be a comma after it so that the python interpreter knows that the surrounding parentheses signify a tuple.The following code should work
data = cur.execute("SELECT password FROM users WHERE email= ?", (request.form['inputEmail'],))
The error here results in an sqlite3.OperationalError which you catch with your "except Exception as e" statement. You then pass the error object directly to the flask flash function rather than a string hence the flask error message that an object of type OperationalError is not serializable. I would recommend avoiding the except Exception statement entirely and limiting exception handling to only the specific exceptions that you know could occur in that function. You can set up a custom error handler to handle all unexpected errors as per the flask documentation http://flask.pocoo.org/docs/1.0/patterns/errorpages/ which should be safer than catch all handlers in each function.
So I'm trying get auto-complete to work with python-ldap and flask.
Here's a test script ldapA.py:
import ldap
#first you must open a connection to the server
def query():
try:
l = ldap.open("server.net")
## searching doesn't require a bind in LDAP V3. If you're using LDAP v2, set the next line appropriately
## and do a bind as shown in the above example.
# you can also set this to ldap.VERSION2 if you're using a v2 directory
# you should set the next option to ldap.VERSION2 if you're using a v2 directory
l.protocol_version = ldap.VERSION3
l.set_option(ldap.OPT_REFERRALS, 0)
username="CN=user user,OU=bbbgbg,OU=bdbfd,DC=dsffd,DC=net"
passw="adsada"
l.simple_bind_s(username,passw)
except ldap.LDAPError, e:
print e
# handle error however you like
## The next lines will also need to be changed to support your search requirements and directory
baseDN = "ou=xds, ou=sd, dc=sd, dc=net"
searchScope = ldap.SCOPE_SUBTREE
## retrieve all attributes - again adjust to your needs - see documentation for more options
retrieveAttributes = ['name']
searchFilter = "name=*jace*"
try:
ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
result_set = []
while 1:
result_type, result_data = l.result(ldap_result_id, 0)
if (result_data == []):
break
else:
## here you don't have to append to a list
## you could do whatever you want with the individual entry
## The appending to list is just for illustration.
if result_type == ldap.RES_SEARCH_ENTRY:
result_set.append(result_data)
res = result_set[0]
res1 = res[0]
res2 = res1[1]
res3 = res2["name"]
print res3[0]
except ldap.LDAPError, e:
print e
query()
It works as intended when I run it. It gives me my name from the AD.
Now when I call it from flask like this:
from flask import render_template
from app import app
from flask import request
from ldapA import query
#app.route('/')
#app.route('/index')
def index():
return render_template("index.html")
#app.route('/autocomplete', methods=['GET'])
def autocomplete():
return query()
I get:
127.0.0.1 - - [19/Jul/2017 14:08:58] "GET /autocomplete HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/jgar/receptionsignin/app/views.py", line 13, in autocomplete
return query()
File "/home/jgar/receptionsignin/ldapA.py", line 36, in query
result_type, result_data = l.result(ldap_result_id, 0)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 703, in result
resp_type, resp_data, resp_msgid = self.result2(msgid,all,timeout)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 707, in result2
resp_type, resp_data, resp_msgid, resp_ctrls = self.result3(msgid,all,timeout)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 714, in result3
resp_ctrl_classes=resp_ctrl_classes
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 734, in result4
resp_data = self._bytesify_results(resp_data, with_ctrls=add_ctrls)
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 266, in _bytesify_results
for (dn, fields) in results
File "/home/jgar/receptionsignin/flask/lib/python2.7/site-packages/ldap/ldapobject.py", line 219, in _maybe_rebytesify_text
assert isinstance(value, text_type), "Should return text, got bytes instead (%r)" % (value,)
AssertionError: Should return text, got bytes instead ('CN=sdsddsc,OU=sds,OU=sds,DC=sdds,DC=net')
I know that this line causes the trouble:
ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
But I'm stumped as to why it happens when called in flask and not when run with python ldapA.py.
It seems to be the ldap lib internal error, but why does it only happen in flask and how could I fix it?
Thanks guys!
Turns out it was a unicode problem, for anyone having the same error:
Go to ldpaobject.py(whererver you have python-ldap installed)
Change
if PY2:
text_type = unicode
else:
text_type = str
to just
text_type = str
python-ldap should now work in flask
i have a problem with Python Flask Restful API and data goes to Elasticsearch, when i post a new data with Postman, problem is:
TypeError: Object of type 'Response' is not JSON serializable
Can you help me?
Model:
from marshmallow import Schema, fields, validate
class Person(object):
def __init__(self,tcno=None,firstname=None,lastname=None,email=None,birthday=None,country=None,gender=None):
self.__tcno = tcno
self.__firstname = firstname
self.__lastname = lastname
self.__email = email
self.__birthday = birthday
self.__country = country
self.__gender = gender
def __repr__(self):
return '<Person(firstname={self.__firstname!r})>'.format(self=self)
class PersonSchema(Schema):
tcno = fields.Str(required=True,validate=[validate.Length(min=11, max=11)])
firstname = fields.Str(required=True)
lastname = fields.Str(required=True)
email = fields.Email(required=True,validate=validate.Email(error="Not a valid email"))
birthday = fields.Date(required=True)
country = fields.Str()
gender = fields.Str()
View:
from flask import Response, json, request, jsonify, Flask
import requests
from flask_marshmallow import Marshmallow
from flask_restful import Api, Resource
from Person import Person, PersonSchema
app = Flask(__name__)
api = Api(app)
ma = Marshmallow(app)
class Apici(Resource):
def __init__(self):
pass
def get(self,people_id):
url = "http://localhost:9200/people/person/{}".format(people_id)
headers = {"Content-type": "application/json"}
r = requests.get(url=url, headers=headers)
json_data = json.loads(r.text)
if json_data['found'] is False:
mesaj = json.dumps({"found": "False"})
resp = Response(mesaj, status=201, mimetype='application/json')
return resp
return json_data["_source"]
def post(self,people_id):
json_input = request.get_json()
person_schema = PersonSchema()
person, errors = person_schema.load(json_input)
if errors:
return jsonify({'errors': errors}), 422
#result = person_schema(person)
url = "http://localhost:9200/people/person/{}".format(people_id)
headers = {"Content-type": "application/json"}
print(url)
r = requests.post(url=url, json=json_input, headers=headers)
print(r)
json_data = json.loads(r.text)
if json_data["result"] is "Updated":
message = json.loads({"result": "updated"})
resp = Response(message, status=201, mimetype='application/json')
return resp
message = json.loads({"result": "created"})
resp = Response(message, status=201, mimetype='application/json')
return resp #jsonify(result.data)
def put(self):
json_input = request.get_json()
person_schema = PersonSchema()
person, errors = person_schema.load(json_input)
if errors:
return jsonify({'errors': errors}), 422
result = person_schema(person)
url = "http://localhost:9200/people/person/{}".format(request.url[-1])
headers = {"Content-type": "application/json"}
r = requests.post(url=url, json=json_input, headers=headers)
json_data = json.loads(r.text)
if json_data["result"] is "Updated":
message = json.dumps({"result": "updated"})
resp = Response(message, status=201, mimetype='application/json')
return resp
message = json.dumps({"result": "created"})
resp = Response(message, status=201, mimetype='application/json')
return resp #jsonify(result.data)
def delete(self):
url = "http://localhost:9200/people/person/{}".format(request.url[-1])
headers = {"Content-type": "application/json"}
r = requests.delete(url=url,headers=headers)
json_data = json.loads(r.text)
if json_data["result"] == "not_found":
message = json.dumps({"result": "not_found"})
return Response(message, status=201, mimetype='application/json')
message = json.dumps({"result": "deleted"})
resp = Response(message, status=201, mimetype='application/json')
return resp
class ApiciList(Resource):
def __init__(self):
pass
def get(self):
url = "http://localhost:9200/people/person/_search"
body = {"query": {"match_all": {}}}
headers = {"Content-type": "application/json"}
r = requests.get(url=url, json=body, headers=headers)
json_data = json.loads(r.text)
return json_data["hits"]["hits"]
api.add_resource(ApiciList, '/person')
api.add_resource(Apici, '/person/<string:people_id>')
if __name__ == '__main__':
app.run(port=5010,debug=True)
Error:
127.0.0.1 - - [08/Jun/2017 11:37:18] "POST /person/1 HTTP/1.1" 500 -
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.6/dist-packages/flask_restful/__init__.py", line 271, in error_router
return original_handler(e)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 32, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/dist-packages/flask_restful/__init__.py", line 271, in error_router
return original_handler(e)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 32, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.6/dist-packages/flask_restful/__init__.py", line 481, in wrapper
return self.make_response(data, code, headers=headers)
File "/usr/local/lib/python3.6/dist-packages/flask_restful/__init__.py", line 510, in make_response
resp = self.representations[mediatype](data, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/flask_restful/representations/json.py", line 20, in output_json
dumped = dumps(data, **settings) + "\n"
File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/usr/lib/python3.6/json/encoder.py", line 437, in _iterencode
o = _default(o)
File "/usr/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'Response' is not JSON serializable
EDIT:
I found problem. It was in def post(self,people_id) method:
if errors:
return jsonify({'errors': errors}), 422
new line:
if errors:
message = json.dumps({'errors': errors})
return Response(message, status=422, mimetype='application/json')
Inspired from this bug, here is a shorter way of doing it:
from flask import jsonify, make_response
def myMethod():
....
return make_response(jsonify(data), 200)
This can be simply done by:
from flask import jsonify
def myMethod():
....
response = jsonify(data)
response.status_code = 200 # or 400 or whatever
return response
I had a similar problem, the problem is that i was using jsonify twice (jsonify(jsonify({abc:123})))
def post(self):
some_json=request.get_json()
return jsonify({'you sent ':some_json})
enough to solve this issue
For this we can try
response=response.json()
response=json.dumps(response)
I'm new to python and as far as i can tell i'm recieving this Tuple Error:
Traceback (most recent call last):
File "/home/cambria/Main.py", line 10, in <module>
main()
File "/home/cambria/Main.py", line 5, in main
respons3 = api.get_summoner_by_name('hi im gosan')
File "/home/cambria/RiotAPI.py", line 31, in get_summoner_by_name
return self._request(api_url)
File "/home/cambria/RiotAPI.py", line 12, in _request
for key, value in params.items():
AttributeError: 'tuple' object has no attribute 'items'
in
def _request(self, api_url, params=()):
args = {'api_key': self.api_key}
for key, value in params.items():
if key not in args:
args[key] = value
response = requests.get(
Consts.URL['base'].format(
proxy=self.region,
region=self.region,
url=api_url
),
params=args
)
print response.url
return response.json()
this is the only error i have received that i really don't know much on. Is this a result of there being no .items on my params? or i left it initialized as an empty dictionary?
EDIT 1: Have tried tinkering with the Tuple and items thing but just not having any luck, my error message is as follows
Traceback (most recent call last):
File "/home/cambria/Desktop/api/Main.py", line 10, in <module>
main()
File "/home/cambria/Desktop/api/Main.py", line 5, in main
respons3 = api.get_summoner_by_name('hi im gosan')
File "/home/cambria/Desktop/api/RiotAPI.py", line 33, in get_summoner_by_name
return self._request(api_url)
File "/home/cambria/Desktop/api/RiotAPI.py", line 23, in _request
params=args
File "/home/cambria/.local/lib/python2.7/site-packages/requests/api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "/home/cambria/.local/lib/python2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/home/cambria/.local/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "/home/cambria/.local/lib/python2.7/site-packages/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "/home/cambria/.local/lib/python2.7/site-packages/requests/adapters.py", line 415, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', gaierror(-2, 'Name or service not known'))
>>>
as far as i can tell and have searched, this is a result of the python REQUESTS not going through completely?
and my new code as follows,
def _request(self, api_url, params=None): #edit
if params is None: #edit
params = {} #edit
args = {'api_key': self.api_key}
for key, value in params.items(): #remove?? since there is no .items()?
if key not in args:
args[key] = value
response = requests.get(
Consts.URL['base'].format(
proxy=self.region,
region=self.region,
url=api_url
),
params=args
)
print response.url
return response.json()
Your code expects params to be a dict {} (or have a .items method). You've passed a tuple (). The two are not equivalent.
Set params to None by default, and pass a when needed.
def _request(self, api_url, params=None):
params = params if params is not None else {}
...
Or expect a list of tuples, rather than a dict.
def _request(self, api_url, params=()):
for key, value in params:
...
A tuple () doesn't have a method named items. You probably mistake that for dictionary. Change you code as follows:
def _request(self, api_url, params=None):
if params is None:
params = {}
...
So, I'm experiencing some weird error with flask-restful and fields.Url that I can't really figure out why is there since it happens randomly. When running my application normally, it doesn't seem to happen, and it only fails randomly in tests.
It's worth noting that it only occurs on POST requests, and works with GET requests.
For reference, all the code is located at https://github.com/Tehnix/cred-server (with the temp fix applied).
Error
It seems that the creation of a URL field fails, while marshalling my data object. The full error is at the end of the question.
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/werkzeug/routing.py", line 1678, in build
raise BuildError(endpoint, values, method)
werkzeug.routing.BuildError: ('events_item', {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x102df6d68>}, None)
Culprit
The endpoint is defined as,
# FILE: cred/routes.py
api.add_resource(EventsItem, '/events/<int:event_id>', endpoint='events_item')
I'm using the following to marshal my SQLAlchemy object,
# FILE: cred/resources/events.py
simple_event_fields = {
'id': flask.ext.restful.fields.Integer(attribute='event_id'),
'uri': flask.ext.restful.fields.Url('events_item', absolute=True),
}
where the fields.Url seems to fail for some reason. And finally the resource that handles the POST request,
# FILE: cred/resources/events.py
class Events(flask.ext.restful.Resource):
"""Methods going to the /events route."""
def post(self):
"""Create a new event and return the id and uri of the event."""
# Parse the POST args using the parser from flask-restful into event_args
# ...
# Create the event in the database
event = EventModel(
self.client,
event_args['name'],
event_args['location'],
event_args['action'],
event_args['value']
)
# Save the event in the database
db.session.add(event)
db.session.commit()
# Finally, convert the event object into our format by marshalling it,
# and returning the JSON object
return {
'status': 201,
'message': 'Created Event',
'event': marshal(event, simple_event_fields)
}, 201
As said in the start, it only occurs when running tests (and only sometimes), so it isn't critical per se, but it would still be nice not having to rerun tests a bunch of times just to see if it goes away and all others pass.
Test case
I'm using Flask-Testing, but it else it is pretty much unittests,
# FILE: cred/test/test_events.py
test_event = {
'event': {
'name': 'Temperature',
'location': 'Living Room',
'action': 'Temperature Above Setting',
'value': '5'
}
}
class BaseTestCase(flask.ext.testing.TestCase):
SQLALCHEMY_DATABASE_URI = "sqlite://"
TESTING = True
def create_app(self):
return app
def setUp(self):
"""Create a SQLite database for quick testing."""
cred.database.init_db(cred.database.db)
self.session_key = None
def tearDown(self):
"""Close the database file and unlink it."""
cred.database.db.session.remove()
cred.database.db.drop_all()
#testutil.authenticate('write')
def test_posting_a_complete_event(self):
"""Create a valid new event."""
# Post the request to the test server
response = self.client.post(
'/events',
data=json.dumps(test_event),
content_type='application/json'
)
resp = json.loads(response.data.decode('utf-8'))
# Run self.assertEqual on all items in a dict
testutil.assertEqual(self, {
response.status_code: 201,
resp['status']: 201,
resp['message']: 'Created Event',
'id' in resp['event']: True,
'uri' in resp['event']: True
})
In the above, test_posting_a_complete_event will fail randomly because of the uri item.
Full error output from nosetests
======================================================================
ERROR: Create a valid new event.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/test/util.py", line 34, in wrapped
fun(self, *args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/test/test_events.py", line 37, in test_posting_a_complete_event
resp = json.loads(response.data.decode('utf-8'))
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/__init__.py", line 318, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/decoder.py", line 343, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/json/decoder.py", line 361, in raw_decode
raise ValueError(errmsg("Expecting value", s, err.value)) from None
nose.proxy.ValueError: Expecting value: line 1 column 1 (char 0)
-------------------- >> begin captured logging << --------------------
cred-server: ERROR: Exception on /events [POST]
Traceback (most recent call last):
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 265, in error_router
return original_handler(e)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 446, in wrapper
resp = resource(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 550, in dispatch_request
resp = meth(*args, **kwargs)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/cred/resources/events.py", line 88, in post
'event': marshal(event, simple_event_fields)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 603, in marshal
return OrderedDict([(envelope, OrderedDict(items))]) if envelope else OrderedDict(items)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/collections/__init__.py", line 56, in __init__
self.__update(*args, **kwds)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/bin/../lib/python3.4/_collections_abc.py", line 602, in update
for key, value in other:
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/__init__.py", line 602, in <genexpr>
for k, v in fields.items())
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask_restful/fields.py", line 294, in output
o = urlparse(url_for(endpoint, _external=self.absolute, **data))
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/helpers.py", line 312, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/app.py", line 1641, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/flask/helpers.py", line 305, in url_for
force_external=external)
File "/Users/tehnix/Dropbox/github/Tehnix/cred/env/lib/python3.4/site-packages/werkzeug/routing.py", line 1678, in build
raise BuildError(endpoint, values, method)
werkzeug.routing.BuildError: ('events_item', {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x102df6d68>}, None)
You need to assign events_items inside the 'fields.Url' before returning it.
This link How to add fields url for nested output fields in flask restful explains more
But if you are using Blueprints, add "." to the fields.Url eg
'uri': fields.Url('.events_items')
ref https://github.com/flask-restful/flask-restful/issues/266#issuecomment-46678118