Skip to content

ENH: Create psm3.py #694

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

Merged
merged 20 commits into from
May 3, 2019
Merged

ENH: Create psm3.py #694

merged 20 commits into from
May 3, 2019

Conversation

mikofski
Copy link
Member

@mikofski mikofski commented Apr 25, 2019

initial concept for psm3 reader

  • Closes make new PSM reader for iotools #592
  • I am familiar with the contributing guidelines.
  • Fully tested. Added and/or modified tests to ensure correct behavior for all reasonable inputs. Tests (usually) must pass on the TravisCI and Appveyor testing services.
  • Updates entries to docs/sphinx/source/api.rst for API changes.
  • Adds description and name entries in the appropriate docs/sphinx/source/whatsnew file for all changes.
  • Code quality and style is sufficient. Passes LGTM and SticklerCI checks.
  • New code is fully documented. Includes sphinx/numpydoc compliant docstrings and comments in the code where necessary.
  • Pull request is nearly complete and ready for detailed review.

initial concept for psm3 reader
@cwhanse
Copy link
Member

cwhanse commented Apr 25, 2019

@mikofski how does this pass lat / long ?

@mikofski
Copy link
Member Author

@cwhanse the arguments for get_psm3() are latitude, longitude, tmy, and interval - tmy defaults to 'tmy' and interval defaults to 60

@cwhanse
Copy link
Member

cwhanse commented Apr 25, 2019

Aha I see it now.

@mikofski
Copy link
Member Author

There are a lot of typos in here, but it does work, I'll fix the typos and upload a test ASAP

* need to strip all leading whitespace, and only one whitespace between,
and longitude is first, then latitude
* fix list() not []
* fix ATTRIBUTES and URL
* coerce all to float, clean up types in header, cast datevec columns to
int, create datetimeindex from datevec columns, set index, get errors
from json when returning HTTPError

Signed-off-by: Mark Mikofski <[email protected]>
@mikofski
Copy link
Member Author

mikofski commented Apr 27, 2019

Bummer, I think the pandas.to_datetime() API changed after pandas-0.16 so the python-27-min build fails. I'll try to decorate test_psm3 with @needs_pandas_0_22

@mikofski mikofski changed the title WIP: ENH: Create psm3.py ENH: Create psm3.py Apr 28, 2019
@mikofski
Copy link
Member Author

How's it looking? Ready?

mikofski added 4 commits May 1, 2019 22:44
* other params full name and affiliation are kwargs
* set reason to pvlib something as suggested by NREL
* catch some errors, like 403 forbidden, are in content, not json, only
some errors like bad well known text WKT gemetry are in JSON
* use python-2 json decode error
* add another test to capture both bad API key and bad WKT
* add note on how to register for key, why they need email, and when it
would be used, and warning about DEMO_KEY being rate limited

Signed-off-by: Mark Mikofski <[email protected]>
@mikofski
Copy link
Member Author

mikofski commented May 2, 2019

@cwhanse and @wholmgren not sure what's up with codecov, it won't even let me log in, everything else is green

# check errors
with pytest.raises(HTTPError):
psm3.get_psm3(LATITUDE, LONGITUDE, api_key='BAD', email=PVLIB_EMAIL)
with pytest.raises(HTTPError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this one fail?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • api_key="BAD" fails because the response is HTTP/1.1 403 Forbidden and there's a long error message in the content, no JSON, that says something like, "please go to NREL developer network and register for a key"
  • Bristol-UK fails because PSM3 only works in the US, maybe South America, and I think some parts of India perhaps around Chennai? I can confirm - perhaps this should be a warning in the docstring?

perhaps I should add some more comments here to explain these tests - like I did here - for future devs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BAD was self explanatory. I don't think we need to test that it fails outside the US. Not our problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PSM3 has data in a lat/long rectangle around the lower 48 states, so there's coverage in northern Mexico for example. But it has a coastline filter and excludes data in the Gulf of Mexico. I think we should test for failure at lat/long where PSM3 does not have data.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does PSM3 return a sensible error if lat/lon outside of its area?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from get_psm3 import get_psm3

import api_keys

MY_KEY = api_keys.get_api_key('nsrdb')

for lat, lon in zip([25, 25, 25], [-125, -124.5, -124]):
    try:
        meta, data = get_psm3(lat, lon, names='tmy', interval=60,
                              api_key=MY_KEY)
    except Exception as e:
        print("{}, {}: ".format(lat, lon), e)

Returns

25, -125:  ["The 'wkt' parameter did not match any known data points."]
25, -124.5:  Expecting value: line 1 column 1 (char 0)
25, -124:  Expecting value: line 1 column 1 (char 0)

The first line is what I expect, the next 2 are json decoding errors that puzzle me.

Copy link
Member

@cwhanse cwhanse May 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, I suspect the 2nd and 3rd messages are empty responses because of the once-per-2second throttle, so raise requests.HTTPError(response.json()['errors']) is throwing the exception about Expecting value:...

Confirmed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

["The 'wkt' parameter did not match any known data points."]

This could be confusing to pvlib users because we're asking the to specify lat/lon instead of API. So I'm ok with catching this in the function and raising a more descriptive error about lat/lon.

mikofski added 2 commits May 2, 2019 10:44
* in raise docstring, change "returns" to "raises", and clarify that
 either r.json()['errors'] or r.content is the exception arg depending
 on the type of HTTP error, and give examples
* add warning in docstring that data are limited to NSRDB locations
* comment on WKT formatting and add TODO to consider making a
 format_WKT() function in tools.py one day
* add response kwarg to HTTPError for better user exception handling
* in test_psm3 add comments to clarify the tests for errors and add two
 more test for bad "names" and interval args
@mikofski
Copy link
Member Author

mikofski commented May 2, 2019

I figured out why codecov is complaining, psm3.py has only 95% coverage because there are two lines in the python compatible import of JSONDecodeError that I can't test - this is only used in Python-3 and it's not covered by either six or python-future afaik. :(
image

the JSONDecodeError is used to get the "errors" field out of the response if it exists, other times though the error message is in the content only. We can safely remove the Python-2 compatibility when we officially drop Python-2

@wholmgren
Copy link
Member

@mikofski thanks for looking into the coverage. No need to fix it.

@mikofski
Copy link
Member Author

mikofski commented May 2, 2019

Is it okay? 🚀 I fixed the defaults, but I don't have time to check the variants for "names", has anyone else already done this? Anymore comments?

@mikofski
Copy link
Member Author

mikofski commented May 3, 2019

@cwhanse do you approve of the changes? merge at will 🚀

@cwhanse
Copy link
Member

cwhanse commented May 3, 2019

@cwhanse do you approve of the changes? merge at will 🚀

@mikofski OK as is, would be nice to add timeout and retry logic to the request.get, but we can do that later if you want to open an issue.

@mikofski
Copy link
Member Author

mikofski commented May 3, 2019

timeout and retry logic to the requests.get

I don't feel comfortable adding that though. I think current handling is sufficient, and I think anything further could and should be handled by the user because it may differ. Maybe you could add that as an issue?

My preference is for smaller methods that are supplemented later by more features as needed, versus adding a lot of functionality up front that might not be required.

@wholmgren wholmgren added this to the 0.6.2 milestone May 3, 2019
@wholmgren wholmgren merged commit a156e6c into pvlib:master May 3, 2019
@mikofski mikofski deleted the patch-1 branch May 3, 2019 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

make new PSM reader for iotools
4 participants