I'm struggling with this one for days
I have code in python that sends get request that returns text file, I'm iterating my requests day by day because amount of data for one day is around 200mb and I don't want to run out of memory.
I'm using gc and deleting all possible variables, but still, according to tracemalloc urllib parse is holding a lot of data in memory and I can't figure out why nor how to free this memory.
import tracemalloc
tracemalloc.start()
import pandas as pd
import json
import gc
from datetime import datetime, timedelta,date
from urllib.request import Request, urlopen # Python 3
gc.enable()
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)
start_date = date(2022, 8, 1)
end_date = date(2022, 8, 7)
def func(single_date):
print(single_date.strftime("%Y-%m-%d"))
date = single_date.strftime("%Y-%m-%d")
req = Request('https://website.com/export?from_date='+date+'&to_date='+date+'&project_id=00000')
req.add_header('Accept', 'text/plain')
req.add_header( 'Authorization', 'Basic ==')
content = urlopen(req)
encoding = content.info().get_content_charset('utf-8')
data_object = content.read()
data = data_object.decode(encoding)
df = pd.read_json(data, lines=True, orient='records')
dfout = pd.concat([df.reset_index()[['event']], pd.json_normalize(df['properties'])], axis=1)
del df
del dfout
del req
del content
del data_object
del data
del date
del encoding
del single_date
for single_date in daterange(start_date, end_date):
gc.collect()
func(single_date)
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
print("[ Top 10 ]")
for stat in top_stats[:10]:
print(stat)
Tracemalloc output:
[ Top 10 ]
/opt/tljh/user/lib/python3.9/urllib/parse.py:461: size=1391 MiB, count=6, average=232 MiB
/opt/tljh/user/lib/python3.9/urllib/parse.py:486: size=1253 MiB, count=6, average=209 MiB
/opt/tljh/user/lib/python3.9/urllib/parse.py:488: size=132 MiB, count=24, average=5628 KiB
<frozen importlib._bootstrap_external>:647: size=12.0 MiB, count=115719, average=108 B
<frozen importlib._bootstrap>:228: size=5055 KiB, count=24566, average=211 B
/opt/tljh/user/lib/python3.9/tracemalloc.py:505: size=754 KiB, count=13788, average=56 B
/opt/tljh/user/lib/python3.9/tracemalloc.py:498: size=647 KiB, count=13788, average=48 B
/opt/tljh/user/lib/python3.9/tracemalloc.py:193: size=646 KiB, count=13787, average=48 B
/home/jupyter/.local/lib/python3.9/site-packages/pandas/util/_decorators.py:389: size=366 KiB, count=256, average=1463 B
/opt/tljh/user/lib/python3.9/re.py:210: size=277 KiB, count=181, average=1568 B
in the end notebook consumes ~4GB of memory after running through 6 days of data.
Could you please point me in the right direction?
#Update 1
changed code inside function to
def func(single_date):
print(single_date.strftime("%Y-%m-%d"))
date = single_date.strftime("%Y-%m-%d")
req = Request('https://website.com/export?from_date='+date+'&to_date='+date+'&project_id=00000')
req.add_header('Accept', 'text/plain')
req.add_header( 'Authorization', 'Basic ==')
with urlopen(req) as content:
encoding = content.info().get_content_charset('utf-8')
data_object = content.read() # data is now bytes
data = data_object.decode(encoding)
df = pd.read_json(data, lines=True, orient='records')
dfout = pd.concat([df.reset_index()[['event']],
pd.json_normalize(df['properties'])], axis=1)
but memory issue remains
#Update 2
also tried similar approach with requests, same result
with requests.get(url, headers=headers) as r:
df = pd.read_json(r.text, lines=True, orient='records')
dfout = pd.concat([df.reset_index()[['event']], pd.json_normalize(df['properties'])], axis=1)
#Update 3
Figured out that issue is originating in pandas