prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Avoid downloading all rasters
  If you have many large scenes, the rasters will all be downloaded at once and you will run out of disk space. This is because the download occurs in the constructor of `RasterSources`. Instead, dwe should download rasters https://github.com/azavea/raster-vision/blob/develop/rastervision/data/raster_source/rasterio_source.py#L79 in the _activate method https://github.com/azavea/raster-vision/blob/develop/rastervision/data/raster_source/rasterio_source.py#L100 and delete them in the _deactivate method. 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `rastervision/command/command.py`
  Content:
  ```
  1 from abc import ABC, abstractmethod
  2 
  3 from rastervision.rv_config import RVConfig
  4 
  5 
  6 class Command(ABC):
  7     @abstractmethod
  8     def run(self, tmp_dir):
  9         """Run the command."""
  10         pass
  11 
  12     def set_tmp_dir(self, tmp_dir):
  13         self._tmp_dir = tmp_dir
  14 
  15     def get_tmp_dir(self):
  16         if hasattr(self, '_tmp_dir') and self._tmp_dir:
  17             if isinstance(self._tmp_dir, str):
  18                 return self._tmp_dir
  19             else:
  20                 return self._tmp_dir.name
  21         else:
  22             return RVConfig.get_tmp_dir().name
  23 
  24 
  25 class NoOpCommand(Command):
  26     """Defines a command that does nothing.
  27     """
  28 
  29     def run(self, tmp_dir):
  30         pass
  31
  ```
  
  Path: `rastervision/data/raster_source/rasterio_source.py`
  Content:
  ```
  1 from abc import abstractmethod
  2 
  3 import numpy as np
  4 import rasterio
  5 from rasterio.enums import (ColorInterp, MaskFlags)
  6 
  7 from rastervision.data import (ActivateMixin, ActivationError)
  8 from rastervision.data.raster_source import RasterSource
  9 from rastervision.core.box import Box
  10 
  11 
  12 def load_window(image_dataset, window=None, channels=None, is_masked=False):
  13     """Load a window of an image from a TIFF file.
  14 
  15     Args:
  16         window: ((row_start, row_stop), (col_start, col_stop)) or
  17         ((y_min, y_max), (x_min, x_max))
  18         channels: An optional list of bands to read.
  19         is_masked: If True, read a  masked array from rasterio
  20     """
  21     if is_masked:
  22         im = image_dataset.read(window=window, boundless=True, masked=True)
  23         im = np.ma.filled(im, fill_value=0)
  24     else:
  25         im = image_dataset.read(window=window, boundless=True)
  26 
  27     # Handle non-zero NODATA values by setting the data to 0.
  28     for channel, nodata in enumerate(image_dataset.nodatavals):
  29         if nodata is not None and nodata != 0:
  30             im[channel, im[channel] == nodata] = 0
  31 
  32     if channels:
  33         im = im[channels, :]
  34     im = np.transpose(im, axes=[1, 2, 0])
  35     return im
  36 
  37 
  38 class RasterioRasterSource(ActivateMixin, RasterSource):
  39     def __init__(self, raster_transformers, temp_dir, channel_order=None):
  40         self.temp_dir = temp_dir
  41         self.imagery_path = self._download_data(temp_dir)
  42 
  43         num_channels = None
  44 
  45         # Activate in order to get information out of the raster
  46         with self.activate():
  47             colorinterp = self.image_dataset.colorinterp
  48             self.channels = [
  49                 i for i, color_interp in enumerate(colorinterp)
  50                 if color_interp != ColorInterp.alpha
  51             ]
  52 
  53             mask_flags = self.image_dataset.mask_flag_enums
  54             self.is_masked = any(
  55                 [m for m in mask_flags if m != MaskFlags.all_valid])
  56 
  57             self.height = self.image_dataset.height
  58             self.width = self.image_dataset.width
  59             # Get 1x1 chip (after applying raster transformers) to test dtype
  60             # and channel order if needed
  61             test_chip = self.get_raw_chip(Box.make_square(0, 0, 1))
  62 
  63             raw_channels = list(range(0, test_chip.shape[2]))
  64             self.channel_order = channel_order or raw_channels
  65             num_channels = len(raw_channels)
  66 
  67             # Transform the chip to get the final dtype
  68             test_chip = test_chip[:, :, self.channel_order]
  69             for transformer in raster_transformers:
  70                 test_chip = transformer.transform(test_chip, channel_order)
  71 
  72             self.dtype = test_chip.dtype
  73 
  74             self._set_crs_transformer()
  75 
  76         super().__init__(channel_order, num_channels, raster_transformers)
  77 
  78     @abstractmethod
  79     def _download_data(self, tmp_dir):
  80         """Download any data needed for this Raster Source.
  81         Return a single local path representing the image or a VRT of the data."""
  82         pass
  83 
  84     def get_crs_transformer(self):
  85         return self.crs_transformer
  86 
  87     def get_extent(self):
  88         return Box(0, 0, self.height, self.width)
  89 
  90     def get_dtype(self):
  91         """Return the numpy.dtype of this scene"""
  92         return self.dtype
  93 
  94     def _get_chip(self, window):
  95         if self.image_dataset is None:
  96             raise ActivationError('RasterSource must be activated before use')
  97         return load_window(self.image_dataset, window.rasterio_format(),
  98                            self.channels)
  99 
  100     def _activate(self):
  101         self.image_dataset = rasterio.open(self.imagery_path)
  102 
  103     def _deactivate(self):
  104         self.image_dataset.close()
  105         self.image_dataset = None
  106
  ```
  
  Path: `rastervision/data/raster_source/image_source.py`
  Content:
  ```
  1 from rastervision.data.raster_source.rasterio_source import (
  2     RasterioRasterSource)
  3 from rastervision.data.crs_transformer.identity_crs_transformer import (
  4     IdentityCRSTransformer)
  5 from rastervision.utils.files import download_if_needed
  6 
  7 
  8 class ImageSource(RasterioRasterSource):
  9     def __init__(self, uri, raster_transformers, temp_dir, channel_order=None):
  10         self.uri = uri
  11         super().__init__(raster_transformers, temp_dir, channel_order)
  12 
  13     def _download_data(self, temp_dir):
  14         return download_if_needed(self.uri, self.temp_dir)
  15 
  16     def _set_crs_transformer(self):
  17         self.crs_transformer = IdentityCRSTransformer()
  18
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/rastervision/command/command.py b/rastervision/command/command.py
  --- a/rastervision/command/command.py
  +++ b/rastervision/command/command.py
  @@ -19,7 +19,9 @@
               else:
                   return self._tmp_dir.name
           else:
  -            return RVConfig.get_tmp_dir().name
  +            tmp_dir = RVConfig.get_tmp_dir()
  +            self.set_tmp_dir(tmp_dir)
  +            return tmp_dir.name
   
   
   class NoOpCommand(Command):
  diff --git a/rastervision/data/raster_source/image_source.py b/rastervision/data/raster_source/image_source.py
  --- a/rastervision/data/raster_source/image_source.py
  +++ b/rastervision/data/raster_source/image_source.py
  @@ -11,7 +11,7 @@
           super().__init__(raster_transformers, temp_dir, channel_order)
   
       def _download_data(self, temp_dir):
  -        return download_if_needed(self.uri, self.temp_dir)
  +        return download_if_needed(self.uri, temp_dir)
   
       def _set_crs_transformer(self):
           self.crs_transformer = IdentityCRSTransformer()
  diff --git a/rastervision/data/raster_source/rasterio_source.py b/rastervision/data/raster_source/rasterio_source.py
  --- a/rastervision/data/raster_source/rasterio_source.py
  +++ b/rastervision/data/raster_source/rasterio_source.py
  @@ -1,4 +1,5 @@
   from abc import abstractmethod
  +import tempfile
   
   import numpy as np
   import rasterio
  @@ -38,8 +39,8 @@
   class RasterioRasterSource(ActivateMixin, RasterSource):
       def __init__(self, raster_transformers, temp_dir, channel_order=None):
           self.temp_dir = temp_dir
  -        self.imagery_path = self._download_data(temp_dir)
  -
  +        self.image_temp_dir = None
  +        self.image_dataset = None
           num_channels = None
   
           # Activate in order to get information out of the raster
  @@ -98,8 +99,14 @@
                              self.channels)
   
       def _activate(self):
  +        # Download images to temporary directory and delete it when done.
  +        self.image_temp_dir = tempfile.TemporaryDirectory(dir=self.temp_dir)
  +        self.imagery_path = self._download_data(self.image_temp_dir.name)
           self.image_dataset = rasterio.open(self.imagery_path)
  +        self._set_crs_transformer()
   
       def _deactivate(self):
           self.image_dataset.close()
           self.image_dataset = None
  +        self.image_temp_dir.cleanup()
  +        self.image_temp_dir = None
  
verification_info: {"golden_diff": "diff --git a/rastervision/command/command.py b/rastervision/command/command.py\n--- a/rastervision/command/command.py\n+++ b/rastervision/command/command.py\n@@ -19,7 +19,9 @@\n             else:\n                 return self._tmp_dir.name\n         else:\n-            return RVConfig.get_tmp_dir().name\n+            tmp_dir = RVConfig.get_tmp_dir()\n+            self.set_tmp_dir(tmp_dir)\n+            return tmp_dir.name\n \n \n class NoOpCommand(Command):\ndiff --git a/rastervision/data/raster_source/image_source.py b/rastervision/data/raster_source/image_source.py\n--- a/rastervision/data/raster_source/image_source.py\n+++ b/rastervision/data/raster_source/image_source.py\n@@ -11,7 +11,7 @@\n         super().__init__(raster_transformers, temp_dir, channel_order)\n \n     def _download_data(self, temp_dir):\n-        return download_if_needed(self.uri, self.temp_dir)\n+        return download_if_needed(self.uri, temp_dir)\n \n     def _set_crs_transformer(self):\n         self.crs_transformer = IdentityCRSTransformer()\ndiff --git a/rastervision/data/raster_source/rasterio_source.py b/rastervision/data/raster_source/rasterio_source.py\n--- a/rastervision/data/raster_source/rasterio_source.py\n+++ b/rastervision/data/raster_source/rasterio_source.py\n@@ -1,4 +1,5 @@\n from abc import abstractmethod\n+import tempfile\n \n import numpy as np\n import rasterio\n@@ -38,8 +39,8 @@\n class RasterioRasterSource(ActivateMixin, RasterSource):\n     def __init__(self, raster_transformers, temp_dir, channel_order=None):\n         self.temp_dir = temp_dir\n-        self.imagery_path = self._download_data(temp_dir)\n-\n+        self.image_temp_dir = None\n+        self.image_dataset = None\n         num_channels = None\n \n         # Activate in order to get information out of the raster\n@@ -98,8 +99,14 @@\n                            self.channels)\n \n     def _activate(self):\n+        # Download images to temporary directory and delete it when done.\n+        self.image_temp_dir = tempfile.TemporaryDirectory(dir=self.temp_dir)\n+        self.imagery_path = self._download_data(self.image_temp_dir.name)\n         self.image_dataset = rasterio.open(self.imagery_path)\n+        self._set_crs_transformer()\n \n     def _deactivate(self):\n         self.image_dataset.close()\n         self.image_dataset = None\n+        self.image_temp_dir.cleanup()\n+        self.image_temp_dir = None\n", "issue": "Avoid downloading all rasters\nIf you have many large scenes, the rasters will all be downloaded at once and you will run out of disk space. This is because the download occurs in the constructor of `RasterSources`. Instead, dwe should download rasters https://github.com/azavea/raster-vision/blob/develop/rastervision/data/raster_source/rasterio_source.py#L79 in the _activate method https://github.com/azavea/raster-vision/blob/develop/rastervision/data/raster_source/rasterio_source.py#L100 and delete them in the _deactivate method. \n", "before_files": [{"content": "from abc import ABC, abstractmethod\n\nfrom rastervision.rv_config import RVConfig\n\n\nclass Command(ABC):\n    @abstractmethod\n    def run(self, tmp_dir):\n        \"\"\"Run the command.\"\"\"\n        pass\n\n    def set_tmp_dir(self, tmp_dir):\n        self._tmp_dir = tmp_dir\n\n    def get_tmp_dir(self):\n        if hasattr(self, '_tmp_dir') and self._tmp_dir:\n            if isinstance(self._tmp_dir, str):\n                return self._tmp_dir\n            else:\n                return self._tmp_dir.name\n        else:\n            return RVConfig.get_tmp_dir().name\n\n\nclass NoOpCommand(Command):\n    \"\"\"Defines a command that does nothing.\n    \"\"\"\n\n    def run(self, tmp_dir):\n        pass\n", "path": "rastervision/command/command.py"}, {"content": "from abc import abstractmethod\n\nimport numpy as np\nimport rasterio\nfrom rasterio.enums import (ColorInterp, MaskFlags)\n\nfrom rastervision.data import (ActivateMixin, ActivationError)\nfrom rastervision.data.raster_source import RasterSource\nfrom rastervision.core.box import Box\n\n\ndef load_window(image_dataset, window=None, channels=None, is_masked=False):\n    \"\"\"Load a window of an image from a TIFF file.\n\n    Args:\n        window: ((row_start, row_stop), (col_start, col_stop)) or\n        ((y_min, y_max), (x_min, x_max))\n        channels: An optional list of bands to read.\n        is_masked: If True, read a  masked array from rasterio\n    \"\"\"\n    if is_masked:\n        im = image_dataset.read(window=window, boundless=True, masked=True)\n        im = np.ma.filled(im, fill_value=0)\n    else:\n        im = image_dataset.read(window=window, boundless=True)\n\n    # Handle non-zero NODATA values by setting the data to 0.\n    for channel, nodata in enumerate(image_dataset.nodatavals):\n        if nodata is not None and nodata != 0:\n            im[channel, im[channel] == nodata] = 0\n\n    if channels:\n        im = im[channels, :]\n    im = np.transpose(im, axes=[1, 2, 0])\n    return im\n\n\nclass RasterioRasterSource(ActivateMixin, RasterSource):\n    def __init__(self, raster_transformers, temp_dir, channel_order=None):\n        self.temp_dir = temp_dir\n        self.imagery_path = self._download_data(temp_dir)\n\n        num_channels = None\n\n        # Activate in order to get information out of the raster\n        with self.activate():\n            colorinterp = self.image_dataset.colorinterp\n            self.channels = [\n                i for i, color_interp in enumerate(colorinterp)\n                if color_interp != ColorInterp.alpha\n            ]\n\n            mask_flags = self.image_dataset.mask_flag_enums\n            self.is_masked = any(\n                [m for m in mask_flags if m != MaskFlags.all_valid])\n\n            self.height = self.image_dataset.height\n            self.width = self.image_dataset.width\n            # Get 1x1 chip (after applying raster transformers) to test dtype\n            # and channel order if needed\n            test_chip = self.get_raw_chip(Box.make_square(0, 0, 1))\n\n            raw_channels = list(range(0, test_chip.shape[2]))\n            self.channel_order = channel_order or raw_channels\n            num_channels = len(raw_channels)\n\n            # Transform the chip to get the final dtype\n            test_chip = test_chip[:, :, self.channel_order]\n            for transformer in raster_transformers:\n                test_chip = transformer.transform(test_chip, channel_order)\n\n            self.dtype = test_chip.dtype\n\n            self._set_crs_transformer()\n\n        super().__init__(channel_order, num_channels, raster_transformers)\n\n    @abstractmethod\n    def _download_data(self, tmp_dir):\n        \"\"\"Download any data needed for this Raster Source.\n        Return a single local path representing the image or a VRT of the data.\"\"\"\n        pass\n\n    def get_crs_transformer(self):\n        return self.crs_transformer\n\n    def get_extent(self):\n        return Box(0, 0, self.height, self.width)\n\n    def get_dtype(self):\n        \"\"\"Return the numpy.dtype of this scene\"\"\"\n        return self.dtype\n\n    def _get_chip(self, window):\n        if self.image_dataset is None:\n            raise ActivationError('RasterSource must be activated before use')\n        return load_window(self.image_dataset, window.rasterio_format(),\n                           self.channels)\n\n    def _activate(self):\n        self.image_dataset = rasterio.open(self.imagery_path)\n\n    def _deactivate(self):\n        self.image_dataset.close()\n        self.image_dataset = None\n", "path": "rastervision/data/raster_source/rasterio_source.py"}, {"content": "from rastervision.data.raster_source.rasterio_source import (\n    RasterioRasterSource)\nfrom rastervision.data.crs_transformer.identity_crs_transformer import (\n    IdentityCRSTransformer)\nfrom rastervision.utils.files import download_if_needed\n\n\nclass ImageSource(RasterioRasterSource):\n    def __init__(self, uri, raster_transformers, temp_dir, channel_order=None):\n        self.uri = uri\n        super().__init__(raster_transformers, temp_dir, channel_order)\n\n    def _download_data(self, temp_dir):\n        return download_if_needed(self.uri, self.temp_dir)\n\n    def _set_crs_transformer(self):\n        self.crs_transformer = IdentityCRSTransformer()\n", "path": "rastervision/data/raster_source/image_source.py"}], "after_files": [{"content": "from abc import ABC, abstractmethod\n\nfrom rastervision.rv_config import RVConfig\n\n\nclass Command(ABC):\n    @abstractmethod\n    def run(self, tmp_dir):\n        \"\"\"Run the command.\"\"\"\n        pass\n\n    def set_tmp_dir(self, tmp_dir):\n        self._tmp_dir = tmp_dir\n\n    def get_tmp_dir(self):\n        if hasattr(self, '_tmp_dir') and self._tmp_dir:\n            if isinstance(self._tmp_dir, str):\n                return self._tmp_dir\n            else:\n                return self._tmp_dir.name\n        else:\n            tmp_dir = RVConfig.get_tmp_dir()\n            self.set_tmp_dir(tmp_dir)\n            return tmp_dir.name\n\n\nclass NoOpCommand(Command):\n    \"\"\"Defines a command that does nothing.\n    \"\"\"\n\n    def run(self, tmp_dir):\n        pass\n", "path": "rastervision/command/command.py"}, {"content": "from abc import abstractmethod\nimport tempfile\n\nimport numpy as np\nimport rasterio\nfrom rasterio.enums import (ColorInterp, MaskFlags)\n\nfrom rastervision.data import (ActivateMixin, ActivationError)\nfrom rastervision.data.raster_source import RasterSource\nfrom rastervision.core.box import Box\n\n\ndef load_window(image_dataset, window=None, channels=None, is_masked=False):\n    \"\"\"Load a window of an image from a TIFF file.\n\n    Args:\n        window: ((row_start, row_stop), (col_start, col_stop)) or\n        ((y_min, y_max), (x_min, x_max))\n        channels: An optional list of bands to read.\n        is_masked: If True, read a  masked array from rasterio\n    \"\"\"\n    if is_masked:\n        im = image_dataset.read(window=window, boundless=True, masked=True)\n        im = np.ma.filled(im, fill_value=0)\n    else:\n        im = image_dataset.read(window=window, boundless=True)\n\n    # Handle non-zero NODATA values by setting the data to 0.\n    for channel, nodata in enumerate(image_dataset.nodatavals):\n        if nodata is not None and nodata != 0:\n            im[channel, im[channel] == nodata] = 0\n\n    if channels:\n        im = im[channels, :]\n    im = np.transpose(im, axes=[1, 2, 0])\n    return im\n\n\nclass RasterioRasterSource(ActivateMixin, RasterSource):\n    def __init__(self, raster_transformers, temp_dir, channel_order=None):\n        self.temp_dir = temp_dir\n        self.image_temp_dir = None\n        self.image_dataset = None\n        num_channels = None\n\n        # Activate in order to get information out of the raster\n        with self.activate():\n            colorinterp = self.image_dataset.colorinterp\n            self.channels = [\n                i for i, color_interp in enumerate(colorinterp)\n                if color_interp != ColorInterp.alpha\n            ]\n\n            mask_flags = self.image_dataset.mask_flag_enums\n            self.is_masked = any(\n                [m for m in mask_flags if m != MaskFlags.all_valid])\n\n            self.height = self.image_dataset.height\n            self.width = self.image_dataset.width\n            # Get 1x1 chip (after applying raster transformers) to test dtype\n            # and channel order if needed\n            test_chip = self.get_raw_chip(Box.make_square(0, 0, 1))\n\n            raw_channels = list(range(0, test_chip.shape[2]))\n            self.channel_order = channel_order or raw_channels\n            num_channels = len(raw_channels)\n\n            # Transform the chip to get the final dtype\n            test_chip = test_chip[:, :, self.channel_order]\n            for transformer in raster_transformers:\n                test_chip = transformer.transform(test_chip, channel_order)\n\n            self.dtype = test_chip.dtype\n\n            self._set_crs_transformer()\n\n        super().__init__(channel_order, num_channels, raster_transformers)\n\n    @abstractmethod\n    def _download_data(self, tmp_dir):\n        \"\"\"Download any data needed for this Raster Source.\n        Return a single local path representing the image or a VRT of the data.\"\"\"\n        pass\n\n    def get_crs_transformer(self):\n        return self.crs_transformer\n\n    def get_extent(self):\n        return Box(0, 0, self.height, self.width)\n\n    def get_dtype(self):\n        \"\"\"Return the numpy.dtype of this scene\"\"\"\n        return self.dtype\n\n    def _get_chip(self, window):\n        if self.image_dataset is None:\n            raise ActivationError('RasterSource must be activated before use')\n        return load_window(self.image_dataset, window.rasterio_format(),\n                           self.channels)\n\n    def _activate(self):\n        # Download images to temporary directory and delete it when done.\n        self.image_temp_dir = tempfile.TemporaryDirectory(dir=self.temp_dir)\n        self.imagery_path = self._download_data(self.image_temp_dir.name)\n        self.image_dataset = rasterio.open(self.imagery_path)\n        self._set_crs_transformer()\n\n    def _deactivate(self):\n        self.image_dataset.close()\n        self.image_dataset = None\n        self.image_temp_dir.cleanup()\n        self.image_temp_dir = None\n", "path": "rastervision/data/raster_source/rasterio_source.py"}, {"content": "from rastervision.data.raster_source.rasterio_source import (\n    RasterioRasterSource)\nfrom rastervision.data.crs_transformer.identity_crs_transformer import (\n    IdentityCRSTransformer)\nfrom rastervision.utils.files import download_if_needed\n\n\nclass ImageSource(RasterioRasterSource):\n    def __init__(self, uri, raster_transformers, temp_dir, channel_order=None):\n        self.uri = uri\n        super().__init__(raster_transformers, temp_dir, channel_order)\n\n    def _download_data(self, temp_dir):\n        return download_if_needed(self.uri, temp_dir)\n\n    def _set_crs_transformer(self):\n        self.crs_transformer = IdentityCRSTransformer()\n", "path": "rastervision/data/raster_source/image_source.py"}]}