Http Post Request - TypeError: 'Response' object is not subscriptable - http-post

I'm trying to write a request for an api to pull a csv for trade histories. I'm having an issue when it gets to the actual request and I'm not sure whether its a client issue, something to do with the libraries, or the way I'm making the request itself. The API is hosted on dYdX's servers and there are a few dependencies -I've follow most of the docs (https://docs.dydx.exchange/).
Here are the imports:
from dydx3 import Client
from dydx3 import constants
from dydx3 import epoch_seconds_to_iso
from os import path
import ciso8601
import datetime
import pprint
import subprocess
import sys
import time
import json
and here is the client initialization and request:
client2 = Client(
host = _api_host,
network_id = _network_id,
api_key_credentials = {
'key': _api_key,
'secret': _api_secret,
'passphrase': _api_passphrase
}
)
get_account_result2 = client2.private.get_account(
ethereum_address = _eth_address
)
account2 = get_account_result2['account']
It keeps crashing on the line with account2 = get_account_result2['account'], TypeError: 'Response' object is not subscriptable. I've run it through Windows and Linux (Ubuntu) Python 3. I feel like it's a syntax thing with the json? Is there something I'm missing?

You are trying to access the ‘account’ value of that Response object as if it’s a dictionary object (subscriptable) but it is not. The good news is it likely has a method to show you the response in json, text or dictionary from.
To see which methods or attributes the Response object has try:
dir(get_account_result2)
If there is a "json" method in that list, you might want to try:
get_account_result2.json()[‘account’]
If there is an "account" attribute (not callable) or method (callable) respectively, you could also try:
get_account_result2.account or get_account_result2.account()
I dont have a dydx account so I cannot verify if any of this works.

Related

FastAPI links created by url_for in Jinja2 template use HTTP instead of HTTPS

I migrated an application in Flask served by waitress to FastAPI served by uvicorn, but I can't force the links (generated by url_for inside the index.html template) to use HTTPS instead of HTTP.
With waitress I used:
from waitress import serve
import flask_app
PORT=5000
HOST_IP_ADDRESS='0.0.0.0'
serve(flask_app.app, host=HOST_IP_ADDRESS, port=PORT, url_scheme="https")
with uvicorn I tried to use proxy_headers, but that didn't work. I used a workaround in the index.html
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
which correctly loaded the style.css from static files, but the links to another endpoint still use HTTP.
Is there an easy way to force all links created by url_for to use HTTPS?
I have also run into this issue before. One possible solution is to create a custom url_for function which changes the protocol, then add it to the Jinja environment. One possible implementation may look something like this:
template = Jinja2Templates("/path/to/templates")
def https_url_for(request: Request, name: str, **path_params: Any) -> str:
http_url = request.url_for(name, **path_params)
# Replace 'http' with 'https'
return http_url.replace("http", "https", 1)
template.env.globals["https_url_for"] = https_url_for
You will have to pass the request to the function so it knows how to generate the url_for, but the request should be passed in to your Jinja2 template either way.
You can then use it in your Jinja2 template like this:
https_url_for(request, "/https/path", search="hi")
The resulting url should look like https://<domain>/https/path?search=hi.
I had the same problems. On develop environment all links were with http.
I solved it this way.
from starlette.templating import Jinja2Templates
from sqladmin import Admin
from jinja2 import ChoiceLoader, FileSystemLoader, PackageLoader
import jinja2
if hasattr(jinja2, "pass_context"):
pass_context = jinja2.pass_context
else:
pass_context = jinja2.contextfunction
#pass_context
def https_url_for(context: dict, name: str, **path_params) -> str:
request = context["request"]
http_url = request.url_for(name, **path_params)
return http_url.replace("http", "https", 1)
class CustomAdmin(Admin):
def init_templating_engine(self) -> Jinja2Templates:
templates = Jinja2Templates("templates")
loaders = [
FileSystemLoader(self.templates_dir),
PackageLoader("sqladmin", "templates"),
]
templates.env.loader = ChoiceLoader(loaders)
templates.env.globals["min"] = min
templates.env.globals["zip"] = zip
templates.env.globals["admin"] = self
templates.env.globals["is_list"] = lambda x: isinstance(x, list)
templates.env.globals["url_for"] = https_url_for
return templates
After all just import this class in main file and init the admin class

Unable to start a Session in Flask within a function

I'm running Flask Session and using Eve as an API. For the Session code I'm following the example here https://pythonhosted.org/Flask-Session/
from flask import Flask, session
from flask.ext.session import Session
app = Flask(__name__)
# Check Configuration section for more details
SESSION_TYPE = 'redis'
app.config.from_object(__name__)
Session(app)
#app.route('/set/')
def set():
session['key'] = 'value'
return 'ok'
#app.route('/get/')
def get():
return session.get('key', 'not set')
I have an Eve API located under /api, and I want to avoid starting a new Session for those requests at least.
I want to start my flask Session only if the request.environ['PATH_INFO'] doesn't start with '/api/' but whenever I put Session() anywhere else it fails.
Following the example:
sess = Session()
sess.init_app(app)
When I try to do that in before_request or similar, then I get:
A setup function was called after the first request was handled.
and if I try to start a session in a normal content generator I get:
AttributeError: 'SecureCookieSession' object has no attribute 'sid'
How can I start a session conditionally, depending on the path/environment/etc?
My current code looks like this:
import flask
import xml.etree.ElementTree as ElementTree
from bson.objectid import ObjectId
from random import shuffle, choice as pick
from cgi import escape as escapehtml
from time import mktime
from urllib import quote as escapeurl, unquote_plus as unescapeurl
from flask import Flask, request, session, render_template, send_from_directory, jsonify, redirect, abort
from flask.ext.session import Session
from flask.ext.login import LoginManager, login_user, logout_user, current_user, UserMixin, user_logged_in, login_required, fresh_login_required
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired, URLSafeTimedSerializer
from flask_mail import Mail, Message
from wtforms import Form, BooleanField, PasswordField
from flask.ext.mongoengine import MongoEngine
from flask.ext.security import Security, MongoEngineUserDatastore, RoleMixin, UserMixin
from flask.ext.principal import Principal, Permission, RoleNeed
from flask_security.forms import RegisterForm, Required, StringField
from flask_images import Images
from eve import Eve
from eve.auth import TokenAuth
from flask.ext.moment import Moment
from eve.io.mongo import Validator
from flask.ext.cors import CORS, cross_origin
from app.admin.one1 import one1
from app.emails.emails import emails
from app.alligator.alligator import alligator
from app.data.ndm_feed.ndm_feed import ndm_feed
from flask.ext import excel
...
login_serializer = URLSafeTimedSerializer(app.secret_key)
login_manager = LoginManager()
app.config.from_object(__name__)
login_manager.init_app(app)
Session(app)
and to avoid starting sessions for API calls I am trying to do things like this:
#app.before_request
def before_request():
if not request.environ['PATH_INFO'].startswith('/api/'):
Session(app)
or the equivalent:
#app.before_request
def before_request():
if not request.environ['PATH_INFO'].startswith('/api/'):
sess = Session()
sess.init_app(app)
But I can't seem to find a way to do it without the errors above.
How can I start a Flask session conditionally, depending on the path/environment/etc?
Actually your app already created before you use this: #app.before_request so it means you are late to add new configuration or extension initialize. Bu you can do with Blueprint:
# api.py
from flask import Blueprint
from flask_session import Session
sess = Session()
api = Blueprint('api', __name__)
# yourapp.py
...
def create_app():
...
try:
from api import api, sess
sess.init_app(app)
app.register_blueprint(api)
# views.py
#api.route('/set/')
def set():
session['key'] = 'value'
return 'ok

How to config a HTTP Request Method GET with JSON BODY in JMeter?

I'm facing the issue while writing the scenario in JMeter. It's API using GET Method and requires JSON BODY.
It's very easy if the method is POST/PUT. But I don't know how to do with method GET. I tried: Add HTTP Header Manager with Content-Type:application/json, but nothing help.
As I know, using BODY with GET request is the not the good way, but the developer team has implemented like that, and it can be worked with curl.
So I would like to know can we config this in JMeter or not? and How?
Thanks in advance.
In fact sending request body with HTTP GET request is not supported by Apache HttpComponents and hence in JMeter, you should be able to send a GET request with JSON body using JSR223 Sampler and the following code (assumes Groovy language):
import org.apache.http.HttpResponse
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.util.EntityUtils
public class HttpGetWithBody extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "GET";
#Override
public String getMethod() {
return METHOD_NAME;
}
}
def client = HttpClientBuilder.create().build();
def getRequest = new HttpGetWithBody();
getRequest.setURI(new URL("http://example.com").toURI());
def json = "{\"employees\":[\n" +
" {\"firstName\":\"John\", \"lastName\":\"Doe\"},\n" +
" {\"firstName\":\"Anna\", \"lastName\":\"Smith\"},\n" +
" {\"firstName\":\"Peter\", \"lastName\":\"Jones\"}\n" +
"]}";
def body = new StringEntity(json, "application/json", "UTF-8");
getRequest.addHeader("Content-Type", "application/json");
getRequest.setEntity(body);
def response = client.execute(getRequest);
def result = EntityUtils.toString(response.getEntity());
log.info(result);
See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! article for more information on using JSR223 test elements and groovy language and scripting best practices.
There is a reported bug in JMeter for this https://bz.apache.org/bugzilla/show_bug.cgi?id=60358 and looks like the fix is on the way. Hopefully this issue would be fixed soon.

Okta api python sdk throwing json error

I'm trying to create a user with the python sdk. When I run my script, I get the following error:
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/sitepackages/oktasdk-python/okta/framework/ApiClient.py", line 53, in post
if self.__check_response(resp, attempts):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/sitepackages/oktasdk-python/okta/framework/ApiClient.py", line 88, in __check_response
raise OktaError(json.loads(resp.text))
okta.framework.OktaError.OktaError: The request body was not well-formed: Could not read JSON
Here is a snippet of my code:
from okta.UsersClient import UsersClient
from collections import namedtuple
def main():
create_okta_user()
def create_okta_user():
usersClient = UsersClient("https://example.okta.com", "0d0d0dexamplekey")
User = namedtuple("User", ["login", "email", "firstName", "lastName"], verbose=False, rename=False)
user = User(login="test#example.com",
email="test#example.com",
firstName="user",
lastName="tester")
usersClient.create_user(user, activate=False)
#usersClient.activate_user(user)
main()
It looks like you're trying to use a namedtuple, which is serialized to a json list, not an object.
Try using the User model like this:
from okta import UsersClient
from okta.models.user import User
def main():
create_okta_user()
def create_okta_user():
usersClient = UsersClient("https://example.okta.com", "0d0d0dexamplekey")
user = User(login="test#example.com",
email="test#example.com",
firstName="user",
lastName="tester")
user = usersClient.create_user(user, activate=False)
#usersClient.activate_user(user)
main()
http://developer.okta.com/docs/sdk/core/python_api_sdk/quickstart.html#create-a-user

Authenticating Multiple Scopes in Google API Oauth2.0

I need to insert multiple scopes into the http post request that creates the service object that permits authentication. However, simply putting in multiple scopes into the string doesn't seem to achieve this unfortunately, returning the error at the bottom.
import gflags
import apiclient
import oauth2client
import argparse
from oauth2client import client
from oauth2client import file
from oauth2client import tools
from apiclient import discovery
from apiclient import sample_tools
import httplib2
import sys
import os
import pprint
from pprint import pprint
name = 'prediction'
scope = "https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/devstorage.full_control testing_data/training_data.csv testing_data/training_data.csv"
filename = '__file__'
client_secrets = os.path.join(os.path.dirname(filename),
'client_secrets.json')
flow = client.flow_from_clientsecrets(client_secrets,scope=scope)
storage = file.Storage(name+'.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run(flow, storage)
http = credentials.authorize(httplib2.Http())
service = discovery.build('prediction','v1.6',http=http)
papi = service.trainedmodels()
result = papi.list(maxResults=10,project='895092811023').execute()
body = {'id':'Universities','storageDataLocation':'testing_data/training_data.csv'}
start = papi.insert(body=body,project='895092811023').execute()
This is the error, which points out that the required scopes are missing. (It is recording some scope, because it is saving a result to result, but just not letting me insert a new model, which I believe is due to the fact that it isn't getting the scope to access the data for this model, which is in Google Cloud Storage?
Traceback (most recent call last):
File "filehere", line 42, in <module>
start = papi.insert(body=body,project='895092811023').execute()
File "build\bdist.win-amd64\egg\oauth2client\util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Python27\lib\site-packages\apiclient\http.py", line 680, in execute
raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 401 when requesting https://www.googleapis.com/prediction/v1.6/projects/895092811023/trainedmodels?alt=json returned "Required scope(s) missing.">
The only thing you need to pass in for scopes are the www.googleapis.com things such as: https://www.googleapis.com/auth/prediction, don't pass in "testing_data/training_data.csv testing_data/training_data.csv".
You can always visit https://accounts.google.com/b/0/IssuedAuthSubTokens and see the scopes that your application has been granted.

Resources