7
7
import time
8
8
from xml .etree import ElementTree
9
9
from datetime import datetime , timezone
10
+ import keyring
10
11
11
12
# 2. third party imports
12
13
import astropy .units as u
17
18
import numpy as np
18
19
19
20
# 3. local imports - use relative imports
20
- # commonly required local imports shown below as example
21
- # all Query classes should inherit from BaseQuery.
22
- from ..query import BaseQuery
23
- # has common functions required by most modules
21
+ from ..query import QueryWithLogin
24
22
from ..utils import commons
25
23
# prepend_docstr is a way to copy docstrings between methods
26
24
from ..utils import prepend_docstr_nosections
27
25
# async_to_sync generates the relevant query tools from _async methods
28
26
from ..utils import async_to_sync
29
27
# import configurable items declared in __init__.py
30
28
from . import conf
29
+ from ..exceptions import LoginError
31
30
32
31
# export all the public classes and methods
33
32
__all__ = ['Casda' , 'CasdaClass' ]
34
33
35
34
36
35
@async_to_sync
37
- class CasdaClass (BaseQuery ):
36
+ class CasdaClass (QueryWithLogin ):
38
37
39
38
"""
40
39
Class for accessing ASKAP data through the CSIRO ASKAP Science Data Archive (CASDA). Typical usage:
@@ -46,18 +45,62 @@ class CasdaClass(BaseQuery):
46
45
URL = conf .server
47
46
TIMEOUT = conf .timeout
48
47
POLL_INTERVAL = conf .poll_interval
48
+ USERNAME = conf .username
49
49
_soda_base_url = conf .soda_base_url
50
+ _login_url = conf .login_url
50
51
_uws_ns = {'uws' : 'http://www.ivoa.net/xml/UWS/v1.0' }
51
52
52
- def __init__ (self , user = None , password = None ):
53
+ def __init__ (self ):
53
54
super ().__init__ ()
54
- if user is None :
55
- self ._authenticated = False
55
+
56
+ def _login (self , * , username = None , store_password = False ,
57
+ reenter_password = False ):
58
+ """
59
+ login to non-public data as a known user
60
+
61
+ Parameters
62
+ ----------
63
+ username : str, optional
64
+ Username to the CASDA archive, uses ATNF OPAL credentials. If not given, it should be
65
+ specified in the config file.
66
+ store_password : bool, optional
67
+ Stores the password securely in your keyring. Default is False.
68
+ reenter_password : bool, optional
69
+ Asks for the password even if it is already stored in the
70
+ keyring. This is the way to overwrite an already stored passwork
71
+ on the keyring. Default is False.
72
+ """
73
+
74
+ if username is None :
75
+ if not self .USERNAME :
76
+ raise LoginError ("If you do not pass a username to login(), "
77
+ "you should configure a default one!" )
78
+ else :
79
+ username = self .USERNAME
80
+
81
+ # Get password from keyring or prompt
82
+ password , password_from_keyring = self ._get_password (
83
+ "astroquery:casda.csiro.au" , username , reenter = reenter_password )
84
+
85
+ # Login to CASDA to test credentals
86
+ log .info ("Authenticating {0} on CASDA ..." .format (username ))
87
+ auth = (username , password )
88
+ login_response = self ._request ("GET" , self ._login_url , auth = auth ,
89
+ timeout = self .TIMEOUT , cache = False )
90
+ authenticated = login_response .status_code == 200
91
+
92
+ if authenticated :
93
+ log .info ("Authentication successful!" )
94
+ self .USERNAME = username
95
+ self ._auth = (username , password )
96
+
97
+ # When authenticated, save password in keyring if needed
98
+ if password_from_keyring is None and store_password :
99
+ keyring .set_password ("astroquery:casda.csiro.au" , username , password )
56
100
else :
57
- self ._authenticated = True
58
- # self._user = user
59
- # self._password = password
60
- self ._auth = (user , password )
101
+ log .exception ("Authentication failed" )
102
+
103
+ return authenticated
61
104
62
105
def query_region_async (self , coordinates , radius = 1 * u .arcmin , height = None , width = None ,
63
106
get_query_payload = False , cache = True ):
@@ -274,7 +317,7 @@ def stage_data(self, table, verbose=False):
274
317
275
318
return self ._complete_job (job_url , verbose )
276
319
277
- def cutout (self , table , * , coordinates = None , radius = None , height = None ,
320
+ def cutout (self , table , * , coordinates = None , radius = 1 * u . arcmin , height = None ,
278
321
width = None , band = None , channel = None , verbose = False ):
279
322
"""
280
323
Produce a cutout from each selected file. All requests for data must use authentication. If you have access to
0 commit comments