Releases: vgrem/office365-rest-python-client
v 2.4.1
Changelog
- #672: Error handling for when response is not present by @akrymskiy
- #667: add ability to pass b64 formatted string when adding attachments by @padamscrestonecapital
- #666: fix for resetting
ClientResult(return type) between calls when passing toexecute_querymethod by @vgrem - #656: upload session query method compatible with memoryfs python library by @brunoabreu0
- #655: fix for OneDrive example by @GitSumito
v 2.4.0
Changelog
- #641: add bcc and cc support for users.send_mail by @caleb-depotanalytics
- #649: added examples and authentication clarification by @rebeccajhampton
- SharePoint API search namespace enhancements
SharePoint API search namespace enhancements
For methods from SharePoint API search namespace those return type contains value pf SimpleDataTable type, cell values getting addressed like this:
for row in results.Table.Rows:
print(row.Cells["Path"]) # prints cell value for `Path` property Here is an complete example
ctx = ClientContext(site_url).with_credentials(user_credentials)
result = ctx.search.query("contentclass:STS_Site").execute_query()
results = result.value.PrimaryQueryResult.RelevantResults
for row in results.Table.Rows:
print(row.Cells["Path"]) # prints site urlv 2.3.16
Changelog
- OneDrive enhancements in terms of Excel support
Create a new table example
from office365.graph_client import GraphClient
from office365.onedrive.workbooks.tables.rows.row import WorkbookTableRow
file_name = "Financial Sample.xlsx"
client = GraphClient(acquire_token)
workbook = client.me.drive.root.get_by_path(file_name).workbook
table = workbook.tables.add("A1:C10", True).execute_query()List rows example
from office365.graph_client import GraphClient
from office365.onedrive.workbooks.tables.rows.row import WorkbookTableRow
file_name = "Financial Sample.xlsx"
client = GraphClient(acquire_token)
workbook = client.me.drive.root.get_by_path(file_name).workbook
table = workbook.worksheets["Sheet1"].tables["financials"].get().execute_query()
print(table.name)
# read table content
rows = table.rows.get().execute_query()
for r in rows: # type: WorkbookTableRow
print(r.values) v 2.3.15
Changelog
- #569: fix for
ClientRuntimeContext.execute_query_retrymethod by @jneuendorf - #584: escape password in _acquire_service_token_from_adfs-method by @chrisdecker1201
- #568: support for passing private_key into
with_client_certificatemethod - enhancements for SharePoint & OneDrive APIs
Enhancements for SharePoint & OneDrive APIs
Instantiate SharePoint client with certificate credentials
cert_path = 'selfsigncert.pem'
with open(cert_path, 'r') as f:
private_key = open(cert_path).read()
cert_credentials = {
'tenant': test_tenant,
'client_id': '--client id--',
'thumbprint': '--thumbprint--',
'private_key': private_key
}
ctx = ClientContext(test_team_site_url).with_client_certificate(**cert_credentials)Setting image field value
field_value = ImageFieldValue(image_url)
list_item.set_property(field_name, field_value).update().execute_query()v 2.3.14
Changelog
Paged data retrieval enhancements, namely:
- introduction of
ClientObjectCollection.get_allmethod to retrieve all the items in a collection, regardless of the size, for example:
def print_progress(items):
"""
:type items: office365.sharepoint.listitems.collection.ListItemCollection
"""
print("Items read: {0}".format(len(items)))
page_size = 500
ctx = ClientContext(site_url).with_credentials(client_credentials)
large_list = ctx.web.lists.get_by_title(list_title)
all_items = target_list.items.get_all(page_size, print_progress).execute_query()- retrieving paged data via
ClientObjectCollection.pagedmethod
page_size = 500
ctx = ClientContext(site_url).with_credentials(client_credentials)
large_list = ctx.web.lists.get_by_title(list_title)
paged_items = large_list.items.paged(page_size, page_loaded=print_progress).get().execute_query()
for index, item in enumerate(paged_items): # type: int, ListItem
print("{0}: {1}".format(index, item.id))Bug fixes:
v 2.3.13
Changelog
Bug fixes:
- #524: determine and construct the list of properties (including navigation) to be retrieved of
QueryOptions.buildmethod, kudos to @jjloneman - #505: improved file addressing in SharePoint API by @fan-e-cae
- better support for
Sharingnamespace in SharePoint API - introduced support for
Site Designs and Site Scriptsin SharePoint API
Example: Share an anonymous access link with view permissions to a file
ctx = ClientContext(site_url).with_credentials(credentials)
file = ctx.web.get_file_by_server_relative_url(file_url)
result = target_file.share_link(SharingLinkKind.AnonymousView).execute_query()Example: create a new site script that apply a custom theme
ctx = ClientContext(site_url).with_credentials(credentials)
site_script = {
"$schema": "schema.json",
"actions": [
{
"verb": "applyTheme",
"themeName": "Contoso Theme"
}
],
"bindata": {},
"version": 1
}
result = SiteScriptUtility.create_site_script(ctx, "Contoso theme script", "", site_script).execute_query()v 2.3.12
Changelog
SharePoint API:
ListItem.validate_update_list_itemmethod: settingdates_in_utcas an optional parameter (#509)Searchnamespace enhancements #496
Example 1: submit search (KQL) query expression via SearchService.query method
ctx = ClientContext(site_url).with_credentials(credentials)
search = SearchService(ctx)
result = search.query("IsDocument:1").execute_query()Example 2: construct sorting search results query and submit via SearchService.post_query method
ctx = ClientContext(site_url).with_credentials(credentials)
search = SearchService(ctx)
request = SearchRequest(query_text="IsDocument:1",
sort_list=[Sort("LastModifiedTime", 1)],
select_properties=["Path", "LastModifiedTime"],
row_limit=20)
result = search.post_query(request).execute_query()v 2.3.11
Changelog
SharePoint API:
ListItemintroduced support for system metadata update (#330)SiteProperies.updatemethod bug fix #480Web.ensure_folder_pathmethod bug fix #452
Support for ListItem system update
Prefer ListItem.validate_update_list_item method which supports overriding system metadata,
Here is an example which demonstrates how to update list item system metadata (namely Author and Modified field values):
ctx = ClientContext(site_url).with_credentials(credentials)
list_tasks = ctx.web.lists.get_by_title("Tasks")
items = list_tasks.items.get().top(1).execute_query()
if len(items) == 0:
sys.exit("No items for update found")
item_to_update = items[0] # type: ListItem
author = ctx.web.site_users.get_by_email(user_principal_name)
modified_date = datetime.utcnow() - timedelta(days=3)
result = item_to_update.validate_update_list_item({
"Author": FieldUserValue.from_user(author),
"Modified": modified_date
}).execute_query()
has_any_error = any([item.HasException for item in result.value])
if has_any_error:
print("Item update completed with errors, for details refer 'ErrorMessage' property")
else:
print("Item has been updated successfully")v 2.3.10
Changelog
Example:
from office365.graph_client import GraphClient
from office365.onedrive.driveitems.driveItem import DriveItem
def print_download_progress(offset):
print("Downloaded '{0}' bytes...".format(offset))
client = GraphClient(acquire_token_by_username_password)
# # 1. address file by path and get file metadata
file_item = client.me.drive.root.get_by_path("archive/big_buck_bunny.mp4").get().execute_query() # type: DriveItem
# 2 download a large file (chunked file download)
with tempfile.TemporaryDirectory() as local_path:
with open(os.path.join(local_path, file_item.name), 'wb') as local_file:
file_item.download_session(local_file, print_download_progress).execute_query()
print("File '{0}' has been downloaded into {1}".format(file_item.name, local_file.name))-
#430: improved support for overriding underlying HTTP request settings(such as proxy and SSL) by @juguerre
-
#465: SharePoint API: allow passing scopes via certificate authentication method by @theodoriss
Example
from office365.sharepoint.client_context import ClientContext
cert_settings = {
'client_id': '-- app id--',
'thumbprint': "-- cert thumbprint--",
'cert_path': 'mycert.pem'),
'scopes': ['https://contoso.onmicrosoft.com/.default']
}
ctx = ClientContext(test_site_url).with_client_certificate(test_tenant, **cert_settings)
current_web = ctx.web.get().execute_query()
print("{0}".format(current_web.url))-
Microsoft Graph API: Improved support for delta queries (official docs)
Example: get incremental changes for users
client = GraphClient(acquire_token_func)
changed_users = self.client.users.delta.get().execute_query()v 2.3.9
Changelog
List of changes:
- #234: determines if security validation expired and refresh if expired for SharePoint client
- SharePoint API enhanced support for
publishing&webhooksnamespaces - Planner API model has been updated
- Outlook API enhancements, namely the support for download MIME content of a message
SharePoint API: create a Site Page
The example demonstrates how to create a Site Page
ctx = ClientContext(team_site_url).with_credentials(client_credentials)
new_page = ctx.site_pages.pages.add()
new_page.save_draft(title="My news page")
new_page.publish().execute_query()SharePoint API: create a new webhook
The example demonstrates how to create a webhook to SharePoint list:
ctx = ClientContext(site_url).with_credentials(client_credentials)
push_service_url = "https://westeurope0.pushnp.svc.ms/notifications?token=526a9d28-d4ec-45b7-81b9-4e1599524784"
target_list = client.web.lists.get_by_title("Documents")
subscription = target_list.subscriptions.add(push_service_url).execute_query()where
push_service_url - your service endpoint URL. SharePoint sends an HTTP POST to this endpoint when events occur in the specified resource
Refer Overview of SharePoint webhooks for a details.
Planner API: create a task (Create plannerTask endpoint)
from office365.graph_client import GraphClient
client = GraphClient(acquire_token_func)
plan = ensure_plan(client.me.planner, "My plan")
task = client.planner.tasks.add(title="New task", planId=plan.id).execute_query()Outlook API: download MIME content of a message (Get MIME content of a message endpoint)
The example demonstrates how to download an Outlook message body in MIME format and save into a file:
client = GraphClient(acquire_token_func)
# requires Mail.ReadWrite permission
user = client.users[test_user_principal_name]
messages = user.messages.select(["id"]).top(10).get().execute_query()
with tempfile.TemporaryDirectory() as local_path:
for message in messages: # type: Message
with open(os.path.join(local_path, message.id + ".eml"), 'wb') as local_file:
message.download(local_file).execute_query() # download MIME representation of a message