Skip to content

Commit

Permalink
Created an add_validation method. [Issue burnash#1420]
Browse files Browse the repository at this point in the history
added a generic request.

finsihed the method

conditon type input uses enum from utils

Added a some docs and crave-out for relative dates

Completed the docs.

fixed the position for kwargs

Adding return value

Added a test for `add_validation`

added validation condtion enum

Added a RealtiveDate enum

removed the realtive date enum

fixed format errors

Explicit kwargs for optional params

Removed reference RelativeDate

Added a type check for `condition_type`.

added examples

fixed formatting for docs

Unbounded values to a standard iterable.

Switched typing syntax to be `Optional` for compatibility.

renamed range and  removed blank args.

re ran the test

fixed the doc issue
  • Loading branch information
muddi900 committed Mar 29, 2024
1 parent 3e5ca62 commit e5e9291
Show file tree
Hide file tree
Showing 4 changed files with 684 additions and 6 deletions.
35 changes: 35 additions & 0 deletions gspread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,41 @@ class GridRangeType(StrEnum):
ListOfLists = "ListOfLists"


class ValidationConditionType(StrEnum):
number_greater = "NUMBER_GREATER"
number_greater_than_eq = "NUMBER_GREATER_THAN_EQ"
number_less = "NUMBER_LESS"
number_less_than_eq = "NUMBER_LESS_THAN_EQ"
number_eq = "NUMBER_EQ"
number_not_eq = "NUMBER_NOT_EQ"
number_between = "NUMBER_BETWEEN"
number_not_between = "NUMBER_NOT_BETWEEN"
text_contains = "TEXT_CONTAINS"
text_not_contains = "TEXT_NOT_CONTAINS"
text_starts_with = "TEXT_STARTS_WITH"
text_ends_with = "TEXT_ENDS_WITH"
text_eq = "TEXT_EQ"
text_is_email = "TEXT_IS_EMAIL"
text_is_url = "TEXT_IS_URL"
date_eq = "DATE_EQ"
date_before = "DATE_BEFORE"
date_after = "DATE_AFTER"
date_on_or_before = "DATE_ON_OR_BEFORE"
date_on_or_after = "DATE_ON_OR_AFTER"
date_between = "DATE_BETWEEN"
date_not_between = "DATE_NOT_BETWEEN"
date_is_valid = "DATE_IS_VALID"
one_of_range = "ONE_OF_RANGE"
one_of_list = "ONE_OF_LIST"
blank = "BLANK"
not_blank = "NOT_BLANK"
custom_formula = "CUSTOM_FORMULA"
boolean = "BOOLEAN"
text_not_eq = "TEXT_NOT_EQ"
date_not_eq = "DATE_NOT_EQ"
filter_expression = "FILTER_EXPRESSION"


def convert_credentials(credentials: Credentials) -> Credentials:
module = credentials.__module__
cls = credentials.__class__.__name__
Expand Down
100 changes: 94 additions & 6 deletions gspread/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
PasteOrientation,
PasteType,
T,
ValidationConditionType,
ValueInputOption,
ValueRenderOption,
a1_range_to_grid_range,
Expand Down Expand Up @@ -2091,12 +2092,14 @@ def add_protected_range(
"description": description,
"warningOnly": warning_only,
"requestingUserCanEdit": requesting_user_can_edit,
"editors": None
if warning_only
else {
"users": editor_users_emails,
"groups": editor_groups_emails,
},
"editors": (
None
if warning_only
else {
"users": editor_users_emails,
"groups": editor_groups_emails,
}
),
}
}
}
Expand Down Expand Up @@ -3201,3 +3204,88 @@ def cut_range(
}

return self.client.batch_update(self.spreadsheet_id, body)

def add_validation(
self,
range: str,
condition_type: ValidationConditionType,
values: Iterable[Any],
inputMessage: Optional[str] = None,
strict: bool = False,
showCustomUi: bool = False,
) -> Any:
"""Adds a data validation rule to any given range.
.. note::
``condition_type`` values are explained here: `ConditionType`_
.. _ConditionType: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/other#ConditionType
:param str source: The A1 notation of the source range to move
:param condition_type: The sort of condition to apply.
:param values: List of condition values.
:type values: Any
:param str inputMessage: Message to show for the validation.
:param bool strict: Whether to reject invalid data or not.
:param bool showCustomUi: Whether to show a custom UI(Dropdown) for list values.
**Examples**
.. code-block:: python
import gspread
from gspread.utils import ValidationConditionType
...
ws = spreadsheet.sheet1
ws.add_validation(
'A1',
ValidationConditionType.number_greater,
10,
strict=True,
inputMessage='Value must be greater than 10',
)
ws.add_validation(
'C2:C7',
ValidationConditionType.one_of_list,
'Yes',
'No',
showCustomUi=True
)
"""

if not isinstance(condition_type, ValidationConditionType):
raise TypeError(
"condition_type param should be a valid ValidationConditionType."
)

grid = a1_range_to_grid_range(range, self.id)

body = {
"requests": [
{
"setDataValidation": {
"range": grid,
"rule": {
"condition": {
"type": condition_type,
"values": [
({"userEnteredValue": value}) for value in values
],
},
"showCustomUi": showCustomUi,
"strict": strict,
"inputMessage": inputMessage,
},
}
}
],
}

return self.client.batch_update(self.spreadsheet_id, body)
Loading

0 comments on commit e5e9291

Please sign in to comment.