I am currently building an API on VS Code using Python 3.11, Flask, Insomnia, and Docker.
when I tried to create my resources file to use flask_smorest I am getting this error on Docker
ValueError: The name 'Items' is already registered for this blueprint. Use 'name=' to provide a unique name.
Insomnia is also giving me a value error indicating "Items" is already registered for this blueprint.
I am learning right now and am not sure how to find out where the blueprint is being used twice so that I can change it and move forward with my course.
Thanks!
app.py file: `
from flask import Flask
from flask_smorest import Api
from resources.item import blp as ItemBlueprint
from resources.item import blp as StoreBlueprint
app = Flask(__name__)
app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
api = Api(app)
api.register_blueprint(ItemBlueprint)
api.register_blueprint(StoreBlueprint)
`
store.py file: `
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import stores
blp = Blueprint("Stores", __name__, description="Operations on stores")
@blp.route("/store/<string:store_id>")
class Store(MethodView):
def get(self, store_id):
try:
# Here you might also want to add the items in this store
# We'll do that later on in the course
return stores[store_id]
except KeyError:
abort(404, message="Store not found.")
def delete(self, store_id):
try:
del stores[store_id]
return {"message": "Store deleted."}
except KeyError:
abort(404, message="Store not found.")
@blp.route("/store")
class Store(MethodView):
def get(self):
return {"stores": list(stores.values())}
def post(self): # sourcery skip: remove-redundant-fstring
store_data = request.get_json()
if "name" not in store_data:
abort(
400,
message="Bad request. Ensure 'name' is included in the JSON payload.",
)
for store in stores.values():
if store_data["name"] == store["name"]:
abort(400, message=f"Store already exists.")
store_id = uuid.uuid4().hex
store = {**store_data, "id": store_id}
stores[store_id] = store
return store
`
item.py file: `
import uuid
from flask import request
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from db import items
blp = Blueprint("Items", __name__, description="Operations on items")
@blp.route("/item/<string:item_id>")
class Item(MethodView):
def get(self, item_id):
try:
# Here you might also want to add the items in this store
# We'll do that later on in the course
return items[item_id]
except KeyError:
abort(404, message="Item not found.")
def delete(self, item_id):
try:
del items[item_id]
return {"message": "Item deleted."}
except KeyError:
abort(404, message="Item not found.")
def put(self, item_id):
item_data = request.get_json()
# There's more validation to do here!
# Like making sure price is a number, and also both items are optional
# Difficult to do with an if statement...
if "price" not in item_data or "name" not in item_data:
abort(
400,
message="Bad request. Ensure 'price', and 'name' are included in the JSON payload.",
)
try:
item = items[item_id]
# https://blog.teclado.com/python-dictionary-merge-update-operators/
item |= item_data
return item
except KeyError:
abort(404, message="Item not found.")
@blp.route("/item")
class ItemList(MethodView):
def get(self):
return {"items": list(items.values())}
def post(self): # sourcery skip: remove-redundant-fstring
item_data = request.get_json()
if "name" not in item_data:
abort(
400,
message="Bad request. Ensure 'name' is included in the JSON payload.",
)
for item in items.values():
if item_data["name"] == item["name"]:
abort(400, message=f"Item already exists.")
item_id = uuid.uuid4().hex
item = {**item_data, "id": item_id}
items[item_id] = item
return item
`
I am not sure how to find out where the first blueprint was created or how I duplicated the blueprint anywhere in the above code. I am hoping someone can offer assistance.
I have restarted this part so many times already!
In app.py
:
from resources.item import blp as ItemBlueprint
from resources.item import blp as StoreBlueprint
you're importing (and later, registering) the same blueprint twice. Do instead:
from resources.item import blp as ItemBlueprint
from resources.store import blp as StoreBlueprint