async def get_by_id(self, schema_id: int, headers: dict = None) -> typing.Optional[AvroSchema]: """ GET /schemas/ids/{int: id} Retrieve a parsed avro schema by id or None if not found Args: schema_id (int): Schema Id headers (dict): Extra headers to add on the requests Returns: client.schema.AvroSchema: Avro Record schema """ if schema_id in self.id_to_schema: return self.id_to_schema[schema_id] url, method = self.url_manager.url_for("get_by_id", schema_id=schema_id) result, code = await self.request(url, method=method, headers=headers) if code == status.HTTP_404_NOT_FOUND: logger.error(f"Schema not found: {code}") return None elif status.is_success(code): schema_str = result.get("schema") result = AvroSchema(schema_str) # cache the result self._cache_schema(result, schema_id) return result raise ClientError(f"Received bad schema (id {schema_id})", http_code=code, server_traceback=result)
def _dumps(self, obj: typing.Dict[str, typing.Any]) -> bytes: """ Given a parsed avro schema, encode a record for the given topic. The record is expected to be a dictionary. The schema is registered with the subject of 'topic-value' """ if "__faust" not in obj or "ns" not in obj["__faust"]: raise ValueError("Record does not have namespace metadata") model_class_name = obj["__faust"]["ns"] if model_class_name not in registry: raise ValueError("The class you are trying to deserialize doesn't exist inside the faust registry") class_reference = registry[model_class_name] if not hasattr(class_reference, "_schema"): raise MissingSchemaException("Record does not have schema defined in '_schema' field") schema_def = getattr(class_reference, "_schema") avro_schema = AvroSchema(schema_def) obj = self.clean_payload(obj) # method available on MessageSerializer return self.encode_record_with_schema( f"{self.schema_subject}-{self._mapping_key[self.is_key]}", avro_schema, obj )
def client(): client = SchemaRegistryClient("http://my-dummy-schema.com") client.register = MagicMock(name="register") client.get_by_id = MagicMock(name="get_by_id") client.register.return_value = 1 client.get_by_id.return_value = AvroSchema(UserModel._schema) return client
def get_schema( self, subject: str, version: typing.Union[int, str] = "latest", headers: dict = None, timeout: typing.Union[TimeoutTypes, UnsetType] = UNSET, ) -> typing.Optional[utils.SchemaVersion]: """ GET /subjects/(string: subject)/versions/(versionId: version) Get a specific version of the schema registered under this subject Args: subject (str): subject name version (int, optional): version id. If is None, the latest schema is returned headers (dict): Extra headers to add on the requests timeout (httpx._client.TimeoutTypes): The timeout configuration to use when sending requests. Default UNSET Returns: SchemaVersion (nametupled): (subject, schema_id, schema, version) None: If server returns a not success response: 404: Schema not found 422: Unprocessable entity ~ (200 - 299): Not success """ url, method = self.url_manager.url_for("get_schema", subject=subject, version=version) result, code = self.request(url, method=method, headers=headers, timeout=timeout) if code == status.HTTP_404_NOT_FOUND: logger.error(f"Schema not found: {code}") return None elif code == status.HTTP_422_UNPROCESSABLE_ENTITY: logger.error(f"Invalid version: {code}") return None elif not status.is_success(code): logger.error(f"Not success version: {code}") return None schema_id = result.get("id") if schema_id in self.id_to_schema: schema = self.id_to_schema[schema_id] else: schema = AvroSchema(result["schema"]) version = result["version"] self._cache_schema(schema, schema_id, subject, version) return utils.SchemaVersion(subject, schema_id, schema, version)
def dummy_avro_schema(): schema = { "type": "record", "namespace": "dummy", "name": "dummy", "fields": [{ "name": "foo", "type": "string" }, { "name": "bar", "type": "string" }] } return AvroSchema(schema)
def get_schema(self, subject, version="latest", headers=None): """ GET /subjects/(string: subject)/versions/(versionId: version) Get a specific version of the schema registered under this subject Args: subject (str): subject name version (int, optional): version id. If is None, the latest schema is returned headers (dict): Extra headers to add on the requests Returns: SchemaVersion (nametupled): (subject, schema_id, schema, version) None: If server returns a not success response: 404: Schema not found 422: Unprocessable entity ~ (200 - 299): Not success """ url = "/".join( [self.url, "subjects", subject, "versions", str(version)]) result, code = self.request(url, headers=headers) if code == status.HTTP_404_NOT_FOUND: log.error(f"Schema not found: {code}") return elif code == status.HTTP_422_UNPROCESSABLE_ENTITY: log.error(f"Invalid version: {code}") return elif not status.is_success(code): log.error(f"Not success version: {code}") return schema_id = result.get("id") if schema_id in self.id_to_schema: schema = self.id_to_schema[schema_id] else: try: schema = AvroSchema(result["schema"]) except ClientError: raise version = result.get("version") self._cache_schema(schema, schema_id, subject, version) return utils.SchemaVersion(subject, schema_id, schema, version)
def get_by_id( self, schema_id: int, headers: dict = None, timeout: typing.Union[TimeoutTypes, UnsetType] = UNSET ) -> typing.Optional[AvroSchema]: """ GET /schemas/ids/{int: id} Retrieve a parsed avro schema by id or None if not found Args: schema_id (int): Schema Id headers (dict): Extra headers to add on the requests timeout (httpx._client.TimeoutTypes): The timeout configuration to use when sending requests. Default UNSET Returns: client.schema.AvroSchema: Avro Record schema """ if schema_id in self.id_to_schema: return self.id_to_schema[schema_id] url, method = self.url_manager.url_for("get_by_id", schema_id=schema_id) result, code = self.request(url, method=method, headers=headers, timeout=timeout) if code == status.HTTP_404_NOT_FOUND: logger.error(f"Schema not found: {code}") return None elif status.is_success(code): schema_str = result.get("schema") result = AvroSchema(schema_str) self._cache_schema(result, schema_id) return result raise ClientError(f"Received bad schema (id {schema_id})", http_code=code, server_traceback=result)
def get_by_id(self, schema_id, headers=None): """ GET /schemas/ids/{int: id} Retrieve a parsed avro schema by id or None if not found Args: schema_id (int): Schema Id headers (dict): Extra headers to add on the requests Returns: avro.schema.RecordSchema: Avro Record schema """ if schema_id in self.id_to_schema: return self.id_to_schema[schema_id] # fetch from the registry url = "/".join([self.url, "schemas", "ids", str(schema_id)]) result, code = self.request(url, headers=headers) if code == status.HTTP_404_NOT_FOUND: log.error(f"Schema not found: {code}") elif not status.is_success(code): log.error(f"Unable to get schema for the specific ID: {code}") else: # need to parse the schema schema_str = result.get("schema") try: result = AvroSchema(schema_str) # cache the result self._cache_schema(result, schema_id) return result except ClientError: # bad schema - should not happen raise ClientError( f"Received bad schema (id {schema_id})", http_code=code, server_traceback=result, )