Source code for gamspy._serialization

from __future__ import annotations

import json
import os
import shutil
import tempfile
import zipfile
from typing import TYPE_CHECKING

from gamspy import Container
from gamspy._model import ATTRIBUTE_MAP
from gamspy.exceptions import ValidationError

if TYPE_CHECKING:
    from collections.abc import Sequence


[docs] def serialize(container: Container, path: str) -> None: """ Serializes the given Container into a zip file. Parameters ---------- container : Container Container to be serialized. path : str Path to the zip file. Examples -------- >>> import gamspy as gp >>> m = gp.Container() >>> i = gp.Set(m, "i", records=range(3)) >>> gp.serialize(m, "serialization_path.zip") """ if not path.endswith(".zip"): raise ValidationError(f"The path must end with .zip but found {path}") if not isinstance(container, Container): raise ValidationError( f"`container` must be of type Container but found {type(container)}" ) with tempfile.TemporaryDirectory() as tmpdir_name: g00_path = os.path.join(tmpdir_name, "gams_state.g00") json_path = os.path.join(tmpdir_name, "dict.json") # Dump the GAMS State to disc container._options._set_debug_options({"save": g00_path}) container._synch_with_gams() container._options._set_debug_options({}) # Serialize symbols info = {} for name, symbol in container.data.items(): info[name] = symbol._serialize() # Serialize models models = {} for model in container.models.values(): models[model.name] = model._serialize() info["models"] = models with open(json_path, "w") as file: json.dump(info, file) shutil.make_archive(path[:-4], "zip", tmpdir_name)
[docs] def deserialize(path: str) -> Container: """ Deserializes the given zip file into a Container. Parameters ---------- path : str Path to the zip file. Returns ------- Container Deserialized Container. Raises ------ ValidationError In case the given path is not a zip file. """ if not zipfile.is_zipfile(path): raise ValidationError(f"`{path}` is not a zip file.") src = path dst = path[:-4] shutil.unpack_archive(src, dst, "zip") g00_path = os.path.join(dst, "gams_state.g00") json_path = os.path.join(dst, "dict.json") with open(json_path) as file: info = json.load(file) container = Container(load_from=g00_path) # Deserialize symbols for name, symbol in container.data.items(): symbol._deserialize(info[name]) # Deserialize models models = info["models"] for name, model in models.items(): equations = container.getEquations() equations = [ equation for equation in equations if equation.name in model["equations"] ] deserialized_matches: dict[str, str | Sequence[str]] = model.get( "_matches", None ) matches = {} if deserialized_matches is not None: for key, value in deserialized_matches.items(): if isinstance(value, str): matches[container[key]] = container[value] else: matches[container[key]] = [ container[var_name] for var_name in value ] objective_variable = model.get("_objective_variable", None) if objective_variable is not None: objective_variable = container[objective_variable] deserialized_model = container.addModel( name=name, problem=model["problem"], sense=model["sense"], equations=equations, matches=matches, objective=objective_variable, ) for attribute in ATTRIBUTE_MAP.values(): setattr(deserialized_model, attribute, model[attribute]) return container