Microsoft 365 & Microsoft Graph Library for Python
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete Azure Active Directory management through Microsoft Graph API including users, groups, applications, devices, and organizational relationships. Provides comprehensive identity and access management capabilities for enterprise environments.
Complete user lifecycle management including creation, updates, deletion, and property management with support for user profiles, authentication methods, and organizational relationships.
class User:
"""Azure AD user entity with comprehensive profile and management capabilities."""
# Core Properties
id: str
display_name: str
mail: str
user_principal_name: str
given_name: str
surname: str
mobile_phone: str
office_location: str
preferred_language: str
job_title: str
department: str
company_name: str
account_enabled: bool
creation_type: str
def get(self) -> 'User':
"""
Retrieve user information from Azure AD.
Returns:
User: Updated user object with current data
"""
def update(self) -> 'User':
"""
Update user properties in Azure AD.
Returns:
User: Updated user object
"""
def delete(self) -> None:
"""Delete user from Azure AD."""
def change_password(self, current_password: str, new_password: str) -> None:
"""
Change user's password.
Args:
current_password (str): Current password
new_password (str): New password
"""
def revoke_sign_in_sessions(self) -> None:
"""Revoke all user sign-in sessions."""
# Navigation Properties
@property
def manager(self) -> 'User':
"""User's manager."""
@property
def direct_reports(self) -> 'UserCollection':
"""Users who report to this user."""
@property
def member_of(self) -> 'GroupCollection':
"""Groups the user is a member of."""
@property
def owned_devices(self) -> 'DeviceCollection':
"""Devices owned by the user."""
@property
def registered_devices(self) -> 'DeviceCollection':
"""Devices registered by the user."""
class UserCollection:
"""Collection of Azure AD users with query and management capabilities."""
def get(self) -> 'UserCollection':
"""Retrieve collection of users."""
def filter(self, expression: str) -> 'UserCollection':
"""
Filter users by OData expression.
Args:
expression (str): OData filter expression
Returns:
UserCollection: Filtered collection
"""
def select(self, properties: List[str]) -> 'UserCollection':
"""
Select specific properties to retrieve.
Args:
properties (List[str]): Property names to select
Returns:
UserCollection: Collection with selected properties
"""
def top(self, count: int) -> 'UserCollection':
"""
Limit results to top N users.
Args:
count (int): Maximum number of users to return
Returns:
UserCollection: Limited collection
"""
def get_by_id(self, user_id: str) -> User:
"""
Get user by ID.
Args:
user_id (str): User's object ID
Returns:
User: User object
"""
def add(self, user_creation_info: Dict[str, Any]) -> User:
"""
Create new user.
Args:
user_creation_info (Dict): User properties for creation
Returns:
User: Created user object
"""Comprehensive group management including security groups, distribution lists, Microsoft 365 groups, and group membership operations with support for dynamic membership rules.
class Group:
"""Azure AD group entity with membership and settings management."""
# Core Properties
id: str
display_name: str
description: str
mail: str
mail_nickname: str
group_types: List[str]
security_enabled: bool
mail_enabled: bool
visibility: str
def get(self) -> 'Group':
"""
Retrieve group information from Azure AD.
Returns:
Group: Updated group object
"""
def update(self) -> 'Group':
"""
Update group properties.
Returns:
Group: Updated group object
"""
def delete(self) -> None:
"""Delete group from Azure AD."""
def add_member(self, user_id: str) -> None:
"""
Add user to group.
Args:
user_id (str): User's object ID
"""
def remove_member(self, user_id: str) -> None:
"""
Remove user from group.
Args:
user_id (str): User's object ID
"""
def add_owner(self, user_id: str) -> None:
"""
Add group owner.
Args:
user_id (str): User's object ID
"""
def remove_owner(self, user_id: str) -> None:
"""
Remove group owner.
Args:
user_id (str): User's object ID
"""
# Navigation Properties
@property
def members(self) -> 'DirectoryObjectCollection':
"""Group members (users, groups, service principals)."""
@property
def owners(self) -> 'DirectoryObjectCollection':
"""Group owners."""
@property
def team(self) -> 'Team':
"""Associated Microsoft Teams team (for Microsoft 365 groups)."""
class GroupCollection:
"""Collection of Azure AD groups with query and management capabilities."""
def get(self) -> 'GroupCollection':
"""Retrieve collection of groups."""
def filter(self, expression: str) -> 'GroupCollection':
"""
Filter groups by OData expression.
Args:
expression (str): OData filter expression
Returns:
GroupCollection: Filtered collection
"""
def get_by_id(self, group_id: str) -> Group:
"""
Get group by ID.
Args:
group_id (str): Group's object ID
Returns:
Group: Group object
"""
def add(self, group_creation_info: Dict[str, Any]) -> Group:
"""
Create new group.
Args:
group_creation_info (Dict): Group properties for creation
Returns:
Group: Created group object
"""Azure AD application registration and service principal management with support for API permissions, secrets, certificates, and application settings.
class Application:
"""Azure AD application registration with configuration and credential management."""
# Core Properties
id: str
app_id: str
display_name: str
description: str
sign_in_audience: str
publisher_domain: str
homepage: str
identifier_uris: List[str]
reply_urls: List[str]
required_resource_access: List[Dict[str, Any]]
def get(self) -> 'Application':
"""
Retrieve application information.
Returns:
Application: Updated application object
"""
def update(self) -> 'Application':
"""
Update application properties.
Returns:
Application: Updated application object
"""
def delete(self) -> None:
"""Delete application registration."""
def add_password(self, display_name: str, end_date_time: str = None) -> Dict[str, str]:
"""
Add client secret to application.
Args:
display_name (str): Secret display name
end_date_time (str, optional): Expiration date (ISO 8601)
Returns:
Dict containing secretText and keyId
"""
def remove_password(self, key_id: str) -> None:
"""
Remove client secret from application.
Args:
key_id (str): Secret key ID
"""
def add_key(self, key_credential: Dict[str, Any]) -> None:
"""
Add certificate key to application.
Args:
key_credential (Dict): Certificate key credential
"""
def remove_key(self, key_id: str, proof: str) -> None:
"""
Remove certificate key from application.
Args:
key_id (str): Key ID
proof (str): Proof of possession token
"""
class ApplicationCollection:
"""Collection of Azure AD applications with query and management capabilities."""
def get(self) -> 'ApplicationCollection':
"""Retrieve collection of applications."""
def filter(self, expression: str) -> 'ApplicationCollection':
"""
Filter applications by OData expression.
Args:
expression (str): OData filter expression
Returns:
ApplicationCollection: Filtered collection
"""
def get_by_id(self, app_id: str) -> Application:
"""
Get application by ID.
Args:
app_id (str): Application object ID
Returns:
Application: Application object
"""
def add(self, app_creation_info: Dict[str, Any]) -> Application:
"""
Create new application registration.
Args:
app_creation_info (Dict): Application properties for creation
Returns:
Application: Created application object
"""
class ServicePrincipal:
"""Service principal entity representing application instance in tenant."""
# Core Properties
id: str
app_id: str
display_name: str
service_principal_type: str
account_enabled: bool
app_role_assignment_required: bool
publisher_name: str
def get(self) -> 'ServicePrincipal':
"""
Retrieve service principal information.
Returns:
ServicePrincipal: Updated service principal object
"""
def update(self) -> 'ServicePrincipal':
"""
Update service principal properties.
Returns:
ServicePrincipal: Updated service principal object
"""
def delete(self) -> None:
"""Delete service principal."""
# Navigation Properties
@property
def app_role_assignments(self) -> 'AppRoleAssignmentCollection':
"""App role assignments for this service principal."""
@property
def oauth2_permission_grants(self) -> 'OAuth2PermissionGrantCollection':
"""OAuth2 permission grants for this service principal."""Azure AD device registration and management with support for device compliance, configuration, and lifecycle operations.
class Device:
"""Azure AD registered device with management and compliance capabilities."""
# Core Properties
id: str
device_id: str
display_name: str
operating_system: str
operating_system_version: str
device_version: int
device_metadata: str
device_category: str
device_ownership: str
enrollment_type: str
is_compliant: bool
is_managed: bool
on_premises_last_sync_date_time: str
trust_type: str
management_type: str
def get(self) -> 'Device':
"""
Retrieve device information.
Returns:
Device: Updated device object
"""
def update(self) -> 'Device':
"""
Update device properties.
Returns:
Device: Updated device object
"""
def delete(self) -> None:
"""Delete device registration."""
# Navigation Properties
@property
def registered_owners(self) -> 'DirectoryObjectCollection':
"""Users who are registered owners of the device."""
@property
def registered_users(self) -> 'DirectoryObjectCollection':
"""Users who are registered users of the device."""
class DeviceCollection:
"""Collection of Azure AD devices with query and management capabilities."""
def get(self) -> 'DeviceCollection':
"""Retrieve collection of devices."""
def filter(self, expression: str) -> 'DeviceCollection':
"""
Filter devices by OData expression.
Args:
expression (str): OData filter expression
Returns:
DeviceCollection: Filtered collection
"""
def get_by_id(self, device_id: str) -> Device:
"""
Get device by ID.
Args:
device_id (str): Device object ID
Returns:
Device: Device object
"""Base directory object functionality providing common operations for all Azure AD objects including users, groups, applications, and service principals.
class DirectoryObject:
"""Base class for all Azure AD directory objects."""
# Core Properties
id: str
deleted_date_time: str
def get(self) -> 'DirectoryObject':
"""
Retrieve directory object information.
Returns:
DirectoryObject: Updated object
"""
def delete(self) -> None:
"""Delete directory object."""
def restore(self) -> 'DirectoryObject':
"""
Restore deleted directory object.
Returns:
DirectoryObject: Restored object
"""
def check_member_groups(self, group_ids: List[str]) -> List[str]:
"""
Check if object is member of specified groups.
Args:
group_ids (List[str]): Group object IDs to check
Returns:
List[str]: Group IDs where object is a member
"""
def get_member_groups(self, security_enabled_only: bool = False) -> List[str]:
"""
Get groups the object is a member of.
Args:
security_enabled_only (bool): Return only security-enabled groups
Returns:
List[str]: Group object IDs
"""
def get_member_objects(self, security_enabled_only: bool = False) -> List[str]:
"""
Get all groups and directory roles the object is a member of.
Args:
security_enabled_only (bool): Return only security-enabled objects
Returns:
List[str]: Object IDs of groups and roles
"""
class DirectoryObjectCollection:
"""Collection of directory objects with query capabilities."""
def get(self) -> 'DirectoryObjectCollection':
"""Retrieve collection of directory objects."""
def filter(self, expression: str) -> 'DirectoryObjectCollection':
"""
Filter objects by OData expression.
Args:
expression (str): OData filter expression
Returns:
DirectoryObjectCollection: Filtered collection
"""
def get_by_ids(self, ids: List[str], types: List[str] = None) -> 'DirectoryObjectCollection':
"""
Get directory objects by their IDs.
Args:
ids (List[str]): Object IDs to retrieve
types (List[str], optional): Object types to filter by
Returns:
DirectoryObjectCollection: Retrieved objects
"""from office365.graph_client import GraphClient
client = GraphClient.with_client_secret(client_id, client_secret, tenant)
# Get all users
users = client.users.get().execute_query()
for user in users:
print(f"{user.display_name} ({user.user_principal_name})")
# Get specific user
user = client.users.get_by_id("user-object-id").get().execute_query()
print(f"User: {user.display_name}, Email: {user.mail}")
# Filter users by department
finance_users = client.users.filter("department eq 'Finance'").get().execute_query()
# Create new user
new_user_info = {
"accountEnabled": True,
"displayName": "John Doe",
"mailNickname": "johndoe",
"userPrincipalName": "johndoe@domain.com",
"passwordProfile": {
"forceChangePasswordNextSignIn": True,
"password": "TempPassword123!"
}
}
new_user = client.users.add(new_user_info).execute_query()
# Update user properties
user.job_title = "Senior Developer"
user.department = "Engineering"
user.update().execute_query()# Get all groups
groups = client.groups.get().execute_query()
# Get specific group
group = client.groups.get_by_id("group-object-id").get().execute_query()
# Create Microsoft 365 group
new_group_info = {
"displayName": "Marketing Team",
"description": "Marketing team collaboration group",
"mailNickname": "marketing-team",
"mailEnabled": True,
"securityEnabled": False,
"groupTypes": ["Unified"]
}
new_group = client.groups.add(new_group_info).execute_query()
# Add members to group
group.add_member("user-object-id")
client.execute_query()
# Get group members
members = group.members.get().execute_query()
for member in members:
print(f"Member: {member.display_name}")# Get all applications
apps = client.applications.get().execute_query()
# Create new application
app_info = {
"displayName": "My API Application",
"signInAudience": "AzureADMyOrg",
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000", # Microsoft Graph
"resourceAccess": [
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", # User.Read
"type": "Scope"
}
]
}
]
}
new_app = client.applications.add(app_info).execute_query()
# Add client secret
secret = new_app.add_password("My Client Secret").execute_query()
print(f"Client Secret: {secret.value.secret_text}")from typing import List, Dict, Any, Optional
class PasswordProfile:
"""User password profile configuration."""
force_change_password_next_sign_in: bool
force_change_password_next_sign_in_with_mfa: bool
password: str
class ResourceAccess:
"""API permission resource access definition."""
id: str # Permission ID
type: str # "Role" or "Scope"
class RequiredResourceAccess:
"""Required API permissions for application."""
resource_app_id: str # Resource application ID (e.g., Microsoft Graph)
resource_access: List[ResourceAccess] # List of required permissions
class KeyCredential:
"""Certificate key credential for application."""
key_id: str
type: str # "AsymmetricX509Cert"
usage: str # "Verify"
key: bytes # Certificate public key
display_name: str
start_date_time: str
end_date_time: str
class PasswordCredential:
"""Password credential (client secret) for application."""
key_id: str
display_name: str
secret_text: str
start_date_time: str
end_date_time: str
class AppRoleAssignment:
"""Application role assignment to user, group, or service principal."""
id: str
app_role_id: str
principal_id: str
principal_type: str
resource_id: strInstall with Tessl CLI
npx tessl i tessl/pypi-office365-rest-python-client