pure-magic-rs 0.2.5__cp313-cp313t-musllinux_1_2_i686.whl
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.
- pure_magic_rs/__init__.py +5 -0
- pure_magic_rs/__init__.pyi +163 -0
- pure_magic_rs/pure_magic_rs.cpython-313t-i386-linux-musl.so +0 -0
- pure_magic_rs/py.typed +0 -0
- pure_magic_rs-0.2.5.dist-info/METADATA +111 -0
- pure_magic_rs-0.2.5.dist-info/RECORD +8 -0
- pure_magic_rs-0.2.5.dist-info/WHEEL +4 -0
- pure_magic_rs.libs/libgcc_s-f5fcfe20.so.1 +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from typing import List, Optional, Dict, Any
|
|
2
|
+
|
|
3
|
+
class Magic:
|
|
4
|
+
"""Represents a detected file type's "magic" information.
|
|
5
|
+
|
|
6
|
+
Attributes:
|
|
7
|
+
source (Optional[str]): The source of the magic detection.
|
|
8
|
+
message (str): A human-readable description of the detected type.
|
|
9
|
+
mime_type (str): The MIME type of the detected file.
|
|
10
|
+
creator_code (Optional[str]): The creator code, if available.
|
|
11
|
+
strength (int): The strength of the detection.
|
|
12
|
+
extensions (List[str]): Possible file extensions for the detected type.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def source(self) -> Optional[str]: ...
|
|
17
|
+
@property
|
|
18
|
+
def message(self) -> str: ...
|
|
19
|
+
@property
|
|
20
|
+
def mime_type(self) -> str: ...
|
|
21
|
+
@property
|
|
22
|
+
def creator_code(self) -> Optional[str]: ...
|
|
23
|
+
@property
|
|
24
|
+
def strength(self) -> int: ...
|
|
25
|
+
@property
|
|
26
|
+
def extensions(self) -> List[str]: ...
|
|
27
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
28
|
+
"""Convert this `Magic` instance into a Python dictionary.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
dict: A dictionary with keys `source`, `message`, `mime_type`,
|
|
32
|
+
`creator_code`, `strength`, and `extensions`.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
>>> magic_dict = magic_instance.to_dict()
|
|
36
|
+
>>> print(magic_dict["mime_type"])
|
|
37
|
+
"""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
class MagicDb:
|
|
41
|
+
"""A file type detection database using magic numbers.
|
|
42
|
+
|
|
43
|
+
This class provides methods to detect file types for both in-memory buffers
|
|
44
|
+
and files on disk.
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
>>> db = MagicDb()
|
|
48
|
+
>>> result = db.first_magic_file("example.txt")
|
|
49
|
+
>>> print(result.mime_type)
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(self) -> None: ...
|
|
53
|
+
def first_magic_buffer(self, input: bytes, extension: Optional[str] = ...) -> Magic:
|
|
54
|
+
"""Detect the first magic match for an in-memory buffer.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
input (bytes): The buffer to analyze.
|
|
58
|
+
extension (Optional[str]): Optional file extension hint.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Magic: The first detected magic result.
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
ValueError: If magic identification failed
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> with open("example.txt", "rb") as f:
|
|
68
|
+
... buffer = f.read()
|
|
69
|
+
>>> result = db.first_magic_buffer(buffer, "txt")
|
|
70
|
+
"""
|
|
71
|
+
...
|
|
72
|
+
|
|
73
|
+
def first_magic_file(self, path: str) -> Magic:
|
|
74
|
+
"""Detect the first magic match for a file.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
path (str): Path to the file to analyze.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Magic: The first detected magic result.
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
IOError: If the file cannot be opened.
|
|
84
|
+
ValueError: If magic identification failed
|
|
85
|
+
|
|
86
|
+
Example:
|
|
87
|
+
>>> result = db.first_magic_file("example.txt")
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
def best_magic_buffer(self, input: bytes) -> Magic:
|
|
92
|
+
"""Detect the best magic match for an in-memory buffer.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
input (bytes): The buffer to analyze.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Magic: The best detected magic result.
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
ValueError: If magic identification failed
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
>>> with open("example.txt", "rb") as f:
|
|
105
|
+
... buffer = f.read()
|
|
106
|
+
>>> result = db.best_magic_buffer(buffer)
|
|
107
|
+
"""
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
def best_magic_file(self, path: str) -> Magic:
|
|
111
|
+
"""Detect the best magic match for a file.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
path (str): Path to the file to analyze.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Magic: The best detected magic result.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
IOError: If the file cannot be opened.
|
|
121
|
+
ValueError: If magic identification failed
|
|
122
|
+
|
|
123
|
+
Example:
|
|
124
|
+
>>> result = db.best_magic_file("example.txt")
|
|
125
|
+
"""
|
|
126
|
+
...
|
|
127
|
+
|
|
128
|
+
def all_magics_buffer(self, input: bytes) -> List[Magic]:
|
|
129
|
+
"""Detect all magic matches for an in-memory buffer.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
input (bytes): The buffer to analyze.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
List[Magic]: All detected magic results.
|
|
136
|
+
|
|
137
|
+
Raises:
|
|
138
|
+
ValueError: If magic identification failed
|
|
139
|
+
|
|
140
|
+
Example:
|
|
141
|
+
>>> with open("example.txt", "rb") as f:
|
|
142
|
+
... buffer = f.read()
|
|
143
|
+
>>> results = db.all_magics_buffer(buffer)
|
|
144
|
+
"""
|
|
145
|
+
...
|
|
146
|
+
|
|
147
|
+
def all_magics_file(self, path: str) -> List[Magic]:
|
|
148
|
+
"""Detect all magic matches for a file.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
path (str): Path to the file to analyze.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List[Magic]: All detected magic results.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
IOError: If the file cannot be opened.
|
|
158
|
+
ValueError: If magic identification failed
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
>>> results = db.all_magics_file("example.txt")
|
|
162
|
+
"""
|
|
163
|
+
...
|
|
Binary file
|
pure_magic_rs/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pure-magic-rs
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
+
Summary: Python bindings for pure-magic crate, a pure Rust re-implementation of libmagic
|
|
8
|
+
Keywords: magic,file,mime,identification,libmagic
|
|
9
|
+
Author-email: Quentin JEROME <quentin.jerome@circl.lu>
|
|
10
|
+
Maintainer-email: Quentin JEROME <quentin.jerome@circl.lu>
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
13
|
+
Project-URL: Issues, https://github.com/qjerome/magic-rs/issues
|
|
14
|
+
Project-URL: Repository, https://github.com/qjerome/magic-rs
|
|
15
|
+
|
|
16
|
+
[](https://pypi.org/project/pure-magic-rs/)
|
|
17
|
+
[](https://github.com/qjerome/magic-rs/actions/workflows/maturin.yml)
|
|
18
|
+

|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<!-- cargo-rdme start -->
|
|
23
|
+
|
|
24
|
+
# Pure Rust Python Bindings for File Type Detection
|
|
25
|
+
|
|
26
|
+
`pure-magic-rs` is a Python module that provides bindings to the [`pure-magic`](https://crates.io/crates/pure-magic) crate, allowing you to detect file types, MIME types, and other metadata using a pure Rust alternative to the C `libmagic` library. This module uses an **embedded magic database**, so everything works out-of-the-box with **no need** of a compiled database or magic rule files.
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
- **Pure Rust implementation**: No C dependencies, easily cross-compilable for great compatibility
|
|
30
|
+
- **Embedded magic database**: No database file or magic rules needed
|
|
31
|
+
- Detect file types from buffers or files
|
|
32
|
+
- Retrieve MIME types, creator codes, and file extensions
|
|
33
|
+
- Convert results to Python dictionaries for easy integration
|
|
34
|
+
- Supports both "first match", "best match" and "all matches" detection strategies
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
```bash
|
|
38
|
+
pip install pure-magic-rs
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Initializing the Database
|
|
44
|
+
```python
|
|
45
|
+
from pure_magic_rs import MagicDb
|
|
46
|
+
# Initialize the Magic database (uses embedded database)
|
|
47
|
+
db = MagicDb()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Detecting File Types from Buffers
|
|
51
|
+
```python
|
|
52
|
+
# Detect the first match for a buffer (e.g., PNG data)
|
|
53
|
+
png_data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00'
|
|
54
|
+
result = db.first_magic_buffer(png_data, None)
|
|
55
|
+
print(f"Detected: {result.message} (MIME: {result.mime_type})")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
# Detect the best match for a buffer
|
|
60
|
+
result = db.best_magic_buffer(png_data)
|
|
61
|
+
print(f"Best match: {result.message}")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# Get all possible matches for a buffer
|
|
66
|
+
results = db.all_magics_buffer(png_data)
|
|
67
|
+
for r in results:
|
|
68
|
+
print(f"Match: {r.message}, MIME: {r.mime_type}, Strength: {r.strength}")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Detecting File Types from Files
|
|
72
|
+
```python
|
|
73
|
+
# Detect the first match for a file
|
|
74
|
+
result = db.first_magic_file("example.png")
|
|
75
|
+
print(f"File type: {result.message}, Extensions: {result.extensions}")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Detect the best match for a file
|
|
80
|
+
result = db.best_magic_file("example.png")
|
|
81
|
+
print(f"Best match: {result.message}")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
# Get all possible matches for a file
|
|
86
|
+
results = db.all_magics_file("example.png")
|
|
87
|
+
for r in results:
|
|
88
|
+
print(f"Match: {r.message}, MIME: {r.mime_type}")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Converting Results to Dictionaries
|
|
92
|
+
```python
|
|
93
|
+
result = db.first_magic_buffer(png_data, None)
|
|
94
|
+
result_dict = result.to_dict()
|
|
95
|
+
print(result_dict)
|
|
96
|
+
# Output: {'source': None, 'message': 'PNG image data', 'mime_type': 'image/png', ...}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Handling Errors
|
|
100
|
+
```python
|
|
101
|
+
try:
|
|
102
|
+
result = db.first_magic_file("nonexistent_file.txt")
|
|
103
|
+
except IOError as e:
|
|
104
|
+
print(f"Error opening file: {e}")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
This project is licensed under the **GPL-3 License**.
|
|
109
|
+
|
|
110
|
+
<!-- cargo-rdme end -->
|
|
111
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pure_magic_rs/__init__.py,sha256=578pugmlUioUEL9jNYxI2DSArh7RaFYFTH4gqrpMWhs,135
|
|
2
|
+
pure_magic_rs/__init__.pyi,sha256=Ylh2DH-MGaKBphMHsARdpQZxVP5eXFTFuBGJzXpejx4,4704
|
|
3
|
+
pure_magic_rs/pure_magic_rs.cpython-313t-i386-linux-musl.so,sha256=Fmb7DCa98SY7YDxo8-TeS2bAXRejNpqe6dSmBc1fO4Q,3811817
|
|
4
|
+
pure_magic_rs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
pure_magic_rs-0.2.5.dist-info/METADATA,sha256=YAx8NdH5g4Qo3I-pdI5lpLxwxRN-cH6pjPC3Y_nuZkU,3999
|
|
6
|
+
pure_magic_rs-0.2.5.dist-info/WHEEL,sha256=6ADlOhKFXhEu-Gk8dFo0B1i68er1Rbvld5DrNBBvRuo,107
|
|
7
|
+
pure_magic_rs.libs/libgcc_s-f5fcfe20.so.1,sha256=AgqyMrWe8E5-efp_cXekgnQn-q6zJOV7u8ZBzQVlfJc,552385
|
|
8
|
+
pure_magic_rs-0.2.5.dist-info/RECORD,,
|
|
Binary file
|