adss 1.0__py3-none-any.whl → 1.2__py3-none-any.whl

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.
@@ -0,0 +1,216 @@
1
+ """
2
+ Database metadata functionality for the Astronomy TAP Client.
3
+ """
4
+ import requests
5
+ from typing import Dict, List, Optional, Any
6
+
7
+ from ..exceptions import (
8
+ AuthenticationError, ResourceNotFoundError, PermissionDeniedError
9
+ )
10
+ from adss.utils import handle_response_errors
11
+ from adss.models.metadata import Column, Table, Schema, DatabaseMetadata
12
+
13
+
14
+ class MetadataEndpoint:
15
+ """
16
+ Handles database metadata discovery.
17
+ """
18
+
19
+ def __init__(self, base_url: str, auth_manager):
20
+ """
21
+ Initialize the Metadata endpoint.
22
+
23
+ Args:
24
+ base_url: The base URL of the API server
25
+ auth_manager: Authentication manager providing auth headers
26
+ """
27
+ self.base_url = base_url.rstrip('/')
28
+ self.auth_manager = auth_manager
29
+
30
+ def get_schemas(self, **kwargs) -> List[str]:
31
+ """
32
+ Get a list of accessible database schemas.
33
+
34
+ Args:
35
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
36
+
37
+ Returns:
38
+ List of schema names accessible to the current user
39
+
40
+ Raises:
41
+ AuthenticationError: If not authenticated (for protected schemas)
42
+ """
43
+ try:
44
+ response = self.auth_manager.request(
45
+ method="GET",
46
+ url="/adss/v1/metadata/schemas",
47
+ **kwargs
48
+ )
49
+ handle_response_errors(response)
50
+
51
+ return response.json()
52
+
53
+ except Exception as e:
54
+ # Authentication error only if trying to access protected schemas
55
+ # Anonymous users should still see public schemas
56
+ if hasattr(e, 'response') and e.response.status_code == 401:
57
+ raise AuthenticationError("Authentication required for protected schemas")
58
+ raise
59
+
60
+ def get_tables(self, schema_name: str, **kwargs) -> List[str]:
61
+ """
62
+ Get a list of accessible tables in a schema.
63
+
64
+ Args:
65
+ schema_name: Name of the schema
66
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
67
+
68
+ Returns:
69
+ List of table names in the schema accessible to the current user
70
+
71
+ Raises:
72
+ AuthenticationError: If not authenticated (for protected schemas)
73
+ PermissionDeniedError: If the user doesn't have access to the schema
74
+ ResourceNotFoundError: If the schema doesn't exist
75
+ """
76
+ try:
77
+ response = self.auth_manager.request(
78
+ method="GET",
79
+ url=f"/adss/v1/metadata/schemas/{schema_name}/tables",
80
+ **kwargs
81
+ )
82
+ handle_response_errors(response)
83
+
84
+ return response.json()
85
+
86
+ except Exception as e:
87
+ if hasattr(e, 'response'):
88
+ if e.response.status_code == 401:
89
+ raise AuthenticationError("Authentication required for protected schemas")
90
+ elif e.response.status_code == 403:
91
+ raise PermissionDeniedError(f"Access denied to schema: {schema_name}")
92
+ elif e.response.status_code == 404:
93
+ raise ResourceNotFoundError(f"Schema not found: {schema_name}")
94
+ raise
95
+
96
+ def get_columns(self, schema_name: str, table_name: str, **kwargs) -> List[Column]:
97
+ """
98
+ Get a list of columns in a table.
99
+
100
+ Args:
101
+ schema_name: Name of the schema
102
+ table_name: Name of the table
103
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
104
+
105
+ Returns:
106
+ List of Column objects in the table
107
+
108
+ Raises:
109
+ AuthenticationError: If not authenticated (for protected schemas)
110
+ PermissionDeniedError: If the user doesn't have access to the table
111
+ ResourceNotFoundError: If the schema or table doesn't exist
112
+ """
113
+ try:
114
+ response = self.auth_manager.request(
115
+ method="GET",
116
+ url=f"/adss/v1/metadata/schemas/{schema_name}/tables/{table_name}/columns",
117
+ **kwargs
118
+ )
119
+ handle_response_errors(response)
120
+
121
+ columns_data = response.json()
122
+ return [Column.from_dict(col_data) for col_data in columns_data]
123
+
124
+ except Exception as e:
125
+ if hasattr(e, 'response'):
126
+ if e.response.status_code == 401:
127
+ raise AuthenticationError("Authentication required for protected schemas")
128
+ elif e.response.status_code == 403:
129
+ raise PermissionDeniedError(f"Access denied to table: {schema_name}.{table_name}")
130
+ elif e.response.status_code == 404:
131
+ raise ResourceNotFoundError(f"Table not found: {schema_name}.{table_name}")
132
+ raise
133
+
134
+ def get_database_metadata(self, **kwargs) -> DatabaseMetadata:
135
+ """
136
+ Get comprehensive database metadata for accessible schemas and tables.
137
+
138
+ Args:
139
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
140
+
141
+ Returns:
142
+ DatabaseMetadata object containing all accessible schema and table information
143
+
144
+ Raises:
145
+ AuthenticationError: If not authenticated (for protected schemas)
146
+ """
147
+ try:
148
+ response = self.auth_manager.request(
149
+ method="GET",
150
+ url="/adss/v1/metadata/database",
151
+ **kwargs
152
+ )
153
+ handle_response_errors(response)
154
+
155
+ metadata = response.json()
156
+ return DatabaseMetadata.from_dict(metadata)
157
+
158
+ except Exception as e:
159
+ if hasattr(e, 'response') and e.response.status_code == 401:
160
+ raise AuthenticationError("Authentication required for protected schemas")
161
+ raise
162
+
163
+ def get_table_info(self, schema_name: str, table_name: str, **kwargs) -> Table:
164
+ """
165
+ Get detailed information about a specific table.
166
+
167
+ Args:
168
+ schema_name: Name of the schema
169
+ table_name: Name of the table
170
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
171
+
172
+ Returns:
173
+ Table object with column information
174
+
175
+ Raises:
176
+ AuthenticationError: If not authenticated (for protected schemas)
177
+ PermissionDeniedError: If the user doesn't have access to the table
178
+ ResourceNotFoundError: If the schema or table doesn't exist
179
+ """
180
+ # Get columns for the table
181
+ columns = self.get_columns(schema_name, table_name, **kwargs)
182
+
183
+ # Create and return Table object
184
+ return Table(name=table_name, columns=columns)
185
+
186
+ def get_schema_info(self, schema_name: str, **kwargs) -> Schema:
187
+ """
188
+ Get detailed information about a specific schema.
189
+
190
+ Args:
191
+ schema_name: Name of the schema
192
+ **kwargs: Additional keyword arguments to pass to the request (e.g., verify=False)
193
+
194
+ Returns:
195
+ Schema object with table information
196
+
197
+ Raises:
198
+ AuthenticationError: If not authenticated (for protected schemas)
199
+ PermissionDeniedError: If the user doesn't have access to the schema
200
+ ResourceNotFoundError: If the schema doesn't exist
201
+ """
202
+ # Get tables in the schema
203
+ table_names = self.get_tables(schema_name, **kwargs)
204
+
205
+ # Get information for each table
206
+ tables = []
207
+ for table_name in table_names:
208
+ try:
209
+ table = self.get_table_info(schema_name, table_name, **kwargs)
210
+ tables.append(table)
211
+ except PermissionDeniedError:
212
+ # Skip tables we don't have access to
213
+ continue
214
+
215
+ # Create and return Schema object
216
+ return Schema(name=schema_name, tables=tables)