Flask: Request works on browser but not on Postman - flask

I'm creating a simple Flask app. My problem is that when I try to do a request from Postman, I alway get a 501 Not Implemented.
However, if I do the request directly from my browser, I got a successful response.
My code is:
from flask import Flask, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class Logs(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(Logs, '/logs')
if __name__ == '__main__':
app.run(debug=True, load_dotenv=True)
I'm not sure what is causing Postman to not being able to communicate with the app.
I'm sure I'm sending a GET request from Postman.
I'm attaching my Postman request configuration as an image.

Did you make sure you put your request type to GET and not to POST on Postman? The error usually means that the server doesn't know the request type and maybe expects a POST request but a post request hasn't been implemented in the Resource in your flask endpoint.

Related

Why does my Flask base URL not work in Google App Engine?

I'm working on a project right now that I'm deploying to Google App Engine. I've almost got everything working except for one thing. I can't get the base URL to work.
I'm using Flask and flask-restx to build an API. I've configured flask-restx to display the swagger documentation when accessing the url something.ey.r.appspot.com/api/and serve the API endpoints from the url something.ey.r.appspot.com/project-api/. All of these endpoints work as expected. However, I want to serve a static html file at the base url of the application. For test purposes I have changed that to a simple "Hello World". Below you can see my Script in main.py
app = Flask(__name__)
app.config['CORS_HEADERS'] = 'Content-Type'
CORS(app, resources={r"/*": {"origins": "*"}}, supports_credentials=True)
api = Api(app,
version='0.1',
title='Project API',
description='An API to access the System',
authorizations=authorizations,
doc='/api/'
)
#app.route('/')
def home():
return 'Hello World'
project_api = api.namespace('project-api', description='Project API')
#project_api.route('/projects')
#project_api.doc(security='Api-Key')
#project_api.doc(responses={200: 'Success', 400: 'Invalid Argument', 401: 'Unauthorized', 500: 'Internal Server Error'})
class ProjectListOperations(Resource):
def get(self, *args, **kwargs):
sys = ProjectSystem()
projects = sys.get_all_projects()
return projects
if __name__ == '__main__':
app.run(debug=True)
When running this code locally, everything works fine. I can see "Hello World" when accessing localhost:5000/ and all API-Endpoints and swagger documentation work. However, when deployed to Google App Engine, the base URL with the "Hello World" doesn't load. It instead returns Not Found The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. For reference, my app.yaml looks like this:
runtime: python39
handlers:
- url: /.*
script: main.py
Has anybody experienced this before and knows a solution for this?
Thanks in advance,

Using telethon with a django application

I want to watch updates on telegram messages in an django application and interact with django orm.
I found telethon library, it works with user api which is what I want.
Below code simply works on its own.
from telethon import TelegramClient
from telethon import events
api_id = 231232131
api_hash = '32131232312312312edwq'
client = TelegramClient('anon', api_id, api_hash)
#client.on(events.NewMessage)
async def my_event_handler(event):
if 'hello' in event.raw_text:
await event.reply('hi!')
client.start()
But telethon requires phone message verification and it needs to work in a seperate thread.
I couldn't find a way to put this code in a django application. And when django starts, I dont know how to bypass phone verification.
It should always work in an seperate loop and interact with django orm. Which is very confusing for me.
You can simply use django-telethon and use the API endpoints for signing bot and user session.
run the following command to start the server:
python manage.py runserver
run the following command to start telegram client:
python manage.py runtelegram
go to admin panel and telegram app section. create a new app. get data from the your Telegram account.
request code from telegram:
import requests
import json
url = "127.0.0.1:8000/telegram/send-code-request/"
payload = json.dumps({
"phone_number": "+12345678901",
"client_session_name": "name of the client session"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
send this request for sign in:
import requests
import json
url = "127.0.0.1:8000/telegram/login-user-request/"
payload = json.dumps({
"phone_number": "+12345678901",
"client_session_name": "name of the client session",
"code": "1234",
"password": "1234"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
It's not the answer I wanted initially.
But, I think this is better approach.
Instead of trying to put all of this in django application. It's better to run it seperately and let django application communicate this with rest framework.

How to make a request to local URL as part of automated tests?

I'm writing an automated test in Django to check that a webhook is working on the application. The test sends a bunch of JSON to the webhook and will check that the call has been logged in the database. The problem I'm hitting however is that the test calls the http://localhost URL and the data is thus saved in my local dev database and not in the temporary database created by the test. So I now have no way to check the call has been received.
Whats the right solution for this?
from django.test import TestCase
import requests
from monzo.models import Transaction, RequestLog
class WebhookChecks(TestCase):
fixtures = ['db.json', ]
def test_simple_expense(self):
my_json = '{"type": "transaction.created", REMOVED FOR SECURITY }'
url = 'http://localhost/some_url/webhook/'
headers = {'Content-Type': 'application/json'}
r = requests.post(url, data=my_json, headers=headers)
if not "200" in str(r):
print("Something didn't work out. Error: "+str(r))
self.assertTrue("200" in str(r))
Use Djangos Client with which you can perform requests in your tests.
Example:
from django.test import Client
c = Client()
c.get('/some_url/..')
Another way is to use Djangos LiveServerTestCase.
You can use self.live_server_url instead of directly writing http://localhost.
This testcase sets up a live server which listens to localhost.

How to send http request to flask installed on EC2

I've tried to set up a flask restful api on EC2 and used postman to test a request, but it returned a method result not allowed after I started a debugging session. Here is my python file:
from flask import Flask
from flask_restful import Api, Resource, reqparse
app=Flask(__name__)
api=Api(app)
data={
#angle
"a":0,
#hasStarted
"hs":False
}
class Angle(Resource):
def put(self):
parser=reqparse.RequestParser()
parser.add_argument("a")
parser.add_argument("hs")
args=parser.parse_args()
data["a"]=int(args["a"])
data["hs"]=bool(args["hs"])
return 200
api.add_resource(Angle,"/")
app.run(debug=True)
this is the PUT request I sent via postman:
ec2-xx-xxx-xx-xxx.us-east-2.compute.amazonaws.com/?a=10&hs=True
Also, I opened http (port 80), so should I use api.add_resource(Angle,"/var/www/html") instead?
I solved it. The reason is that I've already run apache on port 80, I opened 443 and ran my flask app there and it worked

error : redirect_uri_mismatch :: The redirect_uri MUST match the registered callback URL

So I am trying to learn OAuth in Flask using Github OAuth API and I am using flask_dance library for it. I am able to authenticate myself on Github and return back to my app but in its showing 404 Not Found Error and in the url its http://localhost:5000/login/authorized?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application... , The callback url seems correct as it is what I gave on github but still its showing redirect_uri mismatch .
I was reading the documentation here and got to know that we can remove redirect_uri parameter from the request but I am not sure how to do that.
( and I am on Windows 10 )
Any help would be nice. Thanks.
App.py
from flask import Flask, redirect, url_for
from werkzeug.contrib.fixers import ProxyFix
from flask_dance.contrib.github import make_github_blueprint, github
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
app.secret_key = "supersekrit"
blueprint = make_github_blueprint(
client_id="xxxxxxxxx",
client_secret="xxxxxxxx",
)
app.register_blueprint(blueprint, url_prefix="/login")
#app.route("/signup")
def index():
if not github.authorized:
return redirect(url_for("github.login"))
resp = github.get("/user")
assert resp.ok
return "You are #{login} on GitHub".format(login=resp.json()["login"])
if __name__ == "__main__":
app.run(debug=True)
Your callback URL is incorrect - it should be http://localhost:5000/login/github/authorized
The documentation for Flask-Dance says that the code creates a blueprint "github" with two views "/github" and "/github/authorized". The blueprint is also configured with a url_prefix of "/login" so your callback URL therefore needs to be http://localhost:5000/login/github/authorized.
This code makes a blueprint that implements the views necessary to be
a consumer in the OAuth dance. The blueprint has two views: /github,
which is the view that the user visits to begin the OAuth dance, and
/github/authorized, which is the view that the user is redirected to
at the end of the OAuth dance. Because we set the url_prefix to be
/login, the end result is that the views are at /login/github and
/login/github/authorized. The second view is the “authorized callback
URL” that you must tell GitHub about when you create the application.