Skip to content

Commit 0624c2e

Browse files
committed
✨ publish: dymo updated
1 parent 3572ebf commit 0624c2e

File tree

6 files changed

+459
-43
lines changed

6 files changed

+459
-43
lines changed

dymoapi/branches/private.py

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
import requests
2+
from ..config import get_base_url
3+
from ..utils.decorators import deprecated
4+
from typing import Optional, Dict, Any, List
5+
from ..exceptions import APIError, BadRequestError
6+
7+
@deprecated("is_valid_data_raw")
8+
def is_valid_data(token, data):
9+
if not any([key in list(data.keys()) for key in ["url", "email", "phone", "domain", "creditCard", "ip", "wallet", "userAgent", "iban"]]): raise BadRequestError("You must provide at least one parameter.")
10+
try:
11+
response = requests.post(f"{get_base_url()}/v1/private/secure/verify", json=data, headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token})
12+
response.raise_for_status()
13+
return response.json()
14+
except requests.RequestException as e: raise APIError(str(e))
15+
16+
def is_valid_data_raw(token, data):
17+
if not any([key in list(data.keys()) for key in ["url", "email", "phone", "domain", "creditCard", "ip", "wallet", "userAgent", "iban"]]): raise BadRequestError("You must provide at least one parameter.")
18+
try:
19+
response = requests.post(f"{get_base_url()}/v1/private/secure/verify", json=data, headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token})
20+
response.raise_for_status()
21+
return response.json()
22+
except requests.RequestException as e: raise APIError(str(e))
23+
24+
def is_valid_email(token: Optional[str], email: str, rules: Optional[Dict[str, List[str]]] = None) -> Dict[str, Any]:
25+
"""
26+
Validates the given email against the configured deny rules.
27+
28+
Args:
29+
token (str | None): Authentication token (required).
30+
email (str): Email to validate.
31+
rules (dict | None): Optional rules dict with 'deny' list. Defaults to
32+
["FRAUD", "INVALID", "NO_MX_RECORDS", "NO_REPLY_EMAIL"].
33+
⚠️ "NO_MX_RECORDS", "HIGH_RISK_SCORE", "NO_GRAVATAR" and "NO_REACHABLE" are PREMIUM.
34+
35+
Returns:
36+
bool: True if the email passes all deny rules, False otherwise.
37+
38+
Raises:
39+
APIError: If token is None or the request fails.
40+
"""
41+
if token is None: raise APIError("Invalid private token.")
42+
43+
if rules is None: rules = {"deny": ["FRAUD", "INVALID", "NO_MX_RECORDS", "NO_REPLY_EMAIL"]}
44+
45+
plugins = [
46+
"mxRecords" if "NO_MX_RECORDS" in rules["deny"] else None,
47+
"reachable" if "NO_REACHABLE" in rules["deny"] else None,
48+
"riskScore" if "HIGH_RISK_SCORE" in rules["deny"] else None,
49+
"gravatar" if "NO_GRAVATAR" in rules["deny"] else None
50+
]
51+
plugins = [p for p in plugins if p is not None]
52+
53+
try:
54+
resp = requests.post(
55+
f"{get_base_url()}/v1/private/secure/verify",
56+
json={"email": email, "plugins": plugins},
57+
headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token}
58+
)
59+
resp.raise_for_status()
60+
data = resp.json().get("email", {})
61+
62+
deny = rules.get("deny", [])
63+
reasons: List[str] = []
64+
65+
if "INVALID" in deny and not data.get("valid", True):
66+
return {
67+
"email": email,
68+
"allow": False,
69+
"reasons": ["INVALID"],
70+
"response": data
71+
}
72+
if "FRAUD" in deny and data.get("fraud", False): reasons.append("FRAUD")
73+
if "PROXIED_EMAIL" in deny and data.get("proxiedEmail", False): reasons.append("PROXIED_EMAIL")
74+
if "FREE_SUBDOMAIN" in deny and data.get("freeSubdomain", False): reasons.append("FREE_SUBDOMAIN")
75+
if "PERSONAL_EMAIL" in deny and not data.get("corporate", False): reasons.append("PERSONAL_EMAIL")
76+
if "CORPORATE_EMAIL" in deny and data.get("corporate", False): reasons.append("CORPORATE_EMAIL")
77+
if "NO_MX_RECORDS" in deny and len(data.get("plugins", {}).get("mxRecords", [])) == 0: reasons.append("NO_MX_RECORDS")
78+
if "NO_REPLY_EMAIL" in deny and data.get("noReply", False): reasons.append("NO_REPLY_EMAIL")
79+
if "ROLE_ACCOUNT" in deny and data.get("plugins", {}).get("roleAccount", False): reasons.append("ROLE_ACCOUNT")
80+
reachable = data.get("plugins", {}).get("reachable")
81+
if "NO_REACHABLE" in deny and isinstance(reachable, dict) and reachable.get("reachability") == "invalid": reasons.append("NO_REACHABLE")
82+
if "HIGH_RISK_SCORE" in deny and data.get("plugins", {}).get("riskScore", 0) >= 80: reasons.append("HIGH_RISK_SCORE")
83+
if "NO_GRAVATAR" in deny and isinstance(data.get("plugins", {}).get("gravatarUrl"), str): reasons.append("NO_GRAVATAR")
84+
85+
return {
86+
"email": email,
87+
"allow": len(reasons) == 0,
88+
"reasons": reasons,
89+
"response": data
90+
}
91+
92+
except requests.RequestException as e: raise APIError(f"[Dymo API] {str(e)}")
93+
94+
def is_valid_ip(token: Optional[str], ip: str, rules: Optional[Dict[str, List[str]]] = None) -> Dict[str, Any]:
95+
"""
96+
Validates the given IP against the configured deny rules.
97+
98+
Args:
99+
token (str | None): Authentication token (required).
100+
email (str): IP to validate.
101+
rules (dict | None): Optional rules dict with 'deny' list. Defaults to
102+
["FRAUD", "INVALID", "TOR_NETWORK"].
103+
⚠️ "TOR_NETWORK" and "HIGH_RISK_SCORE" are PREMIUM.
104+
105+
Returns:
106+
bool: True if the IP passes all deny rules, False otherwise.
107+
108+
Raises:
109+
APIError: If token is None or the request fails.
110+
"""
111+
if token is None: raise APIError("Invalid private token.")
112+
113+
if rules is None: rules = {"deny": ["FRAUD", "INVALID", "TOR_NETWORK"]}
114+
115+
plugins = [
116+
"torNetwork" if "TOR_NETWORK" in rules["deny"] else None,
117+
"riskScore" if "HIGH_RISK_SCORE" in rules["deny"] else None
118+
]
119+
plugins = [p for p in plugins if p is not None]
120+
121+
try:
122+
resp = requests.post(
123+
f"{get_base_url()}/v1/private/secure/verify",
124+
json={"ip": ip, "plugins": plugins},
125+
headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token}
126+
)
127+
resp.raise_for_status()
128+
data = resp.json().get("ip", {})
129+
130+
deny = rules.get("deny", [])
131+
reasons: List[str] = []
132+
133+
if "INVALID" in deny and not data.get("valid", True):
134+
return {
135+
"ip": ip,
136+
"allow": False,
137+
"reasons": ["INVALID"],
138+
"response": data
139+
}
140+
if "FRAUD" in deny and data.get("fraud", False): reasons.append("FRAUD")
141+
if "TOR_NETWORK" in deny and data.get("plugins", {}).get("torNetwork", False): reasons.append("TOR_NETWORK")
142+
if "HIGH_RISK_SCORE" in deny and data.get("plugins", {}).get("riskScore", 0) >= 80: reasons.append("HIGH_RISK_SCORE")
143+
144+
# Country block rules.
145+
for rule in rules["deny"]:
146+
if rule.startswith("COUNTRY:"):
147+
block = rule.split(":")[1] # Extract country code.
148+
if data.get("countryCode") == block: reasons.append(f"COUNTRY:{block}")
149+
150+
return {
151+
"ip": ip,
152+
"allow": len(reasons) == 0,
153+
"reasons": reasons,
154+
"response": data
155+
}
156+
157+
except requests.RequestException as e: raise APIError(f"[Dymo API] {str(e)}")
158+
159+
def is_valid_phone(token: Optional[str], phone: str, rules: Optional[Dict[str, List[str]]] = None) -> Dict[str, Any]:
160+
"""
161+
Validates the given phone against the configured deny rules.
162+
163+
Args:
164+
token (str | None): Authentication token (required).
165+
phone (str): Phone to validate.
166+
rules (dict | None): Optional rules dict with 'deny' list. Defaults to
167+
["FRAUD", "INVALID"].
168+
⚠️ "HIGH_RISK_SCORE" is PREMIUM.
169+
170+
Returns:
171+
bool: True if the phone passes all deny rules, False otherwise.
172+
173+
Raises:
174+
APIError: If token is None or the request fails.
175+
"""
176+
if token is None: raise APIError("Invalid private token.")
177+
178+
if rules is None: rules = {"deny": ["FRAUD", "INVALID"]}
179+
180+
plugins = [
181+
"riskScore" if "HIGH_RISK_SCORE" in rules["deny"] else None
182+
]
183+
plugins = [p for p in plugins if p is not None]
184+
185+
try:
186+
resp = requests.post(
187+
f"{get_base_url()}/v1/private/secure/verify",
188+
json={"phone": phone, "plugins": plugins},
189+
headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token}
190+
)
191+
resp.raise_for_status()
192+
data = resp.json().get("phone", {})
193+
194+
deny = rules.get("deny", [])
195+
reasons: List[str] = []
196+
197+
if "INVALID" in deny and not data.get("valid", True):
198+
return {
199+
"phone": phone,
200+
"allow": False,
201+
"reasons": ["INVALID"],
202+
"response": data
203+
}
204+
if "FRAUD" in deny and data.get("fraud", False): reasons.append("FRAUD")
205+
if "HIGH_RISK_SCORE" in deny and data.get("plugins", {}).get("riskScore", 0) >= 80: reasons.append("HIGH_RISK_SCORE")
206+
207+
# Country block rules.
208+
for rule in rules["deny"]:
209+
if rule.startswith("COUNTRY:"):
210+
block = rule.split(":")[1] # Extract country code.
211+
if data.get("countryCode") == block: reasons.append(f"COUNTRY:{block}")
212+
213+
return {
214+
"phone": phone,
215+
"allow": len(reasons) == 0,
216+
"reasons": reasons,
217+
"response": data
218+
}
219+
220+
except requests.RequestException as e: raise APIError(f"[Dymo API] {str(e)}")
221+
222+
def send_email(token, data):
223+
if not data.get("from"): raise BadRequestError("You must provide an email address from which the following will be sent.")
224+
if not data.get("to"): raise BadRequestError("You must provide an email to be sent to.")
225+
if not data.get("subject"): raise BadRequestError("You must provide a subject for the email to be sent.")
226+
if not data.get("html"): raise BadRequestError("You must provide HTML.")
227+
try:
228+
response = requests.post(f"{get_base_url()}/v1/private/sender/sendEmail", json=data, headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token})
229+
response.raise_for_status()
230+
return response.json()
231+
except requests.RequestException as e: raise APIError(str(e))
232+
233+
def get_random(token, data):
234+
if not data.get("min") and data.get("min") != 0: raise BadRequestError("Both 'min' and 'max' parameters must be defined.")
235+
if not data.get("max") and data.get("max") != 0: raise BadRequestError("Both 'min' and 'max' parameters must be defined.")
236+
if data.get("min") >= data.get("max"): raise BadRequestError("'min' must be less than 'max'.")
237+
if data.get("min") < -1000000000 or data.get("min") > 1000000000: raise BadRequestError("'min' must be an integer in the interval [-1000000000, 1000000000].")
238+
if data.get("max") < -1000000000 or data.get("max") > 1000000000: raise BadRequestError("'max' must be an integer in the interval [-1000000000, 1000000000].")
239+
try:
240+
response = requests.post(f"{get_base_url()}/v1/private/srng", json=data, headers={"User-Agent": "DymoAPISDK/1.0.0", "X-Dymo-SDK-Env": "Python", "X-Dymo-SDK-Version" : "0.0.68", "Authorization": token})
241+
response.raise_for_status()
242+
return response.json()
243+
except requests.RequestException as e: raise APIError(str(e))
244+
245+
246+
def extract_with_textly(token: str, data: dict) -> dict:
247+
if not data.get("data"): raise BadRequestError("No data provided.")
248+
if not data.get("format"): raise BadRequestError("No format provided.")
249+
250+
try:
251+
response = requests.post(
252+
f"{get_base_url()}/v1/private/textly/extract",
253+
json=data,
254+
headers={
255+
"Content-Type": "application/json",
256+
"User-Agent": "DymoAPISDK/1.0.0",
257+
"X-Dymo-SDK-Env": "Python",
258+
"X-Dymo-SDK-Version": "0.0.68",
259+
"Authorization": token
260+
}
261+
)
262+
response.raise_for_status()
263+
return response.json()
264+
except requests.RequestException as e: raise APIError(str(e))

0 commit comments

Comments
 (0)