0
# Core Interface
1
2
Low-level interface to the exiftool subprocess providing direct command execution, JSON parsing, and subprocess lifecycle management. The ExifTool class offers maximum control and flexibility for advanced users who need fine-grained control over the exiftool process.
3
4
## Capabilities
5
6
### Process Management
7
8
Control the exiftool subprocess lifecycle with start, stop, and context manager support.
9
10
```python { .api }
11
class ExifTool:
12
def __init__(self, executable=None, common_args=["-G", "-n"], win_shell=False, config_file=None, encoding=None, logger=None):
13
"""
14
Initialize ExifTool instance.
15
16
Parameters:
17
- executable: str or Path, path to exiftool executable (default: searches PATH)
18
- common_args: list of str, arguments included in every command (default: ["-G", "-n"])
19
- win_shell: bool, Windows shell visibility (default: False)
20
- config_file: str or Path, path to exiftool config file
21
- encoding: str, text encoding for subprocess communication (default: utf-8)
22
- logger: logger instance for debug output
23
"""
24
25
def run(self):
26
"""
27
Start the exiftool subprocess in batch mode.
28
29
Raises:
30
- ExifToolRunning: if subprocess is already running
31
- Various subprocess errors if startup fails
32
"""
33
34
def terminate(self, timeout=30, _del=False):
35
"""
36
Terminate the exiftool subprocess.
37
38
Parameters:
39
- timeout: int, seconds to wait for clean shutdown (default: 30)
40
- _del: bool, internal flag for destructor cleanup
41
"""
42
43
def __enter__(self):
44
"""Context manager entry - automatically calls run()"""
45
46
def __exit__(self, exc_type, exc_val, exc_tb):
47
"""Context manager exit - automatically calls terminate()"""
48
49
def __del__(self):
50
"""Destructor - automatically terminates subprocess if still running"""
51
```
52
53
### Command Execution
54
55
Execute exiftool commands directly with raw output or JSON parsing.
56
57
```python { .api }
58
def execute(self, *params, raw_bytes=False):
59
"""
60
Execute parameters with the exiftool subprocess.
61
62
Parameters:
63
- *params: str or bytes, command parameters to send to exiftool
64
- raw_bytes: bool, return bytes instead of str (default: False)
65
66
Returns:
67
str or bytes: command stdout output
68
69
Raises:
70
- ExifToolNotRunning: if subprocess is not running
71
- ExifToolVersionError: if version compatibility issues
72
- TypeError: if parameter types are invalid
73
"""
74
75
def execute_json(self, *params):
76
"""
77
Execute parameters and parse JSON output.
78
79
Parameters:
80
- *params: str or bytes, command parameters to send to exiftool
81
82
Returns:
83
list: parsed JSON as list of dictionaries
84
85
Raises:
86
- ExifToolOutputEmptyError: if no output received when expected
87
- ExifToolJSONInvalidError: if invalid JSON received
88
"""
89
```
90
91
### Configuration
92
93
Configure the ExifTool instance behavior and access runtime information.
94
95
```python { .api }
96
# Properties (read/write)
97
@property
98
def executable(self) -> Union[str, Path]:
99
"""Path to exiftool executable (can only be set when not running)"""
100
101
@property
102
def encoding(self) -> str:
103
"""Text encoding for subprocess communication (can only be set when not running)"""
104
105
@property
106
def block_size(self) -> int:
107
"""Block size for reading from subprocess pipes (default: 4096)"""
108
109
@property
110
def common_args(self) -> List[str]:
111
"""Common arguments included in every command (can only be set when not running)"""
112
113
@property
114
def config_file(self) -> Union[str, Path]:
115
"""Path to exiftool config file (can only be set when not running)"""
116
117
# Properties (read-only)
118
@property
119
def running(self) -> bool:
120
"""Whether the exiftool subprocess is currently running"""
121
122
@property
123
def version(self) -> str:
124
"""Version string of the running exiftool process (only available when running)"""
125
126
@property
127
def last_stdout(self) -> Union[str, bytes]:
128
"""STDOUT from most recent execute() call"""
129
130
@property
131
def last_stderr(self) -> Union[str, bytes]:
132
"""STDERR from most recent execute() call"""
133
134
@property
135
def last_status(self) -> int:
136
"""Exit status code from most recent execute() call"""
137
138
# Properties (write-only)
139
@property
140
def logger(self):
141
"""Set logger instance for debug output"""
142
```
143
144
### JSON Customization
145
146
Override the default JSON parser for performance or compatibility.
147
148
```python { .api }
149
def set_json_loads(self, json_loads, **kwargs):
150
"""
151
Override default JSON parser method.
152
153
Parameters:
154
- json_loads: callable, alternative JSON loading function (e.g., ujson.loads)
155
- **kwargs: additional arguments passed to the JSON loader
156
"""
157
```
158
159
## Usage Examples
160
161
### Basic Process Control
162
163
```python
164
import exiftool
165
166
# Manual process control
167
et = exiftool.ExifTool()
168
et.run()
169
try:
170
result = et.execute('-ver')
171
print(f"ExifTool version: {result}")
172
finally:
173
et.terminate()
174
175
# Context manager (recommended)
176
with exiftool.ExifTool() as et:
177
result = et.execute('-ver')
178
print(f"ExifTool version: {result}")
179
```
180
181
### Direct Command Execution
182
183
```python
184
with exiftool.ExifTool() as et:
185
# Get basic info
186
output = et.execute('-n', '-g', 'image.jpg')
187
188
# Get JSON output
189
metadata = et.execute_json('-j', 'image.jpg')
190
191
# Set tags
192
et.execute('-overwrite_original', '-EXIF:Artist=John Doe', 'image.jpg')
193
```
194
195
### Custom JSON Parser
196
197
```python
198
import ujson
199
import exiftool
200
201
with exiftool.ExifTool() as et:
202
# Use ujson for better performance
203
et.set_json_loads(ujson.loads)
204
metadata = et.execute_json('-j', 'large_file.jpg')
205
```
206
207
### Configuration Example
208
209
```python
210
import exiftool
211
212
# Custom configuration
213
et = exiftool.ExifTool(
214
executable='/usr/local/bin/exiftool',
215
common_args=['-G', '-n', '-q'], # Add quiet flag
216
encoding='utf-8',
217
config_file='my_exiftool.config'
218
)
219
220
with et:
221
# All commands will include common_args
222
result = et.execute('image.jpg') # Equivalent to: exiftool -G -n -q image.jpg
223
```