feat(phase1): add image storage utilities
- Create backend/services/image_storage.py with 4 core functions:
- sanitize_filename(): remove unsafe chars, limit to 255 chars, convert to lowercase
- get_unique_filename(): handle collisions with UUID suffix (format: {name}_{uuid8}_{variant}.jpg)
- ensure_image_directories(): create /images/ root and category subdirs on startup
- save_image(): save bytes to /images/{category}/{filename}, returns relative path
- Create comprehensive test suite (22 tests) covering all functionality
- Integrate ensure_image_directories() into FastAPI startup event
- Directory structure: /images/{category}/{filename}
- Collision handling: auto-suffix with UUID if filename exists
- All tests passing, pathlib.Path for safe operations
This commit is contained in:
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,199 @@
|
||||
Metadata-Version: 2.4
|
||||
Name: Deprecated
|
||||
Version: 1.3.1
|
||||
Summary: Python @deprecated decorator to deprecate old python classes, functions or methods.
|
||||
Home-page: https://github.com/laurent-laporte-pro/deprecated
|
||||
Author: Laurent LAPORTE
|
||||
Author-email: laurent.laporte.pro@gmail.com
|
||||
License: MIT
|
||||
Project-URL: Documentation, https://deprecated.readthedocs.io/en/latest/
|
||||
Project-URL: Source, https://github.com/laurent-laporte-pro/deprecated
|
||||
Project-URL: Bug Tracker, https://github.com/laurent-laporte-pro/deprecated/issues
|
||||
Keywords: deprecate,deprecated,deprecation,warning,warn,decorator
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: 3.12
|
||||
Classifier: Programming Language :: Python :: 3.13
|
||||
Classifier: Programming Language :: Python :: 3.14
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
|
||||
Description-Content-Type: text/x-rst
|
||||
License-File: LICENSE.rst
|
||||
Requires-Dist: wrapt<3,>=1.10
|
||||
Requires-Dist: inspect2; python_version < "3"
|
||||
Provides-Extra: dev
|
||||
Requires-Dist: tox; extra == "dev"
|
||||
Requires-Dist: PyTest; extra == "dev"
|
||||
Requires-Dist: PyTest-Cov; extra == "dev"
|
||||
Requires-Dist: bump2version<1; extra == "dev"
|
||||
Requires-Dist: setuptools; python_version >= "3.12" and extra == "dev"
|
||||
Dynamic: author
|
||||
Dynamic: author-email
|
||||
Dynamic: classifier
|
||||
Dynamic: description
|
||||
Dynamic: description-content-type
|
||||
Dynamic: home-page
|
||||
Dynamic: keywords
|
||||
Dynamic: license
|
||||
Dynamic: license-file
|
||||
Dynamic: platform
|
||||
Dynamic: project-url
|
||||
Dynamic: provides-extra
|
||||
Dynamic: requires-dist
|
||||
Dynamic: requires-python
|
||||
Dynamic: summary
|
||||
|
||||
|
||||
Deprecated Library
|
||||
------------------
|
||||
|
||||
Deprecated is Easy to Use
|
||||
`````````````````````````
|
||||
|
||||
If you need to mark a function or a method as deprecated,
|
||||
you can use the ``@deprecated`` decorator:
|
||||
|
||||
Save in a hello.py:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from deprecated import deprecated
|
||||
|
||||
|
||||
@deprecated(version='1.2.1', reason="You should use another function")
|
||||
def some_old_function(x, y):
|
||||
return x + y
|
||||
|
||||
|
||||
class SomeClass(object):
|
||||
@deprecated(version='1.3.0', reason="This method is deprecated")
|
||||
def some_old_method(self, x, y):
|
||||
return x + y
|
||||
|
||||
|
||||
some_old_function(12, 34)
|
||||
obj = SomeClass()
|
||||
obj.some_old_method(5, 8)
|
||||
|
||||
|
||||
And Easy to Setup
|
||||
`````````````````
|
||||
|
||||
And run it:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ pip install Deprecated
|
||||
$ python hello.py
|
||||
hello.py:15: DeprecationWarning: Call to deprecated function (or staticmethod) some_old_function.
|
||||
(You should use another function) -- Deprecated since version 1.2.0.
|
||||
some_old_function(12, 34)
|
||||
hello.py:17: DeprecationWarning: Call to deprecated method some_old_method.
|
||||
(This method is deprecated) -- Deprecated since version 1.3.0.
|
||||
obj.some_old_method(5, 8)
|
||||
|
||||
|
||||
You can document your code
|
||||
``````````````````````````
|
||||
|
||||
Have you ever wonder how to document that some functions, classes, methods, etc. are deprecated?
|
||||
This is now possible with the integrated Sphinx directives:
|
||||
|
||||
For instance, in hello_sphinx.py:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from deprecated.sphinx import deprecated
|
||||
from deprecated.sphinx import versionadded
|
||||
from deprecated.sphinx import versionchanged
|
||||
|
||||
|
||||
@versionadded(version='1.0', reason="This function is new")
|
||||
def function_one():
|
||||
'''This is the function one'''
|
||||
|
||||
|
||||
@versionchanged(version='1.0', reason="This function is modified")
|
||||
def function_two():
|
||||
'''This is the function two'''
|
||||
|
||||
|
||||
@deprecated(version='1.0', reason="This function will be removed soon")
|
||||
def function_three():
|
||||
'''This is the function three'''
|
||||
|
||||
|
||||
function_one()
|
||||
function_two()
|
||||
function_three() # warns
|
||||
|
||||
help(function_one)
|
||||
help(function_two)
|
||||
help(function_three)
|
||||
|
||||
|
||||
The result it immediate
|
||||
```````````````````````
|
||||
|
||||
Run it:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ python hello_sphinx.py
|
||||
|
||||
hello_sphinx.py:23: DeprecationWarning: Call to deprecated function (or staticmethod) function_three.
|
||||
(This function will be removed soon) -- Deprecated since version 1.0.
|
||||
function_three() # warns
|
||||
|
||||
Help on function function_one in module __main__:
|
||||
|
||||
function_one()
|
||||
This is the function one
|
||||
|
||||
.. versionadded:: 1.0
|
||||
This function is new
|
||||
|
||||
Help on function function_two in module __main__:
|
||||
|
||||
function_two()
|
||||
This is the function two
|
||||
|
||||
.. versionchanged:: 1.0
|
||||
This function is modified
|
||||
|
||||
Help on function function_three in module __main__:
|
||||
|
||||
function_three()
|
||||
This is the function three
|
||||
|
||||
.. deprecated:: 1.0
|
||||
This function will be removed soon
|
||||
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `Python package index (PyPi) <https://pypi.org/project/Deprecated/>`_
|
||||
* `GitHub website <https://github.com/laurent-laporte-pro/deprecated>`_
|
||||
* `Read The Docs <https://readthedocs.org/projects/deprecated>`_
|
||||
* `EBook on Lulu.com <http://www.lulu.com/commerce/index.php?fBuyContent=21305117>`_
|
||||
* `StackOverFlow Q&A <https://stackoverflow.com/a/40301488/1513933>`_
|
||||
* `Development version
|
||||
<https://github.com/laurent-laporte-pro/deprecated/zipball/master#egg=Deprecated-dev>`_
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
deprecated-1.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
deprecated-1.3.1.dist-info/METADATA,sha256=QJdnrCOHjBxpSIjOSsxD2razfvorQEmVZ_tcfZ3OWFI,5894
|
||||
deprecated-1.3.1.dist-info/RECORD,,
|
||||
deprecated-1.3.1.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
||||
deprecated-1.3.1.dist-info/licenses/LICENSE.rst,sha256=HoPt0VvkGbXVveNy4yXlJ_9PmRX1SOfHUxS0H2aZ6Dw,1081
|
||||
deprecated-1.3.1.dist-info/top_level.txt,sha256=nHbOYawKPQQE5lQl-toUB1JBRJjUyn_m_Mb8RVJ0RjA,11
|
||||
deprecated/__init__.py,sha256=owN3nj3UYte9J327NJNf_hNQTJovl813H_Q7YKhFX9M,398
|
||||
deprecated/__pycache__/__init__.cpython-312.pyc,,
|
||||
deprecated/__pycache__/classic.cpython-312.pyc,,
|
||||
deprecated/__pycache__/params.cpython-312.pyc,,
|
||||
deprecated/__pycache__/sphinx.cpython-312.pyc,,
|
||||
deprecated/classic.py,sha256=vWW-8nVvEejx4P9sf75vleE9JWbETaha_Sa-Bf9Beyo,10649
|
||||
deprecated/params.py,sha256=_bWRXLZGi2qF-EmZfgWjGe2G15WZabhOH_9Ntvt42cc,2870
|
||||
deprecated/sphinx.py,sha256=cOKnXbDyFAwDr5O7HBEpgQrx-J-qfp57sfdK_LabDxs,11109
|
||||
@@ -0,0 +1,6 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (80.9.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py2-none-any
|
||||
Tag: py3-none-any
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Laurent LAPORTE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1 @@
|
||||
deprecated
|
||||
Reference in New Issue
Block a user