-1

This code writes a file named vip.json. Currently, it is overwriting the same file each time i submit the form. But, I want - Each time i click on submit in my form (which is built in flask) I want new files created for each submission. Something like - vip1.json, vip2.json, vip3.json and so on each time the form is submitted.

from flask import Flask, render_template, url_for, flash, redirect, request, 
jsonify, json
from forms import RequestForm

@app.route("/home", methods=['POST'])
def home():
form = RequestForm()
employee_id = form.employee_id.data
email = form.email.data
network = form.network.data
app_name = form.app_name.data
vip_name = form.vip_name.data
pool_name = form.pool_name.data
pool_monitor = form.pool_monitor.data
pool_member = form.pool_member.data
load_balance = form.load_balance.data
ssl = form.ssl.data

data={}

data = {
    'Employee ID': employee_id,
    'Email': email,
    'Network': network,
    'App Name': app_name,
    'VIP Name': vip_name,
    'Pool name': pool_name,
    'Pool Monitor': pool_monitor,
    'Pool Member': pool_member,
    'Load Balancing Method': load_balance,
    'SSL': ssl
}

if form.validate_on_submit():
    with open("C:\\pytest\\vip.json",'w') as j:
        json.dump(data, j)

    return render_template ('home.html', title='Home', data=data, form=form, employee_id=employee_id, email=email, network=network, app_name=app_name, vip_name=vip_name, pool_name=pool_name, pool_monitor=pool_monitor, pool_member=pool_member, load_balance=load_balance, ssl=ssl)
else:
    return render_template('request.html', form=form)

I had a look online but i could not get anything useful. What will be the best way to do this?

Bharath
  • 559
  • 11
  • 27

2 Answers2

1

This may not be the best way to do it, but you can append a UUID (Universally Unique IDentifier) if you do this:

import uuid
if form.validate_on_submit():
    filename "vip-"+str(uuid.uuid4())+".json"
    with open("C:\\pytest\\"+filename,'w') as j:
        json.dump(data, j)

The probability of clashing is very low, but you can always check if the file exists and generate another one if it does.

If you want to serialize, you can do it by:

  • Storing a pickle that has your filecount
  • Storing the current count in a database
    • I do not know anything about flask or the ORM you are using (if you are), so I'll leave that up to you
  • Using the information in this SO post to get a list of the files and add add 1 to len(list of files) to get your count (this assumes that only these files exist in the directory)
  • Use the same SO post to fetch the list of files, use RegEx to filter out files matching your particular pattern, then add 1 to the highest

To use the pickle approach, go to the directory where your python file is, and run this once:

import pickle
counter=1;
with open("vip_counter.pickle", "wb") as p:
    pickle.dump(p, counter)

This will store a vip_counter.pickle in your file system, where the script is run make sure that the pickle file is in the right spot

Every time before you exit, you need to update the file in the same fashion:

with open("vip_counter.pickle", "rb")as p:
    counter=pickle.load()
#counter is now loaded
counter+=1 #increment your counter before the new filesave
#your code here

#save your pickle back again :)
with open("vip_counter.pickle", "wb") as p:
    pickle.dump(p, counter)
robotHamster
  • 609
  • 1
  • 7
  • 24
  • Thanks @robotHamster. Works like a charm. Fixes for the time being. But i'm looking something like human readable, like vip1, vip2, etc. Many thanks for your answer! :) If you could modify this more i would be more than happy, sorry i'm a rookie to python. – Bharath Nov 12 '18 at 04:20
  • No worries, I think the simplest without knowing what your whole stack looks like is a pickle. I will edit it to include the pickle. Brewing some code.... – robotHamster Nov 12 '18 at 04:25
  • No worries :) The other answer posted by @GreenCell also works. If you chose his approach, I wouldn't mind an upvote :) – robotHamster Nov 12 '18 at 04:38
  • I was also thinking `uuid` would be an easy approach! +1 – Green Cell Nov 12 '18 at 04:43
  • Thanks @GreenCell, `glob` completely escaped me Lol – robotHamster Nov 12 '18 at 04:46
  • Also, the `uuid` approach is the least disk and memory intensive, especially if there's high enough traffic. Every approach will have its merits – robotHamster Nov 12 '18 at 04:47
  • thanks mate! @robotHamster thanks for explaining it so well. Really appreciate your help :) – Bharath Nov 12 '18 at 04:53
1

You could use glob to scan your directory and get a list of all your json files, get the file with the latest version, then iterate it by one for the new file's name:

import os
import glob

# Use glob to get a list of existing vip files.
dir = "C:/pytest/"
files = glob.glob(os.path.join(dir, "vip*.json")) # Let's say it returns ["C:/pytest/vip1.json", "C:/pytest/vip2.json", "C:/pytest/vip3.json"]

# Grab the latest vip file.
latest_file = sorted(files)[-1]

# Strip the path so it's just the file's name.
file_name = os.path.splitext(os.path.basename(latest_file))[0]

# Extract the number from the file's name.
num = int(file_name.lstrip("vip"))

# Generate your new path.
new_path = os.path.join(dir, "vip{}.json".format(num + 1))
# Output of new_path: C:/pytest/vip4.json

You may need additional error checking, like if num is really a number or if there are no existing files then to default num to 1, but I'll leave that to you.

Green Cell
  • 4,677
  • 2
  • 18
  • 49