Skip to content

Commit a9f8af8

Browse files
committed
Documentation updates only. No functional changes.
FAQ - fix a typo in set_json_loads() FAQ - add a section in FAQ to use shlex to help debug argument splitting. Lots of issues are opened just on how to split arguments. - refer to the FAQ from the quickstart/examples page small tweak to the changelog
1 parent ce77f6d commit a9f8af8

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Date (Timezone) | Version | Comment
99
03/26/2022 06:48:01 AM (PDT) | 0.5.3 | Quite a few docstring changes<br>ExifToolHelper's get_tags() and set_tags() checks tag names to prevent inadvertent write behavior<br>Renamed a few of the errors to make sure the errors are explicit<br>ExifToolHelper() has some static helper methods which can be used when extending the class (ExifToolAlpha.set_keywords_batch() demonstrates a sample usage).<br>setup.py tweaked to make it Beta rather than Alpha<br>ExifToolAlpha.get_tag() updated to make it more robust.<br>Fixed ujson compatibility<br>Cleaned up and refactored testing.
1010
08/27/2022 06:06:32 PM (PDT) | 0.5.4 | New Feature: added raw_bytes parameter to ExifTool.execute() to return bytes only with no decoding conversion.<br>Changed: ExifTool.execute() now accepts both [str,bytes]. When given str, it will encode according to the ExifTool.encoding property.<br>Changed: ExifToolHelper.execute() now accepts Any type, and will do a str() on any non-str parameter.<br>Technical change: Popen() no longer uses an -encoding parameter, therefore working with the socket is back to bytes when interfacing with the exiftool subprocess. This should be invisible to most users as the default behavior will still be the same.<br>Tests: Created associated test with a custom makernotes example to write and read back bytes.<br>Docs: Updated documentation with comprehensive samples, and a better FAQ section for common problems.
1111
12/30/2022 02:35:18 PM (PST) | 0.5.5 | No functional changes, only a huge speed improvement with large operations :: Update: Speed up large responses from exiftool. Instead of using + string concatenation, uses list appends and reverse(), which results in a speedup of 10x+ for large operations. See more details from the [reported issue](https://github.com/sylikc/pyexiftool/issues/60) and [PR 61](https://github.com/sylikc/pyexiftool/pull/61) by [prutschman](https://github.com/prutschman)
12-
10/22/2023 03:21:46 PM (PDT) | 0.5.6 | New Feature: added method ExifTool.set_json_loads() which allows setting a method to replace the json.loads() called in ExifTool.execute_json().<br>This permits passing additional configuration parameters to address the [reported issue](https://github.com/sylikc/pyexiftool/issues/76).<br>All documentation has been updated and two accompanying FAQ entries have been written to describe the new functionality. Test cases have been written to test the new functionality and some baseline exiftool tests to ensure that the behavior remains consistent across tests.
12+
10/22/2023 03:21:46 PM (PDT) | 0.5.6 | New Feature: added method ExifTool.set_json_loads() which allows setting a method to replace the json.loads() called in ExifTool.execute_json(). Changed: ujson is no longer used by default when available. Use the set_json_loads() to enable manually<br>This permits passing additional configuration parameters to address the [reported issue](https://github.com/sylikc/pyexiftool/issues/76).<br>All documentation has been updated and two accompanying FAQ entries have been written to describe the new functionality. Test cases have been written to test the new functionality and some baseline exiftool tests to ensure that the behavior remains consistent across tests.
1313

1414

1515
Follow maintenance/release-process.html when releasing a version.

docs/source/examples.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Almost all methods in PyExifTool revolve around the usage of two methods from th
2323

2424
Because both methods are inherited by :py:class:`exiftool.ExifToolHelper` and :py:class:`exiftool.ExifToolAlpha`, you can call it from those classes as well.
2525

26+
27+
.. _examples input params:
28+
2629
Input parameters
2730
----------------
2831

@@ -32,6 +35,8 @@ Both methods take an argument list ``*args``. Examples:
3235

3336
As a general rule of thumb, if there is an **unquoted space on the command line** to *exiftool*, it's a **separate argument to the method** in PyExifTool.
3437

38+
If you have a working `exiftool` command-line but having trouble figuring out how to properly separate the arguments, please refer to the :ref:`FAQ <shlex split>`
39+
3540
* Calling directly:
3641

3742
* exiftool command-line:

docs/source/faq.rst

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,48 @@ So if you want to have the ouput match (*useful for debugging*) between PyExifTo
103103
Y Resolution : 72
104104
105105
106+
107+
.. _shlex split:
108+
109+
I can run this on the command-line but it doesn't work in PyExifTool
110+
====================================================================
111+
112+
A frequent problem encountered by first-time users, is figuring out how to properly split their arguments into a call to PyExifTool.
113+
114+
As noted in the :ref:`Quick Start Examples <examples input params>`:
115+
116+
If there is an **unquoted space on the command line** to *exiftool*, it's a **separate argument to the method** in PyExifTool.
117+
118+
So, what does this look like in practice?
119+
120+
Use `Python's shlex library`_ as a quick and easy way to figure out what the parameters to :py:meth:`exiftool.ExifTool.execute` or :py:meth:`exiftool.ExifTool.execute_json` should be.
121+
122+
* Sample exiftool command line (with multiple quoted and unquoted parameters):
123+
124+
.. code-block:: text
125+
126+
exiftool -v0 -preserve -overwrite_original -api largefilesupport=1 -api "QuickTimeUTC=1" "-EXIF:DateTimeOriginal+=1:2:3 4:5:6" -XMP:DateTimeOriginal="2006:05:04 03:02:01" -gpsaltituderef="Above Sea Level" -make= test.mov
127+
128+
* Using ``shlex`` to figure out the right argument list:
129+
130+
.. code-block::
131+
132+
import shlex, exiftool
133+
with exiftool.ExifToolHelper() as et:
134+
params = shlex.split('-v0 -preserve -overwrite_original -api largefilesupport=1 "-EXIF:DateTimeOriginal+=1:2:3 4:5:6" -XMP:DateTimeOriginal="2006:05:04 03:02:01" -gpsaltituderef="Above Sea Level" -make= test.mov')
135+
print(params)
136+
# Output: ['-v0', '-preserve', '-overwrite_original', '-api', 'largefilesupport=1', '-api', 'QuickTimeUTC=1', '-EXIF:DateTimeOriginal+=1:2:3 4:5:6', '-XMP:DateTimeOriginal=2006:05:04 03:02:01', '-gpsaltituderef=Above Sea Level', '-make=', 'test.mov']
137+
et.execute(*params)
138+
139+
.. note::
140+
141+
``shlex.split()`` is a useful *tool to simplify discovery* of the correct arguments needed to call PyExifTool.
142+
143+
However, since spliting and constructing immutable strings in Python is **slower than building the parameter list properly**, this method is *only recommended for* **debugging**!
144+
145+
146+
.. _`Python's shlex library`: https://docs.python.org/library/shlex.html
147+
106148
.. _set_json_loads faq:
107149

108150
PyExifTool json turns some text fields into numbers
@@ -157,7 +199,7 @@ However, as you can see below, it also *changes the behavior of all float fields
157199
et.set_tags("rose.jpg", {"Comment": "1.10"}) # string: "1.10" == "1.10"
158200
159201
# FocalLength is a FLOAT field
160-
et.set_tags("rose.jpg", {"FocalLength": 1.10}) # float: 1.1 == "1.1"
202+
et.set_tags("rose.jpg", {"FocalLength": 1.10}) # float: 1.1 != "1.1"
161203
print(et.get_tags("rose.jpg", ["Comment", "FocalLength"]))
162204
163205
# Prints: [{'SourceFile': 'rose.jpg', 'File:Comment': '1.10', 'EXIF:FocalLength': '1.1'}]

0 commit comments

Comments
 (0)