Skip to content

Commit b3e97ee

Browse files
committed
Add bounceban provider
1 parent ca2e336 commit b3e97ee

File tree

6 files changed

+311
-0
lines changed

6 files changed

+311
-0
lines changed
Loading

llmstack/client/src/components/apps/ProviderIcon.jsx

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import pineconeIcon_light from "../../assets/images/pinecone-icon-light.png";
3131
import pineconeIcon_dark from "../../assets/images/pinecone-icon-dark.png";
3232
import qdrantIcon_light from "../../assets/images/qdrant-icon-light.png";
3333
import qdrantIcon_dark from "../../assets/images/qdrant-icon-dark.png";
34+
import bouncbanIcon_light from "../../assets/images/bounceban-icon-light.png";
35+
import bouncbanIcon_dark from "../../assets/images/bounceban-icon-light.png";
3436
import weaviateIcon_light from "../../assets/images/weaviate-icon-light.png";
3537
import weaviateIcon_dark from "../../assets/images/weaviate-icon-dark.png";
3638
import singlestoreIcon_light from "../../assets/images/singlestore-icon-light.png";
@@ -74,6 +76,8 @@ export const getProviderIconImage = (icon, isActive) => {
7476
return isActive ? weaviateIcon_dark : weaviateIcon_light;
7577
case "singlestore":
7678
return isActive ? singlestoreIcon_dark : singlestoreIcon_light;
79+
case "bounceban":
80+
return isActive ? bouncbanIcon_dark : bouncbanIcon_light;
7781
default:
7882
return promptlyIcon_light;
7983
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from pydantic import Field
2+
3+
from llmstack.processors.providers.config import ProviderConfig
4+
5+
6+
class BouncebanProviderConfig(ProviderConfig):
7+
provider_slug: str = "bounceban"
8+
api_key: str = Field(
9+
title="API Key",
10+
default="",
11+
description="API Key for the BounceBan API",
12+
json_schema_extra={"widget": "password", "advanced_parameter": False},
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import logging
2+
from typing import Any, Dict, Optional
3+
4+
from asgiref.sync import async_to_sync
5+
from pydantic import Field
6+
7+
from llmstack.apps.schemas import OutputTemplate
8+
from llmstack.common.utils.prequests import get
9+
from llmstack.processors.providers.api_processor_interface import (
10+
ApiProcessorInterface,
11+
ApiProcessorSchema,
12+
)
13+
from llmstack.processors.providers.metrics import MetricType
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
class CheckProcessorInput(ApiProcessorSchema):
19+
email: Optional[str] = Field(description="The email to verify", default=None)
20+
domain: Optional[str] = Field(description="The domain to verify", default=None)
21+
22+
23+
class CheckProcessorOutput(ApiProcessorSchema):
24+
response: str = Field(description="The response from the API call as a string", default="")
25+
response_json: Optional[Dict[str, Any]] = Field(
26+
description="The response from the API call as a JSON object", default={}
27+
)
28+
response_objref: Optional[str] = Field(description="The reference to the response object", default=None)
29+
headers: Optional[Dict[str, str]] = Field(description="The headers from the API call", default={})
30+
code: int = Field(description="The status code from the API call", default=200)
31+
size: int = Field(description="The size of the response from the API call", default=0)
32+
time: float = Field(description="The time it took to get the response from the API call", default=0.0)
33+
34+
35+
class CheckProcessorConfiguration(ApiProcessorSchema):
36+
pass
37+
38+
39+
class EchoProcessor(
40+
ApiProcessorInterface[CheckProcessorInput, CheckProcessorOutput, CheckProcessorConfiguration],
41+
):
42+
"""
43+
Check basic information for an email or domain.
44+
"""
45+
46+
@staticmethod
47+
def name() -> str:
48+
return "Check domain or email"
49+
50+
@staticmethod
51+
def slug() -> str:
52+
return "check"
53+
54+
@staticmethod
55+
def description() -> str:
56+
return "Check basic information for an email or domain."
57+
58+
@staticmethod
59+
def provider_slug() -> str:
60+
return "bounceban"
61+
62+
@classmethod
63+
def get_output_template(cls) -> OutputTemplate | None:
64+
return OutputTemplate(
65+
markdown="{{response}}",
66+
jsonpath="$.response",
67+
)
68+
69+
def process(self) -> dict:
70+
provider_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
71+
deployment_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
72+
api_key = deployment_config.api_key
73+
response = get(
74+
url="https://api.bounceban.com/v1/check",
75+
headers={"Authorization": f"{api_key}"},
76+
params=self._input.model_dump(),
77+
)
78+
self._usage_data.append(
79+
(
80+
f"{self.provider_slug()}/*/*/*",
81+
MetricType.API_INVOCATION,
82+
(provider_config.provider_config_source, 1),
83+
)
84+
)
85+
async_to_sync(self._output_stream.write)(
86+
CheckProcessorOutput(
87+
response=response.text,
88+
response_json=response.json(),
89+
headers=response.headers,
90+
code=response.status_code,
91+
size=len(response.content),
92+
time=response.elapsed.total_seconds(),
93+
)
94+
)
95+
96+
output = self._output_stream.finalize()
97+
return output
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import logging
2+
from typing import Any, Dict, Optional
3+
4+
from asgiref.sync import async_to_sync
5+
from pydantic import Field
6+
7+
from llmstack.apps.schemas import OutputTemplate
8+
from llmstack.common.utils.prequests import get
9+
from llmstack.processors.providers.api_processor_interface import (
10+
ApiProcessorInterface,
11+
ApiProcessorSchema,
12+
)
13+
from llmstack.processors.providers.metrics import MetricType
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
class VerifyProcessorInput(ApiProcessorSchema):
19+
email: str = Field(description="The email to verify")
20+
mode: Optional[str] = Field(description="The mode to use for verification", default="regular")
21+
url: Optional[str] = Field(
22+
description="A webhook target URL specified to receive verification result event in real-time through an HTTP POST request.",
23+
default=None,
24+
)
25+
26+
27+
class VerifyProcessorOutput(ApiProcessorSchema):
28+
response: str = Field(description="The response from the API call as a string", default="")
29+
response_json: Optional[Dict[str, Any]] = Field(
30+
description="The response from the API call as a JSON object", default={}
31+
)
32+
response_objref: Optional[str] = Field(description="The reference to the response object", default=None)
33+
headers: Optional[Dict[str, str]] = Field(description="The headers from the API call", default={})
34+
code: int = Field(description="The status code from the API call", default=200)
35+
size: int = Field(description="The size of the response from the API call", default=0)
36+
time: float = Field(description="The time it took to get the response from the API call", default=0.0)
37+
38+
39+
class VerifyProcessorConfiguration(ApiProcessorSchema):
40+
pass
41+
42+
43+
class EchoProcessor(
44+
ApiProcessorInterface[VerifyProcessorInput, VerifyProcessorOutput, VerifyProcessorConfiguration],
45+
):
46+
"""
47+
Single email verification processor
48+
"""
49+
50+
@staticmethod
51+
def name() -> str:
52+
return "Email Verification"
53+
54+
@staticmethod
55+
def slug() -> str:
56+
return "verify"
57+
58+
@staticmethod
59+
def description() -> str:
60+
return "Submit email for verification."
61+
62+
@staticmethod
63+
def provider_slug() -> str:
64+
return "bounceban"
65+
66+
@classmethod
67+
def get_output_template(cls) -> OutputTemplate | None:
68+
return OutputTemplate(
69+
markdown="{{response}}",
70+
jsonpath="$.response",
71+
)
72+
73+
def process(self) -> dict:
74+
provider_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
75+
deployment_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
76+
api_key = deployment_config.api_key
77+
response = get(
78+
url="https://api.bounceban.com/v1/verify/single",
79+
headers={"Authorization": f"{api_key}"},
80+
params=self._input.model_dump(),
81+
)
82+
self._usage_data.append(
83+
(
84+
f"{self.provider_slug()}/*/*/*",
85+
MetricType.API_INVOCATION,
86+
(provider_config.provider_config_source, 1),
87+
)
88+
)
89+
async_to_sync(self._output_stream.write)(
90+
VerifyProcessorOutput(
91+
response=response.text,
92+
response_json=response.json(),
93+
headers=response.headers,
94+
code=response.status_code,
95+
size=len(response.content),
96+
time=response.elapsed.total_seconds(),
97+
)
98+
)
99+
100+
output = self._output_stream.finalize()
101+
return output
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import logging
2+
from typing import Any, Dict, Optional
3+
4+
from asgiref.sync import async_to_sync
5+
from pydantic import Field
6+
7+
from llmstack.apps.schemas import OutputTemplate
8+
from llmstack.common.utils.prequests import get
9+
from llmstack.processors.providers.api_processor_interface import (
10+
ApiProcessorInterface,
11+
ApiProcessorSchema,
12+
)
13+
from llmstack.processors.providers.metrics import MetricType
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
class VerifyStatusProcessorInput(ApiProcessorSchema):
19+
id: str = Field(description="The unique ID for a single email verification task.")
20+
21+
22+
class VerifyStatusProcessorOutput(ApiProcessorSchema):
23+
response: str = Field(description="The response from the API call as a string", default="")
24+
response_json: Optional[Dict[str, Any]] = Field(
25+
description="The response from the API call as a JSON object", default={}
26+
)
27+
response_objref: Optional[str] = Field(description="The reference to the response object", default=None)
28+
headers: Optional[Dict[str, str]] = Field(description="The headers from the API call", default={})
29+
code: int = Field(description="The status code from the API call", default=200)
30+
size: int = Field(description="The size of the response from the API call", default=0)
31+
time: float = Field(description="The time it took to get the response from the API call", default=0.0)
32+
33+
34+
class VerifyStatusProcessorConfiguration(ApiProcessorSchema):
35+
pass
36+
37+
38+
class EchoProcessor(
39+
ApiProcessorInterface[VerifyStatusProcessorInput, VerifyStatusProcessorOutput, VerifyStatusProcessorConfiguration],
40+
):
41+
"""
42+
Single email verification result processor
43+
"""
44+
45+
@staticmethod
46+
def name() -> str:
47+
return "Email Verification Status"
48+
49+
@staticmethod
50+
def slug() -> str:
51+
return "verify_status"
52+
53+
@staticmethod
54+
def description() -> str:
55+
return "Get the verification result for single email verification."
56+
57+
@staticmethod
58+
def provider_slug() -> str:
59+
return "bounceban"
60+
61+
@classmethod
62+
def get_output_template(cls) -> OutputTemplate | None:
63+
return OutputTemplate(
64+
markdown="{{response}}",
65+
jsonpath="$.response",
66+
)
67+
68+
def process(self) -> dict:
69+
provider_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
70+
deployment_config = self.get_provider_config(provider_slug=self.provider_slug(), processor_slug="*")
71+
api_key = deployment_config.api_key
72+
response = get(
73+
url="https://api.bounceban.com/v1/verify/single/status",
74+
headers={"Authorization": f"{api_key}"},
75+
params=self._input.model_dump(),
76+
)
77+
self._usage_data.append(
78+
(
79+
f"{self.provider_slug()}/*/*/*",
80+
MetricType.API_INVOCATION,
81+
(provider_config.provider_config_source, 1),
82+
)
83+
)
84+
async_to_sync(self._output_stream.write)(
85+
VerifyStatusProcessorOutput(
86+
response=response.text,
87+
response_json=response.json(),
88+
headers=response.headers,
89+
code=response.status_code,
90+
size=len(response.content),
91+
time=response.elapsed.total_seconds(),
92+
)
93+
)
94+
95+
output = self._output_stream.finalize()
96+
return output

0 commit comments

Comments
 (0)