OpenDroneMap / WebODM

User-friendly, commercial-grade software for processing aerial imagery. šŸ›©
https://www.opendronemap.org/webodm/
GNU Affero General Public License v3.0
2.85k stars 953 forks source link

Method "DELETE" not allowed #504

Closed martinsoko closed 6 years ago

martinsoko commented 6 years ago

How did you install WebODM? (Docker, natively, ...)?

Docker

What's your browser and operating system? (Copy/paste the output of https://www.whatismybrowser.com/)

Your web browser is: Edge 42 on Windows 10 Is your Web browser up to date? āœ“ Your web browser is up to date.

What is the problem?

I'm working on a python script to automate the generation of orthomosaics. So far it worked great but I can't delete projects via the requests.delete API.

What should be the expected behavior?

Projects should be deleted

How can we reproduce this? (What steps did you do to trigger the problem? What parameters are you using for processing? If possible please include a copy of your dataset uploaded on Google Drive or Dropbox. Be detailed)

I have a parser that parses the arguments passed via command line to my python script like the project ID, paths to the images to process and path to the output folder.

res = 0
res = requests.post('http://localhost:8000/api/token-auth/', 
                    data={'username': webodm_user,
                          'password': webodm_pass}).json()

res = requests.post('http://localhost:8000/api/projects/', 
                    headers={'Authorization': 'JWT {}'.format(token)},
                    data={'name': args.project_id}).json()

I create a list of images as it says in the documentation and then I use it to create the task

options = json.dumps([
    {'name': "resize-to", 'value': 2048},
    {'name': "orthophoto-resolution", 'value': 100},
    {'name': "fast-ortophoto", 'value': "true"},
    {'name': "min-num-features", 'value': 12000},
    {'name': "dem-terrain-type", 'value': "ComplexNonForest"}
])
res = 0
res = requests.post('http://localhost:8000/api/projects/{}/tasks/'.format(project_id), 
            headers={'Authorization': 'JWT {}'.format(token)},
            files=images,
            data={
                'options': options
            }).json()

Then I wait for the task to complete and download the orthomosaic.

So far so good.

The issue comes when I try to delete the project.

res = requests.delete('http://localhost:8000/api/projects/', headers={'Authorization': 'JWT {}'.format(token)},data={'name': args.project_id}).json()
res
Out[15]: {'detail': 'Method "DELETE" not allowed.'}

I've checked the permissions for the project and I should be able to delete it

res = requests.get('http://localhost:8000/api/projects/', headers={'Authorization': 'JWT {}'.format(token)}).json()

res
Out[17]: 
{'count': 1,
 'next': None,
 'previous': None,
 'results': [{'id': 58,
   'tasks': [],
   'created_at': '2018-08-23T12:26:22.920346Z',
   'permissions': ['add', 'change', 'delete', 'view'],
   'name': 'farlopa',
   'description': ''}]}

I've also tried deleting the project using the 'id' instead of the 'name' but the result was the same. Any help would be useful.

Thanks in advance!

pierotofy commented 6 years ago

Hey @martinsoko :hand:, deletion is the one operation that deviates a bit from REST conventions. To delete a task, you make a POST request as follows:

POST /api/projects/{project_id}/tasks/{task_id}/remove/

http://docs.webodm.org/#remove-task

The reason we don't allow DELETE is because Django's REST Framework would delete the record from the database right after the call, but WebODM needs to do some asynchronous processing before the task can be deleted, so we set the tasks' pending_action to REMOVE and we delete it for real when everything is ready. See http://docs.webodm.org/#pending-actions

Not sure if this should be improved. Are you going to share your script when it's done? Would love to see what people are building with the API.

martinsoko commented 6 years ago

Hi @pierotofy, thanks for your reply.

What happens if I want to delete the whole project at once? I didn't find anything about that in the documentation.

I reverse-engineered the Web GUI and managed to come up with requests.delete('http://localhost:8000/api/projects/{}/'.format(args.project_id), headers={'Authorization': 'JWT {}'.format(token)})

It removes the project from the list but I'm not sure if I should still do some clean up afterwards. Based on what you said, I should first remove the task, wait until it's actually removed and then remove the project. What do you think of that?

Once I have it finished if you want I can share my script!

pierotofy commented 6 years ago

The call is correct. If you delete a project, all tasks associated with it will be automatically deleted also. http://docs.webodm.org/#delete-a-project

No need to cleanup tasks manually. :+1:

Yes please share it when it's done!