adss 1.26__tar.gz → 1.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: adss
3
- Version: 1.26
3
+ Version: 1.28
4
4
  Summary: Astronomical Data Smart System
5
5
  Author-email: Gustavo Schwarz <gustavo.b.schwarz@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/schwarzam/adss
@@ -33,26 +33,3 @@ cd adss
33
33
  pip install .
34
34
  ```
35
35
 
36
- ## Tutorials
37
-
38
- We provide a set of tutorials to help you get started with the library:
39
-
40
- Perform a simple query to retrieve the available tables from the service, print the columns of a table, set the columns and constraints to perform a query and retrieve the data.
41
- - [Basic API](docs/basic_api.md)
42
-
43
- Learn the difference between sync and async queries and when to use each one.
44
- - [Methods of query](docs/sync_async.md)
45
-
46
- Perform a raw query to the service.
47
- - [Raw Query](docs/perform_raw_queries.md)
48
-
49
- Perform a match between two database tables and a match between a database table and a user input table.
50
- - [Match API](docs/match_api.md)
51
-
52
- Perform a match between a database table and a user input table.
53
- - [User Table Input Match](docs/usertable_input_match.md)
54
-
55
-
56
- ## Contributing
57
-
58
- We welcome contributions to this project.
adss-1.28/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # ADSS
2
+ Astronomical Data Smart System
3
+
4
+ ADSS is a database/server project hosted at CBPF (Brazilian Center for Research in Physics) that provides access to astronomical data from different surveys.
5
+
6
+ This repository provides a set of tools for querying astronomical ADSS services using ADQL. You can perform cone searches, cross-match queries between tables, and even cross-match against user-supplied data. The library supports both synchronous and asynchronous query execution.
7
+
8
+ ## Instalation
9
+
10
+ ```bash
11
+ pip install adss
12
+ ```
13
+
14
+ or
15
+
16
+ ```bash
17
+ git clone https://github.com/schwarzam/adss.git
18
+ cd adss
19
+ pip install .
20
+ ```
21
+
@@ -5,6 +5,7 @@ from adss.exceptions import AuthenticationError
5
5
  from adss.utils import handle_response_errors
6
6
  from adss.models.user import User
7
7
 
8
+ import os
8
9
 
9
10
  class Auth:
10
11
  """
@@ -118,4 +119,44 @@ class Auth:
118
119
 
119
120
  def refresh_user_info(self, **kwargs) -> User:
120
121
  self.current_user = self._get_current_user(**kwargs)
121
- return self.current_user
122
+ return self.current_user
123
+
124
+ def download(
125
+ self,
126
+ method: str,
127
+ url: str,
128
+ headers: Optional[Dict[str, str]] = None,
129
+ auth_required: bool = False,
130
+ **kwargs
131
+ ) -> requests.Response:
132
+ """
133
+ Like request(), but always streams the body.
134
+ Caller can iterate over response.iter_content() or
135
+ call response.raw.read() for large files.
136
+
137
+ Signature is identical to request(), so you can just
138
+ swap `request` -> `download` in call sites.
139
+ """
140
+ if auth_required and not self.is_authenticated():
141
+ raise AuthenticationError("Authentication required for this request")
142
+
143
+ # Prepend base_url if needed
144
+ if not url.startswith(('http://', 'https://')):
145
+ url = f"{self.base_url}/{url.lstrip('/')}"
146
+
147
+ # Merge headers
148
+ final_headers = self._get_auth_headers()
149
+ if headers:
150
+ final_headers.update(headers)
151
+
152
+ # Apply verify_ssl unless overridden
153
+ if 'verify' not in kwargs:
154
+ kwargs['verify'] = self.verify_ssl
155
+
156
+ # Force streaming
157
+ kwargs['stream'] = True
158
+
159
+ resp = requests.request(method, url, headers=final_headers, **kwargs)
160
+ handle_response_errors(resp) # fail fast on HTTP errors
161
+
162
+ return resp
@@ -206,6 +206,7 @@ class ADSSClient:
206
206
  file: Optional[Union[str, BinaryIO]] = None,
207
207
  table_name: Optional[str] = None,
208
208
  timeout: Optional[int] = None,
209
+ verbose: bool = False,
209
210
  **kwargs) -> QueryResult:
210
211
  """
211
212
  Execute a query asynchronously and wait for the results.
@@ -221,7 +222,7 @@ class ADSSClient:
221
222
  Returns:
222
223
  QueryResult object containing the query data and metadata
223
224
  """
224
- return self.queries.execute_and_wait(query_text, mode, file, table_name, timeout, **kwargs)
225
+ return self.queries.execute_and_wait(query_text, mode, file, table_name, timeout, verbose, **kwargs)
225
226
 
226
227
  def get_query_history(self, limit: int = 50, **kwargs) -> List[Query]:
227
228
  """
@@ -319,7 +319,7 @@ class LuptonImagesEndpoint:
319
319
  if output_path:
320
320
  with open(output_path, 'wb') as f:
321
321
  f.write(resp.content)
322
- return output_path
322
+ return resp.content
323
323
  return resp.content
324
324
 
325
325
  except Exception as e:
@@ -392,7 +392,7 @@ class LuptonImagesEndpoint:
392
392
  if output_path:
393
393
  with open(output_path, 'wb') as f:
394
394
  f.write(resp.content)
395
- return output_path
395
+ return resp.content
396
396
  return resp.content
397
397
 
398
398
  except Exception as e:
@@ -439,7 +439,7 @@ class LuptonImagesEndpoint:
439
439
  if output_path:
440
440
  with open(output_path, 'wb') as f:
441
441
  f.write(resp.content)
442
- return output_path
442
+ return resp.content
443
443
  return resp.content
444
444
 
445
445
  except Exception as e:
@@ -494,7 +494,7 @@ class LuptonImagesEndpoint:
494
494
  if output_path:
495
495
  with open(output_path, 'wb') as f:
496
496
  f.write(resp.content)
497
- return output_path
497
+ return resp.content
498
498
  return resp.content
499
499
 
500
500
  except Exception as e:
@@ -515,7 +515,7 @@ class StampImagesEndpoint:
515
515
  zmin: Optional[float] = None, zmax: Optional[float] = None,
516
516
  output_path: Optional[str] = None,
517
517
  **kwargs) -> Union[bytes, str]:
518
- url = f"{self.base_url}/adss/v1/images/stamp_images/files/{file_id}/stamp"
518
+ url = f"{self.base_url}/adss/v1/images/collections/{file_id}/stamp"
519
519
  try:
520
520
  headers = self.auth_manager._get_auth_headers()
521
521
  except:
@@ -550,7 +550,7 @@ class StampImagesEndpoint:
550
550
  if output_path:
551
551
  with open(output_path, 'wb') as f:
552
552
  f.write(resp.content)
553
- return output_path
553
+ return resp.content
554
554
  return resp.content
555
555
 
556
556
  except Exception as e:
@@ -615,7 +615,7 @@ class StampImagesEndpoint:
615
615
  if output_path:
616
616
  with open(output_path, 'wb') as f:
617
617
  f.write(resp.content)
618
- return output_path
618
+ return resp.content
619
619
  return resp.content
620
620
 
621
621
  except Exception as e:
@@ -665,7 +665,7 @@ class StampImagesEndpoint:
665
665
  if output_path:
666
666
  with open(output_path, 'wb') as f:
667
667
  f.write(resp.content)
668
- return output_path
668
+ return resp.content
669
669
  return resp.content
670
670
 
671
671
  except Exception as e:
@@ -717,7 +717,7 @@ class StampImagesEndpoint:
717
717
  if output_path:
718
718
  with open(output_path, 'wb') as f:
719
719
  f.write(resp.content)
720
- return output_path
720
+ return resp.content
721
721
  return resp.content
722
722
 
723
723
  except Exception as e:
@@ -781,7 +781,7 @@ class TrilogyImagesEndpoint:
781
781
  if output_path:
782
782
  with open(output_path, 'wb') as f:
783
783
  f.write(resp.content)
784
- return output_path
784
+ return resp.content
785
785
  return resp.content
786
786
 
787
787
  except Exception as e:
@@ -886,7 +886,7 @@ class TrilogyImagesEndpoint:
886
886
  if output_path:
887
887
  with open(output_path, 'wb') as f:
888
888
  f.write(resp.content)
889
- return output_path
889
+ return resp.content
890
890
  return resp.content
891
891
 
892
892
  except Exception as e:
@@ -237,7 +237,7 @@ class QueriesEndpoint:
237
237
  except Exception as e:
238
238
  raise QueryExecutionError(f"Failed to get query status: {str(e)}")
239
239
 
240
- def get_results(self, query_id: str, **kwargs) -> QueryResult:
240
+ def get_results(self, query_id: str, verbose: bool = False, **kwargs) -> QueryResult:
241
241
  """
242
242
  Get the results of a completed asynchronous query.
243
243
 
@@ -269,12 +269,14 @@ class QueriesEndpoint:
269
269
 
270
270
  # Get the results
271
271
  try:
272
- response = self.auth_manager.request(
272
+ response = self.auth_manager.download(
273
273
  method="GET",
274
274
  url=f"/adss/async/{query_id}/results",
275
275
  auth_required=True,
276
276
  **kwargs
277
277
  )
278
+ if verbose:
279
+ print('Results fetched.')
278
280
  handle_response_errors(response)
279
281
 
280
282
  # Parse Parquet data
@@ -350,10 +352,8 @@ class QueriesEndpoint:
350
352
  QueryExecutionError: If the query fails
351
353
  """
352
354
  start_time = time.time()
353
-
354
355
  while True:
355
356
  query = self.get_status(query_id, **kwargs)
356
-
357
357
  if query.is_complete:
358
358
  return query
359
359
 
@@ -368,6 +368,7 @@ class QueriesEndpoint:
368
368
  file: Optional[Union[str, BinaryIO]] = None,
369
369
  table_name: Optional[str] = None,
370
370
  timeout: Optional[int] = None,
371
+ verbose: bool = False,
371
372
  poll_interval: int = 2,
372
373
  **kwargs) -> QueryResult:
373
374
  """
@@ -390,9 +391,13 @@ class QueriesEndpoint:
390
391
  TimeoutError: If the query doesn't complete within the timeout
391
392
  """
392
393
  # Start async query
394
+ if verbose:
395
+ print('Starting asynchronous query...')
393
396
  query_obj = self.execute_async(query, mode, file, table_name, **kwargs)
394
397
 
395
398
  # Wait for completion
399
+ if verbose:
400
+ print(f'Waiting for query {query_obj.id} to complete...')
396
401
  completed_query = self.wait_for_completion(query_obj.id, timeout, poll_interval, **kwargs)
397
402
 
398
403
  if completed_query.is_failed:
@@ -402,7 +407,9 @@ class QueriesEndpoint:
402
407
  )
403
408
 
404
409
  # Get results
405
- return self.get_results(completed_query.id, **kwargs)
410
+ if verbose:
411
+ print('Fetching results...')
412
+ return self.get_results(completed_query.id, verbose, **kwargs)
406
413
 
407
414
  def get_history(self, limit: int = 50, **kwargs) -> List[Query]:
408
415
  """
@@ -69,7 +69,7 @@ class Query:
69
69
  @property
70
70
  def is_complete(self) -> bool:
71
71
  """Check if the query has completed (successfully or with error)."""
72
- return self.status in ['completed', 'failed']
72
+ return self.status in ['completed', 'failed', 'cancelled']
73
73
 
74
74
  @property
75
75
  def is_running(self) -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: adss
3
- Version: 1.26
3
+ Version: 1.28
4
4
  Summary: Astronomical Data Smart System
5
5
  Author-email: Gustavo Schwarz <gustavo.b.schwarz@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/schwarzam/adss
@@ -33,26 +33,3 @@ cd adss
33
33
  pip install .
34
34
  ```
35
35
 
36
- ## Tutorials
37
-
38
- We provide a set of tutorials to help you get started with the library:
39
-
40
- Perform a simple query to retrieve the available tables from the service, print the columns of a table, set the columns and constraints to perform a query and retrieve the data.
41
- - [Basic API](docs/basic_api.md)
42
-
43
- Learn the difference between sync and async queries and when to use each one.
44
- - [Methods of query](docs/sync_async.md)
45
-
46
- Perform a raw query to the service.
47
- - [Raw Query](docs/perform_raw_queries.md)
48
-
49
- Perform a match between two database tables and a match between a database table and a user input table.
50
- - [Match API](docs/match_api.md)
51
-
52
- Perform a match between a database table and a user input table.
53
- - [User Table Input Match](docs/usertable_input_match.md)
54
-
55
-
56
- ## Contributing
57
-
58
- We welcome contributions to this project.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "adss"
7
- version = "1.26"
7
+ version = "1.28"
8
8
  description = "Astronomical Data Smart System"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Gustavo Schwarz", email = "gustavo.b.schwarz@gmail.com" }]
adss-1.26/README.md DELETED
@@ -1,44 +0,0 @@
1
- # ADSS
2
- Astronomical Data Smart System
3
-
4
- ADSS is a database/server project hosted at CBPF (Brazilian Center for Research in Physics) that provides access to astronomical data from different surveys.
5
-
6
- This repository provides a set of tools for querying astronomical ADSS services using ADQL. You can perform cone searches, cross-match queries between tables, and even cross-match against user-supplied data. The library supports both synchronous and asynchronous query execution.
7
-
8
- ## Instalation
9
-
10
- ```bash
11
- pip install adss
12
- ```
13
-
14
- or
15
-
16
- ```bash
17
- git clone https://github.com/schwarzam/adss.git
18
- cd adss
19
- pip install .
20
- ```
21
-
22
- ## Tutorials
23
-
24
- We provide a set of tutorials to help you get started with the library:
25
-
26
- Perform a simple query to retrieve the available tables from the service, print the columns of a table, set the columns and constraints to perform a query and retrieve the data.
27
- - [Basic API](docs/basic_api.md)
28
-
29
- Learn the difference between sync and async queries and when to use each one.
30
- - [Methods of query](docs/sync_async.md)
31
-
32
- Perform a raw query to the service.
33
- - [Raw Query](docs/perform_raw_queries.md)
34
-
35
- Perform a match between two database tables and a match between a database table and a user input table.
36
- - [Match API](docs/match_api.md)
37
-
38
- Perform a match between a database table and a user input table.
39
- - [User Table Input Match](docs/usertable_input_match.md)
40
-
41
-
42
- ## Contributing
43
-
44
- We welcome contributions to this project.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes