[{"data":1,"prerenderedAt":1951},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph":3,"surround:\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph":1919,"ancestors:\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph":1928,"children:\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph":1933,"related:\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph":1934},{"id":4,"title":5,"body":6,"dateModified":1887,"datePublished":1887,"description":1888,"extension":1889,"faq":1890,"keyword":1899,"kind":1900,"meta":1901,"navigation":278,"path":1909,"seo":1910,"slug":1912,"stem":1913,"topics":1914,"type":1917,"__hash__":1918},"docs\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph\u002Findex.md","Share an Excel File in OneDrive with a Link Using Graph",{"type":7,"value":8,"toc":1876},"minimark",[9,19,24,50,70,74,77,192,208,211,215,235,695,704,708,715,990,1028,1189,1193,1196,1600,1608,1611,1733,1737,1777,1781,1811,1815,1821,1827,1833,1839,1843,1872],[10,11,12,13,18],"p",{},"Creating a report in OneDrive or SharePoint is half the job; the other half is getting it to the people who need it, with the right level of access and nothing more. Clicking \"Share\" by hand every month does not scale, and an attachment loses the advantage of a single live file. Microsoft Graph exposes the same sharing model as the OneDrive and SharePoint interfaces: links with a type (view or edit) and a scope (anyone, people in your organisation, or specific people), optional expiry, and direct invitations to named recipients. This page creates each kind from Python, invites recipients without sending Microsoft's notification email so your own report email can carry the link, lists the permissions on a file and removes links that should not outlive the reporting period. It belongs to ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002F","Automating Excel Online with Microsoft Graph",".",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[25,26,31],"pre",{"className":27,"code":28,"language":29,"meta":30,"style":30},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install requests\n","bash","",[32,33,34],"code",{"__ignoreMap":30},[35,36,39,43,47],"span",{"class":37,"line":38},"line",1,[35,40,42],{"class":41},"sMTad","pip",[35,44,46],{"class":45},"srMev"," install",[35,48,49],{"class":45}," requests\n",[10,51,52,53,56,57,60,61,65,66,69],{},"You need a Microsoft Graph token with ",[32,54,55],{},"Files.ReadWrite"," (delegated) or ",[32,58,59],{},"Files.ReadWrite.All"," (application), the drive ID and the item ID of the workbook — for example from the upload in ",[14,62,64],{"href":63},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fcreate-a-new-workbook-in-onedrive-with-microsoft-graph\u002F","Create a New Workbook in OneDrive with Microsoft Graph",". What a link may do is limited by your tenant's sharing policy: if administrators have disabled anonymous links, asking for one fails, whatever the code says. The outputs below come from a mocked Graph API (the ",[32,67,68],{},"responses"," library) that returns the documented response shapes, so they can be shown without a tenant.",[20,71,73],{"id":72},"step-1-choose-the-link-type-and-scope","Step 1 — Choose the link type and scope",[10,75,76],{},"A sharing link has two independent settings, and the combination decides who can do what:",[78,79,87,88,87,92,87,96,87,104,87,112,87,119,87,126,87,129,87,133,87,138,87,144,87,146,87,151,87,153,87,156,87,159,87,163,87,165,87,169,87,171,87,174,87,177,87,181,87,183,87,187,87,189],"svg",{"viewBox":80,"role":81,"ariaLabelledBy":82,"xmlns":85,"style":86},"4 0 752 174","img",[83,84],"gs-scope-t","gs-scope-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[89,90,91],"title",{"id":83},"Link type and scope together decide access",[93,94,95],"desc",{"id":84},"The type sets what holders can do, view or edit. The scope sets who can use the link — anyone holding it, people signed in to your organisation, or only people explicitly granted access. Organisation view links suit internal reports; anonymous edit links are rarely appropriate.",[97,98],"rect",{"x":99,"y":100,"width":101,"height":102,"fill":103},"4","0","752","174","#ffffff",[97,105],{"x":106,"y":107,"width":108,"height":109,"rx":100,"fill":103,"stroke":110,"style":111},"20.0","16.0","108.8","40.0","var(--line,#cdd5e6)","stroke-width:1px",[97,113],{"x":114,"y":107,"width":115,"height":109,"rx":100,"fill":116,"stroke":117,"style":118},"128.8","305.6","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.2px",[120,121,125],"text",{"x":122,"y":123,"style":124},"281.6","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","view",[97,127],{"x":128,"y":107,"width":115,"height":109,"rx":100,"fill":116,"stroke":117,"style":118},"434.4",[120,130,132],{"x":131,"y":123,"style":124},"587.2","edit",[97,134],{"x":106,"y":135,"width":108,"height":136,"rx":100,"fill":137,"stroke":110,"style":111},"56.0","34.0","#e7ebef",[120,139,143],{"x":140,"y":141,"style":142},"32.0","78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","anonymous",[97,145],{"x":114,"y":135,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,147,150],{"x":122,"y":148,"style":149},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","anyone with the link reads",[97,152],{"x":128,"y":135,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,154,155],{"x":131,"y":148,"style":149},"anyone can change it — avoid",[97,157],{"x":106,"y":158,"width":108,"height":136,"rx":100,"fill":137,"stroke":110,"style":111},"90.0",[120,160,162],{"x":140,"y":161,"style":142},"112.0","organization",[97,164],{"x":114,"y":158,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,166,168],{"x":122,"y":167,"style":149},"111.0","colleagues read — usual choice",[97,170],{"x":128,"y":158,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,172,173],{"x":131,"y":167,"style":149},"colleagues edit",[97,175],{"x":106,"y":176,"width":108,"height":136,"rx":100,"fill":137,"stroke":110,"style":111},"124.0",[120,178,180],{"x":140,"y":179,"style":142},"146.0","users",[97,182],{"x":114,"y":176,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,184,186],{"x":122,"y":185,"style":149},"145.0","only named people read",[97,188],{"x":128,"y":176,"width":115,"height":136,"rx":100,"fill":103,"stroke":110,"style":111},[120,190,191],{"x":131,"y":185,"style":149},"only named people edit",[10,193,194,195,198,199,201,202,204,205,207],{},"For internal reports, a ",[196,197,125],"strong",{}," link with ",[196,200,162],{}," scope is the usual choice: anyone signed in to your Microsoft 365 tenant can open it, nobody outside can, and nobody can change the numbers. ",[32,203,143],{}," links work for anyone who holds the URL, which makes them easy to forward and impossible to control — use them only for genuinely public data, and always with an expiry. ",[32,206,180],{}," links work only for people who have been granted access, which suits sensitive reports such as payroll or board packs.",[10,209,210],{},"Think about what the recipients will actually do with the file. Most report readers only look: they filter, sort and maybe copy a figure into an email, none of which needs edit rights — Excel for the web lets viewers sort and filter a view of their own without changing the file. Edit access matters for workbooks people are expected to fill in, such as a forecast return or a checklist, and those are better served by inviting named people than by a link anyone in the company can open. Starting from the narrowest access that works and widening it on request is easier than discovering later that a salary file was reachable by the whole tenant.",[20,212,214],{"id":213},"step-2-create-a-link","Step 2 — Create a link",[10,216,217,218,221,222,225,226,230,231,234],{},"A link is created with a ",[32,219,220],{},"POST"," to the item's ",[32,223,224],{},"createLink"," action. The response is a ",[227,228,229],"em",{},"permission"," whose ",[32,232,233],{},"link.webUrl"," is the URL to send:",[25,236,240],{"className":237,"code":238,"language":239,"meta":30,"style":30},"language-python shiki shiki-themes github-light github-dark-high-contrast","import os\nfrom datetime import datetime, timedelta, timezone\nimport requests\n\nGRAPH = \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\"\nDRIVE, ITEM = \"b!reports-drive\", \"01ITEMSALES0926\"\nsession = requests.Session()\nsession.headers[\"Authorization\"] = f\"Bearer {os.environ['GRAPH_TOKEN']}\"\n\ndef create_link(kind=\"view\", scope=\"organization\", expires_in_days=None):\n    body = {\"type\": kind, \"scope\": scope}\n    if expires_in_days:\n        expiry = datetime.now(timezone.utc) + timedelta(days=expires_in_days)\n        body[\"expirationDateTime\"] = expiry.strftime(\"%Y-%m-%dT%H:%M:%SZ\")\n    r = session.post(f\"{GRAPH}\u002Fdrives\u002F{DRIVE}\u002Fitems\u002F{ITEM}\u002FcreateLink\", json=body, timeout=60)\n    r.raise_for_status()\n    return r.json()\n\norg_view = create_link()\nprint(org_view[\"link\"][\"scope\"], org_view[\"link\"][\"type\"], org_view[\"roles\"], org_view[\"link\"][\"webUrl\"])\npublic = create_link(\"view\", \"anonymous\", expires_in_days=14)\nprint(public[\"link\"][\"scope\"], \"expires\", public[\"expirationDateTime\"][:10])\n","python",[32,241,242,252,266,273,280,293,315,327,366,371,408,431,440,466,494,558,564,573,578,589,632,662],{"__ignoreMap":30},[35,243,244,248],{"class":37,"line":38},[35,245,247],{"class":246},"s-kum","import",[35,249,251],{"class":250},"skGVy"," os\n",[35,253,255,258,261,263],{"class":37,"line":254},2,[35,256,257],{"class":246},"from",[35,259,260],{"class":250}," datetime ",[35,262,247],{"class":246},[35,264,265],{"class":250}," datetime, timedelta, timezone\n",[35,267,269,271],{"class":37,"line":268},3,[35,270,247],{"class":246},[35,272,49],{"class":250},[35,274,276],{"class":37,"line":275},4,[35,277,279],{"emptyLinePlaceholder":278},true,"\n",[35,281,283,287,290],{"class":37,"line":282},5,[35,284,286],{"class":285},"sP0c6","GRAPH",[35,288,289],{"class":246}," =",[35,291,292],{"class":45}," \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\"\n",[35,294,296,299,302,305,307,310,312],{"class":37,"line":295},6,[35,297,298],{"class":285},"DRIVE",[35,300,301],{"class":250},", ",[35,303,304],{"class":285},"ITEM",[35,306,289],{"class":246},[35,308,309],{"class":45}," \"b!reports-drive\"",[35,311,301],{"class":250},[35,313,314],{"class":45},"\"01ITEMSALES0926\"\n",[35,316,318,321,324],{"class":37,"line":317},7,[35,319,320],{"class":250},"session ",[35,322,323],{"class":246},"=",[35,325,326],{"class":250}," requests.Session()\n",[35,328,330,333,336,339,341,344,347,351,354,357,360,363],{"class":37,"line":329},8,[35,331,332],{"class":250},"session.headers[",[35,334,335],{"class":45},"\"Authorization\"",[35,337,338],{"class":250},"] ",[35,340,323],{"class":246},[35,342,343],{"class":246}," f",[35,345,346],{"class":45},"\"Bearer ",[35,348,350],{"class":349},"sSjpA","{",[35,352,353],{"class":250},"os.environ[",[35,355,356],{"class":45},"'GRAPH_TOKEN'",[35,358,359],{"class":250},"]",[35,361,362],{"class":349},"}",[35,364,365],{"class":45},"\"\n",[35,367,369],{"class":37,"line":368},9,[35,370,279],{"emptyLinePlaceholder":278},[35,372,374,377,381,384,386,389,392,394,397,400,402,405],{"class":37,"line":373},10,[35,375,376],{"class":246},"def",[35,378,380],{"class":379},"s_Opv"," create_link",[35,382,383],{"class":250},"(kind",[35,385,323],{"class":246},[35,387,388],{"class":45},"\"view\"",[35,390,391],{"class":250},", scope",[35,393,323],{"class":246},[35,395,396],{"class":45},"\"organization\"",[35,398,399],{"class":250},", expires_in_days",[35,401,323],{"class":246},[35,403,404],{"class":285},"None",[35,406,407],{"class":250},"):\n",[35,409,411,414,416,419,422,425,428],{"class":37,"line":410},11,[35,412,413],{"class":250},"    body ",[35,415,323],{"class":246},[35,417,418],{"class":250}," {",[35,420,421],{"class":45},"\"type\"",[35,423,424],{"class":250},": kind, ",[35,426,427],{"class":45},"\"scope\"",[35,429,430],{"class":250},": scope}\n",[35,432,434,437],{"class":37,"line":433},12,[35,435,436],{"class":246},"    if",[35,438,439],{"class":250}," expires_in_days:\n",[35,441,443,446,448,451,454,457,461,463],{"class":37,"line":442},13,[35,444,445],{"class":250},"        expiry ",[35,447,323],{"class":246},[35,449,450],{"class":250}," datetime.now(timezone.utc) ",[35,452,453],{"class":246},"+",[35,455,456],{"class":250}," timedelta(",[35,458,460],{"class":459},"sa561","days",[35,462,323],{"class":246},[35,464,465],{"class":250},"expires_in_days)\n",[35,467,469,472,475,477,479,482,485,488,491],{"class":37,"line":468},14,[35,470,471],{"class":250},"        body[",[35,473,474],{"class":45},"\"expirationDateTime\"",[35,476,338],{"class":250},[35,478,323],{"class":246},[35,480,481],{"class":250}," expiry.strftime(",[35,483,484],{"class":45},"\"%Y-%m-",[35,486,487],{"class":349},"%d",[35,489,490],{"class":45},"T%H:%M:%SZ\"",[35,492,493],{"class":250},")\n",[35,495,497,500,502,505,508,511,513,515,517,520,522,524,526,529,531,533,535,538,540,543,545,548,551,553,556],{"class":37,"line":496},15,[35,498,499],{"class":250},"    r ",[35,501,323],{"class":246},[35,503,504],{"class":250}," session.post(",[35,506,507],{"class":246},"f",[35,509,510],{"class":45},"\"",[35,512,350],{"class":349},[35,514,286],{"class":285},[35,516,362],{"class":349},[35,518,519],{"class":45},"\u002Fdrives\u002F",[35,521,350],{"class":349},[35,523,298],{"class":285},[35,525,362],{"class":349},[35,527,528],{"class":45},"\u002Fitems\u002F",[35,530,350],{"class":349},[35,532,304],{"class":285},[35,534,362],{"class":349},[35,536,537],{"class":45},"\u002FcreateLink\"",[35,539,301],{"class":250},[35,541,542],{"class":459},"json",[35,544,323],{"class":246},[35,546,547],{"class":250},"body, ",[35,549,550],{"class":459},"timeout",[35,552,323],{"class":246},[35,554,555],{"class":285},"60",[35,557,493],{"class":250},[35,559,561],{"class":37,"line":560},16,[35,562,563],{"class":250},"    r.raise_for_status()\n",[35,565,567,570],{"class":37,"line":566},17,[35,568,569],{"class":246},"    return",[35,571,572],{"class":250}," r.json()\n",[35,574,576],{"class":37,"line":575},18,[35,577,279],{"emptyLinePlaceholder":278},[35,579,581,584,586],{"class":37,"line":580},19,[35,582,583],{"class":250},"org_view ",[35,585,323],{"class":246},[35,587,588],{"class":250}," create_link()\n",[35,590,592,595,598,601,604,606,609,611,613,615,617,620,622,624,626,629],{"class":37,"line":591},20,[35,593,594],{"class":285},"print",[35,596,597],{"class":250},"(org_view[",[35,599,600],{"class":45},"\"link\"",[35,602,603],{"class":250},"][",[35,605,427],{"class":45},[35,607,608],{"class":250},"], org_view[",[35,610,600],{"class":45},[35,612,603],{"class":250},[35,614,421],{"class":45},[35,616,608],{"class":250},[35,618,619],{"class":45},"\"roles\"",[35,621,608],{"class":250},[35,623,600],{"class":45},[35,625,603],{"class":250},[35,627,628],{"class":45},"\"webUrl\"",[35,630,631],{"class":250},"])\n",[35,633,635,638,640,643,645,647,650,652,655,657,660],{"class":37,"line":634},21,[35,636,637],{"class":250},"public ",[35,639,323],{"class":246},[35,641,642],{"class":250}," create_link(",[35,644,388],{"class":45},[35,646,301],{"class":250},[35,648,649],{"class":45},"\"anonymous\"",[35,651,301],{"class":250},[35,653,654],{"class":459},"expires_in_days",[35,656,323],{"class":246},[35,658,659],{"class":285},"14",[35,661,493],{"class":250},[35,663,665,667,670,672,674,676,679,682,685,687,690,693],{"class":37,"line":664},22,[35,666,594],{"class":285},[35,668,669],{"class":250},"(public[",[35,671,600],{"class":45},[35,673,603],{"class":250},[35,675,427],{"class":45},[35,677,678],{"class":250},"], ",[35,680,681],{"class":45},"\"expires\"",[35,683,684],{"class":250},", public[",[35,686,474],{"class":45},[35,688,689],{"class":250},"][:",[35,691,692],{"class":285},"10",[35,694,631],{"class":250},[10,696,697,699,700,703],{},[32,698,224],{}," is idempotent for the same type and scope: asking for an organisation view link twice returns the existing link rather than making a second one, so a monthly job can call it every time without accumulating links. If each month's report is a separate file, each gets its own link; if the job overwrites one file in place, the link people bookmarked keeps working and always shows the latest figures. ",[32,701,702],{},"expirationDateTime"," is a UTC timestamp in ISO 8601 format; after it the link stops working. Some settings depend on the account type — password-protected links, for instance, are available only on OneDrive for personal accounts — and your tenant can enforce a maximum expiry for anonymous links regardless of what you ask for.",[20,705,707],{"id":706},"step-3-invite-named-people","Step 3 — Invite named people",[10,709,710,711,714],{},"To give specific people access — and optionally have Microsoft send them a notification — use ",[32,712,713],{},"invite",":",[25,716,718],{"className":237,"code":717,"language":239,"meta":30,"style":30},"def invite(emails, role=\"read\", notify=False, message=None):\n    body = {\"recipients\": [{\"email\": e} for e in emails], \"roles\": [role],\n            \"requireSignIn\": True, \"sendInvitation\": notify}\n    if notify and message:\n        body[\"message\"] = message\n    r = session.post(f\"{GRAPH}\u002Fdrives\u002F{DRIVE}\u002Fitems\u002F{ITEM}\u002Finvite\", json=body, timeout=60)\n    r.raise_for_status()\n    return r.json()[\"value\"]\n\ngranted = invite([\"maria.lopez@contoso.com\", \"tom.becker@contoso.com\"], role=\"read\")\nfor p in granted:\n    print(p[\"roles\"], p[\"grantedToV2\"][\"user\"][\"displayName\"], p[\"grantedToV2\"][\"user\"][\"email\"])\n",[32,719,720,752,789,808,821,835,888,892,905,909,938,950],{"__ignoreMap":30},[35,721,722,724,727,730,732,735,738,740,743,746,748,750],{"class":37,"line":38},[35,723,376],{"class":246},[35,725,726],{"class":379}," invite",[35,728,729],{"class":250},"(emails, role",[35,731,323],{"class":246},[35,733,734],{"class":45},"\"read\"",[35,736,737],{"class":250},", notify",[35,739,323],{"class":246},[35,741,742],{"class":285},"False",[35,744,745],{"class":250},", message",[35,747,323],{"class":246},[35,749,404],{"class":285},[35,751,407],{"class":250},[35,753,754,756,758,760,763,766,769,772,775,778,781,784,786],{"class":37,"line":254},[35,755,413],{"class":250},[35,757,323],{"class":246},[35,759,418],{"class":250},[35,761,762],{"class":45},"\"recipients\"",[35,764,765],{"class":250},": [{",[35,767,768],{"class":45},"\"email\"",[35,770,771],{"class":250},": e} ",[35,773,774],{"class":246},"for",[35,776,777],{"class":250}," e ",[35,779,780],{"class":246},"in",[35,782,783],{"class":250}," emails], ",[35,785,619],{"class":45},[35,787,788],{"class":250},": [role],\n",[35,790,791,794,797,800,802,805],{"class":37,"line":268},[35,792,793],{"class":45},"            \"requireSignIn\"",[35,795,796],{"class":250},": ",[35,798,799],{"class":285},"True",[35,801,301],{"class":250},[35,803,804],{"class":45},"\"sendInvitation\"",[35,806,807],{"class":250},": notify}\n",[35,809,810,812,815,818],{"class":37,"line":275},[35,811,436],{"class":246},[35,813,814],{"class":250}," notify ",[35,816,817],{"class":246},"and",[35,819,820],{"class":250}," message:\n",[35,822,823,825,828,830,832],{"class":37,"line":282},[35,824,471],{"class":250},[35,826,827],{"class":45},"\"message\"",[35,829,338],{"class":250},[35,831,323],{"class":246},[35,833,834],{"class":250}," message\n",[35,836,837,839,841,843,845,847,849,851,853,855,857,859,861,863,865,867,869,872,874,876,878,880,882,884,886],{"class":37,"line":295},[35,838,499],{"class":250},[35,840,323],{"class":246},[35,842,504],{"class":250},[35,844,507],{"class":246},[35,846,510],{"class":45},[35,848,350],{"class":349},[35,850,286],{"class":285},[35,852,362],{"class":349},[35,854,519],{"class":45},[35,856,350],{"class":349},[35,858,298],{"class":285},[35,860,362],{"class":349},[35,862,528],{"class":45},[35,864,350],{"class":349},[35,866,304],{"class":285},[35,868,362],{"class":349},[35,870,871],{"class":45},"\u002Finvite\"",[35,873,301],{"class":250},[35,875,542],{"class":459},[35,877,323],{"class":246},[35,879,547],{"class":250},[35,881,550],{"class":459},[35,883,323],{"class":246},[35,885,555],{"class":285},[35,887,493],{"class":250},[35,889,890],{"class":37,"line":317},[35,891,563],{"class":250},[35,893,894,896,899,902],{"class":37,"line":329},[35,895,569],{"class":246},[35,897,898],{"class":250}," r.json()[",[35,900,901],{"class":45},"\"value\"",[35,903,904],{"class":250},"]\n",[35,906,907],{"class":37,"line":368},[35,908,279],{"emptyLinePlaceholder":278},[35,910,911,914,916,919,922,924,927,929,932,934,936],{"class":37,"line":373},[35,912,913],{"class":250},"granted ",[35,915,323],{"class":246},[35,917,918],{"class":250}," invite([",[35,920,921],{"class":45},"\"maria.lopez@contoso.com\"",[35,923,301],{"class":250},[35,925,926],{"class":45},"\"tom.becker@contoso.com\"",[35,928,678],{"class":250},[35,930,931],{"class":459},"role",[35,933,323],{"class":246},[35,935,734],{"class":45},[35,937,493],{"class":250},[35,939,940,942,945,947],{"class":37,"line":410},[35,941,774],{"class":246},[35,943,944],{"class":250}," p ",[35,946,780],{"class":246},[35,948,949],{"class":250}," granted:\n",[35,951,952,955,958,960,963,966,968,971,973,976,978,980,982,984,986,988],{"class":37,"line":433},[35,953,954],{"class":285},"    print",[35,956,957],{"class":250},"(p[",[35,959,619],{"class":45},[35,961,962],{"class":250},"], p[",[35,964,965],{"class":45},"\"grantedToV2\"",[35,967,603],{"class":250},[35,969,970],{"class":45},"\"user\"",[35,972,603],{"class":250},[35,974,975],{"class":45},"\"displayName\"",[35,977,962],{"class":250},[35,979,965],{"class":45},[35,981,603],{"class":250},[35,983,970],{"class":45},[35,985,603],{"class":250},[35,987,768],{"class":45},[35,989,631],{"class":250},[10,991,992,995,996,999,1000,1002,1003,1006,1007,1010,1011,1014,1015,1018,1019,1023,1024,18],{},[32,993,994],{},"requireSignIn: True"," means the recipients must sign in as themselves to open the file — the link cannot be forwarded to someone else. With ",[32,997,998],{},"sendInvitation: False",", Graph grants access silently, which is useful when your own report email already contains the link and a second notification from Microsoft would be noise; set it to ",[32,1001,799],{}," with a ",[32,1004,1005],{},"message"," when the sharing email ",[227,1008,1009],{},"is"," the notification. Roles are ",[32,1012,1013],{},"read"," or ",[32,1016,1017],{},"write",". Recipients outside your organisation are invited as guests if the tenant allows external sharing; their first visit asks them to verify their address with a one-time code, so warn them in your own email that this step is coming. Sending the link in your own email is covered in ",[14,1020,1022],{"href":1021},"\u002Fautomating-reporting-workflows\u002Femailing-excel-reports-with-smtplib\u002Fsend-an-excel-report-with-microsoft-graph-api\u002F","Send an Excel Report with the Microsoft Graph API",", and the trade-offs of links versus attachments in ",[14,1025,1027],{"href":1026},"\u002Fautomating-reporting-workflows\u002Femailing-excel-reports-with-smtplib\u002Femail-a-download-link-instead-of-an-excel-attachment\u002F","Email a Download Link Instead of an Excel Attachment",[78,1029,87,1034,87,1037,87,1040,87,1043,87,1049,87,1060,87,1066,87,1070,87,1074,87,1079,87,1084,87,1087,87,1094,87,1098,87,1102,87,1104,87,1108,87,1111,87,1116,87,1123,87,1127,87,1130,87,1133,87,1137,87,1140,87,1145,87,1152,87,1157,87,1160,87,1163,87,1167,87,1170,87,1173,87,1179,87,1183,87,1186],{"viewBox":1030,"role":81,"ariaLabelledBy":1031,"xmlns":85,"style":86},"4 0 752 142",[1032,1033],"gs-flow-t","gs-flow-d",[89,1035,1036],{"id":1032},"Sharing a monthly report",[93,1038,1039],{"id":1033},"The job uploads the workbook, creates or reuses an organisation view link, grants named recipients read access silently, sends its own email with the link, and at the end of the period removes links and grants that should not remain.",[97,1041],{"x":99,"y":100,"width":101,"height":1042,"fill":103},"142",[97,1044],{"x":106,"y":107,"width":1045,"height":1046,"rx":1047,"fill":137,"stroke":110,"style":1048},"115.2","110.5","12","stroke-width:2px",[1050,1051,1053],"g",{"transform":1052},"translate(65.6,29.0) scale(1.000)",[1054,1055],"path",{"d":1056,"fill":1057,"stroke":1058,"style":1059},"M7 18h10a4 4 0 0 0 .6-8A6 6 0 0 0 6.1 11.4 3.4 3.4 0 0 0 7 18z","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[120,1061,1065],{"x":1062,"y":1063,"style":1064},"77.6","75.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","upload",[120,1067,1069],{"x":1062,"y":1068,"style":1064},"93.0","report",[120,1071,1073],{"x":1062,"y":1072,"style":149},"112.5","driveItem id",[37,1075],{"x1":1076,"y1":1077,"x2":1078,"y2":1077,"stroke":117,"style":1048},"140.2","71.2","162.2",[1080,1081],"polygon",{"points":1082,"fill":1083},"166.2,71.2 157.2,76.2 157.2,66.2","#5b5cf0",[97,1085],{"x":1086,"y":107,"width":1045,"height":1046,"rx":1047,"fill":116,"stroke":117,"style":1048},"171.2",[1050,1088,1090],{"transform":1089},"translate(216.8,29.0) scale(1.000)",[1054,1091],{"d":1092,"fill":1057,"stroke":1093,"style":1059},"M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1 M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1","var(--brand-strong,#4338ca)",[120,1095,224],{"x":1096,"y":1063,"style":1097},"228.8","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[120,1099,1101],{"x":1096,"y":1100,"style":149},"95.0","view,",[120,1103,162],{"x":1096,"y":1072,"style":149},[37,1105],{"x1":1106,"y1":1077,"x2":1107,"y2":1077,"stroke":117,"style":1048},"291.4","313.4",[1080,1109],{"points":1110,"fill":1083},"317.4,71.2 308.4,76.2 308.4,66.2",[97,1112],{"x":1113,"y":107,"width":1045,"height":1046,"rx":1047,"fill":1114,"stroke":1115,"style":1048},"322.4","#fdefd8","var(--gold,#b4740a)",[1050,1117,1119],{"transform":1118},"translate(368.0,29.0) scale(1.000)",[1054,1120],{"d":1121,"fill":1057,"stroke":1122,"style":1059},"M9 11a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z M2.5 20c0-3.6 2.9-6 6.5-6s6.5 2.4 6.5 6 M16 4.5a3.3 3.3 0 0 1 0 6.3 M18 14.3c2.2.7 3.5 2.8 3.5 5.7","var(--gold-ink,#7a4e06)",[120,1124,713],{"x":1125,"y":1063,"style":1126},"380.0","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[120,1128,1129],{"x":1125,"y":1100,"style":149},"read, no",[120,1131,1132],{"x":1125,"y":1072,"style":149},"Microsoft email",[37,1134],{"x1":1135,"y1":1077,"x2":1136,"y2":1077,"stroke":117,"style":1048},"442.6","464.6",[1080,1138],{"points":1139,"fill":1083},"468.6,71.2 459.6,76.2 459.6,66.2",[97,1141],{"x":1142,"y":107,"width":1045,"height":1046,"rx":1047,"fill":1143,"stroke":1144,"style":1048},"473.6","#d9f4f1","var(--teal,#0f9488)",[1050,1146,1148],{"transform":1147},"translate(519.2,29.0) scale(1.000)",[1054,1149],{"d":1150,"fill":1057,"stroke":1151,"style":1059},"M3 6h18v12H3z M3 7l9 6 9-6","var(--teal-ink,#0b6157)",[120,1153,1156],{"x":1154,"y":1063,"style":1155},"531.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","send own",[120,1158,1159],{"x":1154,"y":1068,"style":1155},"email",[120,1161,1162],{"x":1154,"y":1072,"style":149},"link in the body",[37,1164],{"x1":1165,"y1":1077,"x2":1166,"y2":1077,"stroke":117,"style":1048},"593.8","615.8",[1080,1168],{"points":1169,"fill":1083},"619.8,71.2 610.8,76.2 610.8,66.2",[97,1171],{"x":1172,"y":107,"width":1045,"height":1046,"rx":1047,"fill":137,"stroke":110,"style":1048},"624.8",[1050,1174,1176],{"transform":1175},"translate(670.4,29.0) scale(1.000)",[1054,1177],{"d":1178,"fill":1057,"stroke":1058,"style":1059},"M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3",[120,1180,1182],{"x":1181,"y":1063,"style":1064},"682.4","tidy up",[120,1184,1185],{"x":1181,"y":1100,"style":149},"delete old",[120,1187,1188],{"x":1181,"y":1072,"style":149},"permissions",[20,1190,1192],{"id":1191},"step-4-list-and-remove-permissions","Step 4 — List and remove permissions",[10,1194,1195],{},"Every link and grant appears as a permission on the item. Listing them shows who has access; deleting one revokes it:",[25,1197,1199],{"className":237,"code":1198,"language":239,"meta":30,"style":30},"def permissions():\n    return session.get(f\"{GRAPH}\u002Fdrives\u002F{DRIVE}\u002Fitems\u002F{ITEM}\u002Fpermissions\", timeout=60).json()[\"value\"]\n\ndef describe(p):\n    if \"link\" in p:\n        return f\"link {p['link']['type']}\u002F{p['link']['scope']}\" + (f\" until {p['expirationDateTime'][:10]}\" if \"expirationDateTime\" in p else \"\")\n    return f\"{p['roles'][0]} for {p['grantedToV2']['user']['displayName']}\"\n\nfor p in permissions():\n    print(f\"{p['id']:\u003C7} {describe(p)}\")\n\nfor p in permissions():\n    if p.get(\"link\", {}).get(\"scope\") == \"anonymous\":\n        session.delete(f\"{GRAPH}\u002Fdrives\u002F{DRIVE}\u002Fitems\u002F{ITEM}\u002Fpermissions\u002F{p['id']}\", timeout=60).raise_for_status()\nprint(\"after removing anonymous links:\", [describe(p) for p in permissions()])\n",[32,1200,1201,1211,1262,1266,1276,1289,1382,1431,1435,1446,1482,1486,1496,1522,1579],{"__ignoreMap":30},[35,1202,1203,1205,1208],{"class":37,"line":38},[35,1204,376],{"class":246},[35,1206,1207],{"class":379}," permissions",[35,1209,1210],{"class":250},"():\n",[35,1212,1213,1215,1218,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242,1244,1247,1249,1251,1253,1255,1258,1260],{"class":37,"line":254},[35,1214,569],{"class":246},[35,1216,1217],{"class":250}," session.get(",[35,1219,507],{"class":246},[35,1221,510],{"class":45},[35,1223,350],{"class":349},[35,1225,286],{"class":285},[35,1227,362],{"class":349},[35,1229,519],{"class":45},[35,1231,350],{"class":349},[35,1233,298],{"class":285},[35,1235,362],{"class":349},[35,1237,528],{"class":45},[35,1239,350],{"class":349},[35,1241,304],{"class":285},[35,1243,362],{"class":349},[35,1245,1246],{"class":45},"\u002Fpermissions\"",[35,1248,301],{"class":250},[35,1250,550],{"class":459},[35,1252,323],{"class":246},[35,1254,555],{"class":285},[35,1256,1257],{"class":250},").json()[",[35,1259,901],{"class":45},[35,1261,904],{"class":250},[35,1263,1264],{"class":37,"line":268},[35,1265,279],{"emptyLinePlaceholder":278},[35,1267,1268,1270,1273],{"class":37,"line":275},[35,1269,376],{"class":246},[35,1271,1272],{"class":379}," describe",[35,1274,1275],{"class":250},"(p):\n",[35,1277,1278,1280,1283,1286],{"class":37,"line":282},[35,1279,436],{"class":246},[35,1281,1282],{"class":45}," \"link\"",[35,1284,1285],{"class":246}," in",[35,1287,1288],{"class":250}," p:\n",[35,1290,1291,1294,1296,1299,1301,1304,1307,1309,1312,1314,1316,1319,1321,1323,1325,1327,1330,1332,1334,1336,1339,1342,1344,1347,1349,1351,1354,1356,1358,1360,1362,1364,1367,1370,1372,1374,1377,1380],{"class":37,"line":295},[35,1292,1293],{"class":246},"        return",[35,1295,343],{"class":246},[35,1297,1298],{"class":45},"\"link ",[35,1300,350],{"class":349},[35,1302,1303],{"class":250},"p[",[35,1305,1306],{"class":45},"'link'",[35,1308,603],{"class":250},[35,1310,1311],{"class":45},"'type'",[35,1313,359],{"class":250},[35,1315,362],{"class":349},[35,1317,1318],{"class":45},"\u002F",[35,1320,350],{"class":349},[35,1322,1303],{"class":250},[35,1324,1306],{"class":45},[35,1326,603],{"class":250},[35,1328,1329],{"class":45},"'scope'",[35,1331,359],{"class":250},[35,1333,362],{"class":349},[35,1335,510],{"class":45},[35,1337,1338],{"class":246}," +",[35,1340,1341],{"class":250}," (",[35,1343,507],{"class":246},[35,1345,1346],{"class":45},"\" until ",[35,1348,350],{"class":349},[35,1350,1303],{"class":250},[35,1352,1353],{"class":45},"'expirationDateTime'",[35,1355,689],{"class":250},[35,1357,692],{"class":285},[35,1359,359],{"class":250},[35,1361,362],{"class":349},[35,1363,510],{"class":45},[35,1365,1366],{"class":246}," if",[35,1368,1369],{"class":45}," \"expirationDateTime\"",[35,1371,1285],{"class":246},[35,1373,944],{"class":250},[35,1375,1376],{"class":246},"else",[35,1378,1379],{"class":45}," \"\"",[35,1381,493],{"class":250},[35,1383,1384,1386,1388,1390,1392,1394,1397,1399,1401,1403,1405,1408,1410,1412,1415,1417,1420,1422,1425,1427,1429],{"class":37,"line":317},[35,1385,569],{"class":246},[35,1387,343],{"class":246},[35,1389,510],{"class":45},[35,1391,350],{"class":349},[35,1393,1303],{"class":250},[35,1395,1396],{"class":45},"'roles'",[35,1398,603],{"class":250},[35,1400,100],{"class":285},[35,1402,359],{"class":250},[35,1404,362],{"class":349},[35,1406,1407],{"class":45}," for ",[35,1409,350],{"class":349},[35,1411,1303],{"class":250},[35,1413,1414],{"class":45},"'grantedToV2'",[35,1416,603],{"class":250},[35,1418,1419],{"class":45},"'user'",[35,1421,603],{"class":250},[35,1423,1424],{"class":45},"'displayName'",[35,1426,359],{"class":250},[35,1428,362],{"class":349},[35,1430,365],{"class":45},[35,1432,1433],{"class":37,"line":329},[35,1434,279],{"emptyLinePlaceholder":278},[35,1436,1437,1439,1441,1443],{"class":37,"line":368},[35,1438,774],{"class":246},[35,1440,944],{"class":250},[35,1442,780],{"class":246},[35,1444,1445],{"class":250}," permissions():\n",[35,1447,1448,1450,1453,1455,1457,1459,1461,1464,1466,1469,1471,1473,1476,1478,1480],{"class":37,"line":373},[35,1449,954],{"class":285},[35,1451,1452],{"class":250},"(",[35,1454,507],{"class":246},[35,1456,510],{"class":45},[35,1458,350],{"class":349},[35,1460,1303],{"class":250},[35,1462,1463],{"class":45},"'id'",[35,1465,359],{"class":250},[35,1467,1468],{"class":246},":\u003C7",[35,1470,362],{"class":349},[35,1472,418],{"class":349},[35,1474,1475],{"class":250},"describe(p)",[35,1477,362],{"class":349},[35,1479,510],{"class":45},[35,1481,493],{"class":250},[35,1483,1484],{"class":37,"line":410},[35,1485,279],{"emptyLinePlaceholder":278},[35,1487,1488,1490,1492,1494],{"class":37,"line":433},[35,1489,774],{"class":246},[35,1491,944],{"class":250},[35,1493,780],{"class":246},[35,1495,1445],{"class":250},[35,1497,1498,1500,1503,1505,1508,1510,1513,1516,1519],{"class":37,"line":442},[35,1499,436],{"class":246},[35,1501,1502],{"class":250}," p.get(",[35,1504,600],{"class":45},[35,1506,1507],{"class":250},", {}).get(",[35,1509,427],{"class":45},[35,1511,1512],{"class":250},") ",[35,1514,1515],{"class":246},"==",[35,1517,1518],{"class":45}," \"anonymous\"",[35,1520,1521],{"class":250},":\n",[35,1523,1524,1527,1529,1531,1533,1535,1537,1539,1541,1543,1545,1547,1549,1551,1553,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574,1576],{"class":37,"line":468},[35,1525,1526],{"class":250},"        session.delete(",[35,1528,507],{"class":246},[35,1530,510],{"class":45},[35,1532,350],{"class":349},[35,1534,286],{"class":285},[35,1536,362],{"class":349},[35,1538,519],{"class":45},[35,1540,350],{"class":349},[35,1542,298],{"class":285},[35,1544,362],{"class":349},[35,1546,528],{"class":45},[35,1548,350],{"class":349},[35,1550,304],{"class":285},[35,1552,362],{"class":349},[35,1554,1555],{"class":45},"\u002Fpermissions\u002F",[35,1557,350],{"class":349},[35,1559,1303],{"class":250},[35,1561,1463],{"class":45},[35,1563,359],{"class":250},[35,1565,362],{"class":349},[35,1567,510],{"class":45},[35,1569,301],{"class":250},[35,1571,550],{"class":459},[35,1573,323],{"class":246},[35,1575,555],{"class":285},[35,1577,1578],{"class":250},").raise_for_status()\n",[35,1580,1581,1583,1585,1588,1591,1593,1595,1597],{"class":37,"line":496},[35,1582,594],{"class":285},[35,1584,1452],{"class":250},[35,1586,1587],{"class":45},"\"after removing anonymous links:\"",[35,1589,1590],{"class":250},", [describe(p) ",[35,1592,774],{"class":246},[35,1594,944],{"class":250},[35,1596,780],{"class":246},[35,1598,1599],{"class":250}," permissions()])\n",[10,1601,1602,1603,1607],{},"The owner permission cannot be removed and inherited permissions from the parent folder or site appear too — leave those alone and delete only the links and grants your job created. A clean-up step like this, run when a reporting period closes, keeps old files from staying reachable through forgotten links. Recording each permission ID as you create it, in a log or a small state file, makes it easy to revoke exactly what the job granted and nothing else; ",[14,1604,1606],{"href":1605},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Flog-python-excel-script-output-to-a-file\u002F","Log Python Excel Script Output to a File"," covers the logging side.",[10,1609,1610],{},"The same listing doubles as an access audit. A short script that walks a reports folder, lists the permissions on every workbook and flags anonymous links, edit links, links without an expiry and grants to addresses outside your domain gives a security reviewer exactly what they ask for, and it takes a few minutes to run rather than an afternoon of clicking through the \"Manage access\" panel file by file. Run it monthly and keep its output with the period's reports.",[78,1612,87,1617,87,1620,87,1623,87,1626,87,1630,87,1634,87,1637,87,1641,87,1645,87,1648,87,1651,87,1657,87,1662,87,1666,87,1671,87,1675,87,1679,87,1681,87,1684,87,1688,87,1691,87,1694,87,1700,87,1703,87,1706,87,1708,87,1711,87,1715,87,1718,87,1721,87,1727,87,1730],{"viewBox":1613,"role":81,"ariaLabelledBy":1614,"xmlns":85,"style":86},"4 0 752 272",[1615,1616],"gs-choose-t","gs-choose-d",[89,1618,1619],{"id":1615},"Which sharing method for which report",[93,1621,1622],{"id":1616},"For internal reports anyone in the company may see, use an organisation view link. For sensitive reports, invite named people with sign-in required. For external recipients, use an expiring anonymous view link only if policy allows, otherwise invite them as guests.",[97,1624],{"x":99,"y":100,"width":101,"height":1625,"fill":103},"272",[97,1627],{"x":1628,"y":107,"width":1629,"height":1063,"rx":1047,"fill":116,"stroke":117,"style":1048},"240.0","280.0",[1050,1631,1632],{"transform":1118},[1054,1633],{"d":1121,"fill":1057,"stroke":1093,"style":1059},[120,1635,1636],{"x":1125,"y":1063,"style":1097},"Who should open the report?",[37,1638],{"x1":1125,"y1":1639,"x2":1125,"y2":1640,"stroke":117,"style":1048},"91.5","111.5",[37,1642],{"x1":1643,"y1":1640,"x2":1644,"y2":1640,"stroke":117,"style":1048},"134.7","625.3",[37,1646],{"x1":1643,"y1":1640,"x2":1643,"y2":1647,"stroke":117,"style":1048},"157.5",[1080,1649],{"points":1650,"fill":1083},"134.7,161.5 129.7,152.5 139.7,152.5",[97,1652],{"x":1653,"y":1654,"width":1655,"height":1656,"rx":692,"fill":103,"stroke":110,"style":118},"68.0","121.5","133.4","21.0",[120,1658,1661],{"x":1643,"y":1659,"style":1660},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","anyone in company",[97,1663],{"x":106,"y":1664,"width":1665,"height":1068,"rx":1047,"fill":1143,"stroke":1144,"style":1048},"163.5","229.3",[1050,1667,1669],{"transform":1668},"translate(122.7,176.5) scale(1.000)",[1054,1670],{"d":1092,"fill":1057,"stroke":1151,"style":1059},[120,1672,1674],{"x":1643,"y":1673,"style":1155},"223.0","organization view link",[120,1676,1678],{"x":1643,"y":1677,"style":149},"242.5","reusable each month",[37,1680],{"x1":1125,"y1":1640,"x2":1125,"y2":1647,"stroke":117,"style":1048},[1080,1682],{"points":1683,"fill":1083},"380.0,161.5 375.0,152.5 385.0,152.5",[97,1685],{"x":1686,"y":1654,"width":1687,"height":1656,"rx":692,"fill":103,"stroke":110,"style":118},"329.2","101.5",[120,1689,1690],{"x":1125,"y":1659,"style":1660},"named people",[97,1692],{"x":1693,"y":1664,"width":1665,"height":1068,"rx":1047,"fill":1114,"stroke":1115,"style":1048},"265.3",[1050,1695,1697],{"transform":1696},"translate(368.0,176.5) scale(1.000)",[1054,1698],{"d":1699,"fill":1057,"stroke":1122,"style":1059},"M6 11h12v9H6z M8.5 11V8a3.5 3.5 0 0 1 7 0v3",[120,1701,1702],{"x":1125,"y":1673,"style":1126},"invite, requireSignIn",[120,1704,1705],{"x":1125,"y":1677,"style":149},"cannot be forwarded",[37,1707],{"x1":1644,"y1":1640,"x2":1644,"y2":1647,"stroke":117,"style":1048},[1080,1709],{"points":1710,"fill":1083},"625.3,161.5 620.3,152.5 630.3,152.5",[97,1712],{"x":1713,"y":1654,"width":1714,"height":1656,"rx":692,"fill":103,"stroke":110,"style":118},"592.1","66.5",[120,1716,1717],{"x":1644,"y":1659,"style":1660},"external",[97,1719],{"x":1720,"y":1664,"width":1665,"height":1068,"rx":1047,"fill":116,"stroke":117,"style":1048},"510.7",[1050,1722,1724],{"transform":1723},"translate(613.3,176.5) scale(1.000)",[1054,1725],{"d":1726,"fill":1057,"stroke":1093,"style":1059},"M12 3a9 9 0 1 0 .01 0z M12 7v5l3.5 2",[120,1728,1729],{"x":1644,"y":1673,"style":1097},"expiring anonymous link",[120,1731,1732],{"x":1644,"y":1677,"style":149},"or invite as guests",[20,1734,1736],{"id":1735},"common-pitfalls","Common pitfalls",[1738,1739,1740,1747,1756,1765,1771],"ul",{},[1741,1742,1743,1746],"li",{},[196,1744,1745],{},"Anonymous edit links."," Anyone holding the URL can change the numbers.",[1741,1748,1749,1752,1753,1755],{},[196,1750,1751],{},"No expiry on public links."," Set ",[32,1754,702],{},"; policy may cap it anyway.",[1741,1757,1758,1761,1762,1764],{},[196,1759,1760],{},"Double notifications."," Use ",[32,1763,998],{}," when your own email has the link.",[1741,1766,1767,1770],{},[196,1768,1769],{},"Deleting inherited permissions."," Remove only what your job created.",[1741,1772,1773,1776],{},[196,1774,1775],{},"Assuming the tenant allows it."," Sharing policy overrides the request.",[20,1778,1780],{"id":1779},"conclusion","Conclusion",[10,1782,1783,1784,221,1786,1788,1789,1014,1791,1793,1794,301,1796,1014,1798,1800,1801,1803,1804,1806,1807,1810],{},"To share a workbook in OneDrive or SharePoint from Python, ",[32,1785,220],{},[32,1787,224],{}," with a type (",[32,1790,125],{},[32,1792,132],{},") and scope (",[32,1795,143],{},[32,1797,162],{},[32,1799,180],{},"), optionally with an expiry, and send the returned ",[32,1802,233],{},". Use ",[32,1805,713],{}," with ",[32,1808,1809],{},"requireSignIn"," to grant named people access, silently or with a notification. List the item's permissions to audit access and delete the links and grants that should not outlive the reporting period.",[20,1812,1814],{"id":1813},"frequently-asked-questions","Frequently asked questions",[10,1816,1817,1820],{},[196,1818,1819],{},"How do I create a sharing link for a OneDrive file in Python?","\nPOST to the createLink action on the drive item with a type of view or edit and a scope of anonymous, organization or users; the response's link.webUrl is the URL to share.",[10,1822,1823,1826],{},[196,1824,1825],{},"How do I make a sharing link expire?","\nInclude expirationDateTime as a UTC ISO 8601 timestamp in the createLink request; the link stops working after that time.",[10,1828,1829,1832],{},[196,1830,1831],{},"How do I share a file with specific people without sending an email?","\nUse the invite action with their addresses, a role, requireSignIn set to true and sendInvitation set to false.",[10,1834,1835,1838],{},[196,1836,1837],{},"How do I remove a sharing link with Microsoft Graph?","\nList the item's permissions, find the one for that link and send a DELETE request for that permission ID.",[20,1840,1842],{"id":1841},"related","Related",[1738,1844,1845,1851,1858,1865],{},[1741,1846,1847,1848,1850],{},"Up one level: ",[14,1849,17],{"href":16}," — Excel in the cloud from Python.",[1741,1852,1853,1857],{},[14,1854,1856],{"href":1855},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fcopy-a-template-workbook-in-sharepoint-with-microsoft-graph\u002F","Copy a Template Workbook in SharePoint with Microsoft Graph"," — creating per-project workbooks.",[1741,1859,1860,1864],{},[14,1861,1863],{"href":1862},"\u002Fautomating-reporting-workflows\u002Fpublishing-excel-reports-to-cloud-storage\u002Fupload-an-excel-report-to-sharepoint-with-python\u002F","Upload an Excel Report to SharePoint with Python"," — getting the report there.",[1741,1866,1867,1871],{},[14,1868,1870],{"href":1869},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fauthenticate-to-microsoft-graph-with-msal-for-excel-automation\u002F","Authenticate to Microsoft Graph with MSAL for Excel Automation"," — the token these calls need.",[1873,1874,1875],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}",{"title":30,"searchDepth":254,"depth":254,"links":1877},[1878,1879,1880,1881,1882,1883,1884,1885,1886],{"id":22,"depth":254,"text":23},{"id":72,"depth":254,"text":73},{"id":213,"depth":254,"text":214},{"id":706,"depth":254,"text":707},{"id":1191,"depth":254,"text":1192},{"id":1735,"depth":254,"text":1736},{"id":1779,"depth":254,"text":1780},{"id":1813,"depth":254,"text":1814},{"id":1841,"depth":254,"text":1842},"2026-10-02","Share an Excel workbook stored in OneDrive or SharePoint from Python with Microsoft Graph: create view or edit links scoped to your organisation or to named people, set an expiry date, invite specific recipients with or without an email, list who has access, and remove links that are no longer needed.","md",[1891,1893,1895,1897],{"q":1819,"a":1892},"POST to the createLink action on the drive item with a type of view or edit and a scope of anonymous, organization or users; the response's link.webUrl is the URL to share.",{"q":1825,"a":1894},"Include expirationDateTime as a UTC ISO 8601 timestamp in the createLink request; the link stops working after that time.",{"q":1831,"a":1896},"Use the invite action with their addresses, a role, requireSignIn set to true and sendInvitation set to false.",{"q":1837,"a":1898},"List the item's permissions, find the one for that link and send a DELETE request for that permission ID.","share an excel file in onedrive with a link using graph",null,{"breadcrumb":1902},[1903,1905,1908],{"name":1904,"item":1318},"Home",{"name":1906,"item":1907},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":17,"item":16},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph",{"title":5,"description":1911},"Share OneDrive and SharePoint workbooks from Python with Microsoft Graph: createLink types and scopes, expiry dates, invite with roles, listing permissions and revoking old links.","share-an-excel-file-in-onedrive-with-a-link-using-graph","automating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fshare-an-excel-file-in-onedrive-with-a-link-using-graph\u002Findex",[1915,1916],"excel-online","publishing","how-to","tFR9yiAZKP8xYWgnhfx8rtijP4GdGI_kFvgfR1M2FbQ",[1920,1924],{"title":1921,"path":1922,"stem":1923,"children":-1},"Run a Report When an Excel File Changes in OneDrive","\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Frun-a-report-when-an-excel-file-changes-in-onedrive","automating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Frun-a-report-when-an-excel-file-changes-in-onedrive\u002Findex",{"title":1925,"path":1926,"stem":1927,"children":-1},"Sort and Filter an Excel Online Table with Microsoft Graph","\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fsort-and-filter-an-excel-online-table-with-microsoft-graph","automating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fsort-and-filter-an-excel-online-table-with-microsoft-graph\u002Findex",[1929,1931],{"path":1930,"title":17},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph",{"path":1932,"title":1906},"\u002Fautomating-reporting-workflows",[],[1935,1937,1940,1943,1946,1948],{"path":1936,"title":1022,"kind":1917},"\u002Fautomating-reporting-workflows\u002Femailing-excel-reports-with-smtplib\u002Fsend-an-excel-report-with-microsoft-graph-api",{"path":1938,"title":1939,"kind":1917},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fadd-a-chart-to-an-excel-online-workbook-with-microsoft-graph","Add a Chart to an Excel Online Workbook with Microsoft Graph",{"path":1941,"title":1942,"kind":1917},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fadd-rename-and-delete-worksheets-with-microsoft-graph","Add, Rename and Delete Worksheets with Microsoft Graph",{"path":1944,"title":1945,"kind":1917},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fappend-rows-to-an-excel-online-table-with-microsoft-graph","Append Rows to an Excel Online Table with Microsoft Graph",{"path":1947,"title":1870,"kind":1917},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fauthenticate-to-microsoft-graph-with-msal-for-excel-automation",{"path":1949,"title":1950,"kind":1917},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fcall-excel-worksheet-functions-through-microsoft-graph","Call Excel Worksheet Functions Through Microsoft Graph",1790972119134]