| As of January 1st, 2020, the client library no longer supports Python 2. For more information, please contact supportdescarteslabs.com. For help with porting to Python 3, please visit https://docs.python.org/3/howto/pyporting.html. |
| ---------
Catalog client
- There is an entirely new backend supporting asynchronous uploads of image files and ndarrays with
the catalog client. There are minor changes to the `ImageUpload` class (a new `events` field has subsumed
`errors`, and the `job_id` field has been removed) but the basic interface is unchanged so most
code will keep functioning without any changes.
- It is now possible to cancel image uploads.
- Errors messages are now easier to read.
- Many improvements to the documentation.
- You can now create or retrieve an existing object using the `get_or_create` method.
- Retrieving a `Band` or `Image` by name is now possible by calling `get_band` or `get_image` on the
`Product` instance. You can also use the Product's `named_id` function to get a complete id for
images and bands.
- A new convenience function `make_valid_name` on `Image` and `Band` classes will return a sanitized
name without invalid characters.
- A new property `ATTRIBUTES` enumerates which attributes are available for a specific catalog object.
- Trying to set an attribute that does not exist will now raise `AttributeError`.
- `update_related_objects_permissions()` should no longer fail with a JSON serialization error.
- Setting a read-only attribute will now raise an `AttributeValidationError`.
- Saving a new object while one with the same id already exists will now raise a `ConflictError`
instead of `BadRequestError`.
- If a retrieved object has since been deleted from the catalog, saving any changes or trying to
reload it will now raise a `DeletedObjectError`.
- Resolution fields now accept string values such as "10m" or "0.008 degrees". If the value cannot
be parsed, an `AttributeValidationError` will be raised.
- Changes to the `extra_properties` attribute are now tracked correctly.
Packaging
- This release no longer supports Python 2.
- This package is now distributed as a Python 3 wheel which will speed up installation.
Workflows (channel `v0-11`) - Added
- **Handling of missing data** via empty ImageCollections
- `ImageCollection.from_id` returns an empty ImageCollection if no data exist for the given time/place, rather than an error
- `ImageCollection.filter` returns an empty ImageCollection if the predicate is False for every Image, rather than an error
- `Image.replace_empty_with` and `ImageCollection.replace_empty_with` for explicitly filling in missing data
- See the [Workflows guide](https://docs.descarteslabs.com/guides/workflows.html) for more information
- **Docstrings and examples** on every class and function!
- **Assigning new metadata to Image properties** & bandinfo: `Image.with_properties()`, `Image.with_bandinfo()`
- Interactive map: **colorbar legends** on layers with colormaps (requires matplotlib)
- **`Dict.from_pairs`**: construct a Dict from a sequence of key-value pairs
- Map displays a **fullscreen button** by default (**[breaking]** if your code adds one, you'll now get two)
- **`wf.concat`** for concatentating `Image` and `ImageCollection` objects
- `ImageCollection.concat` now accepts `Image` objects; new `Image.concat` accepts `Image` or `ImageCollection`
- **`ImageCollection.mosaic()`**
- `FeatureCollection.sorted()`, `FeatureCollection.length()`, `FeatureCollection.__reversed__()`
- `GeometryCollection.length()`, `GeometryCollection.__reversed__()`
Workflows - Changed
- **`wf.zip` now supports `ImageCollection`**, `FeatureCollection`, `GeometryCollection` as well as `List` and `Str`
- **Get a GeoContext for the current bounds of the map in any resolution, shape, or CRS** (including `"utm"`, which automatically picks the right UTM zone for you) with `wf.map.geocontext`. Also now returns a Scenes GeoContext for better introspection and use with Raster.
- Better backend type-checking displays the possible arguments for most functions if called incorrectly
- `arr_shape` included when calling `wf.GeoContext.compute()`
- More readable errors when communication with the backend fails
- Interactive map: layout handles being resized, for example setting `wf.map.layout.height = '1000px'`
- `Any` is no longer callable; `Any.cast` encouraged
- `remove_layer` and `clear_layers` moved from `wf.interactive.MapApp` class to `wf.interactive.Map` (non-breaking change)
- **[possibly breaking]** band renaming in binary operators only occurs when broadcasting: `red + red` is just `red`, rather than `red_add_red`. `red + blue` is still `red_add_blue`. Code which depends on accessing bands by name may need to change.
Workflows - Fixed
- `wf.where` propagates masks correctly, and handles metadata correctly with multi-band inputs
- `processing_level="surface"` actually returns surface-reflectance-processed imagery
- `ImageCollection.sorted()` works properly
- Viewing global-extent WGS84 images on the Workflows map no longer causes errors
- `List` proxytype no longer infinitely iterable in Python
- Repeated use of `axis="bands"` works correctly
- `ImageCollection.from_images` correctly aligns the bands of the inputs
- Numeric casting (`wf.Int(wf.Float(2.2))`) works as expected
- More descriptive error when constructing an invalid `wf.Datetime`
- Computing a single `Bool` value derived from imagery works correctly