Skip to content

Commit 0b3eb3e

Browse files
committed
Examples updates for working with attachments (SP API)
1 parent 37e3b29 commit 0b3eb3e

File tree

10 files changed

+87
-45
lines changed

10 files changed

+87
-45
lines changed

examples/onedrive/lists/get_props.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
from tests import test_client_id, test_client_secret, test_tenant
99

1010
client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret)
11-
lib = client.sites.root.lists["Documents"].get().execute_query()
11+
# lib = client.sites.root.lists["Documents"].get().execute_query()
12+
lib = client.sites.root.lists.get_by_name("Documents").get().execute_query()
1213
print(lib.web_url)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""
2+
Deletes attachments from a List
3+
"""
4+
from office365.sharepoint.client_context import ClientContext
5+
from tests import test_client_credentials, test_team_site_url
6+
7+
ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
8+
list_title = "Company Tasks"
9+
tasks_list = ctx.web.lists.get_by_title(list_title)
10+
task_items = tasks_list.items.get().execute_query()
11+
for task_item in task_items:
12+
task_item.attachment_files.delete_all().execute_query()
13+
print("Attachments have been deleted for list item {0}".format(task_item.id))
14+

examples/sharepoint/listitems/attachments/upload.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
# 1. create a new list item
1313
task_item = tasks_list.add_item({"Title": "New Task"}).execute_query()
1414

15-
# task_item.attachment_files.delete_all().execute_query()
16-
1715
# 2. read & upload attachment for a list item
18-
path = "../../../data/Financial Sample.xlsx"
19-
with open(path, "rb") as f:
16+
paths = ["../../../data/Financial Sample.xlsx", "../../../data/countries.json"]
17+
18+
with open(paths[0], "rb") as f:
2019
attachment = task_item.attachment_files.upload(f).execute_query()
2120
print(attachment)

generator/metadata/MicrosoftGraph.xml

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21739,6 +21739,8 @@
2173921739
<Member Name="unknownFutureValue" Value="5"/>
2174021740
<Member Name="teamifyGroup" Value="6"/>
2174121741
<Member Name="createChannel" Value="7"/>
21742+
<Member Name="archiveChannel" Value="8"/>
21743+
<Member Name="unarchiveChannel" Value="9"/>
2174221744
</EnumType>
2174321745
<EnumType Name="teamSpecialization">
2174421746
<Member Name="none" Value="0"/>
@@ -24956,6 +24958,7 @@
2495624958
<Property Name="description" Type="Edm.String"/>
2495724959
<Property Name="displayName" Type="Edm.String" Nullable="false"/>
2495824960
<Property Name="email" Type="Edm.String"/>
24961+
<Property Name="isArchived" Type="Edm.Boolean"/>
2495924962
<Property Name="isFavoriteByDefault" Type="Edm.Boolean"/>
2496024963
<Property Name="membershipType" Type="graph.channelMembershipType"/>
2496124964
<Property Name="summary" Type="graph.channelSummary"/>
@@ -39082,6 +39085,10 @@
3908239085
<Parameter Name="messageIds" Type="Collection(Edm.String)" Unicode="false"/>
3908339086
<ReturnType Type="Edm.Boolean"/>
3908439087
</Action>
39088+
<Action Name="archive" IsBound="true">
39089+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39090+
<Parameter Name="shouldSetSpoSiteReadOnlyForMembers" Type="Edm.Boolean"/>
39091+
</Action>
3908539092
<Action Name="archive" IsBound="true">
3908639093
<Parameter Name="bindingParameter" Type="graph.team"/>
3908739094
<Parameter Name="shouldSetSpoSiteReadOnlyForMembers" Type="Edm.Boolean"/>
@@ -39106,6 +39113,9 @@
3910639113
<Parameter Name="messageIds" Type="Collection(Edm.String)" Unicode="false"/>
3910739114
<ReturnType Type="Edm.Boolean"/>
3910839115
</Action>
39116+
<Action Name="unarchive" IsBound="true">
39117+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39118+
</Action>
3910939119
<Action Name="unarchive" IsBound="true">
3911039120
<Parameter Name="bindingParameter" Type="graph.team"/>
3911139121
</Action>
@@ -39382,6 +39392,32 @@
3938239392
<Action Name="reauthorize" IsBound="true">
3938339393
<Parameter Name="bindingParameter" Type="graph.subscription"/>
3938439394
</Action>
39395+
<Action Name="completeMigration" IsBound="true">
39396+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39397+
</Action>
39398+
<Action Name="completeMigration" IsBound="true">
39399+
<Parameter Name="bindingParameter" Type="graph.team"/>
39400+
</Action>
39401+
<Action Name="provisionEmail" IsBound="true">
39402+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39403+
<ReturnType Type="graph.provisionChannelEmailResult"/>
39404+
</Action>
39405+
<Action Name="removeEmail" IsBound="true">
39406+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39407+
</Action>
39408+
<Function Name="doesUserHaveAccess" IsBound="true">
39409+
<Parameter Name="bindingParameter" Type="graph.channel"/>
39410+
<Parameter Name="userId" Type="Edm.String" Unicode="false">
39411+
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39412+
</Parameter>
39413+
<Parameter Name="tenantId" Type="Edm.String" Unicode="false">
39414+
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39415+
</Parameter>
39416+
<Parameter Name="userPrincipalName" Type="Edm.String" Unicode="false">
39417+
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39418+
</Parameter>
39419+
<ReturnType Type="Edm.Boolean" Nullable="false"/>
39420+
</Function>
3938539421
<Action Name="clone" IsBound="true">
3938639422
<Parameter Name="bindingParameter" Type="graph.team"/>
3938739423
<Parameter Name="displayName" Type="Edm.String" Unicode="false"/>
@@ -39391,12 +39427,6 @@
3939139427
<Parameter Name="visibility" Type="graph.teamVisibilityType" Nullable="false"/>
3939239428
<Parameter Name="partsToClone" Type="graph.clonableTeamParts" Nullable="false"/>
3939339429
</Action>
39394-
<Action Name="completeMigration" IsBound="true">
39395-
<Parameter Name="bindingParameter" Type="graph.team"/>
39396-
</Action>
39397-
<Action Name="completeMigration" IsBound="true">
39398-
<Parameter Name="bindingParameter" Type="graph.channel"/>
39399-
</Action>
3940039430
<Action Name="sendActivityNotification" IsBound="true">
3940139431
<Parameter Name="bindingParameter" Type="graph.team"/>
3940239432
<Parameter Name="topic" Type="graph.teamworkActivityTopic"/>
@@ -39426,26 +39456,6 @@
3942639456
<Parameter Name="teamsAppId" Type="Edm.String" Unicode="false"/>
3942739457
<Parameter Name="templateParameters" Type="Collection(graph.keyValuePair)"/>
3942839458
</Action>
39429-
<Action Name="provisionEmail" IsBound="true">
39430-
<Parameter Name="bindingParameter" Type="graph.channel"/>
39431-
<ReturnType Type="graph.provisionChannelEmailResult"/>
39432-
</Action>
39433-
<Action Name="removeEmail" IsBound="true">
39434-
<Parameter Name="bindingParameter" Type="graph.channel"/>
39435-
</Action>
39436-
<Function Name="doesUserHaveAccess" IsBound="true">
39437-
<Parameter Name="bindingParameter" Type="graph.channel"/>
39438-
<Parameter Name="userId" Type="Edm.String" Unicode="false">
39439-
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39440-
</Parameter>
39441-
<Parameter Name="tenantId" Type="Edm.String" Unicode="false">
39442-
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39443-
</Parameter>
39444-
<Parameter Name="userPrincipalName" Type="Edm.String" Unicode="false">
39445-
<Annotation Term="Org.OData.Core.V1.OptionalParameter"/>
39446-
</Parameter>
39447-
<ReturnType Type="Edm.Boolean" Nullable="false"/>
39448-
</Function>
3944939459
<Action Name="hideForUser" IsBound="true">
3945039460
<Parameter Name="bindingParameter" Type="graph.chat"/>
3945139461
<Parameter Name="user" Type="graph.teamworkUserIdentity"/>

office365/onedrive/lists/collection.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ def add(self, display_name, list_template="genericList"):
2626
qry = CreateEntityQuery(self, payload, return_type)
2727
self.context.add_query(qry)
2828
return return_type
29+
30+
def get_by_name(self, name):
31+
return List(self.context, EntityPath(name, self.resource_path))
32+
33+
def get_by_id(self, list_id):
34+
return List(self.context, EntityPath(list_id, self.resource_path))

office365/outlook/category.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Optional
2+
13
from office365.entity import Entity
24

35

@@ -6,13 +8,18 @@ class OutlookCategory(Entity):
68
The user defines categories in a master list, and can apply one or more
79
of these user-defined categories to an item."""
810

11+
def __str__(self):
12+
return self.display_name or self.entity_type_name
13+
914
@property
1015
def color(self):
16+
# type: () -> Optional[str]
1117
"""A pre-set color constant that characterizes a category, and that is mapped to one of 25 predefined colors"""
1218
return self.properties.get("color", None)
1319

1420
@property
1521
def display_name(self):
22+
# type: () -> Optional[str]
1623
"""A unique name that identifies a category in the user's mailbox.
1724
After a category is created, the name cannot be changed"""
1825
return self.properties.get("displayName", None)

office365/sharepoint/attachments/attachment.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from typing import AnyStr, Optional
1+
from typing import AnyStr, Optional, IO
2+
3+
from typing_extensions import Self
24

35
from office365.runtime.client_result import ClientResult
46
from office365.runtime.queries.function import FunctionQuery
@@ -58,6 +60,7 @@ def recycle_object(self):
5860
return self
5961

6062
def upload(self, file_object, use_path=True):
63+
# type: (IO, bool) -> Self
6164
"""
6265
Upload attachment into list item
6366
@@ -99,7 +102,7 @@ def file_name_as_path(self):
99102
@property
100103
def server_relative_url(self):
101104
# type: () -> Optional[str]
102-
""" """
105+
""" The server-relative-url of the attachment """
103106
return self.properties.get("ServerRelativeUrl", None)
104107

105108
@property

office365/sharepoint/attachments/collection.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def _delete_all(return_type):
7979
return self
8080

8181
def download(self, download_file, file_downloaded=None):
82-
# type: (IO, Optional[Callable[[], None]]) -> Self
82+
# type: (IO, Optional[Callable[[Attachment], None]]) -> Self
8383
"""Downloads attachments as a zip file"""
8484
import zipfile
8585

@@ -101,9 +101,7 @@ def _download(return_type):
101101

102102
def upload(self, file, use_path=True):
103103
# type: (IO, bool) -> Attachment
104-
"""
105-
Uploads the attachment
106-
"""
104+
""" Uploads the attachment """
107105
info = AttachmentCreationInformation(os.path.basename(file.name), file.read())
108106
if use_path:
109107
return self.add_using_path(info.filename, info.content)
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1+
from typing import IO, TYPE_CHECKING
2+
13
from office365.runtime.http.http_method import HttpMethod
4+
from office365.runtime.http.request_options import RequestOptions
25
from office365.runtime.queries.service_operation import ServiceOperationQuery
36

7+
if TYPE_CHECKING:
8+
from office365.sharepoint.attachments.attachment import Attachment
9+
from office365.sharepoint.files.file import File
410

5-
def create_upload_file_query(file, file_object):
6-
"""
7-
Constructs upload file content query
811

9-
:type file: office365.sharepoint.files.file.File
10-
:type file_object: typing.IO
11-
"""
12+
def create_upload_file_query(file, file_object):
13+
# type: (File|Attachment, IO) -> ServiceOperationQuery
14+
""" Constructs upload file content query"""
1215
qry = ServiceOperationQuery(file, "$value")
1316

14-
def _construct_upload_request(request):
17+
def _construct_request(request):
18+
# type: (RequestOptions) -> None
1519
request.data = file_object.read()
1620
request.method = HttpMethod.Post
1721
request.set_header("X-HTTP-Method", "PUT")
1822

19-
file.context.before_execute(_construct_upload_request)
23+
file.context.before_execute(_construct_request)
2024
return qry

0 commit comments

Comments
 (0)