diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/code-comments.xml b/.idea/code-comments.xml deleted file mode 100644 index ec569269..00000000 --- a/.idea/code-comments.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 065b6a4f..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da..00000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 609296b8..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 11a4e0a0..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/piccolo_api.iml b/.idea/piccolo_api.iml deleted file mode 100644 index cb5d6408..00000000 --- a/.idea/piccolo_api.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/piccolo_api/media/base.py b/piccolo_api/media/base.py index f2e6548a..e5bad626 100644 --- a/piccolo_api/media/base.py +++ b/piccolo_api/media/base.py @@ -68,7 +68,7 @@ "_", ".", "(", - ")", + ")" ) diff --git a/piccolo_api/media/content_type.py b/piccolo_api/media/content_type.py index 508c2a75..0eeead7a 100644 --- a/piccolo_api/media/content_type.py +++ b/piccolo_api/media/content_type.py @@ -1,79 +1,77 @@ -CONTENT_TYPE = { - "aac": "audio/aac", - "abw": "application/x-abiword", - "arc": "application/x-freearc", - "avif": "image/avif", - "avi": "video/x-msvideo", - "azw": "application/vnd.amazon.ebook", - "bin": "application/octet-stream", - "bmp": "image/bmp", - "bz": "application/x-bzip", - "bz2": "application/x-bzip2", - "cda": "application/x-cdf", - "csh": "application/x-csh", - "css": "text/css", - "csv": "text/csv", - "doc": "application/msword", - "docx": "application/vnd.openxmlformats-officedocument" - ".wordprocessingml.document", - "eot": "application/vnd.ms-fontobject", - "epub": "application/epub+zip", - "gz": "application/gzip", - "gif": "image/gif", - "htm": "text/html", - "ico": "image/vnd.microsoft.icon", - "ics": "text/calendar", - "jar": "application/java-archive", - "jpeg": "image/jpeg", - "js": "text/javascript", - "json": "application/json", - "jsonld": "application/ld+json", - "mid": "audio/x-midi", - "mjs": "text/javascript", - "mp3": "audio/mpeg", - "mp4": "video/mp4", - "mpeg": "video/mpeg", - "mpkg": "application/vnd.apple.installer+xml", - "odp": "application/vnd.oasis.opendocument.presentation", - "ods": "application/vnd.oasis.opendocument.spreadsheet", - "odt": "application/vnd.oasis.opendocument.text", - "oga": "audio/ogg", - "ogv": "video/ogg", - "ogx": "application/ogg", - "opus": "audio/opus", - "otf": "font/otf", - "png": "image/png", - "pdf": "application/pdf", - "php": "application/x-httpd-php", - "ppt": "application/vnd.ms-powerpoint", - "pptx": "application/vnd.openxmlformats-officedocument" - ".presentationml.presentation", - "rar": "application/vnd.rar", - "rtf": "application/rtf", - "sh": "application/x-sh", - "svg": "image/svg+xml", - "swf": "application/x-shockwave-flash", - "tar": "application/x-tar", - "tif": "image/tiff", - "tiff": "image/tiff", - "ts": "video/mp2t", - "ttf": "font/ttf", - "txt": "text/plain", - "vsd": "application/vnd.visio", - "wav": "audio/wav", - "weba": "audio/webm", - "webm": "video/webm", - "webp": "image/webp", - "woff": "font/woff", - "woff2": "font/woff2", - "xhtml": "application/xhtml+xml", - "xls": "application/vnd.ms-excel", - "xlsx": "application/vnd.openxmlformats-officedocument" - ".spreadsheetml.sheet", - "xml": "application/xml", - "xul": "application/vnd.mozilla.xul+xml", - "zip": "application/zip", - "3gp": "video/3gpp", - "3g2": "video/3gpp2", - "7z": "application/x-7z-compressed", -} +CONTENT_TYPE = {"aac": "audio/aac", + "abw": "application/x-abiword", + "arc": "application/x-freearc", + "avif": "image/avif", + "avi": "video/x-msvideo", + "azw": "application/vnd.amazon.ebook", + "bin": "application/octet-stream", + "bmp": "image/bmp", + "bz": "application/x-bzip", + "bz2": "application/x-bzip2", + "cda": "application/x-cdf", + "csh": "application/x-csh", + "css": "text/css", + "csv": "text/csv", + "doc": "application/msword", + "docx": "application/vnd.openxmlformats-officedocument" + ".wordprocessingml.document", + "eot": "application/vnd.ms-fontobject", + "epub": "application/epub+zip", "gz": "application/gzip", + "gif": "image/gif", + "htm": "text/html", + "ico": "image/vnd.microsoft.icon", + "ics": "text/calendar", + "jar": "application/java-archive", + "jpeg": "image/jpeg", + "js": "text/javascript", + "json": "application/json", + "jsonld": "application/ld+json", + "mid": "audio/x-midi", + "mjs": "text/javascript", + "mp3": "audio/mpeg", + "mp4": "video/mp4", + "mpeg": "video/mpeg", + "mpkg": "application/vnd.apple.installer+xml", + "odp": "application/vnd.oasis.opendocument.presentation", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "odt": "application/vnd.oasis.opendocument.text", + "oga": "audio/ogg", + "ogv": "video/ogg", + "ogx": "application/ogg", + "opus": "audio/opus", + "otf": "font/otf", + "png": "image/png", + "pdf": "application/pdf", + "php": "application/x-httpd-php", + "ppt": "application/vnd.ms-powerpoint", + "pptx": "application/vnd.openxmlformats-officedocument" + ".presentationml.presentation", + "rar": "application/vnd.rar", + "rtf": "application/rtf", + "sh": "application/x-sh", + "svg": "image/svg+xml", + "swf": "application/x-shockwave-flash", + "tar": "application/x-tar", + "tif": "image/tiff", + "tiff": "image/tiff", + "ts": "video/mp2t", + "ttf": "font/ttf", + "txt": "text/plain", + "vsd": "application/vnd.visio", + "wav": "audio/wav", + "weba": "audio/webm", + "webm": "video/webm", + "webp": "image/webp", + "woff": "font/woff", + "woff2": "font/woff2", + "xhtml": "application/xhtml+xml", + "xls": "application/vnd.ms-excel", + "xlsx": "application/vnd.openxmlformats-officedocument" + ".spreadsheetml.sheet", + "xml": "application/xml", + "xul": "application/vnd.mozilla.xul+xml", + "zip": "application/zip", + "3gp": "video/3gpp", + "3g2": "video/3gpp2", + "7z": "application/x-7z-compressed", + } diff --git a/piccolo_api/media/s3.py b/piccolo_api/media/s3.py index e5f0a1bc..f98f2919 100644 --- a/piccolo_api/media/s3.py +++ b/piccolo_api/media/s3.py @@ -19,18 +19,18 @@ class S3MediaStorage(MediaStorage): def __init__( - self, - column: t.Union[Text, Varchar, Array], - bucket_name: str, - folder_name: str, - cache_max_age: t.Optional[int] = None, - default_acl: str = "private", - connection_kwargs: t.Dict[str, t.Any] = None, - user_defined_meta: t.Dict[str, t.Any] = None, - signed_url_expiry: int = 3600, - executor: t.Optional[Executor] = None, - allowed_extensions: t.Optional[t.Sequence[str]] = ALLOWED_EXTENSIONS, - allowed_characters: t.Optional[t.Sequence[str]] = ALLOWED_CHARACTERS, + self, + column: t.Union[Text, Varchar, Array], + bucket_name: str, + folder_name: str, + cache_max_age: t.Optional[int] = None, + default_acl: str = "private", + connection_kwargs: t.Dict[str, t.Any] = None, + user_defined_meta: t.Dict[str, t.Any] = None, + signed_url_expiry: int = 3600, + executor: t.Optional[Executor] = None, + allowed_extensions: t.Optional[t.Sequence[str]] = ALLOWED_EXTENSIONS, + allowed_characters: t.Optional[t.Sequence[str]] = ALLOWED_CHARACTERS, ): """ Stores media files in S3 compatible storage. This is a good option when @@ -56,8 +56,8 @@ def __init__( :param default_acl: Defines the visibility of the file uploaded. :param user_defined_meta: - Assign Meta Data to the file other than system metadata - For details read AWS S3 documentation + Assign Meta Data to the file other than system metadata + For details read AWS S3 documentation :param connection_kwargs: These kwargs are passed directly to ``boto3``. Learn more about `available options `_. @@ -125,7 +125,7 @@ def get_client(self): # pragma: no cover return client async def store_file( - self, file_name: str, file: t.IO, user: t.Optional[BaseUser] = None + self, file_name: str, file: t.IO, user: t.Optional[BaseUser] = None ) -> str: loop = asyncio.get_running_loop() @@ -138,7 +138,7 @@ async def store_file( return file_key def store_file_sync( - self, file_name: str, file: t.IO, user: t.Optional[BaseUser] = None + self, file_name: str, file: t.IO, user: t.Optional[BaseUser] = None ) -> str: """ A sync wrapper around :meth:`store_file`. @@ -146,28 +146,25 @@ def store_file_sync( file_key = self.generate_file_key(file_name=file_name, user=user) extension = file_key.rsplit(".", 1)[-1] client = self.get_client() - metadata: t.Dict[str, t.Any] = { - "ACL": self.default_acl, - "ContentDisposition": "inline", - } + metadata = {'ACL': self.default_acl, 'ContentDisposition': 'inline'} if extension in CONTENT_TYPE: - metadata["ContentType"] = CONTENT_TYPE[extension] + metadata['ContentType'] = CONTENT_TYPE[extension] if self.cache_max_age: - metadata["CacheControl"] = f"max-age={self.cache_max_age}" + metadata['CacheControl'] = f'max-age={self.cache_max_age}' if self.user_defined_meta: - metadata["Metadata"] = self.user_defined_meta + metadata['Metadata'] = self.user_defined_meta client.upload_fileobj( file, self.bucket_name, str(pathlib.Path(self.folder_name, file_key)), - ExtraArgs=metadata, + ExtraArgs=metadata ) return file_key async def generate_file_url( - self, file_key: str, root_url: str, user: t.Optional[BaseUser] = None + self, file_key: str, root_url: str, user: t.Optional[BaseUser] = None ) -> str: """ This retrieves an absolute URL for the file. @@ -184,7 +181,7 @@ async def generate_file_url( return await loop.run_in_executor(self.executor, blocking_function) def generate_file_url_sync( - self, file_key: str, root_url: str, user: t.Optional[BaseUser] = None + self, file_key: str, root_url: str, user: t.Optional[BaseUser] = None ) -> str: """ A sync wrapper around :meth:`generate_file_url`. @@ -263,10 +260,10 @@ def bulk_delete_files_sync(self, file_keys: t.List[str]): while True: batch = file_keys[ - (iteration * batch_size) : ( # noqa: E203 - iteration + 1 * batch_size - ) - ] + (iteration * batch_size): ( # noqa: E203 + iteration + 1 * batch_size + ) + ] if not batch: # https://github.com/nedbat/coveragepy/issues/772 break # pragma: no cover diff --git a/tests/media/test_s3.py b/tests/media/test_s3.py index 552b31a3..c067d0da 100644 --- a/tests/media/test_s3.py +++ b/tests/media/test_s3.py @@ -60,8 +60,8 @@ def test_store_file(self, get_client: MagicMock, uuid_module: MagicMock): ) with open( - os.path.join(os.path.dirname(__file__), "test_files/bulb.jpg"), - "rb", + os.path.join(os.path.dirname(__file__), "test_files/bulb.jpg"), + "rb", ) as test_file: # Store the file file_key = asyncio.run(