Python, "TypeError: string indices must be integers, not 'str'" while not using any indices

Question:

there! Currently trying to code my first program to automate an API, but got stuck at the moment where I transfer 2 arguments from earlier functions to the 3-rd function.

BTW, feel free to leave any suggestions for the whole code, apart for the error.

Here I’m authenticating and extract the cookie token:

import requests
import json

from workfiles import general_http_methods

base_url = 'https://restful-booker.herokuapp.com'

"""Authentication"""

def booker_auth_method():
    auth_resource = '/auth'
    auth_url = base_url + auth_resource
    print(auth_url)
    auth_body = {'username': 'admin',
                 'password': 'password123'}
    result_auth_token = general_http_methods.general_post_method(auth_url, auth_body)
    json_result_auth_token = result_auth_token.json()
    value_of_the_cookie_json_result_auth_token = str(json_result_auth_token.get('token'))
    adding_token_to_value = 'token=' + value_of_the_cookie_json_result_auth_token
    result_auth_cookie_token = {'Cookie': adding_token_to_value}
    print(result_auth_cookie_token)
    return result_auth_cookie_token


booker_auth_method_var = booker_auth_method()['Cookie']

Then I create a booking:

"""Creating a booking"""


def booker_create_booking_method():
    create_booking_resource = '/booking'
    create_booking_body = {
        "firstname": 'Python',
        "lastname": "Tester",
        "totalprice": 111,
        "depositpaid": True,
        "bookingdates": {
            "checkin": "2023-01-01",
            "checkout": "2023-01-02"},
        "additionalneeds": "Breakfast"}
    create_booking_url = base_url + create_booking_resource
    print(create_booking_url)
    create_booking_result = general_http_methods.general_post_method(create_booking_url, create_booking_body)
    json_create_booking_result = create_booking_result.json()
    booking_id = json_create_booking_result.get('bookingid')
    print(json_create_booking_result)
    print(booking_id)
    return booking_id


booker_create_booking_method_var = booker_create_booking_method()

Finally, I wanna pass the return values from the 2 previous functions into the function below. To do that, I saved the return values in the variables (booker_auth_method_var, booker_create_booking_method_var) and pass them as arguments into my next function.

"Updating the WHOLE booking"


def booker_update_booking_method(booker_auth_method_var, booker_create_booking_method_var):
    update_booking_resource = '/booking/'
    update_booking_cookie_token = booker_auth_method_var  #
    update_booking_id = str(booker_create_booking_method_var)  #
    update_booking_url = base_url + update_booking_resource + update_booking_id
    update_booking_body = {
        "firstname": "Python",
        "lastname": "QA Engineer",
        "totalprice": 777,
        "depositpaid": False,
        "bookingdates": {
            "checkin": "2023-07-08",
            "checkout": "2023-07-15"},
        "additionalneeds": "ALL INCLUSIVE"}
    update_booking_result = general_http_methods.general_put_method(update_booking_url, update_booking_cookie_token, update_booking_body)
    print(update_booking_cookie_token)
    print(update_booking_url)
    print(update_booking_result.text)
    return update_booking_result


booker_update_booking_method(booker_auth_method_var, booker_create_booking_method_var)

However, at the result I get the topic error, even though I don’t even use any indices:

https://restful-booker.herokuapp.com/auth
{'Cookie': 'token=006b0313b7e7bb1'}
https://restful-booker.herokuapp.com/booking
{'bookingid': 8187, 'booking': {'firstname': 'Python', 'lastname': 'Tester', 'totalprice': 111, 'depositpaid': True, 'bookingdates': {'checkin': '2023-01-01', 'checkout': '2023-01-02'}, 'additionalneeds': 'Breakfast'}}
8187
Traceback (most recent call last):
  File "/Users/usr/PycharmProjects/booker_automation/workfiles/booker_http_methods.py", line 80, in <module>
    booker_update_booking_method(booker_auth_method_var, booker_create_booking_method_var)
  File "/Users/usr/PycharmProjects/booker_automation/workfiles/booker_http_methods.py", line 72, in booker_update_booking_method
    update_booking_result = general_http_methods.general_put_method(update_booking_url, update_booking_cookie_token,
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/booker_automation/workfiles/general_http_methods.py", line 20, in general_put_method
    result = requests.put(url, headers=headers, cookies=cookies, json=body)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/autom_udemy_course_smith/lib/python3.11/site-packages/requests/api.py", line 130, in put
    return request("put", url, data=data, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/autom_udemy_course_smith/lib/python3.11/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/autom_udemy_course_smith/lib/python3.11/site-packages/requests/sessions.py", line 573, in request
    prep = self.prepare_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/autom_udemy_course_smith/lib/python3.11/site-packages/requests/sessions.py", line 471, in prepare_request
    cookies = cookiejar_from_dict(cookies)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/usr/PycharmProjects/autom_udemy_course_smith/lib/python3.11/site-packages/requests/cookies.py", line 537, in cookiejar_from_dict
    cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
                                             ~~~~~~~~~~~^^^^^^
TypeError: string indices must be integers, not 'str'

Process finished with exit code 1

The key issue for me here is how to pass the booking id from func 2 into the resource path in the final function. I need to transform it from int to str to concatenate with base_url and update_booking_resource, but it causes the error.

I have already tried to workaround, but it causes other mistakes like

  • ‘int’ object is not subscriptable
  • dict object is not callable

so I believe I have to deal with exactly this mistake but do not understand how

Asked By: bull1t

||

Answers:

So I finally found out the reason:

In the first block I had to call not the key of the dict from the method, but the method itself as only it could be considered as cookie by the function below from my general_http_methods file:

def general_put_method(url, cookies, body):
        result = requests.put(url, headers=headers, cookies=cookies, json=body)
        return result

And using it as the parameter in the third method straightly, without passing into update_booking_cookie_token variable.

So the final code looks like this:

"""HTTP-methods for booker API"""
import requests
import json

from workfiles import general_http_methods

base_url = 'https://restful-booker.herokuapp.com'

"""Authentication"""

def booker_auth_method():
    auth_resource = '/auth'
    auth_url = base_url + auth_resource
    print(auth_url)
    auth_body = {'username': 'admin',
                 'password': 'password123'}
    result_auth_token = general_http_methods.general_post_method(auth_url, auth_body)
    json_result_auth_token = result_auth_token.json()
    value_of_the_cookie_json_result_auth_token = str(json_result_auth_token.get('token'))
    adding_token_to_auth_token_value = 'token=' + value_of_the_cookie_json_result_auth_token
    result_auth_cookie_token = {'Cookie': adding_token_to_auth_token_value}
    print(result_auth_cookie_token)
    return result_auth_cookie_token


booker_auth_method_var = booker_auth_method()

"""Creating a booking"""

def booker_create_booking_method():
    create_booking_resource = '/booking'
    create_booking_body = {
        "firstname": 'Python',
        "lastname": "Tester",
        "totalprice": 111,
        "depositpaid": True,
        "bookingdates": {
            "checkin": "2023-01-01",
            "checkout": "2023-01-02"},
        "additionalneeds": "Breakfast"}
    create_booking_url = base_url + create_booking_resource
    print(create_booking_url)
    create_booking_result = general_http_methods.general_post_method(create_booking_url, create_booking_body)
    str_json_create_booking_result = str(create_booking_result.json()['bookingid'])
    print(create_booking_result, str_json_create_booking_result)
    return str_json_create_booking_result

booker_create_booking_method_var = booker_create_booking_method()

"Updating the WHOLE booking"

def booker_update_booking_method(booker_auth_method_var, booker_create_booking_method_var):
    update_booking_resource = '/booking/'
    update_booking_url = base_url + update_booking_resource + booker_create_booking_method_var
    update_booking_body = {
        "firstname": "Python",
        "lastname": "QA Engineer",
        "totalprice": 777,
        "depositpaid": False,
        "bookingdates": {
            "checkin": "2023-07-08",
            "checkout": "2023-07-15"},
        "additionalneeds": "ALL INCLUSIVE"}
    update_booking_result = general_http_methods.general_put_method(update_booking_url, booker_auth_method_var, update_booking_body)
    print(update_booking_url, update_booking_result, update_booking_result.text)
    return update_booking_result


booker_update_booking_method(booker_auth_method_var, booker_create_booking_method_var)

And here is code from the general_http_methods file:

"""General HTTP-methods"""

import requests

headers = {
    'Content-Type':'application/json',
    'Accept':'application/json'}

def general_get_meothod(url):
    result = requests.get(url)
    return result


def general_post_method(url, body):
    result = requests.post(url, headers=headers, json=body)
    return result


def general_put_method(url, cookies, body):
    result = requests.put(url, headers=headers, cookies=cookies, json=body)
    return result


def general_patch_method(url, cookies, body):
    result = requests.patch(url, headers=headers, cookies=cookies, json=body)
    return result


def general_delete_method(url, cookies, body):
    result = requests.patch(url, headers=headers, cookies=cookies, json=body)
    return result

How it will help somehow in case you gonna have similar issue.

Answered By: bull1t
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.