Repository: mlflow/mlflow

Issue:
[DOC-FIX] mlflow.pyfunc.log_model example uses mlflow.pyfunc.save_model
### Willingness to contribute

Yes. I would be willing to contribute a document fix with guidance from the MLflow community.

### URL(s) with the issue

[https://mlflow.org/docs/latest/python_api/mlflow.pyfunc.html?highlight=pyfunc%20log_model#mlflow.pyfunc.log_model](https://mlflow.org/docs/latest/python_api/mlflow.pyfunc.html?highlight=pyfunc%20log_model#mlflow.pyfunc.log_model)



### Description of proposal (what needs changing)

[This code example](https://mlflow.org/docs/latest/python_api/mlflow.pyfunc.html?highlight=pyfunc%20log_model#mlflow.pyfunc.log_model) in the documentation should explain how to use `pyfunc.log_model()` but shows `pyfunc.save_model()`

```python
from typing import List, Dict
import mlflow


class MyModel(mlflow.pyfunc.PythonModel):
    def predict(self, context, model_input: List[str], params=None) -> List[str]:
        return [i.upper() for i in model_input]


mlflow.pyfunc.save_model("model", python_model=MyModel(), input_example=["a"])
model = mlflow.pyfunc.load_model("model")
print(model.predict(["a", "b", "c"]))  # -> ["A", "B", "C"]
```

A draft example would be something in the lines of (cfr: [mlflow.pyfunc example](https://mlflow.org/docs/latest/python_api/mlflow.pyfunc.html?highlight=pyfunc%20log_model#mlflow.pyfunc.PyFuncModel))

```python

# define a custom model
class MyModel(mlflow.pyfunc.PythonModel):
    def predict(self, context, model_input, params=None):
        return self.my_custom_function(model_input, params)

    def my_custom_function(self, model_input, params=None):
        # do something with the model input
        return 0

# save the model
my_model = MyModel()
with mlflow.start_run():
    model_info = mlflow.pyfunc.log_model(artifact_path="model", python_model=my_model)
```


Discussion:
Hi @Beramos Thanks for raising this up! Though I feel like the example is more for the `python_model` explanation that it could be a PythonModel or a callable, using log_model in the example makes sense to me :D Feel free to raise a PR to update the examples, I'll review it. LMK if you need any help to get started!

Resolving patch:
diff --git a/mlflow/pyfunc/__init__.py b/mlflow/pyfunc/__init__.py
--- a/mlflow/pyfunc/__init__.py
+++ b/mlflow/pyfunc/__init__.py
@@ -495,9 +495,8 @@ def my_custom_function(self, model_input, params=None):
 
             some_input = 1
             # save the model
-            my_model = MyModel()
             with mlflow.start_run():
-                model_info = mlflow.pyfunc.log_model(artifact_path="model", python_model=my_model)
+                model_info = mlflow.pyfunc.log_model(artifact_path="model", python_model=MyModel())
 
             # load the model
             loaded_model = mlflow.pyfunc.load_model(model_uri=model_info.model_uri)
@@ -1917,7 +1916,7 @@ def log_model(
 
         .. code-block:: python
 
-            from typing import List, Dict
+            from typing import List
             import mlflow
 
 
@@ -1926,9 +1925,12 @@ def predict(self, context, model_input: List[str], params=None) -> List[str]:
                     return [i.upper() for i in model_input]
 
 
-            mlflow.pyfunc.save_model("model", python_model=MyModel(), input_example=["a"])
-            model = mlflow.pyfunc.load_model("model")
-            print(model.predict(["a", "b", "c"]))  # -> ["A", "B", "C"]
+            with mlflow.start_run():
+                model_info = mlflow.pyfunc.log_model(artifact_path="model", python_model=MyModel())
+
+
+            loaded_model = mlflow.pyfunc.load_model(model_uri=model_info.model_uri)
+            print(loaded_model.predict(["a", "b", "c"]))  # -> ["A", "B", "C"]
 
         Functional model
 
@@ -1946,9 +1948,14 @@ def predict(model_input: List[str]) -> List[str]:
                 return [i.upper() for i in model_input]
 
 
-            mlflow.pyfunc.save_model("model", python_model=predict, input_example=["a"])
-            model = mlflow.pyfunc.load_model("model")
-            print(model.predict(["a", "b", "c"]))  # -> ["A", "B", "C"]
+            with mlflow.start_run():
+                model_info = mlflow.pyfunc.log_model(
+                    artifact_path="model", python_model=predict, input_example=["a"]
+                )
+
+
+            loaded_model = mlflow.pyfunc.load_model(model_uri=model_info.model_uri)
+            print(loaded_model.predict(["a", "b", "c"]))  # -> ["A", "B", "C"]
 
         If the `predict` method or function has type annotations, MLflow automatically constructs
         a model signature based on the type annotations (unless the ``signature`` argument is


Test patch: