1

i am using geopy library for my Flask web app. i want to save user location which i am getting from my modal(html form) in my database(i am using mongodb), but every single time i am getting this error: TypeError: Object of type 'Location' is not JSON serializable

Here's the code:

@app.route('/register', methods=['GET', 'POST'])
def register_user():
    if request.method == 'POST':
        login_user = mongo.db.mylogin
        existing_user = login_user.find_one({'email': request.form['email']})
        # final_location = geolocator.geocode(session['address'].encode('utf-8'))
        if existing_user is None:
            hashpass = bcrypt.hashpw(
                request.form['pass'].encode('utf-8'), bcrypt.gensalt())
            login_user.insert({'name': request.form['username'], 'email': request.form['email'], 'password': hashpass, 'address': request.form['add'], 'location' : session['location'] })
            session['password'] = request.form['pass']
            session['username'] = request.form['username']
            session['address'] = request.form['add']
            session['location'] = geolocator.geocode(session['address'])
            flash(f"You are Registerd as {session['username']}")
            return redirect(url_for('home'))
        flash('Username is taken !')
        return redirect(url_for('home'))
    return render_template('index.html')

Please Help, let me know if you want more info..

vatsalay
  • 469
  • 1
  • 9
  • 21

2 Answers2

0

According to the geolocator documentation the geocode function "Return a location point by address" geopy.location.Location objcet.

Json serialize support by default the following types:

Python | JSON

dict | object

list, tuple | array

str, unicode | string

int, long, float | number

True | true

False | false

None | null

All the other objects/types are not json serialized by default and there for you need to defined it.

geopy.location.Location.raw

Location’s raw, unparsed geocoder response. For details on this, consult the service’s documentation.

Return type: dict or None

You might be able to call the raw function of the Location (the geolocator.geocode return value) and this value will be json serializable.

Amiram
  • 1,227
  • 6
  • 14
0

Location is indeed not json serializable: there are many properties in this object and there is no single way to represent a location, so you'd have to choose one by yourself.

What type of value do you expect to see in the location key of the response?

Here are some examples:

Textual address

In [9]: json.dumps({'location': geolocator.geocode("175 5th Avenue NYC").address})
Out[9]: '{"location": "Flatiron Building, 175, 5th Avenue, Flatiron District, Manhattan Community Board 5, Manhattan, New York County, New York, 10010, United States of America"}'

Point coordinates

In [10]: json.dumps({'location': list(geolocator.geocode("175 5th Avenue NYC").point)})
Out[10]: '{"location": [40.7410861, -73.9896298241625, 0.0]}'

Raw Nominatim response

(That's probably not what you want to expose in your API, assuming you want to preserve an ability to change geocoding service to another one in future, which might have a different raw response schema).

In [11]: json.dumps({'location': geolocator.geocode("175 5th Avenue NYC").raw})
Out[11]: '{"location": {"place_id": 138642704, "licence": "Data \\u00a9 OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright", "osm_type": "way", "osm_id": 264768896, "boundingbox": ["40.7407597", "40.7413004", "-73.9898715", "-73.9895014"], "lat": "40.7410861", "lon": "-73.9896298241625", "display_name": "Flatiron Building, 175, 5th Avenue, Flatiron District, Manhattan Community Board 5, Manhattan, New York County, New York, 10010, United States of America", "class": "tourism", "type": "attraction", "importance": 0.74059885426854, "icon": "https://nominatim.openstreetmap.org/images/mapicons/poi_point_of_interest.p.20.png"}}'

Textual address + point coordinates

In [12]: location = geolocator.geocode("175 5th Avenue NYC")
    ...: json.dumps({'location': {
    ...:     'address': location.address,
    ...:     'point': list(location.point),
    ...: }})
Out[12]: '{"location": {"address": "Flatiron Building, 175, 5th Avenue, Flatiron District, Manhattan Community Board 5, Manhattan, New York County, New York, 10010, United States of America", "point": [40.7410861, -73.9896298241625, 0.0]}}'
KostyaEsmukov
  • 848
  • 6
  • 11