When deploying a simple API written in Python and Flask, I encountered a strange error: "TypeError: 'float' object is not callable". Even though the variable type was expected to be int, this error appeared. Forcing the variable type to int did not resolve the issue.

Solution
This error is often caused by assigning a float value to a variable that is later used as a callable, such as the range() functon. To fix it, ensure that the variable is declared as an integer, for example:
if lng is not None and lat is not None:
radius = int(0.1) # Explicitly cast to int
Additionally, there are other issues in the code:
-
Assigning float to int variables: Parameters like
price_minwere being read as float, but later used in a context expecting int. Change thetypeparameter toint:price_min = request.args.get('price_min', default=None, type=int) price_max = request.args.get('price_max', default=None, type=int) rooms_min = request.args.get('rooms_min', default=None, type=int) rooms_max = request.args.get('rooms_max', default=None, type=int) -
Using integer variables in string concatenation with out conversion: The code concatenated an integer to a query string without proper conversion. This was fixed, but note that
str(str(counter + 6))is redundant; usestr(counter + 6)instead.
After these corrections, the code should work without the "TypeError: 'float' object is not callable" error.
Corrected Code Example
def closest_point():
lng = request.args.get('lng', default=None, type=float)
lat = request.args.get('lat', default=None, type=float)
price_min = request.args.get('price_min', default=None, type=int)
price_max = request.args.get('price_max', default=None, type=int)
rooms_min = request.args.get('rooms_min', default=None, type=int)
rooms_max = request.args.get('rooms_max', default=None, type=int)
if lng is not None and lat is not None:
radius = int(0.1)
lng_min = lng - radius
lng_max = lng + radius
lat_min = lat - radius
lat_max = lat + radius
cur = g.db.cursor()
query = f"""
SELECT id, link, price, longitude, latitude
FROM {DATABASE_TABLE_NAME}
WHERE latitude >= {lat_min} AND latitude <= {lat_max}
AND longitude >= {lng_min} AND longitude <= {lng_max}
"""
additional_params_count = 0
if price_min:
query += f" AND price >= {price_min}"
additional_params_count += 1
# Add more filters as needed
query += " GROUP BY 1,2,3,4,5"
for counter in range(additional_params_count):
query += f",{counter + 6}"
query += ";"
cur.execute(query)
columns = [desc[0] for desc in cur.description]
rows = cur.fetchall()
flats_json = [
{k: str(v) for k, v in zip(columns, row)}
for row in rows
]
return json.dumps(flats_json)
else:
return "One of lng or lat parameters missing"
Note: The code above uses f-strings for clarity, but ensure they are used safely to avoid SQL injection. In production, consider parameterized queries.