Adding a ConditionalFormatRule to a worksheet fails with missing sheetId
anderser opened this issue · comments
Describe the bug
Adding a ConditionalFormatRule to a worksheet fails with missing 1 required positional argument: 'sheetId'
Version and Environment
Version of package: 0.3.5
Python interpreter: Python 3.7
OS: OS X
To Reproduce
Steps to reproduce the behavior:
Open a worksheet using gspread and run:
myrule = ConditionalFormatRule(
ranges=[GridRange.from_a1_range('D2:D4', worksheet)],
booleanRule=BooleanRule(
condition=BooleanCondition('TEXT_EQ', ['Gul']),
format=cellFormat(backgroundColorStyle=ColorStyle(rgbColor=Color(1,1,0)))
)
)
rules = get_conditional_format_rules(worksheet)
rules.clear()
rules.append(myrule)
rules.save()
Expected behavior
The cells D2 to D4 should be colored if the value is equal to Gul
. Formatting with format_cell_range
etc works as excepted on the given worksheet.
Additional context
Error message:
lib/python3.7/site-packages/gspread_formatting/util.py", line 101, in _props_to_component
return cls(**kwargs) if (kwargs or not none_if_empty) else None
TypeError: __init__() missing 1 required positional argument: 'sheetId'
Would you be able to post the full stacktrace?
File "/Users/username/workspace/myapp/apps/myapp/management/commands/export_dataframe_to_gsheet.py", line 209, in handle
rules = get_conditional_format_rules(worksheet)
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/conditionals.py", line 17, in get_conditional_format_rules
rules = [ ConditionalFormatRule.from_props(p) for p in sheet.get('conditionalFormats', []) ]
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/conditionals.py", line 17, in <listcomp>
rules = [ ConditionalFormatRule.from_props(p) for p in sheet.get('conditionalFormats', []) ]
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/models.py", line 11, in from_props
return _props_to_component(_CLASSES, _underlower(cls.__name__), props)
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/util.py", line 101, in _props_to_component
return cls(**kwargs) if (kwargs or not none_if_empty) else None
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/conditionals.py", line 245, in __init__
for v in ranges
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/conditionals.py", line 245, in <listcomp>
for v in ranges
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/models.py", line 11, in from_props
return _props_to_component(_CLASSES, _underlower(cls.__name__), props)
File "/Users/username/.local/share/virtualenvs/myapp-EgRxHiym/lib/python3.7/site-packages/gspread_formatting/util.py", line 101, in _props_to_component
return cls(**kwargs) if (kwargs or not none_if_empty) else None
TypeError: __init__() missing 1 required positional argument: 'sheetId'
BTW: print(worksheet)
gives this output:
<Worksheet 'Sheet1' id:0>
And it seems to fail already at rules = get_conditional_format_rules(worksheet)
The test suite has lots of coverage for getting and modifying conditional format rules. Your exception is happening when the sheetId is 0
-- the test suite creates its own sheet for testing and that sheet's id is never 0 since it's never the default Sheet1 of a spreadsheet.
The Sheets API documentation seems to be pretty clear that sheetId
property will always be present for any GridRange object in a JSON payload. And yet the exception you're seeing implies that sheetId
is not present in one or more of the ranges
in the API response JSON. I think it's unlikely, given the code and your stacktrace, that the sheetId property in the API response JSON is 0 and that some client-side code is discarding the property because its value is "false".
Would you be able to turn on requests/http debugging and re-run your script, capturing the API response JSON for get_conditional_format_rules
? That would confirm for us what the API response is including or omitting.
@anderser Well, shucks -- I just changed the test suite locally to work on sheet1
, the default worksheet, and the Sheets API responses truly do omit sheetId
property from GridRange objects. I am very suspicious that this was not the API's behavior until just now!
The fix is to allow GridRange.sheetId to be absent when parsing JSON and to default to 0
in the GridRange
python object. Release 0.3.6 now in PyPI contains the fix, let me know if it works for your example!
Wow! That was a swift bug response! I upgraded now, and it seems to work great. Thank you!
Hi!
I'm using the latest version and I'm getting the exact same stacktrace:
Traceback (most recent call last):
File "C:/Users/Joni/PycharmProjects/Oppilasseuranta/Oppilaskorttien päivittäminen.py", line 88, in <module>
rules = get_conditional_format_rules(worksheet)
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\conditionals.py", line 17, in get_conditional_format_rules
rules = [ ConditionalFormatRule.from_props(p) for p in sheet.get('conditionalFormats', []) ]
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\conditionals.py", line 17, in <listcomp>
rules = [ ConditionalFormatRule.from_props(p) for p in sheet.get('conditionalFormats', []) ]
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\models.py", line 11, in from_props
return _props_to_component(_CLASSES, _underlower(cls.__name__), props)
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\util.py", line 101, in _props_to_component
return cls(**kwargs) if (kwargs or not none_if_empty) else None
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\conditionals.py", line 242, in __init__
for v in ranges
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\conditionals.py", line 242, in <listcomp>
for v in ranges
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\models.py", line 11, in from_props
return _props_to_component(_CLASSES, _underlower(cls.__name__), props)
File "C:\Users\Joni\PycharmProjects\Oppilasseuranta\venv\lib\site-packages\gspread_formatting\util.py", line 101, in _props_to_component
return cls(**kwargs) if (kwargs or not none_if_empty) else None
TypeError: __init__() missing 1 required positional argument: 'sheetId'
My code is exactly the same as anderser had: rules = get_conditional_format_rules(worksheet)
with worksheet
being sheet1
which has the id 0
@Jensiii666 Can you confirm that you're using either 0.3.6 or 0.3.7 of gspread-formatting? Because GridRange.__init__
does not have sheetId
as a positional argument in these versions.
Hey!
Thank you for the answer and pointing me in the right direction. I just noticed that the venv indeed didn't have the updated version after all, so I had updated in the wrong place , haha oh man... All good and working now! :)
@Jensiii666 Glad it's working now, enjoy using the package!