python-base-command 0.1.4__tar.gz → 0.1.5__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.
Files changed (42) hide show
  1. {python_base_command-0.1.4 → python_base_command-0.1.5}/PKG-INFO +20 -1
  2. {python_base_command-0.1.4 → python_base_command-0.1.5}/README.md +19 -0
  3. {python_base_command-0.1.4 → python_base_command-0.1.5}/pyproject.toml +1 -1
  4. {python_base_command-0.1.4 → python_base_command-0.1.5}/python_base_command/__init__.py +0 -7
  5. {python_base_command-0.1.4 → python_base_command-0.1.5}/python_base_command/base.py +17 -2
  6. {python_base_command-0.1.4 → python_base_command-0.1.5}/usage_example/commands/registry_cmd.py +6 -0
  7. {python_base_command-0.1.4 → python_base_command-0.1.5}/.config/README.md +0 -0
  8. {python_base_command-0.1.4 → python_base_command-0.1.5}/.config/black.toml +0 -0
  9. {python_base_command-0.1.4 → python_base_command-0.1.5}/.config/pylintrc +0 -0
  10. {python_base_command-0.1.4 → python_base_command-0.1.5}/.config/pylintrc_tests +0 -0
  11. {python_base_command-0.1.4 → python_base_command-0.1.5}/.config/ruff.toml +0 -0
  12. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/CODEOWNERS +0 -0
  13. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  14. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/chat-titles.md +0 -0
  15. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/claude-sonnet-4.md +0 -0
  16. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/gemini-2.5-pro.md +0 -0
  17. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/gpt-4.1.md +0 -0
  18. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/gpt-4o.md +0 -0
  19. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/gpt-5-mini.md +0 -0
  20. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/gpt-5.md +0 -0
  21. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/nes-tab-completion.md +0 -0
  22. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/instructions/IDE Agent/prompt.md +0 -0
  23. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/pull_request_template.md +0 -0
  24. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/workflows/lint.yml +0 -0
  25. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/workflows/publish_to_pypi.yml +0 -0
  26. {python_base_command-0.1.4 → python_base_command-0.1.5}/.github/workflows/tests.yml +0 -0
  27. {python_base_command-0.1.4 → python_base_command-0.1.5}/.gitignore +0 -0
  28. {python_base_command-0.1.4 → python_base_command-0.1.5}/.pre-commit-config.yaml +0 -0
  29. {python_base_command-0.1.4 → python_base_command-0.1.5}/CHANGELOG.md +0 -0
  30. {python_base_command-0.1.4 → python_base_command-0.1.5}/LICENSE +0 -0
  31. {python_base_command-0.1.4 → python_base_command-0.1.5}/MANIFEST.in +0 -0
  32. {python_base_command-0.1.4 → python_base_command-0.1.5}/Taskfile.yml +0 -0
  33. {python_base_command-0.1.4 → python_base_command-0.1.5}/cli.py +0 -0
  34. {python_base_command-0.1.4 → python_base_command-0.1.5}/pytest.ini +0 -0
  35. {python_base_command-0.1.4 → python_base_command-0.1.5}/python_base_command/registry.py +0 -0
  36. {python_base_command-0.1.4 → python_base_command-0.1.5}/python_base_command/runner.py +0 -0
  37. {python_base_command-0.1.4 → python_base_command-0.1.5}/python_base_command/utils.py +0 -0
  38. {python_base_command-0.1.4 → python_base_command-0.1.5}/tests/__init__.py +0 -0
  39. {python_base_command-0.1.4 → python_base_command-0.1.5}/tests/test_base_command.py +0 -0
  40. {python_base_command-0.1.4 → python_base_command-0.1.5}/usage_example/__init__.py +0 -0
  41. {python_base_command-0.1.4 → python_base_command-0.1.5}/usage_example/commands/__init__.py +0 -0
  42. {python_base_command-0.1.4 → python_base_command-0.1.5}/usage_example/commands/greet.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-base-command
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Django-style BaseCommand framework for standalone Python CLI tools
5
5
  Project-URL: Homepage, https://github.com/aviz92/python-base-command
6
6
  Project-URL: Repository, https://github.com/aviz92/python-base-command
@@ -107,6 +107,25 @@ class Command(BaseCommand):
107
107
  self.logger.info(msg)
108
108
  ```
109
109
 
110
+ ```python
111
+ # commands/greet.py
112
+ from python_base_command import BaseCommand, CommandError
113
+
114
+
115
+ class Command(BaseCommand):
116
+ help = "Greet a user by name"
117
+
118
+ def __init__(self) -> None:
119
+ super().__init__()
120
+ self.set_project_version("python-base-command")
121
+
122
+ def add_arguments(self, parser):
123
+ pass
124
+
125
+ def handle(self, **kwargs):
126
+ pass
127
+ ```
128
+
110
129
  Run from anywhere inside the project:
111
130
 
112
131
  ```bash
@@ -84,6 +84,25 @@ class Command(BaseCommand):
84
84
  self.logger.info(msg)
85
85
  ```
86
86
 
87
+ ```python
88
+ # commands/greet.py
89
+ from python_base_command import BaseCommand, CommandError
90
+
91
+
92
+ class Command(BaseCommand):
93
+ help = "Greet a user by name"
94
+
95
+ def __init__(self) -> None:
96
+ super().__init__()
97
+ self.set_project_version("python-base-command")
98
+
99
+ def add_arguments(self, parser):
100
+ pass
101
+
102
+ def handle(self, **kwargs):
103
+ pass
104
+ ```
105
+
87
106
  Run from anywhere inside the project:
88
107
 
89
108
  ```bash
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-base-command"
7
- version = "0.1.4"
7
+ version = "0.1.5"
8
8
  description = "Django-style BaseCommand framework for standalone Python CLI tools"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -15,8 +15,6 @@ Public API
15
15
  - call_command — programmatic command invocation
16
16
  """
17
17
 
18
- from custom_python_logger import build_logger
19
-
20
18
  from .base import (
21
19
  BaseCommand,
22
20
  CommandError,
@@ -36,8 +34,3 @@ __all__ = [
36
34
  "Runner",
37
35
  "call_command",
38
36
  ]
39
-
40
- build_logger(
41
- project_name="python-base-command",
42
- log_format="%(asctime)s | %(levelname)s | %(message)s",
43
- )
@@ -10,9 +10,10 @@ import os
10
10
  import sys
11
11
  from argparse import Action, ArgumentParser, HelpFormatter
12
12
  from collections.abc import Sequence
13
+ from importlib.metadata import version
13
14
  from typing import Any, TextIO
14
15
 
15
- from custom_python_logger import CustomLoggerAdapter, get_logger
16
+ from custom_python_logger import CustomLoggerAdapter, build_logger, get_logger
16
17
 
17
18
  __all__ = [
18
19
  "BaseCommand",
@@ -21,6 +22,7 @@ __all__ = [
21
22
  "LabelCommand",
22
23
  ]
23
24
 
25
+ from python_base_toolkit.utils.path_utils import get_project_path_by_file
24
26
 
25
27
  # ---------------------------------------------------------------------------
26
28
  # Exceptions
@@ -171,9 +173,23 @@ class BaseCommand:
171
173
  ) -> None:
172
174
  _ = stdout, stderr # API compatibility with call_command(stdout=..., stderr=...)
173
175
  self.logger: CustomLoggerAdapter = get_logger(name=self.__class__.__module__.split(".", maxsplit=1)[0])
176
+ build_logger(
177
+ project_name=self.__class__.__name__,
178
+ log_format="%(asctime)s | %(levelname)s | %(message)s",
179
+ log_file=os.getenv("PYTHON_BASE_COMMAND_LOG_FILE", "true").lower() == "true",
180
+ )
174
181
 
175
182
  # ------------------------------------------------------------------ parser
176
183
 
184
+ def set_project_version(self, project_name: str | None = None) -> None:
185
+ if not project_name:
186
+ try:
187
+ project_path = get_project_path_by_file()
188
+ project_name = project_path.name
189
+ except Exception:
190
+ self.logger.warning("Project name not provided and could not be inferred from file markers.")
191
+ self.version = version(project_name) if project_name else self.version
192
+
177
193
  def create_parser(self, prog_name: str, subcommand: str, **kwargs: Any) -> CommandParser:
178
194
  """Create and return the CommandParser used to parse arguments."""
179
195
  kwargs.setdefault("formatter_class", CommandHelpFormatter)
@@ -262,7 +278,6 @@ class BaseCommand:
262
278
  If handle() returns a string and output_transaction is True,
263
279
  wraps it in BEGIN; / COMMIT;.
264
280
  """
265
- output: str | None = None
266
281
  if output := self.handle(**kwargs):
267
282
  if self.output_transaction:
268
283
  output = f"BEGIN;\n{output}\nCOMMIT;"
@@ -9,6 +9,11 @@ registry = CommandRegistry()
9
9
  class Greet2Command(BaseCommand):
10
10
  help = "Greet a user"
11
11
 
12
+ def __init__(self) -> None:
13
+ super().__init__()
14
+ # self.set_project_version("python-base-command")
15
+ self.set_project_version()
16
+
12
17
  def add_arguments(self, parser: CommandParser) -> None:
13
18
  parser.add_argument("name", type=str)
14
19
 
@@ -19,6 +24,7 @@ class Greet2Command(BaseCommand):
19
24
  @registry.register("export")
20
25
  class ExportCommand(BaseCommand):
21
26
  help = "Export data"
27
+ version = "1.0.0"
22
28
 
23
29
  def add_arguments(self, parser: CommandParser) -> None:
24
30
  parser.add_argument("--format", choices=["csv", "json"], default="csv")