WEBVTT

00:00.000 --> 00:09.040
Cool. Hello, I am Safond Rahman. I am actually

00:09.040 --> 00:14.280
have come from Bangladesh. My topic is actually very interesting one and it is not very

00:14.280 --> 00:19.120
like the thing that people try to do and everything. So, it is about like monkey

00:19.120 --> 00:24.560
patching. So, monkey patching is something that you change the code at the runtime. It is

00:24.560 --> 00:31.560
very bad practice, but at least sometimes you need to do that. So, use that in your own

00:31.560 --> 00:40.840
risk. So, the thing is that do not try this at home. Sorry, do not try this at production.

00:40.840 --> 00:49.840
You can try this at home, but you should not try this at production. So, have you ever used

00:49.840 --> 00:56.840
that in your code rather than test? Anyone who is that? Oh, okay, a lot of people who

00:56.840 --> 01:09.840
are with that, okay. Have you pushed monkey patch to do the reproduction? Okay, not

01:09.840 --> 01:16.840
wrong, not Raj. Okay, so, okay, sure.

01:16.840 --> 01:23.840
So, the thing is that, my topic is actually how we can actually use the monkey patching,

01:23.840 --> 01:29.840
the function, this powerful functionality more beneficial for our debugging our code and everything.

01:29.840 --> 01:34.840
Okay, because maybe you should not push this code to the production, but you can use that

01:34.840 --> 01:41.840
this code in your local machine to actually test things and also like debug your packages

01:41.840 --> 01:47.840
the thing. So, while there are bug in a package that you are using is quite difficult to actually

01:47.840 --> 01:55.840
fix that or like debug that in locally and then you can actually get a fix, right. So,

01:55.840 --> 02:00.840
this is a short example as we will all know that how to actually do the monkey patch.

02:00.840 --> 02:09.840
So, in the class, in the class dog there is a method in a bug, but if you actually see

02:10.840 --> 02:17.840
is that after we actually, we are getting the animal object in there and we are actually

02:17.840 --> 02:23.840
making the bug, we are calling the bug function is actually, is actually showing the roof

02:23.840 --> 02:28.840
in the output, okay. But after we actually monkey patch the bug function in this new bug

02:28.840 --> 02:36.840
with this new bug is actually returning the meow, okay. So, this is how we can actually

02:36.840 --> 02:43.840
monkey patch a class directly in python code, okay. This one is actually important one

02:43.840 --> 02:52.840
because like you can make you can monkey patch a class very easily, but it is quite difficult,

02:52.840 --> 02:58.840
what not quite difficult is quite tricky to actually patch a instance or like a object in python,

02:59.840 --> 03:05.840
okay. So, like if you want to, if you need some parameter or anything from your

03:05.840 --> 03:13.840
base class in your function in your class method, what you need to do is that you need to

03:13.840 --> 03:19.840
use the method type, okay. So, if you need to use the method type in that case that as

03:19.840 --> 03:26.840
you see that I actually have patched the gate name function in here with this function

03:27.840 --> 03:32.840
and after we actually use the method type, we could actually, we could actually

03:32.840 --> 03:37.840
access the self-value from the, from the monkey patch function as well, okay.

03:37.840 --> 03:44.840
So, the output will be, the first output will be type, okay, because this is the type,

03:44.840 --> 03:51.840
but in the after monkey patching it will be my name is type, okay, because the monkey patch

03:51.840 --> 03:58.840
function is actually getting the value from the, from the after main class main object,

03:58.840 --> 04:04.840
okay. So, this is the main part, okay. So, how we can actually use the monkey patch to

04:04.840 --> 04:09.840
which we debug, okay, you know, look at me, okay, because maybe we should not push this

04:09.840 --> 04:14.840
code in the production, but we can actually use the monkey patch function to debug our third

04:15.840 --> 04:20.840
package, that we are actually using and maybe that third-party package has bug in there,

04:20.840 --> 04:26.840
okay. So, think about a like a third-party package, it is about like the kelp module,

04:26.840 --> 04:32.840
okay, it has a like, it has a function, this name is kelp, kelp, let's sum, okay.

04:32.840 --> 04:36.840
But it seems like the kelp or sum actually has a bug in there, because other than

04:36.840 --> 04:41.840
calculating the sum, it is actually abstracting that, okay. So, if you actually face this kind

04:41.840 --> 04:45.840
of issue, what would actually you do, okay, in this third-party package, either you can

04:45.840 --> 04:50.840
fork that, you can install that package, vendorize that, anything, but it is quite difficult

04:50.840 --> 04:56.840
to do that. So, in order to debug that, what you can actually do is that you can, you can

04:56.840 --> 05:02.840
import this function as the wrong kelp has a different name, and then you can actually

05:02.840 --> 05:08.840
write another function, okay, like a pairs kelp or sum. So, in the pairs kelp or sum, you

05:08.840 --> 05:12.840
can actually add a break point in there. So, you can understand that what's parameter you

05:12.840 --> 05:17.840
actually getting on in this function, and then you can return the wrong calculation sum

05:17.840 --> 05:22.840
method in there, okay. So, after that, we are actually monkey-watching in there, like we

05:22.840 --> 05:27.840
are term monkey-watching the kelp module, kelp module dot kelp sum, kelp for we actually

05:27.840 --> 05:36.840
monkey-watching the kelp sum in there with our pairs, pairs function in there. So, when

05:36.840 --> 05:40.840
when we are actually importing, this is the very important thing, you should always

05:40.840 --> 05:45.840
monkey-watch before you actually import the actual method, okay. So, if you actually

05:45.840 --> 05:50.840
patch after importing the method or function, you cannot actually monkey-watch that,

05:50.840 --> 05:56.840
write this way, okay. So, if you actually import the kelp module, kelp sum from the kelp

05:56.840 --> 06:01.840
module, and you actually call that function, but you will, you will see that you will

06:01.840 --> 06:05.840
actually get a PDB, okay, you will actually get a debug interface in there. So, in that

06:06.840 --> 06:11.840
debug interface, you can get all the variable and everything, and so that you can actually

06:11.840 --> 06:16.840
debug it more precisely that what is actually happening in there.

06:16.840 --> 06:22.840
This is the second example. So, actually debug that, okay, there the third

06:22.840 --> 06:28.840
party library has a bug. So, how can you fix that in your local machine? So, you can actually

06:29.840 --> 06:35.840
test that, this is the main course, okay. So, what you can do is that, you can, with

06:35.840 --> 06:40.840
the same way, you can just other than adding the debug, like a debugger, you can

06:40.840 --> 06:48.840
actually kind of fix the method in there, and you can actually paste, you can actually

06:48.840 --> 06:54.840
paste that, okay. So, after patching that, if you actually import that, import the function

06:54.840 --> 07:00.840
that module, you will actually get the actual result. So, at the first, I am actually

07:00.840 --> 07:07.840
getting the 70, because the function has a bug, but after we actually paste that and fix

07:07.840 --> 07:13.840
that, I can actually, I am actually getting 130, because this should be 130, okay.

07:13.840 --> 07:19.840
So, this is the interesting one, another one, interesting one is that, sometimes you need to

07:19.840 --> 07:24.840
know that while debugging that, from where this third party function is being called,

07:24.840 --> 07:28.840
okay. So, you have a like, thousands of sounds of flying in a scope, you have like

07:28.840 --> 07:33.840
a lot of packages, like 100 of packages, you need to know from which packages and from

07:33.840 --> 07:39.840
where this function is being called, okay. So, what you can do is that, you can actually

07:39.840 --> 07:46.840
use the Python-in-spec module, okay, in there, this building module in there. So, if you

07:46.840 --> 07:52.840
actually paste that, paste the function, like previously, and you can actually, if you

07:52.840 --> 07:59.840
actually use that, instant module and get the stack, you can understand that, which function

07:59.840 --> 08:04.840
is actually calling that, okay, and from which line is this actually calling, okay.

08:04.840 --> 08:10.840
So, in that way, you will actually get it very easily, that from where this function is

08:10.840 --> 08:15.840
being called, so you can both there and fix that, okay, rather than finding air and

08:15.840 --> 08:25.840
there and everywhere, okay. So, this is the thing that is about the debugging, okay.

08:25.840 --> 08:33.840
So, after debugging, we actually have like a hot fix, okay. So, the thing is that, as I actually

08:33.840 --> 08:40.840
say earlier, that, you should never do this in production, okay, unless you do, you know

08:40.840 --> 08:49.840
what you are doing, okay. So, so, but as you are engineer, we need to handle the production

08:49.840 --> 08:53.840
issue, hot fix, there is the name everything, like there are some downtime in there, and

08:53.840 --> 08:59.840
you need to fix something, you need to make something very emergency in this case, okay.

08:59.840 --> 09:05.840
So, there is the fastest way to do that is actual monkey patching, okay. If actually,

09:05.840 --> 09:12.840
using third-party package, there is some bug, and you want to fix that, and you want

09:12.840 --> 09:19.840
to fix that and make a like a hot fix in there. So, it is very, it is a best way to do

09:19.840 --> 09:26.840
is actual monkey patching. In the later, after the service went, goes up, you can actually,

09:26.840 --> 09:32.840
you can actually change the monkey patching to the actual fix in the library and make a

09:33.840 --> 09:38.840
pull request or use your own version in there, and maybe find some other solution in there.

09:38.840 --> 09:44.840
But, for emergency things, maybe you can actually push some monkey patch code in the production,

09:44.840 --> 09:51.840
okay. So, let me show you some pod example in there.

09:51.840 --> 10:14.840
Can you see this? Yeah, is it okay? Okay. So, this is the one example about the hot

10:14.840 --> 10:24.840
fix, okay. So, this is one example of the hot fix, okay. So, thinking about the situation

10:24.840 --> 10:31.840
like you actually have, I have upgraded the package, okay. So, you have added the package in

10:31.840 --> 10:37.840
your, in the old package, you actually, there are other, you were calling a function, okay.

10:37.840 --> 10:43.840
So, in the function, the one of the parameter was actually not required, okay. So, it was

10:43.840 --> 10:56.840
only divided default none or something like that, okay. But, but in the, in the new module, in the

10:56.840 --> 11:04.840
upgraded one, the function, the AG is actually required, like the variable is actually required

11:04.840 --> 11:10.840
in there, okay. So, what you can actually do is that actually already have upgraded the package,

11:10.840 --> 11:15.840
which the code in the production and the service went down because this is actually asking

11:15.840 --> 11:25.840
about the required argument in there, okay. So, let us see the example.

11:25.840 --> 11:48.840
Let us see, let us try hot fix, okay. If we run the hot fix that one pi, it will actually

11:48.840 --> 11:53.840
give this kind of error, okay. And this kind of error is actually very common in production

11:53.840 --> 11:58.840
system and everything, okay. In the, if you have to upgrade a package and you actually required

11:58.840 --> 12:03.840
a required argument, this kind of error actually very popular in there, okay. So, what you can actually

12:03.840 --> 12:11.840
do is that you can actually monkey pass it out and fix that as well, okay. So, you can actually,

12:11.840 --> 12:17.840
you can actually write a function, okay. In the, in the function, you actually actually

12:17.840 --> 12:24.840
import the module and after you actually import the module, you need to get the old function

12:24.840 --> 12:30.840
old function in the variable, okay. If the every function and everything is object in Python,

12:30.840 --> 12:34.840
you can actually, you keep that in a function in there, okay. Then you can actually write

12:34.840 --> 12:39.840
your own function that actually takes only two argument, the first name and last name, okay.

12:39.840 --> 12:46.840
And then you can pass the AG as none to this old function, okay. And you can actually monkey pass

12:46.840 --> 12:53.840
this new module with gate person, with your own gate person function. So, it will only

12:53.840 --> 12:59.840
take two argument in there, two keyword argument, not three. So, and you need to monkey

12:59.840 --> 13:06.840
pass it before importing, okay. So, after you actually import the function and make the object

13:06.840 --> 13:15.840
in there, this will actually work. You see, this one actually worked, but the previous

13:16.840 --> 13:21.840
one didn't work. The same module and everything, but only as we are actually doing the monkey

13:21.840 --> 13:26.840
patching thing in here, this one actually worked. And this is the simple fix. We, you will need

13:26.840 --> 13:31.840
five minutes, particularly fix that, rather than like downloading the package, fixing that,

13:31.840 --> 13:40.840
making a full request or maybe, downloading the detail of everything, okay.

13:40.840 --> 13:50.840
So, this is another example in here, okay. So, this is another example. So, after you actually

13:50.840 --> 13:59.840
upgrade the package, sometimes, sometimes, there are like, sometimes, there are like new,

13:59.840 --> 14:07.840
there are, there are new fix ways, that's in, that's in, that's in, that's in the package,

14:07.840 --> 14:12.840
that's in the low level package, but not in the high level package in there. You have

14:12.840 --> 14:17.840
not upgraded the high level package. You have upgraded the low level package in there, okay.

14:17.840 --> 14:23.840
So, in that case, what we are actually going to do, because you need the low level package

14:23.840 --> 14:28.840
for other things, but you also need, you cannot actually upgrade the high level package in there.

14:28.840 --> 14:34.840
Okay. So, you can actually monkey pass this low level package, so that the high level package

14:34.840 --> 14:42.840
actually calls that, this, this will actually, this will not result in a row, okay.

14:42.840 --> 14:53.840
So, if you see this, this low level package, okay. So, in the person, okay, we have a

14:53.840 --> 14:58.840
like function name, get upper full name, okay, and get upper full name actually calls the

14:58.840 --> 15:05.840
self-fast name, upper and self-fast name, upper, okay. But in our code, maybe there are some

15:05.840 --> 15:13.840
H cases and maybe in the database, we have null values, that, because of the, because of

15:13.840 --> 15:18.840
that reason, maybe the null value is actually coming for first name and last name, okay.

15:18.840 --> 15:25.840
So, this may actually give some error in there.

15:25.840 --> 15:40.840
You see, so this is the very common during the production, that non-type object has no

15:40.840 --> 15:45.840
attribute upper or something like that, okay. So, because you are actually passing the non-type,

15:45.840 --> 15:50.840
it cannot actually make it upper and give you the actual level. So, what you can actually

15:50.840 --> 15:57.840
do is that, you can actually also monkey page this, you can also monkey page this, like

15:57.840 --> 16:03.840
you can actually, this get function, like get person function, okay. In the, in the get person

16:03.840 --> 16:08.840
function, you can actually see that if it first name is non, you can actually return a like

16:08.840 --> 16:14.840
blank value, if the last name is non, you can also return a blank value, okay, rather than

16:14.840 --> 16:21.840
non, okay. So, in that case, this will also also fix your production issues.

16:21.840 --> 16:32.840
You see, so we are actually passing only the first name, as we are passing only the first

16:32.840 --> 16:39.840
name, it will actually only work, okay. So, the best way to do this kind of fixes is actually,

16:40.840 --> 16:45.840
it is not a best way, okay. But in the monkey page, this is the best way, okay. So, what

16:45.840 --> 16:51.840
you can actually do is that, you can actually create a new class in it in this main class,

16:51.840 --> 16:56.840
okay. So, in the main class, in the inherited class, you can actually fix this issue, okay.

16:56.840 --> 17:01.840
It is the first name is non, you can actually make it blank, it is the last name is non,

17:01.840 --> 17:06.840
you can actually make it blank, okay. And then you can actually do that, and you can actually

17:06.840 --> 17:15.840
just, in the module, okay, from where this class is imported, you need to patch at that module,

17:15.840 --> 17:21.840
okay. Not where the class is actually belong to, which is the file, okay. So, in

17:21.840 --> 17:31.840
it to patch, where from where this person, this class is being imported, okay. So, you can actually

17:31.840 --> 17:38.840
type in the old module, you can just, you can just patch this person, person in here,

17:38.840 --> 17:43.840
and it will actually, it will actually be the new person in here and it will actually fix

17:43.840 --> 17:56.840
your issue. You see, it is fixed, okay. Even though the main module, the old module

17:56.840 --> 18:05.840
has some issues, old module have the person with this issue, okay. And I am actually going

18:05.840 --> 18:11.840
to end with the one thing that is very nasty one, okay. So, you should never do that, okay,

18:11.840 --> 18:17.840
at first, first, first, but I am just showing it for research purpose, okay. So, this is the thing,

18:17.840 --> 18:24.840
okay. So, you do not want your application to have any call to Google.com. So, not your code,

18:24.840 --> 18:30.840
your code, not third-party code, not any code, okay. So, what you can, you can do is that,

18:30.840 --> 18:36.840
you can actually patch the request library, okay. You can patch the request library to get,

18:36.840 --> 18:44.840
to patch the gate, okay. You see, if this patch is the gate, and if the URL is Google.com,

18:44.840 --> 18:50.840
you can just like raise the connection URL, that it will not work. And this can be used in a very

18:50.840 --> 18:56.840
different way, and very unethical way, and very ethical way as well. And you can route these

18:56.840 --> 19:02.840
your traffic from one domain to another and anything. Sometimes, maybe you need to route from

19:02.840 --> 19:09.840
one domain to another domain for the whole project, okay. So, you do not want to change everywhere,

19:09.840 --> 19:16.840
you just change in a, in your based Python call, and it will actually work everywhere, okay.

19:16.840 --> 19:22.840
So, maybe you can actually patch the URL lib. So, even though who are not using the request library,

19:22.840 --> 19:33.840
can actually also benefit that, okay. So, let's see. You see, so the request is actually

19:33.840 --> 19:38.840
like failing. So, its overall project is actually, like, you cannot actually make a good

19:39.840 --> 19:45.840
fault to Google in there. So, if actually, make it as that, okay. So, let's all.

19:50.840 --> 19:55.840
Thank you. Do you have any question?

19:56.840 --> 20:01.840
Hello.

20:06.840 --> 20:15.840
Thank you. Very nice talk. So, quick, quick fixes, the get pushed into production often stay in production forever.

20:15.840 --> 20:22.840
What would you say, like, how is your experience with, like, linting, like an import

20:22.840 --> 20:29.840
in the middle of your file? Yes, is that better?

20:29.840 --> 20:35.840
With a monkey patch that gets into production is probably going to cause linting warnings.

20:35.840 --> 20:41.840
Like, how do you handle your linting warnings in projects? You're going to suppress just like,

20:41.840 --> 20:46.840
what that one line, this temporary fix is here forever, shush, or, yeah.

20:46.840 --> 20:51.840
So, the thing is that you can actually feed that in a very different way, okay.

20:51.840 --> 20:57.840
You can actually feed that in the main code base and maybe you can actually create another class in there.

20:57.840 --> 21:01.840
But sometimes you have no access to that specific package, okay.

21:01.840 --> 21:07.840
Like, you are using one package, that one is calling another package, and that one is calling another package.

21:07.840 --> 21:11.840
Okay. So, in that case, this one is the, like, super-fastest way.

21:11.840 --> 21:16.840
We just fixed that, there is specific package that is going to happen in the bug,

21:16.840 --> 21:19.840
and all the change is actually fixed.

21:19.840 --> 21:22.840
Do you worry about the debt with the...

21:22.840 --> 21:29.840
Yeah, it's a hot fix, okay. You always need to make a good fix after this hot fix after the system gets up.

21:29.840 --> 21:33.840
You always need to do a good fix in there.

21:33.840 --> 21:36.840
You should not keep that in your code base long time, okay.

21:36.840 --> 21:39.840
Okay, yeah, thank you very much.

21:39.840 --> 21:42.840
Another question?

21:44.840 --> 21:45.840
Hello.

21:45.840 --> 21:47.840
Can you hear him? Oh, yes.

21:47.840 --> 21:52.840
So, you've talked about monkey patching, pushing that code.

21:52.840 --> 21:58.840
So, sorry, just try and get out of the way.

21:58.840 --> 22:03.840
So, you've talked about writing monkey patches that you then, like, push to your repository,

22:03.840 --> 22:07.840
and then, like, sort of update your container, you know, rebuild stuff.

22:07.840 --> 22:16.840
Have you, have any experience with literally live patching the code in running processes, like, in production?

22:17.840 --> 22:22.840
So, in that case, if you actually pay as the code directly into the production in the code base,

22:22.840 --> 22:25.840
if you're actually using dog car, if you actually get a new build,

22:25.840 --> 22:29.840
if you actually just not exist there, okay.

22:29.840 --> 22:33.840
So, so, it is possible.

22:33.840 --> 22:39.840
I'm here to plug, like, a tool called pyrocyte, like pyrocyte is about pyrocyte,

22:39.840 --> 22:42.840
so you can get, like, the live python shell into your thing.

22:42.840 --> 22:47.840
It's the last thing you should do, but it is really, really helpful if, like, your thread is blocked,

22:47.840 --> 22:50.840
and it's not getting any debug, say, that kind of thing.

22:50.840 --> 22:53.840
You can literally change anything in the process.

22:53.840 --> 22:54.840
I'll do it.

22:54.840 --> 22:55.840
Cool.

22:57.840 --> 22:59.840
I'm on the question.

22:59.840 --> 23:00.840
Oh, yeah.

23:00.840 --> 23:10.840
Yeah, it's not exactly a question.

23:10.840 --> 23:16.840
I would say, before trying all these things, there are other options.

23:16.840 --> 23:18.840
For example, you gave the example of tracing.

23:18.840 --> 23:23.840
Python has a built in library called trace inside the standard library.

23:23.840 --> 23:26.840
That helps with state tracing.

23:27.840 --> 23:31.840
Similarly, for monkey patching, I would also say, if you really have to do it,

23:31.840 --> 23:36.840
then use the unit test mock patch, you know, then doing it yourself.

23:36.840 --> 23:41.840
So, in the unit test mock patch, it's actually based mostly on unit test use case, okay.

23:41.840 --> 23:45.840
And this is for the, like, basic use case in there, okay.

23:45.840 --> 23:50.840
And yes, there are a lot of ways to do that, and for the python tracing,

23:50.840 --> 23:56.840
but you cannot actually add a debugger to a specific package in the local machine,

23:56.840 --> 23:58.840
or maybe in the production, okay.

23:58.840 --> 24:02.840
So, it's quite difficult to actually add a specific debugger to actually,

24:02.840 --> 24:05.840
a third-party package in this specific line in there.

24:05.840 --> 24:09.840
So, you can actually debug that, what value is actually getting,

24:09.840 --> 24:11.840
and you can actually fix that in there, okay.

24:11.840 --> 24:15.840
Maybe the thing is actually not reproducible in your local machine,

24:15.840 --> 24:17.840
but it's actually happening in the production, okay.

24:18.840 --> 24:21.840
So, these things actually get complicated in there.

24:25.840 --> 24:27.840
Another one? No? Okay.

24:27.840 --> 24:28.840
Thank you so much.

24:28.840 --> 24:29.840
Thank you, everyone.

24:34.840 --> 24:36.840
Next speaker will be,

