ipfs-shipyard / py-ipfs-http-client

A python client library for the IPFS API
MIT License
678 stars 199 forks source link

🐛 : `StatusError: HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true` #318

Open hemangjoshi37a opened 1 year ago

hemangjoshi37a commented 1 year ago

Code :

import ipfshttpclient
client = ipfshttpclient.connect()  # Connects to: /dns/localhost/tcp/5001/http
res = client.add('./test.txt')
res
# {'Hash': 'QmWxS5aNTFEc9XbMX1ASvLET1zrqEaTssqt33rVZQCQb22', 'Name': 'test.txt'}

Error :

---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
File ~/.local/lib/python3.11/site-packages/ipfshttpclient/http.py:266, in HTTPClient._do_raise_for_status(self, response)
    265 try:
--> 266     response.raise_for_status()
    267 except requests.exceptions.HTTPError as error:

File /usr/lib/python3/dist-packages/requests/models.py:1021, in Response.raise_for_status(self)
   1020 if http_error_msg:
-> 1021     raise HTTPError(http_error_msg, response=self)

HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true

The above exception was the direct cause of the following exception:

StatusError                               Traceback (most recent call last)
Cell In[1], line 2
      1 import ipfshttpclient
----> 2 client = ipfshttpclient.connect()  # Connects to: /dns/localhost/tcp/5001/http
      3 res = client.add('./test.txt')
      4 res

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/client/__init__.py:101, in connect(addr, base, chunk_size, session, **defaults)
     98 client = Client(addr, base, chunk_size, session, **defaults)
    100 # Query version number from daemon and validate it
--> 101 version_str = client.version()["Version"]
    102 assert_version(version_str)
    104 # Apply workarounds based on daemon version

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/client/base.py:15, in returns_single_item.<locals>.wrapper(*args, **kwargs)
     13 @functools.wraps(func)
     14 def wrapper(*args, **kwargs):
---> 15     result = func(*args, **kwargs)
     16     if isinstance(result, list):
     17         if len(result) != 1:

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/client/miscellaneous.py:204, in Base.version(self, **kwargs)
    189 @base.returns_single_item
    190 def version(self, **kwargs):
    191     """Returns the software version of the currently connected node.
    192     
    193     .. code-block:: python
   (...)
    202             Daemon and system version information
    203     """
--> 204     return self._client.request('/version', decoder='json', **kwargs)

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/http.py:51, in pass_defaults.<locals>.wrapper(self, *args, **kwargs)
     49 merged = utils.deep_update(merged, self.defaults)
     50 merged = utils.deep_update(merged, kwargs)
---> 51 return func(self, *args, **merged)

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/http.py:385, in HTTPClient.request(self, path, args, files, opts, stream, data, decoder, headers, username, password, timeout, offline, return_result)
    381     stream = False
    383 parser = encoding.get_encoding(decoder if decoder else "none")
--> 385 res = self._request(method, url, params, stream, files, headers,
    386                     username, password, data, timeout)
    388 if not return_result:
    389     return None

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/http.py:307, in HTTPClient._request(self, method, url, params, stream, files, headers, username, password, data, timeout)
    301 res = self._do_request(method, url, params=params, stream=stream,
    302                        files=files, headers=headers, auth=auth,
    303                        data=data, timeout=timeout)
    305 # Raise exception for response status
    306 # (optionally incorporating the response message, if applicable)
--> 307 self._do_raise_for_status(res)
    309 return res

File ~/.local/lib/python3.11/site-packages/ipfshttpclient/http.py:286, in HTTPClient._do_raise_for_status(self, response)
    284     six.raise_from(exceptions.ErrorResponse(msg, error), error)
    285 else:
--> 286     six.raise_from(exceptions.StatusError(error), error)

File <string>:3, in raise_from(value, from_value)

StatusError: HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true
kasteph commented 1 year ago

@hemangjoshi37a what kubo version are you using?

You can get it by running this in your shell:

ipfs --version
hemangjoshi37a commented 1 year ago
(base) hemang@hemang-HP-Pavilion-g6-Notebook-PC:~$ ipfs --version
ipfs version 0.17.0
crushr3sist commented 1 year ago

Are we attempting to provide users with version-based options? Because I personally think, despite there being consistent releases of Kubo, we should only support a single version of IPFS. It could seem like more work to constantly update code to support changes made in Kubo but it could at least provide a bit of control into what the actual issues are with the library. I was just curious because most of the issues are either associated with version issues or with the connection to the api which I believe is caused by the version being out of date causing an exception to be raised.

hemangjoshi37a commented 1 year ago

@kasteph @Wizock and all other contributors,

I appreciate your insights and comments on this issue. From my understanding, the bug StatusError: HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true is likely due to the HTTP method used by the py-ipfs-http-client in making a request to the IPFS API not being supported.

The IPFS version I'm running is 0.17.0. I suspect that the HTTP method we're using is no longer supported in this version of IPFS. The discrepancy in HTTP methods may be the root cause of the problem.

@Wizock 's suggestion is intriguing - focusing on a single, consistent version of IPFS and Kubo, which would make debugging and code maintenance more straightforward. This could prevent issues arising from version incompatibility in the future. However, we also need to bear in mind that we are potentially limiting the usability for those on different versions.

As a potential resolution to this issue, I'd suggest checking the HTTP method being used in the py-ipfs-http-client codebase when making a request to the IPFS API. If the method has indeed changed in the recent IPFS versions, we should update our client library to use the new method. This would likely solve the problem for those using newer versions of IPFS.

Nonetheless, I agree that a long-term strategy for managing IPFS version compatibility should be put in place to prevent similar issues in the future. I'm open to further discussions and suggestions from the community.