Source code for luijo.targets

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
.. currentmodule:: luijo.tasks
.. moduleauthor:: Pat Daburu <pat@daburu.net>

Luigi targets, plus just a little more.
"""

from abc import ABCMeta
from enum import Enum
import pickle
import os
import jsonpickle
import luigi.target


[docs]class Serialization(Enum): """ These are the supported serialization methods. """ JSON = 'json' BINARY = 'binary'
[docs]def touch(local_target: luigi.LocalTarget): """ You can use this function to create a local target file in cases where you just need it to signify that the task completed. :param local_target: the local target """ with local_target.open('w') as target: target.write('')
[docs]class LocalObjectTarget(luigi.LocalTarget): """ This is a local target you can use to serialize a Python object to a file. """ __metaclass__ = ABCMeta
[docs] def deserialize(self): """ Retrieve the target object. :return: the target object """ # We'll try to use jsonpickle first... try: with self.open('r') as fin: frozen = fin.read() thawed = jsonpickle.decode(frozen) return thawed except UnicodeDecodeError: # If the attempt to unpickle using JSON fails, we assume we have a # binary file. with open(self.path, 'rb') as fin: unpickled = pickle.load(fin) return unpickled
[docs] def serialize(self, obj, format_: Serialization = Serialization.BINARY): """ Serialize an object to the local target. :param obj: the object you want to serialize :param format_: the serialization format """ if format_ == Serialization.JSON: # Encode the object. frozen = jsonpickle.encode(obj) # Open the output file for writing. with self.open('w') as fout: # Write the encoded object. fout.write(frozen) elif format_ == Serialization.BINARY: # Pickle the object to the file. os.makedirs( os.path.dirname( os.path.abspath( os.path.expanduser( self.path ) ) ), exist_ok=True) with open(self.path, 'wb') as fout: pickle.dump(obj, fout, pickle.HIGHEST_PROTOCOL) else: # pragma: no cover raise NotImplementedError( f'Unsupported serialization: { format_.name }')