From f21f82c225d6768ec19ac96fd78b8394b5a8bf80 Mon Sep 17 00:00:00 2001 From: Sadra Sabouri <43045767+sadrasabouri@users.noreply.github.com> Date: Tue, 22 Nov 2022 13:01:58 +0330 Subject: [PATCH] Data/Config Upload to IPFS (#164) * add : `get_config` and `get_data`. * add : `upload_data` and `upload_config` parameters added to `nft_storage` method. * log : chages logged. (#144, #145) * edit : config and data are now json dumped. * doc : document updated. * test : tests added. * fix : minor issues fixed in tests. * change : minor changes applied. * test : test splited for inreasing coverage. --- CHANGELOG.md | 4 ++ README.md | 11 +++++ examples/demo.ipynb | 27 +++++++++++- samila/functions.py | 92 ++++++++++++++++++++++++++--------------- samila/genimage.py | 30 +++++++++++++- test/nft_upload_test.py | 22 ++++++++++ 6 files changed, 149 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5210a54..2a7a4ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added - `Marker` enum +- `get_data` function +- `get_config` function ### Changed - `marker` parameter added to `plot` method +- `upload_data` parameter added to `nft_storage` method +- `upload_config` parameter added to `nft_storage` method - `generate` method optimized - Test system modified - `Python 3.11` added to `test.yml` diff --git a/README.md b/README.md index 36253f3..3d8b267 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,17 @@ Upload generated image directly to [NFT.storage](https://NFT.storage) {'status': True, 'message': 'FILE_LINK'} ``` +You can also upload your config/data to nft storage as follows: +```pycon +>>> g.nft_storage(api_key="API_KEY", upload_config=True) +{'status': {'image': True, 'config':True}, 'message': {'image':'IMAGE_FILE_LINK', 'config':'CONFIG_FILE_LINK'} +``` +or +```pycon +>>> g.nft_storage(api_key="API_KEY", upload_data=True) +{'status': {'image': True, 'data':True}, 'message': {'image':'IMAGE_FILE_LINK', 'data':'DATA_FILE_LINK'} +``` + ### Save image Save generated image diff --git a/examples/demo.ipynb b/examples/demo.ipynb index 79e6684..b8c1a06 100644 --- a/examples/demo.ipynb +++ b/examples/demo.ipynb @@ -389,6 +389,31 @@ "source": [ "g1.nft_storage(api_key=\"YOUR_API_KEY\")" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also upload your config/data to nft storage as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "g1.nft_storage(api_key=\"YOUR_API_KEY\", upload_config=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "g1.nft_storage(api_key=\"YOUR_API_KEY\", upload_data=True)" + ] } ], "metadata": { @@ -429,7 +454,7 @@ }, "vscode": { "interpreter": { - "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" } } }, diff --git a/samila/functions.py b/samila/functions.py index 2def26e..1cce9ff 100644 --- a/samila/functions.py +++ b/samila/functions.py @@ -503,6 +503,26 @@ def save_data_file(g, file_adr): :type file_adr: str :return: result as dict """ + data = get_data(g) + result = {"status": True, "message": DATA_SAVE_SUCCESS_MESSAGE} + try: + with open(file_adr, 'w') as fp: + json.dump(data, fp) + result["message"] = os.path.abspath(file_adr) + except Exception as e: + result["status"] = False + result["message"] = str(e) + return result + + +def get_data(g): + """ + Return data. + + :param g: generative image instance + :type g: GenerativeImage + :return: data as a dict + """ matplotlib_version = matplotlib.__version__ data = {} if g.data1 is None or g.data2 is None: @@ -521,15 +541,42 @@ def save_data_file(g, file_adr): "depth": g.depth } data['matplotlib_version'] = matplotlib_version - result = {"status": True, "message": DATA_SAVE_SUCCESS_MESSAGE} - try: - with open(file_adr, 'w') as fp: - json.dump(data, fp) - result["message"] = os.path.abspath(file_adr) - except Exception as e: - result["status"] = False - result["message"] = str(e) - return result + return data + + +def get_config(g): + """ + Return config. + + :param g: generative image instance + :type g: GenerativeImage + :return: config as a dict + """ + matplotlib_version = matplotlib.__version__ + config = {} + if g.function1_str is None or g.function2_str is None: + raise samilaConfigError(CONFIG_NO_STR_FUNCTION_ERROR) + config['f1'] = g.function1_str + config['f2'] = g.function2_str + config['generate'] = { + "seed": g.seed, + "start": g.start, + "step": g.step, + "stop": g.stop + } + config['plot'] = { + "color": g.color, + "bgcolor": g.bgcolor, + "cmap": _serialize_cmap(g.cmap), + "spot_size": g.spot_size, + "projection": g.projection, + "marker": g.marker, + "alpha": g.alpha, + "linewidth": g.linewidth, + "depth": g.depth + } + config['matplotlib_version'] = matplotlib_version + return config def save_config_file(g, file_adr): @@ -542,34 +589,11 @@ def save_config_file(g, file_adr): :type file_adr: str :return: result as dict """ - matplotlib_version = matplotlib.__version__ - data = {} - if g.function1_str is None or g.function2_str is None: - raise samilaConfigError(CONFIG_NO_STR_FUNCTION_ERROR) - data['f1'] = g.function1_str - data['f2'] = g.function2_str - data['generate'] = { - "seed": g.seed, - "start": g.start, - "step": g.step, - "stop": g.stop - } - data['plot'] = { - "color": g.color, - "bgcolor": g.bgcolor, - "cmap": _serialize_cmap(g.cmap), - "spot_size": g.spot_size, - "projection": g.projection, - "marker": g.marker, - "alpha": g.alpha, - "linewidth": g.linewidth, - "depth": g.depth - } - data['matplotlib_version'] = matplotlib_version + config = get_config(g) result = {"status": True, "message": DATA_SAVE_SUCCESS_MESSAGE} try: with open(file_adr, 'w') as fp: - json.dump(data, fp, indent=4) + json.dump(config, fp, indent=4) result["message"] = os.path.abspath(file_adr) except Exception as e: result["status"] = False diff --git a/samila/genimage.py b/samila/genimage.py index 0402fe2..0de6c31 100644 --- a/samila/genimage.py +++ b/samila/genimage.py @@ -1,11 +1,13 @@ # -*- coding: utf-8 -*- """Samila generative image.""" +import json import random import gc import itertools import matplotlib import matplotlib.pyplot as plt from .functions import _GI_initializer, plot_params_filter, generate_params_filter, save_params_filter +from .functions import get_config, get_data from .functions import float_range, save_data_file, save_fig_file, save_fig_buf, save_config_file from .functions import load_data, load_config, random_equation_gen, nft_storage_upload from .functions import set_background @@ -156,12 +158,21 @@ class GenerativeImage: ax.add_artist(ax.patch) self.fig = fig - def nft_storage(self, api_key, depth=None): + def nft_storage( + self, + api_key, + upload_data=False, + upload_config=False, + depth=None): """ Upload image to nft.storage. :param api_key: API key :type api_key: str + :param upload_data: upload data flag + :type upload_data: bool + :param upload_config: upload config flag + :type upload_config: bool :param depth: image depth :type depth: float :return: result as dict @@ -172,7 +183,22 @@ class GenerativeImage: return {"status": False, "message": response["message"]} buf = response["buffer"] response = nft_storage_upload(api_key=api_key, data=buf.getvalue()) - return response + if upload_config == False and upload_data == False: + return response + result = {key: {'image': value} for key, value in response.items()} + if upload_config: + response = nft_storage_upload( + api_key=api_key, + data=json.dumps(get_config(self))) + for key, value in response.items(): + result[key]['config'] = value + if upload_data: + response = nft_storage_upload( + api_key=api_key, + data=json.dumps(get_data(self))) + for key, value in response.items(): + result[key]['data'] = value + return result def save_image(self, file_adr, depth=None): """ diff --git a/test/nft_upload_test.py b/test/nft_upload_test.py index b97ba4f..d0e5669 100644 --- a/test/nft_upload_test.py +++ b/test/nft_upload_test.py @@ -20,4 +20,26 @@ ... time.sleep(10) >>> status True +>>> status = False +>>> counter = 0 +>>> while(status == False and counter>> status["image"] +True +>>> status["config"] +True +>>> status = False +>>> counter = 0 +>>> while(status == False and counter>> status["image"] +True +>>> status["data"] +True """