Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Plug-in architectures for Python web applications
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Raphael Michel
October 25, 2017
Programming
89
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Plug-in architectures for Python web applications
Raphael Michel
October 25, 2017
More Decks by Raphael Michel
See All by Raphael Michel
Automatic Screenshots of your Django web application with py.test and Selenium
raphaelm
1
270
Data Internationalization in Django
raphaelm
2
570
Other Decks in Programming
See All in Programming
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
160
Railsバージョンを4倍にした話
optim
0
310
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
170
Domain-Driven Transformation
hschwentner
2
2.3k
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
420
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
260
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5k
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
210
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
390
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
4
3.2k
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
699
190k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
460
New Earth Scene 8
popppiees
4
2.7k
The untapped power of vector embeddings
frankvandijk
2
1.9k
Odyssey Design
rkendrick25
PRO
2
870
It's Worth the Effort
3n
188
29k
エンジニアに許された特別な時間の終わり
watany
109
250k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
380
Faster Mobile Websites
deanohume
310
32k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Transcript
PLUG IN ECOSYSTEMS FOR PYTHON WEB APPLICATIONS
None
Source: w3techs.com WordPress is used by 59.6% of all the
websites whose content management system we know. This is 28.7% of all websites.
None
Open Source event ticket shop Python/Django stack Key design goal:
Be extensible. Don't make people patch or fork it.
IDEAS FOR PLUGINS Payment methods Export formats, ticket layouts Additional
features
OUR PLAN 1. Establish a way that plugins can hook
into your application 2. Provide many of these hooks 3. Document them well 4. There is no step four!
LET'S WRITE SOME PYTHON!
SIMPLE SIGNAL SYSTEM class Signal: def __init__(self): self.receivers = []
def register(self, func): self.receivers.append(func) return func def send(self, *args, **kwargs) return [ func(*args, **kwargs) for func in self.receivers ] user_created = Signal() @user_created.register def plugin_listener(): send_mail()
DJANGO.DISPATCH.SIGNAL Similar API Handles thread-safety for you Caching, weak references,
… → If you're on Django, use this one.
1 PLUGIN = 1 DJANGO APP Plugins can have their
own models Plugins can have their own templates Plugins can have their own static files …
HOW TO INSTALL A PLUGIN Like a django app! Install
package with source code Add to INSTALLED_APPS in settings.py Add url include to urls.py Too many steps! And we don't want to touch code…
ALL WE WANT IST $ pip install pretix-xyz (+ migrations,
maybe)
PLUGIN: __INIT__.PY from django.apps import AppConfig class PluginApp(AppConfig): name =
'xyz' verbose_name = 'XYZ plugin' class PretixPluginMeta: name = 'XYZ plugin' def ready(self): from . import signals default_app_config = 'pretix_xyz.PluginApp'
PLUGIN: SETUP.PY setup( name='pretix-xyz', install_requires=[], packages=find_packages(exclude=['tests', 'tests.*']), include_package_data=True, entry_points={ 'pretix.plugin':
[ 'pretix_xyz=pretix_xyz:PretixPluginMeta' ] } )
APP: SETTINGS.PY from pkg_resources import iter_entry_points for entry_point in iter_entry_points(
group='pretix.plugin', name=None): INSTALLED_APPS.append(entry_point.module_name)
PLUGIN: URLS.PY urlpatterns = [ url(…), … ]
APP: URLS.PY plugin_patterns = [] for app in apps.get_app_configs(): if
hasattr(app, 'PretixPluginMeta'): if importlib.util.find_spec(app.name + '.urls'): urlmod = importlib.import_module( app.name + '.urls') plugin_patterns.append( url('', include((singlurlmod.urlpatterns, app.label))) ) urlpatterns = [ ..., url('', include((plugin_patterns, 'plugins'))) ] {% url "plugins:pretix_xyz:my.url.name" %}
THAT'S OUR PLUGIN SYSTEM!
BONUS: PLUGINS PER CLIENT/USER Custom Signal() subclass Store list of
enabled plugins per client More URL magic (if wanted)
MAKE IT EASY {% load signal %} … {% signal
"pretix.control.signals.order_info" order=order %} @register.simple_tag def signal(signame: str, **kwargs): sigmodule, signame = signame.rsplit('.', 1) sigmodule = importlib.import_module(sigmodule) signal = getattr(sigmodule, signame) html_result = [] for receiver, response in signal.send(event, **kwargs): if response: html_result.append(response) return mark_safe("".join(html_result))
WRITE DOCUMENTATION No, seriously.
PROVIDE A COOKIECUTTER TEMPLATE $ cookiecutter \ https://github.com/pretix/pretix- plugin-cookiecutter
AUTO-INSTALL Naah, better don't.
THANK YOU! ANY QUESTIONS? Raphael Michel
[email protected]
@_rami_ raphaelm pretix.eu
[email protected]
@pretixeu pretix
MAY 23-27TH, 2018 HEIDELBERG, GERMANY 2018.DJANGOCON.EU