Open Andrioden opened 1 year ago
➤ Automation for Jira commented:
The link to the corresponding Jira issue is https://ably.atlassian.net/browse/SDK-3841
Hi, @Andrioden we will look into it. Meanwhile, can you try serializing it externally, sending it as an int
timestamp instead wdyt?
Link to reference DateTime serialization implementation - https://stackoverflow.com/a/22238613
@sacOO7 - Thanks for the quick response. Changing the data contract is not a good option as i use it for api http server->client data transfer as well. I also prefer str dates over int dates as part of the contracts as they are more readable/debuggable. Instead I went with the following workaround as hinted by you.
EventPublisher - My server helper class
class EventPublisher:
@staticmethod
def _json_serializer(obj: dict) -> str:
"""JSON serializer for objects not serializable by default json code"""
if isinstance(obj, (datetime, date)):
return obj.isoformat()
raise TypeError("Type %s not serializable" % type(obj))
async def publish_to_all_async(self, name: str, data: dict) -> None:
_client = AblyRest(config.ably_server_api_key)
channel = _client.channels.get("global")
await channel.publish(name, json.dumps(data, default=self._json_serializer))
await _client.close()
.isoformat()
works really well, also if datetimes have timezone info. I also tested this. Example: datetime.now(tz=ZoneInfo("America/New_York"))
EventSubscriber - My client web/javascript helper class
export class EventSubscriber {
/**
* @param {string} apiKey
*/
static async init(apiKey) {
const ably = new Ably.Realtime.Promise(apiKey)
await ably.connection.once("connected")
console.log("Event subscriber connected!")
await ably.channels
.get("global")
.subscribe((message) => this.processMessage(message))
}
/**
* @param {Ably.Types.Message} message
*/
static processMessage(message) {
const dataJson = JSON.parse(message.data)
// Do stuff with data...
}
}
Any permanent solution that you implement should:
@sacOO7 - Thanks for the quick response. Changing the data contract is not a good option as i use it for api http server->client data transfer as well. Instead I went with the following workaround as hinted by you.
EventPublisher - My server helper class
class EventPublisher: @staticmethod def _json_serializer(obj: dict) -> str: """JSON serializer for objects not serializable by default json code""" if isinstance(obj, (datetime, date)): return obj.isoformat() raise TypeError("Type %s not serializable" % type(obj)) async def publish_to_all_async(self, name: str, data: dict) -> None: _client = AblyRest(config.ably_server_api_key) channel = _client.channels.get("global") await channel.publish(name, json.dumps(data, default=self._json_serializer)) await _client.close()
.isoformat()
works really well, also if datetimes have timezone info. I also tested this. Example:datetime.now(tz=ZoneInfo("America/New_York"))
EventSubscriber - My client web/javascript helper class
export class EventSubscriber { /** * @param {string} apiKey */ static async init(apiKey) { const ably = new Ably.Realtime.Promise(apiKey) await ably.connection.once("connected") console.log("Event subscriber connected!") await ably.channels .get("global") .subscribe((message) => this.processMessage(message)) } /** * @param {Ably.Types.Message} message */ static processMessage(message) { const dataJson = JSON.parse(message.data) } }
Any permanent solution that you implement should:
- remove the need to json serialize / deserialize the data,
- and handle timezone aware and non-aware datetimes published from the python server, by preserving the timezone data between server-client.
Yeah, we will try to implement the same 👍
This is going to take a good amount of time looking at the wide use of json.dumps
and json.loads
at multiple places. Need to refactor it with one custom JSON serializer and deserializer. Also, need to refactor msgpack use at multiple places. Still, @Andrioden we will create PR to fix this soon. Do star the repo if not already : )
Here should be a minimal script to reproduce it
ably_test.py
Run with
python .\ably_test.py
, throwsEnvironment:
┆Issue is synchronized with this Jira Task by Unito