content-types 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: content-types
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: A library to map file extensions to content types and vice versa.
5
+ Project-URL: Homepage, https://github.com/mikeckennedy/content-types
6
+ Project-URL: Bug Reports, https://github.com/mikeckennedy/content-types/issues
7
+ Project-URL: Source, https://github.com/mikeckennedy/content-types
5
8
  Author-email: Michael Kennedy <mikeckennedy@gmail.com>
6
9
  License-Expression: MIT
7
10
  License-File: LICENSE
@@ -26,6 +29,12 @@ A Python library to map file extensions to MIME types.
26
29
  It also provides a CLI for quick lookups right from your terminal.
27
30
  If no known mapping is found, the tool returns `application/octet-stream`.
28
31
 
32
+ Unlike other libraries, this one does **not** try to access the file
33
+ or parse the bytes of the file or stream. It just looks at the extension
34
+ which is valuable when you don't have access to the file directly.
35
+ For example, you know the filename but it is stored in s3 and you don't want
36
+ to download it just to fully inspect the file.
37
+
29
38
  ## Installation
30
39
 
31
40
  ```bash
@@ -38,19 +47,26 @@ uv pip install content-types
38
47
  import content_types
39
48
 
40
49
  # Forward lookup: filename -> MIME type
41
- mime_type = content_types.get_content_type("example.jpg")
42
- print(mime_type) # "image/jpeg"
50
+ the_type = content_types.get_content_type("example.jpg")
51
+ print(the_type) # "image/jpeg"
43
52
 
44
53
  # For very common files, you have shortcuts:
45
- print(f'Content-Type for webp is {content_types.webp}') # 'image/webp'
54
+ print(f'Content-Type for webp is {content_types.webp}.')
55
+ # Content-Type for webp is image/webp.
46
56
  ```
47
57
 
48
58
  ## CLI
49
59
 
50
- After installing in a virtual environment or system-wide.
60
+ To use the library as a CLI tool, just install it with **uv** or **pipx**.
61
+
62
+ ```bash
63
+ uv tool install content-types
64
+ ```
65
+
66
+ Now it will be available machine-wide.
51
67
 
52
68
  ```bash
53
- contenttypes example.jpg
69
+ content-types example.jpg
54
70
 
55
71
  # Outputs image/jpeg
56
72
  ```
@@ -0,0 +1,53 @@
1
+
2
+ # content-types 🗃️🔎
3
+
4
+ A Python library to map file extensions to MIME types.
5
+ It also provides a CLI for quick lookups right from your terminal.
6
+ If no known mapping is found, the tool returns `application/octet-stream`.
7
+
8
+ Unlike other libraries, this one does **not** try to access the file
9
+ or parse the bytes of the file or stream. It just looks at the extension
10
+ which is valuable when you don't have access to the file directly.
11
+ For example, you know the filename but it is stored in s3 and you don't want
12
+ to download it just to fully inspect the file.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ uv pip install content-types
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```python
23
+ import content_types
24
+
25
+ # Forward lookup: filename -> MIME type
26
+ the_type = content_types.get_content_type("example.jpg")
27
+ print(the_type) # "image/jpeg"
28
+
29
+ # For very common files, you have shortcuts:
30
+ print(f'Content-Type for webp is {content_types.webp}.')
31
+ # Content-Type for webp is image/webp.
32
+ ```
33
+
34
+ ## CLI
35
+
36
+ To use the library as a CLI tool, just install it with **uv** or **pipx**.
37
+
38
+ ```bash
39
+ uv tool install content-types
40
+ ```
41
+
42
+ Now it will be available machine-wide.
43
+
44
+ ```bash
45
+ content-types example.jpg
46
+
47
+ # Outputs image/jpeg
48
+ ```
49
+
50
+ ## Contributing
51
+
52
+ Contributions are welcome! Check out [the GitHub repo](https://github.com/mikeckennedy/content-types)
53
+ for more details on how to get involved.
@@ -0,0 +1,287 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from typing import Dict
4
+
5
+ __VERSION__ = '0.2.2'
6
+
7
+ # This dictionary maps file extensions (no dot) to the most specific content type.
8
+
9
+ # noinspection SpellCheckingInspection
10
+ EXTENSION_TO_CONTENT_TYPE: Dict[str, str] = {
11
+ # Text
12
+ 'txt': 'text/plain',
13
+ 'htm': 'text/html',
14
+ 'html': 'text/html',
15
+ 'css': 'text/css',
16
+ 'csv': 'text/csv',
17
+ 'tsv': 'text/tab-separated-values',
18
+ # JavaScript
19
+ 'js': 'application/javascript', # commonly "application/javascript" nowadays
20
+ # MJS for ES modules
21
+ 'mjs': 'application/javascript',
22
+ # JSON
23
+ 'json': 'application/json',
24
+ 'map': 'application/json',
25
+ # XML (keep application/xml)
26
+ 'xml': 'application/xml',
27
+ # Images
28
+ 'jpg': 'image/jpeg',
29
+ 'jpeg': 'image/jpeg',
30
+ 'png': 'image/png',
31
+ 'gif': 'image/gif',
32
+ 'bmp': 'image/bmp',
33
+ 'webp': 'image/webp',
34
+ 'avif': 'image/avif',
35
+ # Some new ones:
36
+ 'ico': 'image/x-icon',
37
+ 'svg': 'image/svg+xml',
38
+ 'tif': 'image/tiff',
39
+ 'tiff': 'image/tiff',
40
+ 'heic': 'image/heic', # new
41
+ 'heif': 'image/heif', # new
42
+ 'jpe': 'image/jpeg', # new alias
43
+ 'ief': 'image/ief', # new
44
+ 'ras': 'image/x-cmu-raster', # new
45
+ 'pnm': 'image/x-portable-anymap',
46
+ 'pbm': 'image/x-portable-bitmap',
47
+ 'pgm': 'image/x-portable-graymap',
48
+ 'ppm': 'image/x-portable-pixmap',
49
+ 'rgb': 'image/x-rgb',
50
+ 'xbm': 'image/x-xbitmap',
51
+ 'xpm': 'image/x-xpixmap',
52
+ 'xwd': 'image/x-xwindowdump',
53
+ # Audio
54
+ 'mp3': 'audio/mpeg',
55
+ 'ogg': 'audio/ogg',
56
+ 'wav': 'audio/wav',
57
+ 'aac': 'audio/aac',
58
+ 'flac': 'audio/flac',
59
+ 'm4a': 'audio/mp4',
60
+ 'weba': 'audio/webm',
61
+ # New ones:
62
+ 'mp2': 'audio/mpeg', # new
63
+ 'opus': 'audio/opus', # new
64
+ 'aif': 'audio/x-aiff',
65
+ 'aifc': 'audio/x-aiff',
66
+ 'aiff': 'audio/x-aiff',
67
+ 'au': 'audio/basic',
68
+ 'snd': 'audio/basic',
69
+ 'ra': 'audio/x-pn-realaudio',
70
+ # Video
71
+ 'mp4': 'video/mp4',
72
+ 'm4v': 'video/mp4',
73
+ 'mov': 'video/quicktime',
74
+ 'avi': 'video/x-msvideo',
75
+ 'wmv': 'video/x-ms-wmv',
76
+ 'mpg': 'video/mpeg',
77
+ 'mpeg': 'video/mpeg',
78
+ 'ogv': 'video/ogg',
79
+ 'webm': 'video/webm',
80
+ # New aliases:
81
+ 'm1v': 'video/mpeg',
82
+ 'mpa': 'video/mpeg',
83
+ 'mpe': 'video/mpeg',
84
+ 'qt': 'video/quicktime',
85
+ 'movie': 'video/x-sgi-movie',
86
+ # 3GP family (prefer official video/*):
87
+ '3gp': 'video/3gpp',
88
+ '3gpp': 'video/3gpp',
89
+ '3g2': 'video/3gpp2',
90
+ '3gpp2': 'video/3gpp2',
91
+ # Archives / Packages
92
+ 'pdf': 'application/pdf',
93
+ 'zip': 'application/zip',
94
+ 'gz': 'application/gzip',
95
+ 'tgz': 'application/gzip',
96
+ 'tar': 'application/x-tar',
97
+ '7z': 'application/x-7z-compressed',
98
+ 'rar': 'application/vnd.rar',
99
+ # Additional
100
+ 'bin': 'application/octet-stream', # new explicit
101
+ 'a': 'application/octet-stream',
102
+ 'so': 'application/octet-stream',
103
+ 'o': 'application/octet-stream',
104
+ 'obj': 'model/obj', # keep from original (not octet-stream)
105
+ 'dll': 'application/x-msdownload',
106
+ 'exe': 'application/x-msdownload',
107
+ # Some additional archiving/compression tools
108
+ 'bcpio': 'application/x-bcpio',
109
+ 'cpio': 'application/x-cpio',
110
+ 'shar': 'application/x-shar',
111
+ 'sv4cpio': 'application/x-sv4cpio',
112
+ 'sv4crc': 'application/x-sv4crc',
113
+ 'ustar': 'application/x-ustar',
114
+ 'src': 'application/x-wais-source',
115
+ # Application / Office
116
+ 'doc': 'application/msword',
117
+ 'xls': 'application/vnd.ms-excel',
118
+ 'ppt': 'application/vnd.ms-powerpoint',
119
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
120
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
121
+ 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
122
+ # New ones:
123
+ 'dot': 'application/msword',
124
+ 'wiz': 'application/msword',
125
+ 'xlb': 'application/vnd.ms-excel',
126
+ 'pot': 'application/vnd.ms-powerpoint',
127
+ 'ppa': 'application/vnd.ms-powerpoint',
128
+ 'pps': 'application/vnd.ms-powerpoint',
129
+ 'pwz': 'application/vnd.ms-powerpoint',
130
+ # Additional special apps
131
+ 'webmanifest': 'application/manifest+json',
132
+ 'nq': 'application/n-quads',
133
+ 'nt': 'application/n-triples',
134
+ 'oda': 'application/oda',
135
+ 'p7c': 'application/pkcs7-mime',
136
+ 'ps': 'application/postscript',
137
+ 'ai': 'application/postscript',
138
+ 'eps': 'application/postscript',
139
+ 'trig': 'application/trig',
140
+ 'm3u': 'application/vnd.apple.mpegurl',
141
+ 'm3u8': 'application/vnd.apple.mpegurl',
142
+ 'wasm': 'application/wasm',
143
+ 'csh': 'application/x-csh',
144
+ 'dvi': 'application/x-dvi',
145
+ 'gtar': 'application/x-gtar',
146
+ 'hdf': 'application/x-hdf',
147
+ 'h5': 'application/x-hdf5', # not in older standard lists but sometimes used
148
+ 'latex': 'application/x-latex',
149
+ 'mif': 'application/x-mif',
150
+ 'cdf': 'application/x-netcdf',
151
+ 'nc': 'application/x-netcdf',
152
+ 'p12': 'application/x-pkcs12',
153
+ 'pfx': 'application/x-pkcs12',
154
+ 'ram': 'application/x-pn-realaudio',
155
+ 'pyc': 'application/x-python-code',
156
+ 'pyo': 'application/x-python-code',
157
+ 'swf': 'application/x-shockwave-flash',
158
+ 'tcl': 'application/x-tcl',
159
+ 'tex': 'application/x-tex',
160
+ 'texi': 'application/x-texinfo',
161
+ 'texinfo': 'application/x-texinfo',
162
+ 'roff': 'application/x-troff',
163
+ 't': 'application/x-troff',
164
+ 'tr': 'application/x-troff',
165
+ 'man': 'application/x-troff-man',
166
+ 'me': 'application/x-troff-me',
167
+ 'ms': 'application/x-troff-ms',
168
+ # More XML-based
169
+ 'xsl': 'application/xml',
170
+ 'rdf': 'application/xml',
171
+ 'wsdl': 'application/xml',
172
+ 'xpdl': 'application/xml',
173
+ # ODF
174
+ 'odt': 'application/vnd.oasis.opendocument.text',
175
+ 'ods': 'application/vnd.oasis.opendocument.spreadsheet',
176
+ 'odp': 'application/vnd.oasis.opendocument.presentation',
177
+ 'odg': 'application/vnd.oasis.opendocument.graphics',
178
+ # Fonts
179
+ 'otf': 'font/otf',
180
+ 'ttf': 'font/ttf',
181
+ 'woff': 'font/woff',
182
+ 'woff2': 'font/woff2',
183
+ # 3D
184
+ 'gltf': 'model/gltf+json',
185
+ 'glb': 'model/gltf-binary',
186
+ 'stl': 'model/stl',
187
+ # Scripts / Misc
188
+ 'sh': 'application/x-sh',
189
+ 'php': 'application/x-httpd-php',
190
+ # Code files
191
+ 'py': 'text/x-python', # new (rather than text/plain)
192
+ 'c': 'text/plain', # some prefer text/x-c; we’ll keep text/plain
193
+ 'h': 'text/plain',
194
+ 'ksh': 'text/plain',
195
+ 'pl': 'text/plain',
196
+ 'bat': 'text/plain',
197
+ # Packages etc.
198
+ 'apk': 'application/vnd.android.package-archive',
199
+ 'deb': 'application/x-debian-package',
200
+ 'rpm': 'application/x-rpm',
201
+ # Messages
202
+ 'eml': 'message/rfc822',
203
+ 'mht': 'message/rfc822',
204
+ 'mhtml': 'message/rfc822',
205
+ 'nws': 'message/rfc822',
206
+ # Markdown / Markup
207
+ 'md': 'text/markdown',
208
+ 'markdown': 'text/markdown',
209
+ # RDF-ish / text-ish
210
+ 'n3': 'text/n3',
211
+ 'rtx': 'text/richtext',
212
+ 'rtf': 'text/rtf',
213
+ 'srt': 'text/plain',
214
+ 'vtt': 'text/vtt',
215
+ 'etx': 'text/x-setext',
216
+ 'sgm': 'text/x-sgml',
217
+ 'sgml': 'text/x-sgml',
218
+ 'vcf': 'text/x-vcard',
219
+ }
220
+
221
+
222
+ def get_content_type(filename_or_extension: str | Path, treat_as_binary: bool = True) -> str:
223
+ """
224
+ Given a filename (or just an extension), return the most specific,
225
+ commonly accepted MIME type based on extension.
226
+
227
+ Falls back to 'application/octet-stream' if not found.
228
+
229
+ Example:
230
+ >>> get_content_type("picture.jpg")
231
+ 'image/jpeg'
232
+ >>> get_content_type(".webp")
233
+ 'image/webp'
234
+ >>> get_content_type("script.js")
235
+ 'application/javascript'
236
+ >>> get_content_type("unknown.xyz")
237
+ 'application/octet-stream'
238
+ >>> get_content_type("unknown.xyz", treat_as_binary=False)
239
+ 'application/octet-stream'
240
+ """
241
+
242
+ if filename_or_extension is None:
243
+ raise Exception('filename cannot be None.')
244
+
245
+ if isinstance(filename_or_extension, Path):
246
+ filename_or_extension = filename_or_extension.suffix
247
+
248
+ if '.' not in filename_or_extension:
249
+ filename_or_extension = f'.{filename_or_extension}'
250
+
251
+ # Split by dot, take the last part as extension
252
+ # e.g., "archive.tar.gz" => "gz"
253
+ # Also handle cases like ".webp" => "webp"
254
+ dot_parts = filename_or_extension.lower().split('.')
255
+ ext = dot_parts[-1] if len(dot_parts) > 1 else ''
256
+
257
+ if treat_as_binary:
258
+ return EXTENSION_TO_CONTENT_TYPE.get(ext, 'application/octet-stream')
259
+
260
+ return EXTENSION_TO_CONTENT_TYPE.get(ext, 'text/plain')
261
+
262
+
263
+ webp: str = get_content_type('.webp')
264
+ png: str = get_content_type('.png')
265
+ jpg: str = get_content_type('.jpg')
266
+ mp3: str = get_content_type('.mp3')
267
+ json: str = get_content_type('.json')
268
+ pdf: str = get_content_type('.pdf')
269
+ zip: str = get_content_type('.zip') # noqa == it's fine to overwrite zip() in this module only.
270
+ xml: str = get_content_type('.xml')
271
+ csv: str = get_content_type('.csv')
272
+ md: str = get_content_type('.md')
273
+
274
+
275
+ def cli():
276
+ """
277
+ A simple CLI to look up the MIME type for a given filename or extension.
278
+ Usage example:
279
+ contenttypes my_file.jpg
280
+ """
281
+ if len(sys.argv) < 2:
282
+ print('Usage: contenttypes [FILENAME_OR_EXTENSION]\nExample: contenttypes .jpg')
283
+ sys.exit(1)
284
+
285
+ filename = sys.argv[1]
286
+ mime_type = get_content_type(filename)
287
+ print(mime_type)
File without changes
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "content-types"
7
- version = "0.2.0" # You can manage version bumps manually or use a plugin for dynamic versioning
7
+ version = "0.2.2" # You can manage version bumps manually or use a plugin for dynamic versioning
8
8
  description = "A library to map file extensions to content types and vice versa."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -31,5 +31,10 @@ classifiers = [
31
31
  "Topic :: Software Development :: Libraries :: Python Modules"
32
32
  ]
33
33
 
34
+ [project.urls]
35
+ "Homepage" = "https://github.com/mikeckennedy/content-types"
36
+ "Bug Reports" = "https://github.com/mikeckennedy/content-types/issues"
37
+ "Source" = "https://github.com/mikeckennedy/content-types"
38
+
34
39
  [project.scripts]
35
40
  content-types = "content_types:cli"
@@ -1,40 +0,0 @@
1
-
2
- # content-types 🗃️🔎
3
-
4
- A Python library to map file extensions to MIME types.
5
- It also provides a CLI for quick lookups right from your terminal.
6
- If no known mapping is found, the tool returns `application/octet-stream`.
7
-
8
- ## Installation
9
-
10
- ```bash
11
- uv pip install content-types
12
- ```
13
-
14
- ## Usage
15
-
16
- ```python
17
- import content_types
18
-
19
- # Forward lookup: filename -> MIME type
20
- mime_type = content_types.get_content_type("example.jpg")
21
- print(mime_type) # "image/jpeg"
22
-
23
- # For very common files, you have shortcuts:
24
- print(f'Content-Type for webp is {content_types.webp}') # 'image/webp'
25
- ```
26
-
27
- ## CLI
28
-
29
- After installing in a virtual environment or system-wide.
30
-
31
- ```bash
32
- contenttypes example.jpg
33
-
34
- # Outputs image/jpeg
35
- ```
36
-
37
- ## Contributing
38
-
39
- Contributions are welcome! Check out [the GitHub repo](https://github.com/mikeckennedy/content-types)
40
- for more details on how to get involved.
@@ -1,158 +0,0 @@
1
- import sys
2
- from pathlib import Path
3
- from typing import Dict
4
-
5
- __VERSION__ = '0.2.0'
6
-
7
- # This dictionary maps file extensions (no dot) to the most specific content type.
8
- EXTENSION_TO_CONTENT_TYPE: Dict[str, str] = {
9
- # Text
10
- 'txt': 'text/plain',
11
- 'htm': 'text/html',
12
- 'html': 'text/html',
13
- 'css': 'text/css',
14
- 'csv': 'text/csv',
15
- 'tsv': 'text/tab-separated-values',
16
- # JavaScript
17
- 'js': 'application/javascript', # commonly "application/javascript" nowadays
18
- # JSON
19
- 'json': 'application/json',
20
- 'map': 'application/json', # e.g., SourceMap
21
- # XML
22
- 'xml': 'application/xml', # can also be "text/xml" in some contexts
23
- # Images
24
- 'jpg': 'image/jpeg',
25
- 'jpeg': 'image/jpeg',
26
- 'png': 'image/png',
27
- 'gif': 'image/gif',
28
- 'bmp': 'image/bmp',
29
- 'webp': 'image/webp',
30
- 'avif': 'image/avif',
31
- 'ico': 'image/x-icon', # sometimes "image/vnd.microsoft.icon"
32
- 'svg': 'image/svg+xml',
33
- 'tif': 'image/tiff',
34
- 'tiff': 'image/tiff',
35
- # Audio
36
- 'mp3': 'audio/mpeg',
37
- 'ogg': 'audio/ogg',
38
- 'wav': 'audio/wav',
39
- 'aac': 'audio/aac',
40
- 'flac': 'audio/flac',
41
- 'm4a': 'audio/mp4',
42
- 'weba': 'audio/webm',
43
- # Video
44
- 'mp4': 'video/mp4',
45
- 'm4v': 'video/mp4', # often container-based
46
- 'mov': 'video/quicktime',
47
- 'avi': 'video/x-msvideo',
48
- 'wmv': 'video/x-ms-wmv',
49
- 'mpg': 'video/mpeg',
50
- 'mpeg': 'video/mpeg',
51
- 'ogv': 'video/ogg',
52
- 'webm': 'video/webm',
53
- # Application / Archive
54
- 'pdf': 'application/pdf',
55
- 'zip': 'application/zip',
56
- 'gz': 'application/gzip',
57
- 'tgz': 'application/gzip', # or "application/x-tar" + "gzip"
58
- 'tar': 'application/x-tar',
59
- '7z': 'application/x-7z-compressed',
60
- 'rar': 'application/vnd.rar',
61
- # Office
62
- 'doc': 'application/msword',
63
- 'xls': 'application/vnd.ms-excel',
64
- 'ppt': 'application/vnd.ms-powerpoint',
65
- 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
66
- 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
67
- 'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
68
- # OpenDocument
69
- 'odt': 'application/vnd.oasis.opendocument.text',
70
- 'ods': 'application/vnd.oasis.opendocument.spreadsheet',
71
- 'odp': 'application/vnd.oasis.opendocument.presentation',
72
- 'odg': 'application/vnd.oasis.opendocument.graphics',
73
- # Fonts
74
- 'otf': 'font/otf',
75
- 'ttf': 'font/ttf',
76
- 'woff': 'font/woff',
77
- 'woff2': 'font/woff2',
78
- # 3D model
79
- 'gltf': 'model/gltf+json',
80
- 'glb': 'model/gltf-binary',
81
- 'stl': 'model/stl',
82
- 'obj': 'model/obj', # not officially registered; widely used
83
- # Scripts / misc
84
- 'sh': 'application/x-sh',
85
- 'php': 'application/x-httpd-php', # Usually not used at runtime for real responses
86
- 'exe': 'application/x-msdownload',
87
- # Misc
88
- 'apk': 'application/vnd.android.package-archive',
89
- 'deb': 'application/x-debian-package',
90
- 'rpm': 'application/x-rpm',
91
- }
92
-
93
-
94
- def get_content_type(filename_or_extension: str | Path, treat_as_binary: bool = True) -> str:
95
- """
96
- Given a filename (or just an extension), return the most specific,
97
- commonly accepted MIME type based on extension.
98
-
99
- Falls back to 'application/octet-stream' if not found.
100
-
101
- Example:
102
- >>> get_content_type("picture.jpg")
103
- 'image/jpeg'
104
- >>> get_content_type(".webp")
105
- 'image/webp'
106
- >>> get_content_type("script.js")
107
- 'application/javascript'
108
- >>> get_content_type("unknown.xyz")
109
- 'application/octet-stream'
110
- >>> get_content_type("unknown.xyz", treat_as_binary=False)
111
- 'application/octet-stream'
112
- """
113
-
114
- if filename_or_extension is None:
115
- raise Exception('filename cannot be None.')
116
-
117
- if isinstance(filename_or_extension, Path):
118
- filename_or_extension = filename_or_extension.suffix
119
-
120
- if '.' not in filename_or_extension:
121
- filename_or_extension = f'.{filename_or_extension}'
122
-
123
- # Split by dot, take the last part as extension
124
- # e.g., "archive.tar.gz" => "gz"
125
- # Also handle cases like ".webp" => "webp"
126
- dot_parts = filename_or_extension.lower().split('.')
127
- ext = dot_parts[-1] if len(dot_parts) > 1 else ''
128
-
129
- if treat_as_binary:
130
- return EXTENSION_TO_CONTENT_TYPE.get(ext, 'application/octet-stream')
131
-
132
- return EXTENSION_TO_CONTENT_TYPE.get(ext, 'text/plain')
133
-
134
-
135
- webp: str = get_content_type('.webp')
136
- png: str = get_content_type('.png')
137
- jpg: str = get_content_type('.jpg')
138
- mp3: str = get_content_type('.mp3')
139
- json: str = get_content_type('.json')
140
- pdf: str = get_content_type('.pdf')
141
- zip: str = get_content_type('.zip') # noqa == it's fine to overwrite zip() in this module only.
142
- xml: str = get_content_type('.xml')
143
- csv: str = get_content_type('.csv')
144
-
145
-
146
- def cli():
147
- """
148
- A simple CLI to look up the MIME type for a given filename or extension.
149
- Usage example:
150
- contenttypes my_file.jpg
151
- """
152
- if len(sys.argv) < 2:
153
- print('Usage: contenttypes [FILENAME_OR_EXTENSION]\nExample: contenttypes .jpg')
154
- sys.exit(1)
155
-
156
- filename = sys.argv[1]
157
- mime_type = get_content_type(filename)
158
- print(mime_type)
File without changes
File without changes
File without changes