Package: csv2ofx
csv2ofxINTRODUCTIONcsv2ofxis aPython libraryandcommand line interface programthat converts CSV files to OFX and QIF files for importing into GnuCash or similar financial accounting programs. csv2ofx has built in support for importing csv files from mint, yoodlee, and xero.Requirementscsv2ofx has been tested and is known to work on Python 3.7, 3.8, and 3.9; and PyPy3.7.INSTALLATION(You are using avirtualenv, right?)sudo pip install csv2ofxUsagecsv2ofx is intended to be used either directly from Python or from the command line.Library Examplesnormal OFX usageimportitertoolsasitfrommeza.ioimportread_csv,IterStringIOfromcsv2ofximportutilsfromcsv2ofx.ofximportOFXfromcsv2ofx.mappings.defaultimportmappingofx=OFX(mapping)records=read_csv('path/to/file.csv',has_header=True)groups=ofx.gen_groups(records)trxns=ofx.gen_trxns(groups)cleaned_trxns=ofx.clean_trxns(trxns)data=utils.gen_data(cleaned_trxns)content=it.chain([ofx.header(),ofx.gen_body(data),ofx.footer()])forlineinIterStringIO(content):print(line)normal QIF usageimportitertoolsasitfromtabutils.ioimportread_csv,IterStringIOfromcsv2ofximportutilsfromcsv2ofx.qifimportQIFfromcsv2ofx.mappings.defaultimportmappingqif=QIF(mapping)records=read_csv('path/to/file.csv',has_header=True)groups=qif.gen_groups(records)trxns=qif.gen_trxns(groups)cleaned_trxns=qif.clean_trxns(trxns)data=utils.gen_data(cleaned_trxns)content=it.chain([qif.gen_body(data),qif.footer()])forlineinIterStringIO(content):print(line)CLI Examplesshow helpcsv2ofx -husage:csv2ofx[options]<source><dest>

description:csv2ofxconvertsacsvfiletoofxandqif

positionalarguments:sourcethesourcecsvfile(defaultstostdin)desttheoutputfile(defaultstostdout)optionalarguments:-h,--helpshowthishelpmessageandexit-aTYPE,--accountTYPEdefaultaccounttype'CHECKING'forOFXand'Bank'forQIF.-eDATE,--endDATEenddate-lLANGUAGE,--languageLANGUAGEthelanguage-sDATE,--startDATEthestartdate-y,--dayfirstinterpretthefirstvalueinambiguousdates(e.g.01/05/09)astheday-mMAPPING,--mappingMAPPINGtheaccountmapping-xFILE_PATH,--customFILE_PATHpathtoacustommappingfile-cFIELD_NAME,--collapseFIELD_NAMEfieldusedtocombinetransactionswithinasplitfordoubleentrystatements-CROWS,--chunksizeROWSnumberofrowstoprocessatatime(default:2**14)-rROWS,--first-rowROWSnumberofinitialrowstoskip(default:0)-rROWS,--last-rowROWSthefinalrowstoprocess,negativevaluescountfromtheend(default:inf)-OCOLS,--first-colCOLSnumberofinitialcolstoskip(default:0)-L,--list-mappingslisttheavailablemappings-V,--versionshowversionandexit-q,--qifenables'QIF'outputinsteadof'OFX'-o,--overwriteoverwritedestinationfileifitexists-DSERVER_DATE,--server-dateSERVER_DATEOFXserverdate(default:sourcefilemtime)-EENCODING,--encodingENCODINGFileencoding(default:utf-8)-d,--debugdisplaytheoptionsandargumentspassedtotheparser-v,--verboseverboseoutputnormal usagecsv2ofx file.csv file.ofxprint output to stdoutcsv2ofx ~/Downloads/transactions.csvread input from stdincat file.csv | csv2ofxqif outputcsv2ofx -q file.csvspecify date range from one year ago to yesterday with qif outputcsv2ofx -s '-1 year' -e yesterday -q file.csvuse yoodlee settingscsv2ofx -m yoodlee file.csvCUSTOMIZATIONCode modificationIf you would like to import csv files with field names different from the default, you can modify the mapping file or create your own. New mappings must be placed in thecsv2ofx/mappingsfolder (otherwise you must use the ). The mapping object consists of a dictionary whose keys are OFX/QIF attributes and whose values are functions which should return the corresponding value from a record (csv row). The mapping function will take in a record, e.g.,{'Account':'savings 2','Date':'1/3/15','Amount':5000}The most basic mapping function just returns a specific field or value, e.g.,fromoperatorimportitemgettermapping={'bank':'BetterBank','account':itemgetter('Account'),'date':itemgetter('Date'),'amount':itemgetter('Amount')}But more complex parsing is also possible, e.g.,mapping={'account':lambdar:r['Details'].split(':')[0],'date':lambdar:'%s/%s/%s'%(r['Month'],r['Day'],r['Year']),'amount':lambdar:r['Amount']*2,'first_row':1,'last_row':10,'filter':lambdar:r['Amount']>10,}Required field attributesattributedescriptiondefault fieldexampleaccounttransaction accountAccountBetterBank Checkingdatetransaction dateDateitemgetter('Transaction Date')amounttransaction amountAmountitemgetter('Transaction Amount')Optional field attributesattributedescriptiondefault fielddefault valueexampledesctransaction descriptionReferencen/ashell stationpayeetransaction payeeDescriptionn/aShellnotestransaction notesNotesn/afor gascheck_numthe check or transaction numberRown/a2idtransaction idcheck_numNumn/abankthe bank namen/aaccountBankaccounttransaction account typen/acheckingsavingsaccount_idtransaction account idn/ahash ofaccountbb_checkingtypetransaction type (either debit or credit)n/aCREDIT if amount > 0 else DEBITdebitbalanceaccount balancen/an/a$23.00classtransaction classn/an/atravelOptional value attributesattributedescriptiondefault valueexamplehas_headerdoes the csv file have a header rowTrueis_splitdoes the csv file contain split (double entry) transactionsFalsecurrencythe currency ISO codeUSDGBPdelimiterthe csv field delimiter,;date_fmtcustom QIF date output format%m/%d/%y%m/%d/%Ydayfirstinterpret the first value in ambiguous dates (e.g. 01/05/09) as the day (ignored ifparse_fmtis present)FalseTrueparse_fmttransaction date parsing format%m/%d/%Yfirst_rowthe first row to process (zero based)02last_rowthe last row to process (zero based, negative values count from the end)inf-2first_colthe first column to process (zero based)02filterkeep transactions for which function returns truelambda tr: tr['amount'] > 10Scriptscsv2ofx comes with a built in task managermanage.py.Setuppip install -r dev-requirements.txtExamplesRun python linter and nose testsmanagelint
managetestContributingPlease mimic the coding style/conventions used in this repo. If you add new classes or functions, please add the appropriate doc blocks with examples. Also, make sure the python linter and nose tests pass.Ready to contribute? Here's how:Fork and clone.gitclonegit@github.com:<your_username>/csv2ofx.gitcdcsv2ofxSetup a newvirtualenvmkvirtualenv--no-site-packagescsv2ofx
activatecsv2ofx
pythonsetup.pydevelop
pipinstall-rdev-requirements.txtCreate a branch for local developmentgitcheckout-bname-of-your-bugfix-or-featureMake your changes, run linter and tests (see above), and submit a pull request through the GitHub website.Adding MappingsHow to contribute a mapping:Add the mapping incsv2ofx/mappings/Add a simple example CSV file indata/test/.Add the OFX or QIF file that results from the mapping and example CSV file indata/converted/.Add acsv2ofxcall for your mapping to the tests intests/test.py, inPRE_TESTS. If you added an OFX (not QIF) converted file, pay attention to the-e(end date) and-D(server date) arguments in the test- otherwise tests may pass on your workstation and fail on the build server.Ensure your test succeeds (see above).Licensecsv2ofx is distributed under theMIT License, the same asmeza.