From 564f1f6f23d0769db0a1d54660dcbe7554c9c155 Mon Sep 17 00:00:00 2001 From: Peter Doggart Date: Mon, 22 Sep 2025 20:19:47 +0000 Subject: [PATCH] Added a thread lock to guard first-time schema construction. --- CHANGELOG.rst | 2 +- flask_restx/api.py | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a63e2405..24ed9de9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -35,7 +35,7 @@ Bug Fixes :: * Add python version requirement on setup.py (#586) [jason-the-j] - + * Add a thread lock to avoid concurrent schema construction. (#545) [peter-doggart] .. _section-1.3.0: 1.3.0 diff --git a/flask_restx/api.py b/flask_restx/api.py index a76ae3a2..35cef441 100644 --- a/flask_restx/api.py +++ b/flask_restx/api.py @@ -2,6 +2,7 @@ import inspect from itertools import chain import logging +import threading import operator import re import sys @@ -161,6 +162,7 @@ def __init__( } ) self._schema = None + self._schema_lock = threading.Lock() self.models = {} self._refresolver = None self.format_checker = format_checker @@ -567,14 +569,17 @@ def __schema__(self): :returns dict: the schema as a serializable dict """ if not self._schema: - try: - self._schema = Swagger(self).as_dict() - except Exception: - # Log the source exception for debugging purpose - # and return an error message - msg = "Unable to render schema" - log.exception(msg) # This will provide a full traceback - return {"error": msg} + # Guard schema initialization to avoid concurrent construction on first access + with self._schema_lock: + if not self._schema: + try: + self._schema = Swagger(self).as_dict() + except Exception: + # Log the source exception for debugging purpose + # and return an error message + msg = "Unable to render schema" + log.exception(msg) # This will provide a full traceback + return {"error": msg} return self._schema @property