33
Dynamic Code Patterns: Extending Your Applications with Plugins Doug Hellmann – @doughellmann – PyCon 2013 1 Saturday, March 16, 13

Dynamic Code Patterns: Extending Your Applications with Plugins

Embed Size (px)

DESCRIPTION

Python makes loading code dynamically easy, allowing you to configure and extend your application by discovering and loading extensions at runtime. This presentation will discuss the techniques for dynamic code loading used in several well-known applications and weigh the pros and cons of each approach.

Citation preview

Page 1: Dynamic Code Patterns: Extending Your Applications with Plugins

Dynamic Code Patterns:Extending Your

Applications with PluginsDoug Hellmann – @doughellmann – PyCon 2013

1Saturday, March 16, 13

Page 2: Dynamic Code Patterns: Extending Your Applications with Plugins

What is a “Plugin”?

• Loaded Dynamically

• Extends Core

• Possibly Unknown Source

2Saturday, March 16, 13

Page 3: Dynamic Code Patterns: Extending Your Applications with Plugins

Why Plugins?

• Better API Abstraction

• Reduce Core Dependencies

• Strategy Pattern

• Visitor Pattern

• Indirect Code Contributions

3Saturday, March 16, 13

Page 4: Dynamic Code Patterns: Extending Your Applications with Plugins

• OpenStack Metering

• Measures Clouds

• Varied Billing Requirements

• Deployers Extend and Customize

Ceilometer

4Saturday, March 16, 13

Page 5: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 6: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 7: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 8: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 9: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 10: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 11: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 12: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 13: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 14: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Plugins

• Message Bus

• Receiving Notifications

• Polling Compute

• Polling Other

• Storage

6Saturday, March 16, 13

Page 15: Dynamic Code Patterns: Extending Your Applications with Plugins

Research• Blogofile

• Sphinx

• Mercurial

• cliff

• virtualenvwrapper

• Nose

• Trac

• Django

• Pyramid

• SQLAlchemy

• Diamond

• Nova

7Saturday, March 16, 13

Page 16: Dynamic Code Patterns: Extending Your Applications with Plugins

Discovery

Explicit Scan

File

Import Reference

Mercurial DiamondBlogofile

Mercurial DjangoPyramidSphinxNova

TracNosecliff

virtualenvwrapper

8Saturday, March 16, 13

Page 17: Dynamic Code Patterns: Extending Your Applications with Plugins

Enabling

Explicit Implicit

DjangoPyramid

SQLAlchemyBlogofileMercurial

TracSphinx

virtualenvwrappercliff

9Saturday, March 16, 13

Page 18: Dynamic Code Patterns: Extending Your Applications with Plugins

Importing

Custom pkg_resources

DjangoPyramidSphinx

DiamondNova Nose

SQLAlchemyBlogofile

TracNose

SQLAlchemyBlogofile

cliffvirtualenvwrapper

10Saturday, March 16, 13

Page 19: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

Fine Coarse

Prompt

Inspect

Nosevirtualenvwrapper

SphinxTrac

cliffDiamond

MercurialBlogofilePyramidDjango

11Saturday, March 16, 13

Page 20: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

Fine Coarse

Prompt

Inspect

Nosevirtualenvwrapper

SphinxTrac

cliffDiamond

MercurialBlogofilePyramidDjango

12Saturday, March 16, 13

Page 21: Dynamic Code Patterns: Extending Your Applications with Plugins

API Enforcement

Convention Base Class / Interface

BlogofileMercurialDjangoSphinx

Pyramidvirtualenvwrapper

Nose (optional)Trac (interface)

Diamondcliff (abc)

13Saturday, March 16, 13

Page 22: Dynamic Code Patterns: Extending Your Applications with Plugins

Invocation

Driver Dispatcher Iterator

SQLAlchemyNova

MercurialDjangoPyramid

cliff

NoseDiamond

virtualenvwrapper

14Saturday, March 16, 13

Page 23: Dynamic Code Patterns: Extending Your Applications with Plugins

Discovery / Importing

• Entry Points

• Distribute and pkg_resources

• Be Consistent

15Saturday, March 16, 13

Page 24: Dynamic Code Patterns: Extending Your Applications with Plugins

Enabling

• Explicit disabling

• Automatic disabling

16Saturday, March 16, 13

Page 25: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

• Fine

• Inspect

• Application Owns Relationship

17Saturday, March 16, 13

Page 26: Dynamic Code Patterns: Extending Your Applications with Plugins

API Enforcement

• Abstract Base Classes

• Duck Typing

18Saturday, March 16, 13

Page 27: Dynamic Code Patterns: Extending Your Applications with Plugins

Invocation

• Storage – Driver

• Notifications – Dispatcher

• Pollsters – Iterator

19Saturday, March 16, 13

Page 28: Dynamic Code Patterns: Extending Your Applications with Plugins

stevedore

• Implements Patterns

• Wraps pkg_resources

20Saturday, March 16, 13

Page 29: Dynamic Code Patterns: Extending Your Applications with Plugins

NamedExtensionManager

• Multiple Plugins

• Only Loads Named Plugins

• map()

21Saturday, March 16, 13

Page 30: Dynamic Code Patterns: Extending Your Applications with Plugins

EnabledExtensionManager

• Multiple Plugins

• Checks Each with Function on Load

• map()

22Saturday, March 16, 13

Page 31: Dynamic Code Patterns: Extending Your Applications with Plugins

DispatchExtensionManager

• Multiple Plugins

• Invokes Subset on map()

23Saturday, March 16, 13

Page 32: Dynamic Code Patterns: Extending Your Applications with Plugins

DriverManager

• Single Plugin

• Direct Access

24Saturday, March 16, 13

Page 33: Dynamic Code Patterns: Extending Your Applications with Plugins

Dynamic Code Patterns:Extending Your

Applications with PluginsDoug Hellmann – @doughellmann – PyCon 2013

http://packages.python.org/distribute/pkg_resources.html

https://github.com/dreamhost/stevedore

https://launchpad.net/ceilometer

http://doughellmann.com

25Saturday, March 16, 13