Question:
Hello, I am trying to make a multiuser pixel art system similar to r/place on Reddit, however, when it restarts I get this error raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")
.
It even appears randomly at times even when the server does not restart, and it always appeared before I used Dict.
It appears to always be when a pixel is added to the database also.
I tried using return jsonify(dict(json.loads(pixels)))
on the part where the client can fetch the pixels, but it gives a new error raise TypeError(f'the JSON object must be str, bytes or bytearray, '
.
Can anyone help me?
Repl link:
https://replit.com/@StudioHawaii/Pixel-Board?v=1
Server code:
import os
from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit
from replit import db
import json
app = Flask(__name__)
socketio = SocketIO(app)
app.config["TEMPLATES_AUTO_RELOAD"] = (
True # if true, it auto reloads templates if a change is made to them
)
app.secret_key = os.environ["SECRET_KEY"] # The secret key
board_size = 80 # The size of the pixel board (Warning: A very large size may either break the app or overload repl db)
colors = [
"orange",
"purple",
"white",
"cyan",
"blue",
"brown",
] # Avalible colors for the user to use (first color is defualt)
try:
pixels = db["pixels"] # The list of pixels from the database
except: # Set the pixels key if the key was not found
db["pixels"] = {}
pixels = db["pixels"]
pixels["board_size"] = board_size # sets the board size for the info for pixels
"""Routes"""
@app.route("/")
def index():
"""The index page (Board is on it)"""
if request.headers["X-Replit-User-Name"]:
return render_template("index.html", size=board_size, colors=colors)
else:
return render_template("login.html")
@app.route("/pixels")
def pixel_data():
"""Used for the client to get pixel data"""
return jsonify(dict(pixels))
"""Socketio events"""
@socketio.on("change_pixel")
def change_pixel(pixel):
"""The event when a client sends a request to change one of the pixels"""
if (
not pixel.get("Pixel")
or not pixel.get("Color")
or not pixel.get("Pixel").startswith("pixel_")
or not request.headers["X-Replit-User-Name"]
or pixel["Color"] not in colors
): # Make sure the data is valid
return # Cancels changing the pixel if it does not meet the requirements
pixel["Owner_name"] = request.headers[
"X-Replit-User-Name"
] # Adds the username to the pixel data
pixel["Owner_id"] = request.headers[
"X-Replit-User-Id"
] # Adds the userid to the pixel data
pixels[pixel["Pixel"]] = pixel # Upload the pixel to the database
emit("pixel_change", pixel, broadcast=True)
socketio.run(app, host="0.0.0.0")