Skip to content

Commit db97486

Browse files
author
Charles Larivier
committed
feat: add Segment
1 parent f17760b commit db97486

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

metabase/resources/segment.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from __future__ import annotations
2+
3+
from datetime import datetime
4+
from typing import List, Optional
5+
6+
from metabase.resource import ListResource, CreateResource, GetResource, UpdateResource
7+
from metabase.missing import MISSING
8+
9+
10+
class Segment(ListResource, CreateResource, GetResource, UpdateResource):
11+
ENDPOINT = "/api/segment"
12+
13+
id: int
14+
table_id: int
15+
creator_id: int
16+
17+
name: str
18+
description: str
19+
definition: dict
20+
points_of_interest: str
21+
caveats: str
22+
23+
show_in_getting_started: bool
24+
archived: bool
25+
26+
updated_at: str
27+
created_at: str
28+
29+
@classmethod
30+
def list(cls) -> List[Segment]:
31+
return super(Segment, cls).list()
32+
33+
@classmethod
34+
def get(cls, id: int) -> Segment:
35+
return super(Segment, cls).get(id)
36+
37+
@classmethod
38+
def create(
39+
cls,
40+
name: str,
41+
table_id: int,
42+
definition: dict,
43+
description: str = "Created by metabase-python.",
44+
**kwargs
45+
) -> Segment:
46+
return super(Segment, cls).create(
47+
name=name, table_id=table_id, definition=definition, description=description, **kwargs
48+
)
49+
50+
def update(
51+
self,
52+
revision_message: str = "Updated by metabase-python.",
53+
name: str = MISSING,
54+
description: str = MISSING,
55+
definition: dict = MISSING,
56+
show_in_getting_started: str = MISSING,
57+
points_of_interest: str = MISSING,
58+
caveats: str = MISSING,
59+
archived: bool = MISSING,
60+
**kwargs
61+
) -> None:
62+
return super(Segment, self).update(
63+
revision_message=revision_message,
64+
name=name,
65+
description=description,
66+
definition=definition,
67+
points_of_interest=points_of_interest,
68+
caveats=caveats,
69+
archived=archived,
70+
show_in_getting_started=show_in_getting_started,
71+
**kwargs
72+
)
73+
74+
def archive(self):
75+
return self.update(archived=True, revision_message="Archived by metabase-python.")

tests/resources/test_segment.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
from exceptions import NotFoundError
2+
from metabase.resources.segment import Segment
3+
4+
from tests.helpers import IntegrationTestCase
5+
6+
7+
class SegmentTests(IntegrationTestCase):
8+
def tearDown(self) -> None:
9+
segments = Segment.list()
10+
for segment in segments:
11+
segment.archive()
12+
13+
def test_list(self):
14+
"""Ensure Segment.list returns a list of Segment instances."""
15+
# fixture
16+
_ = Segment.create(
17+
name="My Segment",
18+
table_id=1,
19+
definition={
20+
"filter": ["=", ["field", 1, None], 0],
21+
}
22+
)
23+
_ = Segment.create(
24+
name="My Segment",
25+
table_id=1,
26+
definition={
27+
"filter": ["=", ["field", 1, None], 0],
28+
}
29+
)
30+
31+
segments = Segment.list()
32+
33+
self.assertIsInstance(segments, list)
34+
self.assertEqual(2, len(segments))
35+
self.assertTrue(all([isinstance(m, Segment) for m in segments]))
36+
37+
def test_get(self):
38+
"""
39+
Ensure Segment.get returns a Segment instance for a given ID, or
40+
raises a NotFoundError when it does not exist.
41+
"""
42+
# fixture
43+
segment = Segment.create(
44+
name="My Segment",
45+
table_id=1,
46+
definition={
47+
"filter": ["=", ["field", 1, None], 0],
48+
}
49+
)
50+
self.assertIsInstance(segment, Segment)
51+
52+
m = Segment.get(segment.id)
53+
self.assertIsInstance(m, Segment)
54+
self.assertEqual(segment.id, m.id)
55+
56+
with self.assertRaises(NotFoundError):
57+
_ = Segment.get(12345)
58+
59+
def test_create(self):
60+
"""Ensure Segment.create creates a Segment in Metabase and returns a Segment instance."""
61+
segment = Segment.create(
62+
name="My Segment",
63+
table_id=1,
64+
definition={
65+
"filter": ["=", ["field", 1, None], 0],
66+
}
67+
)
68+
69+
self.assertIsInstance(segment, Segment)
70+
self.assertEqual("My Segment", segment.name)
71+
self.assertEqual(1, segment.table_id)
72+
self.assertEqual({"filter": ["=", ["field", 1, None], 0]}, segment.definition)
73+
74+
def test_update(self):
75+
"""Ensure Segment.update updates an existing Segment in Metabase."""
76+
# fixture
77+
segment = Segment.create(
78+
name="My Segment",
79+
table_id=1,
80+
definition={
81+
"filter": ["=", ["field", 1, None], 0],
82+
}
83+
)
84+
85+
self.assertIsInstance(segment, Segment)
86+
self.assertEqual("My Segment", segment.name)
87+
88+
segment.update(
89+
name="New Name"
90+
)
91+
# assert local instance is mutated
92+
self.assertEqual("New Name", segment.name)
93+
94+
# assert metabase object is mutated
95+
m = Segment.get(segment.id)
96+
self.assertEqual("New Name", m.name)
97+
98+
def test_archive(self):
99+
"""Ensure Segment.archive updates archived=True."""
100+
# fixture
101+
segment = Segment.create(
102+
name="My Segment",
103+
table_id=1,
104+
definition={
105+
"filter": ["=", ["field", 1, None], 0],
106+
}
107+
)
108+
109+
self.assertIsInstance(segment, Segment)
110+
self.assertEqual(False, segment.archived)
111+
112+
segment.archive()
113+
# assert local instance is mutated
114+
self.assertEqual(True, segment.archived)
115+
116+
# assert metabase object is mutated
117+
m = Segment.get(segment.id)
118+
self.assertEqual(True, m.archived)
119+

0 commit comments

Comments
 (0)