У меня очень странное поведение os.makedir
в flask приложении.
У меня есть конечная точка API для загрузки изображений. Каждое изображение должно быть сгруппировано в каталоги в зависимости от условий. Если каталог не существует, каталог должен быть создан.
Изначально у меня был такой код в моем приложении:
# create needed dir if doesn't exist
if not os.path.isdir(os.path.dirname(abs_path)):
os.mkdir(os.path.dirname(abs_path))
# create a file and save it into a needed place
with open(abs_path, 'wb') as f:
shutil.copyfileobj(fp, f)
f.flush()
И в 90% случаев он прекрасно работает. Но когда в запросе было два файла, которые должны быть помещены в один каталог, а каталог еще не был создан, я получил это:
flask_1 | File "/app/storage.py", line 101, in save_file
flask_1 | os.mkdir(os.path.dirname(abs_path))
flask_1 | FileExistsError: [Errno 17] File exists: '/static/df273d04909e71beb8b63b4d1b1c0a969ee6fc15'
Он может быть воспроизведен локально с успехом 100% в flask режим отладки с 1 потоком. Кажется, это какой-то Linux / docker или какое-то состояние гонки кеша.
Затем я просто изменил код на этот:
if not os.path.isdir(os.path.dirname(abs_path)):
try:
os.mkdir(os.path.dirname(abs_path))
except FileExistsError:
# Another thread was already created the directory when
# several simultaneous requests has come
if os.path.isdir(os.path.dirname(abs_path)):
pass
else:
raise
# create a file and save it into a needed place
with open(abs_path, 'wb') as f:
shutil.copyfileobj(fp, f)
f.flush()
И проблема исчезла.
Но у меня есть опасения по поводу использования этого кода в рабочей среде, поскольку очень странно, что одна и та же проверка дает разные результаты.
Как убедиться, что каталог действительно создан, прежде чем продолжить обработку первого запроса?
PS Файлы на месте, второй фрагмент кода на месте. С первым только первый файл в каталоге и ошибка на втором.
IE С первым фрагментом кода Flask считает, что все в порядке и продолжает