or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-metadata.mdfile-operations.mdindex.mdutilities.md

file-operations.mddocs/

0

# File Operations

1

2

The XMPFiles class provides convenient access to XMP metadata in files with smart handlers for various file formats. It manages file opening, XMP extraction, modification, and writing back to files.

3

4

## Capabilities

5

6

### XMPFiles Class

7

8

API for accessing main metadata in files with smart file handlers.

9

10

```python { .api }

11

class XMPFiles:

12

def __init__(self, **kwargs):

13

"""

14

Create XMPFiles instance.

15

16

Parameters:

17

- file_path (optional): str, path to file to open

18

"""

19

```

20

21

### File Operations

22

23

```python { .api }

24

def open_file(self, file_path, **kwargs):

25

"""

26

Open file and read XMP metadata.

27

28

Parameters:

29

- file_path: str, path to file

30

- **kwargs: optional keyword arguments from XMP_OPEN_OPTIONS

31

32

Raises:

33

XMPError: if file already open or operation fails

34

"""

35

36

def close_file(self, close_flags=0):

37

"""

38

Close file and write XMP changes.

39

40

Parameters:

41

- close_flags: int, optional close flags from XMP_CLOSE_OPTIONS

42

(default: XMP_CLOSE_NOOPTION)

43

"""

44

```

45

46

### Metadata Access

47

48

```python { .api }

49

def get_xmp(self):

50

"""

51

Get XMP metadata from file.

52

53

Returns:

54

XMPMeta: New XMPMeta instance with file's XMP data, or None if no XMP

55

56

Raises:

57

XMPError: on failure

58

"""

59

60

def put_xmp(self, xmp_obj):

61

"""

62

Write XMP metadata to file.

63

64

Parameters:

65

- xmp_obj: XMPMeta instance with XMP data to write

66

67

Raises:

68

XMPError: on failure

69

"""

70

71

def can_put_xmp(self, xmp_obj):

72

"""

73

Check if XMP can be written to file.

74

75

Parameters:

76

- xmp_obj: XMPMeta instance

77

78

Returns:

79

bool: True if XMP can be written to file

80

"""

81

```

82

83

## File Format Support

84

85

The XMPFiles class includes smart handlers for various file formats:

86

87

- **Image formats**: JPEG, TIFF, PNG, GIF, WebP

88

- **Document formats**: PDF, PostScript, EPS

89

- **RAW formats**: Camera RAW files (via Adobe Camera Raw)

90

- **Video formats**: Various multimedia formats

91

- **Generic**: Packet scanning fallback for unknown formats

92

93

## Open Options

94

95

Available options for `open_file()` method from `libxmp.consts`:

96

97

```python { .api }

98

XMP_OPEN_NOOPTION = 0x00000000 # No special options

99

XMP_OPEN_READ = 0x00000001 # Open for read-only access

100

XMP_OPEN_FORUPDATE = 0x00000002 # Open for read-write access

101

XMP_OPEN_ONLYXMP = 0x00000004 # Only process XMP, ignore other metadata

102

XMP_OPEN_CACHETNAIL = 0x00000008 # Cache thumbnail if present

103

XMP_OPEN_STRICTLY = 0x00000010 # Strict conformance checking

104

XMP_OPEN_USESMARTHANDLER = 0x00000020 # Use smart handlers

105

XMP_OPEN_USEPACKETSCANNING = 0x00000040 # Use packet scanning fallback

106

XMP_OPEN_LIMITSCANNING = 0x00000080 # Limit packet scanning

107

XMP_OPEN_INBACKGROUND = 0x10000000 # Set if calling from background thread

108

```

109

110

## Close Options

111

112

Available options for `close_file()` method:

113

114

```python { .api }

115

XMP_CLOSE_NOOPTION = 0x0000 # No special options

116

XMP_CLOSE_SAFEUPDATE = 0x0001 # Write XMP into safe temp file first

117

```

118

119

## Usage Examples

120

121

### Basic File Operations

122

123

```python

124

from libxmp import XMPFiles, XMPMeta, XMPError

125

126

# Open file and read XMP

127

try:

128

xmpfile = XMPFiles(file_path="photo.jpg")

129

xmp_data = xmpfile.get_xmp()

130

131

if xmp_data:

132

# Read existing metadata

133

creator = xmp_data.get_property("http://purl.org/dc/elements/1.1/", "creator")

134

print(f"Original creator: {creator}")

135

136

# Modify metadata

137

xmp_data.set_property("http://purl.org/dc/elements/1.1/", "creator", "Updated Creator")

138

xmp_data.set_property("http://ns.adobe.com/xap/1.0/", "CreatorTool", "Python XMP Toolkit")

139

140

# Write back to file

141

xmpfile.put_xmp(xmp_data)

142

else:

143

print("No XMP metadata found in file")

144

145

# Close file (writes changes)

146

xmpfile.close_file()

147

148

except XMPError as e:

149

print(f"XMP error: {e}")

150

```

151

152

### Working with Different File Types

153

154

```python

155

from libxmp import XMPFiles, XMPMeta

156

from libxmp.consts import XMP_OPEN_FORUPDATE, XMP_CLOSE_SAFEUPDATE

157

158

# Process multiple file types

159

file_paths = ["document.pdf", "image.tiff", "photo.jpg"]

160

161

for file_path in file_paths:

162

try:

163

# Open with specific options

164

xmpfile = XMPFiles()

165

xmpfile.open_file(file_path, open_forupdate=True)

166

167

xmp_data = xmpfile.get_xmp()

168

if not xmp_data:

169

# Create new XMP if none exists

170

xmp_data = XMPMeta()

171

172

# Add processing timestamp

173

from datetime import datetime

174

xmp_data.set_property_datetime(

175

"http://ns.adobe.com/xap/1.0/",

176

"ModifyDate",

177

datetime.now()

178

)

179

180

# Check if we can write XMP to this file type

181

if xmpfile.can_put_xmp(xmp_data):

182

xmpfile.put_xmp(xmp_data)

183

print(f"Updated XMP in {file_path}")

184

else:

185

print(f"Cannot write XMP to {file_path}")

186

187

# Close with safe update

188

xmpfile.close_file(close_flags=XMP_CLOSE_SAFEUPDATE)

189

190

except Exception as e:

191

print(f"Error processing {file_path}: {e}")

192

```

193

194

### Advanced File Handling

195

196

```python

197

from libxmp import XMPFiles, XMPMeta

198

from libxmp.consts import *

199

200

def process_file_metadata(file_path, metadata_updates):

201

"""

202

Process file metadata with comprehensive error handling.

203

204

Args:

205

file_path: Path to file

206

metadata_updates: Dict of namespace -> {property: value} mappings

207

"""

208

xmpfile = None

209

try:

210

# Open file with comprehensive options

211

xmpfile = XMPFiles()

212

xmpfile.open_file(

213

file_path,

214

open_forupdate=True,

215

open_usesmarthandler=True,

216

open_usepacketscanning=True

217

)

218

219

# Get existing XMP or create new

220

xmp_data = xmpfile.get_xmp()

221

if not xmp_data:

222

xmp_data = XMPMeta()

223

224

# Apply metadata updates

225

for namespace, properties in metadata_updates.items():

226

for prop_name, prop_value in properties.items():

227

if isinstance(prop_value, list):

228

# Handle arrays

229

for item in prop_value:

230

xmp_data.append_array_item(namespace, prop_name, item)

231

else:

232

# Handle simple properties

233

xmp_data.set_property(namespace, prop_name, prop_value)

234

235

# Verify we can write before attempting

236

if xmpfile.can_put_xmp(xmp_data):

237

xmpfile.put_xmp(xmp_data)

238

return True

239

else:

240

print(f"Cannot write XMP to {file_path}")

241

return False

242

243

except Exception as e:

244

print(f"Error processing {file_path}: {e}")

245

return False

246

247

finally:

248

if xmpfile:

249

try:

250

xmpfile.close_file(close_flags=XMP_CLOSE_SAFEUPDATE)

251

except:

252

pass # Ignore close errors after main operation failure

253

254

# Usage

255

updates = {

256

"http://purl.org/dc/elements/1.1/": {

257

"creator": "John Doe",

258

"subject": ["photography", "landscape", "nature"]

259

},

260

"http://ns.adobe.com/xap/1.0/": {

261

"CreatorTool": "Python XMP Toolkit"

262

}

263

}

264

265

success = process_file_metadata("photo.jpg", updates)

266

if success:

267

print("Metadata updated successfully")

268

```

269

270

## Error Handling

271

272

Common XMP file operation errors and handling:

273

274

```python

275

from libxmp import XMPFiles, XMPError, ExempiLoadError

276

277

try:

278

xmpfile = XMPFiles(file_path="example.jpg")

279

xmp_data = xmpfile.get_xmp()

280

# ... work with XMP data

281

282

except ExempiLoadError:

283

print("Exempi library could not be loaded - check installation")

284

285

except XMPError as e:

286

if "Permission denied" in str(e):

287

print("File access denied - check file permissions")

288

elif "No such file" in str(e):

289

print("File not found - check file path")

290

else:

291

print(f"XMP operation failed: {e}")

292

293

except IOError as e:

294

print(f"File I/O error: {e}")

295

296

finally:

297

# Always close file if opened

298

if 'xmpfile' in locals():

299

try:

300

xmpfile.close_file()

301

except:

302

pass # Ignore close errors

303

```