1

I have a file requirement.txt file. the following text are below.How to change the value for django and flask and update the file by passing as command line argument

requirement.txt

 numpy=1.14
 pandas=1.4
 django=1.6
 flask=1.4

my python file.py is below

 import sys
 import re
 program_name = sys.argv[0]
 arguments = sys.argv[1:]
 print (arguments[0])
 print (arguments[1])
 with open('requirement.txt ', 'r') as fr:
     data = fr.readlines()
     with open('requirement.txt ', 'a') as fw:
     fw.write(....)

python file.py django=2.1 flask=2.0

output of requirement.txt

 numpy=1.14
 pandas=1.4
 django=2.1 
 flask=2.0
  • Possible duplicate of [How to search and replace text in a file using Python?](https://stackoverflow.com/questions/17140886/how-to-search-and-replace-text-in-a-file-using-python) – mrzasa Jun 25 '19 at 09:15
  • @Mak, check https://docs.python.org/3/library/fileinput.html to edit a file in-place – RomanPerekhrest Jun 25 '19 at 09:47

4 Answers4

1
import re
import sys

arguments = dict(i.split("=") for i in sys.argv[1:])   #CMD line Arguments.
with open('requirement.txt', 'r') as fr:         #Read content
    data = fr.read()

for k, v in arguments.items():
    data = re.sub(r"{}=(.*)".format(k), "{}={}".format(k,v), data)   #Update content

with open(filename, 'w') as fr:              #Write back data. 
    fr.write(data)
Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

Using 'a' means you will have two requirements of the same type, like this:

numpy=1.14
pandas=1.4
django=1.6
flask=1.4
django=2.1 
flask=2.0

Instead, you should overwrite the file with an updated list of requirements.

First, load the data and put it in a dictionary:

fr=open('requirement.txt ', 'r')
L=fr.read().split("\n") #Better than .readlines(), since it removes '\n'
fr.close() #Very important, since you're going to write back into it.
D=dict()
for e in L:
    E=e.split("=")
    if len(E)<2:
        continue
    D[E[0]]=E[1]

Then, apply the arguments to the dictionary:

D[arguments[0]]=arguments[1]

Finally, put the dictionary data back into a string and overwrite the file:

result="\n".join([e+"="+D[e] for e in D])
fw=open('requirement.txt ', 'a')
fw.write(result)
fw.close()

which should give the desired result.

Additionally, you should keep track of order of keys in a list if you wish to preserve it.

  • Can you check this because result="\n".join([e+"="+D[e] for e in D]), will throw error because of we are trying to concatenate the list to str because D[arguments[0] is list not str –  Jun 25 '19 at 09:50
  • @Mous I found the error. Replace `D[arguments[0]]=arguments ` with `D[arguments[0]]=arguments[1] ` – Dorijan Cirkveni Jun 26 '19 at 11:23
0

I think you might wanna check out argparse: https://docs.python.org/2/library/argparse.html

Otherwise, you can go about it this way:

import sys

requirements = {}

# Save a list of requirements
with open('requirement.txt', 'r') as file:
  for line in file:
    line = line.strip("\n").split("=")
    requirements[line[0]] = line[1]

# Change requirements values
for command in sys.argv[1:]:
  command = command.split("=")
  requirements[command[0]] = command[1]

# Write requirements back to file
with open('requirement.txt', 'w') as file:
  for r, v in requirements.items():
    line = "{}={}\n".format(r, v)
    file.write(line)
Giacomo Casoni
  • 387
  • 2
  • 16
  • i tried argparse. could not able to do it. I thought some one in stackoverflow will help. your code also working fine –  Jun 25 '19 at 09:39
0

With convenient fileintput module - editing in one pass:

import sys
import fileinput

program_name = sys.argv[0]
args = sys.argv[1:]

if not args:    # ensuring replacement items were passed
    sys.exit('No items to replace')

args_dict = dict(arg.split('=') for arg in args)
keys_tuple = tuple(args_dict.keys())

for line in fileinput.input(files='requirements.txt', inplace=True):
    if line.startswith(keys_tuple):
        name, version = line.split('=')
        line = line.replace(version, args_dict[name])
    print(line.strip())

The final requirements.txt file contents:

numpy=1.14
pandas=1.4
django=2.1
flask=2.0
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105