winipedia-utils 0.2.63__py3-none-any.whl → 0.6.6__py3-none-any.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.
Potentially problematic release.
This version of winipedia-utils might be problematic. Click here for more details.
- winipedia_utils/artifacts/build.py +78 -0
- winipedia_utils/concurrent/concurrent.py +7 -2
- winipedia_utils/concurrent/multiprocessing.py +1 -2
- winipedia_utils/concurrent/multithreading.py +2 -2
- winipedia_utils/data/dataframe/cleaning.py +337 -100
- winipedia_utils/git/github/__init__.py +1 -0
- winipedia_utils/git/github/github.py +31 -0
- winipedia_utils/git/github/repo/__init__.py +1 -0
- winipedia_utils/git/github/repo/protect.py +103 -0
- winipedia_utils/git/github/repo/repo.py +205 -0
- winipedia_utils/git/github/workflows/base/__init__.py +1 -0
- winipedia_utils/git/github/workflows/base/base.py +889 -0
- winipedia_utils/git/github/workflows/health_check.py +69 -0
- winipedia_utils/git/github/workflows/publish.py +51 -0
- winipedia_utils/git/github/workflows/release.py +90 -0
- winipedia_utils/git/gitignore/config.py +77 -0
- winipedia_utils/git/gitignore/gitignore.py +5 -63
- winipedia_utils/git/pre_commit/config.py +49 -59
- winipedia_utils/git/pre_commit/hooks.py +46 -46
- winipedia_utils/git/pre_commit/run_hooks.py +19 -12
- winipedia_utils/iterating/iterate.py +63 -1
- winipedia_utils/modules/class_.py +69 -12
- winipedia_utils/modules/function.py +26 -3
- winipedia_utils/modules/inspection.py +56 -0
- winipedia_utils/modules/module.py +22 -28
- winipedia_utils/modules/package.py +116 -10
- winipedia_utils/projects/poetry/config.py +255 -112
- winipedia_utils/projects/poetry/poetry.py +230 -13
- winipedia_utils/projects/project.py +11 -42
- winipedia_utils/setup.py +11 -29
- winipedia_utils/testing/config.py +127 -0
- winipedia_utils/testing/create_tests.py +5 -19
- winipedia_utils/testing/skip.py +19 -0
- winipedia_utils/testing/tests/base/fixtures/fixture.py +36 -0
- winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +3 -3
- winipedia_utils/testing/tests/base/fixtures/scopes/module.py +9 -6
- winipedia_utils/testing/tests/base/fixtures/scopes/session.py +27 -176
- winipedia_utils/testing/tests/base/utils/utils.py +27 -57
- winipedia_utils/text/config.py +250 -0
- winipedia_utils/text/string.py +30 -0
- winipedia_utils-0.6.6.dist-info/METADATA +390 -0
- {winipedia_utils-0.2.63.dist-info → winipedia_utils-0.6.6.dist-info}/RECORD +46 -34
- winipedia_utils/consts.py +0 -21
- winipedia_utils/git/workflows/base/base.py +0 -77
- winipedia_utils/git/workflows/publish.py +0 -79
- winipedia_utils/git/workflows/release.py +0 -91
- winipedia_utils-0.2.63.dist-info/METADATA +0 -738
- /winipedia_utils/{git/workflows/base → artifacts}/__init__.py +0 -0
- /winipedia_utils/git/{workflows → github/workflows}/__init__.py +0 -0
- {winipedia_utils-0.2.63.dist-info → winipedia_utils-0.6.6.dist-info}/WHEEL +0 -0
- {winipedia_utils-0.2.63.dist-info → winipedia_utils-0.6.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,738 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: winipedia-utils
|
|
3
|
-
Version: 0.2.63
|
|
4
|
-
Summary: A package with many utility functions
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Author: Winipedia
|
|
8
|
-
Author-email: win.steveker@gmx.de
|
|
9
|
-
Requires-Python: >=3.12
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
-
Requires-Dist: cryptography (>=45.0.5,<46.0.0)
|
|
15
|
-
Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
|
|
16
|
-
Requires-Dist: keyring (>=25.6.0,<26.0.0)
|
|
17
|
-
Requires-Dist: pathspec (>=0.12.1,<0.13.0)
|
|
18
|
-
Requires-Dist: polars (>=1.34.0,<2.0.0)
|
|
19
|
-
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
|
20
|
-
Requires-Dist: setuptools (>=80.3.1,<81.0.0)
|
|
21
|
-
Requires-Dist: tomlkit (>=0.13.2,<0.14.0)
|
|
22
|
-
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
|
|
23
|
-
Description-Content-Type: text/markdown
|
|
24
|
-
|
|
25
|
-
# 🚀 Winipedia Utils
|
|
26
|
-
(Some of the README is AI generated, so code examples might have bugs, please check the source code directly on problems. Every functions has a docstring.)
|
|
27
|
-
|
|
28
|
-
> A comprehensive Python utility package that enforces best practices, automates project setup, and provides a complete testing framework for modern Python projects.
|
|
29
|
-
|
|
30
|
-
[](https://www.python.org/downloads/)
|
|
31
|
-
[](LICENSE)
|
|
32
|
-
[](https://github.com/astral-sh/ruff)
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 📋 Table of Contents
|
|
37
|
-
|
|
38
|
-
- [Overview](#overview)
|
|
39
|
-
- [Quick Start](#quick-start)
|
|
40
|
-
- [Setup Process](#setup-process)
|
|
41
|
-
- [Utilities](#utilities)
|
|
42
|
-
- [Usage Examples](#usage-examples)
|
|
43
|
-
- [Important Notes](#important-notes)
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Overview
|
|
48
|
-
|
|
49
|
-
**Winipedia Utils** is a utility library that serves two primary purposes:
|
|
50
|
-
|
|
51
|
-
1. **🛠️ Utility Package** - Provides reusable functions across several domains (concurrency, data handling, security, testing, etc.)
|
|
52
|
-
2. **🏗️ Project Framework** - Automates project setup, testing infrastructure, code quality checks, and best practices enforcement
|
|
53
|
-
|
|
54
|
-
### Key Features
|
|
55
|
-
|
|
56
|
-
✨ **Automatic Test Generation** - Creates mirror test structure matching your source code
|
|
57
|
-
🔒 **Security First** - Built-in encryption, keyring integration, and security scanning
|
|
58
|
-
⚡ **Concurrent Processing** - Unified interface for multiprocessing and multithreading
|
|
59
|
-
📊 **Data Handling** - Polars-based dataframe utilities with cleaning pipelines
|
|
60
|
-
🎯 **Strict Type Checking** - mypy in strict mode with full type annotations
|
|
61
|
-
🧹 **Code Quality** - Automated linting, formatting, and security checks
|
|
62
|
-
📝 **Comprehensive Logging** - Automatic method instrumentation and performance tracking
|
|
63
|
-
|
|
64
|
-
> **Note:** Functions starting with `_` are for internal use only and should not be called directly by package users.
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Quick Start
|
|
69
|
-
|
|
70
|
-
### Installation
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
# clone from github
|
|
74
|
-
git clone https://github.com/user/your-repo.git
|
|
75
|
-
|
|
76
|
-
# Initialize a new Poetry project
|
|
77
|
-
poetry init
|
|
78
|
-
|
|
79
|
-
# Add winipedia-utils to your project
|
|
80
|
-
poetry add winipedia-utils
|
|
81
|
-
|
|
82
|
-
# Run the automated setup
|
|
83
|
-
poetry run python -m winipedia_utils.setup
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
That's it! The setup script will configure everything for you.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Setup Process
|
|
91
|
-
|
|
92
|
-
The `winipedia_utils.setup` command automates the entire project initialization in a few steps:
|
|
93
|
-
|
|
94
|
-
### Step 1️⃣ - Install Dev Dependencies
|
|
95
|
-
Installs all development tools needed for code quality like:
|
|
96
|
-
- `ruff` - Fast Python linter and formatter
|
|
97
|
-
- `mypy` - Static type checker
|
|
98
|
-
- `pytest` - Testing framework
|
|
99
|
-
- `bandit` - Security scanner
|
|
100
|
-
- `pre-commit` - Git hooks framework
|
|
101
|
-
|
|
102
|
-
### Step 2️⃣ - Create Pre-commit Configuration
|
|
103
|
-
Sets up `.pre-commit-config.yaml` with the winipedia-utils hook that runs on every commit.
|
|
104
|
-
|
|
105
|
-
### Step 3️⃣ - Install Pre-commit Framework
|
|
106
|
-
Installs git hooks so checks run automatically before commits.
|
|
107
|
-
|
|
108
|
-
### Step 4️⃣ - Update .gitignore
|
|
109
|
-
Adds standard patterns for Python projects:
|
|
110
|
-
```
|
|
111
|
-
__pycache__/
|
|
112
|
-
.idea/
|
|
113
|
-
.mypy_cache/
|
|
114
|
-
.pytest_cache/
|
|
115
|
-
.ruff_cache/
|
|
116
|
-
.vscode/
|
|
117
|
-
dist/
|
|
118
|
-
test.py
|
|
119
|
-
.git/
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Step 5️⃣ - Configure pyproject.toml
|
|
123
|
-
Adds tool configurations in pyproject.toml for e.g.:
|
|
124
|
-
- **mypy** - Strict type checking
|
|
125
|
-
- **ruff** - Linting and formatting rules
|
|
126
|
-
- **pytest** - Test discovery and execution
|
|
127
|
-
- **bandit** - Security scanning
|
|
128
|
-
|
|
129
|
-
### Step 6️⃣ - Create GitHub Actions Workflows
|
|
130
|
-
Sets up `.github/workflows/release.yaml` for automated versioning and publishing:
|
|
131
|
-
- Triggers on pushing tags in the form of v*
|
|
132
|
-
- Creates a release on GitHub
|
|
133
|
-
- Triggers publish.yaml workflow if publish.yaml exists
|
|
134
|
-
- Tests will fail if you do not have release.yaml
|
|
135
|
-
|
|
136
|
-
Sets up `.github/workflows/publish.yaml` for automated PyPI publishing:
|
|
137
|
-
- Triggers on GitHub releases
|
|
138
|
-
- Configures Poetry with PyPI token
|
|
139
|
-
- Builds and publishes package automatically
|
|
140
|
-
- If you do not want to publish to pypi, you can delete the file, tests will not fail bc of it and it won't be added again unless you run the setup script again or delete the .github folder/workflows folder.
|
|
141
|
-
|
|
142
|
-
### Step 7️⃣ - Create Project Root
|
|
143
|
-
Creates your project's root package directory with `py.typed` marker for type hint support.
|
|
144
|
-
|
|
145
|
-
### Step 8️⃣ - Run Pre-commit Hook
|
|
146
|
-
Executes the complete quality pipeline (see below).
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Pre-commit Hook Workflow
|
|
151
|
-
|
|
152
|
-
When you commit code, the winipedia-utils hook automatically runs a few quality checks e.g.:
|
|
153
|
-
```
|
|
154
|
-
┌─────────────────────────────────────────────────────────┐
|
|
155
|
-
│ Pre-commit Hook Execution Pipeline │
|
|
156
|
-
├─────────────────────────────────────────────────────────┤
|
|
157
|
-
│ 1. Patch Version (poetry version patch, git add toml) │
|
|
158
|
-
│ 2. Update Poetry │
|
|
159
|
-
│ 3. Install Dependencies (poetry install) │
|
|
160
|
-
│ 4. Update All Dependencies (poetry update) │
|
|
161
|
-
│ 5. Lock Dependencies (poetry lock) │
|
|
162
|
-
│ 6. Validate Configuration (poetry check) │
|
|
163
|
-
│ 7. Generate Tests (auto-create test files) │
|
|
164
|
-
│ 8. Lint Code (ruff check --fix) │
|
|
165
|
-
│ 9. Format Code (ruff format) │
|
|
166
|
-
│ 10. Type Check (mypy) │
|
|
167
|
-
│ 11. Security Scan (bandit) │
|
|
168
|
-
│ 12. Run Tests (pytest) │
|
|
169
|
-
└─────────────────────────────────────────────────────────┘
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Auto-generated Test Structure
|
|
173
|
-
|
|
174
|
-
The test generation creates a **mirror structure** of your source code:
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
my_project/
|
|
178
|
-
├── my_project/
|
|
179
|
-
│ ├── module_a.py
|
|
180
|
-
│ └── package_b/
|
|
181
|
-
│ └── module_c.py
|
|
182
|
-
└── tests/
|
|
183
|
-
├── test_module_a.py
|
|
184
|
-
└── test_package_b/
|
|
185
|
-
└── test_module_c.py
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
For each function, class, and method, skeleton tests are created with `NotImplementedError` placeholders for you to implement.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Utilities
|
|
193
|
-
|
|
194
|
-
Winipedia Utils provides comprehensive utility modules:
|
|
195
|
-
|
|
196
|
-
### 1. 🔄 Concurrent Processing
|
|
197
|
-
|
|
198
|
-
Execute functions in parallel with automatic worker pool management.
|
|
199
|
-
|
|
200
|
-
**Use Cases:** CPU-bound tasks, I/O-bound operations, batch processing
|
|
201
|
-
|
|
202
|
-
```python
|
|
203
|
-
from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
|
|
204
|
-
from winipedia_utils.concurrent.multithreading import multithread_loop
|
|
205
|
-
|
|
206
|
-
# CPU-bound: Process data in parallel
|
|
207
|
-
def expensive_computation(x):
|
|
208
|
-
return x ** 2
|
|
209
|
-
|
|
210
|
-
data = [[i] for i in range(100)]
|
|
211
|
-
results = multiprocess_loop(expensive_computation, data)
|
|
212
|
-
|
|
213
|
-
# I/O-bound: Fetch URLs concurrently
|
|
214
|
-
def fetch_url(url):
|
|
215
|
-
return requests.get(url).text
|
|
216
|
-
|
|
217
|
-
urls = [["https://example.com"], ["https://google.com"]]
|
|
218
|
-
results = multithread_loop(fetch_url, urls)
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
**Key Functions:**
|
|
222
|
-
- `multiprocess_loop()` - Parallel execution for CPU-bound tasks
|
|
223
|
-
- `multithread_loop()` - Parallel execution for I/O-bound tasks
|
|
224
|
-
- `cancel_on_timeout()` - Decorator to timeout long-running functions
|
|
225
|
-
- `find_max_pools()` - Automatically determine optimal worker count
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
### 2. 📊 Data Cleaning & Handling
|
|
230
|
-
|
|
231
|
-
Build data cleaning pipelines using Polars (not Pandas).
|
|
232
|
-
|
|
233
|
-
**Use Cases:** ETL pipelines, data validation, dataframe transformations
|
|
234
|
-
|
|
235
|
-
```python
|
|
236
|
-
from winipedia_utils.data.dataframe.cleaning import CleaningDF
|
|
237
|
-
import polars as pl
|
|
238
|
-
|
|
239
|
-
class MyDataCleaner(CleaningDF):
|
|
240
|
-
COL_NAME = "name"
|
|
241
|
-
COL_VALUE = "value"
|
|
242
|
-
|
|
243
|
-
@classmethod
|
|
244
|
-
def get_rename_map(cls):
|
|
245
|
-
return {cls.COL_NAME: "original_name", cls.COL_VALUE: "original_value"}
|
|
246
|
-
|
|
247
|
-
@classmethod
|
|
248
|
-
def get_col_dtype_map(cls):
|
|
249
|
-
return {cls.COL_NAME: pl.Utf8, cls.COL_VALUE: pl.Float64}
|
|
250
|
-
|
|
251
|
-
@classmethod
|
|
252
|
-
def get_fill_null_map(cls):
|
|
253
|
-
return {cls.COL_NAME: "Unknown", cls.COL_VALUE: 0.0}
|
|
254
|
-
|
|
255
|
-
@classmethod
|
|
256
|
-
def get_drop_null_subsets(cls):
|
|
257
|
-
return ((cls.COL_NAME,),)
|
|
258
|
-
|
|
259
|
-
@classmethod
|
|
260
|
-
def get_sort_cols(cls):
|
|
261
|
-
return ((cls.COL_NAME, False),)
|
|
262
|
-
|
|
263
|
-
@classmethod
|
|
264
|
-
def get_unique_subsets(cls):
|
|
265
|
-
return ((cls.COL_NAME,),)
|
|
266
|
-
|
|
267
|
-
@classmethod
|
|
268
|
-
def get_no_null_cols(cls):
|
|
269
|
-
return (cls.COL_NAME,)
|
|
270
|
-
|
|
271
|
-
@classmethod
|
|
272
|
-
def get_col_converter_map(cls):
|
|
273
|
-
return {cls.COL_NAME: cls.lower_col}
|
|
274
|
-
|
|
275
|
-
@classmethod
|
|
276
|
-
def get_add_on_duplicate_cols(cls):
|
|
277
|
-
return (cls.COL_VALUE,)
|
|
278
|
-
|
|
279
|
-
@classmethod
|
|
280
|
-
def get_col_precision_map(cls):
|
|
281
|
-
return {cls.COL_VALUE: 2}
|
|
282
|
-
|
|
283
|
-
# Usage
|
|
284
|
-
data = MyDataCleaner({"original_name": ["Alice", "bob"], "original_value": [1.5, 2.7]})
|
|
285
|
-
print(data.df) # Cleaned and validated dataframe
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
**Key Features:**
|
|
289
|
-
- Automatic column renaming
|
|
290
|
-
- Type conversion and validation
|
|
291
|
-
- Null value handling
|
|
292
|
-
- Deduplication with aggregation
|
|
293
|
-
- Sorting and precision rounding
|
|
294
|
-
- Comprehensive data validation
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
### 3. 🔧 Git Utilities
|
|
299
|
-
|
|
300
|
-
Manage gitignore patterns, pre-commit configuration, and GitHub Actions workflows.
|
|
301
|
-
|
|
302
|
-
**Use Cases:** Project setup, git workflow automation, CI/CD pipeline setup
|
|
303
|
-
|
|
304
|
-
```python
|
|
305
|
-
from winipedia_utils.git.gitignore.gitignore import (
|
|
306
|
-
path_is_in_gitignore,
|
|
307
|
-
walk_os_skipping_gitignore_patterns,
|
|
308
|
-
add_patterns_to_gitignore
|
|
309
|
-
)
|
|
310
|
-
from winipedia_utils.git.workflows.publish import (
|
|
311
|
-
load_publish_workflow,
|
|
312
|
-
dump_publish_workflow
|
|
313
|
-
)
|
|
314
|
-
|
|
315
|
-
# Check if path is ignored
|
|
316
|
-
if path_is_in_gitignore("dist/"):
|
|
317
|
-
print("This path is in .gitignore")
|
|
318
|
-
|
|
319
|
-
# Walk directory respecting gitignore
|
|
320
|
-
for root, dirs, files in walk_os_skipping_gitignore_patterns("."):
|
|
321
|
-
print(f"Processing: {root}")
|
|
322
|
-
|
|
323
|
-
# Add patterns to gitignore
|
|
324
|
-
add_patterns_to_gitignore(["*.log", "temp/"])
|
|
325
|
-
|
|
326
|
-
# Load and modify publish workflow
|
|
327
|
-
workflow = load_publish_workflow()
|
|
328
|
-
print(f"Workflow name: {workflow.get('name')}")
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
**Key Functions:**
|
|
332
|
-
- `path_is_in_gitignore()` - Check if path matches gitignore patterns
|
|
333
|
-
- `walk_os_skipping_gitignore_patterns()` - Directory traversal respecting gitignore
|
|
334
|
-
- `add_patterns_to_gitignore()` - Add patterns to .gitignore file
|
|
335
|
-
- `load_publish_workflow()` - Load GitHub Actions publish workflow
|
|
336
|
-
- `dump_publish_workflow()` - Save GitHub Actions publish workflow
|
|
337
|
-
- Pre-commit configuration management
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
### 4. 🔁 Iterating Utilities
|
|
342
|
-
|
|
343
|
-
Handle iterables with sensible defaults.
|
|
344
|
-
|
|
345
|
-
**Use Cases:** Working with generators, unknown-length iterables
|
|
346
|
-
|
|
347
|
-
```python
|
|
348
|
-
from winipedia_utils.iterating.iterate import get_len_with_default
|
|
349
|
-
|
|
350
|
-
# Get length with fallback
|
|
351
|
-
length = get_len_with_default(some_generator, default=100)
|
|
352
|
-
print(f"Length: {length}")
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
---
|
|
356
|
-
|
|
357
|
-
### 5. 📝 Logging Utilities
|
|
358
|
-
|
|
359
|
-
Simple, standardized logging setup with automatic method instrumentation.
|
|
360
|
-
|
|
361
|
-
**Use Cases:** Application logging, debugging, performance tracking
|
|
362
|
-
|
|
363
|
-
```python
|
|
364
|
-
from winipedia_utils.logging.logger import get_logger
|
|
365
|
-
|
|
366
|
-
logger = get_logger(__name__)
|
|
367
|
-
logger.info("Application started")
|
|
368
|
-
logger.warning("This is a warning")
|
|
369
|
-
logger.error("An error occurred")
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
**Features:**
|
|
373
|
-
- Pre-configured logging levels
|
|
374
|
-
- ANSI color support for terminal output
|
|
375
|
-
- Automatic method logging via metaclasses
|
|
376
|
-
|
|
377
|
-
---
|
|
378
|
-
|
|
379
|
-
### 6. 📦 Module/Package Utilities
|
|
380
|
-
|
|
381
|
-
Introspect and manipulate Python modules and packages dynamically.
|
|
382
|
-
|
|
383
|
-
**Use Cases:** Testing frameworks, code generation, dynamic imports
|
|
384
|
-
|
|
385
|
-
```python
|
|
386
|
-
from winipedia_utils.modules.module import (
|
|
387
|
-
to_module_name,
|
|
388
|
-
to_path,
|
|
389
|
-
create_module,
|
|
390
|
-
import_obj_from_importpath,
|
|
391
|
-
make_obj_importpath
|
|
392
|
-
)
|
|
393
|
-
from winipedia_utils.modules.class_ import get_all_cls_from_module
|
|
394
|
-
from winipedia_utils.modules.function import get_all_functions_from_module
|
|
395
|
-
from winipedia_utils.modules.package import find_packages, walk_package
|
|
396
|
-
|
|
397
|
-
# Convert between paths and module names
|
|
398
|
-
module_name = to_module_name("src/package/module.py") # "src.package.module"
|
|
399
|
-
path = to_path("src.package.module", is_package=False) # Path("src/package/module.py")
|
|
400
|
-
|
|
401
|
-
# Create modules dynamically
|
|
402
|
-
new_module = create_module("my_package.new_module", is_package=False)
|
|
403
|
-
|
|
404
|
-
# Import objects by path
|
|
405
|
-
obj = import_obj_from_importpath("my_package.MyClass")
|
|
406
|
-
|
|
407
|
-
# Get all classes in a module
|
|
408
|
-
classes = get_all_cls_from_module("my_package.module")
|
|
409
|
-
|
|
410
|
-
# Get all functions in a module
|
|
411
|
-
functions = get_all_functions_from_module("my_package.module")
|
|
412
|
-
|
|
413
|
-
# Find all packages
|
|
414
|
-
packages = find_packages(depth=1)
|
|
415
|
-
|
|
416
|
-
# Walk package hierarchy
|
|
417
|
-
for package, modules in walk_package(my_package):
|
|
418
|
-
print(f"Package: {package.__name__}, Modules: {len(modules)}")
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
### 7. 🎯 Object-Oriented Programming Utilities
|
|
424
|
-
|
|
425
|
-
Advanced metaclasses and mixins for class composition and behavior extension.
|
|
426
|
-
|
|
427
|
-
**Use Cases:** Framework development, enforcing design patterns, automatic instrumentation
|
|
428
|
-
|
|
429
|
-
```python
|
|
430
|
-
from winipedia_utils.oop.mixins.mixin import ABCLoggingMixin, StrictABCLoggingMixin
|
|
431
|
-
from abc import abstractmethod
|
|
432
|
-
from typing import final
|
|
433
|
-
|
|
434
|
-
# Automatic logging + ABC functionality
|
|
435
|
-
class MyService(ABCLoggingMixin):
|
|
436
|
-
def process_data(self, data):
|
|
437
|
-
# Automatically logged with timing
|
|
438
|
-
return data * 2
|
|
439
|
-
|
|
440
|
-
# Strict implementation enforcement + logging
|
|
441
|
-
class StrictService(StrictABCLoggingMixin):
|
|
442
|
-
@abstractmethod
|
|
443
|
-
def required_method(self):
|
|
444
|
-
pass
|
|
445
|
-
|
|
446
|
-
@final
|
|
447
|
-
def final_method(self):
|
|
448
|
-
return "Cannot be overridden"
|
|
449
|
-
|
|
450
|
-
# Usage
|
|
451
|
-
service = MyService()
|
|
452
|
-
result = service.process_data(42) # Automatically logged
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
**Features:**
|
|
456
|
-
- `ABCLoggingMixin` - Automatic method logging with performance tracking
|
|
457
|
-
- `StrictABCLoggingMixin` - Enforces implementation + logging
|
|
458
|
-
- Rate-limited logging to prevent log flooding
|
|
459
|
-
- Automatic timing of method execution
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
### 8. 🖥️ OS Utilities
|
|
464
|
-
|
|
465
|
-
Operating system utilities for command execution and path management.
|
|
466
|
-
|
|
467
|
-
**Use Cases:** Subprocess management, command discovery
|
|
468
|
-
|
|
469
|
-
```python
|
|
470
|
-
from winipedia_utils.os.os import which_with_raise, run_subprocess
|
|
471
|
-
|
|
472
|
-
# Find command path
|
|
473
|
-
python_path = which_with_raise("python")
|
|
474
|
-
|
|
475
|
-
# Run subprocess with timeout
|
|
476
|
-
result = run_subprocess(
|
|
477
|
-
["python", "-c", "print('hello')"],
|
|
478
|
-
timeout=5,
|
|
479
|
-
capture_output=True
|
|
480
|
-
)
|
|
481
|
-
print(result.stdout)
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
---
|
|
485
|
-
|
|
486
|
-
### 9. 🏗️ Projects Utilities
|
|
487
|
-
|
|
488
|
-
Poetry and project setup utilities.
|
|
489
|
-
|
|
490
|
-
**Use Cases:** Project initialization, configuration management
|
|
491
|
-
|
|
492
|
-
```python
|
|
493
|
-
from winipedia_utils.projects.project import make_name_from_package
|
|
494
|
-
from winipedia_utils.projects.poetry.config import get_poetry_package_name
|
|
495
|
-
|
|
496
|
-
# Get project name from pyproject.toml
|
|
497
|
-
project_name = get_poetry_package_name()
|
|
498
|
-
|
|
499
|
-
# Convert package name to human-readable format
|
|
500
|
-
readable_name = make_name_from_package(my_package)
|
|
501
|
-
# "my_package" -> "My-Package"
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
---
|
|
505
|
-
|
|
506
|
-
### 10. 🔐 Security Utilities
|
|
507
|
-
|
|
508
|
-
Encryption and secure credential storage using keyring.
|
|
509
|
-
|
|
510
|
-
**Use Cases:** API key management, secure data encryption
|
|
511
|
-
|
|
512
|
-
```python
|
|
513
|
-
from winipedia_utils.security.keyring import (
|
|
514
|
-
get_or_create_fernet,
|
|
515
|
-
get_or_create_aes_gcm
|
|
516
|
-
)
|
|
517
|
-
|
|
518
|
-
# Get or create Fernet encryption key
|
|
519
|
-
fernet, key_bytes = get_or_create_fernet("my_app", "user@example.com")
|
|
520
|
-
encrypted = fernet.encrypt(b"secret data")
|
|
521
|
-
decrypted = fernet.decrypt(encrypted)
|
|
522
|
-
|
|
523
|
-
# Get or create AES-GCM key
|
|
524
|
-
aes_gcm, key_bytes = get_or_create_aes_gcm("my_app", "user@example.com")
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
**Features:**
|
|
528
|
-
- Automatic key generation and storage
|
|
529
|
-
- Keyring integration for secure storage
|
|
530
|
-
- Support for Fernet and AES-GCM encryption
|
|
531
|
-
|
|
532
|
-
---
|
|
533
|
-
|
|
534
|
-
### 11. 🧪 Testing Utilities
|
|
535
|
-
|
|
536
|
-
Comprehensive testing framework with automatic test generation.
|
|
537
|
-
|
|
538
|
-
**Use Cases:** Test infrastructure, test discovery, custom assertions
|
|
539
|
-
|
|
540
|
-
```python
|
|
541
|
-
from winipedia_utils.testing.assertions import assert_with_msg
|
|
542
|
-
from winipedia_utils.testing.convention import (
|
|
543
|
-
make_test_obj_name,
|
|
544
|
-
get_test_obj_from_obj,
|
|
545
|
-
make_test_obj_importpath_from_obj
|
|
546
|
-
)
|
|
547
|
-
|
|
548
|
-
# Custom assertions
|
|
549
|
-
assert_with_msg(result == expected, "Result does not match expected value")
|
|
550
|
-
|
|
551
|
-
# Test naming conventions
|
|
552
|
-
test_name = make_test_obj_name(my_function) # "test_my_function"
|
|
553
|
-
|
|
554
|
-
# Get corresponding test object
|
|
555
|
-
test_obj = get_test_obj_from_obj(my_function)
|
|
556
|
-
|
|
557
|
-
# Get test import path
|
|
558
|
-
test_path = make_test_obj_importpath_from_obj(my_function)
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
**Features:**
|
|
562
|
-
- Automatic test file generation
|
|
563
|
-
- Mirror test structure matching source code
|
|
564
|
-
- Test naming conventions
|
|
565
|
-
- Fixture management with scopes (function, class, module, package, session)
|
|
566
|
-
|
|
567
|
-
---
|
|
568
|
-
|
|
569
|
-
### 12. 📄 Text Utilities
|
|
570
|
-
|
|
571
|
-
String manipulation and text processing utilities.
|
|
572
|
-
|
|
573
|
-
**Use Cases:** String processing, XML parsing, hashing, user input
|
|
574
|
-
|
|
575
|
-
```python
|
|
576
|
-
from winipedia_utils.text.string import (
|
|
577
|
-
ask_for_input_with_timeout,
|
|
578
|
-
find_xml_namespaces,
|
|
579
|
-
value_to_truncated_string,
|
|
580
|
-
get_reusable_hash,
|
|
581
|
-
split_on_uppercase
|
|
582
|
-
)
|
|
583
|
-
|
|
584
|
-
# Get user input with timeout
|
|
585
|
-
user_input = ask_for_input_with_timeout("Enter value: ", timeout=10)
|
|
586
|
-
|
|
587
|
-
# Extract XML namespaces
|
|
588
|
-
namespaces = find_xml_namespaces("<root xmlns:ns='http://example.com'/>")
|
|
589
|
-
|
|
590
|
-
# Truncate values for logging
|
|
591
|
-
truncated = value_to_truncated_string(large_object, max_length=50)
|
|
592
|
-
|
|
593
|
-
# Generate consistent hash
|
|
594
|
-
hash_value = get_reusable_hash({"key": "value"})
|
|
595
|
-
|
|
596
|
-
# Split on uppercase
|
|
597
|
-
parts = split_on_uppercase("HelloWorld") # ["Hello", "World"]
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
---
|
|
601
|
-
|
|
602
|
-
### 13. 🎨 Resources Utilities
|
|
603
|
-
|
|
604
|
-
SVG and resource utilities (minimal, may be removed in future versions).
|
|
605
|
-
|
|
606
|
-
---
|
|
607
|
-
|
|
608
|
-
## Usage Examples
|
|
609
|
-
|
|
610
|
-
### Example 1: Setting Up a New Project
|
|
611
|
-
|
|
612
|
-
```bash
|
|
613
|
-
# Create new project
|
|
614
|
-
mkdir my_project
|
|
615
|
-
cd my_project
|
|
616
|
-
|
|
617
|
-
# Initialize Poetry
|
|
618
|
-
poetry init
|
|
619
|
-
|
|
620
|
-
# Add winipedia-utils
|
|
621
|
-
poetry add winipedia-utils
|
|
622
|
-
|
|
623
|
-
# Run setup (this does everything!)
|
|
624
|
-
poetry run python -m winipedia_utils.setup
|
|
625
|
-
|
|
626
|
-
# Start coding
|
|
627
|
-
poetry run python -m my_project
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
### Example 2: Using Concurrent Processing
|
|
631
|
-
|
|
632
|
-
```python
|
|
633
|
-
from winipedia_utils.concurrent.multiprocessing import multiprocess_loop
|
|
634
|
-
|
|
635
|
-
def process_item(item_id, multiplier):
|
|
636
|
-
return item_id * multiplier
|
|
637
|
-
|
|
638
|
-
# Process 1000 items in parallel
|
|
639
|
-
items = [[i] for i in range(1000)]
|
|
640
|
-
results = multiprocess_loop(
|
|
641
|
-
process_item,
|
|
642
|
-
items,
|
|
643
|
-
process_args_static=[2], # multiplier = 2
|
|
644
|
-
process_args_len=1000
|
|
645
|
-
)
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
### Example 3: Building a Data Pipeline
|
|
649
|
-
|
|
650
|
-
```python
|
|
651
|
-
from winipedia_utils.data.dataframe.cleaning import CleaningDF
|
|
652
|
-
import polars as pl
|
|
653
|
-
|
|
654
|
-
class SalesDataCleaner(CleaningDF):
|
|
655
|
-
COL_PRODUCT = "product"
|
|
656
|
-
COL_AMOUNT = "amount"
|
|
657
|
-
|
|
658
|
-
@classmethod
|
|
659
|
-
def get_rename_map(cls):
|
|
660
|
-
return {cls.COL_PRODUCT: "product_name", cls.COL_AMOUNT: "sale_amount"}
|
|
661
|
-
|
|
662
|
-
@classmethod
|
|
663
|
-
def get_col_dtype_map(cls):
|
|
664
|
-
return {cls.COL_PRODUCT: pl.Utf8, cls.COL_AMOUNT: pl.Float64}
|
|
665
|
-
|
|
666
|
-
# ... implement other required methods ...
|
|
667
|
-
|
|
668
|
-
# Usage
|
|
669
|
-
raw_data = {"product_name": ["A", "B"], "sale_amount": [100.5, 200.7]}
|
|
670
|
-
cleaned = SalesDataCleaner(raw_data)
|
|
671
|
-
print(cleaned.df)
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
---
|
|
675
|
-
|
|
676
|
-
## Important Notes
|
|
677
|
-
|
|
678
|
-
### ⚠️ Git Commit Workflow
|
|
679
|
-
|
|
680
|
-
When using winipedia-utils, you **must** use Poetry to run git commit:
|
|
681
|
-
|
|
682
|
-
```bash
|
|
683
|
-
# ✅ Correct - Uses Python environment for pre-commit hook
|
|
684
|
-
poetry run git commit -m "Your commit message"
|
|
685
|
-
|
|
686
|
-
# ❌ Wrong - Pre-commit hook won't run properly
|
|
687
|
-
git commit -m "Your commit message"
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
This is necessary because the pre-commit hook needs access to the Python environment and installed packages.
|
|
691
|
-
|
|
692
|
-
### 📌 Internal Functions
|
|
693
|
-
|
|
694
|
-
Functions and methods starting with `_` are for **internal use only**:
|
|
695
|
-
|
|
696
|
-
```python
|
|
697
|
-
# ❌ Don't use these
|
|
698
|
-
from winipedia_utils.git.gitignore.gitignore import _get_gitignore_patterns
|
|
699
|
-
|
|
700
|
-
# ✅ Use public API instead
|
|
701
|
-
from winipedia_utils.git.gitignore.gitignore import add_patterns_to_gitignore
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
### 🎯 Philosophy
|
|
705
|
-
|
|
706
|
-
The core philosophy of Winipedia Utils is to:
|
|
707
|
-
|
|
708
|
-
> **Enforce good habits, ensure clean code, and save time when starting new projects**
|
|
709
|
-
|
|
710
|
-
By automating setup, testing, linting, formatting, and type checking, you can focus on writing business logic instead of configuring tools.
|
|
711
|
-
|
|
712
|
-
---
|
|
713
|
-
|
|
714
|
-
## Requirements
|
|
715
|
-
|
|
716
|
-
- **Python:** 3.12 or higher
|
|
717
|
-
- **Poetry:** For dependency management
|
|
718
|
-
- **Git:** For version control and pre-commit hooks
|
|
719
|
-
|
|
720
|
-
---
|
|
721
|
-
|
|
722
|
-
## License
|
|
723
|
-
|
|
724
|
-
MIT License - See [LICENSE](LICENSE) file for details
|
|
725
|
-
|
|
726
|
-
---
|
|
727
|
-
|
|
728
|
-
## Contributing
|
|
729
|
-
|
|
730
|
-
Contributions are welcome! Please ensure all code follows the project's quality standards:
|
|
731
|
-
|
|
732
|
-
- Type hints on all functions
|
|
733
|
-
- Comprehensive docstrings (Google style)
|
|
734
|
-
- Full test coverage
|
|
735
|
-
- Pass all linting and security checks
|
|
736
|
-
|
|
737
|
-
---
|
|
738
|
-
|