Report Automation with Python and PyMsTeams
In this article, I’ll show how to create beautiful reports with pymsteams, a package to send requests to Microsoft Teams Webhooks. We’ll explore an end-to-end example with a Stock Market report example.
Create Team in MS Teams
First of all, we need a Team with channel where we can send information in an automated way:
Define the team's name and description
By default, MS Teams creates the general channel. We’re going to use this channel to post the reports, but you can create a new channel and use it for this example.
Create connector in MS Teams
- Go to connectors
2. Search for “Incoming Webhook” and click on “add”
3. Click on Configure the connector
4. Define the name and image of the connector. On a personal whim, I decided to create the image with bing create with the prompt: “Microsoft corporate bot with cyberpunk and epic cartoon style” and use the “msteams-webhook” name for the incoming webhook.
5. Click on Create and you’ll get an URL, save it, we’ll need it later. The URL should be similar to this one:
https://<your-org-domain>.webhook.office.com/webhookb2/1a0a9550-99bd-4ba1-a73f-c64832e636d9@daf7990e-8a3f-409c-9b76-2a5475098000/IncomingWebhook/ef2eac97e22445d4b6b73026d0aaced7/ced8b42e-8c9f-4895-a1f7-3fcd6ad42c55
You’ll see this in the team channel
Python Automation
Now, Imagine we want to generate a report with Stock Market daily information (Close price, price variation, and Traded volume). To keep the exercise simple we only include three stocks: “AAPL”, “MSFT”, and “TSLA”. First, we need to install the libraries pymsteams
and pandas-datareader
pip install pymsteams pandas-datareader
Import python packages and define variables. We also import datetime
python built-in package to make easier the date manipulation we do.
import pymsteams
from datetime import datetime
import pandas_datareader.data as web
WEBHOOK_NAME = "msteams-webhook"
WEBHOOK_URL = "https://<your-org-domain>.webhook.office.com/webhookb2/1a0a9550-99bd-4ba1-a73f-c64832e636d9@daf7990e-8a3f-409c-9b76-2a5475098000/IncomingWebhook/ef2eac97e22445d4b6b73026d0aaced7/ced8b42e-8c9f-4895-a1f7-3fcd6ad42c55"
SYMBOLS = ["AAPL", "MSFT", "TSLA"]
In order to create the report in python in one code snippet, I’ll explain first the steps:
- Iterate each stock and get the data from Yahoo Finance and calculate the percentage variation on the close price.
- Create the variables
close_price
,p_variation
andvolume
. - Create the content by stock (we use markdown syntax to make look prettier the report)
- Create the PyMsTeams section, adding an image from Flaticon
- Create the
stock_report
as pymsteams connector card, with the Webhook URL we define above - Add content to the connector card, like title and text, and finally, we add the pymsteams sections stored in the
report_sections
python list - Send the report to the MS Teams channel
report_sections = []
for symbol in SYMBOLS:
print(f"Preparing report for {symbol}")
# Get stock information from yahoo finance
data = web.get_data_yahoo(symbol,end=datetime.today())
data["pct_change"] = data["Close"].pct_change()
data = data.tail(1)
# calculate report data
variation = round(data['pct_change'][0], 4) * 100
if variation < 0:
p_variation = f'<span style="color:#D61355">{variation}%</span>'
else:
p_variation = f'<span style="color:#1F8A70">{variation}%</span>'
close_price = f"${round(data['Close'][0], 4)}"
volume = f"{round(data['Volume'][0], 4):,}"
# Prepare section content
text_ = f"""
* **Stock Name**: {symbol}
* **Close price**: { close_price }
* **Price variation**: **{ p_variation }**
* **Volume**: { volume }
"""
message_section = pymsteams.cardsection()
message_section.activityTitle(symbol) # Define section title
message_section.activityImage("https://cdn-icons-png.flaticon.com/512/10310/10310226.png")
message_section.activityText(text_) # Insert markdown text
report_sections.append(message_section)
stocks_report = pymsteams.connectorcard(hookurl=WEBHOOK_URL)
stocks_report.title(f"PYMSTEAMS AUTOMATED DAILY STOCK REPORT 🗠")
stocks_report.text(f"""
Report automatically generated by `{WEBHOOK_NAME}`
* **Date**: { datetime.today().strftime('%Y-%m-%d') }
""")
for section in report_sections:
stocks_report.addSection(section)
stocks_report.color("#0F6292")
stocks_report.send()
Another style decision I made was changing the color of the percentage change depending if it is positive (green)or negative (red) using some HTML code in the markdown text_
variable I created by stock.
The final daily report will look like this:
And of course, You can expand the scope or content of the report by exploring the pymsteams library objects (or preparing HTTP requests directly, here Microsfot docs) and improving the style with more sophisticated markdown styles.