def Run(self, args): assert (len(args) == 0), ('Unexpected arguments: %r' % args) assert (self.flags.table is not None), 'Specify --table=...' assert (self.flags.eid is not None), 'Specify --eid=...' assert (self.flags.column is not None), 'Specify --column=family:qualifier' assert (':' in self.flags.column), 'Specify --column=family:qualifier' assert (self.flags.value is not None), 'Specify --value=...' assert (self.flags.schema is not None), 'Specify --schema=...' entity_id = base.JsonDecode(self.flags.eid) logging.debug('Writing cell to row with entity ID: %r', entity_id) (family, qualifier) = self.flags.column.split(':', 1) value = base.JsonDecode(self.flags.value) schema = base.JsonDecode(self.flags.schema) json = self.client.Put( instance=self.flags.instance, table=self.flags.table, entity_id=entity_id, family=family, qualifier=qualifier, value=value, schema=schema, ) logging.debug('JSON result for put: %r', json) return ExitCode.SUCCESS
def Put( self, entity_id, family, qualifier, value, schema, timestamp=None, instance=None, table=None, ): """Writes a single cell into a row. Args: entity_id: ID of the row entity to query. family: Name of the family to write. qualifier: Name of the column to write. value: Value of the cell to write, represented as a Python value for a JSON object. schema: Avro schema of the value to write, represented as a Python value describing an Avro JSON schema. instance: Optional explicit Kiji instance name. table: Optional explicit Kiji table name. Returns: Row content, as a Python value (decoded from JSON). """ if instance is None: instance = self._instance_name assert (instance is not None), 'No Kiji instance specified.' if table is None: table = self._table_name assert (table is not None), 'No Kiji table specified.' path = os.path.join('instances', instance, 'tables', table, 'rows') data = dict( entityId = _RestEntityId(entity_id), cells = { family: { qualifier: [dict( timestamp = timestamp, value = value, writer_schema = schema, )] } } ) text_reply = self.Request( path=path, data=base.JsonEncode(data, pretty=False).encode(), method=HttpMethod.POST, ) return base.JsonDecode(text_reply)
def ListTables(self, instance): """Lists the names of the Kiji tables that exist in a Kiji instance. Args: instance: Name of the Kiji instance to list the table of. Returns: Sorted list of Kiji table names. """ text_reply = self.Request( path=os.path.join('instances', instance, 'tables'), method=HttpMethod.GET, ) return sorted(map(lambda entry: entry['name'], base.JsonDecode(text_reply)))
def Run(self, args): assert (len(args) == 0), ('Unexpected arguments: %r' % args) assert (self.flags.table is not None), 'Specify --table=...' if self.flags.start_eid is not None: start_eid = base.JsonDecode(self.flags.start_eid) else: start_eid = None if self.flags.end_eid is not None: end_eid = base.JsonDecode(self.flags.end_eid) else: end_eid = None logging.debug( 'Scanning rows from entity ID: %r to entity ID: %r', start_eid, end_eid) if (self.flags.columns is not None) and (len(self.flags.columns) > 0): columns = self.flags.columns.split(',') else: columns = None max_rows = self.flags.max_rows if max_rows < 0: max_rows = None for row in self.client.Scan( instance=self.flags.instance, table=self.flags.table, start_eid=start_eid, end_eid=end_eid, columns=columns, max_rows=max_rows, ): print('-' * 80) print(base.JsonEncode(row)) return ExitCode.SUCCESS
def Run(self, args): try: return self._RunInternal(args) except urllib.error.HTTPError as err: # Pretty-print the JSON error trace, if possible: error_text = err.read().decode() if err.headers.get_content_type() == ContentType.JSON: json = base.JsonDecode(error_text) logging.error( 'Error during HTTP request: %s\n%s', err, base.JsonEncode(json)) if 'trace' in json: logging.error('Trace:\n%s', json['trace']) else: logging.error( 'Error during HTTP request: %s\n%s', err, error_text) return ExitCode.FAILURE
def Get( self, entity_id, columns=None, data=None, query=None, instance=None, table=None, ): """Retrieves a single row of data. Args: entity_id: ID of the row entity to query. columns: Optional list of columns to request. Default is to request all columns. data: Optional HTTP request body (data). query: Optional extra HTTP URL query parameters, as a Python dict. instance: Optional explicit Kiji instance name. table: Optional explicit Kiji table name. Returns: Row content, as a Python value (decoded from JSON). """ if instance is None: instance = self._instance_name assert (instance is not None), 'No Kiji instance specified.' if table is None: table = self._table_name assert (table is not None), 'No Kiji table specified.' path = os.path.join('instances', instance, 'tables', table, 'rows') if query is None: query = dict() query['eid'] = base.JsonEncode(_RestEntityId(entity_id), pretty=False) if (columns is not None) and (len(columns) > 0): query['cols'] = ','.join(columns) text_reply = self.Request( path=path, query=query, data=data, method=HttpMethod.GET, ) return base.JsonDecode(text_reply)
def Run(self, args): assert (len(args) == 0), ('Unexpected arguments: %r' % args) assert (self.flags.table is not None), 'Specify --table=...' assert (self.flags.eid is not None), 'Specify --eid=...' entity_id = base.JsonDecode(self.flags.eid) logging.debug('Retrieving row with entity ID: %r', entity_id) if (self.flags.columns is not None) and (len(self.flags.columns) > 0): columns = self.flags.columns.split(',') else: columns = None json = self.client.Get( instance=self.flags.instance, table=self.flags.table, entity_id=entity_id, columns=columns, ) print(base.JsonEncode(json)) return ExitCode.SUCCESS
def GetMetrics(self): """Retrieves the metrics exposed by this REST server. Returns: Python value decoded from the KijiREST JSON metric record. """ url = 'http://%s/metrics' % self.admin_address data = None http_req = urllib.request.Request(url=url, data=data) http_req.add_header('Accept', ContentType.JSON) http_req.add_header('Content-Type', ContentType.JSON) method = HttpMethod.GET http_req.get_method = lambda: method logging.debug( 'Sending HTTP %s request: %s with headers %s and data %r', method, http_req.full_url, http_req.header_items(), data) http_reply = urllib.request.urlopen(http_req) assert (http_reply.getcode() == http.client.OK), \ ('HTTP reply with code %d' % http_reply.getcode()) text_reply = http_reply.readall().decode() return base.JsonDecode(text_reply)
def Scan( self, start_eid=None, end_eid=None, columns=None, data=None, query=None, instance=None, table=None, max_rows=3, ): """Retrieves a range of rows. Args: start_eid: ID of the entity to scan from (included). Default is to scan from the first available row. end_eid: ID of the entity to scan to (excluded). Default is to scan to the last row in the table. columns: Optional list of columns to request. Default is to request all columns. data: Optional HTTP request body (data). query: Optional extra HTTP URL query parameters, as a Python dict. instance: Optional explicit Kiji instance name. table: Optional explicit Kiji table name. max_rows: Optional maximum number of rows to return. None means return all rows. Default is to return 3 rows. Yields: Row content, as a Python value (decoded from JSON). """ if instance is None: instance = self._instance_name assert (instance is not None), 'No Kiji instance specified.' if table is None: table = self._table_name assert (table is not None), 'No Kiji table specified.' path = os.path.join('instances', instance, 'tables', table, 'rows') if query is None: query = dict() if start_eid is not None: query['start_eid'] = \ base.JsonEncode(_RestEntityId(start_eid), pretty=False) if end_eid is not None: query['end_eid'] = \ base.JsonEncode(_RestEntityId(end_eid), pretty=False) if max_rows is None: query['limit'] = -1 else: query['limit'] = max_rows if (columns is not None) and (len(columns) > 0): query['cols'] = ','.join(columns) http_reply = self.Request( path=path, query=query, data=data, method=HttpMethod.GET, raw=True, ) while True: line = http_reply.readline() if (line is not None) and (len(line) > 0): yield base.JsonDecode(line.decode()) else: break
def ListInstances(self): text_reply = self.Request(path='instances') return sorted(map(lambda entry: entry['name'], base.JsonDecode(text_reply)))