a2p2 0.7.4__tar.gz → 0.7.5__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.
Files changed (49) hide show
  1. {a2p2-0.7.4/a2p2.egg-info → a2p2-0.7.5}/PKG-INFO +4 -2
  2. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/catalogs.py +92 -8
  3. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/version.py +6 -2
  4. {a2p2-0.7.4 → a2p2-0.7.5/a2p2.egg-info}/PKG-INFO +4 -2
  5. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2.egg-info/requires.txt +1 -0
  6. {a2p2-0.7.4 → a2p2-0.7.5}/pyproject.toml +1 -0
  7. {a2p2-0.7.4 → a2p2-0.7.5}/LICENSE +0 -0
  8. {a2p2-0.7.4 → a2p2-0.7.5}/MANIFEST.in +0 -0
  9. {a2p2-0.7.4 → a2p2-0.7.5}/README.rst +0 -0
  10. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/__init__.py +0 -0
  11. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/__main__.py +0 -0
  12. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/chara/__init__.py +0 -0
  13. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/chara/facility.py +0 -0
  14. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/chara/gui.py +0 -0
  15. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/client.py +0 -0
  16. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/facility.py +0 -0
  17. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/gui.py +0 -0
  18. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/instrument.py +0 -0
  19. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/__init__.py +0 -0
  20. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/generated_models.py +0 -0
  21. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/models.py +0 -0
  22. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/services.py +0 -0
  23. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/utils.py +0 -0
  24. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/jmmc/webservices.py +0 -0
  25. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/ob.py +0 -0
  26. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/samp.py +0 -0
  27. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/utils.py +0 -0
  28. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/__init__.py +0 -0
  29. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/GRAVITY_ditTable.json +0 -0
  30. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/GRAVITY_rangeTable.json +0 -0
  31. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/MATISSE_ditTable.json +0 -0
  32. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/MATISSE_rangeTable.json +0 -0
  33. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/PIONIER_ditTable.json +0 -0
  34. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/conf/PIONIER_rangeTable.json +0 -0
  35. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/facility.py +0 -0
  36. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/gravity.py +0 -0
  37. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/gui.py +0 -0
  38. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/instrument.py +0 -0
  39. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/matisse.py +0 -0
  40. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2/vlti/pionier.py +0 -0
  41. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2.egg-info/SOURCES.txt +0 -0
  42. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2.egg-info/dependency_links.txt +0 -0
  43. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2.egg-info/entry_points.txt +0 -0
  44. {a2p2-0.7.4 → a2p2-0.7.5}/a2p2.egg-info/top_level.txt +0 -0
  45. {a2p2-0.7.4 → a2p2-0.7.5}/setup.cfg +0 -0
  46. {a2p2-0.7.4 → a2p2-0.7.5}/setup.py +0 -0
  47. {a2p2-0.7.4 → a2p2-0.7.5}/test/test_jmmc_catalog.py +0 -0
  48. {a2p2-0.7.4 → a2p2-0.7.5}/test/test_jmmc_models.py +0 -0
  49. {a2p2-0.7.4 → a2p2-0.7.5}/test/test_test.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: a2p2
3
- Version: 0.7.4
3
+ Version: 0.7.5
4
4
  Author-email: JMMC Tech Group <jmmc-tech-group@jmmc.fr>
5
5
  License: OSI Approved :: GNU General Public License v3 (GPLv3)
6
6
  Project-URL: Homepage, https://www.jmmc.fr/a2p2
@@ -16,7 +16,9 @@ Description-Content-Type: text/x-rst
16
16
  License-File: LICENSE
17
17
  Requires-Dist: appdirs
18
18
  Requires-Dist: astropy>=5.2.2
19
+ Requires-Dist: pyvo>=1.6.1
19
20
  Requires-Dist: p2api
21
+ Dynamic: license-file
20
22
 
21
23
  a2p2 |A2P2Badge|
22
24
  ================
@@ -4,6 +4,9 @@ __all__ = []
4
4
 
5
5
  import logging
6
6
 
7
+ import pyvo
8
+ import astropy.table.table
9
+
7
10
  from ..client import A2P2ClientPreferences
8
11
 
9
12
  from .utils import JmmcAPI
@@ -17,20 +20,36 @@ class Catalog():
17
20
  Credential can be explicitly given for method that require an authentication, else:
18
21
  - a2p2 preferences login will be used if present (see a2p2 -c)
19
22
  - or uses .netrc file
23
+ A where clause can be added to limit on rows of interest (adql syntax)
24
+ A joins list of dictionnary can be provided to combine this catalog to other ones ( format is: [{"name":"cattojoin","id":"commonkey"},...] )
20
25
  """
21
26
 
22
- def __init__(self, catalogName, username=None, password=None, prod=False, apiUrl=None):
27
+ def __init__(self, catalogName, username=None, password=None, prod=False, apiUrl=None, tapUrl=None, where=None, joins=None):
23
28
  self.catalogName = catalogName
29
+ self.where = where
30
+ self.joins = joins
24
31
  self.prod = prod
32
+ self.colDelimiterName = "coldelimiter___"
25
33
 
26
34
  # Manage prod & preprod or user provided access points
27
35
  if apiUrl:
28
36
  self.apiUrl = apiUrl # trust given url as catalogAPI if value is provided
29
- elif self.prod:
30
- self.apiUrl = "https://oidb.jmmc.fr/restxq/catalogs"
31
- else:
32
- self.apiUrl = "https://oidb-beta.jmmc.fr/restxq/catalogs"
33
-
37
+ if tapUrl:
38
+ self.tapUrl = tapUrl # trust given url as TAP server if value is provided
39
+
40
+ if not(apiUrl):
41
+ if self.prod:
42
+ self.apiUrl = "https://oidb.jmmc.fr/restxq/catalogs"
43
+ else:
44
+ self.apiUrl = "https://oidb-beta.jmmc.fr/restxq/catalogs"
45
+
46
+ if not(tapUrl):
47
+ if self.prod:
48
+ self.tapUrl = "https://tap.jmmc.fr/vollt/tap"
49
+ else:
50
+ self.tapUrl = "https://tap-preprod.jmmc.fr/vollt/tap"
51
+
52
+ self.tap = pyvo.dal.TAPService(self.tapUrl)
34
53
  self.api = JmmcAPI(self.apiUrl, username, password)
35
54
 
36
55
  logger.info(f"Create catalog wrapper to access '{catalogName}' ({PRODLABEL[self.prod]} API at {self.api.rootURL})")
@@ -40,7 +59,7 @@ class Catalog():
40
59
  return self.api._get("")
41
60
 
42
61
  def metadata(self):
43
- """ Get catalog metadata """
62
+ """ Get catalog metadata"""
44
63
  return self.api._get(f"/meta/{self.catalogName}")
45
64
 
46
65
  def pis(self):
@@ -66,12 +85,75 @@ class Catalog():
66
85
  return pi["name"]
67
86
 
68
87
  def getRow(self, id):
69
- """ Get a single catalog record for the given id.
88
+ """ Get a single catalog record for the given id on the main catalog.
70
89
 
71
90
  usage: cat.getRow(42)
72
91
  """
73
92
  return self.api._get(f"/{self.catalogName}/{id}")
74
93
 
94
+ def getTable(self, maxrec=10000):
95
+ """ Get an astropy table from the main catalog joined the other if provided in constructor.
96
+
97
+ usage: cat.getRows()
98
+ """
99
+ # using SELECT TOP N below to workarround astroquery.utils.tap BUG
100
+
101
+ clauses = []
102
+ if self.joins :
103
+ joinedCatalogNames = []
104
+ for join in self.joins:
105
+ joinedCatalogNames.append(join["name"] + ".*")
106
+
107
+ # colDelimiterName is added so we can keep the mainCatalog colnames for later updates (using rowsToDict)
108
+ clauses.append(f"SELECT TOP {maxrec} {self.catalogName}.*, '' as {self.colDelimiterName}, {', '.join(joinedCatalogNames)} FROM {self.catalogName}" )
109
+
110
+ for join in self.joins:
111
+ if "catalogKey" in join.keys():
112
+ catalogKey=join["catalogKey"]
113
+ else:
114
+ # we could use the (cached) metadata key, but this would add a additional remote call.A2P2ClientPreferences
115
+ # let's try with this convention using the same key name
116
+ catalogKey=join["id"]
117
+ name=join["name"]
118
+ id=join["id"]
119
+ # LEFT JOIN may be an option provided by join key ?
120
+ clauses.append (f" LEFT JOIN {name} ON {self.catalogName}.{catalogKey} = {name}.{id}")
121
+
122
+ if self.where:
123
+ clauses.append(f" WHERE {self.catalogName}.{self.where}")
124
+ else:
125
+ clauses.append(f"SELECT TOP {maxrec} * FROM {self.catalogName}")
126
+ if self.where:
127
+ clauses.append(f" WHERE {self.where}")
128
+
129
+ query = " ".join(clauses)
130
+ logger.info(f"Queriing TAP : {query}")
131
+ return self.tap.search(query,maxrec=maxrec).to_table()
132
+
133
+
134
+ def tableToDict(self, table):
135
+ """ Convert table (astropy.table or row) to a list of dict so we can modify content and update remote catalog using updateRows().
136
+
137
+ usage: cat.tableToDict(table)
138
+ """
139
+ colnames = table.colnames
140
+ if "coldelimiter___" in colnames:
141
+ colnames = colnames[0:colnames.index("coldelimiter___")]
142
+ dicts=[]
143
+ # handle single row case
144
+ table = table if isinstance(table, astropy.table.table.Table ) else [table]
145
+ for row in table:
146
+ dict = {}
147
+ for colname in colnames:
148
+ v=row[colname]
149
+ if isinstance(v,str):
150
+ dict[colname] = v
151
+ else:
152
+ # avoid np.numeric type to make it json serializable
153
+ dict[colname] = v.item()
154
+ dicts.append(dict)
155
+ return dicts
156
+
75
157
  def updateRow(self, id, values):
76
158
  """ Update record identified by given id and associated values.
77
159
 
@@ -87,6 +169,7 @@ class Catalog():
87
169
  """
88
170
 
89
171
  # We may check befere sending payload that we always provide an id for every record
172
+ # What is the behaviour if we provide various data assosiated to the same id ?
90
173
  return self.api._put(f"/{self.catalogName}", values)
91
174
 
92
175
  def addRows(self, values):
@@ -97,6 +180,7 @@ class Catalog():
97
180
  """
98
181
  return self.api._post(f"/{self.catalogName}", json=values)
99
182
 
183
+
100
184
  def getDelegations(self, pi=None):
101
185
  """ Get -all- delegations.
102
186
  A specific pi parameter may be given but requires admin priviledges. Else use current piname will be used by remote service.
@@ -1,4 +1,4 @@
1
- __version__ = "0.7.4"
1
+ __version__ = "0.7.5"
2
2
 
3
3
  __release_notes__ = {
4
4
  # "0.1.6": {
@@ -23,7 +23,11 @@ __release_notes__ = {
23
23
  # "Try to read OB in P2 and send them back to Aspro2 as a new obs",
24
24
  # ],
25
25
 
26
- "0.7.4": {
26
+ "0.7.5": {
27
+ "A2P2": [
28
+ "Add support for join and filter in a2p2.jmmc.Catalog wrapper",
29
+ ],
30
+ },"0.7.4": {
27
31
  "A2P2": [
28
32
  "Use pyproject.toml for python installation",
29
33
  ],"VLTI": [
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: a2p2
3
- Version: 0.7.4
3
+ Version: 0.7.5
4
4
  Author-email: JMMC Tech Group <jmmc-tech-group@jmmc.fr>
5
5
  License: OSI Approved :: GNU General Public License v3 (GPLv3)
6
6
  Project-URL: Homepage, https://www.jmmc.fr/a2p2
@@ -16,7 +16,9 @@ Description-Content-Type: text/x-rst
16
16
  License-File: LICENSE
17
17
  Requires-Dist: appdirs
18
18
  Requires-Dist: astropy>=5.2.2
19
+ Requires-Dist: pyvo>=1.6.1
19
20
  Requires-Dist: p2api
21
+ Dynamic: license-file
20
22
 
21
23
  a2p2 |A2P2Badge|
22
24
  ================
@@ -1,3 +1,4 @@
1
1
  appdirs
2
2
  astropy>=5.2.2
3
+ pyvo>=1.6.1
3
4
  p2api
@@ -30,6 +30,7 @@ classifiers = [
30
30
  dependencies = [
31
31
  "appdirs",
32
32
  "astropy>=5.2.2",
33
+ "pyvo>=1.6.1",
33
34
  "p2api",
34
35
  ]
35
36
 
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
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
File without changes
File without changes
File without changes