Python - Write multiple JSON files each time user submits the form

277 views Asked by At

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?

2

There are 2 answers

1
Green Cell On BEST ANSWER

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.

7
robotHamster On

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)