1

i have written a python program which makes an api call to a webserver once every minute and then parse the json response and saves parsed values in to the csv files.

here is the code that is saving the values into the csv file :

with open('data.csv', 'a', newline='') as file:
    writer = csv.writer(file)
    writer.writerow([current_time,SHORTPERC, LONGPERC, SHORTvolume, longVolume, longPositions, shortPositions])

how can i make it so that it saves the header only once on the top most row and not on every row ?

UPDATE:

here is a bit of more code to make api call and write the data to file :

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
import requests
import json
import csv
from datetime import datetime






def fn():
    print("Starting...")
    session_id = "auZsJ4F2RsQNJxSPTMDt2238324"
    Outlook='http://www.myfxbook.com/api/get-community-outlook.json?session=' + session_id
    Outlook_response = requests.get(Outlook)
    Outlook_data = Outlook_response.json()['symbols']
    now = datetime.now()
    current_time = now.strftime("%H:%M")





    EURUSD=Outlook_data[0]
    SHORTPERC=EURUSD['shortPercentage']
    LONGPERC =EURUSD['longPercentage']
    SHORTvolume=EURUSD['shortVolume']
    longVolume=EURUSD['longVolume']
    longPositions=EURUSD['longPositions']
    shortPositions=EURUSD['shortPositions']
    with open('data.csv', 'a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([current_time,SHORTPERC, LONGPERC, SHORTvolume, longVolume, longPositions, shortPositions])
    with open('data1.csv', 'a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([SHORTvolume, longVolume])
    with open('data2.csv', 'a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow([SHORTPERC, LONGPERC])

i cant post the full code cuz it will be very ugly since its around 700 lines long , but the above mentioned code should work to create the csv file

this is how one of my csv files look :

07:11,31,69,555.55,1265.14,4750,2607
07:12,31,69,555.55,1265.16,4751,2607
07:13,31,69,555.55,1265.16,4751,2607
07:14,30,70,555.56,1267.36,4752,2608
07:15,30,70,555.56,1267.36,4752,2608
07:16,30,70,555.56,1267.36,4752,2608
07:17,30,70,555.46,1267.36,4752,2607
07:18,31,69,558.61,1267.36,4752,2610
07:19,31,69,558.61,1267.37,4753,2610
07:20,31,69,561.58,1267.37,4753,2611
07:21,31,69,561.61,1267.37,4753,2613
07:22,31,69,561.65,1267.37,4753,2614
07:23,31,69,561.65,1267.36,4752,2614

this is just part of the csv file , more rows keep adding as time passes

EDIT 2: answer suggested by Sparkofska seems to work but somehow it ends up giving an empty row in between every line like this:

Time,ShortPer,LongPer,ShortVolume,LongVolume,ShortPosition,LongPosition

05:47,44,56,19528.8,24789.27,65223,48630

05:48,44,56,19529.04,24789.27,65223,48633

code :

EURUSD=Outlook_data[0]
SHORTPERC=EURUSD['shortPercentage']
LONGPERC =EURUSD['longPercentage']
SHORTvolume=EURUSD['shortVolume']
longVolume=EURUSD['longVolume']
longPositions=EURUSD['longPositions']
shortPositions=EURUSD['shortPositions']
filename='EURUSD.csv';

def write_row_header_aware(filename, row):

     
    if not os.path.exists(filename) or os.stat(filename).st_size == 0:
         
        with open(filename, 'a') as file:
            writer = csv.writer(file)
            writer.writerow(['Time', 'ShortPer', 'LongPer','ShortVolume','LongVolume','ShortPosition','LongPosition'])

     
    with open(filename, 'a') as file:
        writer = csv.writer(file)
        writer.writerow([current_time,SHORTPERC, LONGPERC, SHORTvolume, longVolume, longPositions, shortPositions])
    
write_row_header_aware(filename, [current_time,SHORTPERC, LONGPERC, SHORTvolume, longVolume, longPositions, shortPositions])
print("done...")
Sanders
  • 61
  • 7
  • 1
    I tried that snippet and it only wrote a single row in the file, without header. Can you add a broader example? – Pietro Mar 15 '21 at 10:28
  • your code doesn't give the output you say. May be post little more of the code with a small sample of the output you got. – Abhi_J Mar 15 '21 at 10:30
  • I have updated the code and added more code – Sanders Mar 15 '21 at 10:41
  • Check out the [DictWriter](https://docs.python.org/3/library/csv.html#csv.DictWriter) class – Sparkofska Mar 15 '21 at 11:57
  • Does this answer your question? [Pythonically add header to a csv file](https://stackoverflow.com/questions/20347766/pythonically-add-header-to-a-csv-file) – Sparkofska Mar 15 '21 at 11:59

2 Answers2

1

Please make a check to know if the file exists, if it already exists use append to write rows to file else write the headers. By this way you could avoid writing headers multiple times. Please refer to this link

Sparkofska
  • 1,280
  • 2
  • 11
  • 34
Ashwin S
  • 23
  • 8
1

You could wrap the writerow function to have it automatically add the header if needed.

If your output csv file is not empty, we can assert the header was already written and simply append the row. Otherwise (file not exist or empty) we write the header before appending the row.

import os

def write_row_header_aware(filename, row):

    # in case file doesn't exist or is empty
    if not os.path.exists(filename) or os.stat(filename).st_size == 0:
        # write header
        with open(filename, 'a', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['current_time', 'SHORTPERC', 'LONGPERC', ...])

    # write line as usual
    with open(filename, 'a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(row)
    
write_row_header_aware('data.csv', [current_time, SHORTPERC, LONGPERC, ...])
Sparkofska
  • 1,280
  • 2
  • 11
  • 34
  • thanks @Sparkofska solution seems to be working but it is generating empty spaces in between the rows , i have edited the OP showing the issue , can you check if i did something wrong ? – Sanders Mar 15 '21 at 12:56
  • That might be due to the line terminator on windows. Try adding `newline=''` parameter to the `open()` function as you had it in the very first code snippet. See my edited answer. – Sparkofska Mar 15 '21 at 13:50
  • yep adding newline=' ' worked like a charm – Sanders Mar 15 '21 at 14:13