<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: andrew-godwin</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/andrew-godwin.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2022-12-06T00:50:13+00:00</updated><author><name>Simon Willison</name></author><entry><title>Understanding a Protocol</title><link href="https://simonwillison.net/2022/Dec/6/understanding-a-protocol/#atom-tag" rel="alternate"/><published>2022-12-06T00:50:13+00:00</published><updated>2022-12-06T00:50:13+00:00</updated><id>https://simonwillison.net/2022/Dec/6/understanding-a-protocol/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.aeracode.org/2022/12/05/understanding-a-protocol/"&gt;Understanding a Protocol&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew’s latest notes on how ActivityPub and Mastodon work under the hood, based on his extensive development work building out Takahē.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mastodon"&gt;mastodon&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/activitypub"&gt;activitypub&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="mastodon"/><category term="activitypub"/></entry><entry><title>Quoting Andrew Godwin</title><link href="https://simonwillison.net/2022/Nov/19/andrew-godin/#atom-tag" rel="alternate"/><published>2022-11-19T16:02:57+00:00</published><updated>2022-11-19T16:02:57+00:00</updated><id>https://simonwillison.net/2022/Nov/19/andrew-godin/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://aeracode.org/2022/11/15/twitter-activitypub-future/"&gt;&lt;p&gt;... it [ActivityPub] is crucially good enough. Perfect is the enemy of good, and in ActivityPub we have a protocol that has flaws but, crucially, that works, and has a standard we can all mostly agree on how to implement - and eventually, I hope, agree on how to improve.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://aeracode.org/2022/11/15/twitter-activitypub-future/"&gt;Andrew Godwin&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mastodon"&gt;mastodon&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/activitypub"&gt;activitypub&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="mastodon"/><category term="activitypub"/></entry><entry><title>Django: Added support for asynchronous views and middleware</title><link href="https://simonwillison.net/2020/Mar/19/async-views-and-middleware/#atom-tag" rel="alternate"/><published>2020-03-19T03:43:40+00:00</published><updated>2020-03-19T03:43:40+00:00</updated><id>https://simonwillison.net/2020/Mar/19/async-views-and-middleware/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/django/django/commit/fc0fa72ff4cdbf5861a366e31cb8bbacd44da22d"&gt;Django: Added support for asynchronous views and middleware&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
An enormously consequential feature just landed in Django, and is set to ship as part of Django 3.1 in August. Asynchronous views will allow Django applications to define views using “async def myview(request)”—taking full advantage of Python’s growing asyncio ecosystem and providing enormous performance improvements for Django sites that do things like hitting APIs over HTTP. Andrew has been puzzling over this for ages and it’s really exciting to see it land in a form that should be usable in a stable Django release in just a few months.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/andrewgodwin/status/1240357729174052866"&gt;@andrewgodwin&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="django"/></entry><entry><title>Porting Datasette to ASGI, and Turtles all the way down</title><link href="https://simonwillison.net/2019/Jun/23/datasette-asgi/#atom-tag" rel="alternate"/><published>2019-06-23T21:39:00+00:00</published><updated>2019-06-23T21:39:00+00:00</updated><id>https://simonwillison.net/2019/Jun/23/datasette-asgi/#atom-tag</id><summary type="html">
    &lt;p&gt;This evening I finally closed a &lt;a href="https://simonwillison.net/tags/datasette/"&gt;Datasette&lt;/a&gt; issue that I opened more than 13 months ago: &lt;a href="https://github.com/simonw/datasette/issues/272"&gt;#272: Port Datasette to ASGI&lt;/a&gt;. A few notes on why this is such an important step for the project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://asgi.readthedocs.io/"&gt;ASGI&lt;/a&gt; is the Asynchronous Server Gateway Interface standard. It’s been evolving steadily over the past few years under the guidance of Andrew Godwin. It’s intended as an asynchronous replacement for the venerable &lt;a href="https://wsgi.readthedocs.io/"&gt;WSGI&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Turtles_all_the_way_down_6"&gt;&lt;/a&gt;Turtles all the way down&lt;/h3&gt;
&lt;p&gt;Ten years ago at EuroDjangoCon 2009 in Prague I gave a talk entitled &lt;a href="https://www.slideshare.net/simon/django-heresies"&gt;Django Heresies&lt;/a&gt;. After discussing some of the design decisions in Django that I didn’t think had aged well, I spent the last part of the talk talking about &lt;em&gt;Turtles all the way down&lt;/em&gt;. I &lt;a href="https://simonwillison.net/2009/May/19/djng/?#turtles-all-the-way-down"&gt;wrote that idea up here&lt;/a&gt; on my blog (see also &lt;a href="https://www.slideshare.net/simon/django-heresies/65-The_Django_Contract_A_view"&gt;these slides&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The key idea was that Django would be more interesting if the core Django contract - a function that takes a request and returns a response - was extended to more places in the framework. The top level site, the reusable applications, middleware and URL routing could all share that same contract. Everything could be composed from the same raw building blocks.&lt;/p&gt;
&lt;p&gt;I’m excited about ASGI because it absolutely fits the &lt;em&gt;turtles all the way down&lt;/em&gt; model.&lt;/p&gt;
&lt;p&gt;The ASGI contract is an asynchronous function that takes three arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async def application(scope, receive, send):
    ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;scope&lt;/code&gt; is a serializable dictionary providing the context for the current connection. &lt;code&gt;receive&lt;/code&gt; is an awaitable which can be used to recieve incoming messages. &lt;code&gt;send&lt;/code&gt; is an awaitable that can be used to send replies.&lt;/p&gt;
&lt;p&gt;It’s a pretty low-level set of primitives (and less obvious than a simple request/response) - and that’s because ASGI is about more than just the standard HTTP request/response cycle. This contract works for HTTP, WebSockets and potentially any other protocol that needs to asynchronously send and receive data.&lt;/p&gt;
&lt;p&gt;It’s an extremely elegant piece of protocol design, informed by Andrew’s experience with Django Channels, SOA protocols (we are co-workers at Eventbrite where we’ve both been heavily involved in Eventbrite’s &lt;a href="https://github.com/eventbrite/pysoa"&gt;SOA mechanism&lt;/a&gt;) and Andrew’s extensive conversations with other maintainers in the Python web community.&lt;/p&gt;
&lt;p&gt;The ASGI protocol really is turtles all the way down - it’s a simple, well defined contract which can be composed together to implement all kinds of interesting web architectural patterns.&lt;/p&gt;
&lt;p&gt;My &lt;a href="https://github.com/simonw/asgi-cors/"&gt;asgi-cors library&lt;/a&gt; was my first attempt at building an ASGI turtle. &lt;a href="https://github.com/simonw/asgi-cors/blob/master/asgi_cors.py"&gt;The implementation&lt;/a&gt; is a simple Python decorator which, when applied to another ASGI callable, adds HTTP CORS headers based on the parameters you pass to the decorator. The library has zero installation dependencies (it has test dependencies on pytest and friends) and can be used on any HTTP ASGI project.&lt;/p&gt;
&lt;p&gt;Building &lt;code&gt;asgi-cors&lt;/code&gt; completely sold me on ASGI as the turtle pattern I had been desiring for over a decade!&lt;/p&gt;
&lt;h3&gt;&lt;a id="Datasette_plugins_and_ASGI_31"&gt;&lt;/a&gt;Datasette plugins and ASGI&lt;/h3&gt;
&lt;p&gt;Which brings me to Datasette.&lt;/p&gt;
&lt;p&gt;One of the most promising components of Datasette is its plugin mechanism. Based on &lt;a href="https://pluggy.readthedocs.io/en/latest/"&gt;pluggy&lt;/a&gt; (extracted from pytest), &lt;a href="https://datasette.readthedocs.io/en/stable/plugins.html"&gt;Datasette Plugins&lt;/a&gt; allow new features to be added to Datasette without needing to change the underlying code. This means new features can be built, packaged and shipped entirely independently of the core project. A list of currently available plugins &lt;a href="https://datasette.readthedocs.io/en/latest/ecosystem.html#datasette-plugins"&gt;can be found here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;WordPress is very solid blogging engine. Add in the plugin ecosystem around it and it can be used to build literally any CMS you can possibly imagine.&lt;/p&gt;
&lt;p&gt;My dream for Datasette is to apply the same model: I want a strong core for publishing and exploring data that’s enhanced by plugins to solve a huge array of data analysis, visualization and API-backed problems.&lt;/p&gt;
&lt;p&gt;Datasette has &lt;a href="https://datasette.readthedocs.io/en/latest/plugins.html#plugin-hooks"&gt;a range of plugin hooks already&lt;/a&gt;, but I’ve so far held back on implementing the most useful class of hooks: hooks that allow developers to add entirely new URL routes exposing completely custom functionality.&lt;/p&gt;
&lt;p&gt;The reason I held back is that I wanted to be confident that the contract I was offering was something I would continue to support moving forward. A plugin system isn’t much good if the core implementation keeps on changing in backwards-incompatible ways.&lt;/p&gt;
&lt;p&gt;ASGI is the exact contract I’ve been waiting for. It’s not quite ready yet, but you can follow &lt;a href="https://github.com/simonw/datasette/issues/520"&gt;#520: prepare_asgi plugin hook&lt;/a&gt; (thoughts and suggestions welcome!) to be the first to hear about this hook when it lands. I’m planning to use it to make my asgi-cors library available as a plugin, after which I’m excited to start exploring the idea of bringing authentication plugins to Datasette (and to the wider ASGI world in general).&lt;/p&gt;
&lt;p&gt;I’m hoping that many Datasette ASGI plugins will exist in a form that allows them to be used by other ASGI applications as well.&lt;/p&gt;
&lt;p&gt;I also plan to use ASGI to make components of Datasette itself available to other ASGI applications. If you just want a single instance of Datasette’s &lt;a href="https://datasette.readthedocs.io/en/stable/pages.html#table"&gt;table view&lt;/a&gt; to be embedded somewhere in your URL configuration you should be able to do that by routing traffic directly to the ASGI-compatible view class.&lt;/p&gt;
&lt;p&gt;I’m really excited about exploring the intersection of ASGI turtles-all-the-way-down and pluggy’s powerful mechanism for gluing components together. Both WSGI and Django’s reusable apps have attempted to create a reusable ecosystem in the past, to limited levels of success. Let’s see if ASGI can finally make the turtle dream come true.&lt;/p&gt;

&lt;h3&gt;&lt;a id="Further_reading_53"&gt;&lt;/a&gt;Further reading&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.encode.io/articles/hello-asgi/"&gt;Hello ASGI&lt;/a&gt; by Tom Christie is the best introduction to ASGI I’ve seen. Tom is the author of the &lt;a href="https://www.uvicorn.org/"&gt;Uvicorn&lt;/a&gt; ASGI server (used by Datasette as-of this evening) and &lt;a href="https://www.starlette.io/"&gt;Starlette&lt;/a&gt;, a delightfully well-designd ASGI web framework. I’ve learned an enormous amount about ASGI by reading Tom’s code. Tom also gave &lt;a href="https://www.youtube.com/watch?v=u8GSFEg5lnU"&gt;a talk about ASGI&lt;/a&gt; at DjangoCon Europe a few months ago.&lt;/p&gt;
&lt;p&gt;If you haven’t read &lt;a href="https://www.aeracode.org/2018/06/04/django-async-roadmap/"&gt;A Django Async Roadmap&lt;/a&gt; by Andrew Godwin last year you should absolutely catch up. More than just talking about ASGI, Andrew sketches out a detailed and actionable plan for bringing asyncio to Django core. Andrew landeded &lt;a href="https://github.com/django/django/pull/11209"&gt;the first Django core ASGI code&lt;/a&gt; based on the plan just a few days ago.&lt;/p&gt;
&lt;p&gt;If you're interested in the details of Datasette's ASGI implementation, I posted &lt;a href="https://github.com/simonw/datasette/issues/272"&gt;detailed commentary on issue #272&lt;/a&gt; over the past thirteen months as I researched and finalized my approach. I added further commentary to &lt;a href="https://github.com/simonw/datasette/pull/518"&gt;the associated pull request&lt;/a&gt;, which gathers together the 34 commits it took to ship the feature (squashed into a single commit to master).&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/projects"&gt;projects&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datasette"&gt;datasette&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/asgi"&gt;asgi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/kim-christie"&gt;kim-christie&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pytest"&gt;pytest&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/starlette"&gt;starlette&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="andrew-godwin"/><category term="projects"/><category term="datasette"/><category term="asgi"/><category term="kim-christie"/><category term="pytest"/><category term="starlette"/></entry><entry><title>Quoting Andrew Godwin</title><link href="https://simonwillison.net/2019/May/10/andrew-godwin/#atom-tag" rel="alternate"/><published>2019-05-10T02:00:03+00:00</published><updated>2019-05-10T02:00:03+00:00</updated><id>https://simonwillison.net/2019/May/10/andrew-godwin/#atom-tag</id><summary type="html">
    &lt;blockquote cite="https://github.com/andrewgodwin/deps/blob/async/draft/0009-async.rst"&gt;&lt;p&gt;... the overall conclusion I reach is that we have so much to gain from making Django async-capable that it is worth the large amount of work it will take. I also believe, crucially, that we can undertake this change in an iterative, community-driven way that does not rely solely on one or two long-time contributors burning themselves out.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://github.com/andrewgodwin/deps/blob/async/draft/0009-async.rst"&gt;Andrew Godwin&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="django"/></entry><entry><title>How I moderated the State of Django panel at DjangoCon US.</title><link href="https://simonwillison.net/2018/Oct/22/moderating-the-state-of-django/#atom-tag" rel="alternate"/><published>2018-10-22T19:48:53+00:00</published><updated>2018-10-22T19:48:53+00:00</updated><id>https://simonwillison.net/2018/Oct/22/moderating-the-state-of-django/#atom-tag</id><summary type="html">
    &lt;p&gt;On Wednesday last week I moderated the &lt;a href="https://2018.djangocon.us/talk/state-of-django-panel/"&gt;State of Django panel&lt;/a&gt; as the closing session for &lt;a href="https://2018.djangocon.us/"&gt;DjangoCon US 2018&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think it went well, so I’m writing some notes on exactly how we did it. In my experience it’s worth doing this for things like public speaking: in six months time I might moderate another panel and I’ll be desperately trying to remember what went right last time.&lt;/p&gt;
&lt;p&gt;Panels are hard. Bad panels are way too common, to the point that some good conferences actively avoid having panels at all.&lt;/p&gt;
&lt;p&gt;In my opinion, a good panel has a number of important attributes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The panel needs a coherent theme. It shouldn’t just be several independent speakers that happen to be sharing the same time slot.&lt;/li&gt;
&lt;li&gt;Panels need to be balanced. Having just one or two of the speakers monopolize the conversation is bad for the audience and bad for the panelists themselves.&lt;/li&gt;
&lt;li&gt;The moderator is there to facilitate the conversation, not to be the center of attention. I love public speaking so I feel the need to be particularly cautious here.&lt;/li&gt;
&lt;li&gt;Panelists need to have diverse perspectives on the topics under discussion. A panel where everyone agrees with each other and makes the same points is a very boring panel indeed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I originally pitched the panel to the DjangoCon US organizing committee as a “State of Django” conversation where core maintainers would talk about the current state of the project.&lt;/p&gt;
&lt;p&gt;They countered with a much better idea: a panel that encompassed both the state of the Django framework and the community and ecosystem that it exists within. Since DjangoCon is primarily about bringing that community together this was a much better fit for the conference, and would make for a much more interesting and relevant discussion.&lt;/p&gt;
&lt;p&gt;I worked together with the conference organizers to find our panelists. Nicholle James in particular was the driving force behind assembling the panelists and ensuring everything was in place for the panel to succeed.&lt;/p&gt;
&lt;p&gt;We ended up with a panel representing a comprehensive cross-section of the organizations that make the Django community work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Andrew Godwin, representing Django Core&lt;/li&gt;
&lt;li&gt;Anna Makarudze, representing the &lt;a href="https://www.djangoproject.com/foundation/" title="Django Software Foundation"&gt;DSF&lt;/a&gt;, &lt;a href="https://djangogirls.org/"&gt;Django Girls&lt;/a&gt; and &lt;a href="https://africa.python.org/en/"&gt;Python Africa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Frank Wiles, President of the &lt;a href="https://www.djangoproject.com/foundation/" title="Django Software Foundation"&gt;DSF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Jeff Triplett, President of &lt;a href="https://www.defna.org/" title="Django Events Foundation North America"&gt;DEFNA&lt;/a&gt;, member of the Board of Directors for the &lt;a href="https://www.python.org/psf/" title="Python Software Foundation"&gt;PSF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Josue Balandrano Coronel, representing &lt;a href="https://www.defna.org/" title="Django Events Foundation North America"&gt;DEFNA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Katherine Michel, representing &lt;a href="https://www.defna.org/" title="Django Events Foundation North America"&gt;DEFNA&lt;/a&gt; and DjangoCon US Website Chair&lt;/li&gt;
&lt;li&gt;Kojo Idrissa, &lt;a href="https://www.defna.org/" title="Django Events Foundation North America"&gt;DEFNA&lt;/a&gt; North American Ambassador&lt;/li&gt;
&lt;li&gt;Rachell Calhoun, representing &lt;a href="https://djangogirls.org/"&gt;Django Girls&lt;/a&gt; and &lt;a href="https://www.pyladies.com/"&gt;PyLadies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As it was the closing session for the conference, I wanted the panel to both celebrate the progress of the community and project and to explore what we need to do next: what should we be working on to improve Django and it’s community in the future?&lt;/p&gt;
&lt;p&gt;I had some initial thoughts on topics, but since the panel was scheduled for the last session of the conference I decided to spend the conference itself firming up the topics that would be discussed. This was a really good call: we got to create an agenda for the panel that was almost entirely informed by the other conference sessions combined with hot topics from the halfway track. We also asked conference attendees for their suggestions via an online form, and used those suggestions to further inform the topics that were discussed.&lt;/p&gt;
&lt;p&gt;I made sure to have a 10-15 minute conversation one-on-one with each of the panelists during the conference. We then got together for an hour at lunch before the panel to sync up with the topics and themes we would be discussing.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Topic_and_themes_38"&gt;&lt;/a&gt;Topic and themes&lt;/h3&gt;
&lt;p&gt;Our pre-panel conversations highlighted a powerful theme for the panel itself, which I ended up summarizing as “What can the Django project learn from the Django community?” This formed the framework for the other themes of the panel.&lt;/p&gt;
&lt;p&gt;The themes themselves were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diversity and education - inspired by the work of &lt;a href="https://djangogirls.org/"&gt;Django Girls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Events and international focus, lead by &lt;a href="https://www.defna.org/" title="Django Events Foundation North America"&gt;DEFNA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Django governance: In particular James Bennett’s &lt;a href="https://github.com/django/deps/blob/89712df93daeea9fdf7a993342e7087164620eea/draft/XXXX-dissolve-core.rst"&gt;proposal to split up core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Big feature ideas for Django (guided by Andrew Godwin’s proposed &lt;a href="https://www.aeracode.org/2018/06/04/django-async-roadmap/"&gt;Django async roadmap&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Money: who has it, and who needs it - understanding the role of &lt;a href="https://www.djangoproject.com/foundation/"&gt;the DSF&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the hardest parts for me was figuring out the order in which we would tackle these themes. I ended up settling on the above order about half an hour before the panel started.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Opening_and_closing_52"&gt;&lt;/a&gt;Opening and closing&lt;/h3&gt;
&lt;p&gt;With eight panelists, ensuring that introductions didn’t drag on too long was particularly important. I asked each panelist to introduce themselves with a couple of sentences that highlighted the organizations they were affiliated with that were relevant to the panel. For our chosen group of panelists this was definitely the right framing.&lt;/p&gt;
&lt;p&gt;I then asked each panelist to be prepared to close the panel with a call to action: something an audience member could actively do that would support the community going forward. This worked really well: it provided a great, actionable note to end both the panel and the conference.&lt;/p&gt;
&lt;h3&gt;&lt;a id="Preparing_and_running_the_panel_58"&gt;&lt;/a&gt;Preparing and running the panel&lt;/h3&gt;
&lt;p&gt;We used our panel lunch together to check that no one would have calls to action that overlapped too much, and to provide a rough indication of who had things to say about each topic we planned to discuss.&lt;/p&gt;
&lt;p&gt;This turned out to be essential: I’ve been on smaller panels where the panelists have been able to riff easily on each other’s points, but with eight panelists it turned out not everyone could even see each other, so as panel moderator it fell on me to direct questions to individuals and then prompt others for follow-ups. Thankfully the panel lunch combined with the one-to-one conversations gave me the information I needed for this.&lt;/p&gt;
&lt;p&gt;I had written down a selection of questions for each of the themes. Having a selection turned out to be crucial: a few times the panelists talked about material that I had planned to cover in a later section, so I had to adapt as we went along. In the future I’ll spend more time on this: these written ideas were a crucial component in keeping the panel flowing in the right direction.&lt;/p&gt;
&lt;p&gt;With everything in place the panel itself was a case of concentrating on what everyone was saying and using the selection of the next questions (plus careful ad-libbing) to guide the conversation along the preselected themes. I also tried to keep mental track of who had done the most speaking so I could ensure the conversation stayed as balanced as possible by inviting other panelists into the conversation.&lt;/p&gt;
&lt;p&gt;The video of the panel should be out in around three weeks time, at which point you can evaluate for yourself if we managed to do a good job of it. I’m really happy with the feedback we got after the panel, and I plan to use a similar process for panels I’m involved with in the future.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/djangocon"&gt;djangocon&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/frank-wiles"&gt;frank-wiles&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/panels"&gt;panels&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/speaking"&gt;speaking&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/my-talks"&gt;my-talks&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jeff-triplett"&gt;jeff-triplett&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="andrew-godwin"/><category term="django"/><category term="djangocon"/><category term="frank-wiles"/><category term="panels"/><category term="speaking"/><category term="my-talks"/><category term="jeff-triplett"/></entry><entry><title>Andrew Godwin's www-router Docker container</title><link href="https://simonwillison.net/2018/Feb/21/www-router/#atom-tag" rel="alternate"/><published>2018-02-21T05:04:02+00:00</published><updated>2018-02-21T05:04:02+00:00</updated><id>https://simonwillison.net/2018/Feb/21/www-router/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/andrewgodwin/dockerfiles/tree/master/www-router"&gt;Andrew Godwin&amp;#x27;s www-router Docker container&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Really clever Docker trick: a container that runs Nginx  and uses it to route traffic to other containers based on the hostname—but the hostnames to be routed are configured using environment variables which the run-nginx.py CMD script uses to dynamically construct an nginx config when the container starts.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://twitter.com/andrewgodwin/status/966173557121101824"&gt;@andrewgodwin on Twitter&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nginx"&gt;nginx&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/docker"&gt;docker&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="nginx"/><category term="docker"/></entry><entry><title>Python &amp; Async Simplified</title><link href="https://simonwillison.net/2018/Feb/20/async-simplified/#atom-tag" rel="alternate"/><published>2018-02-20T00:30:03+00:00</published><updated>2018-02-20T00:30:03+00:00</updated><id>https://simonwillison.net/2018/Feb/20/async-simplified/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.aeracode.org/2018/02/19/python-async-simplified/"&gt;Python &amp;amp; Async Simplified&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin: “Python’s async framework is actually relatively simple when you treat it at face value, but a lot of tutorials and documentation discuss it in minute implementation detail, so I wanted to make a higher-level overview that deliberately ignores some of the small facts and focuses on the practicalities of writing projects that mix both kinds of code.” ‪This is really useful: clearly explains the two separate worlds of Python (sync and async functions) and describes Andrew’s clever sync_to_async and async_to_sync decorators as well.‬


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="python"/><category term="python3"/></entry><entry><title>asgiref: AsyncToSync and SyncToAsync</title><link href="https://simonwillison.net/2018/Feb/2/asgiref-asynctosync-and-synctoasync/#atom-tag" rel="alternate"/><published>2018-02-02T19:06:48+00:00</published><updated>2018-02-02T19:06:48+00:00</updated><id>https://simonwillison.net/2018/Feb/2/asgiref-asynctosync-and-synctoasync/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/django/asgiref/blob/538ce5ee92962307db1082552839df7d0037176a/asgiref/sync.py"&gt;asgiref: AsyncToSync and SyncToAsync&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew’s classes in asgiref that can turn a synchronous callable into an awaitable (that runs in a thread pool) or an awaitable callable into a synchronous callable, using Python 3 futures and asyncio.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://www.aeracode.org/2018/02/02/channels-20/"&gt;Andrew Godwin&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="python3"/></entry><entry><title>Channels 2.0</title><link href="https://simonwillison.net/2018/Feb/2/channels-2/#atom-tag" rel="alternate"/><published>2018-02-02T18:19:54+00:00</published><updated>2018-02-02T18:19:54+00:00</updated><id>https://simonwillison.net/2018/Feb/2/channels-2/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.aeracode.org/2018/02/02/channels-20/"&gt;Channels 2.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew just shipped Channels 2.0—a major rewrite and redesign of the Channels project he started back in 2014. Channels brings async to Django, providing a logical, standardized way of supporting things like WebSockets and asynchronous execution on top of a Django application. Previously it required you to run a separate Twisted server and redis/RabbitMQ queue, but thanks to Python 3 async everything can now be deployed as a single process. And the new ASGI spec means its turtles all the way down! Everything from URL routing to view functions to middleware can be composed together using the same ASGI interface.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="django"/><category term="python"/><category term="python3"/><category term="websockets"/></entry><entry><title>The First Few Weeks - ep.io</title><link href="https://simonwillison.net/2011/Jan/13/epio/#atom-tag" rel="alternate"/><published>2011-01-13T04:25:00+00:00</published><updated>2011-01-13T04:25:00+00:00</updated><id>https://simonwillison.net/2011/Jan/13/epio/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.ep.io/blog/first-few-weeks/"&gt;The First Few Weeks - ep.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Another take on managed Python Django/WSGI hosting, from Andrew Godwin and Ben Firshman.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ben-firshman"&gt;ben-firshman&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hosting"&gt;hosting&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/wsgi"&gt;wsgi&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="ben-firshman"/><category term="django"/><category term="hosting"/><category term="python"/><category term="wsgi"/><category term="recovered"/></entry><entry><title>On Django And Migrations</title><link href="https://simonwillison.net/2010/Jun/2/migrations/#atom-tag" rel="alternate"/><published>2010-06-02T16:27:00+00:00</published><updated>2010-06-02T16:27:00+00:00</updated><id>https://simonwillison.net/2010/Jun/2/migrations/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/2010/6/2/django-and-migrations/"&gt;On Django And Migrations&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
South author Andrew Godwin on the plans for migrations in Django. His excellent South migration library will be split in to two parts—one handling database abstraction, dependency resolution and history tracking and the other providing autodetection and the South user interface. The former will go in to Django proper, encouraging other migration libraries to share the same core abstractions.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/migrations"&gt;migrations&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/orm"&gt;orm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/south"&gt;south&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="django"/><category term="migrations"/><category term="orm"/><category term="south"/><category term="recovered"/></entry><entry><title>Announcing Heechee</title><link href="https://simonwillison.net/2009/Sep/11/heechee/#atom-tag" rel="alternate"/><published>2009-09-11T02:16:56+00:00</published><updated>2009-09-11T02:16:56+00:00</updated><id>https://simonwillison.net/2009/Sep/11/heechee/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/2009/9/10/announcing-heechee/"&gt;Announcing Heechee&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“Heechee is a transparent mercurial-as-subversion gateway”—you can use it to allow subversion clients to check out a mercurial repository, meaning svn:externals can work against projects hosted by mercurial. It’s very young code but I’ve already seen it out-perform regular subversion for checkout speed.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/heechee"&gt;heechee&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mercurial"&gt;mercurial&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/subversion"&gt;subversion&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="heechee"/><category term="mercurial"/><category term="subversion"/></entry><entry><title>South's Design</title><link href="https://simonwillison.net/2009/May/13/south/#atom-tag" rel="alternate"/><published>2009-05-13T12:30:45+00:00</published><updated>2009-05-13T12:30:45+00:00</updated><id>https://simonwillison.net/2009/May/13/south/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/2009/5/9/souths-design/"&gt;South&amp;#x27;s Design&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin explains why South resorts to parsing your models.py file in order to construct information about for creating automatic migrations.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/models"&gt;models&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/orm"&gt;orm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/parsing"&gt;parsing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/south"&gt;south&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="django"/><category term="models"/><category term="orm"/><category term="parsing"/><category term="python"/><category term="south"/></entry><entry><title>Southerly Breezes</title><link href="https://simonwillison.net/2009/Mar/15/aeracode/#atom-tag" rel="alternate"/><published>2009-03-15T13:17:20+00:00</published><updated>2009-03-15T13:17:20+00:00</updated><id>https://simonwillison.net/2009/Mar/15/aeracode/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/2009/3/10/southerly-breezes/"&gt;Southerly Breezes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin is slowly assimilating the best ideas from other Django migration systems in to South—the latest additions include ORM Freezing from Migratory and automatic change detection. Exciting stuff.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/databases"&gt;databases&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/migrations"&gt;migrations&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/orm"&gt;orm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/south"&gt;south&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="databases"/><category term="django"/><category term="migrations"/><category term="orm"/><category term="south"/></entry><entry><title>South</title><link href="https://simonwillison.net/2008/Aug/8/aeracode/#atom-tag" rel="alternate"/><published>2008-08-08T11:42:00+00:00</published><updated>2008-08-08T11:42:00+00:00</updated><id>https://simonwillison.net/2008/Aug/8/aeracode/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://aeracode.org/projects/south/"&gt;South&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
A brand new light-weight Django migrations tool from Andrew Godwin. On first glance, this is spookily similar to the system we’ve been putting together at GCap.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gcap"&gt;gcap&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/migrations"&gt;migrations&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/south"&gt;south&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="django"/><category term="gcap"/><category term="migrations"/><category term="south"/></entry><entry><title>LastGraph 3</title><link href="https://simonwillison.net/2008/May/25/lastgraph/#atom-tag" rel="alternate"/><published>2008-05-25T14:05:20+00:00</published><updated>2008-05-25T14:05:20+00:00</updated><id>https://simonwillison.net/2008/May/25/lastgraph/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://lastgraph3.aeracode.org/"&gt;LastGraph 3&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin’s last.fm profile visualisation tool, now in its third incarnation.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastfm"&gt;lastfm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastgraph"&gt;lastgraph&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastgraph3"&gt;lastgraph3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="lastfm"/><category term="lastgraph"/><category term="lastgraph3"/></entry><entry><title>Graphication</title><link href="https://simonwillison.net/2008/Mar/30/aeracode/#atom-tag" rel="alternate"/><published>2008-03-30T19:05:36+00:00</published><updated>2008-03-30T19:05:36+00:00</updated><id>https://simonwillison.net/2008/Mar/30/aeracode/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/projects/graphication/"&gt;Graphication&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin’s Python graphing library, based on Cairo. Responsible for the very handsome graphs on The Carbon Account.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cairo"&gt;cairo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphication"&gt;graphication&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphing"&gt;graphing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/thecarbonaccount"&gt;thecarbonaccount&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="cairo"/><category term="graphication"/><category term="graphing"/><category term="python"/><category term="thecarbonaccount"/></entry><entry><title>LastGraph. Now Available.</title><link href="https://simonwillison.net/2007/Oct/15/aeracode/#atom-tag" rel="alternate"/><published>2007-10-15T22:02:03+00:00</published><updated>2007-10-15T22:02:03+00:00</updated><id>https://simonwillison.net/2007/Oct/15/aeracode/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.aeracode.org/2007/10/15/lastgraph-now-available/"&gt;LastGraph. Now Available.&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin has relaunched his LastGraph Last.fm graphing application. The new version is built on Django and S3 and uses Andrew’s Graphication graphing library based on Cairo.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cairo"&gt;cairo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphication"&gt;graphication&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphing"&gt;graphing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastfm"&gt;lastfm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastgraph"&gt;lastgraph&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/s3"&gt;s3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="cairo"/><category term="django"/><category term="graphication"/><category term="graphing"/><category term="lastfm"/><category term="lastgraph"/><category term="python"/><category term="s3"/></entry></feed>