Sunday, 8 April 2018

Email Verification in Python 

import re
import smtplib
import dns.resolver
# Address used for SMTP MAIL FROM command
fromAddress = 'corn@bt.com'
# Simple Regex for syntax checking
regex = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$'
# Email address to verify
inputAddress = input('Please enter the emailAddress to verify:')
addressToVerify = str(inputAddress)
# Syntax check
match = re.match(regex, addressToVerify)
if match == None:
print('Bad Syntax')
raise ValueError('Bad Syntax')
# Get domain for DNS lookup
splitAddress = addressToVerify.split('@')
domain = str(splitAddress[1])
print('Domain:', domain)
# MX record lookup
records = dns.resolver.query(domain, 'MX')
mxRecord = records[0].exchange
mxRecord = str(mxRecord)
# SMTP lib setup (use debug level for full output)
server = smtplib.SMTP()
server.set_debuglevel(0)
# SMTP Conversation
server.connect(mxRecord)
server.helo(server.local_hostname) ### server.local_hostname(Get local server hostname)
server.mail(fromAddress)
code, message = server.rcpt(str(addressToVerify))
server.quit()
#print(code)
#print(message)
# Assume SMTP response 250 is success
if code == 250:
print('Success')
else:
print('Bad')

Sunday, 17 December 2017

Interesting Facts about decorators Python

decorator is a design pattern in which a class or function alters or adds to the functionality of another class or function without using inheritance, or directly modifying the source code. In Python, decorators are, in simplest terms, functions (or any callable objects) that take as input a set of optional arguments and a function or class, and return a function or class. They can be used to implement the decorator design pattern, or for other purposes. Class decorators are new in Python 2.6.

Decorators are applied to a function or class using the @ symbol in Python. Let's use a simple decorator to log function calls as our first example. Here the decorator takes the time format as an argument and prints a log statement prior to and after every execution of the decorated function with the execution time. This can come in handy when you are comparing the efficiency of two different implementations of the same algorithm, or two separate algorithms, for example.
def logged(time_format):
   def decorator(func):
      def decorated_func(*args, **kwargs):
         print "- Running '%s' on %s " % (
                                         func.__name__,
                                         time.strftime(time_format)
                              )
         start_time = time.time()
         result = func(*args, **kwargs)
         end_time = time.time()
         print "- Finished '%s', execution time = %0.3fs " % (
                                         func.__name__,
                                         end_time - start_time
                              )

         return result
     decorated_func.__name__ = func.__name__
     return decorated_func
 return decorator
Let's look at a use example. Here functions add1 and add2 are decorated using logged and a sample output is given. Notice that the time format argument is stored in the closure of the returned decorated functions. This is why an understanding of closures is important in understanding decorators in Python. Also notice how the returned function's name is replaced with the original function's name, in case it is used later on, to prevent confusion. Python does not do this by default.
@logged("%b %d %Y - %H:%M:%S")
def add1(x, y):
    time.sleep(1)
    return x + y


@logged("%b %d %Y - %H:%M:%S")
def add2(x, y):
    time.sleep(2)
    return x + y


print add1(1, 2)
print add2(1, 2)

# Output:
- Running 'add1' on Jul 24 2013 - 13:40:47
- Finished 'add1', execution time = 1.001s
3
- Running 'add2' on Jul 24 2013 - 13:40:48
- Finished 'add2', execution time = 2.001s
3
If you pay careful attention, you might notice that while we take extra care to make sure the returned function has the right __name__, we do not do so for __doc__, or __module__. So if, in our example, the add function had a doc string, it would be lost. How do we handle this? We could handle it similar to how we handled __name__ but doing so for every decorator becomes tedious. This is why the functools module provides a decorator named wraps which handles exactly this scenario. It might be a bit confusing to see a decorator used inside another, but when you think of decorators as simply functions that take in a function as parameter and return a function, everything makes perfect sense. The wraps decorator is used in our next examples instead of manually fixing __name__ and other such attributes.
Next example is a bit more complicated. Let's write a decorator that caches the result of a function call for a given number of seconds. The code relies on the arguments passed to the function to be hashable objects because we use a tuple with the argsarguments as the first entry, and a frozen set of the items in the keyword arguments kwargs as the second entry as the cache key. Each function will have a unique cache dict generated for it which is stored in the function's closure.
import time
from functools import wraps


def cached(timeout, logged=False):
    """Decorator to cache the result of a function call.
    Cache expires after timeout seconds.
    """
    def decorator(func):
        if logged:
            print "-- Initializing cache for", func.__name__
        cache = {}

        @wraps(func)
        def decorated_function(*args, **kwargs):
            if logged:
                print "-- Called function", func.__name__
            key = (args, frozenset(kwargs.items()))
            result = None
            if key in cache:
                if logged:
                    print "-- Cache hit for", func.__name__, key

                (cache_hit, expiry) = cache[key]
                if time.time() - expiry < timeout:
                    result = cache_hit
                elif logged:
                    print "-- Cache expired for", func.__name__, key
            elif logged:
                print "-- Cache miss for", func.__name__, key

            # No cache hit, or expired
            if result is None:
                result = func(*args, **kwargs)

            cache[key] = (result, time.time())
            return result

        return decorated_function

    return decorator
And here's how it's used. We apply the decorator to a very naive (and inefficient) Fibonacci number calculator. The cache decorator will effectively apply the memoize pattern to the code. Notice how the closure of fib contains the cache dict, a reference to the original fib function, the value of the logged argument.
>>> @cached(10, True)
... def fib(n):
...     """Returns the n'th Fibonacci number."""
...     if n == 0 or n == 1:
...         return 1
...     return fib(n - 1) + fib(n - 2)
...
-- Initializing cache for fib
>>> dump_closure(fib)
1. Dumping function closure for fib:
-- cell 0  = {}
-- cell 1  = <function fib at 0x10eae7500>
-- cell 2  = True
-- cell 3  = 10
>>>
>>> print "Testing - F(4) = %d" % fib(4)
-- Called function fib
-- Cache miss for fib ((4,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((3,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((2,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((1,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((0,), frozenset([]))
-- Called function fib
-- Cache hit for fib ((1,), frozenset([]))
-- Called function fib
-- Cache hit for fib ((2,), frozenset([]))
Testing - F(4) = 5

Class Decorators

In the previous section we looked at function decorators and some non-trivial examples of their uses. Next, let's look at class decorators. Here, the decorator takes as input a class (an object of type type in Python), and returns a modified class.
First example is a simple mathematical example. Given a partially ordered set (also called a posetP, we define Pd to be thedual of P if and only if P(x,y)Pd(y,x). In other words, the ordering is reversed. How can we implement this in Python? Suppose a class defines an ordering by implementing the __lt____le__, etc. set of methods. Then we can write a class decorator that replaces each of these functions with its dual.
def make_dual(relation):
    @wraps(relation, ['__name__', '__doc__'])
    def dual(x, y):
        return relation(y, x)
    return dual


def dual_ordering(cls):
    """Class decorator that reverses all the orderings"""
    for func in ['__lt__', '__gt__', '__ge__', '__le__']:
        if hasattr(cls, func):
            setattr(cls, func, make_dual(getattr(cls, func)))
    return cls
Here's how we can apply that to str, to create a new class called rstr in which opposite lexicographic ordering is used.
@dual_ordering
class rstr(str):
    pass

x = rstr("1")
y = rstr("2")

print x < y
print x <= y
print x > y
print x >= y

# Output:
False
False
True
True
Let's look at another more complicated example. Suppose we want the logged decorator from the previous section to be applied to all the methods in a class. One way to do this would be to go through the code and add the decorator to each method. Another would be write a class decorator that automates this process. Before I do this though, I took the logged decorator from the previous section and improved on it a bit. Firstly, it uses the wraps decorator from functools now instead of manually fixing the __name__. Secondly, a _logged_decorator attribute is added to the returned function which is set to True, and is used to make sure the function does not get double-decorated, which comes in handy when we apply the decorator to classes which might inherit methods from another class. Finally, a name_prefix argument is added to allow for customization of the printed log message.
def logged(time_format, name_prefix=""):
    def decorator(func):
        if hasattr(func, '_logged_decorator') and func._logged_decorator:
            return func

        @wraps(func)
        def decorated_func(*args, **kwargs):
            start_time = time.time()
            print "- Running '%s' on %s " % (
                                            name_prefix + func.__name__,
                                            time.strftime(time_format)
                                 )
            result = func(*args, **kwargs)
            end_time = time.time()
            print "- Finished '%s', execution time = %0.3fs " % (
                                            name_prefix + func.__name__,
                                            end_time - start_time
                                 )

            return result
        decorated_func._logged_decorator = True
        return decorated_func
    return decorator
Now we are ready to write the class decorator.
def log_method_calls(time_format):
    def decorator(cls):
        for o in dir(cls):
            if o.startswith('__'):
                continue
            a = getattr(cls, o)
            if hasattr(a, '__call__'):
                decorated_a = logged(time_format, cls.__name__ + ".")(a)
                setattr(cls, o, decorated_a)
        return cls
    return decorator
And here's how it would be used. Notice how inheritance and overridden methods are handled here.
@log_method_calls("%b %d %Y - %H:%M:%S")
class A(object):
    def test1(self):
        print "test1"


@log_method_calls("%b %d %Y - %H:%M:%S")
class B(A):
    def test1(self):
        super(B, self).test1()
        print "child test1"

    def test2(self):
        print "test2"


b = B()
b.test1()
b.test2()


# Output:
- Running 'B.test1' on Jul 24 2013 - 14:15:03
- Running 'A.test1' on Jul 24 2013 - 14:15:03
test1
- Finished 'A.test1', execution time = 0.000s
child test1
- Finished 'B.test1', execution time = 1.001s
- Running 'B.test2' on Jul 24 2013 - 14:15:04
test2
- Finished 'B.test2', execution time = 2.001s
Our first example of class decorators was to reverse the ordering methods of a class. A somewhat similar decorator, though arguably a lot more useful, that can come in handy would be one that, given only one of __lt____le____gt__, or __ge__and __eq__, would implement the others to make a total ordering for the class. This is precisely what thefunctools.total_ordering decorator does. You can read up on the documentation here.

A Few Examples From Flask

Let's look at some other interesting uses of decorators from Flask.
Suppose that you want certain functions to output a warning message if they are called under certain circumstances, but only in debug mode. Instead of manually adding the code to the beginning of every function, you can write a decorator to do this. This is precisely what the following decorator taken from Flask's app.py file does.
def setupmethod(f):
    """Wraps a method so that it performs a check in debug mode if the
    first request was already handled.
    """
    def wrapper_func(self, *args, **kwargs):
        if self.debug and self._got_first_request:
            raise AssertionError('A setup function was called after the '
                'first request was handled.  This usually indicates a bug '
                'in the application where a module was not imported '
                'and decorators or other functionality was called too late.\n'
                'To fix this make sure to import all your view modules, '
                'database models and everything related at a central place '
                'before the application starts serving requests.')
        return f(self, *args, **kwargs)
    return update_wrapper(wrapper_func, f)
A more interesting example is Flask's route decorator, which is defined in the class Flask. Note how a decorator can be a method in a class, and as such has self as the first parameter. The full source is in the app.py file. Notice that the decorator simply registers the decorated function as a URL handler by calling the add_url_rule function.
def route(self, rule, **options):
 """A decorator that is used to register a view function for a
 given URL rule.  This does the same thing as :meth:`add_url_rule`
 but is intended for decorator usage::

     @app.route('/')
     def index():
         return 'Hello World'

 For more information refer to :ref:`url-route-registrations`.

 :param rule: the URL rule as string
 :param endpoint: the endpoint for the registered URL rule.  Flask
                  itself assumes the name of the view function as
                  endpoint
 :param options: the options to be forwarded to the underlying
                 :class:`~werkzeug.routing.Rule` object.  A change
                 to Werkzeug is handling of method options.  methods
                 is a list of methods this rule should be limited
                 to (`GET`, `POST` etc.).  By default a rule
                 just listens for `GET` (and implicitly `HEAD`).
                 Starting with Flask 0.6, `OPTIONS` is implicitly
                 added and handled by the standard request handling.
 """
 def decorator(f):
     endpoint = options.pop('endpoint', None)
     self.add_url_rule(rule, endpoint, f, **options)
     return f
 return decorator


Further Reading

The official Python Wiki has lots of more information on decorators if you're looking for further reading.
There is also David Beazley's excellent video on metaprogramming in Python 3.