diff --git a/singer_sdk/about.py b/singer_sdk/about.py index 87f83a6ef..d1228b43c 100644 --- a/singer_sdk/about.py +++ b/singer_sdk/about.py @@ -67,6 +67,7 @@ class AboutInfo: capabilities: list[CapabilitiesEnum] settings: dict + env_var_prefix: str class AboutFormatter(abc.ABC): @@ -118,17 +119,33 @@ def format_about(self, about_info: AboutInfo) -> str: # noqa: PLR6301 Returns: A formatted string. """ - return dedent( + output = dedent( f"""\ Name: {about_info.name} Description: {about_info.description} Version: {about_info.version} - SDK Version: {about_info.sdk_version} - Supported Python Versions: {about_info.supported_python_versions} - Capabilities: {about_info.capabilities} - Settings: {about_info.settings}""", + SDK Version: {about_info.sdk_version}""" ) + if about_info.supported_python_versions: + output += "\nSupport Python Versions:\n" + output += "\n".join( + [f" - {v}" for v in about_info.supported_python_versions] + ) + + output += "\nSupport Python Versions:\n" + output += "\n".join([f" - {c}" for c in about_info.capabilities]) + + output += "\nSettings:\n" + for setting, schema in about_info.settings.get("properties", {}).items(): + env_var = about_info.env_var_prefix + setting.upper().replace("-", "_") + json_type = schema.get("type") + output += f" - Name: {setting}\n" + output += f" Type: {json_type}\n" + output += f" Environment Variable: {env_var}\n" + + return output + class JSONFormatter(AboutFormatter, format_name="json"): """About formatter for JSON output.""" @@ -227,43 +244,34 @@ def format_about(self, about_info: AboutInfo) -> str: Returns: A formatted string. """ - # Empty list for string parts - md_list = [] - - # Iterate over Dict to set md - md_list.append( - f"# `{about_info.name}`\n\n" - f"{about_info.description}\n\n" - f"Built with the [Meltano Singer SDK](https://sdk.meltano.com).\n\n", - ) - - # Process capabilities and settings - - capabilities = "## Capabilities\n\n" - capabilities += "\n".join([f"* `{v}`" for v in about_info.capabilities]) - capabilities += "\n\n" - md_list.append(capabilities) + # Header + output = dedent(f"""\ + # `{about_info.name}`\n + {about_info.description}\n + Built with the [Meltano Singer SDK](https://sdk.meltano.com).\n + """) + + # Process capabilities + output += "## Capabilities\n\n" + output += "\n".join([f"* `{v}`" for v in about_info.capabilities]) + output += "\n\n" # Process Supported Python Versions - if about_info.supported_python_versions: - supported_python_versions = "## Supported Python Versions\n\n" - supported_python_versions += "\n".join( + output += "## Supported Python Versions\n\n" + output += "\n".join( [f"* {v}" for v in about_info.supported_python_versions], ) - supported_python_versions += "\n\n" - md_list.append(supported_python_versions) + output += "\n\n" # Process settings - - setting = "## Settings\n\n" - settings_table = ( + output += "## Settings\n\n" + output += ( "| Setting | Required | Default | Description |\n" "|:--------|:--------:|:-------:|:------------|\n" ) - settings_table += "\n".join(self._generate_property_rows(about_info.settings)) - setting += settings_table - setting += ( + output += "\n".join(self._generate_property_rows(about_info.settings)) + output += ( "\n\n" + "\n".join( [ @@ -273,6 +281,5 @@ def format_about(self, about_info: AboutInfo) -> str: ) + "\n" ) - md_list.append(setting) - return "".join(md_list) + return output diff --git a/singer_sdk/plugin_base.py b/singer_sdk/plugin_base.py index b88559088..f709fed95 100644 --- a/singer_sdk/plugin_base.py +++ b/singer_sdk/plugin_base.py @@ -229,6 +229,10 @@ def capabilities(self) -> list[CapabilitiesEnum]: # noqa: PLR6301 PluginCapabilities.BATCH, ] + @classproperty + def _env_var_prefix(cls) -> str: # noqa: N805 + return f"{cls.name.upper().replace('-', '_')}_" + @classproperty def _env_var_config(cls) -> dict[str, t.Any]: # noqa: N805 """Return any config specified in environment variables. @@ -239,11 +243,10 @@ def _env_var_config(cls) -> dict[str, t.Any]: # noqa: N805 Returns: Dictionary of configuration parsed from the environment. """ - plugin_env_prefix = f"{cls.name.upper().replace('-', '_')}_" config_jsonschema = cls.config_jsonschema cls.append_builtin_config(config_jsonschema) - return parse_environment_config(config_jsonschema, plugin_env_prefix) + return parse_environment_config(config_jsonschema, cls._env_var_prefix) # Core plugin metadata: @@ -428,6 +431,7 @@ def _get_about_info(cls: type[PluginBase]) -> about.AboutInfo: supported_python_versions=cls.get_supported_python_versions(), capabilities=cls.capabilities, settings=config_jsonschema, + env_var_prefix=cls._env_var_prefix, ) @classmethod diff --git a/tests/core/test_about.py b/tests/core/test_about.py index a25543ca2..70a445bb1 100644 --- a/tests/core/test_about.py +++ b/tests/core/test_about.py @@ -66,6 +66,7 @@ def about_info() -> AboutInfo: }, "required": ["api_key"], }, + env_var_prefix="TAP_EXAMPLE_", ) diff --git a/tests/snapshots/about_format/text.snap.txt b/tests/snapshots/about_format/text.snap.txt index 06a3649c7..028f0541b 100644 --- a/tests/snapshots/about_format/text.snap.txt +++ b/tests/snapshots/about_format/text.snap.txt @@ -2,6 +2,24 @@ Name: tap-example Description: Example tap for Singer SDK Version: 0.1.1 SDK Version: 1.0.0 -Supported Python Versions: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] -Capabilities: [catalog, discover, state] -Settings: {'properties': {'start_date': {'type': 'string', 'format': 'date-time', 'description': 'Start date for the tap to extract data from.'}, 'api_key': {'type': 'string', 'description': 'API key for the tap to use.'}, 'complex_setting': {'type': 'object', 'description': 'A complex setting, with sub-settings.', 'properties': {'sub_setting': {'type': 'string', 'description': 'A sub-setting.'}}}}, 'required': ['api_key']} \ No newline at end of file +Support Python Versions: + - 3.8 + - 3.9 + - 3.10 + - 3.11 + - 3.12 + - 3.13 +Support Python Versions: + - catalog + - discover + - state +Settings: + - Name: start_date + Type: string + Environment Variable: TAP_EXAMPLE_START_DATE + - Name: api_key + Type: string + Environment Variable: TAP_EXAMPLE_API_KEY + - Name: complex_setting + Type: object + Environment Variable: TAP_EXAMPLE_COMPLEX_SETTING