velatus 0.1.0__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.
@@ -0,0 +1,178 @@
1
+ # This file is autogenerated by maturin v1.8.3
2
+ # To update, run
3
+ #
4
+ # maturin generate-ci github
5
+ #
6
+ name: CI
7
+
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ - master
13
+ tags:
14
+ - '*'
15
+ pull_request:
16
+ workflow_dispatch:
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ linux:
23
+ runs-on: ${{ matrix.platform.runner }}
24
+ strategy:
25
+ matrix:
26
+ platform:
27
+ - runner: ubuntu-22.04
28
+ target: x86_64
29
+ - runner: ubuntu-22.04
30
+ target: x86
31
+ - runner: ubuntu-22.04
32
+ target: aarch64
33
+ - runner: ubuntu-22.04
34
+ target: armv7
35
+ - runner: ubuntu-22.04
36
+ target: s390x
37
+ - runner: ubuntu-22.04
38
+ target: ppc64le
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+ - uses: actions/setup-python@v5
42
+ with:
43
+ python-version: 3.x
44
+ - name: Build wheels
45
+ uses: PyO3/maturin-action@v1
46
+ with:
47
+ target: ${{ matrix.platform.target }}
48
+ args: --release --out dist --find-interpreter
49
+ manylinux: auto
50
+ - name: Upload wheels
51
+ uses: actions/upload-artifact@v4
52
+ with:
53
+ name: wheels-linux-${{ matrix.platform.target }}
54
+ path: dist
55
+
56
+ musllinux:
57
+ runs-on: ${{ matrix.platform.runner }}
58
+ strategy:
59
+ matrix:
60
+ platform:
61
+ - runner: ubuntu-22.04
62
+ target: x86_64
63
+ - runner: ubuntu-22.04
64
+ target: x86
65
+ - runner: ubuntu-22.04
66
+ target: aarch64
67
+ - runner: ubuntu-22.04
68
+ target: armv7
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+ - uses: actions/setup-python@v5
72
+ with:
73
+ python-version: 3.x
74
+ - name: Build wheels
75
+ uses: PyO3/maturin-action@v1
76
+ with:
77
+ target: ${{ matrix.platform.target }}
78
+ args: --release --out dist --find-interpreter
79
+ manylinux: musllinux_1_2
80
+ - name: Upload wheels
81
+ uses: actions/upload-artifact@v4
82
+ with:
83
+ name: wheels-musllinux-${{ matrix.platform.target }}
84
+ path: dist
85
+
86
+ windows:
87
+ runs-on: ${{ matrix.platform.runner }}
88
+ strategy:
89
+ matrix:
90
+ platform:
91
+ - runner: windows-latest
92
+ target: x64
93
+ - runner: windows-latest
94
+ target: x86
95
+ steps:
96
+ - uses: actions/checkout@v4
97
+ - uses: actions/setup-python@v5
98
+ with:
99
+ python-version: 3.x
100
+ architecture: ${{ matrix.platform.target }}
101
+ - name: Build wheels
102
+ uses: PyO3/maturin-action@v1
103
+ with:
104
+ target: ${{ matrix.platform.target }}
105
+ args: --release --out dist --find-interpreter
106
+ - name: Upload wheels
107
+ uses: actions/upload-artifact@v4
108
+ with:
109
+ name: wheels-windows-${{ matrix.platform.target }}
110
+ path: dist
111
+
112
+ macos:
113
+ runs-on: ${{ matrix.platform.runner }}
114
+ strategy:
115
+ matrix:
116
+ platform:
117
+ - runner: macos-13
118
+ target: x86_64
119
+ - runner: macos-14
120
+ target: aarch64
121
+ steps:
122
+ - uses: actions/checkout@v4
123
+ - uses: actions/setup-python@v5
124
+ with:
125
+ python-version: 3.x
126
+ - name: Build wheels
127
+ uses: PyO3/maturin-action@v1
128
+ with:
129
+ target: ${{ matrix.platform.target }}
130
+ args: --release --out dist --find-interpreter
131
+ - name: Upload wheels
132
+ uses: actions/upload-artifact@v4
133
+ with:
134
+ name: wheels-macos-${{ matrix.platform.target }}
135
+ path: dist
136
+
137
+ sdist:
138
+ runs-on: ubuntu-latest
139
+ steps:
140
+ - uses: actions/checkout@v4
141
+ - name: Build sdist
142
+ uses: PyO3/maturin-action@v1
143
+ with:
144
+ command: sdist
145
+ args: --out dist
146
+ - name: Upload sdist
147
+ uses: actions/upload-artifact@v4
148
+ with:
149
+ name: wheels-sdist
150
+ path: dist
151
+
152
+ release:
153
+ name: Release
154
+ runs-on: ubuntu-latest
155
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
156
+ needs: [linux, musllinux, windows, macos, sdist]
157
+ permissions:
158
+ # Use to sign the release artifacts
159
+ id-token: write
160
+ # Used to upload release artifacts
161
+ contents: write
162
+ # Used to generate artifact attestation
163
+ attestations: write
164
+ environment:
165
+ name: pypi
166
+ url: https://pypi.org/p/velatus
167
+ steps:
168
+ - uses: actions/download-artifact@v4
169
+ - name: Generate artifact attestation
170
+ uses: actions/attest-build-provenance@v2
171
+ with:
172
+ subject-path: 'wheels-*/*'
173
+ - name: Publish to PyPI
174
+ if: ${{ startsWith(github.ref, 'refs/tags/') }}
175
+ uses: PyO3/maturin-action@v1
176
+ with:
177
+ command: upload
178
+ args: --non-interactive --skip-existing wheels-*/*
@@ -0,0 +1,72 @@
1
+ /target
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ .pytest_cache/
6
+ *.py[cod]
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ .venv/
14
+ env/
15
+ bin/
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ include/
26
+ man/
27
+ venv/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+
32
+ # Installer logs
33
+ pip-log.txt
34
+ pip-delete-this-directory.txt
35
+ pip-selfcheck.json
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+
45
+ # Translations
46
+ *.mo
47
+
48
+ # Mr Developer
49
+ .mr.developer.cfg
50
+ .project
51
+ .pydevproject
52
+
53
+ # Rope
54
+ .ropeproject
55
+
56
+ # Django stuff:
57
+ *.log
58
+ *.pot
59
+
60
+ .DS_Store
61
+
62
+ # Sphinx documentation
63
+ docs/_build/
64
+
65
+ # PyCharm
66
+ .idea/
67
+
68
+ # VSCode
69
+ .vscode/
70
+
71
+ # Pyenv
72
+ .python-version
@@ -0,0 +1,241 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "aho-corasick"
7
+ version = "1.1.3"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
10
+ dependencies = [
11
+ "memchr",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "arc-swap"
16
+ version = "1.7.1"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
19
+
20
+ [[package]]
21
+ name = "autocfg"
22
+ version = "1.4.0"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
25
+
26
+ [[package]]
27
+ name = "cfg-if"
28
+ version = "1.0.0"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
31
+
32
+ [[package]]
33
+ name = "heck"
34
+ version = "0.5.0"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
37
+
38
+ [[package]]
39
+ name = "indoc"
40
+ version = "2.0.6"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
43
+
44
+ [[package]]
45
+ name = "libc"
46
+ version = "0.2.171"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
49
+
50
+ [[package]]
51
+ name = "log"
52
+ version = "0.4.27"
53
+ source = "registry+https://github.com/rust-lang/crates.io-index"
54
+ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
55
+
56
+ [[package]]
57
+ name = "memchr"
58
+ version = "2.7.4"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
61
+
62
+ [[package]]
63
+ name = "memoffset"
64
+ version = "0.9.1"
65
+ source = "registry+https://github.com/rust-lang/crates.io-index"
66
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
67
+ dependencies = [
68
+ "autocfg",
69
+ ]
70
+
71
+ [[package]]
72
+ name = "once_cell"
73
+ version = "1.21.3"
74
+ source = "registry+https://github.com/rust-lang/crates.io-index"
75
+ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
76
+
77
+ [[package]]
78
+ name = "portable-atomic"
79
+ version = "1.11.0"
80
+ source = "registry+https://github.com/rust-lang/crates.io-index"
81
+ checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
82
+
83
+ [[package]]
84
+ name = "proc-macro2"
85
+ version = "1.0.94"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
88
+ dependencies = [
89
+ "unicode-ident",
90
+ ]
91
+
92
+ [[package]]
93
+ name = "pyo3"
94
+ version = "0.24.1"
95
+ source = "registry+https://github.com/rust-lang/crates.io-index"
96
+ checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229"
97
+ dependencies = [
98
+ "cfg-if",
99
+ "indoc",
100
+ "libc",
101
+ "memoffset",
102
+ "once_cell",
103
+ "portable-atomic",
104
+ "pyo3-build-config",
105
+ "pyo3-ffi",
106
+ "pyo3-macros",
107
+ "unindent",
108
+ ]
109
+
110
+ [[package]]
111
+ name = "pyo3-build-config"
112
+ version = "0.24.1"
113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
114
+ checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1"
115
+ dependencies = [
116
+ "once_cell",
117
+ "target-lexicon",
118
+ ]
119
+
120
+ [[package]]
121
+ name = "pyo3-ffi"
122
+ version = "0.24.1"
123
+ source = "registry+https://github.com/rust-lang/crates.io-index"
124
+ checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc"
125
+ dependencies = [
126
+ "libc",
127
+ "pyo3-build-config",
128
+ ]
129
+
130
+ [[package]]
131
+ name = "pyo3-log"
132
+ version = "0.12.3"
133
+ source = "registry+https://github.com/rust-lang/crates.io-index"
134
+ checksum = "7079e412e909af5d6be7c04a7f29f6a2837a080410e1c529c9dee2c367383db4"
135
+ dependencies = [
136
+ "arc-swap",
137
+ "log",
138
+ "pyo3",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "pyo3-macros"
143
+ version = "0.24.1"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44"
146
+ dependencies = [
147
+ "proc-macro2",
148
+ "pyo3-macros-backend",
149
+ "quote",
150
+ "syn",
151
+ ]
152
+
153
+ [[package]]
154
+ name = "pyo3-macros-backend"
155
+ version = "0.24.1"
156
+ source = "registry+https://github.com/rust-lang/crates.io-index"
157
+ checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855"
158
+ dependencies = [
159
+ "heck",
160
+ "proc-macro2",
161
+ "pyo3-build-config",
162
+ "quote",
163
+ "syn",
164
+ ]
165
+
166
+ [[package]]
167
+ name = "quote"
168
+ version = "1.0.40"
169
+ source = "registry+https://github.com/rust-lang/crates.io-index"
170
+ checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
171
+ dependencies = [
172
+ "proc-macro2",
173
+ ]
174
+
175
+ [[package]]
176
+ name = "regex"
177
+ version = "1.11.1"
178
+ source = "registry+https://github.com/rust-lang/crates.io-index"
179
+ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
180
+ dependencies = [
181
+ "aho-corasick",
182
+ "memchr",
183
+ "regex-automata",
184
+ "regex-syntax",
185
+ ]
186
+
187
+ [[package]]
188
+ name = "regex-automata"
189
+ version = "0.4.9"
190
+ source = "registry+https://github.com/rust-lang/crates.io-index"
191
+ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
192
+ dependencies = [
193
+ "aho-corasick",
194
+ "memchr",
195
+ "regex-syntax",
196
+ ]
197
+
198
+ [[package]]
199
+ name = "regex-syntax"
200
+ version = "0.8.5"
201
+ source = "registry+https://github.com/rust-lang/crates.io-index"
202
+ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
203
+
204
+ [[package]]
205
+ name = "syn"
206
+ version = "2.0.100"
207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
208
+ checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
209
+ dependencies = [
210
+ "proc-macro2",
211
+ "quote",
212
+ "unicode-ident",
213
+ ]
214
+
215
+ [[package]]
216
+ name = "target-lexicon"
217
+ version = "0.13.2"
218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
219
+ checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
220
+
221
+ [[package]]
222
+ name = "unicode-ident"
223
+ version = "1.0.18"
224
+ source = "registry+https://github.com/rust-lang/crates.io-index"
225
+ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
226
+
227
+ [[package]]
228
+ name = "unindent"
229
+ version = "0.2.4"
230
+ source = "registry+https://github.com/rust-lang/crates.io-index"
231
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
232
+
233
+ [[package]]
234
+ name = "velatus"
235
+ version = "0.1.0"
236
+ dependencies = [
237
+ "log",
238
+ "pyo3",
239
+ "pyo3-log",
240
+ "regex",
241
+ ]
@@ -0,0 +1,15 @@
1
+ [package]
2
+ name = "velatus"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+
6
+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
+ [lib]
8
+ name = "velatus"
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ log = "0.4.27"
13
+ pyo3 = "0.24.0"
14
+ pyo3-log = "0.12.3"
15
+ regex = "1.11.1"
velatus-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: velatus
3
+ Version: 0.1.0
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
7
+ Requires-Dist: pytest ; extra == 'tests'
8
+ Provides-Extra: tests
9
+ Requires-Python: >=3.8
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.8,<2.0"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "velatus"
7
+ requires-python = ">=3.8"
8
+ classifiers = [
9
+ "Programming Language :: Rust",
10
+ "Programming Language :: Python :: Implementation :: CPython",
11
+ "Programming Language :: Python :: Implementation :: PyPy",
12
+ ]
13
+ dynamic = ["version"]
14
+ [project.optional-dependencies]
15
+ tests = [
16
+ "pytest",
17
+ ]
18
+ [tool.maturin]
19
+ python-source = "python"
20
+ features = ["pyo3/extension-module"]
21
+
22
+ [tool.pytest]
23
+ sources = ["python"]
@@ -0,0 +1,34 @@
1
+ import pytest
2
+ import velatus
3
+
4
+
5
+ class LightLogRecord:
6
+ def __init__(self, msg: str) -> None:
7
+ self.msg = msg
8
+
9
+
10
+ @pytest.mark.parametrize(
11
+ "mask, strings_to_mask, log_record, expected",
12
+ [
13
+ (None, ["xxx", "yyy"], "This is a log message with secret xxx and yyy", "This is a log message with secret [MASKED] and [MASKED]"),
14
+ ("[REDACTED]", ["xxx", "yyy"], "This is a log message with secret xxx and yyy", "This is a log message with secret [REDACTED] and [REDACTED]"),
15
+ (None, ["$TEST"], "This is a test message with $TEST", "This is a test message with [MASKED]"),
16
+ (None, ["[A-Z]"], "This [A-Z] is a test message with [A-Z]", "This [MASKED] is a test message with [MASKED]"),
17
+ (None, ["\\"], "This is a test message with \\ and \\", "This is a test message with [MASKED] and [MASKED]"),
18
+ ]
19
+ )
20
+ def test_masker(mask, strings_to_mask, log_record, expected):
21
+ """
22
+ Test the Masker class with different parameters.
23
+ """
24
+ m = velatus.Masker(strings_to_mask, mask=mask)
25
+
26
+ # Use the masker to mask the log record
27
+ llr = LightLogRecord(log_record)
28
+
29
+ print(f"Original log record: {llr.msg}")
30
+ m(llr)
31
+ print(f"Masked log record: {llr.msg}")
32
+
33
+ # Check if the log record message is masked
34
+ assert llr.msg == expected
@@ -0,0 +1,19 @@
1
+ from typing import Optional
2
+ from .velatus import *
3
+
4
+ import logging
5
+
6
+ __doc__ = velatus.__doc__
7
+
8
+
9
+ def mask_handlers(secrets: list[str], handlers: list[logging.Handler], mask: Optional[str] = None) -> None:
10
+ """Install a Masker as a filter on all given handlers."""
11
+ # Create a Masker instance
12
+ masker = Masker(secrets, mask=mask)
13
+
14
+ # Iterate through all handlers
15
+ for handler in handlers:
16
+ handler.addFilter(masker)
17
+
18
+
19
+ __all__ = ["Masker"]
File without changes
@@ -0,0 +1,64 @@
1
+ use log::debug;
2
+ use pyo3::{prelude::*, types::PyString};
3
+ use regex::{escape, Regex};
4
+
5
+ // Create a callable class that stores a masking regex
6
+ #[pyclass]
7
+ struct Masker {
8
+ regex: Regex,
9
+ mask: String,
10
+ }
11
+
12
+ #[pymethods]
13
+ impl Masker {
14
+ /// Create a new Masker instance.
15
+ #[new]
16
+ #[pyo3(signature = (strings, mask=None))]
17
+ pub fn new(strings: Vec<Bound<PyString>>, mask: Option<Bound<PyString>>) -> PyResult<Self> {
18
+ // Convert the PyString objects to Rust strings, escaping them for regex
19
+ let res: PyResult<Vec<String>> = strings
20
+ .into_iter()
21
+ .map(|s| s.extract::<String>().map(|s| escape(&s)))
22
+ .collect();
23
+
24
+ let strings: Vec<String> = res?;
25
+
26
+ debug!("Creating masker for {} strings", strings.len());
27
+
28
+ // If a mask is provided, use it; otherwise, default to [MASKED]
29
+ let mask = match mask {
30
+ Some(m) => m.extract::<String>()?,
31
+ None => "[MASKED]".to_string(),
32
+ };
33
+
34
+ // Join the strings with '|' to create a regex pattern
35
+ let pattern = format!("({})", strings.join("|"));
36
+ let regex = Regex::new(&pattern).unwrap();
37
+
38
+ Ok(Masker { regex, mask })
39
+ }
40
+
41
+ /// Mask the log record's message using the regex.
42
+ fn __call__(&self, py: Python<'_>, log_record: PyObject) -> PyResult<bool> {
43
+ // The log_record is expected to be a logging.LogRecord object
44
+ // Extract the message from the log_record
45
+ let msg_attr = log_record.getattr(py, "msg")?;
46
+ let msg = msg_attr.extract::<&str>(py)?;
47
+
48
+ // Replace any regex matches with the mask
49
+ let masked_msg = self.regex.replace_all(msg, &self.mask);
50
+
51
+ // Set the masked message back to the log_record
52
+ log_record.setattr(py, "msg", masked_msg)?;
53
+
54
+ Ok(true)
55
+ }
56
+ }
57
+
58
+ /// A Python module implemented in Rust.
59
+ #[pymodule]
60
+ fn velatus(m: &Bound<'_, PyModule>) -> PyResult<()> {
61
+ pyo3_log::init();
62
+ m.add_class::<Masker>()?;
63
+ Ok(())
64
+ }