Modern typed python: dive into a mature ecosystem from web dev to machine learning

The talk will focus on modern python and its extensive usage of type hints and static type analysis. There will be a special focus on DocArray and multi-modal AI applications.

The talk will cover different topics around modern python:

  • The history of Python and type hint. How Python came from being not static typed language to having static-type analysis?
  • The state of the modern python ecosystem in 2023:
    • Powerful development tools like mypy and beartype. Parallel with TypeScript
    • Powerful libraries that leverage type hint: Pydantic, FastAPI, SQLModel, Typer, DocArray
  • Deep dive on DocArray and the future of AI-based web app:
    • Why modern python is a key to speeding up the development of multi-modal AI applications (stable diffusion, neural search …)?
    • What is DocArray and how does it extend pydantic with multi-modal AI in mind?

This session took place in track Python Language and was classified suitable for intermediate domain / intermediate python by the speaker.

Transcript (auto)

Auto-generated from the recording utilizing Open-Source AI. Speaker labels (Speaker 1, Speaker 2) reflect diarization, not identity. Timestamps refer to the recording.

Speaker 1 [00:03]

Thanks everybody, I'm really happy to be here. So today I'm going to talk about modern type Python, and let's see what we're going to see today. So I will first start to introduce the history of Python and type, and we will see that this is kind of a weird story, and then we will dive into this typed Python ecosystem that my title is talking about, and at the end we're going to look at a library named docker which is the type using this type ecosystem applied to machine learning, and spoiler alert, one of the maintainer of this Docker library. So let's jump directly into the main topic, and is Python a type programming language? Maybe in the audience, can you raise your hand if you think it's true or a false statement? Okay, there is one person who thinks it's a type programming language. Well, it is a type programming language in the sense that you have type in Python, like you can check the type of an object, but precisely it's a duct type programming language. Let me explain what duct typing mean. So this, on the left, you have an example of a Python function is doing, adding to object, and on the right, it's the same function written in Rust, which is a static type programming language like C++ or Java, and one thing which is quite obvious between those two is in the duck typing language, in the duck typing, so Python, you just have your variable and you do your operation, whereas in the static typing, you have to add some stuff here, and this is the type of the variable. You're saying that here you write this function and you expect that x and y are u size, so it's like numbers, and you say the return numbers. And in Python you don't have to do such a thing. It's like, so this is a difference between duck typing and static typing, and the idea is in duck typing you can pass kind of any object to a function, and whereas in static typing you have like a, well a fixed static signature that you have to respect, otherwise the program is not going to work. Let me explain a little bit more what is exactly duck typing. The idea behind duck typing why is it called duck? It's like this philosophy behind Python is if it walks like a duck and talks like a duck, then it's a duck. It basically means that in Python an object doesn't really care if inside the function it's from the type that it's supposed to be. You just want it to behave like the object it's expecting. So it basically means that you can pass all object to Python as long as they follow some characteristics then it will work in the program. And it's really an opposite from a static type language where we actually need to pass the correct object otherwise it will just not accept the function. Even though maybe you only use a subset of the feature of this object it will still complain. This is kind of the idea of duct typing. This is how Python behaves basically. He's like, okay, you all can understand this photo, but we try to plug an electric cable into a pig's hole. And it looks weird, but technically it will work in the sense that you will be able to plug it. And that's how Python is working. He's like, he don't care if it's actually an electric plug. He just cares that it has two holes. And then it will see when he tries to plug, if something fails, something doesn't work, it will just, you know, explode, kind of. Whereas, if you were in C++ or in Rust here, it will basically say, no, you cannot plug this. Even though in Python, well, you can plug it. You will just see what happens when it happens. Duck typing is one of the reasons of Python's success. It's really a lot of pro-argument for duck typing. It's simple and fast to write. So, basically, you don't have to put any types of information in your variable. It means that you have less character to type, And you can write code which is almost look like pseudo code which is super elegant, let's say. You don't need to think too much about abstraction. You don't need each time that you create a function and you want it to work on several objects to create an abstract class which is going to encapsulate all of the abstract behavior so that just your function can be written. You can just pass several different objects to the same function and you will see what's going to happen. And again, not too verbose. It's really an important part of the typing. But it has some cons as well. it's kind of hard to maintain because, well if you don't exactly know what go into your functions and each time you do a modification, you don't know, like maybe you use this function with an object and you add a new functionality inside your code, it's not going to work with another part of your code because you expect a behavior which is not available on this object and you don't have a way to know what's supposed to go into this function, what's supposed to go into which kind of object it is. So it's sometimes hard to maintain. And one of the other problem is error will be catch at run time rather than complete time. It means that, let's come back to this example, that let's say you know this will not work when you're going to plug these things or expect electricity to come, and it will not work if you put it in a big hole, in a big noise, sorry. And this, with Python, you will catch it at run time. It basically means that your program will be running and you will try to do these things and it will fail. Whether or not with a static type language, like you will see before in a compile time or like it will just not be valid code in term of writing it. And you will have an error way before this happen and you know you will basically be able to catch those kind of small mistakes that you can do. So if Python is a duck type language, so it basically means you don't have to precise a type inside your function. Why is this modern Python in 2023 full of type and type hint, type information? Let's take a look. This is a code example from a fast API, which is a really known web framework, and I mean you can see, I hope you can see, where is my mouse, for example, so this is like from the readme of fast API, and you can see here, you have some string information, float information, you create a function, you say union of the string and none, and this looks like a static type language, like you have some int information in the signature of the function, and it's It's kind of weird because I was just saying that Python in this duck type language is one of the main things that make it popular is that you don't have to do this kind of thing. So let's try to understand what happened and how come this is like a kind of, in 2020 this is a normal way to write Python code and using the type hint. Let's see how it happened. Before going into explaining how it happened, let me just explain to you what is the advantage of having type hint in Python. and this will explain how it came into the language. It's kind of expressive to be able to, it's really expressive to be able to say what you're functioning, expecting, and like, you have a signature, it means that it's like you have a contract with the people who are going to use your library or your functions, like, I'm expecting this, and this will work if you give me this object. It's kind of, it's easy to onboard new people on your code base when it's full of type hints because, well, they know, they look at the function and they can reason easily. They know what's going to go into the function. One of the most important, at least according to me, functionality of type hint is like IDE, like PyCharm or VS Code or Vim. They really love type hint. For them, it allows them to do a lot of shortcut for you. It's like they can do, if inside a function they know what kind of object is expected, they can show you the method of this object that is available. And if they don't know it, they have no way to suggest you some method, right? And that's why ID really love type int. It makes refactoring easier because you can catch some small errors that you will do and you will be able to find bugs without running the code and just statically analyze that the contract between your different function is correct. Let's take a look at the history, how all of this happened. So Python released in 1991 by this guy, famous Python author. 10 years later, he's not alone anymore. He has a team, he released Python 2.0. At this time, Python is fully duck-type. You don't have any things related to type hint in the language. 2006, Python 3.0 happened to be in development, and at this time, they start to think about all of these type hint things that we see today in the language. One thing that they realize is like, At the beginning, so I saved Python in 2006 without type, no way to say that your function expecting to work on int or in this abstract class, and they realized that people actually sometimes need this information. For example, this was like, in Python, you have this doc string, and people were putting a lot of information in the doc string. So this was like, this was some code that you can see in this time. Like, people were putting type information in the comments of the variable, in the doc string of the variable. and they were using this doc string for this, and basically what it showed is people wanted to have a way to express type information into their function, even though it's a doc typing language. Then, 2006, the first PEP, Python Enhancement Proposal, so it's basically a feature that people want to add on Python, and this is like the function annotation, Which is different from type hint, but basically we move from the things that you see on the left and we go to the right It means that instead of putting those information into the doc string is now a valid Python Python it's valid Python to put this information after the variable in this way and put the rudder statement in this way and So what's happening what's going to do here is like this will be saved into the function into this annotation which is the dictionary which do the mapping between X and whatever you have here and it's just a dictionary. Function annotation both for parameter and return value are completely optional. This is not something that it's still Python at this time is still fully doc typing and it will always be you can't you don't have to do this but it's just an optional thing that if you want to add information to your function and functional annotation there are no no more than a way of associating arbitrary Python expression with various parts of a function at compile time. It's just a way to do association of your function signature and whatever you want. This means that this is actually valid Python. Here you can put a sentence after your X. You can actually put any object, not even a string. Yeah, like, this is still valid Python. So you see here, we're not still talking about typing. It's just a hint, an information that you can add next to the variable. And of course, this pep was synced to be used for type hinting. But at this time, they were really going in a safe way and just introduced little by little this feature just like, this is annotation, this is not yet type hint, because Python is known to be a duck typing language. Well, that's basically what I said, but there was officially, so at this time, officially no type hinting in Python, to be continued. So let's wait, so we have to wait eight years later, to 2014, and actually type hint are introduced in Python. Like, so what we know about Python, all of these union optional things that is introduced in this PEP 484 in 2014. And just for the history, actually all of the things that has been introduced in this PEP in 2014, that have been proposed 10 years before by the creator of Python. So all of the things, optional, union, all of these things, it has been already coined 10 years later. And just to show you how long it took to actually go into the language, because again, Python is known to be duck typing and people didn't want to do all of this typing thing in Python. The creator already had the idea, but he take a lot of time to actually make it something part of the language. And let's take a look for the people who don't know how it looks like. So you have now this typing library, which is in the standard library, which have a lot like type information, any optional, and this, yeah, and you have, so this is still using the type annotation, yeah, the annotations that we saw earlier, but now with actual type information that's really represent type. We have a lot of advanced type feature, like type var, overloading covariance, control variance, forward reference, a lot of complex things that allow to express a lot of information about the type. in a function. And since 2014, we have seen 16 PEP in six years going into the Python project that are related to TypeHint. And basically each year you have more and more and more TypeHint related feature in the Python. So let's sum up, let's sum up. So Python is not a statically typed programming language. It is a duck type one. And type hint slowly entered the Python world. As I said, it took almost 10 years before the creator of Python coined all of these typing things and 10 before it go into the language. But Python is adding type hint related feature at an exponential rate. Like if you see Python 3.12, you will see five or six pep related to type hint. Okay, so let's take a look and during this time of all of this, like the type hint I've introduced in Python code, in Python code base, and become kind of a norm to use, there are a lot of tools that have been built around this type hint ecosystem. Let me present several of them. Probably the most important one is MyPy. MyPy is a static type checker for Python, and it basically checks that your type hint makes sense. It means that if you have a function which, hey, it expects hints, like one or zero or two, and later in your code you pass a string, then it will say, be careful, you probably are doing something wrong, or otherwise you need to change the signature of your function to express that your function is always able to work on string. 10 years old project, it actually started before the first typing, type hint peps in Python, and they were using their custom type syntax, yes. Second one, birtype is kind of different, it's a runtime type checker. So it basically means that this one is going to catch kind of error at static time. It means you don't have to run your code to catch the error. This one will be catch at runtime. It means that your function, your program will stop to work if you pass a wrong type. And in some time when you want to do some critical programming and you really want it to behave like it's supposed to behave, you want to catch those small things. You want to stop early. you want to stop, you want to have an error early when this kind of thing happens. PyIdentic, it's kind of, PyIdentic, it does data validation using Python type hints. It's five year old, it's quite popular nowadays. It's kind of, at least for me, it's kind of a revolution in the way people use Python. It actually has been introduced before the data class feature, and it's kind of basically what inspired the data class features that now we have in the Python. Let's just briefly take a look at how we do, how we write code with PyIdentic. Basically, in Pydantic, you create this class, and you have the attribute name, and it's type hint. And it's kind of a struct, like a struct that you can see in C or in Rust. It's like you basically say that this object has this property, this attribute, and this is the type that it's supposed to work with. And Pydantic will do a lot of things for you so that it will always make sure that you have those type are respected and we do a lot of validation. It's basically like when you're parsing some data, you can be sure that either it's going to fail at some point or that you are going to have the correct type into your object. FastAPI, FastAPI is modern fast web framework for building API and it's based on standard Python type hint and it's based on Python text that we just saw before. It's five years old and it's super popular. Let's see how it looks like to build an API with FastAPI. So basically in FastAPI you say, I create a model, it's like basically a PyTanchic object and you say that you have created a function which is expecting this model and that's all. That's all you need to build, I mean you have to add one light decorator here, but here, but the really important part is you write just a Python function and FastAPI, if you use type hint with PyTanchic, FastAPI will come and we'll be able to kind of understand this function and say, okay, so if it expect, sorry, this object that he knows that he have an endpoint is going to, if a JSON object of this format is going to come, he's going to parse it into this Python object and give it to the function. And it's really fast to write, that's why we call it FastAPI, to write APIs that way. Because you don't have to think about the parsing, about a lot of thing, and do a lot of automating thing for you, for example, building documentation, building open API specification from you, because he read it from the Python code and can build it on the fly. Let's, like, really, FastAPI is really impressive in how it has been democratized into the Python world. So this is like the number of stars. I know stars are back proxy for a popularity of a project, but I don't have a better way to do it, so. But you can see that Flask is another popular wave framework, probably the most popular one, and you can see that in a couple of years, FastAPI has been as popular as Flask, even though at the end of the day are doing the same thing. SQL model is kind of the same idea, but this time to manage SQL database is created by the same guy. I'm going fast here because I don't have a lot of time left. A typer is the same way to create CLI, base is the same as in typing, so basically create a function, and instead of parsing manually each parameter and then calling a function, it's just like, take your function, you expect a name and an addresses, then the CLI will expose this exact same parameter. We just have to write your Python function. What about machine learning framework? Actually there is one library which is not that well known. It's called JAX typing, but it's allowed to use type information and shape information inside your array-based code. So if you're doing some deep learning or any NumPy-based coding, sometimes it's actually quite useful to express the shape of your function. So basically you say, I want to create a function which is doing matrix multiplication, And, well, we all know that there is this constraint that the last dimension of the first matrix should match the first of the second matrix. Otherwise, you cannot do the matrix multiplication. And with this library, you can express those kind of information. But it's kind of the only one in the machine learning world. So let's sum up. So Python-type ecosystem is growing, and it's growing fast. As I show you, FastAPI, it's really take over the Python web development world in, I don't know, couple of years. It's really impressive. And yeah, type-based libraries are overthrowing long-standing libraries. But the machine learning ecosystem is still missing those type-in-based libraries. And then here we are under Docker. Docker is, again, this is one of the maintainer of this project. That's why I'm talking about here today. And basically, the idea is like Like we bring this TypeHint ecosystem to the machine learning world. So we basically look at what happened with the web development ecosystem. So Pydanchic, FastAPI, SQL models are kind of a new wave of those tools for building application. And this is only based on TypeHint. Like this is our success is based on this feature. And it's great software as well, but the main things that makes them different from the other are those TypeHints. But tomorrow, well app will change drastically, because AI enters the battle. I mean, sure you all have heard of chat GPT, stable diffusion, like all of this AI, AI models that basically can only, can work on modalities that are beyond text. Like stable diffusion, for example, it's creating an image out of text, of whispers that can take your voice and put it into text, and you see here that those applications work on modalities, not only text. One month ago, GPT-4 has been introduced, it's like this LLM, but it's always, it's able to understand image, not only text, so this is kind of the next step in the applications that we're going to build. It's not only text-based, it will be video, image, all of these things will be part of the application. And if you look at Pydentic, Pydentic has some predefined types which are really useful to build applications. For example, you have that time, URL, you even have a payment card number object into Pydantic, just to show you how, but all of this is focused really on today's web app, but not on tomorrow web app, because tomorrow web app, it's not based on text and string only. You will need to be able to handle image, audio, video, 3D object. This is how the new application will be needed. And it's where, enter Docker Ray. So, Docker is a library for representing, sending, and storing multi-modal data, with a focus on machine learning and neural search. It's built on top of Pydentic, we like to call it as a Pydentic for ML, or a hint of Pydentic for machine learning. It's fully compatible with FastAPI, and it's almost one year old now, and we just did a big release one day ago, when we introduced a lot of Pydentic and type-hint related feature. We just moved to the Linux foundation, AI data, and we are around six people working on this project. So this is basically what Zooker is doing. We work on different modalities in a seamless way, let's say, and we provide some storage and computability. Let's, it's like, I coined this with a hint of ML. Let's actually take a look at how it looks like. So here we want to work with podcast data, and podcast is composed of an audio, the most important part of the podcast, but not only. Let's say you want to build a search engine for podcasts. Audio is not the only important part in the podcast. It's actually maybe the least relevant when you want to search for podcasts. For example, thumbnails, it's like the image on the podcast, is really important. The title as well and the description is super important if you want to build a sensor line with this. And here with Docker, in the same way you will do with Pydantic, you will create this document which is like a model. And you can express a lot of things related to machine learning like the shape of the tensors that you expect in your podcast, and then you can create a docvec which is basically a vector of all of this podcast which is suitable to work with machine learning, and yeah, that's kind of the feature that you can do with Pydantic. The difference with Pydantic is that it's array first, so you can create, you think in the array mode, it's like you have a vector or a list of objects rather than just one single object. Another part of DocArray is like it's an ORM for vector database, yeah, you have, we're are connected to several vector database. Let me jump, this is my last slide. So basically what we try to do with Dockery is to be the for machine learning. We have another tool called Jina, which is kind of a fast API, but all of these machine learning things and the SQL model to work with SQL data. We have something in Dockery when you work with vector database, which are like the database of the AI world. And I will stop with this. Thank you for listening to me. Thank you, Sami. I think that's very thorough, interesting talk. And we also have a very lively Q&A session. So just some quick questions for you. First, what is your position on runtime type check using type guard or their type versus static type analysis? When to use WASD? I think it looks like they're doing the same, but it's actually kind of completely different. I think static type analysis, you should actually use it if you have type int in your code base. It's like a good thing to do. Runtime checking is different. It's really depending on what you want to do. Because sometime maybe your code will still work even though you don't pass the right type. And if it's working, it's working. It's depending on if your application is really critical or not. And if you really want to be really sure that you do, like let's say you are implementing a payment system. You want to be sure that what you have as input is what you expected. So that nobody try to hack you by doing some hacky, passing another object or wrong type and it's going to, I don't know, remove all of the money on your book account or something like this. Awesome. Next question. Any thoughts on the future of Python and role of type hinting? Will duck typing be dropped in Python 4.0? I don't think Python 4.0 will ever be a thing, but I'm pretty sure that we can say that Python will always be DuckType language. I mean, it's what make Python Python, it's why it becomes so popular. So I think for me those two things, type hint and DuckTyping work together. Sometimes for example, for me, when I'm doing some Jupyter notebook code, I don't use type hint at all. I mean, I just want to write fast and to prototype. And when I want to build some serious and production-ready libraries, then I will use type hint. Even though I will be slower at the beginning, I know that it will be better for me in the future. Awesome. Next question. Any current peps on type hinting that you are excited about in the future release? Good question. What is this name? I think that introduces annotate objects in the typing library when you can basically go beyond just having to type in, but you can precise additional information. And I think FastAPI is planning on adding a lot of interesting features around this, and it's definitely one of the things I'm most excited with. Okay. We'll see in the future. Next we also have another question about how do you see the futures of typing in NumPy? In NumPy? NumPy. I think maybe it will not be directly NumPy, but this Jack typing that I show, I think it's basically be able to express shape information and array-related information in the typing. At least for me, it's very sexy. I mean, I like doing it. It's kind of a new way to write program. Even to read a code, it's easier when you can actually understand the shape. And in NumPy-based code, you usually see a lot of comments like, this array is actually of shape X, Y, Z. And it's basically what we see earlier with the dog. People were putting information in the dog string, and they wanted something in the language to do it. And I think this will come to maybe not NumPy directly, but in the ecosystem. Awesome. Thanks. I think that's all the questions we have time for today. Again, to conclude, everyone, please give a warm applause.

samsja

Social card for talk: Modern typed python: dive into a mature ecosystem from web dev to machine learning