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
Adds support for file-handlers and file-type in Map and TimeSeries #5193
Conversation
Hello @devanshshukla99! Thanks for updating this PR. There are currently no PEP 8 issues detected in this Pull Request. Cheers! Comment last updated at 2021-07-24 08:00:42 UTC |
@nabobalis I can't find why test |
The hash has changed. You can ignore it. |
db7ee52
to
5782674
Compare
@nabobalis is there any |
https://github.com/sunpy/sunpy/blob/main/sunpy/data/test/goes_truncated_test_goes15.nc |
So just to double check, we want any places where the code cannot use an open file handler to error instead of use the filename and then open the file. |
So, if I understand correctly, we want to support socket file-obj in If so, don't we'll still have to download the file locally for processing considering socket file-obj aren't seekable? |
8b762c8
to
2b27902
Compare
2b27902
to
ac82e7f
Compare
@@ -98,6 +102,11 @@ def test_patterns(self): | |||
assert isinstance(maps, list) | |||
assert ([isinstance(amap, sunpy.map.GenericMap) for amap in maps]) | |||
|
|||
# File-like object | |||
with open(a_fname, "rb") as fd: |
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.
What happens if you pass random binary data to map?
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.
it returns a ValueError
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.
Is there a test for this in this file?
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.
Not currently, should I add one?
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.
If you could.
@@ -59,7 +61,7 @@ def read_file(filepath, filetype=None, **kwargs): | |||
|
|||
Parameters | |||
---------- | |||
filepath : path-like | |||
filepath : `str` or file-like |
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.
Does a pathlib.Path not work?
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.
no it works,
will update👍
Any work on this? Or we could open an issue to support this in future? |
Nothing till now. So, if I understand correctly, we'll have to read the socket fileobj then pass the data to appropriate readers? |
Sure, his use case was makefile which returns a file-like handler. |
Looks doable! |
I think we can bump the socket request from Albert to an issue and leave this PR as it for review. @devanshshukla99, could you rebase this PR for us? |
Hi @devanshshukla99, sorry for the lack of reviews on this PR. I am trying to get someone to have a look but could you also rebase this if you have time? If not, I can do so. |
Apologies from my side too |
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.
Thanks for the work on this @devanshshukla99, sorry it took so long for me to review it. I think it's close, I just think we need to remove the last bit of name checking stuff for file handlers.
@@ -44,6 +45,9 @@ def read(filename, debug=False, **kwargs): | |||
-------- | |||
>>> data = sunpy.io.ana.read(filename) # doctest: +SKIP | |||
""" | |||
if isinstance(filename, io.IOBase): | |||
raise TypeError("Reader does not support file-handler") |
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.
raise TypeError("Reader does not support file-handler") | |
raise TypeError("The ANA reader does not support file handles.") |
@@ -26,6 +27,9 @@ def read(filepath, **kwargs): | |||
pairs : `list` | |||
A list of (data, header) tuples. | |||
""" | |||
if isinstance(filepath, io.IOBase): | |||
raise TypeError("Reader does not support file-handler") |
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.
raise TypeError("Reader does not support file-handler") | |
raise TypeError("The ANA reader does not support file handles.") |
@@ -77,19 +79,24 @@ def read_file(filepath, filetype=None, **kwargs): | |||
----- | |||
Other keyword arguments are passed to the reader used. | |||
""" | |||
filepath = str(pathlib.Path(filepath)) | |||
_filepath = filepath.name if isinstance(filepath, io.IOBase) else filepath |
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.
Not all objects which implement io.IOBase
have a .name
attribute:
>>> import io
>>> isinstance(io.BytesIO(), io.IOBase)
True
>>> io.BytesIO().name
AttributeError: '_io.BytesIO' object has no attribute 'name'
I don't think we should do this at all when dealing with io objects, I think it would be better to work out the type from the magic bytes at the start of the file and not any reference to the filename. (Which already happens if this filename doesn't match anything I think).
@@ -44,6 +44,15 @@ def test_read_file_fits(self): | |||
assert all([isinstance(p[1], | |||
sunpy.io.header.FileHeader) for p in pairs]) | |||
|
|||
# Test file-object |
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.
We should add a test here to check it works as expected with other file objects, something like this:
with open(AIA_171_IMAGE, 'rb') as fd:
fits_bytes = fd.read()
sunpy.io.read_file(io.BytesIO(fits_bytes))
...
eitmap = sunpy.map.Map(a_fname, filetype=pathlib.Path(a_fname).suffix[1:]) | ||
assert isinstance(eitmap, sunpy.map.GenericMap) |
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 aren't really testing this properly here as you are giving it a filename which it can detect the type for. You would be better off giving it a random filename and the type.
(Although it will also use magic bytes to detect file type if the filename doesn't pan out so I am not sure exactly how to make this test fail.)
Description
Fixes #2690
Adds support for file-object and file-type in
sunpy.map.Map
&sunpy.timeseries.TimeSeries
.Currently, the support for
sunpy.timeseries.TimeSeries
is broken