Repository: mlflow/mlflow

Issue:
[BUG] IsADirectoryError while selecting Azure artifact in the UI
### Willingness to contribute

No. I cannot contribute a bug fix at this time.

### System information

- **Have I written custom code (as opposed to using a stock example script provided in MLflow)**: no
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Debian GNU/Linux 11 (bullseye)
- **MLflow installed from (source or binary)**: binary
- **MLflow version (run ``mlflow --version``)**: 1.25.1
- **Python version**: 3.7
- **npm version, if running the dev UI**:


### Describe the problem

We deploy mlflow-server within a docker image on a kubernetes cluster on azure. As artifact store is an azure blob storage configured. MLFlow server is configured as artifact proxy. When logging a new model from a jupyter notebook on the client side, the model gets written correcty to the artifact store. We are also able to download the model again on the client side with the python api. As soon as we want to display the artifacts on the UI, it will not show up as expected. 
![grafik](https://user-images.githubusercontent.com/44830049/168012555-3eebc53b-2391-486e-94fd-6345340e9f00.png)

On the mlflow server we see the following exception:

`[2022-05-12 07:10:38 +0000] [20] [DEBUG] GET /get-artifact
2022/05/12 07:10:39 ERROR mlflow.server: Exception on /get-artifact [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/__init__.py", line 53, in serve_artifacts
    return get_artifact_handler()
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 327, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 409, in get_artifact_handler
    return _send_artifact(artifact_repo, artifact_path)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 318, in _send_artifact
    return send_file(filename, mimetype="text/plain", as_attachment=True)
  File "/usr/local/lib/python3.7/site-packages/flask/helpers.py", line 623, in send_file
    cache_timeout=cache_timeout,
  File "/usr/local/lib/python3.7/site-packages/werkzeug/utils.py", line 491, in send_file
    file = open(path, "rb")  # type: ignore
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpwsvta9ik/9/45c58ecb75b8420a8b58375015a20ea4/artifacts/sklearn-model/requirements.txt'`

When I then try to access the above file, I see that it actually is a directory and not a file:
![grafik](https://user-images.githubusercontent.com/44830049/168013145-85695c0a-e9f1-428f-8d03-cc93fa8139bc.png)

I think this issue is related to the following to issues:
https://github.com/mlflow/mlflow/issues/3154
https://github.com/mlflow/mlflow/issues/2991

Unfortunately I cannot debug the mlflow server in an easy way to print something.


### Tracking information

mlflow server \
    --backend-store-uri postgresql://connection_string \
    --artifacts-destination wasbs://container_name@storage_account.blob.core.windows.net/ \
    --serve-artifacts \
    --host 0.0.0.0 \
    --port 5000 \
    --gunicorn-opts "--log-level debug"

### Code to reproduce issue

It is a mlflow server UI problem.

### Other info / logs

_No response_

### What component(s) does this bug affect?

- [X] `area/artifacts`: Artifact stores and artifact logging
- [ ] `area/build`: Build and test infrastructure for MLflow
- [ ] `area/docs`: MLflow documentation pages
- [ ] `area/examples`: Example code
- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry
- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors
- [ ] `area/projects`: MLproject format, project running backends
- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs
- [ ] `area/server-infra`: MLflow Tracking server backend
- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging

### What interface(s) does this bug affect?

- [X] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server
- [ ] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry
- [ ] `area/windows`: Windows support

### What language(s) does this bug affect?

- [ ] `language/r`: R APIs and clients
- [ ] `language/java`: Java APIs and clients
- [ ] `language/new`: Proposals for new client languages

### What integration(s) does this bug affect?

- [X] `integrations/azure`: Azure and Azure ML integrations
- [ ] `integrations/sagemaker`: SageMaker integrations
- [ ] `integrations/databricks`: Databricks integrations
[BUG] IsADirectoryError while selecting Azure artifact in the UI
### Willingness to contribute

No. I cannot contribute a bug fix at this time.

### System information

- **Have I written custom code (as opposed to using a stock example script provided in MLflow)**: no
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: Debian GNU/Linux 11 (bullseye)
- **MLflow installed from (source or binary)**: binary
- **MLflow version (run ``mlflow --version``)**: 1.25.1
- **Python version**: 3.7
- **npm version, if running the dev UI**:


### Describe the problem

We deploy mlflow-server within a docker image on a kubernetes cluster on azure. As artifact store is an azure blob storage configured. MLFlow server is configured as artifact proxy. When logging a new model from a jupyter notebook on the client side, the model gets written correcty to the artifact store. We are also able to download the model again on the client side with the python api. As soon as we want to display the artifacts on the UI, it will not show up as expected. 
![grafik](https://user-images.githubusercontent.com/44830049/168012555-3eebc53b-2391-486e-94fd-6345340e9f00.png)

On the mlflow server we see the following exception:

`[2022-05-12 07:10:38 +0000] [20] [DEBUG] GET /get-artifact
2022/05/12 07:10:39 ERROR mlflow.server: Exception on /get-artifact [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/__init__.py", line 53, in serve_artifacts
    return get_artifact_handler()
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 327, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 409, in get_artifact_handler
    return _send_artifact(artifact_repo, artifact_path)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 318, in _send_artifact
    return send_file(filename, mimetype="text/plain", as_attachment=True)
  File "/usr/local/lib/python3.7/site-packages/flask/helpers.py", line 623, in send_file
    cache_timeout=cache_timeout,
  File "/usr/local/lib/python3.7/site-packages/werkzeug/utils.py", line 491, in send_file
    file = open(path, "rb")  # type: ignore
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpwsvta9ik/9/45c58ecb75b8420a8b58375015a20ea4/artifacts/sklearn-model/requirements.txt'`

When I then try to access the above file, I see that it actually is a directory and not a file:
![grafik](https://user-images.githubusercontent.com/44830049/168013145-85695c0a-e9f1-428f-8d03-cc93fa8139bc.png)

I think this issue is related to the following to issues:
https://github.com/mlflow/mlflow/issues/3154
https://github.com/mlflow/mlflow/issues/2991

Unfortunately I cannot debug the mlflow server in an easy way to print something.


### Tracking information

mlflow server \
    --backend-store-uri postgresql://connection_string \
    --artifacts-destination wasbs://container_name@storage_account.blob.core.windows.net/ \
    --serve-artifacts \
    --host 0.0.0.0 \
    --port 5000 \
    --gunicorn-opts "--log-level debug"

### Code to reproduce issue

It is a mlflow server UI problem.

### Other info / logs

_No response_

### What component(s) does this bug affect?

- [X] `area/artifacts`: Artifact stores and artifact logging
- [ ] `area/build`: Build and test infrastructure for MLflow
- [ ] `area/docs`: MLflow documentation pages
- [ ] `area/examples`: Example code
- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry
- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors
- [ ] `area/projects`: MLproject format, project running backends
- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs
- [ ] `area/server-infra`: MLflow Tracking server backend
- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging

### What interface(s) does this bug affect?

- [X] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server
- [ ] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry
- [ ] `area/windows`: Windows support

### What language(s) does this bug affect?

- [ ] `language/r`: R APIs and clients
- [ ] `language/java`: Java APIs and clients
- [ ] `language/new`: Proposals for new client languages

### What integration(s) does this bug affect?

- [X] `integrations/azure`: Azure and Azure ML integrations
- [ ] `integrations/sagemaker`: SageMaker integrations
- [ ] `integrations/databricks`: Databricks integrations


Discussion:
Hi @christianbaumberger could you 1) share the code that you're using to generate this run and 2) validate that both the client and the server versions are 1.25.1 as reported?
Hi @BenWilson2 
1) We used the following code to generate this run:
```
from random import random, randint
from sklearn.ensemble import RandomForestRegressor
import mlflow
import mlflow.sklearn
mlflow.set_experiment("test_cba_2022_05_10_3")

with mlflow.start_run(run_name="testrun") as run:
    artifact_uri = mlflow.get_artifact_uri()
    params = {"n_estimators": 5, "random_state": 42}
    sk_learn_rfr = RandomForestRegressor(**params)

    mlflow.log_params(params)
    mlflow.log_param("param_1", randint(0, 100))
    mlflow.log_metrics({"metric_1": random(), "metric_2": random() + 1})

    mlflow.sklearn.log_model(
        sk_model=sk_learn_rfr,
        artifact_path="testmodel",
        registered_model_name="sk-learn-random-forest-reg-model"
    )
```

2) I validated that both, the client and the server have version 1.25.1.

I haven't been able to reproduce this with your exact code (barring, of course, creating a new experiment). 

The pasted image that you provided above has an artifact name that doesn't match with the code that you provided. Could you try to run this and see what those print statements return?:

```py

from random import random, randint
from sklearn.ensemble import RandomForestRegressor
import mlflow

mlflow.set_experiment("testing_pathing")

with mlflow.start_run(run_name="test_run_for_pathing_validation") as run:
    print(f"Artifact uri: {run.info.artifact_uri}\n")
    params = {"n_estimators": 5, "random_state": 42}
    sk_learn_rfr = RandomForestRegressor(**params)
    
    mlflow.log_params(params)
    mlflow.log_param("param_1", randint(0, 100))
    mlflow.log_metrics({"metric_1": random(), "metric_2": random() + 1})

    mlflow.sklearn.log_model(
        sk_model=sk_learn_rfr,
        artifact_path="testmodel/testing/logging/to/different/location",
        registered_model_name="sk-learn-random-forest-reg-model"
    )
    print(f"\nRun info: {run.info}")
```
I was running your code and got the following print statements:

```
Artifact uri: mlflow-artifacts:/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts

Run info: <RunInfo: artifact_uri='mlflow-artifacts:/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts', end_time=None, experiment_id='12', lifecycle_stage='active', run_id='db81d04d75a1481bb7f4d6bcac3ce9a5', run_uuid='db81d04d75a1481bb7f4d6bcac3ce9a5', start_time=1652761771034, status='RUNNING', user_id='myuserid'>

```
Besides that, in the UI it looks like the following:
![grafik](https://user-images.githubusercontent.com/44830049/168729712-b708be05-fe77-4af1-8f13-4f3ef523f9d1.png)

and the log in the mlflow-server looks like this:

```
2022/05/17 04:32:19 ERROR mlflow.server: Exception on /get-artifact [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/__init__.py", line 53, in serve_artifacts
    return get_artifact_handler()
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 327, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 409, in get_artifact_handler
    return _send_artifact(artifact_repo, artifact_path)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 320, in _send_artifact
    return send_file(filename, as_attachment=True)
  File "/usr/local/lib/python3.7/site-packages/flask/helpers.py", line 623, in send_file
    cache_timeout=cache_timeout,
  File "/usr/local/lib/python3.7/site-packages/werkzeug/utils.py", line 491, in send_file
    file = open(path, "rb")  # type: ignore
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpnwq1krpp/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts/testmodel/testing/logging/to/different/location/MLmodel'
```
Hi @BenWilson2 
Just to let you know: I just tried with mlflow version 1.26.0 and the error is the same. 
And another note: this in only a problem with azure blob storage as artifact store. We haven't seen this behaviour with S3!
Is there a service principal configuration that's somehow not getting access to the underlying object store on Azure blob? Does the same thing happen on ADLSGen2? 
It might help to file a ticket with Azure to have them assist on the required configuration to get this to work. I haven't heard any issues from others who use ADLSG2 with proxy access (which is pure anecdotal evidence, to be sure, but I think others have had success with it). Hopefully it's a simple configuration rights management fix! 
Whatever you end up finding with an investigation from Azure, could you share here?
I (colleague of @christianbaumberger) looked into this issue some more and discovered a workaround:

MLflow works as expected iff you configure a sub-path in the artifact root. E.g. instead of `wasbs://my-container@my-account.blob.core.windows.net` configure `wasbs://my-container@my-account.blob.core.windows.net/foo` as `MLFLOW_SERVER_ARTIFACT_ROOT`.

**Details**

`is_directory` (https://github.com/mlflow/mlflow/blob/master/mlflow/store/artifact/artifact_repo.py#L78-L80) erroneously returns `True` in our case. `listing` looks like this, for example:
```
[<FileInfo: file_size=70, is_dir=False, path='0/310c7a8a52c148d5a0123e234b9c0da9/artifacts/testmodel/testing/logging/to/different/location/requirements.txt'>]
```
but it should be an empty array in order for `is_directory` to be `False`.

In the Azure specific code in https://github.com/mlflow/mlflow/blob/master/mlflow/store/artifact/azure_blob_artifact_repo.py#L145-L149, `infos[0].path == rel_path` is `False` in our case, so no empty array is returned from the method.

Hope this helps with debugging this issue...
Hi @nerdinand and @christianbaumberger thank you for the in-depth investigation and for the full explanation of the behavior that you're seeing. We'll be taking a look at the functionality and come up with a fix for ensuring that the listing for a file location doesn't return an additional path, returning an empty array for the UI's artifact viewer. 
(Unless the two of you would like to file a PR fix since you've done the vast majority of the root cause investigation? If yes, please let me know and we'll work with you on it!)
Thanks again and good work tracking down the source of this!
Hi @BenWilson2

I don't think we'll have the time to develop a fix for this and we're fine with the workaround for now. So no urgency to fix this from our side. Thank you for your time and work!
Hi @christianbaumberger could you 1) share the code that you're using to generate this run and 2) validate that both the client and the server versions are 1.25.1 as reported?
Hi @BenWilson2 
1) We used the following code to generate this run:
```
from random import random, randint
from sklearn.ensemble import RandomForestRegressor
import mlflow
import mlflow.sklearn
mlflow.set_experiment("test_cba_2022_05_10_3")

with mlflow.start_run(run_name="testrun") as run:
    artifact_uri = mlflow.get_artifact_uri()
    params = {"n_estimators": 5, "random_state": 42}
    sk_learn_rfr = RandomForestRegressor(**params)

    mlflow.log_params(params)
    mlflow.log_param("param_1", randint(0, 100))
    mlflow.log_metrics({"metric_1": random(), "metric_2": random() + 1})

    mlflow.sklearn.log_model(
        sk_model=sk_learn_rfr,
        artifact_path="testmodel",
        registered_model_name="sk-learn-random-forest-reg-model"
    )
```

2) I validated that both, the client and the server have version 1.25.1.

I haven't been able to reproduce this with your exact code (barring, of course, creating a new experiment). 

The pasted image that you provided above has an artifact name that doesn't match with the code that you provided. Could you try to run this and see what those print statements return?:

```py

from random import random, randint
from sklearn.ensemble import RandomForestRegressor
import mlflow

mlflow.set_experiment("testing_pathing")

with mlflow.start_run(run_name="test_run_for_pathing_validation") as run:
    print(f"Artifact uri: {run.info.artifact_uri}\n")
    params = {"n_estimators": 5, "random_state": 42}
    sk_learn_rfr = RandomForestRegressor(**params)
    
    mlflow.log_params(params)
    mlflow.log_param("param_1", randint(0, 100))
    mlflow.log_metrics({"metric_1": random(), "metric_2": random() + 1})

    mlflow.sklearn.log_model(
        sk_model=sk_learn_rfr,
        artifact_path="testmodel/testing/logging/to/different/location",
        registered_model_name="sk-learn-random-forest-reg-model"
    )
    print(f"\nRun info: {run.info}")
```
I was running your code and got the following print statements:

```
Artifact uri: mlflow-artifacts:/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts

Run info: <RunInfo: artifact_uri='mlflow-artifacts:/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts', end_time=None, experiment_id='12', lifecycle_stage='active', run_id='db81d04d75a1481bb7f4d6bcac3ce9a5', run_uuid='db81d04d75a1481bb7f4d6bcac3ce9a5', start_time=1652761771034, status='RUNNING', user_id='myuserid'>

```
Besides that, in the UI it looks like the following:
![grafik](https://user-images.githubusercontent.com/44830049/168729712-b708be05-fe77-4af1-8f13-4f3ef523f9d1.png)

and the log in the mlflow-server looks like this:

```
2022/05/17 04:32:19 ERROR mlflow.server: Exception on /get-artifact [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2077, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1525, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1523, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1509, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/__init__.py", line 53, in serve_artifacts
    return get_artifact_handler()
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 327, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 409, in get_artifact_handler
    return _send_artifact(artifact_repo, artifact_path)
  File "/usr/local/lib/python3.7/site-packages/mlflow/server/handlers.py", line 320, in _send_artifact
    return send_file(filename, as_attachment=True)
  File "/usr/local/lib/python3.7/site-packages/flask/helpers.py", line 623, in send_file
    cache_timeout=cache_timeout,
  File "/usr/local/lib/python3.7/site-packages/werkzeug/utils.py", line 491, in send_file
    file = open(path, "rb")  # type: ignore
IsADirectoryError: [Errno 21] Is a directory: '/tmp/tmpnwq1krpp/12/db81d04d75a1481bb7f4d6bcac3ce9a5/artifacts/testmodel/testing/logging/to/different/location/MLmodel'
```
Hi @BenWilson2 
Just to let you know: I just tried with mlflow version 1.26.0 and the error is the same. 
And another note: this in only a problem with azure blob storage as artifact store. We haven't seen this behaviour with S3!
Is there a service principal configuration that's somehow not getting access to the underlying object store on Azure blob? Does the same thing happen on ADLSGen2? 
It might help to file a ticket with Azure to have them assist on the required configuration to get this to work. I haven't heard any issues from others who use ADLSG2 with proxy access (which is pure anecdotal evidence, to be sure, but I think others have had success with it). Hopefully it's a simple configuration rights management fix! 
Whatever you end up finding with an investigation from Azure, could you share here?
I (colleague of @christianbaumberger) looked into this issue some more and discovered a workaround:

MLflow works as expected iff you configure a sub-path in the artifact root. E.g. instead of `wasbs://my-container@my-account.blob.core.windows.net` configure `wasbs://my-container@my-account.blob.core.windows.net/foo` as `MLFLOW_SERVER_ARTIFACT_ROOT`.

**Details**

`is_directory` (https://github.com/mlflow/mlflow/blob/master/mlflow/store/artifact/artifact_repo.py#L78-L80) erroneously returns `True` in our case. `listing` looks like this, for example:
```
[<FileInfo: file_size=70, is_dir=False, path='0/310c7a8a52c148d5a0123e234b9c0da9/artifacts/testmodel/testing/logging/to/different/location/requirements.txt'>]
```
but it should be an empty array in order for `is_directory` to be `False`.

In the Azure specific code in https://github.com/mlflow/mlflow/blob/master/mlflow/store/artifact/azure_blob_artifact_repo.py#L145-L149, `infos[0].path == rel_path` is `False` in our case, so no empty array is returned from the method.

Hope this helps with debugging this issue...
Hi @nerdinand and @christianbaumberger thank you for the in-depth investigation and for the full explanation of the behavior that you're seeing. We'll be taking a look at the functionality and come up with a fix for ensuring that the listing for a file location doesn't return an additional path, returning an empty array for the UI's artifact viewer. 
(Unless the two of you would like to file a PR fix since you've done the vast majority of the root cause investigation? If yes, please let me know and we'll work with you on it!)
Thanks again and good work tracking down the source of this!
Hi @BenWilson2

I don't think we'll have the time to develop a fix for this and we're fine with the workaround for now. So no urgency to fix this from our side. Thank you for your time and work!

Resolving patch:
diff --git a/mlflow/store/artifact/azure_blob_artifact_repo.py b/mlflow/store/artifact/azure_blob_artifact_repo.py
--- a/mlflow/store/artifact/azure_blob_artifact_repo.py
+++ b/mlflow/store/artifact/azure_blob_artifact_repo.py
@@ -119,6 +119,9 @@ def list_artifacts(self, path=None):
         except ImportError:
             from azure.storage.blob._models import BlobPrefix
 
+        def is_dir(result):
+            return isinstance(result, BlobPrefix)
+
         (container, _, artifact_path, _) = self.parse_wasbs_uri(self.artifact_uri)
         container_client = self.client.get_container_client(container)
         dest_path = artifact_path
@@ -127,21 +130,29 @@ def list_artifacts(self, path=None):
         infos = []
         prefix = dest_path if dest_path.endswith("/") else dest_path + "/"
         results = container_client.walk_blobs(name_starts_with=prefix)
-        for r in results:
-            if not r.name.startswith(artifact_path):
+
+        for result in results:
+            if (
+                dest_path == result.name
+            ):  # result isn't actually a child of the path we're interested in, so skip it
+                continue
+
+            if not result.name.startswith(artifact_path):
                 raise MlflowException(
                     "The name of the listed Azure blob does not begin with the specified"
                     " artifact path. Artifact path: {artifact_path}. Blob name:"
-                    " {blob_name}".format(artifact_path=artifact_path, blob_name=r.name)
+                    " {blob_name}".format(artifact_path=artifact_path, blob_name=result.name)
                 )
-            if isinstance(r, BlobPrefix):  # This is a prefix for items in a subdirectory
-                subdir = posixpath.relpath(path=r.name, start=artifact_path)
+
+            if is_dir(result):
+                subdir = posixpath.relpath(path=result.name, start=artifact_path)
                 if subdir.endswith("/"):
                     subdir = subdir[:-1]
-                infos.append(FileInfo(subdir, True, None))
+                infos.append(FileInfo(subdir, is_dir=True, file_size=None))
             else:  # Just a plain old blob
-                file_name = posixpath.relpath(path=r.name, start=artifact_path)
-                infos.append(FileInfo(file_name, False, r.size))
+                file_name = posixpath.relpath(path=result.name, start=artifact_path)
+                infos.append(FileInfo(file_name, is_dir=False, file_size=result.size))
+
         # The list_artifacts API expects us to return an empty list if the
         # the path references a single file.
         rel_path = dest_path[len(artifact_path) + 1 :]


Test patch: