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.66" , "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.66" , "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.66" , "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- if "NO_REACHABLE" in deny and not data .get ("plugins" , {}).get ("reachable" , True ): reasons .append ("NO_REACHABLE" )
81- if "HIGH_RISK_SCORE" in deny and data .get ("plugins" , {}).get ("riskScore" , 0 ) >= 80 : reasons .append ("HIGH_RISK_SCORE" )
82- if "NO_GRAVATAR" in deny and isinstance (data .get ("plugins" , {}).get ("gravatarUrl" ), str ): reasons .append ("NO_GRAVATAR" )
83-
84- return {
85- "email" : email ,
86- "allow" : len (reasons ) == 0 ,
87- "reasons" : reasons ,
88- "response" : data
89- }
90-
91- except requests .RequestException as e : raise APIError (f"[Dymo API] { str (e )} " )
92-
93- def is_valid_ip (token : Optional [str ], ip : str , rules : Optional [Dict [str , List [str ]]] = None ) -> Dict [str , Any ]:
94- """
95- Validates the given IP against the configured deny rules.
96-
97- Args:
98- token (str | None): Authentication token (required).
99- email (str): IP to validate.
100- rules (dict | None): Optional rules dict with 'deny' list. Defaults to
101- ["FRAUD", "INVALID", "TOR_NETWORK"].
102- ⚠️ "TOR_NETWORK" and "HIGH_RISK_SCORE" are PREMIUM.
103-
104- Returns:
105- bool: True if the IP passes all deny rules, False otherwise.
106-
107- Raises:
108- APIError: If token is None or the request fails.
109- """
110- if token is None : raise APIError ("Invalid private token." )
111-
112- if rules is None : rules = {"deny" : ["FRAUD" , "INVALID" , "TOR_NETWORK" ]}
113-
114- plugins = [
115- "torNetwork" if "TOR_NETWORK" in rules ["deny" ] else None ,
116- "riskScore" if "HIGH_RISK_SCORE" in rules ["deny" ] else None
117- ]
118- plugins = [p for p in plugins if p is not None ]
119-
120- try :
121- resp = requests .post (
122- f"{ get_base_url ()} /v1/private/secure/verify" ,
123- json = {"ip" : ip , "plugins" : plugins },
124- headers = {"User-Agent" : "DymoAPISDK/1.0.0" , "X-Dymo-SDK-Env" : "Python" , "X-Dymo-SDK-Version" : "0.0.66" , "Authorization" : token }
125- )
126- resp .raise_for_status ()
127- data = resp .json ().get ("ip" , {})
128-
129- deny = rules .get ("deny" , [])
130- reasons : List [str ] = []
131-
132- if "INVALID" in deny and not data .get ("valid" , True ):
133- return {
134- "ip" : ip ,
135- "allow" : False ,
136- "reasons" : ["INVALID" ],
137- "response" : data
138- }
139- if "FRAUD" in deny and data .get ("fraud" , False ): reasons .append ("FRAUD" )
140- if "TOR_NETWORK" in deny and data .get ("plugins" , {}).get ("torNetwork" , False ): reasons .append ("TOR_NETWORK" )
141- if "HIGH_RISK_SCORE" in deny and data .get ("plugins" , {}).get ("riskScore" , 0 ) >= 80 : reasons .append ("HIGH_RISK_SCORE" )
142-
143- # Country block rules.
144- for rule in rules ["deny" ]:
145- if rule .startswith ("COUNTRY:" ):
146- block = rule .split (":" )[1 ] # Extract country code.
147- if data .get ("countryCode" ) == block : reasons .append (f"COUNTRY:{ block } " )
148-
149- return {
150- "ip" : ip ,
151- "allow" : len (reasons ) == 0 ,
152- "reasons" : reasons ,
153- "response" : data
154- }
155-
156- except requests .RequestException as e : raise APIError (f"[Dymo API] { str (e )} " )
157-
158- def is_valid_phone (token : Optional [str ], phone : str , rules : Optional [Dict [str , List [str ]]] = None ) -> Dict [str , Any ]:
159- """
160- Validates the given phone against the configured deny rules.
161-
162- Args:
163- token (str | None): Authentication token (required).
164- phone (str): Phone to validate.
165- rules (dict | None): Optional rules dict with 'deny' list. Defaults to
166- ["FRAUD", "INVALID"].
167- ⚠️ "HIGH_RISK_SCORE" is PREMIUM.
168-
169- Returns:
170- bool: True if the phone passes all deny rules, False otherwise.
171-
172- Raises:
173- APIError: If token is None or the request fails.
174- """
175- if token is None : raise APIError ("Invalid private token." )
176-
177- if rules is None : rules = {"deny" : ["FRAUD" , "INVALID" ]}
178-
179- plugins = [
180- "riskScore" if "HIGH_RISK_SCORE" in rules ["deny" ] else None
181- ]
182- plugins = [p for p in plugins if p is not None ]
183-
184- try :
185- resp = requests .post (
186- f"{ get_base_url ()} /v1/private/secure/verify" ,
187- json = {"phone" : phone , "plugins" : plugins },
188- headers = {"User-Agent" : "DymoAPISDK/1.0.0" , "X-Dymo-SDK-Env" : "Python" , "X-Dymo-SDK-Version" : "0.0.66" , "Authorization" : token }
189- )
190- resp .raise_for_status ()
191- data = resp .json ().get ("phone" , {})
192-
193- deny = rules .get ("deny" , [])
194- reasons : List [str ] = []
195-
196- if "INVALID" in deny and not data .get ("valid" , True ):
197- return {
198- "phone" : phone ,
199- "allow" : False ,
200- "reasons" : ["INVALID" ],
201- "response" : data
202- }
203- if "FRAUD" in deny and data .get ("fraud" , False ): reasons .append ("FRAUD" )
204- if "HIGH_RISK_SCORE" in deny and data .get ("plugins" , {}).get ("riskScore" , 0 ) >= 80 : reasons .append ("HIGH_RISK_SCORE" )
205-
206- # Country block rules.
207- for rule in rules ["deny" ]:
208- if rule .startswith ("COUNTRY:" ):
209- block = rule .split (":" )[1 ] # Extract country code.
210- if data .get ("countryCode" ) == block : reasons .append (f"COUNTRY:{ block } " )
211-
212- return {
213- "phone" : phone ,
214- "allow" : len (reasons ) == 0 ,
215- "reasons" : reasons ,
216- "response" : data
217- }
218-
219- except requests .RequestException as e : raise APIError (f"[Dymo API] { str (e )} " )
220-
221- def send_email (token , data ):
222- if not data .get ("from" ): raise BadRequestError ("You must provide an email address from which the following will be sent." )
223- if not data .get ("to" ): raise BadRequestError ("You must provide an email to be sent to." )
224- if not data .get ("subject" ): raise BadRequestError ("You must provide a subject for the email to be sent." )
225- if not data .get ("html" ): raise BadRequestError ("You must provide HTML." )
226- try :
227- 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.66" , "Authorization" : token })
228- response .raise_for_status ()
229- return response .json ()
230- except requests .RequestException as e : raise APIError (str (e ))
231-
232- def get_random (token , data ):
233- if not data .get ("min" ) and data .get ("min" ) != 0 : raise BadRequestError ("Both 'min' and 'max' parameters must be defined." )
234- if not data .get ("max" ) and data .get ("max" ) != 0 : raise BadRequestError ("Both 'min' and 'max' parameters must be defined." )
235- if data .get ("min" ) >= data .get ("max" ): raise BadRequestError ("'min' must be less than 'max'." )
236- if data .get ("min" ) < - 1000000000 or data .get ("min" ) > 1000000000 : raise BadRequestError ("'min' must be an integer in the interval [-1000000000, 1000000000]." )
237- if data .get ("max" ) < - 1000000000 or data .get ("max" ) > 1000000000 : raise BadRequestError ("'max' must be an integer in the interval [-1000000000, 1000000000]." )
238- try :
239- 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.66" , "Authorization" : token })
240- response .raise_for_status ()
241- return response .json ()
242- except requests .RequestException as e : raise APIError (str (e ))
243-
244-
245- def extract_with_textly (token : str , data : dict ) -> dict :
246- if not data .get ("data" ): raise BadRequestError ("No data provided." )
247- if not data .get ("format" ): raise BadRequestError ("No format provided." )
248-
249- try :
250- response = requests .post (
251- f"{ get_base_url ()} /v1/private/textly/extract" ,
252- json = data ,
253- headers = {
254- "Content-Type" : "application/json" ,
255- "User-Agent" : "DymoAPISDK/1.0.0" ,
256- "X-Dymo-SDK-Env" : "Python" ,
257- "X-Dymo-SDK-Version" : "0.0.66" ,
258- "Authorization" : token
259- }
260- )
261- response .raise_for_status ()
262- return response .json ()
263- except requests .RequestException as e : raise APIError (str (e ))
0 commit comments