Skip to content

Commit 953cc7a

Browse files
author
Vadim
committed
Add examples: Bookings, To-Do, attack simulation
1 parent b9fd09f commit 953cc7a

6 files changed

Lines changed: 307 additions & 0 deletions

File tree

examples/booking/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Microsoft Bookings
2+
3+
Examples for managing Bookings businesses, services, appointments, staff, and customers.
4+
5+
- [`manage.py`](./manage.py) — List businesses, services, staff availability, create appointments, manage customers
6+
7+
## Prerequisites
8+
9+
| Permission | Description | Reference |
10+
|---|---|---|
11+
| `Bookings.ReadWrite.All` | Read and manage booking businesses, services, staff | [Bookings permissions](https://learn.microsoft.com/en-us/graph/permissions-reference#bookings-permissions) |
12+
| `BookingsAppointment.ReadWrite.All` | Create and manage appointments | [Bookings permissions](https://learn.microsoft.com/en-us/graph/permissions-reference#bookings-permissions) |

examples/booking/manage.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""
2+
Microsoft Bookings — manage businesses, services, appointments,
3+
staff, and customers.
4+
5+
Bookings is Microsoft's appointment scheduling solution. This example
6+
covers the full lifecycle:
7+
- List booking businesses
8+
- List services for a business
9+
- Get staff availability
10+
- Create an appointment
11+
- List customers
12+
13+
Requires delegated permission ``Bookings.ReadWrite.All``,
14+
``BookingsAppointment.ReadWrite.All``.
15+
16+
https://learn.microsoft.com/en-us/graph/api/resources/booking-api-overview
17+
"""
18+
19+
import sys
20+
from datetime import datetime, timedelta, timezone
21+
22+
from office365.graph_client import GraphClient
23+
from tests import test_client_id, test_client_secret, test_tenant
24+
25+
26+
def main():
27+
client = GraphClient(tenant=test_tenant).with_client_secret(test_client_id, test_client_secret)
28+
29+
# -- Step 1: list booking businesses --
30+
businesses = client.solutions.booking_businesses.get().execute_query()
31+
print(f"Booking businesses: {len(businesses)}\n")
32+
33+
for b in businesses:
34+
address = b.address
35+
display = b.display_name or "(unnamed)"
36+
city = address.city if address else "?"
37+
print(f" {display:40s} city={city}")
38+
39+
if not businesses:
40+
print(" (no booking businesses — create one first at https://outlook.office.com/bookings)")
41+
print()
42+
# Create a sample business (commented)
43+
# from office365.booking.business.collection import BookingBusinessCollection
44+
# new_biz = client.solutions.booking_businesses.add(displayName="Demo Consulting").execute_query()
45+
# print(f"Created: {new_biz.display_name}")
46+
return
47+
48+
biz = businesses[0]
49+
print(f"\nInspecting: {biz.display_name}")
50+
print(f" Business hours:")
51+
if biz.business_hours and biz.business_hours.value:
52+
for wh in biz.business_hours.value:
53+
print(f" {wh.properties.get('day', '?'):10s} {wh.properties.get('timeSlots', [])}")
54+
55+
# -- Step 2: list services --
56+
services = biz.services.get().execute_query()
57+
print(f"\n Services ({len(services)}):")
58+
for s in services:
59+
display = s.properties.get("displayName", "?")
60+
duration = s.properties.get("duration", "?")
61+
price = s.properties.get("defaultPrice", "?")
62+
currency = s.properties.get("defaultPriceType", "?")
63+
print(f" {display:35s} duration={duration} price={price} {currency}")
64+
65+
# -- Step 3: get staff availability --
66+
print(f"\n Getting staff availability for next 7 days...")
67+
staff = biz.staff_members.get().execute_query()
68+
print(f" Staff members: {len(staff)}")
69+
for s in staff[:3]:
70+
name = s.properties.get("displayName", "?")
71+
email = s.properties.get("emailAddress", "?")
72+
availability = biz.get_staff_availability(
73+
staff_ids=[s.id],
74+
start_date=datetime.now(timezone.utc),
75+
end_date=datetime.now(timezone.utc) + timedelta(days=7),
76+
).execute_query()
77+
print(f" {name:25s} {email:30s}")
78+
79+
# -- Step 4: create an appointment --
80+
if services:
81+
service = services[0]
82+
now = datetime.now(timezone.utc)
83+
start = now + timedelta(days=1, hours=9)
84+
end = start + timedelta(hours=1)
85+
86+
appointment = biz.appointments.add(
87+
serviceId=service.id,
88+
serviceName=service.properties.get("displayName", "Consultation"),
89+
startDateTime={"dateTime": start.isoformat(), "timeZone": "UTC"},
90+
endDateTime={"dateTime": end.isoformat(), "timeZone": "UTC"},
91+
customerEmail="client@example.com",
92+
customerName="John Doe",
93+
customerPhone="+1 555 123 4567",
94+
additionalInformation="Initial consultation booking via API",
95+
).execute_query()
96+
print(f"\n ✓ Appointment created: {appointment.id}")
97+
98+
# -- Step 5: list customers --
99+
customers = biz.customers.get().execute_query()
100+
print(f"\n Customers: {len(customers)}")
101+
for c in customers:
102+
name = c.properties.get("displayName", "?")
103+
email = c.properties.get("emailAddress", "?")
104+
print(f" {name:30s} {email}")
105+
106+
107+
if __name__ == "__main__":
108+
main()

examples/security/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Security & Attack Simulation
2+
3+
Examples for Microsoft 365 Defender security operations and attack simulation training.
4+
5+
- [`attack_simulation.py`](./attack_simulation.py) — List phishing campaigns, simulation automations, landing pages
6+
7+
## Prerequisites
8+
9+
| Permission | Description | Reference |
10+
|---|---|---|
11+
| `AttackSimulation.Read.All` | Read attack simulation campaigns, automations, payloads | [Attack simulation permissions](https://learn.microsoft.com/en-us/graph/permissions-reference#attack-simulation-permissions) |
12+
| `SecurityEvents.Read.All` | Read security events and alerts | [Security permissions](https://learn.microsoft.com/en-us/graph/permissions-reference#security-permissions) |
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""
2+
Attack simulation training — list phishing simulation campaigns,
3+
automations, payloads, and training assignments.
4+
5+
Attack simulation is part of Microsoft 365 Defender. Security teams
6+
use this to:
7+
- List active and past phishing simulations
8+
- View simulation automations (recurring campaigns)
9+
- Check landing pages configured for the tenant
10+
11+
Requires delegated permission ``AttackSimulation.Read.All`` and
12+
``SecurityEvents.Read.All``.
13+
14+
https://learn.microsoft.com/en-us/graph/api/resources/attacksimulationroot
15+
"""
16+
17+
from office365.graph_client import GraphClient
18+
from tests import test_client_id, test_client_secret, test_tenant
19+
20+
21+
def main():
22+
client = GraphClient(tenant=test_tenant).with_client_secret(test_client_id, test_client_secret)
23+
24+
sim = client.security.attack_simulation
25+
26+
# -- Step 1: list simulations (phishing campaigns) --
27+
simulations = sim.simulations.get().execute_query()
28+
print(f"Attack simulations: {len(simulations)}\n")
29+
30+
for s in simulations:
31+
s_id = s.id or "?"
32+
display = s.properties.get("displayName", s.properties.get("name", "(unnamed)"))
33+
status = s.properties.get("status", "?")
34+
technique = s.properties.get("attackTechnique", "?")
35+
created = s.properties.get("createdDateTime", "?")
36+
if hasattr(created, "strftime"):
37+
created = created.strftime("%Y-%m-%d")
38+
39+
completion = s.properties.get("completionDateTime", "?")
40+
if hasattr(completion, "strftime"):
41+
completion = completion.strftime("%Y-%m-%d")
42+
43+
print(f" {display:50s} status={status:15s} technique={technique:20s} created={created} complete={completion}")
44+
45+
# -- Step 2: list simulation automations (recurring campaigns) --
46+
automations = sim.simulation_automations.get().execute_query()
47+
print(f"\nSimulation automations: {len(automations)}")
48+
49+
for a in automations:
50+
name = a.properties.get("displayName", "(unnamed)")
51+
status = a.properties.get("status", "?")
52+
print(f" {name:50s} status={status}")
53+
54+
# Show automation runs
55+
runs = a.runs.get().execute_query()
56+
for r in runs:
57+
s_id = r.simulation_id or "?"
58+
run_status = r.properties.get("status", "?")
59+
run_dt = r.properties.get("startDateTime", "?")
60+
if hasattr(run_dt, "strftime"):
61+
run_dt = run_dt.strftime("%Y-%m-%d")
62+
print(f" ↳ run: simulation={s_id[:20]} status={run_status} start={run_dt}")
63+
64+
# -- Step 3: list landing pages --
65+
pages = sim.landing_pages.get().execute_query()
66+
print(f"\nLanding pages: {len(pages)}")
67+
for p in pages:
68+
lang = p.properties.get("locale", "?")
69+
status = p.properties.get("status", "?")
70+
print(f" locale={lang:10s} status={status}")
71+
72+
73+
if __name__ == "__main__":
74+
main()

examples/todo/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Microsoft To-Do
2+
3+
Examples for managing personal tasks, task lists, and checklist items.
4+
5+
- [`manage.py`](./manage.py) — List task lists, create tasks with due dates, add checklist items, mark complete
6+
7+
## Prerequisites
8+
9+
| Permission | Description | Reference |
10+
|---|---|---|
11+
| `Tasks.ReadWrite` | Read and manage tasks in To-Do | [Tasks permissions](https://learn.microsoft.com/en-us/graph/permissions-reference#tasks-permissions) |

examples/todo/manage.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Microsoft To-Do — manage task lists, tasks, and checklist items.
3+
4+
To-Do is the personal task management service (different from
5+
Planner, which is team-based). This example covers:
6+
- List task lists
7+
- Create a task with due date and details
8+
- Add checklist items
9+
- Mark a task as complete
10+
- Delete a task
11+
12+
Requires delegated permission ``Tasks.ReadWrite``.
13+
14+
https://learn.microsoft.com/en-us/graph/api/resources/todo-overview
15+
"""
16+
17+
import sys
18+
from datetime import datetime, timedelta, timezone
19+
20+
from office365.graph_client import GraphClient
21+
from tests import test_client_id, test_client_secret, test_tenant
22+
23+
24+
def main():
25+
client = GraphClient(tenant=test_tenant).with_client_secret(test_client_id, test_client_secret)
26+
27+
# -- Step 1: list task lists --
28+
lists = client.me.todo.lists.get().execute_query()
29+
print(f"Task lists: {len(lists)}\n")
30+
31+
for lst in lists:
32+
print(f" {lst.display_name:40s} id={lst.id[:15]}...")
33+
34+
# -- Step 2: create or find a task list --
35+
target_list_name = "SDK Demo Tasks"
36+
task_list = next((lst for lst in lists if lst.display_name == target_list_name), None)
37+
38+
if task_list is None:
39+
task_list = client.me.todo.lists.add(displayName=target_list_name).execute_query()
40+
print(f"Created task list: '{task_list.display_name}'")
41+
else:
42+
print(f"Using existing task list: '{task_list.display_name}'")
43+
44+
# -- Step 3: create a task with due date --
45+
due = (datetime.now(timezone.utc) + timedelta(days=3)).isoformat()
46+
task = task_list.tasks.add(
47+
title="Review SDK documentation",
48+
dueDateTime={"dateTime": due, "timeZone": "UTC"},
49+
importance="high",
50+
body={"content": "Final review before release.", "contentType": "text"},
51+
).execute_query()
52+
print(f"\nCreated task: '{task.title}'")
53+
print(f" Due: {task.due_date_time.strftime('%Y-%m-%d %H:%M') if task.due_date_time else '?'}")
54+
print(f" Importance: {task.properties.get('importance', '?')}")
55+
56+
# -- Step 4: add checklist items --
57+
checklist = [
58+
{"title": "Check all examples parse", "isChecked": False},
59+
{"title": "Verify Graph API permissions", "isChecked": False},
60+
{"title": "Test with client credentials", "isChecked": True},
61+
]
62+
63+
for item in checklist:
64+
cl_item = task.checklist_items.add(
65+
title=item["title"],
66+
isChecked=item["isChecked"],
67+
).execute_query()
68+
print(f" Checklist: {cl_item.title} {'✓' if cl_item.is_checked else '☐'}")
69+
70+
# -- Step 5: list all tasks --
71+
all_tasks = task_list.tasks.get().execute_query()
72+
print(f"\nAll tasks in '{task_list.display_name}' ({len(all_tasks)}):")
73+
for t in all_tasks:
74+
title = t.title or "(untitled)"
75+
status = t.properties.get("status", "?")
76+
due_str = t.due_date_time.strftime("%Y-%m-%d") if t.due_date_time else ""
77+
print(f" [{status:10s}] {title:40s} {due_str}")
78+
79+
# -- Step 6: complete the task --
80+
task.set_property("status", "completed")
81+
task.update().execute_query()
82+
print(f"\n✓ Task '{task.title}' marked as completed.")
83+
84+
# -- Step 7: delete the task list (commented) --
85+
# task_list.delete_object().execute_query()
86+
# print(f"Deleted task list: '{task_list.display_name}'")
87+
88+
89+
if __name__ == "__main__":
90+
main()

0 commit comments

Comments
 (0)