 Thank you, Jason. So let me share my screen and we can go to the presentation. So hello, everyone. Welcome to this presentation that will be about resolving problems in Python dependencies. And my name is Fridolin. You can find me on Twitter on the Fridex handle. You can find me also under this handle on GitHub. And I'm a team member of TOTS since 2019. I like Python and I do road cycling. When it comes to Project TOTS, it started as a research project in AI Center of Excellence that is a team in the office of the CTO. And one of the main offerings we do is cloud-based Python resolver that I will talk about in this talk. If you are interested in TOTS, feel free to visit our web page, this TOTSTATION.NINJA. We have also Twitter. And you can find also our YouTube channel that is linked from TOTSTATION.NINJA homepage. So in this talk, we will have two main topics. The first one is dependency monkey. And the second one is cloud-based Python resolver with prescriptions that is a feature that the resolver offers. We will talk about a story, how dependency monkey found an issue and how the cloud-based resolver was able to resolve dependencies of a Python application without causing troubles to developers. So preventing from the found issue to be seen in Python's developers' environments. Okay, so let's start with dependency monkey. So dependency monkey is a service that is capable of evaluating different combinations of Python packages. So if you do install some package, pip under the hood resolves dependencies for your application, but dependency monkey can do it the other way. It can traverse the dependency graph based on some criteria and resolve all the possible resolutions that can be found in the dependency graph that still satisfies the version range specification of your Python applications. If you are interested in this dependency monkey, we recently released an article that is available on developers.redhead.com. And it talks more about dependency monkey, about its design and how it works and operates. If we go into this direction, then the dependency monkey really can try to find all the resolutions in the dependency graph and then submit a request to another service that is called AMoom that was also developed within project tot. So with resolved set of dependencies, dependency monkey also submits information about runtime environment where the application is supposed to be run. And so you can imagine information about container image that should be used to build the application. Optionally, RP and PQGs that should be used. The resolved set of Python dependencies that the dependency monkey found. And then also other information regarding, for example, hardware. So if your application is supposed to run on some specific CPU or GPU because of machine learning computations, dependency monkey can submit such request to AMoom and what AMoom does under the hood. AMoom builds the application with specified set of Python dependencies and the runtime environment specification that was sent to the service. Then once the build is done, AMoom executes so-called inspection that basically runs the application with supplied script and checks characteristics of the application. Then once the application run is finished, we aggregate reports and in that report one can find information such as how the application behaved during the run, what hardware was used during the application run, what dependencies were used and stuff like that. So it's a full report of build and also of application run. Then this report is stored in Tots database and it can be further inspected or people can check what went wrong or what was really good with the application and application stack that was tested on AMoom. With this scenario, we conducted a few experiments. They are recorded in a repository that lives in Tots station organization. The repository is called dependency monkey zoo where you can find inputs to dependency monkey and also information how the applications were tested. If you are interested more in this, feel free to visit the linked article on developers redhead.com which discusses more in depth about this. One of the things that we observed was issues in tensorflow stack, tensorflow is a machine learning library and its dependency graph is quite large so it was very nice thing to use to explore possibilities and also how dependency monkey work and we found out that transitive dependency of tensorflow introduced issue in which case in some specific cases when tensorflow is resolved with specific URL lip3 package, then the tensorflow does not start at all. So this just proves that it's not possible to evaluate all the possible combinations in test suits in a standard way and that's why dependency monkey is available to test the applications. So we have this issue and we know how dependency monkey works so we have these reports and now let's try to feedback this knowledge to the cloud python resolver. Python by default installs dependencies or if you are using python you can install dependencies using pip, pipand or poetry. On the other hand we have an offering that is cloud based resolver, it's publicly available to the community so you can use it and in fact it's a recommendation engine for python applications. Under the hood it's implemented as a stochastic resolver, it uses gradient free reinforcement learning techniques to come up with most suited set of dependencies that can be used on developers environments. If you are more interested again feel free to browse our documentation and when it comes to the flow, if you want to use the cloud based resolver it's a standard resolver so you provide information about requirements and also optionally information about constraints that you have on your python dependencies. Then there are also additional options that you can supply to help the resolver come up with the most suited set of dependencies for your runtime environment so you can include operating system, python interpreter version, base image that you are using but also native dependencies such as CUDA. Also information about CPU, GPU that you are running so thought resolver can really come up with the most suited set of dependencies for your application. So this is the inputs to the cloud based resolver. Once the cloud based resolver resolves software packages it provides a log file so your application has reproducible set of dependencies and also justification on why you should use these dependencies or why the cloud resolver suggests you to use these dependencies. If you want to give a trial you can do so. The client tool that interacts with the cloud based resolver is called Tamos. You can install it from PyPI and the thing that you need to do is to configure the environment so Tamos discovers how your runtime environment looks like and then ask for an advice with three requirements on dependencies that you have. The cloud based resolver uses gradient free reinforcement learning and the reason behind that is that there are possibly infinite possibilities how to resolve software packages. If you consider all the inputs to the resolver really a number of combinations how to resolve a specific set of packages that are suited for your needs that's really like a huge number. So on each request we train a model gradient free reinforcement learning is used where in the exploration phase we explore how the dependency graph looks like and how the dependencies look like and then subsequently we do exploitation phase where we find the most suitable set of dependencies for your application. The whole resolution process is modeled as a resolution pipeline that is made out of pipeline units and these pipeline units can be implemented directly in Python or the resolver has a declarative interface where you can state pipeline units in a form of YAML files and then the resolution engine automatically consumes these YAML files and guides the resolution process based on things that were declaratively stated using pipeline units. Okay so if we take a look at this concept of declaring pipeline units using YAML files one can see this similarity with OpenShift or Kubernetes. So in OpenShift you have manifest files that state a desired state of a cluster and once applied the cluster orchestrator tries to satisfy this desired state. These YAML files that are called prescriptions in AtoT state how the resolution process should look like how the desired resolution process should look like and then it's up to the reinforcement learning algorithm that is implemented in the resolver to satisfy this desired resolution of Python dependencies. So prescriptions provide this declarative interface to the resolver. If you are more interested in this concept feel free to visit developers.redhead.com where we published an article about this concept and if you are a Python developer and you spot an issue or if you maintain a Python library feel free to report issues to TOT and we can write prescriptions for the cloud-based resolver. This way we can accumulate knowledge about open-source Python libraries and make a Python ecosystem as a whole a better place to code in. Now let's take a look at example how a prescription can look like so in this case we have an example when below in some specific version in version 8.3.0 is causing issues when it is resolved together with NumPy. This issue was observed after the release and in a standard way there is no way how to fix this except for some post releases. But the cloud-based resolver offers these prescriptions that can heal Python applications and prevent from these issues from happening. So here we can see a YAML that states prescription each YAML file states pipeline units that should be registered in the resolution process. In this case we have a pipeline unit that is a step. So as mentioned earlier there are different type of pipeline units and the type of pipeline unit basically describes a set of actions that can be done by the given prescription or by the given pipeline unit and also describes when the pipeline unit is applied during the resolution process. So some pipeline units can be applied before the actual resolution process starts, some during the resolution process and some pipeline units can post process the application stack that is recommended by the recommendation ng. So in this case we have a pipeline unit that is called step and is run during the actual resolution process. So here you can see the name of the pipeline unit to even clear identify it and also type. Then we state when the pipeline unit should be included. In this case it's very simple. When users ask for advisory advisories we run this pipeline unit or include this pipeline unit in the resolution process. You can think of more complex situations when you want to include a certain set of pipeline units only for GPU-enabled environments or only for environments with some specific CUDA version and things like that. So this section provides you the ability to express when such pipeline units should be included and run in the resolution process. Then there is section which states when the pipeline unit should be triggered during the resolution process. So here we see if a package pillow in version 8.3.0 from pipi.org is about to be resolved together with NumPy. So NumPy is already resolved. Then this pipeline unit is triggered and we have the last section of the pipeline of the prescription and it states that the resolution process will disregard this step in the resolution process and will inform users that pillow in version 8.3.0 does not work with NumPy. We'll link to the specific pillow issue and the resolver, the reinforcement learning algorithm that is implemented in the resolver will try to come up with a different resolution path that satisfies version range, version specification of your requirements. So this is one way how or an example how the cloud-based resolver can heal applications and application dependencies. You can think of more complex pipeline units and prescriptions. So if you browse our repository with prescriptions you can find for example a prescription that is providing TensorFlow GPU as a pseudonym to TensorFlow if you are running a GPU enabled environment. Another prescription is suggesting specific version of TensorFlow GPU based on TensorFlow support metrics and another prescription will fix overpinning issues of TensorFlow that TensorFlow in specific version is having. So as you can see we have atomic PCs, these prescriptions in the resolution process but together they can form a very complex resolution process and can give you the right set of dependencies that you can use when running your application. So this way we help developers with overpinning issues selecting the right GPU enabled build of TensorFlow considering CUDA, CUDNN and injecting TensorFlow GPU built that is GPU enabled build of TensorFlow. Here are some more examples. So prioritizing some builds of TensorFlow or using other things. If you are more interested in TOT feel free to visit our homepage. If you are interested in Dependence Monkey or prescriptions concept feel free to feel free to visit also articles on developers.vr.com and this way I would like to thank you and if you have any questions feel free to ask them. Awesome thank you I'll give a couple seconds for people to write any questions they have in. I do want to mention because I missed it during the intro that Freedom joins us from last year as well the only returned speaker but I was really excited I think this is a really neat area that everybody ends up pumping into problems and super important that we get this kind of coverage again so thank you for coming back again.