feat: added output management integration#161
Conversation
|
|
|
Hi. Could you give a more detailed description of this new feature for future reference? Also, is necessary that the title follows commit convention, for exemple: |
There was a problem hiding this comment.
Tests seems to be failing. Could you fix it?
| self, | ||
| http_session: requests.Session, | ||
| base_url: str, | ||
| destination: any = None, |
There was a problem hiding this comment.
If these parameters are optional, please use:
destination: Optional[any] = Noneor even
destination: Optional[Destination] = None| http_session: requests.Session, | ||
| base_url: str, | ||
| destination: any = None, | ||
| destination_instance: str = None, |
There was a problem hiding this comment.
destination_instance: Optional[str] = None| def __init__( | ||
| self, | ||
| base_url: str, | ||
| destination: any = None, |
There was a problem hiding this comment.
destination: Optional[any] = Noneor even
destination: Optional[Destination] = None| self, | ||
| base_url: str, | ||
| destination: any = None, | ||
| destination_instance: str = None, |
There was a problem hiding this comment.
destination_instance: Optional[str] = None|
|
||
| return None | ||
|
|
||
| def _execute_request(self, method: str, endpoint: str, **kwargs): |
There was a problem hiding this comment.
Missing return type annotation.
| self._destination_instance = destination_instance | ||
|
|
||
| # Get sender-provider-subaccount-id from environment variable | ||
| self._sender_provider_subaccount_id = os.getenv("APPFND_CONHOS_SUBACCOUNTID") |
There was a problem hiding this comment.
We are now using CLOUD_SDK_CFG_ as prefix. You can algo take a look at src/sap_cloud_sdk/core/secret_resolver, it may help
| # Get the destination object - it handles authentication automatically | ||
| http_destination = self._destination_credential_config.get_destination() | ||
|
|
||
| # Get the base URL from destinatiozxn |
|
|
||
| # If no ID found, use template key as fallback | ||
| if not doc_id: | ||
| doc_id = f"{notification_template_key}-{id(business_document)}" |
There was a problem hiding this comment.
Use id() as fallback can not be a good choice, once it is not stable across runs
| # Build attachment config if URLs are provided | ||
| attachment_config = None | ||
| if attachment_urls: | ||
| from ..models.attachment_config import AttachmentConfig |
There was a problem hiding this comment.
This lazy imports seems to serve no purpose here. There is no circular dependency risk here.
| from sap_cloud_sdk.destination import create_certificate_client, AccessStrategy | ||
| import tempfile | ||
| import base64 | ||
| from cryptography.hazmat.primitives.serialization import pkcs12, Encoding, PrivateFormat, NoEncryption |
There was a problem hiding this comment.
This hides an undeclared runtime dependency from static analysis tools (ruff, ty), prevents the type checker from seeing the symbols, and means the ImportError is only discovered at call time rather than at startup.
| import logging | ||
| from typing import Dict, Optional | ||
| import os | ||
| import json |
| CONTENT_TYPE_PDF = "application/pdf" | ||
|
|
||
|
|
||
| class Status(Enum): |
There was a problem hiding this comment.
Shouldn't the values be lowercased?
| CANCELLED = "CANCELLED" | ||
|
|
||
|
|
||
| class FileFormat(Enum): |
There was a problem hiding this comment.
Shouldn't the values be lowercased?
| XML = "XML" | ||
|
|
||
|
|
||
| class Channel(Enum): |
There was a problem hiding this comment.
Shouldn't the values be lowercased?
| API_OUTPUT_CONTROL = "/api/output-control-api/v1/" | ||
|
|
||
| # Headers | ||
| CONTENT_TYPE = "Content-Type" |
There was a problem hiding this comment.
Why CONTENT_TYPE and HEADER_CONTENT_TYPE have the same value?
|
|
||
| # Headers | ||
| CONTENT_TYPE = "Content-Type" | ||
| APPLICATION_JSON = "application/json" |
There was a problem hiding this comment.
Same goes for APPLICATION_JSON and CONTENT_TYPE_JSON.
|
|
||
| return None | ||
|
|
||
| def _execute_request(self, method: str, endpoint: str, **kwargs): |
There was a problem hiding this comment.
Also, is this method necessary? Its a wrapper for just one line.
| destination_name: str, | ||
| cc: Optional[List[str]] = None, | ||
| template_language: str = "en", | ||
| access_strategy: str = "PROVIDER_ONLY", |
There was a problem hiding this comment.
access_strategy: Optional[str] = "PROVIDER_ONLY"| business_document: Dict[str, Any], | ||
| destination_name: str, | ||
| cc: Optional[List[str]] = None, | ||
| template_language: str = "en", |
There was a problem hiding this comment.
template_language: Optional[str] = "en"|
|
||
| try: | ||
| request_body = output_request.model_dump(by_alias=True, exclude_none=True) | ||
| logger.info(f"Request body: {request_body}") |
There was a problem hiding this comment.
Should we log the request body? I believe it may have sensitive information.
Done |
Description
Output Management is a BTP shared service which has features like sending documents to external system in various channels like EDI/EMAIL/Print. As part of this, we are mainly concentrating on the email use case where one can send email via our framework along with attachments if necessary.
We are exposing capabilities via util methods of sending email as BTP destination based and via integrated MCP hub. When using the MCP Hub way, we are giving the capability to construct the required payload and invoke the util functions. When using the BTP destination way, we are giving the options to input the destination details and the payloads.
Related Issue
Closes #<issue_number>
(Link to the GitHub issue this PR addresses)
Type of Change
Please check the relevant option:
How to Test
Describe how reviewers can test your changes:
Checklist
Before submitting your PR, please review and check the following:
Breaking Changes
If this PR introduces breaking changes, please describe:
Additional Notes
Add any additional context, screenshots, or information that would help reviewers.