Repository: rasterio/rasterio

Issue:
unable to read private key from azure with az://{container}/{key} but /vsiaz/{container}/{key} works
<!--

WELCOME ABOARD!

Hi and welcome to the Rasterio project. We appreciate bug reports, questions
about documentation, and suggestions for new features. This issue template
isn't intended to ward you off; only to intercept and redirect some particular
categories of reports, and to collect a few important facts that issue reporters
often omit.

The primary forum for questions about installation and usage of Rasterio is 
https://rasterio.groups.io/g/main. The authors and other users will answer 
questions when they have expertise to share and time to explain. Please take the
time to craft a clear question and be patient about responses. Please do not
bring these questions to Rasterio's issue tracker, which we want to reserve for
bug reports and other actionable issues.

Questions about development of Rasterio, brainstorming, requests for comment,
and not-yet-actionable proposals are welcome in the project's developers 
discussion group https://rasterio.groups.io/g/dev. Issues opened in Rasterio's
GitHub repo which haven't been socialized there may be perfunctorily closed.

Please note: Rasterio contains extension modules and is thus susceptible to
C library compatibility issues. If you are reporting an installation or module
import issue, please note that this project only accepts reports about problems
with packages downloaded from the Python Package Index. Conda users should take
issues to one of the following trackers:

- https://github.com/ContinuumIO/anaconda-issues/issues
- https://github.com/conda-forge/rasterio-feedstock

You think you've found a bug? We believe you!
-->

## Expected behavior and actual behavior.

I would like to be able to rely on the environment variables `AZURE_STORAGE_ACCOUNT` and `AZURE_STORAGE_ACCESS_KEY` to make it possible to read files that look like `az://{container}/{key}`, but rasterio does not seem to be pulling those environment variables the same way it can for S3 URIs.

This was working for me as recently as version 1.3a3, but in 1.3.3 I cannot get it to work! I have combed through `rasterio/session.py` and it appears that `AZURE_STORAGE_ACCOUNT` gets pulled from the environment, but `AZURE_STORAGE_ACCESS_KEY` does not. Is that intentional?

## Steps to reproduce the problem.
I am not really sure how to provide a full reproducible examples for private storage container, but here is the pattern that I have observed.

This works:
```sh
AZURE_STORAGE_ACCOUNT={AZURE_STORAGE_ACCOUNT} AZURE_STORAGE_ACCESS_KEY={AZURE_STORAGE_ACCESS_KEY} rio info /vsiaz/{container}/{key}
```

This fails:
```sh
AZURE_STORAGE_ACCOUNT={AZURE_STORAGE_ACCOUNT} AZURE_STORAGE_ACCESS_KEY={AZURE_STORAGE_ACCESS_KEY} rio info az://{container}/{key}
```

I think this is happening because `AzureSession` will not pull `AZURE_STORAGE_ACCESS_KEY` from the environment.

```sh
$ AZURE_STORAGE_ACCOUNT=foo AZURE_STORAGE_ACCESS_KEY=bar python - <<EOF
> from rasterio.session import Session
> sesh = Session.from_path("az://lol/wut")
> print(sesh.credentials)
> EOF
{'azure_storage_account': 'foo', 'azure_storage_access_key': None}
```

As far as I can tell the only way to provide it is by calling `AzureSession(azure_storage_access_key={AZURE_STORAGE_ACCESS_KEY})`, but I don't know how to propagate that behavior through my entire environment.



#### Environment Information
```sh
$ rio --show-versions
rasterio info:
  rasterio: 1.3.3
      GDAL: 3.4.3
      PROJ: 8.2.1
      GEOS: 3.10.2
 PROJ DATA: /home/henry/.local/share/proj:/usr/share/proj
 GDAL DATA: None

System:
    python: 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0]
executable: /home/henry/.virtualenvs/sequoia/bin/python
   machine: Linux-5.15.0-52-generic-x86_64-with-glibc2.35

Python deps:
    affine: 2.3.0
     attrs: 21.4.0
   certifi: 2021.10.08
     click: 8.0.3
     cligj: 0.7.2
    cython: 0.29.32
     numpy: 1.22.1
    snuggs: 1.4.7
click-plugins: None
setuptools: 59.8.0
```

## Installation Method

```sh
pip install rasterio==1.3.3
```



Discussion:

Resolving patch:
diff --git a/rasterio/session.py b/rasterio/session.py
--- a/rasterio/session.py
+++ b/rasterio/session.py
@@ -563,7 +563,8 @@ def __init__(self, azure_storage_connection_string=None,
         """
 
         self.unsigned = bool(os.getenv("AZURE_NO_SIGN_REQUEST", azure_unsigned))
-        self.storage_account = os.getenv("AZURE_STORAGE_ACCOUNT", azure_storage_account)
+        self.storage_account = azure_storage_account or os.getenv("AZURE_STORAGE_ACCOUNT")
+        self.storage_access_key = azure_storage_access_key or os.getenv("AZURE_STORAGE_ACCESS_KEY")
 
         if azure_storage_connection_string:
             self._creds = {
@@ -572,7 +573,7 @@ def __init__(self, azure_storage_connection_string=None,
         elif not self.unsigned:
             self._creds = {
                 "azure_storage_account": self.storage_account,
-                "azure_storage_access_key": azure_storage_access_key
+                "azure_storage_access_key": self.storage_access_key
             }
         else:
             self._creds = {


Test patch:
diff --git a/tests/test_session.py b/tests/test_session.py
--- a/tests/test_session.py
+++ b/tests/test_session.py
@@ -282,6 +282,16 @@ def test_session_factory_az_kwargs_connection_string():
     assert sesh.get_credential_options()['AZURE_STORAGE_CONNECTION_STRING'] == 'AccountName=myaccount;AccountKey=MY_ACCOUNT_KEY'
 
 
+def test_session_factory_az_env(monkeypatch):
+    """Get an AzureSession for az:// paths with environment variables"""
+    monkeypatch.setenv('AZURE_STORAGE_ACCOUNT', 'foo')
+    monkeypatch.setenv('AZURE_STORAGE_ACCESS_KEY', 'bar')
+    sesh = Session.from_path("az://lol/wut")
+    assert isinstance(sesh, AzureSession)
+    assert sesh.get_credential_options()['AZURE_STORAGE_ACCOUNT'] == 'foo'
+    assert sesh.get_credential_options()['AZURE_STORAGE_ACCESS_KEY'] == 'bar'
+
+
 def test_azure_no_sign_request(monkeypatch):
     """If AZURE_NO_SIGN_REQUEST is set do not default to azure_unsigned=False"""
     monkeypatch.setenv('AZURE_NO_SIGN_REQUEST', 'YES')