Skip to content

Commit 897f04a

Browse files
committed
refactor constraints into a separate module
1 parent a30145d commit 897f04a

3 files changed

Lines changed: 82 additions & 47 deletions

File tree

src/bubble_data_api_client/client/raw_client.py

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,10 @@
44

55
import httpx
66

7+
from bubble_data_api_client.constraints import Constraint
78
from bubble_data_api_client.transport import Transport
89

910

10-
# all constraints are of the form:
11-
class BaseConstraint(typing.TypedDict):
12-
key: str
13-
constraint_type: str
14-
15-
16-
# some constraints have a value, some do not
17-
class Constraint(BaseConstraint, total=False):
18-
value: str
19-
20-
2111
# https://manual.bubble.io/core-resources/api/the-bubble-api/the-data-api/data-api-requests#sorting
2212
# in addition to 'sort_field' and 'descending', it is possible to have
2313
# multiple additional sort fields
@@ -26,42 +16,6 @@ class AdditionalSortField(typing.TypedDict):
2616
descending: bool
2717

2818

29-
# https://manual.bubble.io/core-resources/api/the-bubble-api/the-data-api/data-api-requests#constraint-types
30-
class ConstraintTypes:
31-
# Use to test strict equality
32-
EQUALS = "equals"
33-
NOT_EQUAL = "not equal"
34-
35-
# Use to test whether a thing's given field is empty or not
36-
IS_EMPTY = "is_empty"
37-
IS_NOT_EMPTY = "is_not_empty"
38-
39-
# Use to test whether a text field contains a string.
40-
# Text contains will not respect partial words that are not of the same stem.
41-
TEXT_CONTAINS = "text contains"
42-
NOT_TEXT_CONTAINS = "not text contains"
43-
44-
# Use to compare a thing's field value relative to a given value
45-
GREATER_THAN = "greater than"
46-
LESS_THAN = "less than"
47-
48-
# Use to test whether a thing's field is in a list or not for all field types.
49-
IN = "in"
50-
NOT_IN = "not in"
51-
52-
# Use to test whether a list field contains an entry or not for list fields only.
53-
CONTAINS = "contains"
54-
NOT_CONTAINS = "not contains"
55-
56-
# Use to test whether a list field is empty or not for list fields only.
57-
EMPTY = "empty"
58-
NOT_EMPTY = "not empty"
59-
60-
# Use to test if the current thing is within a radius from a central address.#
61-
# To use this, the value sent with the constraint must have an address and a range.
62-
GEOGRAPHIC_SEARCH = "geographic_search"
63-
64-
6519
class RawClient:
6620
"""
6721
Raw Client layer focuses on bubble.io API endpoints.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import typing
2+
3+
4+
# all constraints are of the form:
5+
class BaseConstraint(typing.TypedDict):
6+
key: str
7+
constraint_type: str
8+
9+
10+
# some constraints have a value, some do not
11+
class Constraint(BaseConstraint, total=False):
12+
value: str
13+
14+
15+
def constraint(
16+
key: str,
17+
constraint_type: str,
18+
value: typing.Any = None,
19+
) -> Constraint:
20+
"""Factory method to create a constraint dict."""
21+
result: Constraint = {"key": key, "constraint_type": constraint_type}
22+
if value is not None:
23+
result["value"] = value
24+
return result
25+
26+
27+
# https://manual.bubble.io/core-resources/api/the-bubble-api/the-data-api/data-api-requests#constraint-types
28+
class ConstraintTypes:
29+
# Use to test strict equality
30+
EQUALS = "equals"
31+
NOT_EQUAL = "not equal"
32+
33+
# Use to test whether a thing's given field is empty or not
34+
IS_EMPTY = "is_empty"
35+
IS_NOT_EMPTY = "is_not_empty"
36+
37+
# Use to test whether a text field contains a string.
38+
# Text contains will not respect partial words that are not of the same stem.
39+
TEXT_CONTAINS = "text contains"
40+
NOT_TEXT_CONTAINS = "not text contains"
41+
42+
# Use to compare a thing's field value relative to a given value
43+
GREATER_THAN = "greater than"
44+
LESS_THAN = "less than"
45+
46+
# Use to test whether a thing's field is in a list or not for all field types.
47+
IN = "in"
48+
NOT_IN = "not in"
49+
50+
# Use to test whether a list field contains an entry or not for list fields only.
51+
CONTAINS = "contains"
52+
NOT_CONTAINS = "not contains"
53+
54+
# Use to test whether a list field is empty or not for list fields only.
55+
EMPTY = "empty"
56+
NOT_EMPTY = "not empty"
57+
58+
# Use to test if the current thing is within a radius from a central address.#
59+
# To use this, the value sent with the constraint must have an address and a range.
60+
GEOGRAPHIC_SEARCH = "geographic_search"

src/tests/unit/test_constraints.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from bubble_data_api_client.constraints import ConstraintTypes, constraint
2+
3+
4+
def test_constraint_with_value():
5+
"""Test constraint factory with a value."""
6+
result = constraint("_id", ConstraintTypes.IN, ["uid1", "uid2"])
7+
assert result == {
8+
"key": "_id",
9+
"constraint_type": "in",
10+
"value": ["uid1", "uid2"],
11+
}
12+
13+
14+
def test_constraint_without_value():
15+
"""Test constraint factory without a value."""
16+
result = constraint("field", ConstraintTypes.IS_EMPTY)
17+
assert result == {
18+
"key": "field",
19+
"constraint_type": "is_empty",
20+
}
21+
assert "value" not in result

0 commit comments

Comments
 (0)