2

I use requests to send some data to a server. The URL needs to look like "http://IP:PORT/api/json/v1/transfer/transferItem?organisation=Organisation&branch=1&itemnumber=1&operation=U&dyn=VARIABLE1=blabla;VARIABLE2=blabla"

I Used the following Code:

def send(self):
    for i in range(1, 8):
        try:
            self.statusBar().showMessage('Connection...')
            resp = requests.get(url,
                params={'organisation': 'Organisation', 'branch': '1', 'itemnumber': str(i), 'operation': 'U', 'dyn': {'VARIABLE1': 'blabla', 'VARIABLE2': 'blabla'} })
            print(resp.url)
            if resp.status_code == requests.codes.ok:
                self.statusBar().showMessage('Finished '+str(i) +' / 7')
                time.sleep(0.5)
        except requests.exceptions.ConnectionError:
            self.statusBar().showMessage('Connection Error')
            break

But the print(resp.url) always ends after ...dyn=VARIABLE1.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Andre F.
  • 33
  • 3
  • Why isn't `VARIABLE2` quoted? That is probably not what you want. – etene Apr 11 '18 at 13:24
  • You are right, but that didnt solve the problem at all :/ (i edit my text) – Andre F. Apr 11 '18 at 13:26
  • I suspect that passing nested data as `GET` request parameters won't work as intended. This looks like an use case for a `POST` request anyway. – etene Apr 11 '18 at 13:27
  • See https://stackoverflow.com/questions/29035921/how-to-pass-a-nested-dictionary-to-flasks-get-request-handler – etene Apr 11 '18 at 13:28
  • if i use `POST` i got an error from the server because it is not allowed – Andre F. Apr 11 '18 at 14:04
  • Well in that case (assuming you don't have control over what the server accepts), you'll have to encode your `params` properly, especially the `dyn` part. See the post I linked, it should give you helpful pointers. – etene Apr 11 '18 at 14:17
  • I posted some code that encodes the request parameters the way you need it as an answer, that was getting too complicated for comments. – etene Apr 11 '18 at 14:32

1 Answers1

0

Your params aren't fit for a GET request as-is because they contain a nested item (dyn).

What you should do in that particular case is encode this nested item separately in the format your server accepts. Which would give something like:

def send(self):
    for i in range(1, 8):
        try:
            self.statusBar().showMessage('Connection...')

            params = {
                'organisation': 'Organisation',
                'branch': '1',
                'itemnumber': str(i),
                'operation': 'U',
                'dyn': {'VARIABLE1': 'blabla', 'VARIABLE2': 'blabla'}
            }
            # Replace the 'dyn' param with a "key1=value1;key2=value2" representation
            params['dyn'] = ";".join("=".join(j) for j in params['dyn'].items())

            # EDIT: Got to encode the parameters ourselves or requests will urlencode them
            params = "&".join("=".join(k) for k in params.items())

            resp = requests.get(url, params)
            print(resp.url)
            if resp.status_code == requests.codes.ok:
                self.statusBar().showMessage('Finished %d / 7' % i)
                time.sleep(0.5)
        except requests.exceptions.ConnectionError:
            self.statusBar().showMessage('Connection Error')
            break

Obviously I can't test it but that should be about it. Tell me if you have issues.

However I want to stress that this isn't really good design on the server side; POST would be more appropriate for arbitrary nested data.

etene
  • 710
  • 4
  • 12
  • Thanks for the post, but i have some problems to get this into my code could you maybe show me how i need to implement this in my posted code :/? Thanks in advance – Andre F. Apr 12 '18 at 07:00
  • That seems to work near perfect :) But the requests libary replace `=` with `%3D` and `;` with `%3B` and the server cant hande this right. Do you have any idea how the solve this ? The Output looks like`http://IP:PORT/api/json/v1/transfer/transferItem?organisation=Organisation&branch=1&itemnumber=1&operation=U&dyn=VARIABLE1%3Dblabla%3BVARIABLE2%3Dblabla` – Andre F. Apr 12 '18 at 07:20
  • [this post](https://stackoverflow.com/questions/23496750/how-to-prevent-python-requests-from-percent-encoding-my-urls) is about your new problem. I'll update my answer, but I encourage you to check it out. – etene Apr 12 '18 at 07:30