[{"data":1,"prerenderedAt":1645},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings":1636},{"id":4,"title":5,"body":6,"dateModified":1605,"datePublished":1605,"description":1606,"extension":1607,"faq":1608,"meta":1617,"navigation":250,"path":1628,"seo":1629,"slug":1632,"stem":1633,"type":1634,"__hash__":1635},"docs\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings\u002Findex.md","Read and Write a Live Excel Workbook with xlwings",{"type":7,"value":8,"toc":1592},"minimark",[9,18,27,180,185,212,215,219,222,352,366,372,376,383,566,576,678,681,782,786,789,894,897,985,988,992,1006,1198,1204,1301,1305,1308,1315,1319,1455,1459,1475,1482,1486,1496,1500,1507,1513,1523,1539,1543,1546,1555,1558,1588],[10,11,12,13,17],"p",{},"openpyxl and pandas read and write the ",[14,15,16],"code",{},".xlsx"," file. xlwings does something different: it drives the Excel application through its automation interface, so the workbook on screen responds to your Python code. That is the difference between \"produce a file\" and \"operate the spreadsheet\" — and it is why xlwings can do two things the file-level libraries cannot: recalculate formulas and run macros.",[10,19,20,21,26],{},"The cost is that Excel must actually be installed and running, which rules out the headless server where most reports are generated. This guide covers the live-workbook workflow — connect, read, write, recalculate, clean up — as part of ",[22,23,25],"a",{"href":24},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002F","Automating Excel with xlwings Basics",".",[28,29,37,38,37,42,37,46,37,53,37,63,37,69,37,74,37,81,37,87,37,90,37,95,37,100,37,104,37,110,37,115,37,119,37,123,37,129,37,134,37,137,37,141,37,145,37,149,37,153,37,156,37,159,37,162,37,167,37,171,37,177],"svg",{"viewBox":30,"role":31,"ariaLabelledBy":32,"xmlns":35,"style":36},"0 0 740 246","img",[33,34],"xw-live-t","xw-live-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:740px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[39,40,41],"title",{"id":33},"Talking to the file versus talking to the application",[43,44,45],"desc",{"id":34},"openpyxl and pandas read and write the .xlsx file on disk, so they never see a formula's result unless Excel cached one. xlwings sends commands to a running Excel application, which owns the calculation engine, the macros and any add-ins, and which writes the file itself when told to save.",[47,48],"rect",{"x":49,"y":49,"width":50,"height":51,"fill":52},"0","740","246","#ffffff",[47,54],{"x":55,"y":56,"width":57,"height":58,"rx":59,"fill":60,"stroke":61,"style":62},"20","46","200","76","12","#ebebfd","var(--brand,#5b5cf0)","stroke-width:2px",[64,65,68],"text",{"x":66,"y":58,"style":67},"120","font-size:12.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Python",[64,70,73],{"x":66,"y":71,"style":72},"100","font-size:11px;fill:var(--muted,#5b6780);text-anchor:middle","your script",[47,75],{"x":76,"y":77,"width":57,"height":78,"rx":59,"fill":79,"stroke":80,"style":62},"290","30","60","#fdefd8","var(--gold,#b4740a)",[64,82,86],{"x":83,"y":84,"style":85},"390","55","font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","openpyxl \u002F pandas",[64,88,89],{"x":83,"y":58,"style":72},"reads and writes the file",[47,91],{"x":76,"y":92,"width":57,"height":78,"rx":59,"fill":93,"stroke":94,"style":62},"112","#d9f4f1","var(--teal,#0f9488)",[64,96,99],{"x":83,"y":97,"style":98},"137","font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","xlwings",[64,101,103],{"x":83,"y":102,"style":72},"158","commands the application",[105,106],"line",{"x1":107,"y1":108,"x2":109,"y2":78,"stroke":80,"style":62},"224","70","286",[111,112],"polygon",{"points":113,"fill":114},"290,59 279,55 281,65","#8a5808",[105,116],{"x1":107,"y1":117,"x2":109,"y2":118,"stroke":94,"style":62},"98","136",[111,120],{"points":121,"fill":122},"290,138 278,133 280,143","#0f766e",[47,124],{"x":125,"y":77,"width":126,"height":78,"rx":59,"fill":127,"stroke":128,"style":62},"556","164","#f0f2f5","var(--line,#cdd5e6)",[64,130,133],{"x":131,"y":84,"style":132},"638","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","report.xlsx",[64,135,136],{"x":131,"y":58,"style":72},"bytes on disk",[47,138],{"x":125,"y":92,"width":126,"height":78,"rx":59,"fill":139,"stroke":140,"style":62},"#5b5cf0","var(--brand-strong,#4338ca)",[64,142,144],{"x":131,"y":97,"style":143},"font-size:12px;font-weight:700;fill:#ffffff;text-anchor:middle","Excel",[64,146,148],{"x":131,"y":102,"style":147},"font-size:11px;fill:rgba(255,255,255,0.9);text-anchor:middle","calc engine · macros",[105,150],{"x1":151,"y1":78,"x2":152,"y2":78,"stroke":80,"style":62},"494","552",[111,154],{"points":155,"fill":114},"556,60 546,55 546,65",[105,157],{"x1":151,"y1":158,"x2":152,"y2":158,"stroke":94,"style":62},"142",[111,160],{"points":161,"fill":122},"556,142 546,137 546,147",[105,163],{"x1":131,"y1":92,"x2":131,"y2":164,"stroke":165,"style":166},"94","var(--muted,#5b6780)","stroke-width:2px;stroke-dasharray:4 3",[111,168],{"points":169,"fill":170},"638,90 632,104 644,104","#5b6780",[64,172,176],{"x":173,"y":174,"style":175},"370","204","font-size:11.5px;fill:var(--muted,#5b6780);text-anchor:middle","Only the lower path can evaluate a formula — which is exactly why it needs Excel installed,",[64,178,179],{"x":173,"y":107,"style":175},"and exactly why it is the wrong choice for an unattended job on a server.",[181,182,184],"h2",{"id":183},"prerequisites","Prerequisites",[186,187,192],"pre",{"className":188,"code":189,"language":190,"meta":191,"style":191},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install xlwings pandas\n","bash","",[14,193,194],{"__ignoreMap":191},[195,196,198,202,206,209],"span",{"class":105,"line":197},1,[195,199,201],{"class":200},"sMTad","pip",[195,203,205],{"class":204},"srMev"," install",[195,207,208],{"class":204}," xlwings",[195,210,211],{"class":204}," pandas\n",[10,213,214],{},"You also need Microsoft Excel installed — on Windows or macOS. xlwings drives the real application, so there is no Linux path and no headless mode. On macOS you will be asked to grant automation permission the first time; on Windows nothing extra is needed.",[181,216,218],{"id":217},"step-1-connect-to-a-workbook","Step 1: Connect to a workbook",[10,220,221],{},"There are three ways in, and choosing the right one avoids most of the confusion:",[186,223,227],{"className":224,"code":225,"language":226,"meta":191,"style":191},"language-python shiki shiki-themes github-light github-dark-high-contrast","import xlwings as xw\n\n# 1. Attach to a workbook that is already open by name\nbook = xw.Book(\"budget.xlsx\")\n\n# 2. Open a file in a NEW, invisible Excel instance — the automation case\napp = xw.App(visible=False, add_book=False)\nbook = app.books.open(\"budget.xlsx\")\n\n# 3. The workbook this script was called from (xlwings add-in \u002F RunPython)\n# book = xw.Book.caller()\n","python",[14,228,229,245,252,259,277,282,288,321,335,340,346],{"__ignoreMap":191},[195,230,231,235,239,242],{"class":105,"line":197},[195,232,234],{"class":233},"s-kum","import",[195,236,238],{"class":237},"skGVy"," xlwings ",[195,240,241],{"class":233},"as",[195,243,244],{"class":237}," xw\n",[195,246,248],{"class":105,"line":247},2,[195,249,251],{"emptyLinePlaceholder":250},true,"\n",[195,253,255],{"class":105,"line":254},3,[195,256,258],{"class":257},"s-wDw","# 1. Attach to a workbook that is already open by name\n",[195,260,262,265,268,271,274],{"class":105,"line":261},4,[195,263,264],{"class":237},"book ",[195,266,267],{"class":233},"=",[195,269,270],{"class":237}," xw.Book(",[195,272,273],{"class":204},"\"budget.xlsx\"",[195,275,276],{"class":237},")\n",[195,278,280],{"class":105,"line":279},5,[195,281,251],{"emptyLinePlaceholder":250},[195,283,285],{"class":105,"line":284},6,[195,286,287],{"class":257},"# 2. Open a file in a NEW, invisible Excel instance — the automation case\n",[195,289,291,294,296,299,303,305,309,312,315,317,319],{"class":105,"line":290},7,[195,292,293],{"class":237},"app ",[195,295,267],{"class":233},[195,297,298],{"class":237}," xw.App(",[195,300,302],{"class":301},"sa561","visible",[195,304,267],{"class":233},[195,306,308],{"class":307},"sP0c6","False",[195,310,311],{"class":237},", ",[195,313,314],{"class":301},"add_book",[195,316,267],{"class":233},[195,318,308],{"class":307},[195,320,276],{"class":237},[195,322,324,326,328,331,333],{"class":105,"line":323},8,[195,325,264],{"class":237},[195,327,267],{"class":233},[195,329,330],{"class":237}," app.books.open(",[195,332,273],{"class":204},[195,334,276],{"class":237},[195,336,338],{"class":105,"line":337},9,[195,339,251],{"emptyLinePlaceholder":250},[195,341,343],{"class":105,"line":342},10,[195,344,345],{"class":257},"# 3. The workbook this script was called from (xlwings add-in \u002F RunPython)\n",[195,347,349],{"class":105,"line":348},11,[195,350,351],{"class":257},"# book = xw.Book.caller()\n",[10,353,354,357,358,361,362,365],{},[14,355,356],{},"xw.Book(\"budget.xlsx\")"," attaches to an open workbook of that name if there is one and opens it otherwise, which is convenient interactively and unpredictable in a script — if a colleague has a different ",[14,359,360],{},"budget.xlsx"," open, that is the one you get. For anything automated, create your own ",[14,363,364],{},"App"," and open the file explicitly.",[10,367,368,371],{},[14,369,370],{},"add_book=False"," stops Excel creating an empty Book1 alongside yours, which is the small annoyance everyone hits first.",[181,373,375],{"id":374},"step-2-read-and-write-ranges","Step 2: Read and write ranges",[10,377,378,379,382],{},"A range's ",[14,380,381],{},".value"," is the whole interface, and it converts in both directions:",[186,384,386],{"className":224,"code":385,"language":226,"meta":191,"style":191},"sheet = book.sheets[\"Budget\"]\n\nprint(sheet[\"B2\"].value)                  # a single cell → a scalar\nprint(sheet[\"A1:C5\"].value)               # a block → a list of row lists\nprint(sheet[\"A1\"].expand().value)         # the whole contiguous block from A1\n\nsheet[\"B2\"].value = 1250.0                # write one cell\nsheet[\"A10\"].value = [[\"North\", 120], [\"South\", 180]]   # write a block\n\nsheet[\"D1\"].value = \"=SUM(B2:B9)\"         # write a formula\nsheet[\"B2:B9\"].number_format = '#,##0.00'\nsheet.autofit(\"c\")                        # widths from the live application\n",[14,387,388,404,408,425,440,455,459,477,515,519,536,551],{"__ignoreMap":191},[195,389,390,393,395,398,401],{"class":105,"line":197},[195,391,392],{"class":237},"sheet ",[195,394,267],{"class":233},[195,396,397],{"class":237}," book.sheets[",[195,399,400],{"class":204},"\"Budget\"",[195,402,403],{"class":237},"]\n",[195,405,406],{"class":105,"line":247},[195,407,251],{"emptyLinePlaceholder":250},[195,409,410,413,416,419,422],{"class":105,"line":254},[195,411,412],{"class":307},"print",[195,414,415],{"class":237},"(sheet[",[195,417,418],{"class":204},"\"B2\"",[195,420,421],{"class":237},"].value)                  ",[195,423,424],{"class":257},"# a single cell → a scalar\n",[195,426,427,429,431,434,437],{"class":105,"line":261},[195,428,412],{"class":307},[195,430,415],{"class":237},[195,432,433],{"class":204},"\"A1:C5\"",[195,435,436],{"class":237},"].value)               ",[195,438,439],{"class":257},"# a block → a list of row lists\n",[195,441,442,444,446,449,452],{"class":105,"line":279},[195,443,412],{"class":307},[195,445,415],{"class":237},[195,447,448],{"class":204},"\"A1\"",[195,450,451],{"class":237},"].expand().value)         ",[195,453,454],{"class":257},"# the whole contiguous block from A1\n",[195,456,457],{"class":105,"line":284},[195,458,251],{"emptyLinePlaceholder":250},[195,460,461,464,466,469,471,474],{"class":105,"line":290},[195,462,463],{"class":237},"sheet[",[195,465,418],{"class":204},[195,467,468],{"class":237},"].value ",[195,470,267],{"class":233},[195,472,473],{"class":307}," 1250.0",[195,475,476],{"class":257},"                # write one cell\n",[195,478,479,481,484,486,488,491,494,496,498,501,504,506,509,512],{"class":105,"line":323},[195,480,463],{"class":237},[195,482,483],{"class":204},"\"A10\"",[195,485,468],{"class":237},[195,487,267],{"class":233},[195,489,490],{"class":237}," [[",[195,492,493],{"class":204},"\"North\"",[195,495,311],{"class":237},[195,497,66],{"class":307},[195,499,500],{"class":237},"], [",[195,502,503],{"class":204},"\"South\"",[195,505,311],{"class":237},[195,507,508],{"class":307},"180",[195,510,511],{"class":237},"]]   ",[195,513,514],{"class":257},"# write a block\n",[195,516,517],{"class":105,"line":337},[195,518,251],{"emptyLinePlaceholder":250},[195,520,521,523,526,528,530,533],{"class":105,"line":342},[195,522,463],{"class":237},[195,524,525],{"class":204},"\"D1\"",[195,527,468],{"class":237},[195,529,267],{"class":233},[195,531,532],{"class":204}," \"=SUM(B2:B9)\"",[195,534,535],{"class":257},"         # write a formula\n",[195,537,538,540,543,546,548],{"class":105,"line":348},[195,539,463],{"class":237},[195,541,542],{"class":204},"\"B2:B9\"",[195,544,545],{"class":237},"].number_format ",[195,547,267],{"class":233},[195,549,550],{"class":204}," '#,##0.00'\n",[195,552,554,557,560,563],{"class":105,"line":553},12,[195,555,556],{"class":237},"sheet.autofit(",[195,558,559],{"class":204},"\"c\"",[195,561,562],{"class":237},")                        ",[195,564,565],{"class":257},"# widths from the live application\n",[10,567,568,571,572,575],{},[14,569,570],{},"expand()"," is the one to know: it grows the range to the edges of the contiguous block, which is how you read \"whatever the user typed\" without hard-coding an end row. And ",[14,573,574],{},"autofit"," is genuinely Excel's autofit — the thing no file-level library can do, because the widths depend on font metrics only the application knows.",[28,577,37,582,37,585,37,588,37,591,37,596,37,603,37,608,37,611,37,615,37,622,37,625,37,627,37,630,37,633,37,635,37,640,37,644,37,648,37,651,37,654,37,657,37,660,37,665,37,668,37,672,37,675],{"viewBox":578,"role":31,"ariaLabelledBy":579,"xmlns":35,"style":36},"0 0 740 218",[580,581],"xw-cost-t","xw-cost-d",[39,583,584],{"id":580},"Why block reads and writes are so much faster than cell loops",[43,586,587],{"id":581},"Every range access crosses the boundary between Python and the Excel process, and the crossing costs far more than the data. A thousand single-cell writes make a thousand crossings; assigning a list of lists to one range makes one, carrying the same values.",[47,589],{"x":49,"y":49,"width":50,"height":590,"fill":52},"218",[64,592,595],{"x":593,"y":77,"style":594},"184","font-size:12.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","a loop over cells",[47,597],{"x":598,"y":599,"width":600,"height":601,"rx":602,"fill":60,"stroke":61,"style":62},"24","52","86","96","10",[64,604,68],{"x":605,"y":606,"style":607},"67","106","font-size:11px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[47,609],{"x":610,"y":599,"width":600,"height":601,"rx":602,"fill":127,"stroke":128,"style":62},"258",[64,612,144],{"x":613,"y":606,"style":614},"301","font-size:11px;font-weight:700;fill:var(--text,#172033);text-anchor:middle",[105,616],{"x1":617,"y1":618,"x2":619,"y2":618,"stroke":620,"style":621},"114","66","254","var(--accent-ink,#be185d)","stroke-width:1.5px",[105,623],{"x1":617,"y1":624,"x2":619,"y2":624,"stroke":620,"style":621},"80",[105,626],{"x1":617,"y1":164,"x2":619,"y2":164,"stroke":620,"style":621},[105,628],{"x1":617,"y1":629,"x2":619,"y2":629,"stroke":620,"style":621},"108",[105,631],{"x1":617,"y1":632,"x2":619,"y2":632,"stroke":620,"style":621},"122",[105,634],{"x1":617,"y1":118,"x2":619,"y2":118,"stroke":620,"style":621},[64,636,639],{"x":593,"y":637,"style":638},"176","font-size:11.5px;fill:var(--text,#172033);text-anchor:middle","1,000 values → 1,000 crossings",[64,641,643],{"x":593,"y":642,"style":72},"198","tens of seconds, most of it overhead",[64,645,647],{"x":125,"y":77,"style":646},"font-size:12.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","one block assignment",[47,649],{"x":650,"y":599,"width":600,"height":601,"rx":602,"fill":60,"stroke":61,"style":62},"396",[64,652,68],{"x":653,"y":606,"style":607},"439",[47,655],{"x":656,"y":599,"width":600,"height":601,"rx":602,"fill":127,"stroke":128,"style":62},"630",[64,658,144],{"x":659,"y":606,"style":614},"673",[105,661],{"x1":662,"y1":71,"x2":663,"y2":71,"stroke":94,"style":664},"486","626","stroke-width:3px",[111,666],{"points":667,"fill":122},"630,100 618,94 618,106",[64,669,647],{"x":125,"y":670,"style":671},"42","font-size:11px;font-weight:600;fill:var(--teal-ink,#0b6157);text-anchor:middle",[64,673,674],{"x":125,"y":637,"style":638},"1,000 values → 1 crossing",[64,676,677],{"x":125,"y":642,"style":72},"a fraction of a second, same result",[10,679,680],{},"DataFrames go both ways with an options call:",[186,682,684],{"className":224,"code":683,"language":226,"meta":191,"style":191},"import pandas as pd\n\ndf = sheet[\"A1\"].expand().options(pd.DataFrame, index=False).value\ndf[\"variance\"] = df[\"actual\"] - df[\"budget\"]\nsheet[\"G1\"].options(index=False).value = df\n",[14,685,686,698,702,727,758],{"__ignoreMap":191},[195,687,688,690,693,695],{"class":105,"line":197},[195,689,234],{"class":233},[195,691,692],{"class":237}," pandas ",[195,694,241],{"class":233},[195,696,697],{"class":237}," pd\n",[195,699,700],{"class":105,"line":247},[195,701,251],{"emptyLinePlaceholder":250},[195,703,704,707,709,712,714,717,720,722,724],{"class":105,"line":254},[195,705,706],{"class":237},"df ",[195,708,267],{"class":233},[195,710,711],{"class":237}," sheet[",[195,713,448],{"class":204},[195,715,716],{"class":237},"].expand().options(pd.DataFrame, ",[195,718,719],{"class":301},"index",[195,721,267],{"class":233},[195,723,308],{"class":307},[195,725,726],{"class":237},").value\n",[195,728,729,732,735,738,740,743,746,748,751,753,756],{"class":105,"line":261},[195,730,731],{"class":237},"df[",[195,733,734],{"class":204},"\"variance\"",[195,736,737],{"class":237},"] ",[195,739,267],{"class":233},[195,741,742],{"class":237}," df[",[195,744,745],{"class":204},"\"actual\"",[195,747,737],{"class":237},[195,749,750],{"class":233},"-",[195,752,742],{"class":237},[195,754,755],{"class":204},"\"budget\"",[195,757,403],{"class":237},[195,759,760,762,765,768,770,772,774,777,779],{"class":105,"line":279},[195,761,463],{"class":237},[195,763,764],{"class":204},"\"G1\"",[195,766,767],{"class":237},"].options(",[195,769,719],{"class":301},[195,771,267],{"class":233},[195,773,308],{"class":307},[195,775,776],{"class":237},").value ",[195,778,267],{"class":233},[195,780,781],{"class":237}," df\n",[181,783,785],{"id":784},"step-3-recalculate-then-read-the-result","Step 3: Recalculate, then read the result",[10,787,788],{},"This is the capability that justifies xlwings. openpyxl reads formula text, or a cached value that may not exist; xlwings asks the running application, so the number is the number Excel just computed:",[186,790,792],{"className":224,"code":791,"language":226,"meta":191,"style":191},"book.app.calculate()                       # recalculate everything\n\ntotal = sheet[\"D1\"].value                  # the computed number, not \"=SUM(B2:B9)\"\nprint(f\"total: {total:,.2f}\")\n\nsheet[\"B3\"].value = 999.0\nbook.app.calculate()\nprint(\"after edit:\", sheet[\"D1\"].value)\n",[14,793,794,802,806,823,854,858,872,877],{"__ignoreMap":191},[195,795,796,799],{"class":105,"line":197},[195,797,798],{"class":237},"book.app.calculate()                       ",[195,800,801],{"class":257},"# recalculate everything\n",[195,803,804],{"class":105,"line":247},[195,805,251],{"emptyLinePlaceholder":250},[195,807,808,811,813,815,817,820],{"class":105,"line":254},[195,809,810],{"class":237},"total ",[195,812,267],{"class":233},[195,814,711],{"class":237},[195,816,525],{"class":204},[195,818,819],{"class":237},"].value                  ",[195,821,822],{"class":257},"# the computed number, not \"=SUM(B2:B9)\"\n",[195,824,825,827,830,833,836,840,843,846,849,852],{"class":105,"line":261},[195,826,412],{"class":307},[195,828,829],{"class":237},"(",[195,831,832],{"class":233},"f",[195,834,835],{"class":204},"\"total: ",[195,837,839],{"class":838},"sSjpA","{",[195,841,842],{"class":237},"total",[195,844,845],{"class":233},":,.2f",[195,847,848],{"class":838},"}",[195,850,851],{"class":204},"\"",[195,853,276],{"class":237},[195,855,856],{"class":105,"line":279},[195,857,251],{"emptyLinePlaceholder":250},[195,859,860,862,865,867,869],{"class":105,"line":284},[195,861,463],{"class":237},[195,863,864],{"class":204},"\"B3\"",[195,866,468],{"class":237},[195,868,267],{"class":233},[195,870,871],{"class":307}," 999.0\n",[195,873,874],{"class":105,"line":290},[195,875,876],{"class":237},"book.app.calculate()\n",[195,878,879,881,883,886,889,891],{"class":105,"line":323},[195,880,412],{"class":307},[195,882,829],{"class":237},[195,884,885],{"class":204},"\"after edit:\"",[195,887,888],{"class":237},", sheet[",[195,890,525],{"class":204},[195,892,893],{"class":237},"].value)\n",[10,895,896],{},"If calculation has been set to manual — common in large models — nothing recalculates until you ask. Set it explicitly rather than assuming:",[186,898,900],{"className":224,"code":899,"language":226,"meta":191,"style":191},"book.app.calculation = \"manual\"            # batch a lot of writes...\nfor r, value in enumerate(new_values, start=2):\n    sheet[f\"B{r}\"].value = value\nbook.app.calculation = \"automatic\"         # ...then recalculate once\nbook.app.calculate()\n",[14,901,902,915,943,969,981],{"__ignoreMap":191},[195,903,904,907,909,912],{"class":105,"line":197},[195,905,906],{"class":237},"book.app.calculation ",[195,908,267],{"class":233},[195,910,911],{"class":204}," \"manual\"",[195,913,914],{"class":257},"            # batch a lot of writes...\n",[195,916,917,920,923,926,929,932,935,937,940],{"class":105,"line":247},[195,918,919],{"class":233},"for",[195,921,922],{"class":237}," r, value ",[195,924,925],{"class":233},"in",[195,927,928],{"class":307}," enumerate",[195,930,931],{"class":237},"(new_values, ",[195,933,934],{"class":301},"start",[195,936,267],{"class":233},[195,938,939],{"class":307},"2",[195,941,942],{"class":237},"):\n",[195,944,945,948,950,953,955,958,960,962,964,966],{"class":105,"line":254},[195,946,947],{"class":237},"    sheet[",[195,949,832],{"class":233},[195,951,952],{"class":204},"\"B",[195,954,839],{"class":838},[195,956,957],{"class":237},"r",[195,959,848],{"class":838},[195,961,851],{"class":204},[195,963,468],{"class":237},[195,965,267],{"class":233},[195,967,968],{"class":237}," value\n",[195,970,971,973,975,978],{"class":105,"line":261},[195,972,906],{"class":237},[195,974,267],{"class":233},[195,976,977],{"class":204}," \"automatic\"",[195,979,980],{"class":257},"         # ...then recalculate once\n",[195,982,983],{"class":105,"line":279},[195,984,876],{"class":237},[10,986,987],{},"That pattern is also the main performance lever, because with automatic calculation on, every write triggers a recalculation of everything that depends on it.",[181,989,991],{"id":990},"step-4-save-and-quit-without-leaving-excel-behind","Step 4: Save and quit without leaving Excel behind",[10,993,994,995,997,998,1001,1002,1005],{},"An ",[14,996,364],{}," that is never quit leaves an invisible ",[14,999,1000],{},"EXCEL.EXE"," running, holding a lock on the file. Do the cleanup in ",[14,1003,1004],{},"finally",", or let the context manager do it:",[186,1007,1009],{"className":224,"code":1008,"language":226,"meta":191,"style":191},"import xlwings as xw\n\n\ndef update_budget(path, updates):\n    with xw.App(visible=False, add_book=False) as app:\n        app.display_alerts = False            # no \"overwrite?\" dialog\n        app.screen_updating = False           # faster, and nothing flickers\n        book = app.books.open(path)\n        try:\n            sheet = book.sheets[\"Budget\"]\n            for cell, value in updates.items():\n                sheet[cell].value = value\n            app.calculate()\n            result = sheet[\"D1\"].value\n            book.save()\n        finally:\n            book.close()\n    return result\n",[14,1010,1011,1021,1025,1029,1041,1070,1083,1095,1105,1113,1126,1139,1148,1154,1169,1175,1183,1189],{"__ignoreMap":191},[195,1012,1013,1015,1017,1019],{"class":105,"line":197},[195,1014,234],{"class":233},[195,1016,238],{"class":237},[195,1018,241],{"class":233},[195,1020,244],{"class":237},[195,1022,1023],{"class":105,"line":247},[195,1024,251],{"emptyLinePlaceholder":250},[195,1026,1027],{"class":105,"line":254},[195,1028,251],{"emptyLinePlaceholder":250},[195,1030,1031,1034,1038],{"class":105,"line":261},[195,1032,1033],{"class":233},"def",[195,1035,1037],{"class":1036},"s_Opv"," update_budget",[195,1039,1040],{"class":237},"(path, updates):\n",[195,1042,1043,1046,1048,1050,1052,1054,1056,1058,1060,1062,1065,1067],{"class":105,"line":279},[195,1044,1045],{"class":233},"    with",[195,1047,298],{"class":237},[195,1049,302],{"class":301},[195,1051,267],{"class":233},[195,1053,308],{"class":307},[195,1055,311],{"class":237},[195,1057,314],{"class":301},[195,1059,267],{"class":233},[195,1061,308],{"class":307},[195,1063,1064],{"class":237},") ",[195,1066,241],{"class":233},[195,1068,1069],{"class":237}," app:\n",[195,1071,1072,1075,1077,1080],{"class":105,"line":284},[195,1073,1074],{"class":237},"        app.display_alerts ",[195,1076,267],{"class":233},[195,1078,1079],{"class":307}," False",[195,1081,1082],{"class":257},"            # no \"overwrite?\" dialog\n",[195,1084,1085,1088,1090,1092],{"class":105,"line":290},[195,1086,1087],{"class":237},"        app.screen_updating ",[195,1089,267],{"class":233},[195,1091,1079],{"class":307},[195,1093,1094],{"class":257},"           # faster, and nothing flickers\n",[195,1096,1097,1100,1102],{"class":105,"line":323},[195,1098,1099],{"class":237},"        book ",[195,1101,267],{"class":233},[195,1103,1104],{"class":237}," app.books.open(path)\n",[195,1106,1107,1110],{"class":105,"line":337},[195,1108,1109],{"class":233},"        try",[195,1111,1112],{"class":237},":\n",[195,1114,1115,1118,1120,1122,1124],{"class":105,"line":342},[195,1116,1117],{"class":237},"            sheet ",[195,1119,267],{"class":233},[195,1121,397],{"class":237},[195,1123,400],{"class":204},[195,1125,403],{"class":237},[195,1127,1128,1131,1134,1136],{"class":105,"line":348},[195,1129,1130],{"class":233},"            for",[195,1132,1133],{"class":237}," cell, value ",[195,1135,925],{"class":233},[195,1137,1138],{"class":237}," updates.items():\n",[195,1140,1141,1144,1146],{"class":105,"line":553},[195,1142,1143],{"class":237},"                sheet[cell].value ",[195,1145,267],{"class":233},[195,1147,968],{"class":237},[195,1149,1151],{"class":105,"line":1150},13,[195,1152,1153],{"class":237},"            app.calculate()\n",[195,1155,1157,1160,1162,1164,1166],{"class":105,"line":1156},14,[195,1158,1159],{"class":237},"            result ",[195,1161,267],{"class":233},[195,1163,711],{"class":237},[195,1165,525],{"class":204},[195,1167,1168],{"class":237},"].value\n",[195,1170,1172],{"class":105,"line":1171},15,[195,1173,1174],{"class":237},"            book.save()\n",[195,1176,1178,1181],{"class":105,"line":1177},16,[195,1179,1180],{"class":233},"        finally",[195,1182,1112],{"class":237},[195,1184,1186],{"class":105,"line":1185},17,[195,1187,1188],{"class":237},"            book.close()\n",[195,1190,1192,1195],{"class":105,"line":1191},18,[195,1193,1194],{"class":233},"    return",[195,1196,1197],{"class":237}," result\n",[10,1199,1200,1203],{},[14,1201,1202],{},"display_alerts = False"," matters more than it looks: an automation run that trips a modal dialog — \"a file already exists\", \"this workbook contains links\" — blocks forever with no visible window to click. Turning alerts off makes Excel take the default action instead of waiting for a human who cannot see the prompt.",[28,1205,37,1210,37,1213,37,1216,37,1221,37,1225,37,1230,37,1236,37,1238,37,1242,37,1245,37,1249,37,1253,37,1257,37,1261,37,1266,37,1269,37,1271,37,1275,37,1277,37,1281,37,1284,37,1288,37,1291,37,1294,37,1297],{"viewBox":1206,"role":31,"ariaLabelledBy":1207,"xmlns":35,"style":36},"8 6 706 200",[1208,1209],"xw-clean-t","xw-clean-d",[39,1211,1212],{"id":1208},"What happens when the Excel instance is not closed",[43,1214,1215],{"id":1209},"If an exception skips the cleanup, the hidden Excel process keeps running and keeps its lock on the workbook. Each subsequent run starts another one, memory climbs, and the next job that tries to write the file fails with a permission error. Wrapping the work in a context manager closes the application on every path.",[47,1217],{"x":1218,"y":1219,"width":1220,"height":57,"fill":52},"8","6","706",[64,1222,1224],{"x":593,"y":1223,"style":594},"32","no cleanup on the error path",[47,1226],{"x":598,"y":599,"width":1227,"height":1228,"rx":1218,"fill":1229,"stroke":620,"style":62},"90","40","#fce9e9",[64,1231,1235],{"x":1232,"y":1233,"style":1234},"69","77","font-size:11px;fill:var(--text,#172033);text-anchor:middle","run 1",[47,1237],{"x":632,"y":599,"width":1227,"height":1228,"rx":1218,"fill":1229,"stroke":620,"style":62},[64,1239,1241],{"x":1240,"y":1233,"style":1234},"167","run 2",[47,1243],{"x":1244,"y":599,"width":1227,"height":1228,"rx":1218,"fill":1229,"stroke":620,"style":62},"220",[64,1246,1248],{"x":1247,"y":1233,"style":1234},"265","run 3",[64,1250,1252],{"x":593,"y":1251,"style":638},"118","three hidden EXCEL.EXE processes",[64,1254,1256],{"x":593,"y":1255,"style":72},"144","each holding a lock on the workbook,",[64,1258,1260],{"x":593,"y":1259,"style":72},"162","each keeping its memory",[64,1262,1265],{"x":593,"y":1263,"style":1264},"192","font-size:11.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","the next write fails: permission denied",[64,1267,1268],{"x":125,"y":1223,"style":646},"with xw.App(...) as app:",[47,1270],{"x":650,"y":599,"width":1227,"height":1228,"rx":1218,"fill":93,"stroke":94,"style":62},[64,1272,1274],{"x":1273,"y":1233,"style":1234},"441","run 1 ✓",[47,1276],{"x":151,"y":599,"width":1227,"height":1228,"rx":1218,"fill":93,"stroke":94,"style":62},[64,1278,1280],{"x":1279,"y":1233,"style":1234},"539","run 2 ✗",[47,1282],{"x":1283,"y":599,"width":1227,"height":1228,"rx":1218,"fill":93,"stroke":94,"style":62},"592",[64,1285,1287],{"x":1286,"y":1233,"style":1234},"637","run 3 ✓",[64,1289,1290],{"x":125,"y":1251,"style":638},"no processes left, even after the failure",[64,1292,1293],{"x":125,"y":1255,"style":72},"the exception still propagates —",[64,1295,1296],{"x":125,"y":1259,"style":72},"it is the cleanup that is guaranteed",[64,1298,1300],{"x":125,"y":1263,"style":1299},"font-size:11.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","the file is free for the next run",[181,1302,1304],{"id":1303},"step-5-know-when-to-stop-using-it","Step 5: Know when to stop using it",[10,1306,1307],{},"xlwings is the right tool for a narrow set of jobs: recalculating a model whose formulas you cannot reimplement, running a macro, using an add-in's functions, exporting with Excel's own renderer, or updating a workbook a colleague has open in front of them.",[10,1309,1310,1311,26],{},"It is the wrong tool for generating a report on a schedule. Microsoft does not support Office automation from a service or unattended session, and in practice it fails in the ways you would expect: a modal dialog with nobody to dismiss it, a licence prompt after an update, an orphaned process holding the output file. A scheduled job should build the workbook with openpyxl or xlsxwriter and, if a PDF is needed, use LibreOffice headless — the routes compared in ",[22,1312,1314],{"href":1313},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002F","Exporting Excel Reports to PDF",[181,1316,1318],{"id":1317},"common-pitfalls-and-gotchas","Common pitfalls and gotchas",[1320,1321,1322,1338],"table",{},[1323,1324,1325],"thead",{},[1326,1327,1328,1332,1335],"tr",{},[1329,1330,1331],"th",{},"Symptom",[1329,1333,1334],{},"Cause",[1329,1336,1337],{},"Fix",[1339,1340,1341,1363,1376,1393,1408,1422,1433,1444],"tbody",{},[1326,1342,1343,1347,1353],{},[1344,1345,1346],"td",{},"Invisible Excel processes pile up",[1344,1348,1349,1350,1352],{},"The ",[14,1351,364],{}," was never quit",[1344,1354,1355,1356,1359,1360],{},"Use ",[14,1357,1358],{},"with xw.App(...)",", or ",[14,1361,1362],{},"try\u002Ffinally",[1326,1364,1365,1368,1371],{},[1344,1366,1367],{},"Script hangs with no window",[1344,1369,1370],{},"A modal dialog is waiting",[1344,1372,1373],{},[14,1374,1375],{},"app.display_alerts = False",[1326,1377,1378,1381,1387],{},[1344,1379,1380],{},"Wrong workbook was modified",[1344,1382,1383,1386],{},[14,1384,1385],{},"xw.Book(name)"," attached to someone else's",[1344,1388,1389,1390,1392],{},"Create an ",[14,1391,364],{}," and open by full path",[1326,1394,1395,1398,1404],{},[1344,1396,1397],{},"An empty Book1 appears",[1344,1399,1400,1401],{},"Default new workbook on ",[14,1402,1403],{},"App()",[1344,1405,1406],{},[14,1407,370],{},[1326,1409,1410,1413,1416],{},[1344,1411,1412],{},"Formula result is stale",[1344,1414,1415],{},"Calculation set to manual",[1344,1417,1418,1421],{},[14,1419,1420],{},"app.calculate()"," after the writes",[1326,1423,1424,1427,1430],{},[1344,1425,1426],{},"Very slow with many writes",[1344,1428,1429],{},"Recalculating on every cell",[1344,1431,1432],{},"Batch writes, calculation manual, calculate once",[1326,1434,1435,1438,1441],{},[1344,1436,1437],{},"Fails on the server",[1344,1439,1440],{},"Office automation is unsupported unattended",[1344,1442,1443],{},"Use openpyxl for scheduled jobs",[1326,1445,1446,1449,1452],{},[1344,1447,1448],{},"Permission denied on save",[1344,1450,1451],{},"Another instance still has the file",[1344,1453,1454],{},"Close orphaned processes; check Task Manager",[181,1456,1458],{"id":1457},"performance-and-scale-notes","Performance and scale notes",[10,1460,1461,1462,1466,1467,1470,1471,1474],{},"Every property access crosses a process boundary, so the cost is per ",[1463,1464,1465],"em",{},"call",", not per cell. Writing a thousand cells one at a time is slow; writing them as one block assigned to ",[14,1468,1469],{},"sheet[\"A1\"].value"," is fast. The same is true for reading — ",[14,1472,1473],{},"expand().value"," once beats a loop over cells by an order of magnitude.",[10,1476,1477,1478,1481],{},"Beyond that, the two settings that matter are ",[14,1479,1480],{},"screen_updating = False"," and manual calculation while a batch runs. With both applied, a bulk update that took minutes typically drops to seconds. If it is still slow after that, the workbook's own formulas are the bottleneck, and no amount of Python tuning will help.",[181,1483,1485],{"id":1484},"conclusion","Conclusion",[10,1487,1488,1489,1492,1493,1495],{},"xlwings is the tool for when the spreadsheet has to be ",[1463,1490,1491],{},"operated"," rather than produced: connect to the application, read and write ranges as blocks, force a calculation and read the numbers Excel actually computed. Open your own ",[14,1494,364],{}," rather than attaching by name, turn off alerts so no invisible dialog can block the run, batch the writes with calculation set to manual, and quit through a context manager so nothing is left holding the file. When the job has none of those needs, openpyxl is simpler and runs where Excel does not.",[181,1497,1499],{"id":1498},"frequently-asked-questions","Frequently asked questions",[10,1501,1502,1506],{},[1503,1504,1505],"strong",{},"When is xlwings the right tool rather than openpyxl?","\nWhen you need Excel itself — to recalculate formulas, run a macro, use an add-in, or drive a workbook someone has open. For generating or reading files unattended, openpyxl and pandas are faster and need no Excel installation.",[10,1508,1509,1512],{},[1503,1510,1511],{},"Does this work on a server?","\nNot reliably, and Microsoft does not support Office automation in a service context. xlwings needs a real Excel installation and an interactive session; a scheduled job on a server should use openpyxl instead.",[10,1514,1515,1518,1519,1522],{},[1503,1516,1517],{},"How do I read the value a formula produced?","\nRead the range after Excel has calculated. Unlike openpyxl, xlwings asks the live application, so ",[14,1520,1521],{},"range.value"," returns the computed number rather than the formula text or a stale cached value.",[10,1524,1525,1528,1529,1531,1532,1534,1535,1538],{},[1503,1526,1527],{},"Why is an invisible Excel process left running?","\nThe ",[14,1530,364],{}," was never quit, usually because an exception skipped the cleanup. Wrap the work in ",[14,1533,1362],{},", or use ",[14,1536,1537],{},"xw.App"," as a context manager, and check Task Manager while developing.",[181,1540,1542],{"id":1541},"related","Related",[10,1544,1545],{},"Up to the parent guide:",[1547,1548,1549],"ul",{},[1550,1551,1552,1554],"li",{},[22,1553,25],{"href":24}," — installation, the object model and where xlwings fits.",[10,1556,1557],{},"Related guides:",[1547,1559,1560,1567,1574,1581],{},[1550,1561,1562,1566],{},[22,1563,1565],{"href":1564},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fxlwings-run-macro-from-python-example\u002F","xlwings: Run a Macro from Python"," — the other job only the live application can do.",[1550,1568,1569,1573],{},[22,1570,1572],{"href":1571},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fread-formula-results-with-openpyxl-data-only\u002F","Read Formula Results with openpyxl data_only"," — why the file-level route cannot answer this question.",[1550,1575,1576,1580],{},[22,1577,1579],{"href":1578},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fconvert-excel-formulas-to-values-with-python\u002F","Convert Excel Formulas to Values with Python"," — freezing a calculated model into plain numbers.",[1550,1582,1583,1587],{},[22,1584,1586],{"href":1585},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fconvert-excel-file-to-pdf-with-python\u002F","Convert an Excel File to PDF with Python"," — where Excel's own renderer is worth the dependency.",[1589,1590,1591],"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 .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}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}",{"title":191,"searchDepth":247,"depth":247,"links":1593},[1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604],{"id":183,"depth":247,"text":184},{"id":217,"depth":247,"text":218},{"id":374,"depth":247,"text":375},{"id":784,"depth":247,"text":785},{"id":990,"depth":247,"text":991},{"id":1303,"depth":247,"text":1304},{"id":1317,"depth":247,"text":1318},{"id":1457,"depth":247,"text":1458},{"id":1484,"depth":247,"text":1485},{"id":1498,"depth":247,"text":1499},{"id":1541,"depth":247,"text":1542},"2026-08-10","Drive the open application rather than the file: connect to a running workbook, read and write ranges, force a recalculation, read what the formulas produced, and clean up so no invisible Excel is left behind.","md",[1609,1611,1613,1615],{"q":1505,"a":1610},"When you need Excel itself — to recalculate formulas, run a macro, use an add-in, or drive a workbook someone has open. For generating or reading files unattended, openpyxl and pandas are faster and need no Excel installation.",{"q":1511,"a":1612},"Not reliably, and Microsoft does not support Office automation in a service context. xlwings needs a real Excel installation and an interactive session; a scheduled job on a server should use openpyxl instead.",{"q":1517,"a":1614},"Read the range after Excel has calculated. Unlike openpyxl, xlwings asks the live application, so range.value returns the computed number rather than the formula text or a stale cached value.",{"q":1527,"a":1616},"The App was never quit, usually because an exception skipped the cleanup. Wrap the work in try\u002Ffinally, or use xw.App as a context manager, and check Task Manager while developing.",{"breadcrumb":1618},[1619,1622,1625,1626],{"name":1620,"item":1621},"Home","\u002F",{"name":1623,"item":1624},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":25,"item":24},{"name":5,"item":1627},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings\u002F","\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings",{"title":1630,"description":1631},"Read & Write a Live Excel Workbook with xlwings","Use xlwings to control a running Excel instance from Python — connect to an open book, read and write ranges and DataFrames, recalculate, read computed values, and quit cleanly.","read-and-write-a-live-excel-workbook-with-xlwings","getting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fread-and-write-a-live-excel-workbook-with-xlwings\u002Findex","how-to","Viws3lskAd8GoBDuF3Vh_CHpVChDJeO-z5B33bRcDYk",[1637,1641],{"title":1638,"path":1639,"stem":1640,"children":-1},"Call Python from Excel with an xlwings UDF","\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fcall-python-from-excel-with-xlwings-udf","getting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fcall-python-from-excel-with-xlwings-udf\u002Findex",{"title":1642,"path":1643,"stem":1644,"children":-1},"xlwings: Run a VBA Macro From Python (Example)","\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fxlwings-run-macro-from-python-example","getting-started-with-python-excel-automation\u002Fautomating-excel-with-xlwings-basics\u002Fxlwings-run-macro-from-python-example\u002Findex",1786800028673]