Summary
As we rely more on small, distributed processes for building our applications, being able to take advantage of asynchronous I/O is increasingly important for performance. This week Alex Grönholm explains how the Asphalt Framework was created to make it easier to build these network oriented software stacks and the technical challenges that he faced in the process.
Preface
- Hello and welcome to Podcast.__init__, the podcast about Python and the people who make it great.
- I would like to thank everyone who supports us on Patreon. Your contributions help to make the show sustainable.
- When you’re ready to launch your next project you’ll need somewhere to deploy it. Check out Linode at podastinit.com/linode and get a $20 credit to try out their fast and reliable Linux virtual servers for running your awesome app. And now you can deliver your work to your users even faster with the newly upgraded 200 GBit network in all of their datacenters.
- If you’re tired of cobbling together your deployment pipeline then it’s time to try out GoCD, the open source continuous delivery platform built by the people at ThoughtWorks who wrote the book about it. With GoCD you get complete visibility into the life-cycle of your software from one location. To download it now go to podcatinit.com/gocd. Professional support and enterprise plugins are available for added piece of mind.
- Visit the site to subscribe to the show, sign up for the newsletter, and read the show notes. And if you have any questions, comments, or suggestions I would love to hear them. You can reach me on Twitter at @Podcast__init__ or email hosts@podcastinit.com)
- To help other people find the show please leave a review on iTunes, or Google Play Music, tell your friends and co-workers, and share it on social media.
- Your host as usual is Tobias Macey and today I’m interviewing Alex Grönholm about the Asphalt Framework, a Python microframework for network oriented applications
Interview
- Introductions
- How did you get introduced to Python?
- What is Asphalt and what was your reason for building it?
- How does Asphalt compare to Twisted?
- What are the most challenging parts of writing asynchronous and event-based applications and how does Asphalt help simplify that process?
- When building an Asphalt application it can be easy to accidentally block an async loop by pulling in third party libraries that don’t support asynchronous execution. What are some of the techniques for identifying and resolving blocking portions of your application?
- What does the internal architecture of Asphalt look like and how has that evolved from when you first started working on it?
- What have been some of the most difficult aspects of building and evolving Asphalt?
- What are some of the most interesting or unexpected uses of Asphalt that you have seen?
- What are some of the new features or improvements that you have planned for the future of Asphalt?
Keep In Touch
- Gitter
- IRC
- GitHub
- agronholm on GitHub
- @agronholm on Twitter
Picks
- Tobias
- Alex
Links
- Asphalt
- ERP
- Asyncio
- Tornado
- Twisted
- SQLAlchemy
- PEP 550
- Sanic
- WAMP
- Podcast.init Interview About Crossbar
- Tee
- FlexGet
- APScheduler
- BitTorrent
- uvloop
- Tokio
The intro and outro music is from Requiem for a Fish The Freak Fandango Orchestra / CC BY-SA
Hello, and welcome to podcast dot in it, the podcast about Python and the people who make it great. I would like to thank everyone who supports the show on Patreon. Your contributions help to make the show sustainable. When you're ready to launch your next project, you'll need somewhere to deploy it, so you should check out linode@podcastinit.com/linode and get a $20 credit to try out their fast and reliable Linux virtual servers for running your app. And now you can deliver your work to your users even faster with the newly upgraded 200 gigabit network in all of their data centers. If you're tired of cobbling together your deployment pipeline, then it's time to try out GoCD, the open source continuous delivery platform built by the people at Thoughtworks who wrote the book about it. With GoCD, you get complete visibility into the life cycle of your software from 1 location. To download it now, go to podcastinit.com/gocd. Professional support and enterprise plug ins are available for added peace of mind. You can visit the site at podcastinnit.com to subscribe to the show, sign up for the newsletter, and read the show notes. And if you have any questions, comments, or suggestions, I would love to hear them. You can reach me on Twitter at podcastinit or email me at host@podcastinit.com.
To help other people find the show, please leave a review on Itunes or Google Play Music. Tell your friends and coworkers and share it on social media. Your host as usual is Tobias Macy. And today, I'm interviewing Alex Gronholm about the Asphalt framework, a Python micro framework for network oriented applications. So, Alex, could you please introduce yourself?
[00:01:32] Unknown:
Hi, everyone. My name is Alex Grouhon. I'm a software engineer. I've been running code for almost my whole life now, I guess. I've been working, professionally as a software developer, since 2005. My first job was writing PHP code, actually. That lasted 6 months, during which time I developed a very passionate hate for PHP. After that, I moved on to Java, that enterprise Java. I wrote an enterprise resource planning software during the next 2 years. Java was a lot better than PHP, obviously, but, I found it a bit clumsy and cumbersome and verbose.
So when I finally found Python, it was pretty liberating.
[00:02:27] Unknown:
And do you remember how you first came across Python?
[00:02:30] Unknown:
Yeah. Many years before I actually started with Python, I had heard about it, and I had heard that it has the it had the kind of grammar where, voice space was significant, and I found it intriguing. But it took many years, before I actually started using it. And, when I picked it up, I found it really easy. Like, the easiest programming language I have ever learned. In less than 2 hours, I had already, made my first practical application. So, I found it really impressive that, that a language could be learned so easily.
[00:03:09] Unknown:
And you ended up using Python for building the project we're talking about today, which is the Asphalt framework. So I'm wondering if you can just, discuss briefly what Asphalt is and what your reason was for building it. Yeah.
[00:03:24] Unknown:
The thing is, when I was building this enterprise resource planning software, I ended up using tools other than HTTP for communication. And, I found that there are no application frameworks at all for running non web apps. So I would have had to use something like Twisted or Tornado. Actually, I ended up using Tornado for it. But, really, you can't you you just can't find a generic extension components like, you know, Twizydd is a low level networking framework. It's not really an application framework per se. So that bugged me, it bugged me that there's no such thing available in contrast to enterprise Java, where you do have such such a thing. I ended up trying to build that framework.
I wanted to build a framework that that will serve everyone's needs, not just the web developers needs. So you could, you could use the same extension components, for any kind of application, starting from command line tools to really complex multi protocol applications. So you could do whatever you want without having to switch tools, and, that was my goal.
[00:04:46] Unknown:
And you mentioned that the sort of main differentiator between Asphalt and Twisted is the fact that Twisted is so low level, whereas Asphalt gives you a lot of higher level primitives for being able to compose an application.
[00:04:59] Unknown:
Yeah. Yeah. So App, Asphalt is an application framework where whereas Twisted is a networking framework really. I think the only common thing between these 2 is that they both have an application runner, which reads configuration and then starts an application, but really, asphalt was meant for building components from which you compose applications.
[00:05:26] Unknown:
And 1 of the really appealing things about Asphalt is the fact that it is purely asynchronous throughout the entire stack and looks like it takes advantage of the new async IO capabilities in the Python 3 runtime. Mhmm. So just curious if you can explain your reasoning for, that heavy focus on the asynchronous capabilities and what that gains you for the particular type of, applications that you're looking to build with Asphalt.
[00:05:55] Unknown:
I really meant Asphalt to be the 1 framework to end them all. So, the reason I picked asyncio was, well, first, because asyncio is part of the standard library. I needed some kind of a networking stack underneath it. So, the choices were either using Twisted or Tornado or some else, some other async framework for it, or I could have gone to the threaded route and do like a Flask or pyramid or Cheng or you name it. But, the thing is, sometimes you do need a sync. For example, when you have tens of thousands of concurrent con connections, and, the thing is if you, if asphalt was based on blocking code threads, it would be pretty difficult to add this, async capability into it. So I figured, the best base, would be asyncio because, well, as I said, it's in a standard library. And, there are pretty good facilities for running blocking code from within the event loop, but, you can't really do it the other way around. It's, pretty difficult. So that's why, I chose asyncio.
[00:07:14] Unknown:
And what are some of the most challenging parts of writing asynchronous code and event based applications and particularly making the entire stack asynchronous? And how does Asphalt help with, enabling people to be able to write those kinds of applications?
[00:07:30] Unknown:
Yeah. The fact is that, multitasking is difficult no matter how you put it. If you're using threads, there are some advantages and disadvantages, and the same applies to cooperating multitasking like with Daisy. There are always pros and cons to everything there, but, it's difficult no matter what you do. So asphalt has a few things that will make life easier for writing code for in the async or training manner. For example, if you need to access the libraries that, that work in blocking mode, use, file IO or blocking networking code, then, asphalt has a few methods, that you can use to easily easily run code in worker threads. And, likewise, it has functions that enable you to call on the event loop from worker threads.
So sometimes, I write my applications in a way that I run most most of the functions in worker threads, but then sometimes I end up having to call some coroutine or or some code that really needs to run on the async event loop, then, I have this thing called call async, which, so pretty much suspends the worker set until until the function call is done on the event loop. The asyncio library doesn't really offer something like this, out of the box. It has something like run coroutine thread safe, but you have to know that the code is a coroutine. Call async runs whatever code even even if it's a plain function or a core team function, it doesn't care. It will run whatever async code you want in the in the event loop.
[00:09:27] Unknown:
And when you're pulling in 3rd party libraries to use in your application, it's all too easy to pull in some libraries that don't work properly with async capabilities. So what are some of the techniques for being able to identify some of those blocking portions of the code and resolve them by either wrapping them in an explicit thread or making them async compatible?
[00:09:51] Unknown:
Yeah. Identifying them is the easy part. Usually the libraries that are written for asyncio, they quite prominently displayed. So you will see, in the documentation and examples where they use async and await, so that part is not hard. When you encounter library like, say, SQL Alchemy or ExchangeLib, then usually you have to find which, which functions will block and which ones don't. That's pretty much the hard part. So when you know that, this function call will cause, file IO or blocking network IO then, there are several techniques you can use to wrap that code to call to that code. 1 is the call in executor call that asphalt offers. You just pretty much do, the wait call in executor and you give the function and these arguments as arguments to that function, and you await on the result. Another technique that I'm actually pretty proud of, is the async with thread pool approach.
So what this does is that you have a coroutine function, and inside this coroutine function, you have an async with block inside which you put the blocking code. So when the execution enters this block, it adjourns the task, the async task that is running, and it switches to using a worker thread until the block is done, at which points, the execution resumes on the function in the event loop. It's something I've never seen before anywhere else, and, it makes writing, mixing blocking code and async code much more natural. And, asphalt has some some sub, some component projects that wrap these services in easier ways, for the consumer to use.
[00:12:04] Unknown:
So what is the internal architecture of asphalt look like, and how is that design evolved from when you first started working on it? There are a few basic building blocks in Asphalt. I think because you start with components.
[00:12:17] Unknown:
Components are something that, they are classes which are used for adding resources. Basically, when an asphalt application starts, it, is always starts from a root component, and, this root component can then start other components and so forth. Components pretty much, they launch services and they, they add resources to to a context. And, these resources are typically services like, say a mailer service or database connection or anything. A resource can literally be any object of any type. So when these resources are added to the context, then, other components can, request these resources.
So you can build a component that depends on services provided by other components. You can build a pretty large hierarchy of these complex services built on simpler services this way. And you can also build independent side hierarchies of components this way and combine them. For this reason, context can be stacked so that you can have multiple levels of context. As a child context can access resources from this parent context but not vice versa. This is for the purpose of isolating the, like, small smaller independent parts so that they don't interfere with with each other. Yeah. That's pretty much the core. Yeah. But you ask other questions too, like, how does that how does that evolve during my development?
In the earlier stages, the code was of course in quite a flux, so the problem was that nobody had really tried to do this in the Python space, so I didn't know what was the right approach. So asphalt has had a number of breaking changes in this history mostly related to the context and especially context teardown because 1 part I neglected early on was the teardown process. When the application shuts down, it needs to shut down the services as well, in an orderly manner, and, I think it was 3.0 where I actually managed to fix that. And also also, 1 issue that I haven't fully resolved yet is the startup processes, where there is a time out, but some services may require additional time to connect to the network services and so on. So it's difficult to know when, the launching of a component has actually stalled or if it needs more time.
[00:15:16] Unknown:
And 1 of the things that you mentioned in there was the ability to maintain context for a particular async task. And 1 of the PEPs that's currently being discussed is PEP 550 for context local variables that will be somewhat akin to the thread local variables that frameworks like Flask and Django, make such heavy use of. So I'm just curious how much that is going to simplify or benefit the work that you've been doing with Asphalt as far as that particular,
[00:15:46] Unknown:
problem. Yeah. I've been following that development with interest. The thing is, if I were to adopt this approach, I would have to introduce breaking change to asphalt. But, yeah, I have run into situations where, that would have been beneficial. Like, when you have SQLAlchemy listeners, then injecting the current context is, quite cumbersome. I've done it, but it's difficult. And, if you are using a library that requires similar things and you don't have the benefit of ready made component project for it, then it's going to be quite difficult without the context local variable or techno, I mean, task local variables.
Also, there's this issue of threads because asphalt relies quite heavily on worker threads to access those, blocking libraries. So I'm not sure I can't really recall, how this PIP works with threads, but, of course, the thread would need to know which task it's tied to, and that presents additional problems. Also, there's this thing in the Python send about explicit being better than implicit. So there are really really like the way asphalt works currently passing the context object around. And sometimes sometimes it may be cumbersome, but it really is explicit and it, I think it helps with testing. It makes, things, so much more explicit really and easier to reason about, at least in my opinion.
But, yeah, it's something I may consider adopting in the in the future.
[00:17:36] Unknown:
And going back to the component based nature of Asphalt, there are pretty impressive number of integrations that you've built up for it in the GitHub organization. And I noticed that there are a couple of them that you've got in there as placeholders such as the Asphalt Bridge for being able to bridge between asphalt instances. So I'm just curious if you can give, high level of some of the ones that you're most proud of or find most useful and some of the ones that you would like to be able to,
[00:18:08] Unknown:
start work on or have some additional help with? Yeah. I would totally love to have a a lot of help with this project because I just don't have time for all of them. Yeah. About asphalt bridge, it's, that's my most ambitious component project for asphalt. The idea behind asphalt bridge was that, you could actually bridge to asphalt instances so that you could have 1 instance running on another machine requesting resources from another asphalt instance. So you could have you could scale horizontally, and you could have a network of services.
You you wouldn't have to care where the services have actually been published. You you could just network your asphalt things and test request resources as usual and not care where they are provided. And, they would use some form of RPC for communication. Obviously, you can't you can't do this with all kinds of resources, like, for example, database connections might not be a good fit for this, but things like a mailer service would. So if you do like a have a mailer service abstraction, you would have an application that would request a mailer and another machine would provide the mailer service, you could have it use either SMTP, maybe on any server and then then you could just switch it to SendGrid implementation and the component that dependent on this mailer would not know the difference.
There's just a mailer that works and it doesn't care how it works. And so the other project that I would really love to complete is, well, there's this thing called as file schedule scheduler. It's really, really high on my priority list. I just haven't had, any time for it lately. Are you familiar with AP scheduler?
[00:20:14] Unknown:
I am. Yes. I, was actually looking at your, GitHub profile while I was preparing for the show and noticed that you were the author of that. And I actually made fairly heavy use of that in 1 of my early Python projects. So thank you very much for for that as well. It's quite a useful project. Yeah. No. You're welcome. So, Asphalt Scheduler is pretty much,
[00:20:35] Unknown:
a redesign of AP Scheduler as a native service for asphalt. It reuses much of its code, but of course, it's vastly improved. Asphalt scheduler let me let me do a lot of nice things. I have this almost finished project called, asphalt feed reader, which is a library for reading RSS and Atom feeds, and it also has back end which lets you lets you fetch any arbitrary pages and produce artists like events from them. And that's really neat, but it needs some kind of scheduling component to it. And initially, I set out to duplicate some of AP scheduler functionality for it, but then I realized that I really need to do this in its own schedule library because it would be duplication of effort.
So that's just 1 thing where I would need scheduling. I think, the GitHub project, where that call was supposed to go is named asphalt tasks. It's named that way because I initially intended to combine a scheduler with a task queue, like with Celery. But, I found out that the scope of this project was too broad. So I figured my that my next best step would be to just take the scheduler part and implement that as its own library to get going with that because most of my tasks, as I found out, are really simple, core team based stuff. Actually, you you can use as well scheduler for that, but and AP scheduler, but it's core team support is not the greatest, and I mean it does work with coroutines, but it was pretty much added as an afterthought, and it doesn't integrate very well with, with asphalt because asphalt has this asynchronous signal is event system, which was pretty much copied from the qt library, and, it doesn't, apscheduler has its own event system, and I really didn't want to mix these 2 systems together. So that's 1 reason why I wanted to make, asphalt scheduler as its whole thing rather than integrating ap scheduler.
Also, the thing I'll be working on this weekend is asphalt web. The funny thing is, that although I'll be using asphalt in production for a year, asphalt in production. Yeah. Anyway, asphalt web, provides web application support for asphalt. The reason why I haven't been, talking about the asphalt, in public so much is that, asphalt doesn't really cater to web developers, and that's something I wanted to fix first before I really start marketing it. So I needed the web framework that would truly integrate with asphalt. For example, asphalt has these serialization and templating components, and I wanted the web component to integrate with those 2. And while I've been experimenting with creating rest services on top of sonic with some glue code to make work with asphalt, they don't really integrate that well.
So that's why I'm working on Asphaltweb as its own standalone project instead of integrating say SONIC into Asphalt.
[00:24:23] Unknown:
And what have been some of the most difficult aspects of building and growing the Asphalt framework and its capabilities?
[00:24:30] Unknown:
I would have to say that it's because, Asphalt breaks a new ground breaks new ground, in a lot of ways, so I have had very little feedback from people because, as I found people don't really have anything to say, they don't they go on like, I don't know how this how any of this works, so I can't say anything about it. So it's it's been pretty hard to get a reasonable feedback for the things I've done with asphalt because there are not really no frameworks like this in in the Python space, and I think that's that's the most difficult part because you you do a design and then you can't know for sure if it's, if it's correct and what problems, will I be facing later on. So that's given me a lot of headache.
[00:25:24] Unknown:
And, what are some of the most interesting or unexpected uses or, projects with asphalt that you have seen or done?
[00:25:35] Unknown:
I haven't heard that much back from people using asphalt. I know there are people who use it, but, they don't really talk to me that much about it. So I can tell you some things I've done with asphalt myself. For example, I have this work project where I use asphalt for IoT gateways, and what they do is they read stuff from the serial port, they do some processing on it, and then they use, WAMP, short for web application message protocol, a web socket sub protocol. They use a WAMP to publish messages on the 1 router, where then another application also asphalt based picks up these messages and saves them to the database.
And they are also published to web based clients, which see the events in real time. So I think that, qualifies as interesting.
[00:26:37] Unknown:
Yeah. The Womp protocol is definitely something that that I found interesting as well, and I actually had, Tobias Oberstein on the show a little while ago to talk about his work with Crossbar and developing that protocol. So I was amused and interested to see the, fact that you had incorporate that you had built a component for Asphalt to be able to take advantage of that protocol as well. So it's definitely cool to hear about it being used in real world use cases and integrated with asphalt for being able to provide, sort of a real time, equivalent to the UNIX t for a data stream.
[00:27:10] Unknown:
Yeah. I haven't run across anything comparable to 1. I think that most, most users of, WebSockets, do this. They implement the RPC or PubSub, on their own, which is actually what I did first before I learned about WAMP. As I as I mentioned before, I had this enterprise resource planning software, that I made, and I also based a later version of it on WebSockets, and I had implemented a custom RPC protocol and PubSub system. But it was a lot of work and I really didn't want to maintain something like that. So I I asked myself, hasn't anybody done the same? And then I started looking and I found 1. So I was pretty glad to find something that was already done. Something like a standard on which I could build. So I fully embrace 1 for all the projects that I do.
[00:28:09] Unknown:
And what are some of the, new features or improvements that you have planned for the future of asphalt or some, components that you would like to see people, build and contribute to the project?
[00:28:22] Unknown:
Oh, where to begin? Some of these I mentioned already. The the schedule part is really important for me. I actually, needed a schedule in all of my work projects, and I have something suboptimal implemented in each 1 of them. And I really love to have a working fully featured scheduler in all of them. And obviously, having a web component is really important for the future of Asphalt. Also, as I mentioned, Celery, I think Asphalt needs integration or a native component that's, lets you queue tasks because a lot of these tasks that need to be, that application need to run are CPU intensive and doing that in threads is suboptimal.
So, yeah, definitely something like that I would like to have. Also, BitTorrent support would be great because, have you heard of this, protocol Flexgit?
[00:29:21] Unknown:
I think I may have heard reference to it briefly, but I'm not terribly familiar with it if you'd like to explain.
[00:29:27] Unknown:
Yeah. Flexkit is, like a downloader framework. It can pull websites for new things. Think of like downloading new episodes or movies or whatever. It can pull websites and then automatically start downloads for the things you care about. It's really really cool, and I figured that a good proof of concept for asphalt would be to have all the components necessary for that and, then build the flex kit like application for asphalt.
[00:30:02] Unknown:
And 1 question that I forgot to ask earlier is, what was your what's the story behind the name that you chose for the project?
[00:30:12] Unknown:
Yeah. The thing is, there's a slogan for asphalt paving the way to the future. So I thought that asphalt was a metaphor for having a framework that's let lets you focus on the application in the instead of the integrations and whatnot. So you could just slap components together and focus on the business logic. So it's like a like a difference between riding driving a bumpy road and then a smooth, road made with asphalt, if you understand the meaning.
[00:30:49] Unknown:
Yeah. No. Definitely. It's, I assumed that it was something along those lines, so it's good to hear sort of the reasoning behind it. And are there any other aspects of the project or, anything related to it that you think we should talk about before we start to close out the show?
[00:31:04] Unknown:
I think we covered the most important parts list. I can't think of anything else.
[00:31:10] Unknown:
And, 1 other thing that I thought that we should probably mention is that as I noticed in the documentation, because of the fact that asphalt is built on top of asyncio, it is compatible with the UV UV loop engine for being able to get some pretty impressive performance out of the actual runtime.
[00:31:26] Unknown:
Yeah. Hopefully. In fact, as for support some more than just UV loop, it supports aiog event and, the new Rust based Tokyo event loop. I haven't actually used anything else than the basic, asyncio event loop and UV loop, but, I think support for Tokyo and the AIL g event was trivial, so there you have it, feel free to experiment.
[00:31:50] Unknown:
And for anybody who wants to get in touch with you or follow the work that you're doing, I'll have you add your preferred contact information to the show notes. And with that, I'll move us into the picks. And my pick for this week is going to be the movie Thor Ragnarok. I just went and saw that last night in the theaters, and I thoroughly enjoyed it. It's a good story with a lot of humor throughout, so it's just a really enjoyable film. So for anybody who's into any of the Marvel movies or, that particular genre, it's well worth the watch. And with that, I'll pass it to you. Do you have any picks for us this week, Alex?
[00:32:24] Unknown:
Yeah. Actually, recent favorite of mine would be music from, the 2 steps from hell band, which is actually a Norwegian duo, who have moved to the United States. They make the kind kind of music they make. It's really the kind of music they make. It's really really epic and always inspiring.
[00:32:53] Unknown:
Yeah. Definitely have to check that out. That sounds interesting. There's a lot of really great groups that have come out of the, Norway and Scandinavia region, so let's take a look at that. Mhmm. Alright. Well, I really appreciate you taking the time today to talk to me about the work that you've been doing with asphalt. It's a really interesting project and 1 that I hope to see succeed in the long run. Seems like it's going to simplify a lot of the work that people are going to be doing, going into the future, particularly as they start embracing more of the async capabilities. So, thank you again for your time and I hope you enjoy the rest of your day. Thank you very much for having me and,
[00:33:30] Unknown:
as a last note, I know that async IO can be difficult to grasp. I don't blame anybody for, telling that it's difficult to start with, but I really hope that people can overcome this obstacle and really start embracing async code because when you get it, it's really rewarding in my opinion. So, I really welcome anybody who wants to try asphalt. I have many many channels to which you can get help. Gitter will be the best option, and there's also IRC, and of course, the issue tracker on GitHub. So, just drop by and ask anything you like, and thank you.
Introduction to the Guest and Topic
Alex's Journey to Python
Overview of the Asphalt Framework
Asynchronous Capabilities in Asphalt
Challenges of Writing Asynchronous Code
Internal Architecture of Asphalt
Asphalt Integrations and Future Plans
Difficulties and Interesting Uses of Asphalt
Future Features and Components for Asphalt
Origin of the Asphalt Name and Closing Remarks