Hi all, Perhaps this is hidden somewhere in the rdflib repo and I wasn’t able to find it, but I found myself wanting to encode rdflib.term.Literal values to JSON as e.g. {“value”: literal.value, “datatype”: literal.datatype, …}. I ended up adapting the advice of a SO post. Here is my answer on SO with an rdflib example: [https://stackoverflow.com/a/69588931/1820042](https://stackoverflow.com/a/69588931/1820042) <https://www.fastmail.com/mail/Inbox/compose/[https://stackoverflow.com/a/69588931/1820042](https://stackoverflow.com/a/69588931/1820042)>.
Also reproduced below. I hope folks find it useful. Also feel free to point out where this has already been done, and I’ll pip install that instead of my custom code! `from json.encoder import (_make_iterencode, JSONEncoder, encode_basestring_ascii, INFINITY, encode_basestring) class CustomObjectEncoder(JSONEncoder): def iterencode(self, o, _one_shot=False): """Encode the given object and yield each string representation as available. For example:: for chunk in JSONEncoder().iterencode(bigobject): mysocket.write(chunk) Change from json.encoder.JSONEncoder.iterencode is setting _one_shot=False and isinstance=self.isinstance in call to `_make_iterencode`. And not using `c_make_encoder`. """ if self.check_circular: markers = {} else: markers = None if self.ensure_ascii: _encoder = encode_basestring_ascii else: _encoder = encode_basestring def floatstr(o, allow_nan=self.allow_nan, _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY): # Check for specials. Note that this type of test is processor # and/or platform-specific, so do tests which don't depend on the # internals. if o != o: text = 'NaN' elif o == _inf: text = 'Infinity' elif o == _neginf: text = '-Infinity' else: return _repr(o) if not allow_nan: raise ValueError( "Out of range float values are not JSON compliant: " + repr(o)) return text _iterencode = _make_iterencode( markers, self.default, _encoder, self.indent, floatstr, self.key_separator, self.item_separator, self.sort_keys, self.skipkeys, _one_shot=False, isinstance=self.isinstance) return _iterencode(o, 0) ` Example subclass: `import datetime from rdflib.term import Literal, BNode class RDFTermEncoder(CustomObjectEncoder): def isinstance(self, o, cls): if isinstance(o, (Literal, BNode)): return False return isinstance(o, cls) def default(self, o): if isinstance(o, Literal): rv = {"value": o.value} if o.datatype is not None: rv["datatype"] = o.datatype if o.language is not None: rv["lang"] = o.language return rv if isinstance(o, BNode): return "http://localhost/bnode/" + str(o) if isinstance(o, datetime.datetime): return o.isoformat() if isinstance(o, datetime.date): return str(o) # Let the base class default method raise the TypeError return super().default(o) ` I just used this successfully for my work as `db_json = json.loads(json.dumps(db_custom, cls=RDFTermEncoder)) ` Best, Donny — Donny Winston, PhD (he/him/his) | Polyneme LLC https://donnywinston.com | https://polyneme.xyz If I’ve emailed you, I’d love to speak with you. Schedule a meeting (15min+): https://meet.polyneme.xyz -- http://github.com/RDFLib --- You received this message because you are subscribed to the Google Groups "rdflib-dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to rdflib-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/rdflib-dev/5a70d567-652c-45da-b500-7776447210dd%40www.fastmail.com.