cli-ih 0.6.3.1__py3-none-any.whl → 0.7.1__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.
- cli_ih/__init__.py +1 -0
- cli_ih/asyncClient.py +109 -10
- cli_ih/client.py +110 -18
- cli_ih/utils.py +51 -0
- cli_ih-0.7.1.dist-info/METADATA +100 -0
- cli_ih-0.7.1.dist-info/RECORD +9 -0
- {cli_ih-0.6.3.1.dist-info → cli_ih-0.7.1.dist-info}/top_level.txt +0 -1
- cli_ih-0.6.3.1.dist-info/METADATA +0 -86
- cli_ih-0.6.3.1.dist-info/RECORD +0 -425
- venv/Lib/site-packages/__editable___cli_ih_0_6_3_1_finder.py +0 -85
- venv/Lib/site-packages/pip/__init__.py +0 -13
- venv/Lib/site-packages/pip/__main__.py +0 -24
- venv/Lib/site-packages/pip/__pip-runner__.py +0 -50
- venv/Lib/site-packages/pip/_internal/__init__.py +0 -18
- venv/Lib/site-packages/pip/_internal/build_env.py +0 -349
- venv/Lib/site-packages/pip/_internal/cache.py +0 -291
- venv/Lib/site-packages/pip/_internal/cli/__init__.py +0 -3
- venv/Lib/site-packages/pip/_internal/cli/autocompletion.py +0 -184
- venv/Lib/site-packages/pip/_internal/cli/base_command.py +0 -244
- venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py +0 -1138
- venv/Lib/site-packages/pip/_internal/cli/command_context.py +0 -28
- venv/Lib/site-packages/pip/_internal/cli/index_command.py +0 -175
- venv/Lib/site-packages/pip/_internal/cli/main.py +0 -80
- venv/Lib/site-packages/pip/_internal/cli/main_parser.py +0 -134
- venv/Lib/site-packages/pip/_internal/cli/parser.py +0 -298
- venv/Lib/site-packages/pip/_internal/cli/progress_bars.py +0 -151
- venv/Lib/site-packages/pip/_internal/cli/req_command.py +0 -351
- venv/Lib/site-packages/pip/_internal/cli/spinners.py +0 -235
- venv/Lib/site-packages/pip/_internal/cli/status_codes.py +0 -6
- venv/Lib/site-packages/pip/_internal/commands/__init__.py +0 -139
- venv/Lib/site-packages/pip/_internal/commands/cache.py +0 -231
- venv/Lib/site-packages/pip/_internal/commands/check.py +0 -66
- venv/Lib/site-packages/pip/_internal/commands/completion.py +0 -135
- venv/Lib/site-packages/pip/_internal/commands/configuration.py +0 -288
- venv/Lib/site-packages/pip/_internal/commands/debug.py +0 -203
- venv/Lib/site-packages/pip/_internal/commands/download.py +0 -145
- venv/Lib/site-packages/pip/_internal/commands/freeze.py +0 -107
- venv/Lib/site-packages/pip/_internal/commands/hash.py +0 -58
- venv/Lib/site-packages/pip/_internal/commands/help.py +0 -40
- venv/Lib/site-packages/pip/_internal/commands/index.py +0 -159
- venv/Lib/site-packages/pip/_internal/commands/inspect.py +0 -92
- venv/Lib/site-packages/pip/_internal/commands/install.py +0 -798
- venv/Lib/site-packages/pip/_internal/commands/list.py +0 -400
- venv/Lib/site-packages/pip/_internal/commands/lock.py +0 -170
- venv/Lib/site-packages/pip/_internal/commands/search.py +0 -178
- venv/Lib/site-packages/pip/_internal/commands/show.py +0 -231
- venv/Lib/site-packages/pip/_internal/commands/uninstall.py +0 -113
- venv/Lib/site-packages/pip/_internal/commands/wheel.py +0 -181
- venv/Lib/site-packages/pip/_internal/configuration.py +0 -397
- venv/Lib/site-packages/pip/_internal/distributions/__init__.py +0 -21
- venv/Lib/site-packages/pip/_internal/distributions/base.py +0 -55
- venv/Lib/site-packages/pip/_internal/distributions/installed.py +0 -33
- venv/Lib/site-packages/pip/_internal/distributions/sdist.py +0 -165
- venv/Lib/site-packages/pip/_internal/distributions/wheel.py +0 -44
- venv/Lib/site-packages/pip/_internal/exceptions.py +0 -881
- venv/Lib/site-packages/pip/_internal/index/__init__.py +0 -1
- venv/Lib/site-packages/pip/_internal/index/collector.py +0 -489
- venv/Lib/site-packages/pip/_internal/index/package_finder.py +0 -1059
- venv/Lib/site-packages/pip/_internal/index/sources.py +0 -287
- venv/Lib/site-packages/pip/_internal/locations/__init__.py +0 -441
- venv/Lib/site-packages/pip/_internal/locations/_distutils.py +0 -173
- venv/Lib/site-packages/pip/_internal/locations/_sysconfig.py +0 -215
- venv/Lib/site-packages/pip/_internal/locations/base.py +0 -82
- venv/Lib/site-packages/pip/_internal/main.py +0 -12
- venv/Lib/site-packages/pip/_internal/metadata/__init__.py +0 -164
- venv/Lib/site-packages/pip/_internal/metadata/_json.py +0 -87
- venv/Lib/site-packages/pip/_internal/metadata/base.py +0 -685
- venv/Lib/site-packages/pip/_internal/metadata/importlib/__init__.py +0 -6
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_compat.py +0 -87
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +0 -223
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +0 -143
- venv/Lib/site-packages/pip/_internal/metadata/pkg_resources.py +0 -298
- venv/Lib/site-packages/pip/_internal/models/__init__.py +0 -1
- venv/Lib/site-packages/pip/_internal/models/candidate.py +0 -25
- venv/Lib/site-packages/pip/_internal/models/direct_url.py +0 -227
- venv/Lib/site-packages/pip/_internal/models/format_control.py +0 -78
- venv/Lib/site-packages/pip/_internal/models/index.py +0 -28
- venv/Lib/site-packages/pip/_internal/models/installation_report.py +0 -57
- venv/Lib/site-packages/pip/_internal/models/link.py +0 -613
- venv/Lib/site-packages/pip/_internal/models/pylock.py +0 -188
- venv/Lib/site-packages/pip/_internal/models/scheme.py +0 -25
- venv/Lib/site-packages/pip/_internal/models/search_scope.py +0 -126
- venv/Lib/site-packages/pip/_internal/models/selection_prefs.py +0 -53
- venv/Lib/site-packages/pip/_internal/models/target_python.py +0 -122
- venv/Lib/site-packages/pip/_internal/models/wheel.py +0 -141
- venv/Lib/site-packages/pip/_internal/network/__init__.py +0 -1
- venv/Lib/site-packages/pip/_internal/network/auth.py +0 -564
- venv/Lib/site-packages/pip/_internal/network/cache.py +0 -133
- venv/Lib/site-packages/pip/_internal/network/download.py +0 -342
- venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py +0 -213
- venv/Lib/site-packages/pip/_internal/network/session.py +0 -528
- venv/Lib/site-packages/pip/_internal/network/utils.py +0 -98
- venv/Lib/site-packages/pip/_internal/network/xmlrpc.py +0 -61
- venv/Lib/site-packages/pip/_internal/operations/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/operations/build/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/operations/build/build_tracker.py +0 -140
- venv/Lib/site-packages/pip/_internal/operations/build/metadata.py +0 -38
- venv/Lib/site-packages/pip/_internal/operations/build/metadata_editable.py +0 -41
- venv/Lib/site-packages/pip/_internal/operations/build/metadata_legacy.py +0 -73
- venv/Lib/site-packages/pip/_internal/operations/build/wheel.py +0 -38
- venv/Lib/site-packages/pip/_internal/operations/build/wheel_editable.py +0 -47
- venv/Lib/site-packages/pip/_internal/operations/build/wheel_legacy.py +0 -119
- venv/Lib/site-packages/pip/_internal/operations/check.py +0 -175
- venv/Lib/site-packages/pip/_internal/operations/freeze.py +0 -259
- venv/Lib/site-packages/pip/_internal/operations/install/__init__.py +0 -1
- venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py +0 -48
- venv/Lib/site-packages/pip/_internal/operations/install/wheel.py +0 -746
- venv/Lib/site-packages/pip/_internal/operations/prepare.py +0 -742
- venv/Lib/site-packages/pip/_internal/pyproject.py +0 -182
- venv/Lib/site-packages/pip/_internal/req/__init__.py +0 -105
- venv/Lib/site-packages/pip/_internal/req/constructors.py +0 -562
- venv/Lib/site-packages/pip/_internal/req/req_dependency_group.py +0 -75
- venv/Lib/site-packages/pip/_internal/req/req_file.py +0 -620
- venv/Lib/site-packages/pip/_internal/req/req_install.py +0 -937
- venv/Lib/site-packages/pip/_internal/req/req_set.py +0 -81
- venv/Lib/site-packages/pip/_internal/req/req_uninstall.py +0 -639
- venv/Lib/site-packages/pip/_internal/resolution/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/base.py +0 -20
- venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +0 -598
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +0 -142
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +0 -582
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +0 -814
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +0 -166
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +0 -276
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py +0 -85
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py +0 -247
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +0 -336
- venv/Lib/site-packages/pip/_internal/self_outdated_check.py +0 -254
- venv/Lib/site-packages/pip/_internal/utils/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/utils/_jaraco_text.py +0 -109
- venv/Lib/site-packages/pip/_internal/utils/_log.py +0 -38
- venv/Lib/site-packages/pip/_internal/utils/appdirs.py +0 -52
- venv/Lib/site-packages/pip/_internal/utils/compat.py +0 -85
- venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py +0 -201
- venv/Lib/site-packages/pip/_internal/utils/datetime.py +0 -10
- venv/Lib/site-packages/pip/_internal/utils/deprecation.py +0 -126
- venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py +0 -87
- venv/Lib/site-packages/pip/_internal/utils/egg_link.py +0 -81
- venv/Lib/site-packages/pip/_internal/utils/entrypoints.py +0 -88
- venv/Lib/site-packages/pip/_internal/utils/filesystem.py +0 -152
- venv/Lib/site-packages/pip/_internal/utils/filetypes.py +0 -24
- venv/Lib/site-packages/pip/_internal/utils/glibc.py +0 -102
- venv/Lib/site-packages/pip/_internal/utils/hashes.py +0 -150
- venv/Lib/site-packages/pip/_internal/utils/logging.py +0 -364
- venv/Lib/site-packages/pip/_internal/utils/misc.py +0 -765
- venv/Lib/site-packages/pip/_internal/utils/packaging.py +0 -44
- venv/Lib/site-packages/pip/_internal/utils/retry.py +0 -45
- venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py +0 -149
- venv/Lib/site-packages/pip/_internal/utils/subprocess.py +0 -248
- venv/Lib/site-packages/pip/_internal/utils/temp_dir.py +0 -294
- venv/Lib/site-packages/pip/_internal/utils/unpacking.py +0 -337
- venv/Lib/site-packages/pip/_internal/utils/urls.py +0 -55
- venv/Lib/site-packages/pip/_internal/utils/virtualenv.py +0 -105
- venv/Lib/site-packages/pip/_internal/utils/wheel.py +0 -132
- venv/Lib/site-packages/pip/_internal/vcs/__init__.py +0 -15
- venv/Lib/site-packages/pip/_internal/vcs/bazaar.py +0 -130
- venv/Lib/site-packages/pip/_internal/vcs/git.py +0 -571
- venv/Lib/site-packages/pip/_internal/vcs/mercurial.py +0 -186
- venv/Lib/site-packages/pip/_internal/vcs/subversion.py +0 -335
- venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +0 -693
- venv/Lib/site-packages/pip/_internal/wheel_builder.py +0 -334
- venv/Lib/site-packages/pip/_vendor/__init__.py +0 -117
- venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py +0 -29
- venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py +0 -70
- venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py +0 -168
- venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py +0 -75
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +0 -8
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +0 -145
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +0 -48
- venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py +0 -511
- venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py +0 -119
- venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py +0 -157
- venv/Lib/site-packages/pip/_vendor/cachecontrol/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py +0 -146
- venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py +0 -43
- venv/Lib/site-packages/pip/_vendor/certifi/__init__.py +0 -4
- venv/Lib/site-packages/pip/_vendor/certifi/__main__.py +0 -12
- venv/Lib/site-packages/pip/_vendor/certifi/core.py +0 -83
- venv/Lib/site-packages/pip/_vendor/certifi/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/dependency_groups/__init__.py +0 -13
- venv/Lib/site-packages/pip/_vendor/dependency_groups/__main__.py +0 -65
- venv/Lib/site-packages/pip/_vendor/dependency_groups/_implementation.py +0 -209
- venv/Lib/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py +0 -59
- venv/Lib/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py +0 -62
- venv/Lib/site-packages/pip/_vendor/dependency_groups/_toml_compat.py +0 -9
- venv/Lib/site-packages/pip/_vendor/dependency_groups/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/distlib/__init__.py +0 -33
- venv/Lib/site-packages/pip/_vendor/distlib/compat.py +0 -1137
- venv/Lib/site-packages/pip/_vendor/distlib/resources.py +0 -358
- venv/Lib/site-packages/pip/_vendor/distlib/scripts.py +0 -447
- venv/Lib/site-packages/pip/_vendor/distlib/util.py +0 -1984
- venv/Lib/site-packages/pip/_vendor/distro/__init__.py +0 -54
- venv/Lib/site-packages/pip/_vendor/distro/__main__.py +0 -4
- venv/Lib/site-packages/pip/_vendor/distro/distro.py +0 -1403
- venv/Lib/site-packages/pip/_vendor/distro/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/idna/__init__.py +0 -45
- venv/Lib/site-packages/pip/_vendor/idna/codec.py +0 -122
- venv/Lib/site-packages/pip/_vendor/idna/compat.py +0 -15
- venv/Lib/site-packages/pip/_vendor/idna/core.py +0 -437
- venv/Lib/site-packages/pip/_vendor/idna/idnadata.py +0 -4243
- venv/Lib/site-packages/pip/_vendor/idna/intranges.py +0 -57
- venv/Lib/site-packages/pip/_vendor/idna/package_data.py +0 -1
- venv/Lib/site-packages/pip/_vendor/idna/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/idna/uts46data.py +0 -8681
- venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py +0 -55
- venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py +0 -48
- venv/Lib/site-packages/pip/_vendor/msgpack/ext.py +0 -170
- venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py +0 -929
- venv/Lib/site-packages/pip/_vendor/packaging/__init__.py +0 -15
- venv/Lib/site-packages/pip/_vendor/packaging/_elffile.py +0 -109
- venv/Lib/site-packages/pip/_vendor/packaging/_manylinux.py +0 -262
- venv/Lib/site-packages/pip/_vendor/packaging/_musllinux.py +0 -85
- venv/Lib/site-packages/pip/_vendor/packaging/_parser.py +0 -353
- venv/Lib/site-packages/pip/_vendor/packaging/_structures.py +0 -61
- venv/Lib/site-packages/pip/_vendor/packaging/_tokenizer.py +0 -195
- venv/Lib/site-packages/pip/_vendor/packaging/licenses/__init__.py +0 -145
- venv/Lib/site-packages/pip/_vendor/packaging/licenses/_spdx.py +0 -759
- venv/Lib/site-packages/pip/_vendor/packaging/markers.py +0 -362
- venv/Lib/site-packages/pip/_vendor/packaging/metadata.py +0 -862
- venv/Lib/site-packages/pip/_vendor/packaging/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/packaging/requirements.py +0 -91
- venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py +0 -1019
- venv/Lib/site-packages/pip/_vendor/packaging/tags.py +0 -656
- venv/Lib/site-packages/pip/_vendor/packaging/utils.py +0 -163
- venv/Lib/site-packages/pip/_vendor/packaging/version.py +0 -582
- venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py +0 -3676
- venv/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +0 -631
- venv/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +0 -55
- venv/Lib/site-packages/pip/_vendor/platformdirs/android.py +0 -249
- venv/Lib/site-packages/pip/_vendor/platformdirs/api.py +0 -299
- venv/Lib/site-packages/pip/_vendor/platformdirs/macos.py +0 -144
- venv/Lib/site-packages/pip/_vendor/platformdirs/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/unix.py +0 -272
- venv/Lib/site-packages/pip/_vendor/platformdirs/version.py +0 -21
- venv/Lib/site-packages/pip/_vendor/platformdirs/windows.py +0 -272
- venv/Lib/site-packages/pip/_vendor/pygments/__init__.py +0 -82
- venv/Lib/site-packages/pip/_vendor/pygments/__main__.py +0 -17
- venv/Lib/site-packages/pip/_vendor/pygments/console.py +0 -70
- venv/Lib/site-packages/pip/_vendor/pygments/filter.py +0 -70
- venv/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +0 -940
- venv/Lib/site-packages/pip/_vendor/pygments/formatter.py +0 -129
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +0 -157
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/_mapping.py +0 -23
- venv/Lib/site-packages/pip/_vendor/pygments/lexer.py +0 -963
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +0 -362
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +0 -602
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +0 -1201
- venv/Lib/site-packages/pip/_vendor/pygments/modeline.py +0 -43
- venv/Lib/site-packages/pip/_vendor/pygments/plugin.py +0 -72
- venv/Lib/site-packages/pip/_vendor/pygments/regexopt.py +0 -91
- venv/Lib/site-packages/pip/_vendor/pygments/scanner.py +0 -104
- venv/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +0 -247
- venv/Lib/site-packages/pip/_vendor/pygments/style.py +0 -203
- venv/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +0 -61
- venv/Lib/site-packages/pip/_vendor/pygments/styles/_mapping.py +0 -54
- venv/Lib/site-packages/pip/_vendor/pygments/token.py +0 -214
- venv/Lib/site-packages/pip/_vendor/pygments/unistring.py +0 -153
- venv/Lib/site-packages/pip/_vendor/pygments/util.py +0 -324
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__init__.py +0 -31
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_impl.py +0 -410
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py +0 -21
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py +0 -389
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/requests/__init__.py +0 -179
- venv/Lib/site-packages/pip/_vendor/requests/__version__.py +0 -14
- venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +0 -50
- venv/Lib/site-packages/pip/_vendor/requests/adapters.py +0 -719
- venv/Lib/site-packages/pip/_vendor/requests/api.py +0 -157
- venv/Lib/site-packages/pip/_vendor/requests/auth.py +0 -314
- venv/Lib/site-packages/pip/_vendor/requests/certs.py +0 -17
- venv/Lib/site-packages/pip/_vendor/requests/compat.py +0 -90
- venv/Lib/site-packages/pip/_vendor/requests/cookies.py +0 -561
- venv/Lib/site-packages/pip/_vendor/requests/exceptions.py +0 -151
- venv/Lib/site-packages/pip/_vendor/requests/help.py +0 -127
- venv/Lib/site-packages/pip/_vendor/requests/hooks.py +0 -33
- venv/Lib/site-packages/pip/_vendor/requests/models.py +0 -1039
- venv/Lib/site-packages/pip/_vendor/requests/packages.py +0 -25
- venv/Lib/site-packages/pip/_vendor/requests/sessions.py +0 -831
- venv/Lib/site-packages/pip/_vendor/requests/status_codes.py +0 -128
- venv/Lib/site-packages/pip/_vendor/requests/structures.py +0 -99
- venv/Lib/site-packages/pip/_vendor/requests/utils.py +0 -1086
- venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py +0 -27
- venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py +0 -196
- venv/Lib/site-packages/pip/_vendor/resolvelib/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py +0 -55
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py +0 -27
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py +0 -47
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py +0 -48
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py +0 -57
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py +0 -622
- venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py +0 -209
- venv/Lib/site-packages/pip/_vendor/rich/__init__.py +0 -177
- venv/Lib/site-packages/pip/_vendor/rich/__main__.py +0 -245
- venv/Lib/site-packages/pip/_vendor/rich/_cell_widths.py +0 -454
- venv/Lib/site-packages/pip/_vendor/rich/_emoji_codes.py +0 -3610
- venv/Lib/site-packages/pip/_vendor/rich/_emoji_replace.py +0 -32
- venv/Lib/site-packages/pip/_vendor/rich/_export_format.py +0 -76
- venv/Lib/site-packages/pip/_vendor/rich/_extension.py +0 -10
- venv/Lib/site-packages/pip/_vendor/rich/_fileno.py +0 -24
- venv/Lib/site-packages/pip/_vendor/rich/_inspect.py +0 -268
- venv/Lib/site-packages/pip/_vendor/rich/_log_render.py +0 -94
- venv/Lib/site-packages/pip/_vendor/rich/_loop.py +0 -43
- venv/Lib/site-packages/pip/_vendor/rich/_null_file.py +0 -69
- venv/Lib/site-packages/pip/_vendor/rich/_palettes.py +0 -309
- venv/Lib/site-packages/pip/_vendor/rich/_pick.py +0 -17
- venv/Lib/site-packages/pip/_vendor/rich/_ratio.py +0 -153
- venv/Lib/site-packages/pip/_vendor/rich/_spinners.py +0 -482
- venv/Lib/site-packages/pip/_vendor/rich/_stack.py +0 -16
- venv/Lib/site-packages/pip/_vendor/rich/_timer.py +0 -19
- venv/Lib/site-packages/pip/_vendor/rich/_win32_console.py +0 -661
- venv/Lib/site-packages/pip/_vendor/rich/_windows.py +0 -71
- venv/Lib/site-packages/pip/_vendor/rich/_windows_renderer.py +0 -56
- venv/Lib/site-packages/pip/_vendor/rich/_wrap.py +0 -93
- venv/Lib/site-packages/pip/_vendor/rich/abc.py +0 -33
- venv/Lib/site-packages/pip/_vendor/rich/align.py +0 -306
- venv/Lib/site-packages/pip/_vendor/rich/ansi.py +0 -241
- venv/Lib/site-packages/pip/_vendor/rich/bar.py +0 -93
- venv/Lib/site-packages/pip/_vendor/rich/box.py +0 -474
- venv/Lib/site-packages/pip/_vendor/rich/cells.py +0 -174
- venv/Lib/site-packages/pip/_vendor/rich/color.py +0 -621
- venv/Lib/site-packages/pip/_vendor/rich/color_triplet.py +0 -38
- venv/Lib/site-packages/pip/_vendor/rich/columns.py +0 -187
- venv/Lib/site-packages/pip/_vendor/rich/console.py +0 -2680
- venv/Lib/site-packages/pip/_vendor/rich/constrain.py +0 -37
- venv/Lib/site-packages/pip/_vendor/rich/containers.py +0 -167
- venv/Lib/site-packages/pip/_vendor/rich/control.py +0 -219
- venv/Lib/site-packages/pip/_vendor/rich/default_styles.py +0 -193
- venv/Lib/site-packages/pip/_vendor/rich/diagnose.py +0 -39
- venv/Lib/site-packages/pip/_vendor/rich/emoji.py +0 -91
- venv/Lib/site-packages/pip/_vendor/rich/errors.py +0 -34
- venv/Lib/site-packages/pip/_vendor/rich/file_proxy.py +0 -57
- venv/Lib/site-packages/pip/_vendor/rich/filesize.py +0 -88
- venv/Lib/site-packages/pip/_vendor/rich/highlighter.py +0 -232
- venv/Lib/site-packages/pip/_vendor/rich/json.py +0 -139
- venv/Lib/site-packages/pip/_vendor/rich/jupyter.py +0 -101
- venv/Lib/site-packages/pip/_vendor/rich/layout.py +0 -442
- venv/Lib/site-packages/pip/_vendor/rich/live.py +0 -400
- venv/Lib/site-packages/pip/_vendor/rich/live_render.py +0 -106
- venv/Lib/site-packages/pip/_vendor/rich/logging.py +0 -297
- venv/Lib/site-packages/pip/_vendor/rich/markup.py +0 -251
- venv/Lib/site-packages/pip/_vendor/rich/measure.py +0 -151
- venv/Lib/site-packages/pip/_vendor/rich/padding.py +0 -141
- venv/Lib/site-packages/pip/_vendor/rich/pager.py +0 -34
- venv/Lib/site-packages/pip/_vendor/rich/palette.py +0 -100
- venv/Lib/site-packages/pip/_vendor/rich/panel.py +0 -317
- venv/Lib/site-packages/pip/_vendor/rich/pretty.py +0 -1016
- venv/Lib/site-packages/pip/_vendor/rich/progress.py +0 -1715
- venv/Lib/site-packages/pip/_vendor/rich/progress_bar.py +0 -223
- venv/Lib/site-packages/pip/_vendor/rich/prompt.py +0 -400
- venv/Lib/site-packages/pip/_vendor/rich/protocol.py +0 -42
- venv/Lib/site-packages/pip/_vendor/rich/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/rich/region.py +0 -10
- venv/Lib/site-packages/pip/_vendor/rich/repr.py +0 -149
- venv/Lib/site-packages/pip/_vendor/rich/rule.py +0 -130
- venv/Lib/site-packages/pip/_vendor/rich/scope.py +0 -86
- venv/Lib/site-packages/pip/_vendor/rich/screen.py +0 -54
- venv/Lib/site-packages/pip/_vendor/rich/segment.py +0 -752
- venv/Lib/site-packages/pip/_vendor/rich/spinner.py +0 -132
- venv/Lib/site-packages/pip/_vendor/rich/status.py +0 -131
- venv/Lib/site-packages/pip/_vendor/rich/style.py +0 -796
- venv/Lib/site-packages/pip/_vendor/rich/styled.py +0 -42
- venv/Lib/site-packages/pip/_vendor/rich/syntax.py +0 -985
- venv/Lib/site-packages/pip/_vendor/rich/table.py +0 -1006
- venv/Lib/site-packages/pip/_vendor/rich/terminal_theme.py +0 -153
- venv/Lib/site-packages/pip/_vendor/rich/text.py +0 -1361
- venv/Lib/site-packages/pip/_vendor/rich/theme.py +0 -115
- venv/Lib/site-packages/pip/_vendor/rich/themes.py +0 -5
- venv/Lib/site-packages/pip/_vendor/rich/traceback.py +0 -899
- venv/Lib/site-packages/pip/_vendor/rich/tree.py +0 -257
- venv/Lib/site-packages/pip/_vendor/tomli/__init__.py +0 -8
- venv/Lib/site-packages/pip/_vendor/tomli/_parser.py +0 -770
- venv/Lib/site-packages/pip/_vendor/tomli/_re.py +0 -112
- venv/Lib/site-packages/pip/_vendor/tomli/_types.py +0 -10
- venv/Lib/site-packages/pip/_vendor/tomli/py.typed +0 -1
- venv/Lib/site-packages/pip/_vendor/tomli_w/__init__.py +0 -4
- venv/Lib/site-packages/pip/_vendor/tomli_w/_writer.py +0 -229
- venv/Lib/site-packages/pip/_vendor/tomli_w/py.typed +0 -1
- venv/Lib/site-packages/pip/_vendor/truststore/__init__.py +0 -36
- venv/Lib/site-packages/pip/_vendor/truststore/_api.py +0 -333
- venv/Lib/site-packages/pip/_vendor/truststore/_macos.py +0 -571
- venv/Lib/site-packages/pip/_vendor/truststore/_openssl.py +0 -66
- venv/Lib/site-packages/pip/_vendor/truststore/_ssl_constants.py +0 -31
- venv/Lib/site-packages/pip/_vendor/truststore/_windows.py +0 -567
- venv/Lib/site-packages/pip/_vendor/truststore/py.typed +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py +0 -102
- venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py +0 -355
- venv/Lib/site-packages/pip/_vendor/urllib3/_version.py +0 -2
- venv/Lib/site-packages/pip/_vendor/urllib3/connection.py +0 -572
- venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +0 -1140
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +0 -36
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +0 -519
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +0 -397
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py +0 -314
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +0 -130
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +0 -518
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +0 -920
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +0 -216
- venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +0 -323
- venv/Lib/site-packages/pip/_vendor/urllib3/fields.py +0 -274
- venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py +0 -98
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +0 -51
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py +0 -155
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py +0 -1076
- venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +0 -540
- venv/Lib/site-packages/pip/_vendor/urllib3/request.py +0 -191
- venv/Lib/site-packages/pip/_vendor/urllib3/response.py +0 -879
- venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py +0 -49
- venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py +0 -149
- venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py +0 -57
- venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py +0 -22
- venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py +0 -137
- venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py +0 -107
- venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +0 -622
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +0 -504
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +0 -159
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py +0 -221
- venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py +0 -271
- venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py +0 -435
- venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py +0 -152
- venv/Lib/site-packages/pip/py.typed +0 -4
- {cli_ih-0.6.3.1.dist-info → cli_ih-0.7.1.dist-info}/WHEEL +0 -0
cli_ih/__init__.py
CHANGED
cli_ih/asyncClient.py
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
from typing import Coroutine, Callable, Any
|
|
2
2
|
from .exceptions import HandlerClosed
|
|
3
|
-
import
|
|
3
|
+
from .utils import safe_print as print, register_handler
|
|
4
|
+
import logging, warnings, asyncio, inspect, threading, sys, shutil, msvcrt
|
|
4
5
|
|
|
5
6
|
class AsyncInputHandler:
|
|
6
|
-
def __init__(self, cursor = "", *, logger: logging.Logger | None = None, register_defaults: bool = True):
|
|
7
|
+
def __init__(self, cursor = "", thread_mode: bool = True, *, logger: logging.Logger | None = None, register_defaults: bool = True):
|
|
8
|
+
register_handler(self)
|
|
7
9
|
self.commands = {}
|
|
8
10
|
self.is_running = False
|
|
11
|
+
self.thread_mode = thread_mode
|
|
9
12
|
self.cursor = f"{cursor.strip()} " if cursor else ""
|
|
10
13
|
self.global_logger = logger if logger else None
|
|
11
14
|
self.logger = logger.getChild("InputHandler") if logger else None
|
|
12
15
|
self.register_defaults = register_defaults
|
|
16
|
+
self.print_lock = threading.Lock()
|
|
17
|
+
self.input_buffer = ""
|
|
18
|
+
self.processing_command = False
|
|
19
|
+
self.history = []
|
|
20
|
+
self.history_index = 0
|
|
21
|
+
|
|
13
22
|
if self.register_defaults:
|
|
14
23
|
self.register_default_commands()
|
|
15
24
|
else:
|
|
@@ -71,23 +80,105 @@ class AsyncInputHandler:
|
|
|
71
80
|
return func
|
|
72
81
|
return decorator
|
|
73
82
|
|
|
74
|
-
|
|
75
|
-
"""Starts the input handler loop in a
|
|
83
|
+
def start(self):
|
|
84
|
+
"""Starts the input handler loop. Runs in a thread if thread_mode is True, otherwise blocks."""
|
|
76
85
|
self.is_running = True
|
|
86
|
+
if self.thread_mode:
|
|
87
|
+
thread = threading.Thread(target=self._start_thread, daemon=True)
|
|
88
|
+
thread.start()
|
|
89
|
+
else:
|
|
90
|
+
self._start_thread()
|
|
91
|
+
|
|
92
|
+
def _start_thread(self):
|
|
93
|
+
asyncio.run(self._run())
|
|
94
|
+
|
|
95
|
+
async def _run(self):
|
|
96
|
+
"""Starts the input handler loop in a separate thread if thread mode is enabled."""
|
|
77
97
|
loop = asyncio.get_running_loop()
|
|
78
98
|
input_queue = asyncio.Queue()
|
|
79
99
|
|
|
80
100
|
def _input_worker():
|
|
101
|
+
# Initial prompt
|
|
102
|
+
with self.print_lock:
|
|
103
|
+
sys.stdout.write(self.cursor)
|
|
104
|
+
sys.stdout.flush()
|
|
105
|
+
|
|
81
106
|
while self.is_running:
|
|
82
107
|
try:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
108
|
+
if msvcrt.kbhit():
|
|
109
|
+
char = msvcrt.getwch()
|
|
110
|
+
|
|
111
|
+
if char == '\xe0' or char == '\x00': # Special keys (Arrows, etc)
|
|
112
|
+
try:
|
|
113
|
+
scancode = msvcrt.getwch()
|
|
114
|
+
if scancode == 'H': # Up Arrow
|
|
115
|
+
if self.history_index > 0:
|
|
116
|
+
self.history_index -= 1
|
|
117
|
+
self.input_buffer = self.history[self.history_index]
|
|
118
|
+
with self.print_lock:
|
|
119
|
+
sys.stdout.write('\r' + ' ' * (shutil.get_terminal_size().columns - 1) + '\r')
|
|
120
|
+
sys.stdout.write(self.cursor + self.input_buffer)
|
|
121
|
+
sys.stdout.flush()
|
|
122
|
+
|
|
123
|
+
elif scancode == 'P': # Down Arrow
|
|
124
|
+
if self.history_index < len(self.history):
|
|
125
|
+
self.history_index += 1
|
|
126
|
+
|
|
127
|
+
if self.history_index == len(self.history):
|
|
128
|
+
self.input_buffer = ""
|
|
129
|
+
else:
|
|
130
|
+
self.input_buffer = self.history[self.history_index]
|
|
131
|
+
|
|
132
|
+
with self.print_lock:
|
|
133
|
+
sys.stdout.write('\r' + ' ' * (shutil.get_terminal_size().columns - 1) + '\r')
|
|
134
|
+
sys.stdout.write(self.cursor + self.input_buffer)
|
|
135
|
+
sys.stdout.flush()
|
|
136
|
+
except Exception:
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
elif char == '\r': # Enter
|
|
140
|
+
with self.print_lock:
|
|
141
|
+
sys.stdout.write('\n')
|
|
142
|
+
sys.stdout.flush()
|
|
143
|
+
text = self.input_buffer
|
|
144
|
+
self.input_buffer = ""
|
|
145
|
+
|
|
146
|
+
if text:
|
|
147
|
+
if not self.history or self.history[-1] != text:
|
|
148
|
+
self.history.append(text)
|
|
149
|
+
self.history_index = len(self.history)
|
|
150
|
+
|
|
151
|
+
loop.call_soon_threadsafe(input_queue.put_nowait, text)
|
|
152
|
+
|
|
153
|
+
elif char == '\x08': # Backspace
|
|
154
|
+
if len(self.input_buffer) > 0:
|
|
155
|
+
self.input_buffer = self.input_buffer[:-1]
|
|
156
|
+
with self.print_lock:
|
|
157
|
+
sys.stdout.write('\b \b')
|
|
158
|
+
sys.stdout.flush()
|
|
159
|
+
|
|
160
|
+
elif char == '\x03': # Ctrl+C
|
|
161
|
+
loop.call_soon_threadsafe(input_queue.put_nowait, KeyboardInterrupt)
|
|
162
|
+
break
|
|
163
|
+
|
|
164
|
+
else:
|
|
165
|
+
# Verify printable
|
|
166
|
+
if char.isprintable():
|
|
167
|
+
self.input_buffer += char
|
|
168
|
+
with self.print_lock:
|
|
169
|
+
sys.stdout.write(char)
|
|
170
|
+
sys.stdout.flush()
|
|
171
|
+
else:
|
|
172
|
+
pass
|
|
173
|
+
# Small sleep to prevent high CPU usage,
|
|
174
|
+
# but we are in a dedicated thread so it's fine-ish,
|
|
175
|
+
# actually explicit sleep is good.
|
|
176
|
+
import time
|
|
177
|
+
time.sleep(0.01)
|
|
178
|
+
|
|
88
179
|
except Exception:
|
|
89
180
|
break
|
|
90
|
-
|
|
181
|
+
|
|
91
182
|
thread = threading.Thread(target=_input_worker, daemon=True)
|
|
92
183
|
thread.start()
|
|
93
184
|
|
|
@@ -152,6 +243,7 @@ class AsyncInputHandler:
|
|
|
152
243
|
if not user_input:
|
|
153
244
|
continue
|
|
154
245
|
|
|
246
|
+
self.processing_command = True
|
|
155
247
|
cmdargs = user_input.split(' ')
|
|
156
248
|
command_name = cmdargs[0].lower()
|
|
157
249
|
args = cmdargs[1:]
|
|
@@ -159,6 +251,13 @@ class AsyncInputHandler:
|
|
|
159
251
|
await _run_command(self.commands, command_name, args)
|
|
160
252
|
else:
|
|
161
253
|
self.__warning(f"Unknown command: '{command_name}'")
|
|
254
|
+
self.processing_command = False
|
|
255
|
+
|
|
256
|
+
# Reprompt after command execution
|
|
257
|
+
with self.print_lock:
|
|
258
|
+
sys.stdout.write(self.cursor)
|
|
259
|
+
sys.stdout.flush()
|
|
260
|
+
|
|
162
261
|
except EOFError:
|
|
163
262
|
self.__error("Input ended unexpectedly.")
|
|
164
263
|
break
|
cli_ih/client.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from typing import Callable
|
|
2
2
|
from .exceptions import HandlerClosed
|
|
3
|
-
import
|
|
3
|
+
from .utils import safe_print as print, register_handler
|
|
4
|
+
import logging, warnings, sys, shutil, threading, msvcrt
|
|
4
5
|
|
|
5
6
|
class InputHandler:
|
|
6
7
|
def __init__(self, thread_mode = True, cursor = "", *, logger: logging.Logger | None = None, register_defaults: bool = True):
|
|
8
|
+
register_handler(self)
|
|
7
9
|
self.commands = {}
|
|
8
10
|
self.is_running = False
|
|
9
11
|
self.thread_mode = thread_mode
|
|
@@ -12,6 +14,12 @@ class InputHandler:
|
|
|
12
14
|
self.global_logger = logger if logger else None
|
|
13
15
|
self.logger = logger.getChild("InputHandler") if logger else None
|
|
14
16
|
self.register_defaults = register_defaults
|
|
17
|
+
self.print_lock = threading.Lock()
|
|
18
|
+
self.input_buffer = ""
|
|
19
|
+
self.processing_command = False
|
|
20
|
+
self.history = []
|
|
21
|
+
self.history_index = 0
|
|
22
|
+
|
|
15
23
|
if self.register_defaults:
|
|
16
24
|
self.register_default_commands()
|
|
17
25
|
else:
|
|
@@ -130,26 +138,110 @@ class InputHandler:
|
|
|
130
138
|
"""Continuously listens for user input and processes commands."""
|
|
131
139
|
while self.is_running:
|
|
132
140
|
try:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
141
|
+
# Initial prompt
|
|
142
|
+
with self.print_lock:
|
|
143
|
+
sys.stdout.write(self.cursor)
|
|
144
|
+
sys.stdout.flush()
|
|
145
|
+
|
|
146
|
+
while self.is_running:
|
|
147
|
+
if msvcrt.kbhit():
|
|
148
|
+
char = msvcrt.getwch()
|
|
149
|
+
|
|
150
|
+
if char == '\xe0' or char == '\x00': # Special keys (Arrows, etc)
|
|
151
|
+
try:
|
|
152
|
+
scancode = msvcrt.getwch()
|
|
153
|
+
if scancode == 'H': # Up Arrow
|
|
154
|
+
if self.history_index > 0:
|
|
155
|
+
self.history_index -= 1
|
|
156
|
+
self.input_buffer = self.history[self.history_index]
|
|
157
|
+
with self.print_lock:
|
|
158
|
+
# Clear current line visually
|
|
159
|
+
# We don't have columns info here easily, but safe_print logic uses clearing.
|
|
160
|
+
# Let's try to just use \r and spaces? No, let's just use \r and overwrite.
|
|
161
|
+
# To properly clear, we need to know the length of what was there.
|
|
162
|
+
# A reuse of _safe_print logic might be good but avoiding circularity.
|
|
163
|
+
# Simple clear strategy: \r, print many spaces, \r, print prompt + buffer
|
|
164
|
+
# Or better: \r + prompt + buffer + spaces to clear rest?
|
|
165
|
+
|
|
166
|
+
# We'll use a crude clear for now or simple overwrite if shorter?
|
|
167
|
+
# Best to clear the line.
|
|
168
|
+
sys.stdout.write('\r' + ' ' * (shutil.get_terminal_size().columns - 1) + '\r')
|
|
169
|
+
sys.stdout.write(self.cursor + self.input_buffer)
|
|
170
|
+
sys.stdout.flush()
|
|
171
|
+
|
|
172
|
+
elif scancode == 'P': # Down Arrow
|
|
173
|
+
if self.history_index < len(self.history):
|
|
174
|
+
self.history_index += 1
|
|
175
|
+
|
|
176
|
+
if self.history_index == len(self.history):
|
|
177
|
+
self.input_buffer = ""
|
|
178
|
+
else:
|
|
179
|
+
self.input_buffer = self.history[self.history_index]
|
|
180
|
+
|
|
181
|
+
with self.print_lock:
|
|
182
|
+
sys.stdout.write('\r' + ' ' * (shutil.get_terminal_size().columns - 1) + '\r')
|
|
183
|
+
sys.stdout.write(self.cursor + self.input_buffer)
|
|
184
|
+
sys.stdout.flush()
|
|
185
|
+
except Exception:
|
|
186
|
+
pass
|
|
187
|
+
|
|
188
|
+
elif char == '\r': # Enter
|
|
189
|
+
with self.print_lock:
|
|
190
|
+
sys.stdout.write('\n')
|
|
191
|
+
sys.stdout.flush()
|
|
192
|
+
text = self.input_buffer
|
|
193
|
+
self.input_buffer = ""
|
|
194
|
+
|
|
195
|
+
if text:
|
|
196
|
+
# Add to history if unique or last one different?
|
|
197
|
+
# Usually standard behavior: always add, or add if different from last.
|
|
198
|
+
# Let's add if not empty.
|
|
199
|
+
if not self.history or self.history[-1] != text:
|
|
200
|
+
self.history.append(text)
|
|
201
|
+
self.history_index = len(self.history)
|
|
202
|
+
|
|
203
|
+
self.processing_command = True
|
|
204
|
+
cmdargs = text.split(' ')
|
|
205
|
+
command_name = cmdargs[0].lower()
|
|
206
|
+
args = cmdargs[1:]
|
|
207
|
+
if command_name in self.commands:
|
|
208
|
+
_run_command(self.commands, command_name, args)
|
|
209
|
+
else:
|
|
210
|
+
self.__warning(f"Unknown command: '{command_name}'")
|
|
211
|
+
self.processing_command = False
|
|
212
|
+
|
|
213
|
+
# Break inner loop to reprompt
|
|
214
|
+
break
|
|
215
|
+
|
|
216
|
+
elif char == '\x08': # Backspace
|
|
217
|
+
if len(self.input_buffer) > 0:
|
|
218
|
+
self.input_buffer = self.input_buffer[:-1]
|
|
219
|
+
with self.print_lock:
|
|
220
|
+
sys.stdout.write('\b \b')
|
|
221
|
+
sys.stdout.flush()
|
|
222
|
+
|
|
223
|
+
elif char == '\x03': # Ctrl+C
|
|
224
|
+
self.__error("Input interrupted.")
|
|
225
|
+
self.is_running = False
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
else:
|
|
229
|
+
# Verify printable
|
|
230
|
+
if char.isprintable():
|
|
231
|
+
self.input_buffer += char
|
|
232
|
+
with self.print_lock:
|
|
233
|
+
sys.stdout.write(char)
|
|
234
|
+
sys.stdout.flush()
|
|
235
|
+
else:
|
|
236
|
+
import time
|
|
237
|
+
time.sleep(0.01)
|
|
238
|
+
|
|
150
239
|
except HandlerClosed:
|
|
151
240
|
self.__info("Input Handler exited.")
|
|
152
241
|
break
|
|
242
|
+
except Exception as e:
|
|
243
|
+
self.__exeption("Input loop error", e)
|
|
244
|
+
break
|
|
153
245
|
self.is_running = False
|
|
154
246
|
if self.thread_mode:
|
|
155
247
|
self.thread = threading.Thread(target=_thread, daemon=True)
|
cli_ih/utils.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
_HANDLER = None
|
|
5
|
+
|
|
6
|
+
def register_handler(handler):
|
|
7
|
+
global _HANDLER
|
|
8
|
+
_HANDLER = handler
|
|
9
|
+
|
|
10
|
+
def safe_print(msg: str, cursor: str | None = None, input_buffer: str | None = None):
|
|
11
|
+
"""
|
|
12
|
+
Prints a message safely while preserving the current input buffer and cursor.
|
|
13
|
+
This ensures logs appear above the input line appropriately.
|
|
14
|
+
"""
|
|
15
|
+
if cursor is None and input_buffer is None and _HANDLER is not None:
|
|
16
|
+
lock = None
|
|
17
|
+
try:
|
|
18
|
+
# Try to acquire lock if available to prevent race conditions
|
|
19
|
+
lock = getattr(_HANDLER, "print_lock", None)
|
|
20
|
+
if lock:
|
|
21
|
+
lock.acquire()
|
|
22
|
+
|
|
23
|
+
cursor = str(getattr(_HANDLER, "cursor", ""))
|
|
24
|
+
input_buffer = str(getattr(_HANDLER, "input_buffer", ""))
|
|
25
|
+
processing_command = getattr(_HANDLER, "processing_command", False)
|
|
26
|
+
|
|
27
|
+
if processing_command:
|
|
28
|
+
cursor = ""
|
|
29
|
+
input_buffer = ""
|
|
30
|
+
|
|
31
|
+
_do_safe_print(msg, cursor, input_buffer)
|
|
32
|
+
finally:
|
|
33
|
+
if lock:
|
|
34
|
+
lock.release()
|
|
35
|
+
else:
|
|
36
|
+
# Fallback or explicit arguments
|
|
37
|
+
_do_safe_print(msg, cursor or "", input_buffer or "")
|
|
38
|
+
|
|
39
|
+
def _do_safe_print(msg: str, cursor: str, input_buffer: str):
|
|
40
|
+
try:
|
|
41
|
+
columns = shutil.get_terminal_size().columns
|
|
42
|
+
except:
|
|
43
|
+
columns = 80
|
|
44
|
+
|
|
45
|
+
# Clear line
|
|
46
|
+
sys.stdout.write('\r' + ' ' * (columns - 1) + '\r')
|
|
47
|
+
# Print message
|
|
48
|
+
sys.stdout.write(f"{msg}\n")
|
|
49
|
+
# Reprint cursor and buffer
|
|
50
|
+
sys.stdout.write(f"{cursor}{input_buffer}")
|
|
51
|
+
sys.stdout.flush()
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cli_ih
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: A background command handler for python's command-line interface.
|
|
5
|
+
Author-email: Hotment <michatchuplay@gmail.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# InputHandler Library
|
|
10
|
+
|
|
11
|
+
A lightweight Python library for creating interactive command-line interfaces with custom command registration, input handling, and clean log output. It supports synchronous and asynchronous modes, threaded input processing, and enhanced logging.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Command Registration**: Register commands with decorators and descriptions.
|
|
16
|
+
- **Threaded Input**: Non-blocking input handling by default.
|
|
17
|
+
- **Safe Printing**: Logs appear above the input line, preserving your typed text and cursor position.
|
|
18
|
+
- **Command History**: Navigate recent commands with Up/Down arrow keys.
|
|
19
|
+
- **Sync & Async**: Support for both synchronous and asynchronous (asyncio) applications.
|
|
20
|
+
- **Colored Logging**: Built-in support for colored log messages.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
`pip install cli_ih`
|
|
25
|
+
|
|
26
|
+
## Quick Start (Synchronous)
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from cli_ih import InputHandler, safe_print
|
|
30
|
+
|
|
31
|
+
handler = InputHandler(cursor="> ")
|
|
32
|
+
|
|
33
|
+
# Use safe_print instead of print to keep the input line clean!
|
|
34
|
+
@handler.command(name="greet", description="Greets the user.")
|
|
35
|
+
def greet(name):
|
|
36
|
+
safe_print(f"Hello, {name}!")
|
|
37
|
+
|
|
38
|
+
@handler.command(name="add", description="Adds two numbers.")
|
|
39
|
+
def add(a, b):
|
|
40
|
+
safe_print(int(a) + int(b))
|
|
41
|
+
|
|
42
|
+
handler.start()
|
|
43
|
+
|
|
44
|
+
# Using safe_print allows you to print logs in the background
|
|
45
|
+
# without messing up the user's current input line.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Async Client Example
|
|
49
|
+
|
|
50
|
+
The `AsyncInputHandler` integrates with `asyncio`. The `start()` method is non-blocking when `thread_mode=True` (default).
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import asyncio
|
|
54
|
+
from cli_ih import AsyncInputHandler, safe_print
|
|
55
|
+
|
|
56
|
+
handler = AsyncInputHandler(cursor="Async> ")
|
|
57
|
+
|
|
58
|
+
@handler.command(name="greet", description="Greets the user asynchronously.")
|
|
59
|
+
async def greet(name):
|
|
60
|
+
await asyncio.sleep(1)
|
|
61
|
+
safe_print(f"Hello, {name}")
|
|
62
|
+
|
|
63
|
+
@handler.command(name="add", description="Adds two numbers.")
|
|
64
|
+
async def add(a, b):
|
|
65
|
+
safe_print(int(a) + int(b))
|
|
66
|
+
|
|
67
|
+
# Start the handler (runs in a separate thread by default)
|
|
68
|
+
handler.start()
|
|
69
|
+
|
|
70
|
+
# Keep the main thread alive or run your main event loop
|
|
71
|
+
async def main():
|
|
72
|
+
while handler.is_running:
|
|
73
|
+
await asyncio.sleep(1)
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
asyncio.run(main())
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Key Considerations
|
|
80
|
+
|
|
81
|
+
### Safe Printing
|
|
82
|
+
Always use `from cli_ih import safe_print` for outputting text to the console. This utility automatically detects the active input handler and ensures that your log message is printed *above* the current input line, preserving the user's cursor and any text they are currently typing.
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from cli_ih import safe_print
|
|
86
|
+
|
|
87
|
+
# Good
|
|
88
|
+
safe_print("Log message")
|
|
89
|
+
|
|
90
|
+
# Avoid (might disrupt input line)
|
|
91
|
+
print("Log message")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Thread Mode
|
|
95
|
+
Both `InputHandler` and `AsyncInputHandler` accept a `thread_mode` parameter (default `True`).
|
|
96
|
+
- `thread_mode=True`: The input loop runs in a separate thread. `start()` returns immediately.
|
|
97
|
+
- `thread_mode=False`: The input loop runs in the current thread. `start()` blocks until exit.
|
|
98
|
+
|
|
99
|
+
### Command History
|
|
100
|
+
Use the **Up** and **Down** arrow keys to cycle through your previously entered commands, just like in a standard terminal.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
cli_ih/__init__.py,sha256=wCwv9grczxpu7EXqunCdFgAWlx3XEZVw4O4U3fs45PY,278
|
|
2
|
+
cli_ih/asyncClient.py,sha256=v7JaKi50xCEiqFUHlxhf83EoXzAwQ-r8VCjdlYz3q4c,13399
|
|
3
|
+
cli_ih/client.py,sha256=EKgVCfC-O-Xxdxb7ZqG6DgYvti37wtpjthYns6ghssA,14158
|
|
4
|
+
cli_ih/exceptions.py,sha256=0xqaMCVu-yEURIrB6wEhbf6kfdsRmODJBoDsQTOp29s,156
|
|
5
|
+
cli_ih/utils.py,sha256=HstJPjjlTfVKz68sHU_whSBsOoBKhxizCcycNyQeK2k,1685
|
|
6
|
+
cli_ih-0.7.1.dist-info/METADATA,sha256=rd-ysIOjWIYi8SgIGLbf8TGogLorPQziQCmOej_xQaA,3411
|
|
7
|
+
cli_ih-0.7.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
cli_ih-0.7.1.dist-info/top_level.txt,sha256=Ve1CRLNXhPyPSkpN0xLu26roh30LQCpNzkF61BZYfk0,7
|
|
9
|
+
cli_ih-0.7.1.dist-info/RECORD,,
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: cli_ih
|
|
3
|
-
Version: 0.6.3.1
|
|
4
|
-
Summary: A background command handler for python's command-line interface.
|
|
5
|
-
Author-email: Hotment <michatchuplay@gmail.com>
|
|
6
|
-
Requires-Python: >=3.8
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
|
|
9
|
-
# InputHandler Library
|
|
10
|
-
|
|
11
|
-
A lightweight Python library for creating interactive command-line interfaces with custom command registration and input handling. It supports threaded input processing and includes enhanced logging with color-coded output.
|
|
12
|
-
|
|
13
|
-
## Features
|
|
14
|
-
|
|
15
|
-
- Command registration system with descriptions
|
|
16
|
-
- Threaded or non-threaded input handling
|
|
17
|
-
- Colored logging with support for debug mode
|
|
18
|
-
- Built-in `help`, `debug`, and `exit` commands
|
|
19
|
-
- Error handling for missing or invalid command arguments
|
|
20
|
-
- NEW: Register commands with decorators
|
|
21
|
-
|
|
22
|
-
## Installation
|
|
23
|
-
|
|
24
|
-
`pip install cli_ih`
|
|
25
|
-
|
|
26
|
-
## Quick Start
|
|
27
|
-
|
|
28
|
-
```python
|
|
29
|
-
from cli_ih import InputHandler
|
|
30
|
-
|
|
31
|
-
def greet(args):
|
|
32
|
-
print(f"Hello, {' '.join(args)}!")
|
|
33
|
-
|
|
34
|
-
handler = InputHandler(cursor="> ")
|
|
35
|
-
# NEW
|
|
36
|
-
@handler.command(name="add", description="Performs the `+` operator on the first 2 arguments.") # The name param will use the func name if its not provided
|
|
37
|
-
def add(args):
|
|
38
|
-
print(int(args[0])+int(args[1]))
|
|
39
|
-
|
|
40
|
-
handler.register_command("greet", greet, "Greets the user. Usage: greet [name]")
|
|
41
|
-
handler.start()
|
|
42
|
-
|
|
43
|
-
# Now type commands like:
|
|
44
|
-
# > greet world
|
|
45
|
-
# Hello, world!
|
|
46
|
-
# > add 1 2
|
|
47
|
-
# 3
|
|
48
|
-
# > help
|
|
49
|
-
# Available commands:
|
|
50
|
-
# help: Displays all the available commands
|
|
51
|
-
# debug: If a logger is present changes the logging level to DEBUG.
|
|
52
|
-
# exit: Exits the Input Handler irreversibly.
|
|
53
|
-
# add: Performs the `+` operator on the first 2 arguments.
|
|
54
|
-
# greet: Greets the user. Usage: greet [name]
|
|
55
|
-
#
|
|
56
|
-
# > debug
|
|
57
|
-
# > exit
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## New Async client
|
|
61
|
-
```python
|
|
62
|
-
import asyncio
|
|
63
|
-
from cli_ih import AsyncInputHandler
|
|
64
|
-
|
|
65
|
-
print(cli_ih.__version__)
|
|
66
|
-
|
|
67
|
-
handler = AsyncInputHandler(cursor="> ")
|
|
68
|
-
|
|
69
|
-
@handler.command(name="greet", description="Greets the user. Usage: greet [name]")
|
|
70
|
-
async def greet(name, *args):
|
|
71
|
-
await asyncio.sleep(1)
|
|
72
|
-
print(f"Hello, {name}{" " if args else ""}{' '.join(args)}!")
|
|
73
|
-
# NEW
|
|
74
|
-
@handler.command(name="add", description="Performs the `+` operator on the first 2 arguments.")
|
|
75
|
-
async def add(a, b):
|
|
76
|
-
print(a+b)
|
|
77
|
-
|
|
78
|
-
asyncio.run(handler.start())
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Additional Info
|
|
82
|
-
|
|
83
|
-
- You can provide a valid logger `logger=logger` to the `InputHandler` to enable logging (this will be removed soon)
|
|
84
|
-
- You can provide the `thread_mode` param to the `InputHandler` class to set if it shoud run in a thread or no.
|
|
85
|
-
(If you are using the `cli-ih` module on its own without any other background task set `thread_mode=False` to false)
|
|
86
|
-
- You can also provide a `cursor` param to the `InputHandler` class to set the cli cursor (default cusor is empty)
|