Do you have stateless code that needs to run in the cloud?
The clear answer years ago was to create an HTTP or even GASP, a SOAP service before then.
While HTTP services are still very important, some of this code can be moved entirely away
from the framework that runs it and over to serverless programming and hosted functions.
On this episode, I meet up with Asavri Tayal to discuss serverless programming in the cloud.
This is Talk Python to Me, episode 218, recorded live at Microsoft Build on May 8, 2019.
Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the
ecosystem, and the personalities.
This is your host, Michael Kennedy.
Follow me on Twitter where I'm @mkennedy.
Keep up with the show and listen to past episodes at talkpython.fm and follow the show on Twitter
via at talkpython.
This episode is brought to you by Command Line Heroes from Red Hat and Datadog.
Please check out what they're offering during their segments.
It really helps support the show.
Asavri, welcome to Talk Python.
Hi, Michael.
Thank you.
It's super to have you here.
It's great to meet you live at Build.
So it's going to be a lot of fun to talk about serverless.
Yeah, excited to be here.
Yeah, it's cool.
So it feels like everyone I'm having on the show lately is doing this like sort of dual
life, right?
Like we're at PyCon and then now are at Microsoft Build.
Yep.
Same for you?
Same for me.
We were just in Cleveland at PyCon and it was great.
So now coming back to Seattle back home and enjoying Build.
Yeah.
Both of those are great conferences.
What was your thoughts on PyCon?
Did you enjoy it?
You had a good time there?
Yeah, this was my second PyCon ever.
Definitely a lot of fun.
I really like the sense of community that Python developers have.
It's different from all the marketing conferences we go to.
You know, Build being one of them.
So always a pleasant experience.
Always good.
Yeah.
Yeah, I would say one of the biggest differences I felt was when you walk onto the expo floor
at PyCon, it's like everybody there is kind of doing their own thing, their own separate
thing.
It's just a sampling of the community, whereas places like Build, they're great, but they're
like, it's more like, here's the team for this.
So here's the team for that, right?
It's much more sort of focused.
Great.
I like the fact that at PyCon, everybody was there to share their stories of, hey,
this is how we use Python.
This is what we build.
And maybe it's useful for you as well.
So I'm going to share my story with you.
That was definitely my favorite part of PyCon.
Yeah, that's awesome.
I had a great time there as well.
I always enjoy that conference.
So let's go ahead and get started with your story, though.
How did you get into programming in Python?
Yeah, I started web development when I was 15.
And definitely my first programming language was JavaScript.
But eventually, as I got exposed to Python, and I remember, I think my first web application
that I developed was in Django, was developing like a portal of some kind for farmers to go
up and look up various great imaging systems that was being developed by a computer vision
lab.
So anyway, that's how I started Python.
And eventually, when there was an opportunity to make Azure great for Python developers, it
just happened that I was there and I had some experience with Python and was basically asked
to take over Python for functions and app service.
Yeah, that's super cool.
Tell me more about this Django app.
Yeah, so the Django app I was building was back in college.
I was working with the University of Illinois computer vision laboratory.
And they were building a algorithm that could take as input the image of some grain and basically
identify the quality of that grain based on a machine learning model or a computer vision
model.
So I wasn't as involved with the data science part of things.
But at the end of the day, the algorithm needed to plug into a portal that the farmer could
go interact with, plug in their grain and get market value for it.
So that portal was something I built using Django.
Yeah, that sounds like a really fun first project, actually.
Yeah.
Nice.
Okay, so that was then.
And did you study computer science at University of Illinois?
Yes.
Yeah, cool.
And now you're at Microsoft working on the Azure team.
Yes.
Tell me what you do there.
Yeah, so I'm a product manager on Azure Functions.
And currently, I'm leading both the Python experience on Azure Functions and Java experience
as well.
So really, what that means is everything that needs to be built, either on the platform tooling
or the runtime, I go in and build.
So trying to understand the story of the journey of a Python developer on the Azure Functions
platform, how they come in, what their problems are.
So on a daily basis, speaking to lots and lots of customers about why they're trying to use
serverless, why they're trying to use functions, what are some problems they face today and how
we can solve them.
And really taking those requirements back to the engineering team, building POCs and prioritizing
features on the product.
Yeah, that's cool.
Did you have a lot of those conversations at PyCon?
At PyCon, yes.
Also at Build the last two days, it's great to see that the number of folks who are developing
with Python are increasing at Build every year.
Yeah, it's pretty cool.
Did you guys have like an expo stand area?
We do.
It's a pretty, there's a lot of hustle bustle around the functions stand.
It's been great to see all the interest, yeah.
Yeah, I'm sure it's a fun area to work on.
Yep, for sure.
Cool.
So before we get into the details of Azure Functions and the Python story, let's focus
on just serverless.
We had servers.
And then we had the cloud, we had kind of virtual servers, and then we have serverless.
Walk us through that.
Right.
So we almost think of serverless as the evolution of application development on the cloud.
You know, we used to have on-prem or on-premise, and then we moved on to IaaS, then we moved
on to PaaS.
And now serverless is even the next level of PaaS.
What that means is, hey, PaaS already took away your problems of having to manage physical
hardware when it comes to servers.
Now you only need to worry about what's running on that hardware.
But you still needed to worry about what OS you're using, what packages or dependencies are installed
on that OS.
patching those OS is upgrading those machines.
serverless takes away all of that because at the end of the day, what you need to do as a
developer is give us your application code, and we'll run it in the cloud for you.
Very important concept in serverless is that you also no longer need to estimate how many
app servers do you need to run your application.
So typically when you were building an app, you would have to think, hey, my app's going
to get 20,000 requests.
And so I estimate I'll need about maybe 100 servers to serve those requests coming in.
You no longer have to do that with serverless because we're going to automatically scale based
on events that your application is receiving.
Right.
You don't have to worry about memory, like your server running out of memory because it's
doing too much and things like that, right?
Exactly.
Just at the individual level, maybe.
Exactly.
And that's why when we talk about serverless, we actually also start to talk about event-driven
serverless, which is really important because if you write an application that's going to
be triggered off an event in the cloud, something like an HTTP request or an event in some source
system somewhere, could be storage, could be an eventing mechanism, we are constantly
watching for those events.
And when those events occur, we'll go ahead and spin the resources you need to run your
application.
And when more of those events happen, we go spin more resources.
So you're really never out of compute or memory in that matter.
Yeah, that's pretty cool.
So maybe some scenario like that fits in my world.
Maybe I have some videos from an online course, but they're in a raw form.
I want to get them transcoded for the right kind of streaming.
I could upload them to like a storage that could trigger an event, a serverless function, which
grabs it, runs it through a transcoder service, and then drops it back maybe like in a file
in a location and something like this.
Yeah.
Exactly.
Both.
I think in the scenario that you described, there were two important factors.
One, your scenario was event-driven.
You were going to kick it off and then process something and drop it in a queue somewhere.
And the other one that it seemed like it was a lightweight job that you maybe didn't need
to stand dedicated servers up for.
Right.
Can you do like timing?
Like, could I say run this function every hour?
Yes, absolutely.
We've got the timer trigger.
So if you go ahead and set the time that you'd like your function to run on, we can always
do that.
Cool.
So I guess maybe I would put that into like an automation category.
Like what are some of the other main scenarios?
I guess this was automation.
The other two scenarios that we talk about with Python, the first one is web scripting or APIs.
If you, for instance, had a Cosmos DB instance and you wanted to go ahead and stand up
a REST API in front of that Cosmos DB, you could do that using functions.
Okay.
So it might be like an easy way to build an API endpoint that serves up JSON or something
like that.
Exactly.
How would I, I guess, in the Python space, what technology would I use that?
Like if I were building an API and I was hosting it in MicroWisgi, I would do that with Flask
or Pyramid or API star or something like that.
Like, do I work at that level in these functions or like what's the story there?
Yeah.
So when you develop a function, you would have to pick a trigger for your function, right?
That's the event that we were talking about earlier.
In this case, as long as you tell us, hey, it's going to be an HTTP trigger, you configure
the parameters you want for that request.
Things like, are we accepting a get post request or are we authenticating against an API key
or an AED or no auth to mechanism?
As long as you give us that configuration and give us the Python script that you'd like to
run when that trigger occurs, we'd be able to run it as a function for you.
You no longer have to go in and define droughts in a Flask app.
Right.
Do I return a string?
Do I return a dictionary?
Like, what do I return?
It's up to you.
We have this concept called bindings and functions.
So you can actually return or you can bind your return value to a data source.
So for instance, if you were to say, hey, I'd like an output binding for my function app,
which was Azure Q Storage, for instance, right?
And I'd like to bind that to the return value of function.
Now, whatever you return, whether it's a string value or a byte array or a JSON string or a stream,
we'd go ahead and use that to create a message in Azure Storage Q.
Okay.
That's pretty cool.
That's the website.
And what's the third one?
The third one that we're actually seeing very often is ML inferencing.
So I've mentioned I've been talking to a lot of customers for serverless, specifically Python applications and serverless.
And really seeing two personas.
One, a lot of data scientists who are coming to us and telling us, hey, I trained a machine learning model.
Now I'd like to deploy it as a web service.
Serverless sounds like I no longer need to worry about all those things that typically I don't care about.
And I would have to go spend time on figuring out.
Right.
As a data scientist, you don't care about like configuring micro WSGI for high performance or whatever.
I'm not a data scientist, but I imagine for a data scientist,
those problems are not even fun.
You like thinking about the algorithm you want to use for training your model or the libraries you want to use.
Probably not about what packages to install or when to security patch your OS, right?
Yeah, yeah.
Serverless is a great scenario there because you give us your model, you give us your scoring script,
tell us what event to use, and we'll go ahead and provision the application for you in the cloud, right?
And then there are also second kind of category of the people or customers that we speak to who are,
saying maybe not mainstream Python developers.
They might say, hey, we work at a large enterprise and we're using Java for our mainframe application.
But our data science team gave us this thing called a model,
and we need to kind of run it in our application or use it in our application to make some predictions.
Doesn't look like I can do that with Java.
I'd like to do that with Python.
Serverless is a great way to create a microservice that you can invoke via an HTTP endpoint,
all written in Python, that you can call from your mainframe Java application if you want to do it.
That sounds pretty cool.
Do you find students using it a lot for like testing out their code or creating little projects?
That's a good one.
I still think serverless is very new to the student community.
We're trying to create more awareness in that space.
But definitely spoken to a couple of people who've taken an interest and started to use serverless more on the cognitive services side of things.
But I think we still have a long way to go there.
There's always kind of a lag between academic courses and stuff like that, right?
They don't seem to change technology super fast.
So I can imagine that.
So you're talking about Azure Functions, and obviously it supports Python, and that's great.
But just to kind of round out the story, like what other languages does it support?
Yeah, Functions supports JavaScript, TypeScript, .NET, Java, and we recently announced PowerShell as of a week ago.
That sounds pretty cool.
What does a workflow look like if I write regular functions in a Python file?
I know what that is, but I don't edit this like on Azure or AWS or wherever I'm working on with my functions.
Like what does the workflow kind of look like there?
Give me a sense.
To help you develop functions, we basically have two tooling options.
And they sort of walk you through the process of building a function.
The first one is we've got an extension with Visual Studio Code where you can go in and say,
hey, I'd like to create a project, which is a function project.
Pick a language for your project.
That would be Python.
Pick a trigger for your very first function.
It can be an HTTP trigger.
And then it'll populate a template for you that you can start modifying.
So when I say a template, it's basically a combination of two files.
One's a template Python script, which pretty much has a single function.
It's a hello world function.
Takes an HTTP request, returns hello name as the response.
Right.
So that's where you write your normal code, right?
Exactly.
You can do pretty much what you want between the beginning and end there, right?
Like long as it conforms to the shape.
Exactly.
You can do pretty much what you want.
You can also load up additional modules within that folder itself.
So you don't have to have all your Python code living in that file.
If you had dependencies or in our ML case, if you wanted to throw in a model as a dependency
in your function, you can go ahead and add all of the data within your function project.
And what about packages I'm using?
Like suppose I'm using requests or NumPy or whatever.
Right.
So we've got a requirements TXT format that we support.
You automatically get that when you generate a new function project.
Just go and type in your packages and the versions you need and we'll go ahead and install them
for you when you deploy.
Yeah, that's cool.
So basically it creates a little virtual environment for the thing.
Right.
When you're developing locally, we actually leave it up to you for how you'd like to manage
your dependencies.
As long as you're running in some environment where the Python path does have the packages you
need, we'll be able to identify the packages on that path and run.
So we leave it up to you whether using VN, FIPN, the global Python installed in your machine
definitely feels like Python developers are passionate about how they manage their virtual
environments.
For sure.
In the cloud, the only contract is that you give us a requirements TXT file and we'll use
that to install the packages.
This portion of Talk Python to Me is brought to you by Command Line Heroes.
Command Line Heroes is an original podcast from Red Hat and it's back for its third
season.
This one is all about the epic history of programming languages.
The very first episode explores the origin and evolution of Python.
Let me tell you, this show is really good.
It has a great host.
It's highly produced and edited.
Imagine if Radiolab made a tech podcast.
Yeah, it'd be like that.
Even better, this particular episode has a bunch of cool Python personalities such as Guido
van Rossum and I even make an appearance in there.
Listen and subscribe wherever you get your podcasts or just visit talkpython.fm/heroes.
That's talkpython.fm/heroes.
Do you like pre-compute that little environment or something?
So, because you don't want to obviously reinstall it per request.
Yeah.
So, it basically gets installed during deployment time.
Yeah.
When you deploy your function, we take your code, install the dependencies that it needs, package
it up as a zip package, store it in Azure storage.
And when your applications are invoked or the first call comes in, that's when we go ahead
and run that zip package on the platform.
How's it run?
Does it run like in a Docker container?
Does it run in like a VM?
How is it shared?
Like, what's that story look like?
Good question.
You shouldn't worry about it because it's serverless.
But since you asked nicely, I'll share it with you.
We do run in a container underneath the covers.
Good thing is our Python offering is actually running on Linux, which is something that's brand
new to Azure Functions.
Traditionally, we only supported Windows hosting.
Just given the kinds of scenarios Python developers are bringing in, we decided to go ahead and
host Python on Linux.
So, underneath the covers, things are running in a Docker container on Linux.
We actually go ahead and even open source that image.
It's called the Azure Functions Python image on our Docker Hub profile.
And you can use that to build your own custom container.
Or if you're just giving us code, we'll go ahead and run that code in that container for you.
That's cool.
Could I use it to like test locally?
Could I, you know, Docker pull, Docker run that image locally and play with it?
Yeah, you can absolutely do that.
If you wanted to have the container approach, the cool thing is you don't need to.
Right.
We've got something called the Azure Functions Core Tools.
It's a CLI experience.
As long as you install the Azure Functions Core Tools on your local machine and VS Code, in
fact, does that for you.
You can test your functions locally simply by hitting F5 in VS Code.
It automatically starts the function process.
In fact, it'll even identify that it's a function process and go ahead and attach the Python debugger to the functions process.
So you can start serving your function on the local host endpoint and start testing against real Azure events.
That sounds pretty cool.
I saw that it had a command line.
So you can do things like go in and say like it's the funk command, right?
So you can go and say funk new.
And then you can say, what is it?
Funk run or something like this to like.
Yep.
Funk host start.
Yeah.
Funk host start.
That's right.
That sounds funky.
Yeah.
So yeah.
So you can do that in the command line as well.
Like if you don't use Jules Chico.
That sounds pretty cool.
Absolutely.
So you can use the command line in conjunction with your favorite editor.
So if you were using PyCharm, that's what some of the users are using as well.
Yeah.
You can definitely go ahead and attach.
Yeah.
That's cool.
Like one of the things that drives me crazy about working with the cloud, any cloud, right?
Whatever is the sort of airplane scenario as I see it.
All right.
Like I'm working on this project and now I'm somewhere without internet or I'm in a hotel
with bad internet or whatever.
And it's just like, well, now you're done.
You know, it doesn't work anymore.
And so it's cool that you have this way to kind of like run it locally, like regardless
of that.
Yep.
And it's the same runtime that's running in the cloud as well.
So there's nothing different about it.
Okay.
Well, that seems pretty cool.
We talked about some of the events, right?
We talked about HTTP.
We talked about, I asked if I could do it on a timer, like a cron job equivalent, which
is pretty cool.
What are some of the other ones?
All the storage events.
So Azure Storage, QBlob, Cosmos DB events, also the eventing and messaging systems.
So Service Bus Queues, Service Bus Topics, Event Hubs, any IoT Hub messages coming to an
Event Hub, Event Grid.
And the cool thing is, as of two days ago, we also announced Kafka.
Kafka triggers are supported as well.
Going back to functions being open source, I feel like sometimes I can't say that enough.
We've got an extensibility model where we do support any trigger or binding that you want
to bring in.
An example would be somebody recently wrote a SignalR binding for Python.
And so pretty much any binding that you bring can plug into our extensibility model as well.
That's pretty cool.
Could I build a Slack one?
So anytime a certain Slack message comes in?
Yes.
I actually just built a demo for that yesterday.
Oh, really?
We should talk about that.
That's pretty awesome.
Like, what was the scenario you were like laying out there?
Yeah.
So we wanted to build a demo when a GitHub issue is filed.
I'd like to go ahead and process that issue, do some sentiment analysis on it, and go ahead
and post to our Slack channel.
So that was the simple scenario I was building.
But definitely felt like just having those bindings to these data sources or just being
able to write my Python code and not focus on anything else made things really easy for
my demo.
Of course, that's super cool.
You mentioned the IoT stuff, and that seems like a really interesting angle, right?
People create these little IoT devices, and they've got to be sitting back like tons of data in
some cases.
So I can just somehow subscribe to that in particular and not necessarily have to write an HTTP endpoint.
What was the story there?
Right.
So the IoT events are generally routed through IoT Hub to Event Hub.
So as long as these events are coming into Event Hub, we've got an Event Hub triggered.
So every time a message is received on Event Hub, we'll go ahead and trigger or invoke your
function script and pass it the message coming from or the data coming from your IoT device
for the function to process.
So that actually makes a very popular scenario for serverless as well, because IoT scenarios are
generally burst nature.
So you'll suddenly get 1,000 events that you need to process and spin up functions for,
and then it might just go down to zero.
So really, it doesn't probably make sense for you to be paying for VMs that are running 24
hours to serve that one-time burst activity.
Yeah, sure.
Well, you talk about paying and pricing, right?
Like, if I go and spin up a virtual machine, Linode, or somewhere like that, I know that
it's $5 or $10 a month flat, right?
Like, there's no surprises.
If I leave it on, it's $10, let's say.
What's the story with functions?
I feel like of so many of the cloud resources, it's not always sure, but with functions, it's
like really not clear all the time, like what is this going to cost?
Right.
There's a lot of factors, right?
Not just how many times it's called, but how much work did each function do, things like
this.
How do I know, like, what this might cost?
Or is there a free tier, things like that?
Yeah.
With functions, we actually support a few different hosting plans, and the price is typically tied
to what hosting plan you pick.
So the first and the most popular one is the serverless, or the truly serverless, or what
we call the consumption plan.
What that means is that when a function execution occurs, there's a flat rate for that function
execution, and you only get charged for the compute that you use GB per second to run that
function, right?
So your actual compute consumption determines the cost.
And of course, any other resources that you might be using during that consumption, memory,
et cetera.
That's the truly serverless plan.
On that, I believe we give you, and I do need to go back and double check this once, but
I know we give you a million executions free to get started.
I forget the other thing that we also give you free with the memory.
I should go back, double check that.
The other hosting plan that we have is called an app service plan.
And this is different from what a lot of the other serverless vendors actually provide, because
we had a bunch of customers who told us, hey, I love the functions programming model,
but you know, I already have the set of VMs that I'm using to run a web application.
Maybe can I just use the extra compute available to me on those VMs to run my function as well,
and scale within those set of VMs.
And so that's what we call the app service plan.
Hey, it's not truly serverless, but if you already have a set of N VMs, tell us about those VMs and what plan they're running on,
call the app service plan, and we'll go ahead and run the function on that for you.
It's not serverless scaling.
It's CPU-based scaling.
So it's scaling based on CPU metrics, how much CPU is being used or how much memory is being used.
But it's kind of a determined set.
It does give you advantages like now you can put your functions within a VNet.
So there's networking options.
You can connect to data in a VNet, you know, those kind of capabilities.
So we more or less had these two groups of people, the serverless plan people, really happy about their true serverless event-based scaling.
They just don't have to think about it.
It does its magic.
Exactly.
It's the cloud.
And then we had the folks who were super happy with the app service plan because the performance is great because things are already provisioned for you and all the networking capabilities.
So in the last few months, we actually went and did some work to enable a third hosting plan, which we're very, very excited about, actually.
It's called the Elastic Premium Plan.
And in the Elastic Premium Plan, what you can essentially do is you can tell us how many reserved VMs you want for your application.
So if you're going to have a third one, which is the first time, which is the first time you want for your application.
So if you're going to have a third of the application, you can tell us how many of the applications are going for your application.
I always want to have my application warm and running on that one instance.
But if I receive traffic that's more than that instance can handle, I'd like to scale out to meet that demand and scale back down to one when the demand's gone.
Which is cool because now you get the benefits of really good performance because reserved instance, networking options because you already have something that's provisioned there, and the serverless scale.
Yeah, that sounds pretty cool.
Like most of the time, probably just one VM may do it.
And one of the things that I think that I'm always a little suspicious of in the serverless world is there's how long your code takes to run,
and then how long it takes end to end for the request to come in, for the temporary Docker image to spin up and get created, and all that kind of stuff.
And it seems to me like you might be able to avoid a lot of it in this scenario you're talking about here.
If you have your own VM that's dedicated to it.
In fact, what you explained right now, we're already optimizing for that.
So, you know, the whole point of us running in a Docker container, which we are certain what container it is, is the fact that it's already warm and running.
Even when a first call comes to your application, we're actually running a dummy Python site.
And when we invoke your application, we go ahead and specialize that site with your code and with your application settings in order to invoke your code.
A lot of that's already been done.
So we're optimizing for performance even on the serverless plan.
That said, though, even that doing that job takes a little bit of time because, again, it is serverless.
We're not provisioning anything for you.
So when you do specialize something, it takes a little bit of time.
If you absolutely had a workload that could not function on that kind of latency either, premium plan is a great option.
Interesting.
There's a lot of talk about Docker and Docker images and stuff in here.
And it's really cool.
And that obviously gives you like a decent level of isolation in your environment and stuff like that.
But would I be able to like create my own Docker container?
Say instead of taking the one that we talked about that we could get Docker pull and mess with, could I base a custom image on that and like get it exactly the way I want?
And then run that?
Yeah, you can absolutely do that.
So like I said, our Docker image is open source.
You could go ahead and extend that image to add whatever requirements you want to add.
And the typical reasons why we see somebody would do that is if you had dependencies that weren't essentially pip installable, but something that was an OS level dependency.
Maybe you wanted to install the PyTorch package via apt-get on your container, right?
In that case, custom container is a great scenario.
The other one is if you were using a distribution of Python that we didn't support out of the box, something like the Anaconda distribution.
Again, go ahead and customize the container with the Anaconda distribution and you can still use functions with it.
Okay, then I put like blob storage and point to it in my container or my function concentrate.
How do I do it?
You can simply push your Docker image to either Docker Hub or ACR and we also support private repositories.
But as long as you bring us the image itself, we'd be able to use that to create a function app.
This is mixing a lot of these cloud and networking ideas together, right?
Right, and that's why the only caveat I will mention though with custom containers is we will not be offering the consumption or the serverless plan with custom containers.
We are sticking to the premium plan and the app service plan to optimize for performance benefits.
Sure.
So we talked a little bit about being able to run with that func host start command, run locally our code.
But, you know, if you're going to do like a production release of your code, you probably want to have continuous integration, maybe continuous deployment.
Like how do I test this stuff?
Can I test it in like some kind of CI system or something like that?
We integrate with Azure DevOps.
Azure DevOps is basically a CI CD tool.
Specifically, Azure Pipelines is the CI CD component of DevOps.
And it provides you with multiple client touch points.
You can go to this portal where you'd say, hey, I'd like to set up a DevOps pipeline or a CI CD pipeline for my function app.
We're already populating functions and Python templates in there.
So it'll be able to generate the structure of the various steps that you need to take in order to do CD.
And you can go ahead and integrate your own CI in there as well.
We've also got the command line experience, which is starting from if you've already developed a function app,
you can go ahead and run the az function app devops create command.
It's documented in the functions documentation.
But that'll automatically identify the app that you're using is a Python app.
It contains requirements txt, which are certain packages.
And go ahead and generate what's called an Azure Pipelines YAML file that contains exactly the script that needs to run for your CD step.
Okay.
And then how do I test it?
Can I test it with like pytest or like what is the story?
You can definitely write unit tests against pytest.
For each of the triggers and bindings that we integrate with, we're including in the library mock interfaces.
Right.
Okay.
So if I want to have like say a CosmoDB or like a blob storage one, I guess that would be hard to test.
Like it would be hard to simulate something going into blob storage, right?
Exactly.
So in that case, you'd use that mock rich type that we're providing to create an object that you can test against in a CI CD kind of setting.
If you were to be testing locally, however, we do let you run against real time Azure events.
So if I started a function that's going to be triggered by a message being added to queue, when I'm running it locally on my local host endpoint, I can go to Azure, add a message to queue, and it will trigger off the function.
Yeah, that sounds like a pretty cool way.
So that's more of a development side of things.
It's more like the inner loop, outer loop story.
Okay.
Right.
So we think of like, hey, when you're developing locally, just trying to get your function to work in the way you want it to.
Inner loop is great.
You develop with a CLI.
You test against real time Azure events.
Now, when you think you're ready with your function app and you'd like to move to the cloud, that's when you go ahead and initiate the CI CD or DevOps create command.
Okay.
I'm happy with it.
I want to put it out there.
How do I do that without?
Let's suppose I have a function.
It's getting 100 requests per second, right?
Even if it only takes, you know, half a second to deploy this thing, that could be a problem.
Is there a way to roll it out so that it kind of upgrades without breaking inbound requests?
We've got this feature called deployment slots.
Okay.
And essentially what that means is, hey, you can have different kind of canary environments that you're publishing your application to.
For instance, I could have an app that's running in a production slot and 100% of my traffic is coming to that slot.
Now I've got an updated version of that app, a V2 version, say.
I'll go ahead and create a separate slot, which is, you know, my canary slot, say, and publish my application to that slot.
And I can start navigating some of my traffic, the incoming traffic to that slot so that, you know, maybe 80% of my traffic is coming to production, 20% is going to canary, and so on and so forth.
I start to navigate the traffic until I feel very comfortable that my staging slot or my canary slot is doing what I expected to do and bring my number of requests on the production slot down to zero before I swap.
Yeah, that's actually cooler than I expected.
I figured, like, there might be some kind of, like, Kubernetes sort of upgrade story type of thing.
But the ability to, like, send, like, 1% of your traffic at it and just go, well, let's just make sure that this is going to hang together.
Yep.
Yeah, that's pretty cool.
This portion of Talk Python to me was brought to you by Datadog.
Get insights into your Python applications and infrastructures with Datadog's fully integrated platform.
Debug and optimize your code by tracing requests across web servers, databases, and services in your environment.
Then correlate and pivot between distributed request traces, metrics, and logs to troubleshoot issues without switching tools or contexts.
Get started today with a 14-day trial, and Datadog will send you a free t-shirt.
Visit talkpython.fm/Datadog for more details.
So, Bill, there's always a lot of announcements from folks at Microsoft.
Like, this is one of the conferences that you hold back all of your big news for, right, until you, like, let it out here.
So, I guess, you know, maybe give us a rundown on, like, what's the big news for you in the serverless and Python?
Yeah, it's interesting because we've actually been releasing pretty exciting announcements over the last month, month and a half almost.
So, the Elastic Premium plan that I spoke about went out about a month ago.
And that's the biggest thing, even at Build, we're talking about it, and a lot of people already knew.
So, I would say that's the biggest announcement of it all.
The second one that's also super exciting is support for Kubernetes.
So, Functions was already open source, the runtime and the programming model and the framework itself.
But there was still a component of the platform that was still novel to what Azure was doing.
That was called the Scale Controller.
And just to give you a little rundown, Scale Controller is the component that's responsible for event-based scaling.
So, for instance, if your function was triggering off messages in a queue, are Scale Controllers always watching that queue?
How many messages are on that queue?
What's the size of each message?
How long is it taking to process?
And depending on that, actually scaling your infrastructure.
Now, we actually went in and rewrote that Scale Controller in Golang and made it open source.
So, you can now deploy your functions containers or function apps to Kubernetes and also take advantage of the event-based scaling.
It's a project we're calling KEDA.
And it's an attempt to really open source a lot of what we're doing in functions and try to reduce the vendor lock-in that may still be remaining.
For instance, I mentioned earlier in the podcast, we added support for the Kafka trigger.
That was motivated by the KEDA project.
We're also looking at adding support for things like RabbitMQ as triggers.
That sounds super cool because, you know, to me, I feel like the cloud is the new lock-in, right?
For both good and bad, like, you know, not just Azure, but AWS and the other ones.
Like, the more you take advantage of these really cool features, the more you are kind of committed, right?
But it sounds like with this, as long as you're willing to run a Kubernetes cluster, you can kind of bring it wherever you want it to go.
Exactly. And it's more for the audience, I'd say, who are already bought into Kubernetes.
You know, you don't have to do that if you really, truly are serverless.
Just leave the infrastructure to us and let us do what we do best.
But if you're a big enterprise and everything you have is going to be running on Kubernetes and you want functions to be a part of that,
it's a great way to still be able to take advantage of the event-driven serverless functions.
Okay, so I already have a Kubernetes cluster.
Can I just take this and, like, run it on the cluster as one of the things and then start calling the endpoints there?
Exactly.
Where's the rest of the infrastructure?
Like, where are the HTTP endpoints that tie it back to the functions and, you know, stuff like that?
Is that enough to just sort of have my own little private serverless thing in some cluster or what?
Yeah, absolutely. I'd actually, without going too much in detail on KEDA, I would encourage you to look at the documentation.
It's got some great references on how things are actually working in the Kubernetes space.
There's a lot going on in terms of your cluster, your pods.
I'm still learning about Kubernetes, to be honest.
There is great documentation online.
I'd encourage you to go look up KEDA, KEDA project.
Okay, cool. What else?
We introduced this concept called extension bundles.
It's a little underneath the cover, so you don't really need to know about it.
But really, historically, what happened was because our core runtimes were in .NET.
There's a lot of .NET that kind of flew out or snuck up on you when you were developing Python.
And really, we don't want that for our Python developers.
You know, we want, if you're a Python developer, let us come and plug into your ecosystem rather than trying to drive you to .NET.
Extension bundles abstracts away a lot of that stuff.
So if you're using an extension or a binding that's written in .NET, you no longer have to have the .NET SDK installed.
All you need is Python if you're developing in Python.
And we'll take care of all of that for you.
You're kind of what you would expect, but I guess it's nice that it's there, right?
It's an evolution of the platform.
I think from functions we want to where you could only develop on Windows and host on Windows to v2, where you can now develop on any platform, be it macOS, Windows, Linux machine, and host on Linux, to finally being able to abstract the few fritters that were still left.
I'm really excited and looking forward to a place that we're at right now.
I think we're getting pretty close.
Yeah, that's cool.
So speaking of environments, what versions of Python are supported?
Today we support 3.6, Python 3.6.
We're looking to add 3.7 support in the future as well.
We've already got a container image available if that's of interest.
And I guess if you can do your own container, then put whatever else you want out there, right?
Exactly.
Our core runtime is actually already compatible with 3.6 and 3.7.
We heard feedback from specifically some of the ML users that there were packages like TensorFlow that weren't yet compatible with 3.7 or were still working on the wheels for 3.7 and such.
So we just decided to delay that by a few months before we go ahead and make a big release.
Sure.
Okay, cool.
One of the things that I saw people doing on AWS Lambda is using sort of abstracting away the deployment of something like Flask, right?
So there's a project called Zappa, and Zappa will let you take what looks like a Flask function and turn it into a bunch of serverless functions, which is an interesting idea.
I don't know.
I saw that in the docs you guys have something kind of like that, but it's much more manual than working directly with Flask.
Do you have any plans for something like that?
Not yet.
And honestly, we're still thinking about it.
We don't know if that's a direction that most users want to go in.
Just speaking to customers, and we've got a very good community of preview users.
They've given a lot of feedback.
This hasn't come out that much.
So really, I'd encourage you and everybody who's listening to give us feedback on that.
Tell us if that scenario is something that's important for you, and help us just understand how we should think about these things.
Yeah, honestly, I look at that, and it's super interesting, and it's kind of cool to think about it.
But in practice, I'm like, do I really want to maintain my web app as like 100 separate little things?
Or does it make more sense to maybe build like 10 specialized serverless bits and then host the rest of it as like a regular web app or something?
I don't know.
It's an interesting idea, though.
Right, right.
Yeah, yeah.
Cool.
Well, I guess that's probably about it.
Anything else you want to share about the service that you guys got going on right now?
We've got a few things in motion.
I would say the biggest one, definitely Python is something that is our biggest focus right now for the Azure Functions team.
So just keep your eyes and ears open for what we have coming next in terms of improvements for the preview itself and our geo offering.
That's really my biggest call to action here.
Yeah, cool.
One of the things I thought was really nice is I went to the Azure serverless functions bit for Python and said to subscribe to our announcements.
Just go watch the GitHub repository.
That's a pretty cool way to like, instead of like, yeah, we're going to shoot you a newsletter or something.
No, just it'll be in GitHub.
Subscribe to it.
Yeah, we definitely spend a lot of time and lives on GitHub these days.
Open source is great.
Anytime we want to speak to the community, we pretty much post an announcement.
Even something like, I'm not sure if you've heard of durable functions in Python.
We're thinking about, hey, it doesn't make sense to have durable functions for Python.
Do Python users have scenarios that they need durable for?
Something I posted the announcement about a GitHub issue about, and there was a ton of interest.
So it's a great way to just go watch our repository, see what we're doing every day, the questions we're asking, and participate in the discussion.
Yeah, that's cool.
What do you mean by durable functions?
Like functions, if they fail, they'll like restart, kind of like a transaction, or what is this?
No, actually.
So going back to a little bit of principles of serverless per se, serverless functions are typically supposed to be short-lived and stateless, right?
Okay.
But what we heard was there can be scenarios that are long-running because maybe you're running some kind of an orchestration.
Maybe you're doing a function, like a map-reduced scenario, a fan-in, fan-out scenario, right?
I see.
And that can be a problem because a lot of the server infrastructure, serverless infrastructure will stop your function if it takes too long, right?
Exactly.
In fact, on our infrastructure, on our platform, it's a 10-minute default timeout, but you can tweak it to be a 20-minute at the max.
The new Elastic Premium plan actually can run forever.
That's a premium benefit of the Premium plan.
But with durable functions, what we do is we are basically providing a framework for you to be able to orchestrate your function executions.
There are two concepts in durable.
There is something called an orchestrator function, which can run forever.
And orchestrator function basically calls into what are called activity functions, which are basically just regular functions and have the 20-minute timeout.
So if I were doing a scenario like function chaining, I could have my orchestrator function kind of coordinate calling function A, taking the response from function A, and using it to invoke B.
Similarly, B to C, and so on.
Simple function chaining scenario or something where I was actually doing a fan-in, fan-out would be more complicated.
I could orchestrate various functions with the long-running orchestrator function.
Or even the other day, somebody built a scenario which required an OTP pin, for instance.
Human interaction with a function, which we humans take time sometimes to respond.
Yeah, for sure.
So those kind of scenarios are possible with durable functions.
It kind of solves the problem of being able to maintain state and run for a longer duration.
Does it like serialize a state while it's waiting and like bring it back?
It basically does.
Somebody on Twitter today just posted about the black magic of durable.
So it's a little bit complex and I can go into the details.
But yes, it's basically using storage to maintain state.
Okay, cool.
That's exciting.
That's a cool idea.
Yeah.
All right.
Well, thanks for sharing all these ideas.
There's just a couple of questions I'll ask you before I'll let you go.
One is if you're going to write some Python code, what editor do you use?
Yeah, so good question because I was traditionally using PyCharm and recently, when I say recently,
since about the last year or so, starting using VS Code.
And I'm really appreciating right now the VS Code ability to be able to work with Azure
because I work a lot with the Azure cloud.
The extensions do a great job at it.
Yeah, that's cool.
There's definitely a lot of integration there.
Do you have plugins for PyCharm as well?
I was using a few plugins for PyCharm.
I honestly don't even remember what plugins there were right now.
Yeah, sure.
It's been a while.
All right.
And then a notable PyPI package that maybe you ran across.
You're like, oh, that's cool.
People should know about this.
So yesterday, I ran into something called Flask Dance.
Flask Dance.
And really, what it helps you do is a lot of the OAuth dance that you would do manually,
typically, I mentioned the Slack application to you, right?
A lot of the OAuth dance that you would do typically yourself, it makes it really, really easy to be able to do that.
And I was super thankful for that package yesterday when I had to do this in a short time.
Yeah, that's awesome.
Because OAuth can be kind of annoying.
You do this, and then it calls back this function, and then it gets to be...
And of course, every API provider does it differently.
Yeah, of course.
And yeah, that's no fun.
So awesome.
Flask Dance.
That's cool.
I hadn't heard about that one.
All right.
Final call to action.
People are excited about serverless.
What should they do?
I think you should go check out Azure Functions.
We've got some great getting started material.
Like I said, if you're a CLI person, go ahead, download a CLI tool, start developing.
Or you can also use VS Code.
We are all eyes and ears right now for any feedback that you can give us.
And given that we're out there in the open, all of our discussions, ideas, feature requests,
you really have a great chance to influence the Azure product, I'd encourage you to come
participate and talk to us.
Yeah.
All right.
Cool.
Well, thank you so much for being on the show and sharing all of what you're up to here.
Yeah.
Thank you so much for having me.
Yeah.
Bye.
This has been another episode of Talk Python to Me.
Our guest on this episode was Asavri Tayal, and it's been brought to you by Command Line Heroes
and Datadog.
Command Line Heroes is a podcast telling the story of developers.
This season is all about programming languages and starts off with Python, of course.
Subscribe at talkpython.fm/heroes.
Datadog gives you visibility into the whole system running your code.
Visit talkpython.fm/datadog and see what you've been missing.
Don't even throw in a free t-shirt for doing the tutorial.
Want to level up your Python?
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.
Or if you're looking for something more advanced, check out our new async course that digs into
all the different types of async programming you can do in Python.
And of course, if you're interested in more than one of these, be sure to check out our
Everything Bundle.
It's like a subscription that never expires.
Be sure to subscribe to the show.
Open your favorite podcatcher and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play,
and the direct RSS feed at /rss on talkpython.fm.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
We'll see you next time.