Skip to content

Commit 788d416

Browse files
add EncondingSchema enum and start implementation on default schema representations as a concept in the library
1 parent 39525ce commit 788d416

File tree

2 files changed

+94
-11
lines changed

2 files changed

+94
-11
lines changed

conSys4Py/constants.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,19 @@ class APIResourceTypes(Enum):
9090
SYSTEM = "System"
9191
SYSTEM_EVENT = "SystemEvent"
9292
SYSTEM_HISTORY = "SystemHistory"
93+
94+
95+
class EncodingSchema(Enum):
96+
"""
97+
Defines the encoding formats
98+
"""
99+
JSON = "application/json"
100+
XML = "application/xml"
101+
SWE_XML = "application/swe+xml"
102+
SWE_JSON = "application/swe+json"
103+
SWE_CSV = "application/swe+csv"
104+
SWE_BINARY = "application/swe+binary"
105+
SWE_TEXT = "application/swe+text"
106+
GEO_JSON = "application/geo+json"
107+
SML_JSON = "application/sml+json"
108+
OM_JSON = "application/om+json"

conSys4Py/core/default_api_helpers.py

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
from __future__ import annotations
2+
13
from abc import ABC
24
from dataclasses import dataclass
35

4-
from conSys4Py import APIResourceTypes, APITerms
6+
from pydantic import BaseModel, Field
7+
8+
from conSys4Py import APIResourceTypes, APITerms, EncodingSchema
59
from conSys4Py.con_sys_api import ConnectedSystemAPIRequest
610

711

@@ -73,30 +77,35 @@ def resource_type_to_endpoint(res_type: APIResourceTypes, parent_type: APIResour
7377
@dataclass
7478
class APIHelper(ABC):
7579
server_url = None
76-
api_endpoint = "/api"
80+
api_root = "/api"
7781
username = None
7882
password = None
7983
user_auth = False
8084

8185
def create_resource(self, res_type: APIResourceTypes, json_data: any, parent_res_id: str = None,
82-
from_collection: bool = False):
86+
from_collection: bool = False, url_endpoint: str = None):
8387
"""
8488
Creates a resource of the given type with the given data, will attempt to create a sub-resource if parent_res_id
8589
is provided.
8690
:param res_type:
8791
:param json_data:
8892
:param parent_res_id:
8993
:param from_collection:
94+
:param url_endpoint: If given, will override the default URL construction. Should contain the endpoint past the API root.
9095
:return:
9196
"""
92-
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
97+
98+
if url_endpoint is None:
99+
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
100+
else:
101+
url = f'{self.server_url}/{self.api_root}/{url_endpoint}'
93102
api_request = ConnectedSystemAPIRequest(url=url, request_method='POST', auth=self.get_helper_auth(),
94103
body=json_data)
95104
return api_request.make_request()
96105

97106
def retrieve_resource(self, res_type: APIResourceTypes, res_id: str, parent_res_id: str = None,
98107
from_collection: bool = False,
99-
collection_id: str = None):
108+
collection_id: str = None, url_endpoint: str = None):
100109
"""
101110
Retrieves a resource or list of resources if no res_id is provided, will attempt to retrieve a sub-resource if
102111
parent_res_id is provided.
@@ -105,14 +114,18 @@ def retrieve_resource(self, res_type: APIResourceTypes, res_id: str, parent_res_
105114
:param parent_res_id:
106115
:param from_collection:
107116
:param collection_id:
117+
:param url_endpoint: If given, will override the default URL construction. Should contain the endpoint past the API root.
108118
:return:
109119
"""
110-
url = self.resource_url_resolver(res_type, res_id, parent_res_id, from_collection)
120+
if url_endpoint is None:
121+
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
122+
else:
123+
url = f'{self.server_url}/{self.api_root}/{url_endpoint}'
111124
api_request = ConnectedSystemAPIRequest(url=url, request_method='GET', auth=self.get_helper_auth())
112125
return api_request.make_request()
113126

114127
def update_resource(self, res_type: APIResourceTypes, res_id: str, json_data: any, parent_res_id: str = None,
115-
from_collection: bool = False):
128+
from_collection: bool = False, url_endpoint: str = None):
116129
"""
117130
Updates a resource of the given type by its id, if necessary, will attempt to update a sub-resource if
118131
parent_res_id is provided.
@@ -121,31 +134,48 @@ def update_resource(self, res_type: APIResourceTypes, res_id: str, json_data: an
121134
:param json_data:
122135
:param parent_res_id:
123136
:param from_collection:
137+
:param url_endpoint: If given, will override the default URL construction. Should contain the endpoint past the API root.
124138
:return:
125139
"""
126-
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
140+
if url_endpoint is None:
141+
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
142+
else:
143+
url = f'{self.server_url}/{self.api_root}/{url_endpoint}'
127144
api_request = ConnectedSystemAPIRequest(url=url, request_method='PUT', auth=self.get_helper_auth(),
128145
body=json_data)
129146
return api_request.make_request()
130147

131148
def delete_resource(self, res_type: APIResourceTypes, res_id: str, parent_res_id: str = None,
132-
from_collection: bool = False):
149+
from_collection: bool = False, url_endpoint: str = None):
133150
"""
134151
Deletes a resource of the given type by its id, if necessary, will attempt to delete a sub-resource if
135152
parent_res_id is provided.
136153
:param res_type:
137154
:param res_id:
138155
:param parent_res_id:
139156
:param from_collection:
157+
:param url_endpoint: If given, will override the default URL construction. Should contain the endpoint past the API root.
140158
:return:
141159
"""
142-
url = self.resource_url_resolver(res_type, res_id, parent_res_id, from_collection)
160+
if url_endpoint is None:
161+
url = self.resource_url_resolver(res_type, None, parent_res_id, from_collection)
162+
else:
163+
url = f'{self.server_url}/{self.api_root}/{url_endpoint}'
143164
api_request = ConnectedSystemAPIRequest(url=url, request_method='DELETE', auth=self.get_helper_auth())
144165
return api_request.make_request()
145166

146167
# Helpers
147168
def resource_url_resolver(self, res_type: APIResourceTypes, res_id: str = None, parent_res_id: str = None,
148169
from_collection: bool = False):
170+
"""
171+
Helper to generate a URL endpoint for a given resource type and id by matching the resource type to an
172+
appropriate parent endpoint and inserting the resource ids as necessary.
173+
:param res_type:
174+
:param res_id:
175+
:param parent_res_id:
176+
:param from_collection:
177+
:return:
178+
"""
149179
if res_type is None:
150180
raise ValueError('Resource type must contain a valid APIResourceType')
151181
if res_type is APIResourceTypes.COLLECTION and from_collection:
@@ -160,8 +190,16 @@ def resource_url_resolver(self, res_type: APIResourceTypes, res_id: str = None,
160190
return self.construct_url(parent_type, res_id, res_type, parent_res_id)
161191

162192
def construct_url(self, parent_type, res_id, res_type, parent_res_id):
193+
"""
194+
Constructs an API endpoint url from the given parameters
195+
:param parent_type:
196+
:param res_id:
197+
:param res_type:
198+
:param parent_res_id:
199+
:return:
200+
"""
163201
# TODO: Test for less common cases to ensure that the URL is being constructed correctly
164-
base_url = f'{self.server_url}/{self.api_endpoint}'
202+
base_url = f'{self.server_url}/{self.api_root}'
165203
resource_endpoint = resource_type_to_endpoint(res_type, parent_type)
166204
url = f'{base_url}/{resource_endpoint}'
167205

@@ -178,3 +216,32 @@ def get_helper_auth(self):
178216
if self.user_auth:
179217
return self.username, self.password
180218
return None
219+
220+
221+
@dataclass(kw_only=True)
222+
class ResponseParserHelper:
223+
default_object_reps: DefaultObjectRepresentations
224+
225+
226+
class DefaultObjectRepresentations(BaseModel):
227+
"""
228+
Intended to be used as a way to determine which formats should be used when serializing and deserializing objects.
229+
Should work in tandem with planned Serializer/Deserializer classes.
230+
"""
231+
# Part 1
232+
collections: str = Field(EncodingSchema.JSON.value)
233+
deployments: str = Field(EncodingSchema. GEO_JSON.value)
234+
procedures: str = Field(EncodingSchema.GEO_JSON.value)
235+
properties: str = Field(EncodingSchema.SML_JSON.value)
236+
sampling_features: str = Field(EncodingSchema.GEO_JSON.value)
237+
systems: str = Field(EncodingSchema.GEO_JSON.value)
238+
# Part 2
239+
datastreams: str = Field(EncodingSchema.JSON.value)
240+
observations: str = Field(EncodingSchema.JSON.value)
241+
control_channels: str = Field(EncodingSchema.JSON.value)
242+
commands: str = Field(EncodingSchema.JSON.value)
243+
system_events: str = Field(EncodingSchema.OM_JSON.value)
244+
system_history: str = Field(EncodingSchema.GEO_JSON.value)
245+
# TODO: validate schemas for each resource to amke sure they are allowed per the spec
246+
247+

0 commit comments

Comments
 (0)