Skip to content

Commit 1eac524

Browse files
add tom_client class to access TOM
1 parent 4dc41ce commit 1eac524

File tree

3 files changed

+107
-61
lines changed

3 files changed

+107
-61
lines changed

resspect/fit_lightcurves.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
from resspect.lightcurves_utils import find_available_key_name_in_header
3939
from resspect.lightcurves_utils import PLASTICC_TARGET_TYPES
4040
from resspect.lightcurves_utils import PLASTICC_RESSPECT_FEATURES_HEADER
41+
from resspect.tom_client import TomClient
4142

42-
__all__ = ["fit_snpcc", "fit_plasticc", "fit_TOM"]
43+
__all__ = ["fit_snpcc", "fit_plasticc", "fit_TOM", "request_TOM_data"]
4344

4445

4546
FEATURE_EXTRACTOR_MAPPING = {
@@ -296,7 +297,14 @@ def fit_TOM(data_dic: dict, features_file: str,
296297
write_features_to_output_file(
297298
light_curve_data, snpcc_features_file)
298299
logging.info("Features have been saved to: %s", features_file)
299-
300+
301+
def request_TOM_data(url: str = "https://desc-tom-2.lbl.gov", username: str = None,
302+
passwordfile: str = None, password: str = None):
303+
tom = TomClient(url = url, username = username, passwordfile = passwordfile,
304+
password = password)
305+
res = tom.request( 'POST', 'elasticc2/gethotsne/10/' )
306+
data_dic = res.json()
307+
return data_dic
300308

301309

302310
def main():

resspect/request_webservice_elasticc.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

resspect/tom_client.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2020 resspect software
2+
# Author: Rob Knop
3+
#
4+
# created on 12 March 2024
5+
#
6+
# Licensed GNU General Public License v3.0;
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# https://www.gnu.org/licenses/gpl-3.0.en.html
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
import requests
19+
20+
class TomClient:
21+
"""A thin class that supports sending requests via "requests" to the DESC tom.
22+
23+
Usage: initialize one of these, giving it the url, your TOM
24+
username, and either your TOM password, or a file that has your TOM
25+
password in it:
26+
27+
tc = TomClient( username='rknop', passwordfile='/home/raknop/secrets/tom_rknop_passwd' )
28+
29+
(You can give it a url with url=; it defaults to https://desc-tom.lbl.gov.)
30+
31+
Thereafter, just do something like
32+
33+
res = tc.request( "POST", "elasticc2/ppdbdiaobject/55772173" )
34+
35+
and res will come back with a string that you can load into JSON
36+
that will have all the fun data about PPDBDiaObject number 55772173.
37+
38+
tc.request is just a thin front-end to python requests.request. The
39+
only reason to use this client rather than the python requests
40+
module directly is that this class takes care of the stupid fiddly
41+
bits of getting some headers that django demands set up right in the
42+
request object when you log in.
43+
44+
"""
45+
46+
def __init__( self, url="https://desc-tom.lbl.gov", username=None, password=None, passwordfile=None, connect=True ):
47+
self._url = url
48+
self._username = username
49+
self._password = password
50+
self._rqs = None
51+
if self._password is None:
52+
if passwordfile is None:
53+
raise RuntimeError( "Must give either password or passwordfile. " )
54+
with open( passwordfile ) as ifp:
55+
self._password = ifp.readline().strip()
56+
57+
if connect:
58+
self.connect()
59+
60+
def connect( self ):
61+
self._rqs = requests.session()
62+
res = self._rqs.get( f'{self._url}/accounts/login/' )
63+
if res.status_code != 200:
64+
raise RuntimeError( f"Got status {res.status_code} from first attempt to connect to {self._url}" )
65+
res = self._rqs.post( f'{self._url}/accounts/login/',
66+
data={ 'username': self._username,
67+
'password': self._password,
68+
'csrfmiddlewaretoken': self._rqs.cookies['csrftoken'] } )
69+
if res.status_code != 200:
70+
raise RuntimeError( f"Failed to log in; http status: {res.status_code}" )
71+
if 'Please enter a correct' in res.text:
72+
# This is a very cheesy attempt at checking if the login failed.
73+
# I haven't found clean documentation on how to log into a django site
74+
# from an app like this using standard authentication stuff. So, for
75+
# now, I'm counting on the HTML that happened to come back when
76+
# I ran it with a failed login one time. One of these days I'll actually
77+
# figure out how Django auth works and make a version of /accounts/login/
78+
# designed for use in API scripts like this one, rather than desgined
79+
# for interactive users.
80+
raise RuntimeError( "Failed to log in. I think. Put in a debug break and look at res.text" )
81+
self._rqs.headers.update( { 'X-CSRFToken': self._rqs.cookies['csrftoken'] } )
82+
83+
def request( self, method="GET", page=None, **kwargs ):
84+
"""Send a request to the TOM
85+
86+
method : a string with the HTTP method ("GET", "POST", etc.)
87+
88+
page : the page to get; this is the URL but with the url you
89+
passed to the constructor removed. So, if you wanted to get
90+
https://desc-tom.lbl.gov/elasticc, you'd pass just "elasticc"
91+
here.
92+
93+
**kwargs : additional keyword arguments are passed on to
94+
requests.request
95+
96+
"""
97+
return self._rqs.request( method=method, url=f"{self._url}/{page}", **kwargs )

0 commit comments

Comments
 (0)