'ValueError: Out of range float values are not JSON compliant error on Heroku, and WSL but not on Windows

I'm trying to deploy a CNN model created using Tensorflow to Heroku with FastAPI. The app runs on Heroku but returns an error when trying to make model predictions. Running heroku logs --tail returns this:

2022-02-17T03:32:12.426547+00:00 app[web.1]: [2022-02-17 03:32:12 +0000] [10] [ERROR] Exception in ASGI application
2022-02-17T03:32:12.426549+00:00 app[web.1]: Traceback (most recent call last):
2022-02-17T03:32:12.426549+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi
2022-02-17T03:32:12.426550+00:00 app[web.1]: result = await app(self.scope, self.receive, self.send)
2022-02-17T03:32:12.426550+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
2022-02-17T03:32:12.426551+00:00 app[web.1]: return await self.app(scope, receive, send)
2022-02-17T03:32:12.426551+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/fastapi/applications.py", line 212, in __call__
2022-02-17T03:32:12.426552+00:00 app[web.1]: await super().__call__(scope, receive, send)
2022-02-17T03:32:12.426552+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
2022-02-17T03:32:12.426552+00:00 app[web.1]: await self.middleware_stack(scope, receive, send)
2022-02-17T03:32:12.426553+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
2022-02-17T03:32:12.426553+00:00 app[web.1]: raise exc
2022-02-17T03:32:12.426554+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
2022-02-17T03:32:12.426554+00:00 app[web.1]: await self.app(scope, receive, _send)
2022-02-17T03:32:12.426554+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
2022-02-17T03:32:12.426554+00:00 app[web.1]: raise exc
2022-02-17T03:32:12.426555+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
2022-02-17T03:32:12.426555+00:00 app[web.1]: await self.app(scope, receive, sender)
2022-02-17T03:32:12.426555+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
2022-02-17T03:32:12.426555+00:00 app[web.1]: await route.handle(scope, receive, send)
2022-02-17T03:32:12.426556+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/routing.py", line 259, in handle
2022-02-17T03:32:12.426556+00:00 app[web.1]: await self.app(scope, receive, send)
2022-02-17T03:32:12.426556+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/routing.py", line 61, in app
2022-02-17T03:32:12.426556+00:00 app[web.1]: response = await func(request)
2022-02-17T03:32:12.426557+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/fastapi/routing.py", line 250, in app
2022-02-17T03:32:12.426557+00:00 app[web.1]: response = actual_response_class(response_data, **response_args)
2022-02-17T03:32:12.426557+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/responses.py", line 49, in __init__
2022-02-17T03:32:12.426558+00:00 app[web.1]: self.body = self.render(content)
2022-02-17T03:32:12.426558+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/starlette/responses.py", line 174, in render
2022-02-17T03:32:12.426558+00:00 app[web.1]: return json.dumps(
2022-02-17T03:32:12.426559+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/json/__init__.py", line 234, in dumps
2022-02-17T03:32:12.426559+00:00 app[web.1]: return cls(
2022-02-17T03:32:12.426559+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/json/encoder.py", line 199, in encode
2022-02-17T03:32:12.426560+00:00 app[web.1]: chunks = self.iterencode(o, _one_shot=True)
2022-02-17T03:32:12.426560+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/json/encoder.py", line 257, in iterencode
2022-02-17T03:32:12.426560+00:00 app[web.1]: return _iterencode(o, 0)
2022-02-17T03:32:12.426561+00:00 app[web.1]: ValueError: Out of range float values are not JSON compliant

Most notably on the last line, it says `ValueError: Out of range float values are not JSON compliant". My procfile looks like this:

web: gunicorn -w 2 -k uvicorn.workers.UvicornWorker main:app

When trying to run the server on WSL using python -m uvicorn main:app, I get this error

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/eruaro/.local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 375, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/fastapi/applications.py", line 212, in __call__
    await super().__call__(scope, receive, send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/routing.py", line 259, in handle
    await self.app(scope, receive, send)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/routing.py", line 61, in app
    response = await func(request)
  File "/home/eruaro/.local/lib/python3.8/site-packages/fastapi/routing.py", line 250, in app
    response = actual_response_class(response_data, **response_args)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/responses.py", line 49, in __init__
    self.body = self.render(content)
  File "/home/eruaro/.local/lib/python3.8/site-packages/starlette/responses.py", line 174, in render
    return json.dumps(
  File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
    return cls(
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
ValueError: Out of range float values are not JSON compliant

It's similar to the one I get on Heroku. However, on Windows, using the same command like the one I used on WSL, the app works. No error is returned and I'm able to make predictions on the server. How do I remove the JSON compliant error?

For reference, my code is in a singular main.py file:

from fastapi import FastAPI
from tensorflow.keras.models import load_model
from tensorflow.keras.utils import get_file 
from tensorflow.keras.utils import load_img 
from tensorflow.keras.utils import img_to_array
from tensorflow import expand_dims
from tensorflow.nn import softmax
from numpy import argmax
from numpy import max
from numpy import array

app = FastAPI()
model_dir = "food-vision-model.h5"
model = load_model(model_dir)

class_predictions = array([
    'apple_pie',
    'baby_back_ribs',
    'baklava',
    'beef_carpaccio',
    'beef_tartare',
    'beet_salad',
    'beignets',
    'bibimbap',
    'bread_pudding',
    'breakfast_burrito',
    'bruschetta',
    'caesar_salad',
    'cannoli',
    'caprese_salad',
    'carrot_cake',
    'ceviche',
    'cheesecake',
    'cheese_plate',
    'chicken_curry',
    'chicken_quesadilla',
    'chicken_wings',
    'chocolate_cake',
    'chocolate_mousse',
    'churros',
    'clam_chowder',
    'club_sandwich',
    'crab_cakes',
    'creme_brulee',
    'croque_madame',
    'cup_cakes',
    'deviled_eggs',
    'donuts',
    'dumplings',
    'edamame',
    'eggs_benedict',
    'escargots',
    'falafel',
    'filet_mignon',
    'fish_and_chips',
    'foie_gras',
    'french_fries',
    'french_onion_soup',
    'french_toast',
    'fried_calamari',
    'fried_rice',
    'frozen_yogurt',
    'garlic_bread',
    'gnocchi',
    'greek_salad',
    'grilled_cheese_sandwich',
    'grilled_salmon',
    'guacamole',
    'gyoza',
    'hamburger',
    'hot_and_sour_soup',
    'hot_dog',
    'huevos_rancheros',
    'hummus',
    'ice_cream',
    'lasagna',
    'lobster_bisque',
    'lobster_roll_sandwich',
    'macaroni_and_cheese',
    'macarons',
    'miso_soup',
    'mussels',
    'nachos',
    'omelette',
    'onion_rings',
    'oysters',
    'pad_thai',
    'paella',
    'pancakes',
    'panna_cotta',
    'peking_duck',
    'pho',
    'pizza',
    'pork_chop',
    'poutine',
    'prime_rib',
    'pulled_pork_sandwich',
    'ramen',
    'ravioli',
    'red_velvet_cake',
    'risotto',
    'samosa',
    'sashimi',
    'scallops',
    'seaweed_salad',
    'shrimp_and_grits',
    'spaghetti_bolognese',
    'spaghetti_carbonara',
    'spring_rolls',
    'steak',
    'strawberry_shortcake',
    'sushi',
    'tacos',
    'takoyaki',
    'tiramisu',
    'tuna_tartare',
    'waffles'
])

@app.get("/")
async def root():
    return {"message": "Welcome to the Food Vision API!"}

@app.post("/net/image/prediction/")
async def get_net_image_prediction(image_link: str = ""):
    if image_link == "":
        return {"message": "No image link provided"}
    
    img_path = get_file(
        origin = image_link
    )
    img = load_img(
        img_path, 
        target_size = (224, 224)
    )

    img_array = img_to_array(img)
    img_array = expand_dims(img_array, 0)

    pred = model.predict(img_array)
    score = softmax(pred[0])

    class_prediction = class_predictions[argmax(score)]
    model_score = round(max(score) * 100, 2)

    return {
        "model_prediction_class": class_prediction,
        "model_prediction_score": model_score
    }


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source