Convert a string that has a list with strings - python

In python I have a function that's calling an api, when I check the result type by doing:
type(desi)
result:
<class 'str'>
When I do:
print(desi)
result:
["word"]
I want to convert that result to a list type. I am not sure why the API is returning a string with a list inside it instead of just a list.

You can parse this string to a list with the builtin json module.
import json
desi = '["word"]'
print(type(desi))
print(desi)
desi2 = json.loads(desi)
print(type(desi2))
print(desi2)
output:
<class 'str'>
["word"]
<class 'list'>
['word']
An HTTP request is just text, whatever library you're using to interact with it just hasn't parsed the text for you.

Related

How to convert a python dict to json in order to submit to kinesis

So I am trying to push some data into kinesis stream using Python and the record needs to be in JSON format but for the life of me I cant seem to get it correct.
I have a python dict object:
o = {'Name':'John Doe'}
I want to submit this to kinesis, so I did the following:
//omitting kinesis initialisation and all..
response = kinesis_client.put_records(
StreamName='kinesis_test_stream',
Records=json.dumps(o)
)
It gives me following error:
type: <class 'str'>, valid types: <class 'list'>, <class 'tuple'>
So instead of json.dumps(o) I tried Records=json.loads(json.dumps(o))
Then it gives me this error:
type: <class 'dict'>, valid types: <class 'list'>, <class 'tuple'>
I have been banging my head around this for an hour now, I think it should be something very small and silly that I am missing.
I tried this SO post but nothing helped.
Can anyone help me please?
As the error suggests, the Records parameter expects a list. Try
response = kinesis_client.put_records(
StreamName='kinesis_test_stream',
Records=[o]
)
And check the docs for put_records.

How to fix expected <type 'basestring'> in python code

I am using Troposphere to create CloudFormation templates.
If I use a variable or string I get the error - <class 'troposphere.efs.FileSystem'>, expected <type 'basestring'>
I am new to troposphere and python so any help is appreciated.
My code when using strings
MyEFSMountTarget1a = t.add_resource(MountTarget(
"MyEFSMountTarget1a",
FileSystemId=(efs_file_system),
SecurityGroups=["sg-0c69656095ee1a5b8"],
SubnetId="subnet-091b67136896b2be8"
))
My code when using variables
MyEFSMountTarget1a = t.add_resource(MountTarget(
"MyEFSMountTarget1a",
FileSystemId=(efs_file_system),
SecurityGroups=[efs_security_group],
SubnetId=PublicSubnet1a
))
The Error: <class 'troposphere.efs.MountTarget'>: MyEFSMountTarget1a.FileSystemId is <class 'troposphere.efs.FileSystem'>, expected <type 'basestring'>
What I am doing is importing values from another cloudformation stack and using them in another stack.
Here is how I populate the variables -
efs_security_group = ImportValue(Join("-", [params.ENVIRONMENT, "efsSecurityGroup"]),)
PublicSubnet1a = ImportValue(Join("-", [params.ENVIRONMENT, "PublicSubnet1a"]),)
They are populated correctly and I assumed they were jutt strings - which they are. So I guess I can not use strings for SecurityGroups or SubnetId? Do I need to convert the strings to a basestring and how?
Ernie
My mistake - It was the filesystem id - I forgot to add a ref to it FileSystemId=Ref(efs_file_system),

Read data from PyIUknown type variable

I'm using win32com.client to read data from custom COM Object developed in VB.Net.
With the following code I'm able to read a string result
>>> import win32com.client
>>> cstApp = win32com.client.Dispatch("CustomLib.CSTApp")
>>> string = cstApp.GiveMeTestString()
>>> print(type(string))
<class 'str'>
>>> print("Test String: {0}".format(string))
Test String: Well done! I come from COM Object
I've now a method that give as result a VB.Net Dictionary type, but when I try to read it from my python script I get a PyIUknown type and I'm not able to read its values
>>> username = 'artur'
>>> resultset = cstApp.OpenTaskforUser(username)
>>> print(type(resultset))
<class 'PyIUnknown'>
>>> print(resultset)
<PyIUnknown at 0x0000003C47ABAC30 with obj at 0x0000003C47EAFF18>
How can I read it's data?
Otherwise, which type I need to use in VB.Net to be able to read a Python list containing dictionaries from win32com?
Thank you for your help.
After a week of working I've better understood how works win32com and Python support of COM interface, so I wanna share the workaround I've used to avoid the situation for which I posted this question.
1. First of all PyIUnknown is not an error. IUnknown Interface is the root Interface from which derive all other Interface. IUnknown (and so PyIUnknown) could be used through QueryInterface method. [1]
2. On the other hand , not all Python Types are mapped in a COM Interface. So IDictionary is one of them. This is why I get the PyIUnknown result. [2]
3. To use easly a COM Interface in Python is useful to generate a static proxy class that maps all the interfaces available in the library. There are different ways to do this activity. In the early steps I've used makepy method . Then I've used EnsureDispatch one. [3]
The final workaround, to avoid the problems at point 1. and 2., was to ask to custom API COM developer to change the returned type from a IDictionary to JSON string.
In this way I get a easily to use Python dictionary.
>>> import win32com.client
>>> import json
>>> cstApp = win32com.client..gencache.EnsureDispatch("CustomLib.CSTApp")
>>> resultset_json = cstApp.OpenTaskforUser('artur')
>>> type(resultset_json)
<class 'str'>
>>> resultset = json.loads(resultset_json)
>>> type(resultset)
<class 'dict'>
I hope this answer could help other people.

How can I permanently alter the values within a module from a separate script

I have a module english.py which contains a dictionary monograms. The value associated with each key is of type str and I would like to permanently change the type of the value associated with each key to int from a separate script.
I have tried to mimic the response to this question with the following:
import english
english.monograms['the'] = int(english.monograms['the'])
print(type(english.monograms['the']))
yielding the expected: <class 'int'>
However, when I rerun the code with the 2nd line commented out:
import english
#english.monograms['the'] = int(english.monograms['the'])
print(type(english.monograms['the']))
I recieve <class 'str'>
How can I make this change permanant without a complicated function that would read, parse and re-write the module?

How to access json in python

I am trying to access json object in python and I am running through different errors
this is the data
value = '{"0":{"created":"05-16-13","counter":3},"1":{"created":"05-17-13","counter":1},"2":{"created":"05-18-13","counter":1}}'
I will like to get
"05-16-13","counter":3
"05-18-13","counter":1
I did
for info in value:
print info['counter']
I keep getting a type error, any help?
TypeError: string indices must be integers, not str
Use json.loads to convert it into a Python dictionary:
import json
value = '{"0":{"created":"05-16-13","counter":3},"1":{"created":"05-17-13","counter":1},"2":{"created":"05-18-13","counter":1}}'
d = json.loads(value)
for key, info in d.items():
print info['counter']
The error you were getting before was because string objects should be indexed by integers.
Let's take a completely different string and see why:
'abcd'[0] # 'a'
'abcd'['xyx'] # What does this even mean? TypeError!
'{"0":{"created":"05-16-13","counter":3}"}'['couter'] # TypeError for the same reasons.
There is a json library that you can import and use in Python. You can see docs for Python 3 here and Docs for Python 2 here.
import json
value = '{"0":{"created":"05-16-13","counter":3},"1":{"created":"05-17-13","counter":1},"2":{"created":"05-18-13","counter":1}}'
value = json.loads(value)
print(value[0])
Because value is a string. You should parse the json in it to access to its elements:
import json
value = json.loads('{"0":{"created":"05-16-13","counter":3},"1":{"created":"05-17-13","counter":1},"2":{"created":"05-18-13","counter":1}}')
for info in value.items():
print info['counter']

Categories

Resources