When periodic reports need to be shared in dedicated spaces, managing documents manually can quickly become a significant burden. Every reporting cycle involves generating and uploading files to multiple SharePoint folders, a time-consuming process that’s also prone to human error. The main challenge lies in handling SharePoint tasks manually, which affects efficiency, consistency, and makes it harder to scale since over time the quantity of reports grows and the number recipients might increase.
To address this issue, we’ve implemented an automated solution leveraging Python and the Microsoft Graph API, allowing for example the periodic reports described in previous articles about Vulnerability Management and External Attack Surface Management to be generated and distributed efficiently using Python.
This approach enables reliable, repeatable, and precise report distribution among the Business Partners of the Würth Group, significantly reducing manual effort while improving accuracy, scalability and overall operational efficiency.
Let’s take a closer look at how the workflow is defined. The operational flow is structured this way:
The following code snippet shows at a high level the core logic used to authenticate, retrieve the SharePoint location, and upload the report.
import msal
import requests
# Configuration
tenant_id = "YOUR_TENANT_ID"
client_id = "YOUR_CLIENT_ID"
authority = f"https://login.microsoftonline.com/{tenant_id}"
certificate_path = "path/to/your/private.key"
thumbprint = "YOUR_CERT_THUMBPRINT"
site_name = "YOUR_SITE_NAME"
site_domain = "YOUR_SITE_DOMAIN"
file_path = "path/to/your/file/report.pdf"
# Authenticate with MS Graph API
scope = ["https://graph.microsoft.com/.default"]
app = msal.ConfidentialClientApplication(
client_id=client_id,
authority=authority,
client_credential={"private_key": open(certificate_path).read(), "thumbprint": thumbprint}
)
# Acquire token
token_response = app.acquire_token_for_client(scopes=scope)
access_token = token_response.get("access_token")
# Get Site ID and Drive ID
header = {"Authorization": f"Bearer {access_token}"}
response=requests.get(url="https://graph.microsoft.com/v1.0/sites/{site_domain}:/sites/{site_name}", headers=header)
site_id = response.json()["id"]
response = requests.get(url="https://graph.microsoft.com/v1.0/sites/{site_id}/drives", headers=header)
for drive in response.json()["value"]:
if drive["name"] == "{your_drive_name}":
drive_id = drive["id"]
break
file_name="{path/to/your/file/on/SharePoint}"
# Upload to SharePoint
with Path.open(file_path, "rb") as f:
file_content = f.read()
header = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/pdf",
}
response = requests.put(url="https://graph.microsoft.com/v1.0/sites/{site_id}/drives/{drive_id}/root:/{file_name}:/content", headers=header, data=file_content)
The automated report sharing solution described above brings clear benefits for managing periodic reports across multiple companies in the group. To conclude, some of the key advantages include:
Overall, this solution provides a robust, efficient, and scalable way to manage report distribution, creating a solid foundation for further automation and process improvement.
Did you find this article interesting? Does it match your skill set? Our customers often present us with problems that need customized solutions. In fact, we’re currently hiring for roles just like this and others here at Würth IT Italy.