def reg_schema_from_url(url, method='GET', data=None, headers=None, timeout=TIMEOUT, err_404='No such object.'): '''A generic method to call a URL and transform the reply into a RegisteredSchema object. Most of the API calls can use this skeleton. ''' schema_str = None resp = None if headers == None: headers = {'Accept': 'application/json', } elif isinstance(headers, dict): headers['Accept'] = 'application/json' try: if method.upper() == 'GET': resp = requests.get(url, timeout=timeout) schema_str = resp.content elif method.upper() == 'POST': resp = requests.post(url, data=data, headers=headers, timeout=timeout) schema_str = resp.content elif method.upper() == 'PUT': resp = requests.put(url, data=data, headers=headers, timeout=timeout) schema_str = resp.content # check for error cases if resp == None: raise TASRError('Timeout for request to %s' % url) if 404 == resp.status_code: raise TASRError(err_404) if 409 == resp.status_code: raise TASRError(resp.content) if not resp.status_code in [200, 201]: raise TASRError('Failed request to %s (status code: %s)' % (url, resp.status_code)) # OK - so construct the RS and return it ras = RegisteredAvroSchema() ras.schema_str = schema_str ras.created = True if resp.status_code == 201 else False schema_meta = SchemaHeaderBot.extract_metadata(resp) if schema_str and not schema_meta.sha256_id == ras.sha256_id: raise TASRError('Schema was modified in transit.') ras.update_from_schema_metadata(schema_meta) return ras except Exception as exc: raise TASRError(exc)
def schema_for_schema_str(schema_str, object_on_miss=False, host=TASR_HOST, port=TASR_PORT, timeout=TIMEOUT): ''' POST /tasr/schema In essence this is very similar to the schema_for_id_str, but with the calculation of the ID string being moved to the server. That is, the client POSTs the schema JSON itself, the server canonicalizes it, then calculates the SHA256-based ID string for what was sent, then looks for a matching schema based on that ID string. This allows clients that do not know how to canonicalize or hash the schemas to find the metadata (is it registered, what version does it have for a topic) with what they have. A RegisteredSchema object is returned if the schema string POSTed has been registered for one or more topics. If the schema string POSTed has yet to be registered for a topic and the object_on_miss flag is True, a RegisteredSchema calculated for the POSTed schema string is returned (it will have no topic-versions as there are none). This provides an easy way for a client to get the ID strings to use for subsequent requests. If the object_on_miss flag is False (the default), then a request for a previously unregistered schema will raise a TASRError. ''' url = 'http://%s:%s/tasr/schema' % (host, port) headers = {'content-type': 'application/json; charset=utf8', } resp = requests.post(url, data=schema_str, headers=headers, timeout=timeout) if resp == None: raise TASRError('Timeout for request to %s' % url) if 200 == resp.status_code: # success -- return a normal reg schema ras = RegisteredAvroSchema() ras.schema_str = resp.context schema_meta = SchemaHeaderBot.extract_metadata(resp) ras.update_from_schema_metadata(schema_meta) return ras elif 404 == resp.status_code and object_on_miss: ras = RegisteredAvroSchema() ras.schema_str = schema_str schema_meta = SchemaHeaderBot.extract_metadata(resp) ras.update_from_schema_metadata(schema_meta) return ras raise TASRError('Schema not registered to any topics.')