HTTP Error: Backend error. 400 Bad Request

Hi, I'm trying to pull some data with the following:

screener_tsvx = "SCREEN(U(IN(Equity(active,public,primary))/*UNV:Public*/), IN(TR.ExchangeMarketIdCode,""TSXV"",""XTNX"",""XTSE"",""XTSX""), TR.AvgDailyValTraded20D>=GMEDIAN(ZAV(TR.AvgDailyValTraded20D),universe=""univ""), CURN=CAD)" 
ek.get_data([screener_tsvx],["TR.CommonName"])
# ek.get_data([screener_tsx],["TR.CommonName;TR.InstrumentType;TR.CompanyMarketCap"])

It works in excel, but in my jupyter notebook I get the following HTTPError:

---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
<ipython-input-100-fa4ae8947122> in <module>()
1 screener_tsvx = "SCREEN(U(IN(Equity(active,public,primary))/*UNV:Public*/), IN(TR.ExchangeMarketIdCode,""TSXV"",""XTNX"",""XTSE"",""XTSX""), TR.AvgDailyValTraded20D>=GMEDIAN(ZAV(TR.AvgDailyValTraded20D),universe=""univ""), CURN=CAD)"
----> 2 ek.get_data([screener_tsvx],["TR.CommonName"])
3 # ek.get_data([screener_tsx],["TR.CommonName;TR.InstrumentType;TR.CompanyMarketCap"])

~\Anaconda3\lib\site-packages\eikon\data_grid.py in get_data(instruments, fields, parameters, field_name, raw_output, debug)
149 payload = {'instruments': instruments,'fields': fields_for_request}
150 if parameters: payload.update({'parameters': parameters})
--> 151 result = eikon.json_requests.send_json_request(DataGrid_UDF_endpoint, payload, debug=debug)
152
153 if raw_output:

~\Anaconda3\lib\site-packages\eikon\json_requests.py in send_json_request(entity, payload, ID, debug)
85 if response.status_code == 200:
86 result = response.json()
---> 87 check_server_error(result)
88 return result
89 if response.status_code == 401:

~\Anaconda3\lib\site-packages\eikon\json_requests.py in check_server_error(server_response)
133 else:
134 status_code = server_response['ErrorCode']
--> 135 raise requests.HTTPError(error_message, response=server_response)
136
137 # check DataGrid error

HTTPError: Backend error. 400 Bad Request

I've seen some suggestions of queries timing out, but I'm not sure if this is the case. I've also been unable to find a detailed documentation on how the `instruments` field for the get_data function can be specified. I've been trying to use the Screener function as a work around, and now I've run into the HTTP Backend error. Not entirely sure what my options are now. Any suggestions, advice would be nice.

Thank you!

Best Answer

  • Alex Putkov.1
    Answer ✓

    The use of equity screener through Eikon Data APIs is not supported yet. One reason for this is that currently any get_data request is automatically timed out from the server side if the server cannot return the data requested in 15 seconds. Rendering the data through screener can take much longer than 15 seconds to complete, in which case you get back "HTTPError: Backend error. 400 Bad Request". Work is being done to address this issue. Until this work is complete the screener through Eikon Data APIs can only be used for basic expressions that the server can render in less than 15 seconds.

    Could you elaborate on what you expect from "detailed documentation on how the instruments field for the get_data function can be specified"? It seems you've already checked the "Eikon Data APIs for Python - Reference Guide" available from the Documentation tab on Eikon Data APIs page on this portal, which provides definition of all the methods and their signatures available in Eikon Data APIs for Python. Per this document the "instruments" argument is a string representing an identifier for a single instrument or a list of strings where each string represents an instrument identifier. For instrument identifier you can use a variety of symbol types including RIC, ISIN, CUSIP, SEDOL, Wertpapierkennnummer, PermID etc. If you have a list of instrument identifiers for which you need market or fundamental & reference data, you can use this list directly to retrieve the data using get_data method, e.g.

    ek.get_data(['TRI.N','AAPL.O'],['TR.Revenue'])
    The screener is useful when you need to identify stocks that satisfy your criteria.

Answers

  • I guess I'm asking if there's a list that provides all possible types of values that the get_data `instruments` field can take. For example, I can provide `['TRI.N', 'AAPL.O']` which is a list of symbols. I could also use `'#0.SPX'`, as well as `"SCREEN()"` or `"PORTFOLIO()"`. I was wondering what other options there are and whether or not there is a documented list of allowed methods available.

    Thank you!

  • I see. Well, you pretty much listed all of them. The only one you missed is "LISTS()", which is similar to "PORTFOLIO()". When instruments argument is a single string, it can take the same string values you can provide to the first argument of =TR function in Excel, notwithstanding the known issue with the server timeout that I described earlier.

  • The values the Universe argument of =TR function can take are documented in the Help, which you can access from the Thomson Reuters tab in Eikon Excel ribbon. But even this documentation is not necessarily all exhaustive. E.g. it doesn't specifically mention using chain RICs such as "0#.SPX" as universe, and we may be adding other types of universes in the future.

  • Ok, Thank you!

  • Hi,

    Any updates getting equity screener support in the API? I'm still getting the same timeout error.

  • Hi dear, I have enjoyed reading this article, its well written,well presented and informative.Have learnt a lot about blog posting and i find it awesome. Thank you for the great tips! If you need a support for Canon Printer then contact us: canon printer offline

  • Make sure you use the latest version of Eikon Data APIs library for Python. Version 1.0.1 of the library released in May 2019 introduced a fix that greatly reduced the occurrence of "EikonError: Error code 400 | Backend error. 400 Bad Request" due to timeouts from the backend. Currently the most recent production version of Eikon Data APIs library for Python on PYPI is v1.0.2.

  • Yeah I'm definitely on 1.0.2. Guess I'll find another way. Thanks

  • If you're on v1.0.2, then the error is not due to a timeout from the backend. Are you sure the syntax in your Screener expression is correct? Do you want me to try your call on my end and see if I can reproduce the error?

  • def get_exchange_at_once(country): 
        
        country_to_get = "SCREEN(U(IN(Equity(active,public))/*UNV:Public*/), IN(TR.ExchangeCountryCode, "+"'"+country+"'))"
        df = pd.DataFrame
        file = 'file.csv'
        
        df, e = ek.get_data(country_to_get, \
                            ['TR.COMMONNAME', \
                            'AVG(TR.TURNOVER(SDATE=2019-01-01, EDATE=2019-10-31, CURN=USD))', \
                            'TR.FREEFLOAT', \
                            {'TR.CLOSEPRICE':{'params':{'CURN':'USD'}}}])
        df.to_csv(file, sep=',', mode='a', header=False)

    countries = ['AU', 'NZ', 'JP', 'CN']
    for i in countries: 
        get_exchange_at_once(i)


    Any thoughts on a better way to do this? I have a working version which pulls the data one RIC at a time, so no rush.


    Thank you.

  • I don't see any syntax errors. This code runs fine on my end. I'm able to retrieve all the data requested. There's a logical error in your code: when you run the loop the content of file.csv is overwritten rather than added to. I would also suggest simplifying the syntax for TR.CLOSEPRICE field. Instead of {'TR.CLOSEPRICE':{'params':{'CURN':'USD'}}} use 'TR.CLOSEPRICE(CURN=USD)'. But as I said the code runs fine for me.

  • Thanks Alex. mode='a' appends to the csv file. I have it working on another query. Thanks for the tip on syntax.

  • Oh yeah, you're right. I missed mode='a' parameter. I stand corrected.

  • The 400 Bad Request error is an HTTP status code indicates that the request you sent to the webserver was malformed , in other words, the data stream sent by the client to the server didn't follow the rules. It means that the request itself has somehow incorrect or corrupted and the server couldn't understand it. There are a number of different causes for a 400: Bad Request Error . It might be a malformed request syntax, invalid request message framing, or deceptive request routing . In most cases, the problem is on the website itself, and there's not much you can do about that.

  • The "400 Bad Request" error is an HTTP status code that indicates the server cannot process the request due to a client error. This error usually occurs when the server receives an invalid or malformed request from the client.Double-check the URL you're accessing and ensure that it is correct. Additionally, review any parameters or data being sent with the request and verify their format and validity.Ensure that the request follows the proper syntax for the HTTP method being used (e.g., GET, POST, PUT, DELETE). Check that the headers, body, and formatting of the request are correct.

  • Here are a few possible reasons for encountering this error:

    1. Incorrect syntax: The request may have incorrect syntax, such as missing or invalid headers, improper URL formatting, or missing required parameters. Review the request and ensure that it follows the correct syntax.

    2. Invalid or missing data: The request may be missing required data or include invalid data. Check that all the necessary data is provided and that it is in the correct format. https://community.developers.refinitiv.com/questions/27832/http-error-backend-error-400-bad-request.html?childToView=109210 Donkey Kong childToView=109210#answer-109210