0

I am trying to create easy demo example for REST API using Flask. My code is Ok when I am testing it from localhost. But been deployed with Pythonanywhere free account, I have 400 Error. I.e. requests without params still works properly, but only GET requests with params start to give 400.

   response = requests.get(
        'https://api.openweathermap.org/data/2.5/weather',
        params=params
    )

Here is the proving - api.openweathermap.org is in the whitelist enter image description here

any help please?

This is the part of final code

import requests

URL = "http://demoapi.pythonanywhere.com"

def printer(method, requests_answer):
    print(F"{requests_answer=} for {method=}")
    if requests_answer:
        print(F"{requests_answer.text}")
        try:
            print(F"{requests_answer.json()=}")
        except:
            print('json is not present')
    print("\n", 30*"*^")
    

response = requests.get(URL)
printer('GET' ,response)

response = requests.get(URL + '/data/weather/Львів')
printer('GET', response)

params = dict(city_name='Львів')
response = requests.get(URL + '/data/weather', params=params)
printer('GET', response)

So requests.get(URL) and requests.get(URL + '/data/weather/Львів') is still Ok, but requests.get(URL + '/data/weather', params=params) gives 400.

Please say any when give me MINUS for this question...

P.S. My investigations show - only PUT and POST work on Pythonanywhere host, GET and DELETE gives 400. At localhost the same code works properly with GET POST PUT DELETE. The same code.

Code for interesting readers. Say again. This code wors properly:

import requests

NO_PROXY = {
    'no': 'pass',
}

URL = 'http://127.0.0.1:5000'


def printer(method, requests_answer):
    print(F"{requests_answer=} for {method=}")
    if requests_answer:
        print(F"{requests_answer.text}")
        try:
            print(F"{requests_answer.json()=}")
        except:
            print('json is not present')
    print("\n", 30*"*^")
    

response = requests.get(URL, proxies=NO_PROXY)
printer('GET' ,response)

response = requests.get(URL + '/data/weather/Львів', proxies=NO_PROXY)
printer('GET', response)

params = dict(city_name='Львів')
response = requests.get(URL + '/data/weather', params=params, proxies=NO_PROXY)
printer('GET', response)

and PARTIALY wrong if URL = "http://demoapi.pythonanywhere.com"

Here is the server full code if needed

from flask import Flask, jsonify, request, make_response
#  https://stackoverflow.com/questions/13081532/return-json-response-from-flask-view

from get_weather_by_cityname import get_city_weather

app = Flask(__name__)

prohibited_city_names ={
    1: 'Днепр',
    2: 'Киев',
    3: 'Львов',
    4: 'Одесса',
}

def my_jsonify(json_text: str):
    resp = make_response(json_text)
    resp.headers['Content-Type'] = 'application/json'  
    return resp   


@app.route('/')
@app.route('/api')
def index():
    return """<h1>  Опис ІПЗ визначення поточної погоди за назвою міста!  </h1>
    <p>  <i><b>Користуємось так:</i></b></p>
    <p>  https:/demoapi.pythonanywhere.com/data/weather/Львів</p>
    <p>  <i><b>Отримуємо таке:</i></b></p>
    <pre>  
    {
    "погода описово": "хмарно",
    "температура, C": 8.22,
    "температура відчувається як": 5.24,
    "атмосферний тиск": 1022,
    "вологість повітря": 72,
    "відсоток неба в хмарах": 100
    }
    </pre>
    """ 



@app.route('/data/weather/<city_name>', methods=['GET'])
def get_wether_in_town(city_name):
    city_name = city_name.strip()
    if city_name not in prohibited_city_names.values():
        return my_jsonify(get_city_weather(city_name))
    else:
        return 'Помилка в назві міста ...'


@app.route('/data/weather', methods=['GET'])
def get_data():
    print(F'--------get_data, {request.json=}   {request.args.get("city_name")=}', flush=True)
    city_name = request.args.get("city_name")
    if city_name:
        if city_name not in prohibited_city_names.values():
            print(request.json, flush=True)
            return my_jsonify(get_city_weather(city_name))
        else:
            return 'Помилка в назві міста ...'
    else:
        print(F'--------get_data, {request.json=}', flush=True)
        return jsonify(prohibited_city_names)


if __name__ == '__main__':
    app.run(debug=True)
Vasyl Kolomiets
  • 365
  • 8
  • 20
  • 2
    The 400 error response might have a readable body that explains the error. This code hardly constitutes a MCVE, the error could be in the contents of the params. – Antti Haapala -- Слава Україні Apr 09 '23 at 06:39
  • 1
    @AnttiHaapala--СлаваУкраїні Look. I've said. The code works properly when I am testing from IDE on localhost. It gives expected result. BUT when I'll try the same from Pythonanywhere hosting request with params gives 400. Yes You right. Героям Слава – Vasyl Kolomiets Apr 09 '23 at 06:47
  • But the final code does not use api.openweather. In any case you want to print the `response.text` for the failed response. – Antti Haapala -- Слава Україні Apr 09 '23 at 06:54
  • @AnttiHaapala--СлаваУкраїні - Ive placed the `server` code for my question now ) Thanks for been patiant ) – Vasyl Kolomiets Apr 09 '23 at 06:56
  • What does your print in the first line of `get_data` show? – Giles Thomas Apr 09 '23 at 13:54
  • @GilesThomas nothing when placed on pythonanywhere and: --------get_data, request.json=None request.args.get("city_name")='Львів' from localhost – Vasyl Kolomiets Apr 09 '23 at 14:34
  • @AnttiHaapala--СлаваУкраїні 400 Bad Request

    Bad Request

    The browser (or proxy) sent a request that this server could not understand.

    ----- response.headers = {'Date': 'Sun, 09 Apr 2023 17:54:28 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Content-Length': '167', 'Connection': 'keep-alive', 'Server': 'PythonAnywhere'} ---- Look. My OS is Wimdows. PythonAnywhere - Linux. Some encoding problems may be?
    – Vasyl Kolomiets Apr 09 '23 at 18:15
  • I'd recommend adding "flush=True" as a kwarg at the end of your prints on PythonAnywhere; it might just be that Python is buffering output. – Giles Thomas Apr 13 '23 at 20:47

0 Answers0