Skip to content

Commit d3ff3d3

Browse files
chore: clean up project (#26)
1 parent ebd4bc3 commit d3ff3d3

10 files changed

Lines changed: 59 additions & 131 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ logs/
3939
.pytype/
4040
.vscode
4141
.cursor
42+
.claude/
43+
AGENTS.md

listeners/events/entity_details_requested.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ def entity_details_requested_callback(event: dict, client: WebClient, logger: lo
6161
json=payload,
6262
)
6363
except SlackResponseError as e:
64-
logger.error(f"Failed to fetch or parse sample data. Error details: {str(e)}", exc_info=e)
64+
logger.error(f"Failed to fetch or parse sample data. Error details: {e}", exc_info=e)
6565
except Exception as e:
6666
logger.error(
67-
f"An unexpected error occurred handling entity_details_requested event: {type(e).__name__} - {str(e)}",
67+
f"An unexpected error occurred handling entity_details_requested event: {type(e).__name__} - {e}",
6868
exc_info=e,
6969
)

listeners/filters.py

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,16 @@
1-
from dataclasses import dataclass
2-
from enum import Enum
3-
from typing import List, Optional
4-
5-
6-
class FilterType(Enum):
7-
MULTI_SELECT = "multi_select"
8-
TOGGLE = "toggle"
9-
10-
11-
@dataclass
12-
class FilterOptions:
13-
name: str
14-
value: str
15-
16-
17-
@dataclass
18-
class Filter:
19-
name: str
20-
display_name: str
21-
type: FilterType
22-
display_name_plural: Optional[str] = None
23-
options: Optional[List[FilterOptions]] = None
24-
25-
26-
LANGUAGES_FILTER = Filter(
27-
name="languages",
28-
display_name="Language",
29-
display_name_plural="Languages",
30-
type=FilterType.MULTI_SELECT.value,
31-
options=[
32-
FilterOptions(name="Python", value="python"),
33-
FilterOptions(name="Java", value="java"),
34-
FilterOptions(name="JavaScript", value="javascript"),
35-
FilterOptions(name="TypeScript", value="typescript"),
1+
LANGUAGES_FILTER = {
2+
"name": "languages",
3+
"display_name": "Language",
4+
"display_name_plural": "Languages",
5+
"type": "multi_select",
6+
"options": [
7+
{"name": "Python", "value": "python"},
8+
{"name": "Java", "value": "java"},
9+
{"name": "JavaScript", "value": "javascript"},
10+
{"name": "TypeScript", "value": "typescript"},
3611
],
37-
)
38-
39-
TEMPLATES_FILTER = Filter(name="template", display_name="Templates", type=FilterType.TOGGLE.value)
12+
}
4013

14+
TEMPLATES_FILTER = {"name": "template", "display_name": "Templates", "type": "toggle"}
4115

42-
SAMPLES_FILTER = Filter(name="sample", display_name="Samples", type=FilterType.TOGGLE.value)
16+
SAMPLES_FILTER = {"name": "sample", "display_name": "Samples", "type": "toggle"}

listeners/functions/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66

77
def register(app: App):
8-
app.function("search", auto_acknowledge=False)(search_step_callback)
9-
app.function("filters", auto_acknowledge=False)(filters_step_callback)
8+
app.function("search", auto_acknowledge=False, ack_timeout=10)(search_step_callback)
9+
app.function("filters", auto_acknowledge=False, ack_timeout=10)(filters_step_callback)

listeners/functions/filters.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,24 @@
11
import logging
2-
from dataclasses import asdict
3-
from typing import Dict
42

53
from slack_bolt import Ack, Complete, Fail
64

75
from listeners.filters import LANGUAGES_FILTER, SAMPLES_FILTER, TEMPLATES_FILTER
86

9-
FILTER_PROCESSING_ERROR_MSG = (
10-
"We encountered an issue processing filter results. Please try again or contact the app owner if the problem persists."
11-
)
12-
13-
def filter_none(items: Dict):
14-
return {k: v for k, v in items if v is not None}
15-
167

178
def filters_step_callback(ack: Ack, inputs: dict, fail: Fail, complete: Complete, logger: logging.Logger):
189
try:
1910
user_context = inputs.get("user_context", {})
2011
logger.debug(f"User {user_context.get('id')} executing filter request")
2112

22-
complete(
23-
outputs={
24-
"filters": [
25-
asdict(LANGUAGES_FILTER, dict_factory=filter_none),
26-
asdict(TEMPLATES_FILTER, dict_factory=filter_none),
27-
asdict(SAMPLES_FILTER, dict_factory=filter_none),
28-
]
29-
}
30-
)
13+
complete(outputs={"filters": [LANGUAGES_FILTER, TEMPLATES_FILTER, SAMPLES_FILTER]})
3114
except Exception as e:
3215
logger.error(
33-
f"Unexpected error occurred while processing filter request: {type(e).__name__} - {str(e)}",
16+
f"Unexpected error occurred while processing filter request: {type(e).__name__} - {e}",
3417
exc_info=e,
3518
)
36-
fail(error=FILTER_PROCESSING_ERROR_MSG)
19+
fail(
20+
error="We encountered an issue processing filter results. "
21+
"Please try again or contact the app owner if the problem persists."
22+
)
3723
finally:
3824
ack()

listeners/functions/search.py

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,10 @@
11
import logging
2-
from typing import List, NotRequired, Optional, TypedDict
32

43
from slack_bolt import Ack, Complete, Fail
54
from slack_sdk import WebClient
65

76
from listeners.sample_data_service import SlackResponseError, fetch_sample_data
87

9-
SEARCH_PROCESSING_ERROR_MSG = (
10-
"We encountered an issue processing your search results. "
11-
"Please try again or contact the app owner if the problem persists."
12-
)
13-
14-
15-
class EntityReference(TypedDict):
16-
id: str
17-
type: Optional[str]
18-
19-
20-
class SearchResult(TypedDict):
21-
title: str
22-
description: str
23-
link: str
24-
date_updated: str
25-
external_ref: EntityReference
26-
content: NotRequired[str]
27-
288

299
def search_step_callback(
3010
ack: Ack,
@@ -42,27 +22,14 @@ def search_step_callback(
4222

4323
samples = response.get("samples", [])
4424

45-
results: List[SearchResult] = [
46-
{
47-
"title": sample["title"],
48-
"description": sample["description"],
49-
"link": sample["link"],
50-
"date_updated": sample["date_updated"],
51-
"external_ref": sample["external_ref"],
52-
**({"content": sample["content"]} if "content" in sample else {}),
53-
}
54-
for sample in samples
55-
]
56-
57-
complete(outputs={"search_results": results})
25+
complete(outputs={"search_results": samples})
26+
except SlackResponseError as e:
27+
logger.error(f"Failed to fetch or parse sample data. Error details: {e}", exc_info=e)
28+
fail(
29+
error="We encountered an issue processing your search results. "
30+
"Please try again or contact the app owner if the problem persists."
31+
)
5832
except Exception as e:
59-
if isinstance(e, SlackResponseError):
60-
logger.error(f"Failed to fetch or parse sample data. Error details: {str(e)}", exc_info=e)
61-
fail(error=SEARCH_PROCESSING_ERROR_MSG)
62-
else:
63-
logger.error(
64-
f"Unexpected error occurred while processing search request: {type(e).__name__} - {str(e)}",
65-
exc_info=e,
66-
)
33+
logger.error(f"Unexpected error processing search request: {type(e).__name__} - {e}", exc_info=e)
6734
finally:
6835
ack()

listeners/sample_data_service.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99

1010
class SlackResponseError(Exception):
11-
def __init__(self, message: str):
12-
super().__init__(message)
13-
self.name = "SlackResponseError"
11+
pass
1412

1513

1614
def fetch_sample_data(client: WebClient, query: str = None, filters: dict = None, logger: logging.Logger = None):
@@ -19,18 +17,18 @@ def fetch_sample_data(client: WebClient, query: str = None, filters: dict = None
1917
if filters:
2018
selected_filters = {}
2119

22-
languages = filters.get(LANGUAGES_FILTER.name, [])
23-
templates = filters.get(TEMPLATES_FILTER.name, False)
24-
samples = filters.get(SAMPLES_FILTER.name, False)
20+
languages = filters.get(LANGUAGES_FILTER["name"], [])
21+
templates = filters.get(TEMPLATES_FILTER["name"], False)
22+
samples = filters.get(SAMPLES_FILTER["name"], False)
2523

2624
if languages:
27-
selected_filters[LANGUAGES_FILTER.name] = languages
25+
selected_filters[LANGUAGES_FILTER["name"]] = languages
2826

2927
if templates ^ samples:
3028
if templates:
31-
selected_filters["type"] = TEMPLATES_FILTER.name
29+
selected_filters["type"] = TEMPLATES_FILTER["name"]
3230
elif samples:
33-
selected_filters["type"] = SAMPLES_FILTER.name
31+
selected_filters["type"] = SAMPLES_FILTER["name"]
3432

3533
if selected_filters:
3634
params["filters"] = selected_filters

tests/listeners/functions/test_filters.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from slack_bolt import Ack, Complete, Fail
44

5-
from listeners.functions.filters import FILTER_PROCESSING_ERROR_MSG, filters_step_callback
5+
from listeners.functions.filters import filters_step_callback
66

77

88
class TestFilters:
@@ -84,7 +84,4 @@ def test_filters_step_callback_unexpected_exception(self):
8484
)
8585

8686
self.mock_fail.assert_called_once()
87-
call_args = self.mock_fail.call_args
88-
assert call_args.kwargs["error"] == FILTER_PROCESSING_ERROR_MSG
89-
9087
self.mock_ack.assert_called_once()

tests/listeners/functions/test_search.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from slack_sdk import WebClient
55

66
from listeners.filters import LANGUAGES_FILTER, SAMPLES_FILTER, TEMPLATES_FILTER
7-
from listeners.functions.search import SEARCH_PROCESSING_ERROR_MSG, search_step_callback
7+
from listeners.functions.search import search_step_callback
88
from listeners.sample_data_service import SlackResponseError
99

1010

@@ -41,7 +41,7 @@ def setup_method(self):
4141
def test_search_step_callback_success(self, mock_fetch_sample_data):
4242
mock_fetch_sample_data.return_value = self.mock_sample_data
4343

44-
filters = {LANGUAGES_FILTER.name: ["python"]}
44+
filters = {LANGUAGES_FILTER["name"]: ["python"]}
4545

4646
inputs = {"query": "test query", "filters": filters}
4747

@@ -74,7 +74,11 @@ def test_search_step_callback_success(self, mock_fetch_sample_data):
7474
def test_search_step_callback_multiple_filter_types(self, mock_fetch_sample_data):
7575
mock_fetch_sample_data.return_value = self.mock_sample_data
7676

77-
filters = {TEMPLATES_FILTER.name: True, SAMPLES_FILTER.name: True, LANGUAGES_FILTER.name: ["python", "javascript"]}
77+
filters = {
78+
TEMPLATES_FILTER["name"]: True,
79+
SAMPLES_FILTER["name"]: True,
80+
LANGUAGES_FILTER["name"]: ["python", "javascript"],
81+
}
7882

7983
inputs = {"query": "test query", "filters": filters}
8084

@@ -135,9 +139,6 @@ def test_search_step_callback_slack_response_error(self, mock_fetch_sample_data)
135139
)
136140

137141
self.mock_fail.assert_called_once()
138-
call_args = self.mock_fail.call_args
139-
assert call_args.kwargs["error"] == SEARCH_PROCESSING_ERROR_MSG
140-
141142
self.mock_complete.assert_not_called()
142143
self.mock_ack.assert_called_once()
143144

tests/listeners/test_sample_data_service.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def test_fetch_sample_data_with_query(self):
4848
assert result == self.mock_response
4949

5050
def test_fetch_sample_data_with_languages_filter(self):
51-
filters = {LANGUAGES_FILTER.name: ["python", "javascript"]}
51+
filters = {LANGUAGES_FILTER["name"]: ["python", "javascript"]}
5252

5353
result = fetch_sample_data(client=self.mock_client, query="test query", filters=filters, logger=self.mock_logger)
5454

@@ -57,41 +57,44 @@ def test_fetch_sample_data_with_languages_filter(self):
5757
assert result == self.mock_response
5858

5959
def test_fetch_sample_data_with_templates_filter(self):
60-
filters = {TEMPLATES_FILTER.name: True}
60+
filters = {TEMPLATES_FILTER["name"]: True}
6161

6262
result = fetch_sample_data(client=self.mock_client, query="test query", filters=filters, logger=self.mock_logger)
6363

6464
self.mock_client.api_call.assert_called_once_with(
65-
API_METHOD, params={"query": "test query", "filters": {"type": TEMPLATES_FILTER.name}}
65+
API_METHOD, params={"query": "test query", "filters": {"type": TEMPLATES_FILTER["name"]}}
6666
)
6767

6868
assert result == self.mock_response
6969

7070
def test_fetch_sample_data_with_samples_filter(self):
71-
filters = {SAMPLES_FILTER.name: True}
71+
filters = {SAMPLES_FILTER["name"]: True}
7272

7373
result = fetch_sample_data(client=self.mock_client, query="test query", filters=filters, logger=self.mock_logger)
7474

7575
self.mock_client.api_call.assert_called_once_with(
76-
API_METHOD, params={"query": "test query", "filters": {"type": SAMPLES_FILTER.name}}
76+
API_METHOD, params={"query": "test query", "filters": {"type": SAMPLES_FILTER["name"]}}
7777
)
7878

7979
assert result == self.mock_response
8080

8181
def test_fetch_sample_data_with_combined_filters(self):
82-
filters = {LANGUAGES_FILTER.name: ["python"], TEMPLATES_FILTER.name: True}
82+
filters = {LANGUAGES_FILTER["name"]: ["python"], TEMPLATES_FILTER["name"]: True}
8383

8484
result = fetch_sample_data(client=self.mock_client, query="test query", filters=filters, logger=self.mock_logger)
8585

8686
self.mock_client.api_call.assert_called_once_with(
8787
API_METHOD,
88-
params={"query": "test query", "filters": {LANGUAGES_FILTER.name: ["python"], "type": TEMPLATES_FILTER.name}},
88+
params={
89+
"query": "test query",
90+
"filters": {LANGUAGES_FILTER["name"]: ["python"], "type": TEMPLATES_FILTER["name"]},
91+
},
8992
)
9093

9194
assert result == self.mock_response
9295

9396
def test_fetch_sample_data_with_both_template_and_sample(self):
94-
filters = {TEMPLATES_FILTER.name: True, SAMPLES_FILTER.name: True}
97+
filters = {TEMPLATES_FILTER["name"]: True, SAMPLES_FILTER["name"]: True}
9598

9699
result = fetch_sample_data(client=self.mock_client, query="test query", filters=filters, logger=self.mock_logger)
97100

0 commit comments

Comments
 (0)