pyegeria 5.4.0.dev14__py3-none-any.whl → 5.4.0.2__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.
Files changed (43) hide show
  1. commands/cat/__init__.py +1 -17
  2. commands/cat/dr_egeria_md.py +6 -4
  3. commands/cat/list_collections.py +46 -36
  4. md_processing/__init__.py +5 -2
  5. md_processing/data/commands-working.json +34850 -0
  6. md_processing/data/commands.json +1750 -530
  7. md_processing/md_commands/product_manager_commands.py +171 -220
  8. md_processing/md_processing_utils/common_md_proc_utils.py +9 -0
  9. md_processing/md_processing_utils/common_md_utils.py +15 -2
  10. md_processing/md_processing_utils/md_processing_constants.py +44 -6
  11. pyegeria/__init__.py +8 -4
  12. pyegeria/_client.py +2 -1
  13. pyegeria/_client_new.py +688 -0
  14. pyegeria/_exceptions_new.py +364 -0
  15. pyegeria/_globals.py +3 -1
  16. pyegeria/_output_formats.py +196 -0
  17. pyegeria/_validators.py +72 -199
  18. pyegeria/collection_manager_omvs.py +602 -324
  19. pyegeria/data_designer_omvs.py +251 -203
  20. pyegeria/load_config.py +206 -0
  21. pyegeria/logging_configuration.py +204 -0
  22. pyegeria/output_formatter.py +162 -31
  23. pyegeria/utils.py +99 -61
  24. {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/METADATA +4 -1
  25. {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/RECORD +28 -37
  26. commands/cat/debug_log +0 -2806
  27. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  28. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  29. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +0 -1
  30. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +0 -1
  31. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +0 -31
  32. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +0 -177
  33. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +0 -663
  34. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +0 -719
  35. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +0 -41
  36. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +0 -33
  37. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +0 -192
  38. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +0 -527
  39. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +0 -527
  40. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +0 -474
  41. {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/LICENSE +0 -0
  42. {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/WHEEL +0 -0
  43. {pyegeria-5.4.0.dev14.dist-info → pyegeria-5.4.0.2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,206 @@
1
+
2
+ """
3
+ SPDX-License-Identifier: Apache-2.0
4
+ Copyright Contributors to the ODPi Egeria project.
5
+
6
+ This module configures logging for pyegeria.
7
+ """
8
+ import os
9
+ from loguru import logger
10
+
11
+ # PYEGERIA_LOG_DIRECTORY = os.getenv("PYEGERIA_LOG_DIRECTORY", "logs")
12
+ # PYEGERIA_CONSOLE_LOG_LVL = os.getenv("PYEGERIA_CONSOLE_LOG_LVL", "INFO")
13
+ # PYEGERIA_FILE_LOG_LVL = os.getenv("PYEGERIA_FILE_LOG_LVL", "TRACE")
14
+
15
+ # config.py
16
+
17
+ import os
18
+ import json
19
+ # from dotenv import load_dotenv # pip install python-dotenv if you use .env files
20
+
21
+ # --- Configuration Loading Logic ---
22
+
23
+ # Private variable to hold the loaded configuration
24
+ _app_config = None
25
+
26
+ def load_app_config():
27
+ """
28
+ Loads application configuration from files and environment variables.
29
+ This function should ideally be called only once at application startup.
30
+ """
31
+ global _app_config # Declare intent to modify the global _app_config
32
+
33
+ if _app_config is not None:
34
+ # Configuration already loaded, return existing instance
35
+ return _app_config
36
+
37
+ # 1. Load .env variables first if present (for local development)
38
+ # This ensures os.getenv can pick them up.
39
+ # load_dotenv()
40
+
41
+ # Define default configuration values
42
+ config = {
43
+ "Environment": {
44
+ "Console Width": 200,
45
+ "Dr. Egeria Inbox": "md-processing/dr-egeria-inbox",
46
+ "Dr. Egeria Outbox": "md-processing/dr-egeria-outbox",
47
+ "Egeria Engine Host URL": "",
48
+ "Egeria Engine Host": "qs-engine-host",
49
+ "Egeria Glossary Path": "glossary",
50
+ "Egeria Integration Daemon URL": "https://localhost:9443",
51
+ "Egeria Integration Daemon": "qs-integration-daemon",
52
+ "Egeria Jupyter": True,
53
+ "Egeria Kafka Endpoint": "localhost:9192",
54
+ "Egeria Mermaid Folder": "mermaid_graphs",
55
+ "Egeria Metadata Store": "qs-metadata-store",
56
+ "Egeria Platform URL": "https://localhost:9443",
57
+ "Egeria View Server URL": "https://localhost:9443",
58
+ "Egeria View Server": "qs-view-server",
59
+ "Pyegeria Root": "/Users/dwolfson/localGit/egeria-v5-3/egeria-python",
60
+ },
61
+
62
+ "Debug": {
63
+ "debug_mode": False,
64
+ "enable_logger_catch": False,
65
+ "timeout_seconds": 30,
66
+ },
67
+ "feature_x_enabled": False,
68
+ "Logging": {
69
+ "console_filter_levels": [
70
+ "ERROR"
71
+ ],
72
+ "console_logging_enabled": [
73
+ "_client_new",
74
+ "_exceptions_new",
75
+ "collections_manager_omvs"
76
+ "tests",
77
+ ],
78
+ "console_logging_level": "INFO",
79
+ "enable_logging": False,
80
+ "file_logging_level": "INFO",
81
+ "log_directory": "logs",
82
+ "logging_console_format":
83
+ " <cyan>{name}</cyan>:<cyan>{line}</cyan> - <level>{message}</level> -{extra}",
84
+ " <green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> |"
85
+ "logging_file_format":
86
+ " {time:YYYY-MM-DD HH:mm:ss} | {level} | {function}:{line} - {message }-{extra}"
87
+ },
88
+ "User Profile": {
89
+ "Egeria Home Collection": "MyHome",
90
+ "Egeria Home Glossary Name": "Egeria-Markdown",
91
+ "Egeria Local Qualifier": "PDR"
92
+ }
93
+ }
94
+
95
+ # 2. Load from a configuration file (e.g., config.json)
96
+ # This allows overriding defaults with file-based settings.
97
+ root_path = os.getenv("PYEGERIA_ROOT_PATH", config["Environment"].get("Pyegeria Root",""))
98
+ config_file = os.getenv("PYEGERIA_CONFIG_FILE", "config.json")
99
+ config_file_path = os.path.join(root_path,config_file)
100
+ if os.path.exists(config_file_path):
101
+ try:
102
+ with open(config_file_path, 'r') as f:
103
+ file_config = json.load(f)
104
+ config.update(file_config) # Merge/override defaults
105
+ # logger.debug("Configuration file loaded from {}".format(config_file_path))
106
+ except json.JSONDecodeError:
107
+ print(f"Warning: Could not parse {config_file_path}. Using defaults/env vars.")
108
+ except Exception as e:
109
+ print(f"Warning: Error reading {config_file_path}: {e}. Using defaults/env vars.")
110
+
111
+ # 3. Override with environment variables
112
+ # Environment variables take highest precedence.
113
+ debug = config["Debug"]
114
+ debug['debug_mode'] = os.getenv("PYEGERIA_DEBUG_MODE", debug.get("debug_mode", False))
115
+ debug["enable_logger_catch"] = os.getenv("PYEGERIA_ENABLE_LOGGER_CATCH", debug.get("enable_logger_catch", False))
116
+ debug["timeout_seconds"] = int(os.getenv("PYEGERIA_TIMEOUT_SECONDS", debug.get("timeout_seconds", 30)))
117
+
118
+ env = config["Environment"]
119
+ env["Console Width"] = int(os.getenv("PYEGERIA_CONSOLE_WIDTH", env.get("EGERIA_WIDTH", 200)))
120
+ env["Dr.Egeria Inbox"] = os.getenv("DR_EGERIA_INBOX_PATH", env.get("Dr_EGERIA_INBOX",
121
+ "md-processing/dr-egeria-inbox"))
122
+ env["Dr.Egeria Outbox"] = os.getenv("DR_EGERIA_OUTBOX_PATH", env.get("DR_EGERIA_OUTBOX",
123
+ "md-processing/dr-egeria-outbox"))
124
+ env["Egeria Engine Host"] = os.getenv("EGERIA_ENGINE_HOST", env.get("Egeria Engine Host", "qs-engine-host"))
125
+ env["Egeria Engine Host URL"] = os.getenv("EGERIA_ENGINE_HOST_URL",env.get("Egeria Engine Host URL", "https://localhost:9443"))
126
+
127
+ env["Egeria Glossary Path"] = os.getenv("EGERIA_GLOSSARY_PATH", env.get("Egeria Glossary Path", "glossary"))
128
+ env["Egeria Integration Daemon"] = os.getenv("EGERIA_INTEGRATION_DAEMON", env.get("Egeria Integration Daemon", "qs-integration-daemon"))
129
+ env["Egeria Integration Daemon URL"] = os.getenv("EGERIA_INTEGRATION_DAEMON_URL",env.get("Egeria Integration Daemon URL", "https://localhost:9443"))
130
+ env["Egeria Jupyter"] = os.getenv("EGERIA_JUPYTER", env.get("Egeria Jupyter", True))
131
+ env["Egeria Kafka"] = os.getenv("EGERIA_KAFKA", env.get("Egeria Kafka", "https://localhost:9192"))
132
+ env["Egeria Mermaid Folder"] = os.getenv("EGERIA_MERMAID_FOLDER", env.get("Egeria Mermaid Folder","mermaid_graphs"))
133
+ env["Egeria Metadata Store"] = os.getenv("EGERIA_METADATA_STORE", env.get("Egeria Metadata Store","qs-metadata-store"))
134
+ env["Egeria Platform URL"] = os.getenv("EGERIA_PLATFORM_URL", env.get("Egeria Platform URL","https://localhost:9443"))
135
+ env["Egeria View Server"] = os.getenv("EGERIA_VIEW_SERVER", env.get("Egeria View Server","qs-view-server"))
136
+ env["Egeria VIew Server URL"] = os.getenv("EGERIA_VIEW_SERVER_URL", env.get("Egeria View Server URL","https://localhost:9443"))
137
+ env["Pyegeria Root"] = root_path
138
+
139
+ log = config["Logging"]
140
+ log["console_filter_levels"] = os.getenv("PYEGERIA_CONSOLE_FILTER_LEVELS",
141
+ log.get("console_filter_levels", ["ERROR"]))
142
+ log["console_logging_enabled"] = os.getenv("PYEGERIA_CONSOLE_LOGGING_ENABLED",
143
+ log.get("console_logging_enabled", ["tests"]))
144
+ log["console_logging_level"] = os.getenv("PYEGERIA_CONSOLE_LOG_LVL", log.get("console_logging_level", None))
145
+ log["enable_logging"] = os.getenv("PYEGERIA_ENABLE_LOGGING", log.get("enable_logging", False))
146
+ log["file_logging_level"] = os.getenv("PYEGERIA_FILE_LOG_LVL", log.get("file_logging_level","INFO"))
147
+ log["log_directory"] = os.getenv("PYEGERIA_LOG_DIRECTORY", log.get("log_directory",None))
148
+ log["logging_console_format"] = os.getenv("PYEGERIA_LOGGING_CONSOLE_FORMAT", log.get("logging_console_format",
149
+ " <green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | "
150
+ "<cyan>{name}</cyan>:<cyan>{line}</cyan> - "
151
+ "<level>{message}</level> -{extra}" ))
152
+ log["logging_file_format"] = os.getenv("PYEGERIA_LOGGING_FILE_FORMAT",log.get("logging_file_format",
153
+ " {time:YYYY-MM-DD HH:mm:ss} | {level} | {function}:{line} "
154
+ "- {message }-{extra}" ))
155
+
156
+ user = config["User Profile"]
157
+ user["Egeria Home Collection"] = os.getenv("EGERIA_HOME_COLLECTION", user.get("Egeria Home Collection", "myHome"))
158
+ user["Egeria Home Glossary Name"] = os.getenv("EGERIA_HOME_GLOSSARY_NAME", user.get("Egeria Home Glossary Name", "Egeria-Markdown"))
159
+ user["Egeria Local Qualifier"] = os.getenv("EGERIA_LOCAL_QUALIFIER", user.get("Egeria Local Qualifier", "myLocal"))
160
+ user["user_name"] = os.getenv("EGERIA_USER_NAME", "peterprofile")
161
+ user["user_pwd"] = os.getenv("EGERIA_USER_PASSWORD", "secret")
162
+
163
+
164
+
165
+
166
+ # Handle type conversion for env vars (they are always strings)
167
+ # if "TIMEOUT_SECONDS" in os.environ:
168
+ # try:
169
+ # config["timeout_seconds"] = int(os.getenv("TIMEOUT_SECONDS"))
170
+ # except ValueError:
171
+ # print("Warning: TIMEOUT_SECONDS environment variable is not an integer. Using default.")
172
+ #
173
+ # if "DEBUG_MODE" in os.environ:
174
+ # # Convert string "True", "False", "1", "0" to boolean
175
+ # debug_str = os.getenv("DEBUG_MODE").lower()
176
+ # config["debug_mode"] = debug_str in ('True', '1', 't', 'y', 'yes', 'on')
177
+ #
178
+ # if "FEATURE_X_ENABLED" in os.environ:
179
+ # feature_x_str = os.getenv("FEATURE_X_ENABLED").lower()
180
+ # config["feature_x_enabled"] = feature_x_str in ('True', '1', 't', 'y', 'yes', 'on')
181
+
182
+ # 4. Handle sensitive API key (only from environment variable)
183
+ # config["api_key"] = os.getenv("MY_SERVICE_API_KEY")
184
+ # if config["api_key"] is None:
185
+ # print("Error: MY_SERVICE_API_KEY environment variable is critical and not set.")
186
+ # # In a production application, you might raise a critical exception here:
187
+ # # raise ValueError("MY_SERVICE_API_KEY is not set!")
188
+
189
+ _app_config = config # Store the final loaded configuration
190
+ return _app_config
191
+
192
+ def get_app_config():
193
+ """
194
+ Provides access to the loaded application configuration.
195
+ Ensures config is loaded if not already (useful for testing or simple scripts).
196
+ For structured apps, load_app_config() should be called explicitly once at startup.
197
+ """
198
+ if _app_config is None:
199
+ # If get_app_config is called before load_app_config, load it now.
200
+ # This can be convenient but explicit loading is generally better.
201
+ return load_app_config()
202
+ return _app_config
203
+
204
+ # You can also define constants based on the config for common access,
205
+ # but be aware these won't update if the config changes after initial load.
206
+ # E.g., API_ENDPOINT = get_app_config().get("api_endpoint")
@@ -0,0 +1,204 @@
1
+
2
+ """
3
+ SPDX-License-Identifier: Apache-2.0
4
+ Copyright Contributors to the ODPi Egeria project.
5
+
6
+ This module configures logging using loguru. The pyegeria library modules do not configure
7
+ loguru automatically so that the calling application has control over the logging. However, if the
8
+ calling application doesn't have its own logging setup, it can use this module to configure loguru logging.
9
+
10
+ If the application uses another logging library, such as the built-in python logging, it can
11
+ do so by redirecting loguru output. Here is an example:
12
+
13
+ # application.py - App uses standard logging, redirects Loguru)
14
+
15
+ import logging
16
+ import logging.config
17
+ import sys # For sys.stderr
18
+ from loguru import logger # Import Loguru's logger
19
+ from my_library.my_module import MyLibraryClass, library_function
20
+
21
+ # --- Standard Logging Configuration (for the application) ---
22
+ # This is your application's primary logging setup.
23
+ LOGGING_CONFIG = {
24
+ "version": 1,
25
+ "disable_existing_loggers": False,
26
+ "formatters": {
27
+ "standard": {
28
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
29
+ }
30
+ },
31
+ "handlers": {
32
+ "console": {
33
+ "class": "logging.StreamHandler",
34
+ "level": "INFO",
35
+ "formatter": "standard",
36
+ "stream": "ext://sys.stdout"
37
+ },
38
+ "file": {
39
+ "class": "logging.handlers.RotatingFileHandler",
40
+ "level": "DEBUG",
41
+ "formatter": "standard",
42
+ "filename": "app_standard.log",
43
+ "maxBytes": 10485760,
44
+ "backupCount": 5
45
+ }
46
+ },
47
+ "loggers": {
48
+ # Root logger for the application
49
+ "": { # Empty string means the root logger
50
+ "handlers": ["console", "file"],
51
+ "level": "DEBUG", # Set the overall minimum level here
52
+ "propagate": False
53
+ }
54
+ }
55
+ }
56
+
57
+ try:
58
+ logging.config.dictConfig(LOGGING_CONFIG)
59
+ app_logger = logging.getLogger(__name__)
60
+ app_logger.info("Application standard logging configured successfully.")
61
+ except Exception as e:
62
+ print(f"Error configuring standard logging: {e}. Falling back to basicConfig.")
63
+ logging.basicConfig(level=logging.INFO)
64
+ app_logger = logging.getLogger(__name__)
65
+ app_logger.warning("Using basic logging due to configuration error.")
66
+
67
+ # --- Integrate Loguru with Standard Logging ---
68
+ # This is the key to "disabling" Loguru's separate output.
69
+
70
+ # 1. Remove Loguru's default handler (which outputs to stderr)
71
+ logger.remove(0)
72
+
73
+ # 2. Add a handler to Loguru that redirects messages to the standard logging module.
74
+ # The level here determines what Loguru sends to standard logging.
75
+ logger.add(
76
+ logging.StreamHandler(sys.stderr), # You can use any standard logging handler here
77
+ level="DEBUG", # Loguru will send messages at this level or higher to standard logging
78
+ format="{message}" # Keep Loguru's format simple, let standard logging handle formatting
79
+ )
80
+
81
+ # Optional: If you want to completely suppress Loguru's output and rely solely on standard logging
82
+ # for your library's messages, you can set Loguru's level to a very high value:
83
+ # logger.level("CRITICAL") # This would make it only log critical errors
84
+ # Or, if you want to completely disable it (not recommended for general use):
85
+ # logger.disable("my_library") # This disables logging for the 'my_library' hierarchy
86
+
87
+ app_logger.info("Loguru integrated with standard logging.")
88
+
89
+ # --- Main Application Logic ---
90
+ if __name__ == "__main__":
91
+ app_logger.info("Application started.")
92
+
93
+ # Your library's logs will now go through the standard logging system
94
+ my_instance = MyLibraryClass("test_value")
95
+ processed = my_instance.process_data("hello world")
96
+ app_logger.info("Processed data: %s", processed)
97
+
98
+ library_function()
99
+
100
+ try:
101
+ my_instance.perform_risky_operation()
102
+ except Exception:
103
+ app_logger.error("Caught exception from risky operation in library.")
104
+
105
+ app_logger.info("Application finished.")
106
+
107
+ To suppress logging, an application can do the following:
108
+ # application.py (Scenario C: App wants library to be silent)
109
+
110
+ from loguru import logger
111
+ from my_library.my_module import MyLibraryClass, library_function
112
+
113
+ # Remove Loguru's default handler
114
+ logger.remove(0)
115
+
116
+ # Completely disable logging for the 'my_library' hierarchy
117
+ logger.disable("my_library")
118
+
119
+ logger.info("Application started. Loguru for 'my_library' is disabled.")
120
+
121
+ my_instance = MyLibraryClass("test_value")
122
+ processed = my_instance.process_data("hello world") # These will not be logged by library
123
+ logger.info("Processed data: %s", processed) # This will be logged by app's logger
124
+
125
+ library_function() # This will not be logged by library
126
+
127
+ logger.info("Application finished.")
128
+
129
+ """
130
+
131
+ # application.py (Scenario A: App uses Loguru)
132
+ import os, sys
133
+ from loguru import logger
134
+ from pyegeria.load_config import get_app_config
135
+
136
+ # Load configuration parameters
137
+ app_settings = get_app_config()
138
+
139
+ def console_log_filter(record):
140
+ return (record["module"] in app_settings["Logging"]["console_logging_enabled"]
141
+ and
142
+ record["level"].name in app_settings["Logging"]["console_filter_levels"]
143
+ )
144
+
145
+
146
+
147
+ def config_logging():
148
+ """
149
+ Configures logging for the application using Loguru.
150
+
151
+ This function sets up logging functionalities for the application. It reads
152
+ the necessary logging configurations, ensures the desired log directory exists,
153
+ and defines logging handlers for both file-based and console-based logging.
154
+ Log messages can be retained with a rotation and compression policy for file logs.
155
+
156
+ Raises:
157
+ OSError: If the log directory cannot be created.
158
+
159
+ """
160
+
161
+
162
+ # Get the directory for log files from the environment variable
163
+ log_app_settings = app_settings["Logging"]
164
+ log_directory = log_app_settings.get("log_directory","/tmp")
165
+ console_logging_level = log_app_settings.get("console_logging_level","SUCCESS")
166
+ logging_console_format = log_app_settings.get("console_format","{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{line}"
167
+ " - {message} - {extra}")
168
+ file_logging_level = log_app_settings.get("file_logging_level", "INFO")
169
+ logging_file_format = log_app_settings.get("file_format", "{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{line}"
170
+ " - {message} - {extra}")
171
+ console_logging_enabled = log_app_settings.get("console_logging_enabled", "tests")
172
+ enable_logging = log_app_settings.get("enable_logging", True)
173
+
174
+ # Ensure the directory exists
175
+ os.makedirs(log_directory, exist_ok=True)
176
+
177
+ # Define the log file path
178
+ log_file_path = os.path.join(log_directory, "pyegeria.log")
179
+ # Remove Loguru's default stderr handler (id=0) if you want full control
180
+ logger.remove()
181
+
182
+ # Add your desired handlers for the application (and thus the library)
183
+ logger.add(log_file_path,
184
+ level=file_logging_level,
185
+ format=logging_file_format,
186
+ filter = "collection_manager_omvs",
187
+ retention="7 days", # Keep logs for 7 days
188
+ rotation="10 MB", # rotate logs once they are 10mb
189
+ compression="zip")
190
+ logger.add(
191
+ sys.stderr,
192
+ level=console_logging_level,
193
+ format=logging_console_format,
194
+ filter=console_log_filter,
195
+ colorize=True
196
+ )
197
+
198
+ if enable_logging:
199
+ logger.enable("")
200
+ logger.info("Application started with Loguru configured.")
201
+
202
+
203
+
204
+