Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 69 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,101 +1,84 @@
Python AOP Framework
====================
# Python AOP Framework

Python AOP Framework is a minimal Framework to use Aspect-Oriented Programming
on your Python applications

Examples
--------
## Examples

### Definition of Aspects ###
### Definition of Aspects

>>> import logging
>>> from aop import Aspect
>>>
>>> class InvocationLoggerAspect(Aspect):
... def __init__(self, *args, **kwargs):
... super().__init__(*args, **kwargs)
... self.logger = logging.getLogger('python-aop')
... self.logger.setLevel(logging.DEBUG)
...
... fh = logging.FileHandler('auth.log')
... fh.setLevel(logging.DEBUG)
...
... self.logger.addHandler(fh)
...
... def before(self, *args, **kwargs):
... self.logger.info(
... 'Invocation: name=%s, args=%s, kwargs=%s' % (
... self.function,
... args,
... kwargs
... )
... )
...
>>>
```python
import logging
from aop import Aspect
class InvocationLoggerAspect(Aspect):
def __init__(self, *args, **kwargs):
super(InvocationLoggerAspect, self).__init__(*args, **kwargs)
self.logger = logging.getLogger('python-aop')
self.logger.setLevel(logging.DEBUG)

fh = logging.FileHandler('auth.log')
fh.setLevel(logging.DEBUG)

self.logger.addHandler(fh)

def before(self, *args, **kwargs):
self.logger.info(
'Invocation: name=%s, args=%s, kwargs=%s' % (
self.function,
args,
kwargs
)
)
```


### Use of Aspect over functions ###
### Use of Aspect over functions

If we want to log each invocation attempt we can apply the aspect directly to a function

>>> def auth(user, password):
... if user == 'aop' and password == '#$%3&23%#$(%':
... return True
... return False
...
>>>
>>> auth = InvocationLoggerAspect(auth)
>>>
>>> auth('aop', '#$%3&23%#$(%')
True
>>> auth('aop', '')
False
>>>
```python
>>> def auth(user, password):
... if user == 'aop' and password == '#$%3&23%#$(%':
... return True
... return False
...
>>>
>>> auth = InvocationLoggerAspect(auth)
>>>
>>> auth('aop', '#$%3&23%#$(%')
True
>>> auth('aop', '')
False
>>>
```

The content of **auth.log**:
The content of `auth.log`:

Invocation: name=<function auth at 0x7f1e30282290>, args=('aop', '#$%3&23%#$(%'), kwargs={}
Invocation: name=<function auth at 0x7f1e30282290>, args=('aop', ''), kwargs={}
```text
Invocation: name=<function auth at 0x7f1e30282290>, args=('aop', '#$%3&23%#$(%'), kwargs={}
Invocation: name=<function auth at 0x7f1e30282290>, args=('aop', ''), kwargs={}
```

### Use of AspectType

### Use of AspectType ###
```python
>>> from aop import Aspect, AspectType
>>> class AuthenticationBackend(object):
... __metaclass__ = AspectType
...
... def auth(self, user, password):
... if user == 'aop' and password == '#$%3&23%#$(%':
... return True
... return False
...
>>> AuthenticationBackend.pointcut('auth', InvocationLoggerAspect)
>>>
>>> backend = AuthenticationBackend()
>>> backend.auth('aop', '#$%3&23%#$(%')
True
>>> backend.auth('aop', '')
False
>>>
```

>>> import logging
>>> from aop import Aspect, AspectType
>>>
>>> class InvocationLoggerAspect(Aspect):
... def __init__(self, *args, **kwargs):
... super().__init__(*args, **kwargs)
... self.logger = logging.getLogger('python-aop')
... self.logger.setLevel(logging.DEBUG)
...
... fh = logging.FileHandler('auth.log')
... fh.setLevel(logging.DEBUG)
...
... self.logger.addHandler(fh)
...
... def before(self, *args, **kwargs):
... self.logger.info(
... 'Invocation: name=%s, args=%s, kwargs=%s' % (
... self.function,
... args,
... kwargs
... )
... )
...
>>>
>>> class AuthenticationBackend(metaclass=AspectType):
... def auth(self, user, password):
... if user == 'aop' and password == '#$%3&23%#$(%':
... return True
... return False
...
>>> AuthenticationBackend.pointcut('auth', InvocationLoggerAspect)
>>>
>>> backend = AuthenticationBackend()
>>> backend.auth('aop', '#$%3&23%#$(%')
True
>>> backend.auth('aop', '')
False
>>>
The same `auth.log` is generated.
1 change: 1 addition & 0 deletions aop/aspectbase.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
"""
python-aop is part of LemonFramework.

Expand Down
1 change: 1 addition & 0 deletions aop/aspecttype.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
"""
python-aop is part of LemonFramework.

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
python-aop is part of LemonFramework.

Expand Down
File renamed without changes.
8 changes: 5 additions & 3 deletions tests/aspecttype.py → tests/test_aspecttype.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

class TestAspectType(unittest.TestCase):
def test_pointcut_attr(self):
class TestClass(metaclass=AspectType):
pass
class TestClass(object):
__metaclass__ = AspectType

self.assertTrue(hasattr(TestClass, 'pointcut'))

def test_pointcut(self):
class TestClass(metaclass=AspectType):
class TestClass(object):
__metaclass__ = AspectType

def method(self):
return True

Expand Down