-
Notifications
You must be signed in to change notification settings - Fork 199
add optional arguments to add_str() #287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
16e2f64
079baf2
70d9b71
78c402d
add51e1
4a5c2a1
5a3f74e
e03d2cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -240,7 +240,15 @@ def apply_workarounds(self): | |
|
||
@utils.return_field('Hash') | ||
@base.returns_single_item(dict) | ||
def add_bytes(self, data: bytes, **kwargs): | ||
def add_bytes(self, data: bytes, | ||
trickle: bool = False, | ||
only_hash: bool = False, | ||
chunker: ty.Optional[str] = None, | ||
pin: bool = True, | ||
raw_leaves: bool = None, | ||
cid_version: ty.Optional[int] = None, | ||
**kwargs: base.CommonArgs) -> str: | ||
|
||
"""Adds a set of bytes as a file to IPFS. | ||
|
||
.. code-block:: python | ||
|
@@ -254,19 +262,57 @@ def add_bytes(self, data: bytes, **kwargs): | |
---------- | ||
data | ||
Content to be added as a file | ||
trickle | ||
Use trickle-dag format (optimized for streaming) when generating | ||
the dag; see `the old FAQ <https://github.com/ipfs/faq/issues/218>`_ | ||
for more information | ||
only_hash | ||
Only chunk and hash, but do not write to disk | ||
chunker | ||
The chunking algorithm to use | ||
pin | ||
Pin this object when adding | ||
raw_leaves | ||
Use raw blocks for leaf nodes. (experimental). (Default: ``True`` | ||
when *nocopy* is True, or ``False`` otherwise) | ||
cid_version | ||
CID version. Default value is provided by IPFS daemon. (experimental) | ||
|
||
Returns | ||
------- | ||
str | ||
Hash of the added IPFS object | ||
""" | ||
|
||
opts: ty.Dict[str, ty.Union[str, bool]] = { | ||
"trickle": trickle, | ||
"only-hash": only_hash, | ||
"pin": pin, | ||
"raw-leaves": raw_leaves if raw_leaves is not None else nocopy, | ||
} | ||
for option_name, option_value in [ | ||
("chunker", chunker), | ||
("cid-version", cid_version), | ||
]: | ||
if option_value is not None: | ||
opts[option_name] = option_value | ||
kwargs.setdefault("opts", {}).update(opts) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we avoid mutating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied the implementation from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It "works" because changes to the It's bad style - mutating mutable arguments can cause sneaky defects in functions that call the function doing the mutating (unless the documentation or name of the function states or strongly suggests that's the expected behavior). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that if you refactor this into a new function that returns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @c0llab0rat0r: I don't believe that mutating the I've seen plenty of code doing things like: def func(a, *a, **kw):
xtra_arg = kw.pop("xtra", "default")
... This was/is a very common trick to emulate kw-only args with writing Python 2 compatible code. Until we dropped Python 2 support py-ipfs-api-client had similar code itself… Note: |
||
|
||
body, headers = multipart.stream_bytes(data, chunk_size=self.chunk_size) | ||
return self._client.request('/add', decoder='json', | ||
data=body, headers=headers, **kwargs) | ||
|
||
@utils.return_field('Hash') | ||
@base.returns_single_item(dict) | ||
def add_str(self, string, **kwargs): | ||
def add_str(self, string, | ||
trickle: bool = False, | ||
only_hash: bool = False, | ||
chunker: ty.Optional[str] = None, | ||
pin: bool = True, | ||
raw_leaves: bool = None, | ||
cid_version: ty.Optional[int] = None, | ||
**kwargs: base.CommonArgs) -> str: | ||
|
||
"""Adds a Python string as a file to IPFS. | ||
|
||
.. code-block:: python | ||
|
@@ -280,17 +326,54 @@ def add_str(self, string, **kwargs): | |
---------- | ||
string : str | ||
Content to be added as a file | ||
trickle | ||
Use trickle-dag format (optimized for streaming) when generating | ||
the dag; see `the old FAQ <https://github.com/ipfs/faq/issues/218>`_ | ||
for more information | ||
only_hash | ||
Only chunk and hash, but do not write to disk | ||
chunker | ||
The chunking algorithm to use | ||
pin | ||
Pin this object when adding | ||
raw_leaves | ||
Use raw blocks for leaf nodes. (experimental). (Default: ``True`` | ||
when *nocopy* is True, or ``False`` otherwise) | ||
cid_version | ||
CID version. Default value is provided by IPFS daemon. (experimental) | ||
|
||
Returns | ||
------- | ||
str | ||
Hash of the added IPFS object | ||
""" | ||
|
||
opts: ty.Dict[str, ty.Union[str, bool]] = { | ||
"trickle": trickle, | ||
"only-hash": only_hash, | ||
"pin": pin, | ||
"raw-leaves": raw_leaves if raw_leaves is not None else nocopy, | ||
} | ||
for option_name, option_value in [ | ||
("chunker", chunker), | ||
("cid-version", cid_version), | ||
]: | ||
if option_value is not None: | ||
opts[option_name] = option_value | ||
kwargs.setdefault("opts", {}).update(opts) | ||
|
||
body, headers = multipart.stream_text(string, chunk_size=self.chunk_size) | ||
return self._client.request('/add', decoder='json', | ||
data=body, headers=headers, **kwargs) | ||
|
||
def add_json(self, json_obj, **kwargs): | ||
def add_json(self, json_obj, | ||
trickle: bool = False, | ||
only_hash: bool = False, | ||
chunker: ty.Optional[str] = None, | ||
pin: bool = True, | ||
raw_leaves: bool = None, | ||
cid_version: ty.Optional[int] = None, | ||
**kwargs: base.CommonArgs) -> str: | ||
"""Adds a json-serializable Python dict as a json file to IPFS. | ||
|
||
.. code-block:: python | ||
|
@@ -302,12 +385,42 @@ def add_json(self, json_obj, **kwargs): | |
---------- | ||
json_obj : dict | ||
A json-serializable Python dictionary | ||
trickle | ||
Use trickle-dag format (optimized for streaming) when generating | ||
the dag; see `the old FAQ <https://github.com/ipfs/faq/issues/218>`_ | ||
for more information | ||
only_hash | ||
Only chunk and hash, but do not write to disk | ||
chunker | ||
The chunking algorithm to use | ||
pin | ||
Pin this object when adding | ||
raw_leaves | ||
Use raw blocks for leaf nodes. (experimental). (Default: ``True`` | ||
when *nocopy* is True, or ``False`` otherwise) | ||
cid_version | ||
CID version. Default value is provided by IPFS daemon. (experimental) | ||
|
||
|
||
Returns | ||
------- | ||
str | ||
Hash of the added IPFS object | ||
""" | ||
opts: ty.Dict[str, ty.Union[str, bool]] = { | ||
"trickle": trickle, | ||
"only-hash": only_hash, | ||
"pin": pin, | ||
"raw-leaves": raw_leaves if raw_leaves is not None else nocopy, | ||
} | ||
for option_name, option_value in [ | ||
("chunker", chunker), | ||
("cid-version", cid_version), | ||
]: | ||
if option_value is not None: | ||
opts[option_name] = option_value | ||
kwargs.setdefault("opts", {}).update(opts) | ||
|
||
return self.add_bytes(encoding.Json().encode(json_obj), **kwargs) | ||
|
||
|
||
|
@@ -330,4 +443,4 @@ def get_json(self, cid, **kwargs): | |
object | ||
Deserialized IPFS JSON object value | ||
""" | ||
return self.cat(cid, decoder='json', **kwargs) | ||
return self.cat(cid, decoder='json', **kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale for enabling the experimental
raw blocks
feature whennocopy
is enabled? Since it's experimental, canraw blocks
be left disabled by default even whennocopy
is being used?Note - I'm not yet suggesting the behavior must change, but rather seeing to understand the choice first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no rationale, I'm working by copy/pasting here. I was just trying to scratch an itch (e.g. why
add()
hasonly_hash=True
butadd_str()
did not.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like we need @ntninja to provide some more background on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raw_leaves
is a prerequisite fornocopy
on the daemon side because of how no-copy blocks are stored there.Also I already asked @ftyers to remove the
nocopy
argument because it does not make sense for content not added from local files or URLs. So all that is really needed here is:nocopy
in the docs (the entire Default: part can go)False
instead ofNone
"raw-leaves": raw_leaves if raw_leaves is not None else nocopy,
to just"raw-leaves": raw_leaves,
below (that should also fix the test failure)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
raw blocks
still an experimental feature? (ignoring that the entire IPFS is v0.x lol)Is some adjustment needed to both this new docstring and the existing docstrings mentioning raw blocks / raw leaves?