0

I am doing a task in python (learning phase) wherein i have a text file with list of ip's eg: 10.8.9.0 10.7.8.7 10.4.5.6 and so on. Each on one line , one below another.

I have to read its contents and create its json as [{"ip":"10.8.9.0"},{"ip":"10.7.8.7"}..]

Code:

    with open("filename.txt") as file:
        content = [x.strip('\n') for x in file.readlines()]
        print content   
        print "content",type(content)
        content_json=json.dumps(content)
        print content_json
        print type(content_json)

The output of content is ['ip adrress1','ip address2'] which is a list.

When i dump the list in content_json the type shown is "Str" . However i need it as json

My concern is - my further task is to validate ip and add a item in existing json stating {"status":"valid/invalid"}.

I dnt know how to do that as the type of my json is showing str.

  1. Kindly let me knw how to proceed and add status for every ip in existing json.

  2. Also i wish to know why is the type of the json i dumped my list with is being showed as str.

The desired output should be

[ { "ip":"10.8.9.0", "status":"valid" }, { "ip":"10.7.8.A", "status":"invalid" }, ..so on ]

Iram Khan
  • 37
  • 2
  • 12
  • i have tried adding status in existing json too but i am unable to do that as my json's type is being showed as str and not json. Will appreciate help. Thanks :) – Iram Khan Apr 29 '16 at 12:59
  • 1
    Json is a serialization format, that is it's a way of converting an object to a _string_. You need to amend your object(s) first, then encode them as json. – snakecharmerb Apr 29 '16 at 13:03
  • You are also creating a list of strings, but your desired output is a list of dictionaries. You really need a dict comprehension inside your list comprehension. – Wyrmwood Apr 29 '16 at 13:15
  • Also, don't use "file" as a variable, since it is a keyword. – Wyrmwood Apr 29 '16 at 13:17

5 Answers5

1

First thing: The result is a list because you're building a list with [x.strip('\n') for x in file.readlines()]. In case you're not sure that means: Take every line x in file, remove the \n character from it and then build a list of those results. You want something like [{"ip":x.strip('\n')} for x in file.readlines()]. Now, the function json.dumps takes a Python object and attempts to create a JSON representation of it. That representation is serialized as a string so if you ask for the type of content_json that's what you'll get.

yorodm
  • 4,359
  • 24
  • 32
0

You have to make the distinction between a python list/dictionary and a JSON string.

This

>>> with open('input.txt') as inp:
...     result = [dict(ip=ip.strip()) for ip in inp]
... 
>>> result
[{'ip': '10.8.9.0'}, {'ip': '10.7.8.7'}, {'ip': '10.4.5.6'}]

will give you a list of dictionaries that is easy to mutate. When you are done with it, you can dump it as a JSON string:

>>> result[1]['status'] = 'valid'
>>> result
[{'ip': '10.8.9.0'}, {'status': 'valid', 'ip': '10.7.8.7'}, {'ip': '10.4.5.6'}]
>>> json.dumps(result)
'[{"ip": "10.8.9.0"}, {"status": "valid", "ip": "10.7.8.7"}, {"ip": "10.4.5.6"}]'
timgeb
  • 76,762
  • 20
  • 123
  • 145
0

You should supply key:value properly for the dump. Putting just the value alone would store it as String

Refer this : https://docs.python.org/2/library/json.html

Krash
  • 1
  • 1
0

Maybe something like this?

import json
import socket

result = list()
with open("filename.txt") as file:
    for line in file:
        ip = line.strip()
        try:
            socket.inet_aton(ip)
            result.append({"ip": line.strip(), "status": "valid"})
        except socket.error:
            result.append({"ip": line.strip(), "status": "invalid"})

print(json.dumps(result))
salomonderossi
  • 2,180
  • 14
  • 20
  • what am i suppose to do to add each ip's status.. as i mentioned in my question ..really cnt figure it out.. – Iram Khan Apr 29 '16 at 13:17
  • the above solution u provided splits my ip and output is--> [{"ip": "1"}, {"ip": "0"}, {"ip": "."}, {"ip": "1"}, {"ip": "."}, {"ip": "2"}, { "ip": "."}, {"ip": "3"}, {"ip": ""}] – Iram Khan Apr 29 '16 at 13:20
  • cuz it's readline, which returns one line, thus you are iterating of the string of one returned line. Just use line in file or line in file.splitlines() – Wyrmwood Apr 29 '16 at 13:23
  • file object has no attribute splitlines . – Iram Khan Apr 29 '16 at 13:27
  • socket.inet_aton doesnt validate if '0' is entered as IP. thats why its not a grt option. also i need to add status dynamically after ip nad all the above solutions are giving output as [{"status": "valid", "ip": "10.1.2.3"}, {"status": "invalid", "ip": "10.8.9.A"}, {"status": "valid", "ip": "0"}, {"status": "valid", "ip": "10.9.4.5"}] – Iram Khan Apr 29 '16 at 13:30
  • You can choose the answer from here which best fits your needs, regarding ip validation ;) http://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python – salomonderossi Apr 29 '16 at 13:35
  • sorry but even IPy does not validate '0' entered as IP. I tried all the fixes but to no avail – Iram Khan Apr 30 '16 at 08:55
0

Finally, I got a fix:

import os
import sys
import json
from IPy import IP
filepath="E:/Work/"
filename="data.txt"
result = list()
with open(os.path.join(filepath+filename)) as file:
  for line in file:
     ip = line.strip()
     if ip.startswith("0"):
        result.append({"ip": line.strip(), "status": "invalid"})
     else:
        try:
            ip_add=IP(ip)
            result.append({"ip": line.strip(), "status": "Valid"})
        except ValueError:
            result.append({"ip": line.strip(), "status": "invalid"})
print(json.dumps(result))
Iram Khan
  • 37
  • 2
  • 12