diff --git a/knowledge base/python.md b/knowledge base/python.md index 19a326d..45133d0 100644 --- a/knowledge base/python.md +++ b/knowledge base/python.md @@ -1,13 +1,16 @@ # Python 1. [TL,DR](#tldr) -2. [Dictionaries](#dictionaries) -3. [F-strings](#f-strings) -4. [Web servers](#web-servers) +1. [Dictionaries](#dictionaries) +1. [F-strings](#f-strings) +1. [Logging](#logging) +1. [Web servers](#web-servers) 1. [Flask](#flask) - 2. [WSGI server](#wsgi-server) -5. [Further readings](#further-readings) -6. [Sources](#sources) + 1. [WSGI server](#wsgi-server) +1. [Execute commands on the host](#execute-commands-on-the-host) +1. [Concurrent execution](#concurrent-execution) +1. [Further readings](#further-readings) +1. [Sources](#sources) ## TL,DR @@ -72,6 +75,25 @@ f"Hello, {name}. You are {age}." F"{name.lower()} is funny." ``` +## Logging + +Very basic logger: + +```py +import logging +logging.basicConfig(level=logging.WARNING) + +logging.critical("CRITICAL level message") +logging.exception("ERROR level message") +logging.error("ERROR level message") +logging.warning("WARNING level message") +logging.info("INFO level message") +logging.debug("DEBUG level message") +logging.log(level, "{level} level message") +``` + +See [logging howto] and [logging library] for more information. + ## Web servers ### Flask @@ -128,6 +150,33 @@ pip install flask waitress python hello.py ``` +## Execute commands on the host + +Very basic execution: + +```py +import subprocess +subprocess.call(command) +``` + +See [subprocess library] for more information. + +## Concurrent execution + +Very basic multi-threaded operations: + +```py +from concurrent.futures import ThreadPoolExecutor +from os import cpu_count + +with ThreadPoolExecutor(max_workers=cpu_count()) as executor: + for element in elements: + logging.debug(f"submitting thread for {element}") + executor.submit(function_name, function_arg_1, function_arg_n) +``` + +See [concurrent execution] for more information. + ## Further readings - [Dictionaries] @@ -137,21 +186,27 @@ python hello.py - [Data types] - [F-strings] - [How to filter list elements in Python] -- [Logging] +- [Logging howto] - [Flask at first run: do not use the development server in a production environment] - [Flask example with POST] - [Multi-value query parameters with Flask] - [*args and **kwargs in Python] - [An intro to threading in Python] - [ThreadPoolExecutor in Python: the complete guide] +- [Concurrent execution] ## Sources - [10 python one-liners for dictionaries] +- [Logging library] +- [Subprocess library] +[concurrent execution]: https://docs.python.org/3/library/concurrency.html [dictionaries]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries -[logging]: https://docs.python.org/3/howto/logging.html +[logging howto]: https://docs.python.org/3/howto/logging.html +[logging library]: https://docs.python.org/3/library/logging.html +[subprocess library]: https://docs.python.org/3/library/subprocess.html [pip]: ./pip.md diff --git a/scripts/git-all.py b/scripts/git-all.py index 1196f02..aebb3a6 100755 --- a/scripts/git-all.py +++ b/scripts/git-all.py @@ -1,6 +1,10 @@ #!/usr/bin/env python3 -# /usr/bin/env python3 -m pip install --user gitpython +# Easy, quick & dirty solution to act upon multiple git repositories at once. + +# TODO: +# - proper commands +# - use 'gitpython' instead of calling `git` import logging import subprocess @@ -10,10 +14,13 @@ from os import cpu_count, getcwd, walk from os.path import basename, dirname, isdir from sys import argv -log_level = logging.DEBUG +dry_run = False +log_level = logging.WARNING root_directory = getcwd() threads_count = cpu_count() +logging.basicConfig(level=log_level) + def git_command(directory, *args): logging.debug(f"thread for {directory}") logging.debug(f"using args {args}") @@ -26,13 +33,20 @@ def git_command(directory, *args): command.extend(args) logging.debug(command) - subprocess.call(command) + if dry_run is False: + subprocess.call(command) if __name__ == "__main__": - if argv[1] == "--debug": - logging.basicConfig(level=log_level) + if "--debug" in argv: + logging.basicConfig(level=logging.DEBUG, force=True) + logging.warning("debug mode") argv.remove("--debug") + if "--dry-run" in argv: + dry_run = True + logging.warning("dry-run mode") + argv.remove("--dry-run") + logging.debug(f"using globals {globals()}") logging.debug(f"using locals {locals()}") @@ -41,7 +55,9 @@ if __name__ == "__main__": if isdir(argv[-1]): root_directory = argv[-1] git_args = argv[1:-1] - else: git_args = argv[1:] + else: + git_args = argv[1:] + logging.debug(f"starting from {root_directory}") logging.debug(f"using git args {git_args}") @@ -51,4 +67,5 @@ if __name__ == "__main__": logging.debug(f"creating threads") with ThreadPoolExecutor(max_workers=threads_count) as executor: for repository in repositories: + logging.debug(f"submitting thread for {repository}") executor.submit(git_command, repository, *git_args)