im-internals 0.4.2__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.
- im_internals-0.4.2/.github/workflows/publish.yaml +39 -0
- im_internals-0.4.2/.gitignore +72 -0
- im_internals-0.4.2/CHANGELOG.md +69 -0
- im_internals-0.4.2/CONTRIBUTING.md +129 -0
- im_internals-0.4.2/LICENSE +16 -0
- im_internals-0.4.2/PKG-INFO +156 -0
- im_internals-0.4.2/README.md +118 -0
- im_internals-0.4.2/docs/api/api.md +4 -0
- im_internals-0.4.2/docs/api/cfg_commands.md +4 -0
- im_internals-0.4.2/docs/api/email.md +4 -0
- im_internals-0.4.2/docs/api/file.md +4 -0
- im_internals-0.4.2/docs/api/folder.md +4 -0
- im_internals-0.4.2/docs/api/ftp.md +4 -0
- im_internals-0.4.2/docs/api/sanitize.md +4 -0
- im_internals-0.4.2/docs/api/sftp.md +4 -0
- im_internals-0.4.2/docs/api/sql.md +4 -0
- im_internals-0.4.2/docs/api/transfer.md +4 -0
- im_internals-0.4.2/docs/index.md +65 -0
- im_internals-0.4.2/im_internals/__init__.py +34 -0
- im_internals-0.4.2/im_internals/api.py +471 -0
- im_internals-0.4.2/im_internals/cfg_commands.py +185 -0
- im_internals-0.4.2/im_internals/email.py +224 -0
- im_internals-0.4.2/im_internals/file.py +216 -0
- im_internals-0.4.2/im_internals/folder.py +83 -0
- im_internals-0.4.2/im_internals/ftp.py +630 -0
- im_internals-0.4.2/im_internals/logging.py +221 -0
- im_internals-0.4.2/im_internals/sanitize.py +177 -0
- im_internals-0.4.2/im_internals/sftp.py +691 -0
- im_internals-0.4.2/im_internals/sql.py +251 -0
- im_internals-0.4.2/im_internals/transfer.py +536 -0
- im_internals-0.4.2/im_internals.egg-info/PKG-INFO +156 -0
- im_internals-0.4.2/im_internals.egg-info/SOURCES.txt +49 -0
- im_internals-0.4.2/im_internals.egg-info/dependency_links.txt +1 -0
- im_internals-0.4.2/im_internals.egg-info/entry_points.txt +2 -0
- im_internals-0.4.2/im_internals.egg-info/requires.txt +5 -0
- im_internals-0.4.2/im_internals.egg-info/scm_file_list.json +45 -0
- im_internals-0.4.2/im_internals.egg-info/scm_version.json +8 -0
- im_internals-0.4.2/im_internals.egg-info/top_level.txt +1 -0
- im_internals-0.4.2/mkdocs.yml +37 -0
- im_internals-0.4.2/pyproject.toml +58 -0
- im_internals-0.4.2/setup.cfg +4 -0
- im_internals-0.4.2/tests/test_api.py +256 -0
- im_internals-0.4.2/tests/test_cfg_commands.py +144 -0
- im_internals-0.4.2/tests/test_email.py +163 -0
- im_internals-0.4.2/tests/test_file.py +128 -0
- im_internals-0.4.2/tests/test_folder.py +104 -0
- im_internals-0.4.2/tests/test_ftp.py +250 -0
- im_internals-0.4.2/tests/test_sanitize.py +100 -0
- im_internals-0.4.2/tests/test_sftp.py +15 -0
- im_internals-0.4.2/tests/test_sql.py +41 -0
- im_internals-0.4.2/tests/test_transfer.py +19 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Publish Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
# any tag that starts with “v”, e.g. v0.2.0
|
|
6
|
+
tags:
|
|
7
|
+
- 'v*.*.*'
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build-and-publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
# required for PyPI Trusted Publishing (OIDC) - no API token/secret needed or stored here.
|
|
15
|
+
id-token: write
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v3
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.x'
|
|
24
|
+
|
|
25
|
+
- name: Install build tools
|
|
26
|
+
run: pip install build
|
|
27
|
+
|
|
28
|
+
- name: Build distributions
|
|
29
|
+
run: python -m build
|
|
30
|
+
|
|
31
|
+
- name: Create GitHub Release and upload wheel
|
|
32
|
+
uses: softprops/action-gh-release@v1
|
|
33
|
+
with:
|
|
34
|
+
files: dist/*
|
|
35
|
+
|
|
36
|
+
- name: Publish to PyPI
|
|
37
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
38
|
+
with:
|
|
39
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
eggs/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
.eggs/
|
|
16
|
+
|
|
17
|
+
# Virtual environment directories
|
|
18
|
+
venv/
|
|
19
|
+
.env/
|
|
20
|
+
ENV/
|
|
21
|
+
env/
|
|
22
|
+
|
|
23
|
+
# Installer logs
|
|
24
|
+
pip-log.txt
|
|
25
|
+
pip-delete-this-directory.txt
|
|
26
|
+
|
|
27
|
+
# Unit test / coverage reports
|
|
28
|
+
htmlcov/
|
|
29
|
+
.coverage
|
|
30
|
+
.coverage.*
|
|
31
|
+
.cache
|
|
32
|
+
.pytest_cache/
|
|
33
|
+
|
|
34
|
+
# MyPy
|
|
35
|
+
.mypy_cache/
|
|
36
|
+
.dmypy.json
|
|
37
|
+
|
|
38
|
+
# IDE/editor directories and files
|
|
39
|
+
.vscode/
|
|
40
|
+
.idea/
|
|
41
|
+
*.sublime-project
|
|
42
|
+
*.sublime-workspace
|
|
43
|
+
|
|
44
|
+
# OS files
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# Configuration files
|
|
49
|
+
config.yaml
|
|
50
|
+
|
|
51
|
+
# Logs and temporary files
|
|
52
|
+
*.log
|
|
53
|
+
/tmp/
|
|
54
|
+
|
|
55
|
+
# SFTP key files
|
|
56
|
+
id_rsa
|
|
57
|
+
id_rsa.pub
|
|
58
|
+
|
|
59
|
+
# PyInstaller
|
|
60
|
+
*.manifest
|
|
61
|
+
*.spec
|
|
62
|
+
|
|
63
|
+
# Sanity checks
|
|
64
|
+
*.bak
|
|
65
|
+
*.swp
|
|
66
|
+
|
|
67
|
+
# SQLite databases
|
|
68
|
+
*.sqlite3
|
|
69
|
+
|
|
70
|
+
# JetBrains IDE
|
|
71
|
+
*.iml
|
|
72
|
+
out/
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes. to **im-internals** will be documented in this file following the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
- (Future enhancements and fixes)
|
|
7
|
+
|
|
8
|
+
## [0.3.4] - 2026-09-10
|
|
9
|
+
### Fixed
|
|
10
|
+
- `transfer.Move.copy_files_or_folders`, `transfer.Move.copy_list_of_files_or_folders`, and
|
|
11
|
+
`transfer.recursive_folder_lookup` called the pre-rewrite two-argument `File(folder, filename)`
|
|
12
|
+
constructor and read a `.md_hash` attribute, both removed when `file.File` was rewritten to its
|
|
13
|
+
current single-argument `File(file_path)` / `.md5` API. Any of the three now raised
|
|
14
|
+
`TypeError: File.__init__() takes 2 positional arguments but 3 were given` as soon as a caller hit
|
|
15
|
+
the file-already-exists/hash-comparison branch (e.g. `Move.copy_files_or_folders(move_folder=True)`
|
|
16
|
+
recursing into an existing destination folder). No test coverage previously touched this path.
|
|
17
|
+
|
|
18
|
+
## [0.3.0] - 2026-04-02
|
|
19
|
+
### Added
|
|
20
|
+
- `project_logging` module — centralised logging singleton with `progress`, `warn`,
|
|
21
|
+
`error`, `log_kv`, and `step` helpers, plus stdout formatting with timestamps.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- All modules (`api`, `email`, `file`, `folder`, `ftp`, `sanitize`, `sftp`, `sql`,
|
|
25
|
+
`transfer`) migrated from bare `logging.*` / per-instance loggers to the
|
|
26
|
+
`project_logging` singleton.
|
|
27
|
+
- `Ftp._log_setup()` and `Sftp._log_setup()` now delegate to `project_logging.get()`
|
|
28
|
+
instead of creating their own `FileHandler`; `logger_name` parameters kept for
|
|
29
|
+
backward compatibility.
|
|
30
|
+
|
|
31
|
+
## [0.2.2] - 2025-08-14
|
|
32
|
+
- Changed name of the package from "im-internals" -> "im_internals"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## [0.2.1] - 2025-06-11
|
|
36
|
+
### Added
|
|
37
|
+
- Tests from `API` up to `SANITIZE`. Still needs tests for `SFTP, SQL, TRANSFER`
|
|
38
|
+
- [publish.yaml](.github%2Fworkflows%2Fpublish.yaml) to build package with every update. Buils upon using `tag vX.X.X` system. Tag should contain the same version as [pyproject.toml](pyproject.toml).
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- Bumped project version to 0.2.1.
|
|
42
|
+
- Added to [CONTRIBUTING.md](CONTRIBUTING.md) the `GIT commands` to verify if user has `Signed-off-by:` added to every commit
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## [0.2.0] - 2025-06-08
|
|
46
|
+
### Added
|
|
47
|
+
- PDF processing and text extraction utilities via `pypdf`.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
- Bumped project version to 0.2.0.
|
|
51
|
+
- Updated console script entry-point to PEP 621 format under `[project.entry-points]`.
|
|
52
|
+
- Cleaned up setuptools-specific package configuration.
|
|
53
|
+
|
|
54
|
+
## [0.1.0] - 2025-06-01
|
|
55
|
+
### Added
|
|
56
|
+
- Initial release of internal helper toolkit:
|
|
57
|
+
- Database helpers (`pyodbc`)
|
|
58
|
+
- SFTP & FTP utilities (`paramiko`, `ftplib`)
|
|
59
|
+
- API client wrappers with retry logic (`requests`, `tenacity`)
|
|
60
|
+
- Email send/receive utilities
|
|
61
|
+
- Configurable console script `cfg-commands`
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
[Unreleased]: https://github.com/<company>/im-internals/compare/v0.3.0...HEAD
|
|
65
|
+
[0.3.0]: https://github.com/<company>/im-internals/compare/v0.2.2...v0.3.0
|
|
66
|
+
[0.2.2]: https://github.com/<company>/im-internals/compare/v0.2.1...v0.2.2
|
|
67
|
+
[0.2.0]: https://github.com/<company>/im-internals/compare/v0.1.0...v0.2.0
|
|
68
|
+
[0.1.0]: https://github.com/<company>/im-internals/releases/tag/v0.1.0
|
|
69
|
+
```
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Writing CONTRIBUTING.md to disk for download
|
|
2
|
+
content = """# Contributing to im-internals
|
|
3
|
+
|
|
4
|
+
Thank you for considering contributing to **im-internals**, our internal helper toolkit. To keep the project consistent and maintainable, please follow these guidelines in your contributions.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
1. [Code Style](#code-style)
|
|
9
|
+
2. [Documentation](#documentation)
|
|
10
|
+
3. [Assertions](#assertions)
|
|
11
|
+
4. [Error Handling & Retries](#error-handling--retries)
|
|
12
|
+
5. [Testing](#testing)
|
|
13
|
+
6. [Commits & Pull Requests](#commits--pull-requests)
|
|
14
|
+
7. [Dependencies & Compatibility](#dependencies--compatibility)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Code Style
|
|
20
|
+
|
|
21
|
+
- **Python Version**: Target Python 3.10+.
|
|
22
|
+
- **Formatting**: Use [Black](https://github.com/psf/black) with default settings. Run `black .` before committing.
|
|
23
|
+
- **Linting**: Follow [flake8](https://github.com/PyCQA/flake8) rules. Run `flake8 .` to catch common issues.
|
|
24
|
+
- **Type Hints**: Annotate all functions and public methods with type hints. Use `typing` constructs where appropriate.
|
|
25
|
+
- **Naming**: Use `snake_case` for functions and variables, `PascalCase` for classes, and `UPPER_CASE` for constants.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## Documentation
|
|
29
|
+
|
|
30
|
+
- **Docstrings**: Every public function, class, and module must include a docstring following the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings).
|
|
31
|
+
- **README Updates**: If adding new features, update `README.md` to include usage examples and reference new functionality.
|
|
32
|
+
- **CHANGELOG**: Maintain `CHANGELOG.md` entries for notable changes, fixes, and improvements.
|
|
33
|
+
- **In-line Comments**: Add comments for non-obvious code sections to explain the intent and rationale.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Assertions
|
|
37
|
+
|
|
38
|
+
- Use `assert` statements to enforce internal invariants and catch programmer errors early.
|
|
39
|
+
- Avoid using `assert` for validating external inputs; instead, raise appropriate exceptions (e.g., `ValueError`, `TypeError`).
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## Error Handling & Retries
|
|
43
|
+
|
|
44
|
+
- **Exceptions**: Catch and handle exceptions thoughtfully. Do not swallow broad exceptions.
|
|
45
|
+
- **Retries**: For network or I/O operations (e.g., database queries, FTP/SFTP, API calls), use the [Tenacity](https://github.com/jd/tenacity) library:
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from tenacity import retry, stop_after_attempt, wait_exponential
|
|
49
|
+
|
|
50
|
+
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, max=10))
|
|
51
|
+
def fetch_data(...):
|
|
52
|
+
...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- **Configurable Parameters**: Allow retry parameters (attempts, wait time) to be configurable via function arguments or environment variables.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Testing
|
|
59
|
+
|
|
60
|
+
- **Unit Tests**: Write unit tests using [pytest](https://pytest.org). Place tests in the `tests/` directory mirroring the package structure.
|
|
61
|
+
- **Test Coverage**: Aim for at least 80% coverage. Use `pytest --cov` to measure coverage.
|
|
62
|
+
- **Fixtures & Mocks**: Use `pytest` fixtures and `unittest.mock` for isolating external dependencies (e.g., network, file system).
|
|
63
|
+
- **CI Integration**: Ensure all tests pass locally and in the CI pipeline before submitting a PR.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## Commits & Pull Requests
|
|
68
|
+
|
|
69
|
+
- **Branching**: Create feature branches named `feature/<name>` or bugfix branches named `bugfix/<issue-number>-<short-desc>`.
|
|
70
|
+
- **Commit Messages**: Use [Conventional Commits](https://www.conventionalcommits.org/) format:
|
|
71
|
+
```text
|
|
72
|
+
feat: add SFTP upload helper
|
|
73
|
+
fix: handle timeout in API client
|
|
74
|
+
docs: update README with new CLI options
|
|
75
|
+
```
|
|
76
|
+
### **Signed-off-by**:
|
|
77
|
+
- At the end of each commit message, include a `Signed-off-by:` trailer with your name and email, for example:
|
|
78
|
+
```text
|
|
79
|
+
Signed-off-by: Ivan Bilej <ivan.bilej@ironmountain.com>
|
|
80
|
+
```
|
|
81
|
+
To add this automatically, use:
|
|
82
|
+
```markdown
|
|
83
|
+
git commit -s -m "<type>: <scope> - <description>"
|
|
84
|
+
```
|
|
85
|
+
To enable auto sign-off for commits in just this repository, run:
|
|
86
|
+
```markdown
|
|
87
|
+
git config format.signoff true
|
|
88
|
+
```
|
|
89
|
+
To enable auto sign-off for all your commits globally, run:
|
|
90
|
+
```markdown
|
|
91
|
+
git config --global format.signoff true
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Verifying Signed-off-by
|
|
95
|
+
- Run one of these GIT commands:
|
|
96
|
+
- Verifies local only for this repo
|
|
97
|
+
```markdown
|
|
98
|
+
git config --get format.signoff
|
|
99
|
+
```
|
|
100
|
+
- Verifies the global signoff
|
|
101
|
+
```markdown
|
|
102
|
+
git config --get --global format.signoff
|
|
103
|
+
```
|
|
104
|
+
If it prints `true`, you've enabled the signoff
|
|
105
|
+
|
|
106
|
+
- OR Inspect the latest commit:
|
|
107
|
+
```markdown
|
|
108
|
+
git log -1 --pretty=format:"%B" HEAD
|
|
109
|
+
```
|
|
110
|
+
Ensure it ends with your `Signed-off-by:` trailer
|
|
111
|
+
- Test with an empty commit:
|
|
112
|
+
```markdown
|
|
113
|
+
git commit --allow-empty -s -m "test: verifying signoff"
|
|
114
|
+
git show -1
|
|
115
|
+
git reset --hard HEAD~1
|
|
116
|
+
```
|
|
117
|
+
This lets you verify signoff without impacting your branch
|
|
118
|
+
|
|
119
|
+
### **Pull Request**:
|
|
120
|
+
1. Reference the issue number in the PR title or description.
|
|
121
|
+
2. Describe the change, motivation, and any relevant details.
|
|
122
|
+
3. Ensure all checks (lint, tests, type checks) pass.
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
## Dependencies & Compatibility
|
|
126
|
+
|
|
127
|
+
- **Pinning**: For library dependencies, specify minimum versions only. Colleagues may tighten in downstream projects.
|
|
128
|
+
- **Compatibility**: Ensure new code does not break existing functionality. Run the full test suite after updating dependencies.
|
|
129
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Effective as of June 8, 2025
|
|
2
|
+
© 2025 Ivan Bilej
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted to Iron Mountain Czech Republic s.r.o. and Micro zone s.r.o.,
|
|
5
|
+
and to individuals who are actively employed by either of these companies,
|
|
6
|
+
to use, copy, modify, and distribute this software and derivative works
|
|
7
|
+
within those companies only, for any purpose, royalty-free.
|
|
8
|
+
|
|
9
|
+
External distribution, sublicensing, or publication of the source code
|
|
10
|
+
or derivative works is prohibited without the copyright holder’s
|
|
11
|
+
express written permission.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
14
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
15
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
16
|
+
CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY…
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: im_internals
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: Internal helper toolkit for DB, (S)FTP, API, e-mail and other utilities.
|
|
5
|
+
Author-email: Ivan Bilej <ivan.bilej@ironmountain.com>
|
|
6
|
+
License: Effective as of June 8, 2025
|
|
7
|
+
© 2025 Ivan Bilej
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted to Iron Mountain Czech Republic s.r.o. and Micro zone s.r.o.,
|
|
10
|
+
and to individuals who are actively employed by either of these companies,
|
|
11
|
+
to use, copy, modify, and distribute this software and derivative works
|
|
12
|
+
within those companies only, for any purpose, royalty-free.
|
|
13
|
+
|
|
14
|
+
External distribution, sublicensing, or publication of the source code
|
|
15
|
+
or derivative works is prohibited without the copyright holder’s
|
|
16
|
+
express written permission.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
19
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
20
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
21
|
+
CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY…
|
|
22
|
+
|
|
23
|
+
Project-URL: Source, https://github.com/Iron-Mountain-CR/IM_internals
|
|
24
|
+
Project-URL: Tracker, https://github.com/Iron-Mountain-CR/IM_internals/issues
|
|
25
|
+
Keywords: internal,helpers,toolkit,sftp,database,api
|
|
26
|
+
Classifier: Programming Language :: Python :: 3
|
|
27
|
+
Classifier: License :: Other/Proprietary License
|
|
28
|
+
Classifier: Operating System :: OS Independent
|
|
29
|
+
Requires-Python: >=3.10
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: requests>=2
|
|
33
|
+
Requires-Dist: paramiko>=3
|
|
34
|
+
Requires-Dist: pyodbc>=5
|
|
35
|
+
Requires-Dist: tenacity>=8
|
|
36
|
+
Requires-Dist: pypdf>=1
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# Writing README.md to disk for download
|
|
40
|
+
readme_content = """# im-internals
|
|
41
|
+
|
|
42
|
+
**im-internals** is an internal helper toolkit developed to streamline common tasks across database operations, (S)FTP transfers, API integrations, email handling, and other utilities within our organization.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Database Helpers**: Simplify connections and queries using `pyodbc`.
|
|
47
|
+
- **SFTP & FTP Utilities**: Secure file transfers via `paramiko` and built-in `ftplib` wrappers.
|
|
48
|
+
- **API Clients**: Lightweight wrappers for RESTful API interactions using `requests` and retry logic via `tenacity`.
|
|
49
|
+
- **Email Utilities**: Send and receive emails with built-in MIME support.
|
|
50
|
+
- **Configurable Commands**: Console script `cfg-commands` for running configuration-related tasks.
|
|
51
|
+
- **PDF Processing**: Basic PDF manipulation and text extraction using `PyPDF2`.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
This package is **not published to PyPI** — `pip install im-internals` will not work. Install
|
|
57
|
+
directly from a tagged GitHub Release wheel instead:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install --upgrade "https://github.com/Iron-Mountain-CR/IM_internals/releases/download/<tag>/im_internals-<version>-py3-none-any.whl"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Replace `<tag>`/`<version>` with the release you want, e.g. for `v0.3.4`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
python -m pip install --upgrade "https://github.com/Iron-Mountain-CR/IM_internals/releases/download/v0.3.4/im_internals-0.3.4-py3-none-any.whl"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Verify the installed version:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
python -c "import im_internals; print(im_internals.__version__)"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Alternatively, to always track the latest `main` (rebuilds from source on every install, no URL to
|
|
76
|
+
update per release):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python -m pip install --upgrade "git+https://github.com/Iron-Mountain-CR/IM_internals.git@main"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## Quick Start
|
|
84
|
+
### Database Example
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from im_internals.db import Database
|
|
88
|
+
|
|
89
|
+
# Initialize and query
|
|
90
|
+
db = Database(dsn="MY_DB_DSN")
|
|
91
|
+
rows = db.query("SELECT * FROM my_table WHERE status=?", params=("active",))
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### SFTP Upload
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from im_internals.sftp import SFTPClient
|
|
99
|
+
|
|
100
|
+
client = SFTPClient(host="sftp.example.com", user="user", key_path="~/.ssh/id_rsa")
|
|
101
|
+
client.upload_file(local_path="data.csv", remote_path="/incoming/data.csv")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
### API Request with Retries
|
|
106
|
+
```python
|
|
107
|
+
from im_internals.api import ApiClient
|
|
108
|
+
|
|
109
|
+
api = ApiClient(base_url="https://api.example.com", retry_config={"tries":3, "wait":2})
|
|
110
|
+
response = api.get("/v1/resource")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
### Send Email
|
|
115
|
+
```python
|
|
116
|
+
from im_internals.email import EmailClient
|
|
117
|
+
|
|
118
|
+
email = EmailClient(smtp_host="smtp.example.com", port=587)
|
|
119
|
+
email.send(
|
|
120
|
+
sender="noreply@company.com",
|
|
121
|
+
recipients=["user@company.com"],
|
|
122
|
+
subject="Test Email",
|
|
123
|
+
body="Hello from im-internals!"
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## CLI Usage
|
|
129
|
+
```markdown
|
|
130
|
+
# View available cfg-commands
|
|
131
|
+
cfg-commands --help
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
## Configuration
|
|
136
|
+
All configuration parameters—including database DSNs, SFTP credentials, API settings, and email credentials—are managed via company-standard .cfg files stored and secured externally. Do not include any credentials or config files in this repository.
|
|
137
|
+
A typical .cfg file follows the INI format. Example section for email:
|
|
138
|
+
```markdown
|
|
139
|
+
[email]
|
|
140
|
+
host = smtp.example.com
|
|
141
|
+
port = 587
|
|
142
|
+
user = your_email_username
|
|
143
|
+
password = your_email_password
|
|
144
|
+
use_tls = true
|
|
145
|
+
```
|
|
146
|
+
By default, if you omit the -p/--path flag, cfg-commands will scan the current working directory for the first .cfg or .CFG file and use that. There is no built-in default path such as ~/.im-internals.cfg—to specify a file in another location, always use -p <path>.
|
|
147
|
+
Clients will inject values into environment variables or client constructors based on the loaded .cfg file.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
## Contributing
|
|
152
|
+
Thank you for considering contributing to **im-internals**! Please follow the guidelines outlined in [CONTRIBUTING.md](CONTRIBUTING.md) to keep the project consistent and maintainable.
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
This toolkit is proprietary and intended for internal use only. See the [LICENSE](LICENSE) file at the project root for full terms.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Writing README.md to disk for download
|
|
2
|
+
readme_content = """# im-internals
|
|
3
|
+
|
|
4
|
+
**im-internals** is an internal helper toolkit developed to streamline common tasks across database operations, (S)FTP transfers, API integrations, email handling, and other utilities within our organization.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- **Database Helpers**: Simplify connections and queries using `pyodbc`.
|
|
9
|
+
- **SFTP & FTP Utilities**: Secure file transfers via `paramiko` and built-in `ftplib` wrappers.
|
|
10
|
+
- **API Clients**: Lightweight wrappers for RESTful API interactions using `requests` and retry logic via `tenacity`.
|
|
11
|
+
- **Email Utilities**: Send and receive emails with built-in MIME support.
|
|
12
|
+
- **Configurable Commands**: Console script `cfg-commands` for running configuration-related tasks.
|
|
13
|
+
- **PDF Processing**: Basic PDF manipulation and text extraction using `PyPDF2`.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
This package is **not published to PyPI** — `pip install im-internals` will not work. Install
|
|
19
|
+
directly from a tagged GitHub Release wheel instead:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install --upgrade "https://github.com/Iron-Mountain-CR/IM_internals/releases/download/<tag>/im_internals-<version>-py3-none-any.whl"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Replace `<tag>`/`<version>` with the release you want, e.g. for `v0.3.4`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python -m pip install --upgrade "https://github.com/Iron-Mountain-CR/IM_internals/releases/download/v0.3.4/im_internals-0.3.4-py3-none-any.whl"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Verify the installed version:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -c "import im_internals; print(im_internals.__version__)"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Alternatively, to always track the latest `main` (rebuilds from source on every install, no URL to
|
|
38
|
+
update per release):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python -m pip install --upgrade "git+https://github.com/Iron-Mountain-CR/IM_internals.git@main"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
### Database Example
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from im_internals.db import Database
|
|
50
|
+
|
|
51
|
+
# Initialize and query
|
|
52
|
+
db = Database(dsn="MY_DB_DSN")
|
|
53
|
+
rows = db.query("SELECT * FROM my_table WHERE status=?", params=("active",))
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### SFTP Upload
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from im_internals.sftp import SFTPClient
|
|
61
|
+
|
|
62
|
+
client = SFTPClient(host="sftp.example.com", user="user", key_path="~/.ssh/id_rsa")
|
|
63
|
+
client.upload_file(local_path="data.csv", remote_path="/incoming/data.csv")
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### API Request with Retries
|
|
68
|
+
```python
|
|
69
|
+
from im_internals.api import ApiClient
|
|
70
|
+
|
|
71
|
+
api = ApiClient(base_url="https://api.example.com", retry_config={"tries":3, "wait":2})
|
|
72
|
+
response = api.get("/v1/resource")
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Send Email
|
|
77
|
+
```python
|
|
78
|
+
from im_internals.email import EmailClient
|
|
79
|
+
|
|
80
|
+
email = EmailClient(smtp_host="smtp.example.com", port=587)
|
|
81
|
+
email.send(
|
|
82
|
+
sender="noreply@company.com",
|
|
83
|
+
recipients=["user@company.com"],
|
|
84
|
+
subject="Test Email",
|
|
85
|
+
body="Hello from im-internals!"
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## CLI Usage
|
|
91
|
+
```markdown
|
|
92
|
+
# View available cfg-commands
|
|
93
|
+
cfg-commands --help
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
All configuration parameters—including database DSNs, SFTP credentials, API settings, and email credentials—are managed via company-standard .cfg files stored and secured externally. Do not include any credentials or config files in this repository.
|
|
99
|
+
A typical .cfg file follows the INI format. Example section for email:
|
|
100
|
+
```markdown
|
|
101
|
+
[email]
|
|
102
|
+
host = smtp.example.com
|
|
103
|
+
port = 587
|
|
104
|
+
user = your_email_username
|
|
105
|
+
password = your_email_password
|
|
106
|
+
use_tls = true
|
|
107
|
+
```
|
|
108
|
+
By default, if you omit the -p/--path flag, cfg-commands will scan the current working directory for the first .cfg or .CFG file and use that. There is no built-in default path such as ~/.im-internals.cfg—to specify a file in another location, always use -p <path>.
|
|
109
|
+
Clients will inject values into environment variables or client constructors based on the loaded .cfg file.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## Contributing
|
|
114
|
+
Thank you for considering contributing to **im-internals**! Please follow the guidelines outlined in [CONTRIBUTING.md](CONTRIBUTING.md) to keep the project consistent and maintainable.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
This toolkit is proprietary and intended for internal use only. See the [LICENSE](LICENSE) file at the project root for full terms.
|