TandoorRecipes / recipes

Application for managing recipes, planning meals, building shopping lists and much much more!
https://docs.tandoor.dev
Other
5.56k stars 589 forks source link

Not able to GET/POST from Django REST API #2352

Closed IRONROCK20 closed 1 year ago

IRONROCK20 commented 1 year ago

Issue

Hello to everyone,

Firstly, thanks for all the incredible work, it’s fantastic!!!!!!

I’ve issues trying to GETting the Rest API. I’m hosting it, with also a lot of other things in my NAS (it’s a Syno). I’ve a calendar server that sync directly with my iOS devices, and also a Flask werbserver where inserting a list let me compare the prices in a webpage of the grocery shops here in Spain to order goods online.

So, I need to do two things:

First GET the /api/meal-plan/ (adding a time with the python code) for sending it to the DaviCal (so it can update the iOS calendars).

The second in the Grocery Buy Flask server is simply a button that retrieve the grocery list, put the products list in a column, select those and finally clicking on it, will search in multiple websites (in multiple forms).

I tried almost everything, every time that I try to GET with a python code, bash or curl it always answer me that I don’t have the permission or credentials. I tried with user and password, I tried with the Bearer Token, I tried to store the CSFR Token with cookies but all of these without success. At the end, I changed the Rest Framework to AllowAny, but also without success.

Any hints?

Thank you in advance!

Following the Bash Script with cURL:

Retrieve session cookies from login page

curl -c cookies.txt http://192.168.188.40:8777/admin/login/

Extract CSRF token from cookies file

TOKEN=$(grep csrftoken cookies.txt | awk '{print $NF}') SESSION=$(grep sessionid cookies.txt | awk '{print $NF}')

curl -c cookies.txt -b cookies.txt -d "username=iron&password=Cuse1234&csrfmiddlewaretoken=$TOKEN&a=1&csrfmiddlewaretoken=$TOKEN" http://192.168.188.40:8777/admin/login/

Send POST request to login page with username, password, and CSRF token

curl -X POST -d "username=iron&password=Cuse1234&csrfmiddlewaretoken=$TOKEN" -b cookies.txt http://192.168.188.40:8777/admin/login/

curl -X GET http://192.168.188.40:8777/api/meal-plan/ -d username=iron -d password=Cuse1234 csrfmiddlewaretoken=$TOKEN

Send GET request to meal plan API endpoint with API token

curl -v -X GET -H "X-CSRFToken: $TOKEN" --cookie "csrftoken=$TOKEN;sessionid=$SESSION" http://192.168.188.40:8777/api/meal-plan/?format=json

Delete cookies file

rm cookies.txt


I also tried with Python:

import requests import json import time import icalendar from flask import Flask, Response from datetime import datetime, timedelta

app = Flask(name)

Define the URL of the API

url = "http://192.168.188.40:8777/api/plan-ical/{}/{}/"

Define the headers to include the API token

headers = { "Authorization": "Token tda_805faedb_bd0e_4252_9c67_28536bd4e134", "Content-Type": "application/json" }

Define a function to convert the JSON response to an iCal format

def json_to_ical(json_data): events = [] for item in json_data: try: summary = item["summary"] description = item["description"] start_time = datetime.strptime(item["start_time"], "%Y-%m-%dT%H:%M:%S.%fZ") end_time = datetime.strptime(item["end_time"], "%Y-%m-%dT%H:%M:%S.%fZ") if item.get("end_time") else None

        event = icalendar.Event()
        event.add('summary', summary)
        event.add('description', description)
        event.add('dtstart', start_time)
        event.add('dtend', end_time)
        events.append(event)

    except (TypeError, KeyError) as e:
        print(f"Error parsing item {item}: {e}")

calendar = icalendar.Calendar()
calendar.add('prodid', '-//My Calendar//EN')
calendar.add('version', '2.0')

for event in events:
    calendar.add_component(event)

return calendar.to_ical()

@app.route('/calendar.ics') def generate_calendar(): while True:

Calculate the next Monday and Sunday dates

    today = datetime.today()
    next_monday = today + timedelta(days=(7 - today.weekday()) % 7)
    next_sunday = next_monday + timedelta(days=6)

    # Format the dates as strings for the API URL
    from_date = next_monday.strftime("%Y-%m-%d")
    to_date = next_sunday.strftime("%Y-%m-%d")

    # Make the API request and convert the response to JSON
    response = requests.get(url.format(from_date, to_date), headers=headers)
    json_data = json.loads(response.text)

    # Convert the JSON data to iCal format
    ical_data = json_to_ical(json_data)

    # Wait for 30 seconds before making the next API request
    time.sleep(30)

    # Return the iCal data as a response to the GET request
    resp = Response(ical_data, status=200, mimetype='text/calendar')
    resp.headers['Content-Disposition'] = 'attachment; filename=calendar.ics'
    return resp

if name == 'main': app.run(host='0.0.0.0', port=8666, debug=True, threaded=True)

Tandoor Version

Last available

OS Version

In a Docker Container

Setup

Synology

Reverse Proxy

No reverse proxy

Other

No response

Environment file

No response

Docker-Compose file

The original Plain Docker Compose

Relevant logs

No response

vabene1111 commented 1 year ago

The issue is probably the request header, it should be

headers = {
"Authorization": "Bearer tda_805faedb_bd0e_4252_9c67_28536bd4e134",
"Content-Type": "application/json"
}

also make sure your token has the read and write scope, you can set that in your user account settings

IRONROCK20 commented 1 year ago

Thanks for the answer! No way... I got 403 Error with the python code and with the cURL command I got : {"detail":"Authentication credentials were not provided."}

cURL command: curl -X GET -H "Authorization: Bearer tda_805faedb_bd0e_4252_9c67_28536bd4e134" http://192.168.188.40:8777/api/meal-plan/?format=json

Yes, the Bearer Token is set to read write.

Any ideas?

IRONROCK20 commented 1 year ago

Sorry it's solved. A Docker Container error, with the JSON's Header it's working fine. Thank you so much for the support and for the great work!