I have a view function that initiates user login requests
it looks something like this:
def initiate_login(request):
# get request parameters
return check_user_and_send_otp(login_id)
The request is then processed by another function
def check_user_and_send_otp(login_id):
# check if user exits
return send_otp_to_user(phone_number)
And then another function
def send_otp_to_user(phone_number):
# sends a message to user
return response
The problem is while testing my code, I don't want to send messages to a phone number while testing.
My login test function looks somewhat like this, is it possible to mock it without changing my code?
def test_login_initiator(self):
response = self.client.post(self.login_url, data=self.login_data, content_type="application/json", **self.headers)
self.assertEqual(response.status_code, 200)
All these functions that were called by others are located in seperate modules
If you don't want to actually receive the message on a physical phone, you can use online sms receivers. Check out this blog.
Additionally, you can send messages through other free online services like Way2sms. You just have to google them up. To do this from within Python, you need to use web parsing using urllib2/requests and beautifulsoup, which is a totally new question.
Or you can skip this function by simply commenting out the message sender code or returning true from the function.
If you wanna live dangerously, think about making a config file which can help you to make switches that tell whether to execute something or not.
The right thing to do would be use something like magic mock and structure the code into proper classes so that we can create mock objects for each of them.
Related
I'm having a hard time trying to wrap my mind around this issue - is it possible to somehow use more than just one Stripe API key in Djstripe webhook handler? If so, how?
I have two client apps, both using Stripe. Expectedly, there are two sets of Stripe API keys, each set for a client app. There are no issues with making the payment intents and charging, app is sending enough info, and the keys are explicitly defined (e.g. stripe.api_key = STRIPE_SECRET_KEY) so those part of the code can juggle between API keys succesfully.
The hard problem I have encountered is, Stripe webhook handler does not have info to do the juggling - it fails with an error saying:
stripe.error.InvalidRequestError: Request <req_id>: No such payment_intent: <payment_intent_id>
Sure enough, if I use only one set of API keys, it'll do as expected, but I'd need them both.
My idea is to use two webhook endpoints, but I'm not sure how to define additional webhook endpoint in my config/urls.py file. Currently, I'm using this:
urlpatterns = [
...
path("stripe/", include("djstripe.urls", namespace="djstripe")),
...
In the webhook.py file, I'm using #webhooks decorator:
#webhooks.handler('payment_intent.succeeded')
def payment_intent_succeeded(event, **kwargs):
# code goes here...
Since there are only two sets of API keys, I can try to use one key in try block, then use another if that one fails, but there is some magic configuration string usage there I was not able to crack, code inside that webhook never gets executed, so I can't even try that approach.
I was wondering is there any way to define what API key to use there?
Thank you for any ideas!
(I'm using dj-stripe version 2.5.1, and yes, I've inherited that code)
I’m new to django programming, not python, and could do with a hand.
I am attempting to make a website exclusive to a certain device. I have created a disallow page accessible by '/disallow/'. How do I go about running os/browser checks that then redirect in the event the os/browser is not on the verified list.
I know the information I am wanting to check will be in the request and I can use
request.META['HTTP_USER_AGENT']
However where do I write any logic required and how could I apply this to any page the user tries to access.
Any help would really be appreciated
Ed
You'll want a Django middleware. It sits in front of all response handlers, so it can capture every request and take any action on it that you require.
Simple example (untested), a function that returns a function:
your_app/middleware.py
def restrict_middleware(get_response):
def middleware(request):
if request.META['HTTP_USER_AGENT'] == ...:
return redirect('/disallow/')
else:
return get_response(request)
return middleware
Then register your_app.middleware.restrict_middleware in the MIDDLEWARE array in your settings file.
Note that such browser/OS detection relies on what the browser/OS itself is claiming that it is, and can easily be spoofed on the client. So don't use this for any security purposes.
I have created an API using the Bottle Library in Python. It endpoints look like this
#app.get('/api/users/<id>', name='user')
def get_user(model, id):
user = model.get_user(id)
if not user:
return HTTPError(404, 'User not found')
else:
response.content_type = "application/json"
return json.dumps(user)
I want to call the API in other functions within the same app
#app.route('/users/<id>')
def users (id=1):
user = request.get("http://localhost:8001/api/user/1")
return template('user', user=user)
However, this is showing no results. The request get timed out each time
So my question is, how to call a bottle API from within that app using Requests library or through any other means.
Are you running Bottle in single-threaded mode (the default)? If so, then your internal get request will hang forever. This is because your server can serve only one request at a time, and you are asking it to handle two at once: the first call to /users/<id>, and then the second call to /api/users/<id>.
A band-aid fix would be to run the server in asynchronous mode. Try this method and see if your timeouts go away:
run(host='0.0.0.0', port=YOUR_PORT_NUMBER, server='gevent')
However: You shouldn't be designing your application this way in the first place. Instead, refactor your code so that both methods can call a function that returns the JSON representation of a user. Then one api call can return that raw json object, while the other api call can present it as HTML. NOTE: that's not how I would design this API, but it's the answer that's the shortest distance from how you've structured your application so far.
I have some code I want to run for every request that comes into Flask-- specifically adding some analytics information. I know I could do this with a decorator, but I'd rather not waste the extra lines of code for each of my views. Is there a way to just write this code in a catch all that will be applied before or after each view?
Flask has dedicated hooks called before and after requests. Surprisingly, they are called:
Flask.before_request()
Flask.after_request()
Both are decorators:
#app.before_request
def do_something_whenever_a_request_comes_in():
# request is available
#app.after_request
def do_something_whenever_a_request_has_been_handled(response):
# we have a response to manipulate, always return one
return response
I am new to python. I am using Flask for creating a web service which makes lots of api calls to linkedin. The problem with this is getting the final result set lot of time and frontend remains idle for this time. I was thinking of returning partial results found till that point and continuing api calling at server side. Is there any way to do it in Python? Thanks.
Flask has the ability to stream data back to the client. Sometimes this requires javascript modifications to do what you want but it is possible to send content to a user in chunks using flask and jinja2. It requires some wrangling but it's doable.
A view that uses a generator to break up content could look like this (though the linked to SO answer is much more comprehensive).
from flask import Response
#app.route('/image')
def generate_large_image():
def generate():
while True:
if not processing_finished():
yield ""
else:
yield get_image()
return Response(generate(), mimetype='image/jpeg')
There are a few ways to do this. The simplest would be to return the initial request via flask immediately and then use Javascript on the page you returned to make an additional request to another URL and load that when it comes back. Maybe displaying a loading indicator or something.
The additional URL would look like this
#app.route("/linkedin-data")
def linkedin():
# make some call to the linked in api which returns "data", probably in json
return flask.jsonify(**data)
Fundamentally, no. You can't return a partial request. So you have to break your requests up into smaller units. You can stream data using websockets. But you would still be sending back an initial request, which would then create a websocket connection using Javascript, which would then start streaming data back to the user.