-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for s3 buckets in OLCI and ABI l1 readers #1439
Changes from 22 commits
0ef06c0
36ff447
47a4dcf
973ca18
f04c137
dedeaea
8afdb38
445fe1b
02ff1f8
407fa63
719386f
9c5b55f
034b521
b2956f2
2b3f026
4bffac3
eb7b9c2
4dd8b20
ecdcbce
be6c757
4e3b7b5
81505c6
d7d227b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# Copyright (c) 2020 Satpy developers | ||
# | ||
# This file is part of satpy. | ||
# | ||
# satpy is free software: you can redistribute it and/or modify it under the | ||
# terms of the GNU General Public License as published by the Free Software | ||
# Foundation, either version 3 of the License, or (at your option) any later | ||
# version. | ||
# | ||
# satpy is distributed in the hope that it will be useful, but WITHOUT ANY | ||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License along with | ||
# satpy. If not, see <http://www.gnu.org/licenses/>. | ||
"""Backports and compatibility fixes for satpy.""" | ||
|
||
from functools import lru_cache | ||
|
||
|
||
def cached_property(func): | ||
"""Port back functools.cached_property.""" | ||
return property(lru_cache(maxsize=None)(func)) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
import os | ||
import warnings | ||
from datetime import datetime, timedelta | ||
from functools import total_ordering | ||
|
||
import yaml | ||
|
||
|
@@ -519,7 +520,7 @@ def load_readers(filenames=None, reader=None, reader_kwargs=None, | |
|
||
|
||
def _get_reader_kwargs(reader, reader_kwargs): | ||
"""Helper for load_readers to form reader_kwargs. | ||
"""Help load_readers to form reader_kwargs. | ||
|
||
Helper for load_readers to get reader_kwargs and | ||
reader_kwargs_without_filter in the desirable form. | ||
|
@@ -538,3 +539,73 @@ def _get_reader_kwargs(reader, reader_kwargs): | |
reader_kwargs_without_filter[k].pop('filter_parameters', None) | ||
|
||
return (reader_kwargs, reader_kwargs_without_filter) | ||
|
||
|
||
@total_ordering | ||
class FSFile(os.PathLike): | ||
"""Implementation of a PathLike file object, that can be opened. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused by this line. Is it a file object or a path object? If it's a file object it's already opened? I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a path indeed, but can be opened to return a file object. |
||
|
||
This is made to be used in conjuction with fsspec or s3fs. For example:: | ||
|
||
from satpy import Scene | ||
|
||
import fsspec | ||
filename = 'noaa-goes16/ABI-L1b-RadC/2019/001/17/*_G16_s20190011702186*' | ||
|
||
the_files = fsspec.open_files("simplecache::s3://" + filename, s3={'anon': True}) | ||
|
||
from satpy.readers import FSFile | ||
fs_files = [FSFile(open_file) for open_file in the_files] | ||
|
||
scn = Scene(filenames=fs_files, reader='abi_l1b') | ||
scn.load(['true_color_raw']) | ||
|
||
""" | ||
|
||
def __init__(self, file, fs=None): | ||
"""Initialise the FSFile instance. | ||
|
||
*file* can be string or an fsspec.OpenFile instance. In the latter case, the follow argument *fs* has no effect. | ||
*fs* can be None or a fsspec filesystem instance. | ||
""" | ||
try: | ||
self._file = file.path | ||
self._fs = file.fs | ||
except AttributeError: | ||
self._file = file | ||
self._fs = fs | ||
|
||
def __str__(self): | ||
"""Return the string version of the filename.""" | ||
return self._file | ||
|
||
def __fspath__(self): | ||
"""Comply with PathLike.""" | ||
return self._file | ||
|
||
def __repr__(self): | ||
"""Representation of the object.""" | ||
return '<FSFile "' + str(self._file) + '">' | ||
|
||
def open(self): | ||
"""Open the file. | ||
|
||
This is read-only. | ||
""" | ||
try: | ||
return self._fs.open(self._file) | ||
except AttributeError: | ||
return open(self._file) | ||
|
||
def __lt__(self, other): | ||
"""Implement ordering.""" | ||
return os.fspath(self) < os.fspath(other) | ||
|
||
|
||
def open_file_or_filename(unknown_file_thing): | ||
"""Try to open the *unknown_file_thing*, otherwise return the filename.""" | ||
try: | ||
f_obj = unknown_file_thing.open() | ||
except AttributeError: | ||
f_obj = unknown_file_thing | ||
return f_obj |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,9 +20,8 @@ | |
from abc import ABCMeta | ||
|
||
import numpy as np | ||
from pathlib import PurePath | ||
|
||
from pyresample.geometry import SwathDefinition | ||
|
||
from satpy.dataset import combine_metadata | ||
|
||
|
||
|
@@ -31,10 +30,7 @@ class BaseFileHandler(metaclass=ABCMeta): | |
|
||
def __init__(self, filename, filename_info, filetype_info): | ||
"""Initialize file handler.""" | ||
if isinstance(filename, PurePath): | ||
self.filename = str(filename) | ||
else: | ||
self.filename = filename | ||
self.filename = filename | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change will break pathlib objects for all other readers right? (assuming the low-level I/O library doesn't support them) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That said, I'm ok with this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably yes... Is this bad? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @gerritholl was the first user to point out that Satpy didn't work with pathlib objects so he should maybe make the final decision. It probably isn't great that this breaks it for all other readers, but I'm not sure how many readers need strings for their lower-level I/O libraries either. |
||
self.navigation_reader = None | ||
self.filename_info = filename_info | ||
self.filetype_info = filetype_info | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I was thinking putting the import of cached_property in here too. That way I could do
from satpy._compat import cached_property
with no try/except in my reader module. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you got it.