diff --git a/patchwork/steps/CallSQL/CallSQL.py b/patchwork/steps/CallSQL/CallSQL.py index dca37c5d4..6ae811530 100644 --- a/patchwork/steps/CallSQL/CallSQL.py +++ b/patchwork/steps/CallSQL/CallSQL.py @@ -33,7 +33,7 @@ def __build_engine(self, inputs: dict): **{k: v for k, v in kwargs.items() if v is not None}, ) - connect_args = None + connect_args = dict() if inputs.get("db_driver_args") is not None: connect_args = parse_to_dict(inputs.get("db_driver_args")) diff --git a/patchwork/steps/SendEmail/SendEmail.py b/patchwork/steps/SendEmail/SendEmail.py new file mode 100644 index 000000000..bba3bea0d --- /dev/null +++ b/patchwork/steps/SendEmail/SendEmail.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import smtplib +from email.mime.text import MIMEText + +from patchwork.common.utils.utils import mustache_render +from patchwork.step import Step +from patchwork.steps.SendEmail.typed import SendEmailInputs, SendEmailOutputs + + +class SendEmail(Step, input_class=SendEmailInputs, output_class=SendEmailOutputs): + def __init__(self, inputs): + super().__init__(inputs) + self.email_template_value = inputs.get("email_template_value", dict()) + self.subject = inputs.get("subject", "Patchwork Execution Email") + self.body = inputs.get("body", "Patchwork Execution Email") + self.sender_email = inputs["sender_email"] + self.recipient_email = inputs["recipient_email"] + self.password = inputs["sender_email_password"] + self.smtp_host = inputs.get("smtp_host", "smtp.gmail.com") + self.smtp_port = int(inputs.get("smtp_port", 465)) + + def run(self) -> dict: + msg = MIMEText(mustache_render(self.body, self.email_template_value)) + msg["Subject"] = mustache_render(self.subject, self.email_template_value) + msg["From"] = self.sender_email + msg["To"] = self.recipient_email + + # TODO: support smtp without ssl + with smtplib.SMTP_SSL(self.smtp_host, self.smtp_port) as smtp_server: + smtp_server.login(self.sender_email, self.password) + smtp_server.sendmail(self.sender_email, self.recipient_email, msg.as_string()) + + return dict() diff --git a/patchwork/steps/SendEmail/__init__.py b/patchwork/steps/SendEmail/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/patchwork/steps/SendEmail/typed.py b/patchwork/steps/SendEmail/typed.py new file mode 100644 index 000000000..b1e0a3587 --- /dev/null +++ b/patchwork/steps/SendEmail/typed.py @@ -0,0 +1,21 @@ +from typing_extensions import Annotated, Any, Dict, TypedDict + +from patchwork.common.utils.step_typing import StepTypeConfig + + +class __SendEmailRequiredInputs(TypedDict): + sender_email: str + recipient_email: str + sender_email_password: str + + +class SendEmailInputs(__SendEmailRequiredInputs, total=False): + email_template_value: dict[str, Any] + subject: str + body: str + smtp_host: str + smtp_port: int + + +class SendEmailOutputs(TypedDict): + pass diff --git a/patchwork/steps/__init__.py b/patchwork/steps/__init__.py index fe690655f..d2a405251 100644 --- a/patchwork/steps/__init__.py +++ b/patchwork/steps/__init__.py @@ -47,6 +47,7 @@ from patchwork.steps.ScanDepscan.ScanDepscan import ScanDepscan from patchwork.steps.ScanSemgrep.ScanSemgrep import ScanSemgrep from patchwork.steps.ScanSonar.ScanSonar import ScanSonar +from patchwork.steps.SendEmail.SendEmail import SendEmail from patchwork.steps.SimplifiedLLM.SimplifiedLLM import SimplifiedLLM from patchwork.steps.SimplifiedLLMOnce.SimplifiedLLMOnce import SimplifiedLLMOnce from patchwork.steps.SlackMessage.SlackMessage import SlackMessage @@ -99,6 +100,7 @@ "ScanDepscan", "ScanSemgrep", "ScanSonar", + "SendEmail", "SimplifiedLLM", "SimplifiedLLMOnce", "SimplifiedLLMOncePB", diff --git a/pyproject.toml b/pyproject.toml index 03bc16b01..40ca5a569 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "patchwork-cli" -version = "0.0.97" +version = "0.0.98" description = "" authors = ["patched.codes"] license = "AGPL"