AOP in Python API design         Douwe van der Meij Goldmund, Wyldebeast & Wunderliebe
Outline● Problem description● Aspect Oriented Programming● Implementation
Case● BioBench:  ○ Application for biogas installations● Enter measurements● Normalize data● Calculate plant performance
Problem description● Large code-base● A lot of calculations● Django web-interface● Make calculations available via an API
Problem description● Is there a library/framework?● Are the alternatives?● What is the actual impact of the feature?● What...
Problem description● Aspects:  ○ Security  ○ Statistics / Logging  ○ Serialization  ○ More?
Problem descriptiondef add(lhs, rhs):   return lhs + rhs
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   return add(request.args[lhs],             ...
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   if request.args[token] == valid:      retu...
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   if request.args[token] == valid:     datab...
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   if request.args[token] == valid:     datab...
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   if request.args[token] == valid:     datab...
Problem descriptiondef add(lhs, rhs):   return lhs + rhsdef api_add(request):   if request.args[token] == valid:     datab...
Problem description     Code base
Problem description● Security      Code base
Problem description● Statistics / Logging       Code base
Problem description● Serialization       Code base
Problem description● Dispatcher      Code base
Problem description● Scattered / tangled code      Code base
Aspect Oriented Programming● What is AOP?● Separation of concerns (aspects)● Avoid scattering / tangling
Aspect Oriented Programming● Scattered / tangled code      Code base
Aspect Oriented Programming● Avoid scattering      Code base
Aspect Oriented Programming● Avoid tangling      Code base
Aspect Oriented Programming● How to implement these marvelous  concepts?  ○ In pure python please!
Aspect Oriented Programming● Decorators!
Aspect Oriented Programming● Aspect:  ○ Pointcuts  ○ Join points  ○ Advices    ■ Before advices    ■ After advices    ■ Ar...
Aspect Oriented Programming● Before advice   ○ Must execute the function (no side-effects)def aspect(function):   def advi...
Aspect Oriented Programming● After advice   ○ Must execute the function (no side-effects)def aspect(function):   def advic...
Aspect Oriented Programming● Around advice   ○ Allowed to bypass the functiondef aspect(function):   def advice(*args, **k...
Implementation● How to apply it to our case?
Implementation● The decorators
Implementation● Security aspect   ○ Around advicedef secure(function):   def advice(*args, **kwargs):       if   valid tok...
Implementation● Statistics aspect   ○ Before advicedef statistics(function):   def advice(*args, **kwargs):       increase...
Implementation● Serialization aspect   ○ Around advicedef serialize(function):   def advice(format, *args, **kwargs):     ...
Implementation● Dispatcher aspect   ○ Around advicedef dispatch(function):   def advice(*args, **kwargs):       proxy the ...
Implementationmapping   = {    api_function:        (core_function, [lhs, rhs]),    create_token:        (create_token, [u...
Implementationdef dispatch(function):   def advice(*args, **kwargs):      if   API call   proxy mapping:                  ...
Implementation● The API itself
Implementation@secure@serialize@statistics@dispatchdef api_call(*args, **kwargs):   proxy_function = kwargs[proxy]   param...
Conclusion● AOP offers some brilliant concepts in  software engineering● Separate your concerns / aspects  ○ Avoid classic...
Questions?● Thank you! vandermeij@gw20e.com @douwevandermeij
Upcoming SlideShare
Loading in …5
×

AOP in Python API design

3,192 views

Published on

Talk at PyGrunn 2012 by Douwe van der Meij.

Published in: Technology

AOP in Python API design

  1. 1. AOP in Python API design Douwe van der Meij Goldmund, Wyldebeast & Wunderliebe
  2. 2. Outline● Problem description● Aspect Oriented Programming● Implementation
  3. 3. Case● BioBench: ○ Application for biogas installations● Enter measurements● Normalize data● Calculate plant performance
  4. 4. Problem description● Large code-base● A lot of calculations● Django web-interface● Make calculations available via an API
  5. 5. Problem description● Is there a library/framework?● Are the alternatives?● What is the actual impact of the feature?● What aspects to take into account?
  6. 6. Problem description● Aspects: ○ Security ○ Statistics / Logging ○ Serialization ○ More?
  7. 7. Problem descriptiondef add(lhs, rhs): return lhs + rhs
  8. 8. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): return add(request.args[lhs], request.args[rhs])
  9. 9. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): if request.args[token] == valid: return add(request.args[lhs], request.args[rhs]) raise Exception(Security error)
  10. 10. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): if request.args[token] == valid: database.query().alter usage counter return add(request.args[lhs], request.args[rhs]) raise Exception(Security error)
  11. 11. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): if request.args[token] == valid: database.query().alter usage counter result = add(request.args[lhs], request.args[rhs]) return <xml>{0}</xml>.format(result) raise Exception(Security error)
  12. 12. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): if request.args[token] == valid: database.query().alter usage counter result = add(request.args[lhs], request.args[rhs]) return <xml>{0}</xml>.format(result) raise Exception(Security error)
  13. 13. Problem descriptiondef add(lhs, rhs): return lhs + rhsdef api_add(request): if request.args[token] == valid: database.query().alter usage counter result = add(request.args[lhs], request.args[rhs]) return <xml>{0}</xml>.format(result) raise Exception(Security error)
  14. 14. Problem description Code base
  15. 15. Problem description● Security Code base
  16. 16. Problem description● Statistics / Logging Code base
  17. 17. Problem description● Serialization Code base
  18. 18. Problem description● Dispatcher Code base
  19. 19. Problem description● Scattered / tangled code Code base
  20. 20. Aspect Oriented Programming● What is AOP?● Separation of concerns (aspects)● Avoid scattering / tangling
  21. 21. Aspect Oriented Programming● Scattered / tangled code Code base
  22. 22. Aspect Oriented Programming● Avoid scattering Code base
  23. 23. Aspect Oriented Programming● Avoid tangling Code base
  24. 24. Aspect Oriented Programming● How to implement these marvelous concepts? ○ In pure python please!
  25. 25. Aspect Oriented Programming● Decorators!
  26. 26. Aspect Oriented Programming● Aspect: ○ Pointcuts ○ Join points ○ Advices ■ Before advices ■ After advices ■ Around advices
  27. 27. Aspect Oriented Programming● Before advice ○ Must execute the function (no side-effects)def aspect(function): def advice(*args, **kwargs): do something here return function(*args, **kwargs) return advice
  28. 28. Aspect Oriented Programming● After advice ○ Must execute the function (no side-effects)def aspect(function): def advice(*args, **kwargs): result = function(*args, **kwargs) do something here return result return advice
  29. 29. Aspect Oriented Programming● Around advice ○ Allowed to bypass the functiondef aspect(function): def advice(*args, **kwargs): do something here result = function(*args, **kwargs) do something here return result return advice
  30. 30. Implementation● How to apply it to our case?
  31. 31. Implementation● The decorators
  32. 32. Implementation● Security aspect ○ Around advicedef secure(function): def advice(*args, **kwargs): if valid token in request object: return function(*args, **kwargs) raise Exception(No valid token provided) return advice
  33. 33. Implementation● Statistics aspect ○ Before advicedef statistics(function): def advice(*args, **kwargs): increase API usage count for the user logged in return function(*args, **kwargs) return advice
  34. 34. Implementation● Serialization aspect ○ Around advicedef serialize(function): def advice(format, *args, **kwargs): if not format in [html, xml, json]: raise exception result = function(*args, **kwargs) make a http response of result in the right format return advice
  35. 35. Implementation● Dispatcher aspect ○ Around advicedef dispatch(function): def advice(*args, **kwargs): proxy the API call to a call to the core system return advice
  36. 36. Implementationmapping = { api_function: (core_function, [lhs, rhs]), create_token: (create_token, [username, password]),}
  37. 37. Implementationdef dispatch(function): def advice(*args, **kwargs): if API call proxy mapping: in core_function, params = mapping[API call] kwargs.update(extract(params, request)) return function(proxy=core_function, params=params, *args, **kwargs) raise exception return advice
  38. 38. Implementation● The API itself
  39. 39. Implementation@secure@serialize@statistics@dispatchdef api_call(*args, **kwargs): proxy_function = kwargs[proxy] params = kwargs[params] return proxy_function(extract params from kwargs)
  40. 40. Conclusion● AOP offers some brilliant concepts in software engineering● Separate your concerns / aspects ○ Avoid classical scattering and tangling
  41. 41. Questions?● Thank you! vandermeij@gw20e.com @douwevandermeij

×