API search returning '_WeaviateUUIDInt' object has no attribute 'is_safe'

Hi there,

I’m using the Weaviate 1.24.1 and python client V4 for a RAG app. Since the upgrade from V3 to V4 I’m getting the following error on this code:

from flask import Flask, request, jsonify
import weaviate

# Create Weaviate client
client = weaviate.connect_to_local()

# Flask application setup
app = Flask(__name__)

@app.route('/search', methods=['POST'])
def search():
    data = request.json
    query = data['query']
    print("Received data:", query)
    try:
        print("Querying Weaviate directly...")

        collection = client.collections.get("TextChunks")
        search_results = collection.query.near_text(
            query = query,
            limit = 10,
            return_properties=["title", "content"]
        )
        print("Search results:", search_results) # optional: this is a diagnostic check to see the search results
        
        return jsonify(search_results)

    except Exception as e:
        app.logger.error(f'Error in /search: {e}')
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001, debug=True)

Error in /search: ‘_WeaviateUUIDInt’ object has no attribute ‘is_safe’

My diagnostic print statement does return the text chunks, thus it seems that somewhere in the jsonify something happens. is_safe isn’t an attribute that is stored in one of the outer layers nor accessible to me, thus this might have something to do how the V4 client deals with jsnoify.

Is this already on the radar? Or what could I change in my code to make it work?

For additional context, here is my docker-compose:

version: '3.4'
services:
  weaviate:
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: cr.weaviate.io/semitechnologies/weaviate:1.24.1
    ports:
    - 8080:8080
    - 50051:50051
    volumes:
    - ./data/Volumes:/var/lib/weaviate
    restart: on-failure:0
    environment:
      TRANSFORMERS_INFERENCE_API: 'http://t2v-transformers:8080'
      OPENAI_APIKEY: $OPENAI_APIKEY
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'text2vec-openai'
      ENABLE_MODULES: 'text2vec-transformers,text2vec-openai,ref2vec-centroid,generative-openai'
      CLUSTER_HOSTNAME: 'node1'
  t2v-transformers:
    image: cr.weaviate.io/semitechnologies/transformers-inference:sentence-transformers-multi-qa-MiniLM-L6-cos-v1
    environment:
      ENABLE_CUDA: '0'
volumes:
  weaviate_data:

HI @ThomasB91,

At the moment query results are not JSON serializable.

I usually iterate through the response.objects and print them like this:

for o in response.objects:
    print(o.uuid)
    print(o.properties)

Override serialization

If you need to print print straight from a JSON object, you could override the serialization fucntion.

This is the same problem that occurs when using mongo in Python so I’d recommend following an identical logic as here: python - UUID('...') is not JSON serializable - Stack Overflow

In mongo you do:

import json
from bson import ObjectId
 
class JSONEncoder(json.JSONEncoder):
    def default(self, item):
        if isinstance(item, ObjectId):
            return str(item)
        return json.JSONEncoder.default(self, item)

So for us, it could be something like this:

import json
from uuid import UUID

class UUIDEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            # if the obj is uuid, we simply return the value of uuid
            return obj.hex
        return json.JSONEncoder.default(self, obj)

Then the user will need to override the default JSONEncoder in their Flask app like this: Custom JSON encoder for Flask · GitHub