question

Upvotes
Accepted
5 2 2 4

urlencode list universe in data/symbology/convert

Hello,

I am using the elektron platform's category=data/symbology, endpoint=convert and I am also using python3's urllib for making GET/POST request.

I can use the following GET method for converting symbols (which means my headers, auth, etc are all good):

https://api.refinitiv.com/data/symbology/beta1/convert?universe=IBM.N@RIC,MSFT.O@RIC

However when I tried to use the POST method and construct the body with a list of symbols I get 400 error. More specifically, what is the anticipated body for the following data:

data = {

"universe": [

"IBM.N",

"MSFT.O",

]

}

is it 'universe=IBM.N&universe=MSFT.O', 'universe=IBM.N,MSFT.O', 'universe%5B%5D=%5B%27IBM.N%27%2C+%27MSFT.O%27%5D' or 'universe=%5B%27IBM.N%27%2C+%27MSFT.O%27%5D'? The later two are given by urllib's urlencode method.

Thanks,

rdp-apirefinitiv-data-platformsymbologyposturl
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
Accepted
14.7k 39 12 18

The body of the POST message should be a JSON object. when you pass the dictionary object to the library, the object gets split up and is sent as individual name/value pairs.

I used:

data = json.dumps(requestData)

and it works. Try using a debugging proxy to catch and verify the actual request that your application is sending down and crosscheck it with the capture that I have posted here.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
7.6k 15 6 9

@yuan.shen

Http Status code 400 is a Bad Request. Your request body is not a valid format.

Please remove ',' after "MSFT.O". The correct one should be

data = { "universe": [ "IBM.N", "MSFT.O" ] } 

You can also try your JSON request data with APIDocs Playground before using it with your python codes.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 2 2 4

@moragodkrit

It still does not work without the ','.

python's urlencode treat them the same as an input Dict[str, List[str]] and after encoding, I am looking for the right format of the body your API expects.

Again, I am struggling to find whether it is

(1) 'universe=IBM.N&universe=MSFT.O'

(2) 'universe=IBM.N,MSFT.O'

(3) 'universe%5B%5D=%5B%27IBM.N%27%2C+%27MSFT.O%27%5D'

(4) 'universe=%5B%27IBM.N%27%2C+%27MSFT.O%27%5D'

after the encoding? None of them seems to work for me.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
14.7k 39 12 18

This is the raw HTTP capture:

POST https://api.refinitiv.com/data/symbology/beta1/convert HTTP/1.1
Host: api.refinitiv.com . .
Content-Length: 31
Authorization: Bearer eyJ0eXAiOiJK****

{"universe":["MSFT.O","IBM.N"]}

If you post your code snippet, we can help you tweak it.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 2 2 4

@Gurpreet.

Here is a minimal code snippet I have been using, it employs OpenerDirector from urllib because my company environment needs SSLCertificate, ProxyHandler, etc that goes beyond the functionalities of the request library.

Below, 'YOUR TOKEN STR' is the access_token from auth/oauth2, token endpoint.

from urllib.parse import urlencode

from urllib.request import build_opener, Request

opener = build_opener()

opener.addheaders = [

('Authorization', 'Bearer %s' % 'YOUR TOKEN STR'),

('Accept', 'application/json'),

('Content-Type', 'application/json')

]

# GET works for me

ans = opener.open(Request('https://api.refinitiv.com/data/symbology/beta1/convert?universe=MSFT.O,IBM.N'))

# which one of them is correct? None works for me

data = '{"universe":["MSFT.O","IBM.N"]}'

data = urlencode({"universe": ["MSFT.O", "IBM.N"]})

data = urlencode({"universe": ["MSFT.O", "IBM.N"]}, doseq=True)

# POST

ans = opener.open(Request('https://api.refinitiv.com/data/symbology/beta1/convert'), data=data.encode('utf-8'))

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
5 2 2 4

@Gurpreet.

Thanks for the tip, it helps solving the problem, json.dumps would give a string that equals the first data I listed above:

data = '{"universe":["MSFT.O","IBM.N"]}'

The problem is with my function call of Request, my opener has the header of (Content-Type, application/json) but it is not added to the Request object. when I changed it to the following it works

req = Request('https://api.refinitiv.com/data/symbology/beta1/convert')

req.add_header('Content-Type', 'application/json')

ans = opener.open(req, data='{"universe":["MSFT.O","IBM.N"]}'.encode('utf-8'))

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.