1
0

body_content.rst 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. .. _embedded:
  2. Embedding Content
  3. =================
  4. Red Mail allows to embed images and tables to the
  5. HTML bodies of emails. By default, tables often
  6. look outdated and ugly in emails but Red Mail
  7. has pre-made table templates that render nicer
  8. looking tables from Pandas dataframes.
  9. .. _embedding-images:
  10. Embedded Images
  11. ---------------
  12. You can also embed images straight to the HTML body
  13. of the email:
  14. .. code-block:: python
  15. email.send(
  16. subject='An image',
  17. receivers=['first.last@example.com'],
  18. html="""
  19. <h1>This is an image:</h1>
  20. {{ my_image }}
  21. """,
  22. body_images={
  23. 'my_image': 'path/to/image.png',
  24. }
  25. )
  26. The outcome looks like this:
  27. .. image:: /imgs/email_emb_img.png
  28. :align: center
  29. The image will be rendered as ``<img src="cid:...">``.
  30. In case you need to control the image (like the size)
  31. you can also create the ``img`` tag yourself:
  32. .. code-block:: python
  33. email.send(
  34. subject='An image',
  35. receivers=['first.last@example.com'],
  36. html="""
  37. <h1>This is an image:</h1>
  38. <img src="{{ my_image.src }}" width=500 height=350>
  39. """,
  40. body_images={
  41. 'my_image': 'path/to/image.png',
  42. }
  43. )
  44. In addition to paths as strings, the following are supported:
  45. - pathlib.Path
  46. - :ref:`bytes (the image as raw bytes) <embedding-images-bytes>`
  47. - :ref:`matplotlib.pyplot.Figure <embedding-images-plt>`
  48. - :ref:`PIL.Image (Pillow image) <embedding-images-pil>`
  49. - :ref:`dict (content as bytes and specify the type) <embedding-images-dict>`
  50. .. _embedding-images-bytes:
  51. Embedding Image from bytes
  52. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  53. You may also pass the image as bytes:
  54. .. code-block:: python
  55. import base64
  56. # data of a simple PNG image
  57. data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
  58. data_as_bytes = base64.b64decode(data_as_base64)
  59. gmail.send(
  60. subject='An image',
  61. receivers=['first.last@example.com'],
  62. html="""
  63. <h1>This is an image:</h1>
  64. {{ myimage }}
  65. """,
  66. body_images={
  67. 'myimage': data_as_bytes
  68. },
  69. )
  70. .. note::
  71. The bytes are expected to represent a PNG image. In case your image is in
  72. other format (ie. JPEG), you should specify the image using the
  73. :ref:`dict format <embedding-images-dict>`
  74. .. _embedding-images-dict:
  75. Embedding Image with dict format
  76. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  77. You may also include images using the dict format:
  78. .. code-block:: python
  79. import base64
  80. # data of a simple PNG image
  81. data = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
  82. data_as_bytes = base64.b64decode(data_as_base64)
  83. gmail.send(
  84. subject='An image',
  85. receivers=['first.last@example.com'],
  86. html="""
  87. <h1>This is an image:</h1>
  88. {{ myimage }}
  89. """,
  90. body_images={
  91. 'myimage': {
  92. 'myimage': data_as_bytes,
  93. 'subtype': 'png'
  94. }
  95. }
  96. )
  97. This enables more control than including bytes as you may specify the ``subtype`` of the image.
  98. .. _embedding-images-plt:
  99. Embedding Figure
  100. ^^^^^^^^^^^^^^^^
  101. As mentioned, you may also include Matplotlib figures directly to the email.
  102. This is especially handy if you are creating automatic statistics.
  103. A simple example to include a figure:
  104. .. code-block:: python
  105. # Create a simple plot
  106. import matplotlib.pyplot as plt
  107. fig = plt.figure()
  108. plt.plot([1,2,3,2,3])
  109. # Send the plot
  110. email.send(
  111. subject='A plot',
  112. receivers=['first.last@example.com'],
  113. html="""
  114. <h1>This is a plot:</h1>
  115. {{ my_plot }}
  116. """,
  117. body_images={
  118. 'my_plot': fig,
  119. }
  120. )
  121. The outcome looks like this:
  122. .. image:: /imgs/email_emb_plt.png
  123. :align: center
  124. .. _embedding-images-pil:
  125. Embedding Pillow Image
  126. ^^^^^^^^^^^^^^^^^^^^^^
  127. You may also include Pillow image:
  128. .. code-block:: python
  129. # Create a simple image
  130. from PIL.Image import Image
  131. img = Image.new('RGB', (100, 30), color = (73, 109, 137))
  132. # Send the plot
  133. email.send(
  134. subject='A PIL image',
  135. receivers=['first.last@example.com'],
  136. html="""
  137. <h1>This is a Pillow image:</h1>
  138. {{ my_image }}
  139. """,
  140. body_images={
  141. 'my_image': img,
  142. }
  143. )
  144. .. _embedding-tables:
  145. Embedded Tables
  146. ---------------
  147. You may include tables simply by turning them
  148. to raw HTML for example using ``df.to_html()``
  149. in Pandas. However, this often lead to very
  150. ugly tables as SMTP is poor at handling CSS
  151. or styling in general. Here is a comparison
  152. of using ``df.to_html()`` directly vs embedding
  153. via Red Mail:
  154. |pic1| vs |pic2|
  155. .. |pic1| image:: /imgs/table_without_style.png
  156. :height: 150px
  157. :align: top
  158. .. |pic2| image:: /imgs/table_with_style.png
  159. :height: 150px
  160. :align: top
  161. To embed tables, you can simply pass them
  162. to the send function as Pandas dataframes:
  163. .. code-block:: python
  164. # Creating a simple dataframe
  165. import pandas as pd
  166. df = pd.DataFrame({
  167. 'nums': [1,2,3],
  168. 'strings': ['yes', 'no', 'yes'],
  169. })
  170. # Let Red Mail to render the dataframe for you:
  171. email.send(
  172. subject='A prettified table',
  173. receivers=['first.last@example.com'],
  174. html="<h1>This is a table:</h1> {{ mytable }}",
  175. body_tables={
  176. 'mytable': df,
  177. }
  178. )
  179. Red Mail uses Jinja and inline HTML styling to make the
  180. tables look nice. Email servers typically don't handle
  181. well CSS.
  182. .. warning::
  183. Red Email Pandas templating should work on various
  184. dataframe strucutres (empty, multi-indexed etc.) but
  185. sometimes the rendering may be off if the dataframe
  186. is especially complex in structural sense. There are
  187. plans to make it even more better.
  188. You may also override the template paths (see
  189. :ref:`templating`) to create custom templates
  190. if you wish to make your own table prettifying:
  191. .. code-block:: python
  192. email.set_template_paths(
  193. html_table="path/to/templates",
  194. text_template="path/to/templates"
  195. )
  196. email.default_html_theme = "my_table_template.html"
  197. email.default_text_theme = "my_table_template.txt"
  198. The templates get parameter ``df`` which is the dataframe
  199. to be prettified.