Error: "405 Client Error: Method Not Allowed" while connecting to IPFS using ipfshttpclient in Django project
I’m working on a Django project where I’m using IPFS to store and retrieve files. However, I’m encountering an issue when trying to use the ipfshttpclient (or ipfsapi) library to connect to the IPFS daemon.
When I run the migrate command in my Django project, I get the following error:
405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true
(env) root@LAPTOP-SEOPFS2E:~/project/EMS/env/project/clgproject# python manage.py migrate
/root/project/EMS/env/project/clgproject/EMS/views.py:12: FutureWarning: The `ipfsapi` library is deprecated and will stop receiving updates on the 31.12.2019! If you are on Python 3.5+ please enable and fix all Python deprecation warnings (CPython flag `-Wd`) and switch to the new `ipfshttpclient` library name. Python 2.7 and 3.4 will not be supported by the new library, so please upgrade.
import os, requests, ipfsapi , ipfshttpclient #added by DD 'ipfshttpclient'
Traceback (most recent call last):
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 266, in _do_raise_for_status
response.raise_for_status()
File "/root/project/EMS/env/lib/python3.8/site-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.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:
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 87, in handle
executor = MigrationExecutor(connection, self.migration_progress_callback)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 49, in __init__
self.build_graph()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 206, in build_graph
self.load_disk()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 108, in load_disk
migration_module = import_module(migration_path)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 848, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/root/project/EMS/env/project/clgproject/EMS/migrations/0001_initial.py", line 11, in <module>
class Migration(migrations.Migration):
File "/root/project/EMS/env/project/clgproject/EMS/migrations/0001_initial.py", line 30, in Migration
('paper', models.FileField(storage=ipfs_storage.InterPlanetaryFileSystemStorage(), upload_to='')),
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfs_storage/__init__.py", line 32, in __init__
self._ipfs_client = ipfsapi.connect(
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfsapi/client/__init__.py", line 88, in connect
assert_version(client.version()['Version'])
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfsapi/client/__init__.py", line 205, in wrapper
return value(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/client/base.py", line 15, in wrapper
result = func(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/client/miscellaneous.py", line 204, in version
return self._client.request('/version', decoder='json', **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 51, in wrapper
return func(self, *args, **merged)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 385, in request
res = self._request(method, url, params, stream, files, headers,
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 307, in _request
self._do_raise_for_status(res)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 286, in _do_raise_for_status
six.raise_from(exceptions.StatusError(error), error)
File "<string>", line 3, in raise_from
ipfshttpclient.exceptions.StatusError: HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true
(env) root@LAPTOP-SEOPFS2E:~/project/EMS/env/project/clgproject# python manage.py migrate
/root/project/EMS/env/lib/python3.8/site-packages/ipfs_storage/__init__.py:7: FutureWarning: The `ipfsapi` library is deprecated and will stop receiving updates on the 31.12.2019! If you are on Python 3.5+ please enable and fix all Python deprecation warnings (CPython flag `-Wd`) and switch to the new `ipfshttpclient` library name. Python 2.7 and 3.4 will not be supported by the new library, so please upgrade.
import ipfsapi
Traceback (most recent call last):
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 266, in _do_raise_for_status
response.raise_for_status()
File "/root/project/EMS/env/lib/python3.8/site-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.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:
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 87, in handle
executor = MigrationExecutor(connection, self.migration_progress_callback)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 49, in __init__
self.build_graph()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 206, in build_graph
self.load_disk()
File "/root/project/EMS/env/lib/python3.8/site-packages/django/db/migrations/loader.py", line 108, in load_disk
migration_module = import_module(migration_path)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 848, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/root/project/EMS/env/project/clgproject/EMS/migrations/0001_initial.py", line 11, in <module>
class Migration(migrations.Migration):
File "/root/project/EMS/env/project/clgproject/EMS/migrations/0001_initial.py", line 30, in Migration
('paper', models.FileField(storage=ipfs_storage.InterPlanetaryFileSystemStorage(), upload_to='')),
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfs_storage/__init__.py", line 32, in __init__
self._ipfs_client = ipfsapi.connect(
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfsapi/client/__init__.py", line 88, in connect
assert_version(client.version()['Version'])
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfsapi/client/__init__.py", line 205, in wrapper
return value(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/client/base.py", line 15, in wrapper
result = func(*args, **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/client/miscellaneous.py", line 204, in version
return self._client.request('/version', decoder='json', **kwargs)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 51, in wrapper
return func(self, *args, **merged)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 385, in request
res = self._request(method, url, params, stream, files, headers,
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 307, in _request
self._do_raise_for_status(res)
File "/root/project/EMS/env/lib/python3.8/site-packages/ipfshttpclient/http.py", line 286, in _do_raise_for_status
six.raise_from(exceptions.StatusError(error), error)
File "<string>", line 3, in raise_from
ipfshttpclient.exceptions.StatusError: HTTPError: 405 Client Error: Method Not Allowed for url: http://localhost:5001/api/v0/version?stream-channels=true
Here’s a snippet of my code where the issue arises:
Views.py
from django.shortcuts import render,redirect
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.views.decorators.csrf import csrf_exempt
from django.contrib import messages
from .models import *
from .encryption import *
from .a_encryption import *
from django.conf import settings
from django.core.files import File
#import os, requests, ipfsapi , ipfshttpclient #added by DD 'ipfshttpclient'
import os, requests,ipfshttpclient #added by DD 'ipfshttpclient'
# Create your views here.
def user_login(request):
if request.user.role == 'teacher':
return redirect('teacher_dashboard')
if request.user.role == "coe":
return redirect('coe_dashboard')
if request.user.role == 'superintendent':
return redirect('st_dashboard')
@login_required(login_url='login')
@csrf_exempt
def user_logout(request):
logout(request)
return HttpResponseRedirect('/')
@login_required(login_url='login')
@csrf_exempt
def teacher_dashboard(request):
p_request = Request.objects.filter(tusername=request.user.username,status='Pending')
a_request = Request.objects.filter(tusername=request.user.username).exclude(status='Pending')
if request.method == 'POST':
if request.POST.get('accept'):
username = request.user.username
b_id = request.POST['b_id']
Request.objects.filter(tusername=username,id=b_id).update(status='Accepted')
messages.success(request, 'Request Accepted! Click on Accepted Request Section on check your requests.',extra_tags='accept')
else:
paper = request.FILES.get('paper',None)
key = encrypt_file(paper)
#api = ipfsapi.connect('127.0.0.1', 5001)
#api = ipfshttpclient.connect('127.0.0.1', 5001) #added by DD 'ipfshttpclient'
api = ipfshttpclient.connect('/ip4/127.0.0.1/tcp/5001') #added by DD 'ipfshttpclient'
new_file = api.add('static/encrypted_files/'+str(paper)+'.encrypted')
hash_id = new_file['Hash']
arr = a_encryption(hash_id,key,request.user.teacher_id)
file_ = open(os.path.join(settings.ENCRYPTION_ROOT,request.user.teacher_id+'_private_key.pem'),'rb')
p_file = File(file_)
store = Request.objects.get(tusername=request.user.username)
store.private_key.save(request.user.teacher_id+'_private_key.pem',p_file,save=True)
store.enc_field = arr
store.status = 'Uploaded'
store.save()
os.remove('static/encrypted_files/'+str(paper)+'.encrypted')
messages.success(request, 'Paper uploaded successfully!', extra_tags='upload')
return render(request,'teacher.html',{'p_request':p_request,'a_request':a_request})
@login_required(login_url='login')
@csrf_exempt
def coe_dashboard(request):
if request.method == "POST":
s_code = request.POST['s_code']
t_id = request.POST['t_id']
Request.objects.filter(s_code=s_code).exclude(id=t_id).delete()
queryset,created = Request.objects.update_or_create(id=t_id,defaults={'status':'Finalized'})
messages.success(request, 'Paper has been finalized and sent to respective superintendent.')
f_papers = Request.objects.filter(id=t_id).values('tusername','enc_field','private_key','s_code')
for paper in f_papers:
teacher = CustomUser.objects.filter(username=paper['tusername']).values('course','semester','branch','subject')
values = a_decryption([paper['enc_field'],paper['private_key']])
hash_id = values[1].decode('utf-8')
r = requests.get('http://localhost:8080/ipfs/'+hash_id)
final_paper = decrypt_file(r,values[0],paper['s_code'])
FinalPapers.objects.create(s_code=paper['s_code'],course=teacher[0]['course'],semester=teacher[0]['semester'],
branch=teacher[0]['branch'],subject=teacher[0]['subject'])
final = FinalPapers.objects.latest('id')
final.paper.save(paper['s_code']+'.pdf',final_paper,save=True)
requests_ = Request.objects.values('tusername','status')
arr = []
for r in requests_:
name = CustomUser.objects.filter(username=r['tusername']).values('first_name','last_name')
arr.append({'name':name[0]['first_name']+ " " + name[0]['last_name'],'status':r['status']})
return render(request,'coe.html',{'arr':arr})
@login_required(login_url='login')
@csrf_exempt
def st_dashboard(request):
queryset = FinalPapers.objects.all()
return render(request,'superintendent.html',{'queryset':queryset})
def get_teachers(request):
course = request.POST.get('course',None)
semester = request.POST.get('semester',None)
branch = request.POST.get('branch',None)
subject = request.POST.get('subject',None)
queryset1 = Request.objects.values('tusername').distinct()
s_code = SubjectCode.objects.filter(subject=subject).values()
queryset2 = Request.objects.filter(s_code=s_code[0]['s_code'],status='Uploaded').values('id')
queryset = CustomUser.objects.filter(course=course,semester=semester,branch=branch,subject=subject).exclude(username__in=queryset1).values()
data = { 'queryset':list(queryset),'s_code':s_code[0]['s_code'],'queryset2':list(queryset2) }
return JsonResponse(data)
def add_teacher(request):
s_code = request.POST.get('s_code',None)
syllabus = request.FILES.get('syllabus',None)
q_pattern = request.FILES.get('q_pattern',None)
t_id = request.POST.get('g_id')
deadline = request.POST.get('deadline',None)
username = CustomUser.objects.filter(id=t_id).values('username')
print(s_code,syllabus,t_id)
Request.objects.create(tusername=username[0]['username'],s_code=s_code,syllabus=syllabus,q_pattern=q_pattern,deadline=deadline)
new_teacher = CustomUser.objects.filter(username=username[0]['username']).values()
return JsonResponse({'new_teacher':list(new_teacher)})
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
import datetime
from django.contrib.postgres.fields import ArrayField
def teacherID():
t_id = 'TEA-1'
try:
prev = CustomUser.objects.values('teacher_id').last()
prev = prev['teacher_id']
number = prev.split('-')[1]
number=int(number)+1
t_id = 'TEA-'+str(number)
except:
t_id='TEA-1'
return t_id
ROLE = (
('teacher','teacher'),
('coe','coe'),
('superintendent','superintendent')
)
SEM = (
('None','None'),
('I','I'),
('II','II'),
('III','III'),
('IV','IV'),
('V','V'),
('VI','VI'),
('VII','VII'),
('VIII','VIII')
)
BRANCH = (
('None','None'),
('CSE','CSE'),
('IT','IT'),
('ECE','ECE'),
('EEE','EEE'),
('MECH','MECH'),
('BioTech','BioTech')
)
SUB = (
('None','None'),
('Compiler Design','Compiler Design'),
('Digital Signal Processing','Digital Signal Processing'),
('Cloud Computing','Cloud Computing'),
('Agile Development','Agile Development')
)
STATUS = (
('Pending','Pending'),
('Accepted','Accepted'),
('Uploaded','Uploaded'),
('Finalized','Finalized')
)
class CustomUser(AbstractUser):
teacher_id = models.CharField(max_length=20,default=teacherID,blank=True)
course = models.CharField(max_length=4,choices = (('None','None'),('B.E.',"B.E."),('M.E.','M.E.')),default='None')
semester = models.CharField(max_length=4,choices = SEM, default='None')
branch = models.CharField(max_length=40,choices=BRANCH,default='None')
subject = models.CharField(max_length=30,choices=SUB,default='None')
role = models.CharField(max_length=20,choices = ROLE, default='teacher')
def __str__(self):
return self.username
class Request(models.Model):
tusername = models.CharField(max_length=40,default='None')
s_code = models.CharField(max_length=7,default="None")
syllabus = models.FileField(default=None)
q_pattern = models.FileField(default=None)
deadline = models.DateField(default=datetime.date.today)
status = models.CharField(max_length=10,default='Pending')
enc_field = ArrayField(models.BinaryField(max_length=500,default=None),default=list)
private_key = models.FileField(default=None)
def __str__(self):
return self.tusername
class FinalPapers(models.Model):
s_code = models.CharField(max_length=7,default="None")
course = models.CharField(max_length=4,default='None')
semester = models.CharField(max_length=4,default='None')
branch = models.CharField(max_length=40,default='None')
subject = models.CharField(max_length=30,default='None')
paper = models.FileField(default=None)
def __str__(self):
return self.s_code
class SubjectCode(models.Model):
s_code = models.CharField(max_length=7)
subject = models.CharField(max_length=40)
def __str__(self):
return self.subject
Here's the image of my daemon running
Steps Taken So Far:
Verified that the IPFS daemon is running by visiting http://localhost:5001/webui. The web UI loads successfully.
Checked the IPFS daemon version using ipfs --version. My current version is 0.32.1.
Updated the ipfshttpclient library to the latest version (pip install --upgrade ipfshttpclient).
Questions:
Why is the IPFS daemon returning a 405 Method Not Allowed error for the /version endpoint?
How can I correctly configure my Django project and IPFS integration to resolve this issue?
Is there a specific compatibility issue between the ipfshttpclient library and my IPFS daemon version?
Environment Details:
Host OS: Windows (via WSL2)
WSL OS: Ubuntu 20.04
Python Version: 3.8
Django Version: 3.2
ipfshttpclient Version: 0.4.13.2 (installed via pip)
IPFS Daemon Version: 0.32.1
I've never worked on these tech stack and this project is cloned from the github repo. please let me know if any other information required