cookbook.rst 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. .. _cookbook:
  2. Cookbook
  3. =========
  4. This section provides various examples for various
  5. needs.
  6. .. _cookbook-campaign:
  7. Email Campaign
  8. --------------
  9. In case you have a list of clients or customers you
  10. wish to send personalized emails, you may benefit from
  11. templating. It may help to make the templates to an HTML
  12. file, polish them and after then send:
  13. .. code-block:: python
  14. from redmail import EmailSender
  15. email = EmailSender(...)
  16. email.receivers = ['we@example.com']
  17. email.set_template_paths(
  18. html="path/to/campaigns"
  19. )
  20. Then make a HTML file, for example ``path/to/campaigns/summer_sale.html``:
  21. .. code-block:: html
  22. <img src="{{ company_logo }}" width=200 height=100>
  23. <h1>Thank you, {{ customer }}, for being awesome!</h1>
  24. <p>
  25. We are pleased to inform you that we have a lot of products
  26. in huge discounts.
  27. </p>
  28. <ul>
  29. {% for product, discount, in discounts.items() %}
  30. <li>{{ product }}: {{ '{:.0f} %'.format(discount * 100) }}</li>
  31. {% endfor %}
  32. </ul>
  33. <p>Kind regards, We Ltd.</p>
  34. Finally send the emails:
  35. .. code-block:: python
  36. discounts = {'shoes': 0.2, 'shirts': 0.4}
  37. customers = ['cust1@example.com', 'cust2@example.com', ...]
  38. for customer in customers:
  39. email.send(
  40. subject="Summer Sale!",
  41. html_template="summer_sale.html",
  42. body_params={
  43. "customer": customer,
  44. "discounts": discounts
  45. },
  46. body_images={
  47. "company_logo": "path/to/logo.png"
  48. }
  49. )
  50. .. _cookbook-alerts:
  51. Error Alerts
  52. ------------
  53. If you are building long running program (ie. web app) you can make a
  54. templated error alerts that include the full traceback:
  55. .. code-block:: python
  56. from redmail import EmailSender
  57. error_email = EmailSender(...)
  58. error_email.sender = 'me@example.com'
  59. error_email.receivers = ['me@example.com']
  60. error_email.html = """
  61. <h2>An error encountered</h2>
  62. {{ error }}
  63. """
  64. try:
  65. raise RuntimeError("Oops")
  66. except:
  67. # Send an email including the traceback
  68. error_email.send(subject="Fail: doing stuff failed")
  69. .. note::
  70. The ``error`` formatting object identifies which body it is being
  71. attached to. If you wish to use text body, ``error`` will show up
  72. similarly as Python errors you see on terminals. See more from
  73. :class:`redmail.models.Error`
  74. .. _cookbook-stats:
  75. Stats Reports
  76. -------------
  77. As demonstrated :ref:`here <embedding-plt>`, embedding Matplotlib
  78. figures to the HTML bodies is trivial. Therefore you can easily
  79. create diagnostic reports or automatic analyses. Just create
  80. the plots and let Red Mail send them to you:
  81. .. code-block:: python
  82. from redmail import EmailSender
  83. stats_report = EmailSender(...)
  84. stats_report.sender = 'no-reply@example.com'
  85. stats_report.receivers = ['me@example.com']
  86. # Create a plot
  87. import matplotlib.pyplot as plt
  88. fig_performance = plt.Figure()
  89. plt.plot([1,2,3,2,3])
  90. # Create summary table
  91. import pandas as pd
  92. df = pd.DataFrame(...)
  93. df_summary = df.describe()
  94. # Send the report
  95. stats_report.send(
  96. subject="System Diagnostics",
  97. html="""
  98. <h1>System Diagnostics ({{ now }})</h1>
  99. <hr>
  100. <h2>Performance</h2>
  101. {{ perf_plot }}
  102. <h2>Summary Statistics</h2>
  103. {{ tbl_summary }}
  104. <hr>
  105. <p>System running on {{ node }}</p>
  106. """,
  107. body_images={
  108. "perf_plot": fig_performance,
  109. },
  110. body_tables={
  111. "tbl_summary": df_summary
  112. }
  113. )
  114. Distribution Lists
  115. ------------------
  116. There might be a situation in which you would like to
  117. specify some sets of pre-defined distribution lists
  118. for which you will send emails to depending on situation.
  119. To accomplish this, you can create subclass the :class:`.EmailSender`
  120. and create cystin distribution list logic:
  121. .. code-block:: python
  122. from redmail import EmailSender
  123. class DistributionSender(EmailSender):
  124. "Send email using pre-defined distribution lists"
  125. def __init__(self, *args, distributions:dict, **kwargs):
  126. super().__init__(*args, **kwargs)
  127. self.distributions = distributions
  128. def get_receivers(self, receiver_list):
  129. if receiver_list:
  130. return self.distributions[receiver_list]
  131. def get_cc(self, receiver_list):
  132. if receiver_list:
  133. return self.distributions[receiver_list]
  134. def get_bcc(self, receiver_list):
  135. if receiver_list:
  136. return self.distributions[receiver_list]
  137. Then to use it:
  138. .. code-block:: python
  139. email = DistributionSender(
  140. host="localhost", port=0,
  141. distributions={
  142. "managers": ["boss1@example.com", "boss2@example.com"],
  143. "developers": ["dev1@example.com", "dev2@example.com"]
  144. }
  145. )
  146. email.send(
  147. subject="Important news",
  148. receivers="developers",
  149. cc="managers",
  150. ...
  151. )
  152. You can also accomplish this without subclassing to limited extent:
  153. .. code-block:: python
  154. managers = EmailSender(host="localhost", port=0)
  155. managers.receivers = ["boss1@example.com", "boss2@example.com"]
  156. developers = EmailSender(host="localhost", port=0)
  157. developers.receivers = ["dev1@example.com", "dev2@example.com"]
  158. # Send an email to the developers
  159. developers.send(
  160. subject="Important news"
  161. )