AWS

python으로 AWS S3 파일 읽고 쓰기

whistory 2022. 12. 6. 09:39
반응형

 

 

 

KOSIS openAPI 를 가져왔으니, 이를 AWS S3에 올리려고 한다.

 

 

일단 S3에 접근할수 있는 IAM 자격정보를 가져온다

 

[IAM] - [액세스 관리] - [사용] 로 이동한다.

 

사용자를 클릭하고, [보안 자격 증명] 으로 이동한 뒤 [엑세스 키 만들기] 를 클릭한다.

 

액세스키를 만들고, 

엑세스 키 ID 와,

비밀 액세스 키 를 이용해 python에서 S3에 접근한다.

 

 

 

 

로컬에, parquet 파일 만들기 (SDMX)

import pandas as pd
import requests
from bs4 import BeautifulSoup

open_url = "https://kosis.kr/openapi/statisticsBigData.do?method=getList&apiKey=api_key&format=sdmx&userStatsId=whiseung/135/DT_135N_1A001A/3/1/20221124104644&type=StructureSpecific&prdSe=Y&newEstPrdCnt=1&version=v2_1"
res = requests.get(open_url)
soup = BeautifulSoup(res.content, 'html.parser')

datalist = soup.find_all('series')

data = []
for item in datalist:
    value = []
    value.append(item.get('item'))
    value.append(item.get('c_a01'))
    value.append(item.get('unit'))
    subitem = item.find('obs')
    value.append(subitem.get('time_period'))
    value.append(subitem.get('obs_value'))

    data.append(value)

df = pd.DataFrame(data)
df.columns = ['item', 'category', 'unit', 'date', 'value']
df.head()
print(df)

df.to_parquet('data3.parquet', engine='pyarrow', index=False)

 

 

로컬의 parquet 파일을 S3 upload

import boto3

ACCESS_KEY = 'access_key'
SECRET_KEY = 'secret_key'

bucket_name = 'bucket_name'
region = 'ap-northeast-2'
prefix = 'prefix/'

s3 = boto3.client('s3',aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)

file_name = 'data3.parquet'

s3.upload_file(file_name, bucket_name, file_name)

결과

 

S3 의 리스트 조회

import boto3

ACCESS_KEY = 'access_key'
SECRET_KEY = 'secret_key'

bucket_name = 'bucket_name'
region = 'ap-northeast-2'
prefix = ''

s3 = boto3.client('s3',aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)

response = s3.list_buckets()

obj_list = s3.list_objects(Bucket=bucket_name, Prefix=prefix)
contens_list = obj_list['Contents']

for content in contens_list:
    print(content)
PS C:\\workspace\\api> & C:/Users/서휘승/AppData/Local/Microsoft/WindowsApps/python3.8.exe c:/workspace/api/getS3.py
{'Key': 'data3.parquet', 'LastModified': datetime.datetime(2022, 11, 29, 4, 36, 12, tzinfo=tzutc()), 'ETag': '"etag"', 'Size': 7798, 'StorageClass': 'STANDARD', 'Owner': {'ID': 'id'}}

 

S3 의 parquet file 읽기

import boto3
import io
import pandas as pd

ACCESS_KEY = 'access_key'
SECRET_KEY = 'secret_key'

bucket_name = 'bucket_name'

s3 = boto3.client('s3',aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)

obj = s3.get_object(Bucket=bucket_name, Key='data3.parquet')
result = pd.read_parquet(io.BytesIO(obj['Body'].read()))
print(result)
PS C:\\workspace\\api> & C:/Users/서휘승/AppData/Local/Microsoft/WindowsApps/python3.8.exe c:/workspace/api/getS3.py
        item category        unit  date    value
0    16135A1     A001  14STD03818  2020  1714579
1    16135A3     A001  14STD03818  2020  1399428
2    16135A5     A001  14STD04548  2020  1638387
3    16135A1     A002  14STD03818  2020  1044438
4    16135A3     A002  14STD03818  2020   767742
..       ...      ...         ...   ...      ...
511  16135A3     A244  14STD03818  2020     2475
512  16135A5     A244  14STD04548  2020     3000
513  16135A1     A300  14STD03818  2020      668
514  16135A3     A300  14STD03818  2020      657
515  16135A5     A300  14STD04548  2020      676

[516 rows x 5 columns]
PS C:\\workspace\\api>

 

로컬에 파일 저장하지 않고, 바로 S3에 저장하도록 구현 (json)

import json
import io
import boto3
import pandas as pd
from urllib.request import urlopen
from datetime import datetime

ACCESS_KEY = 'access_key'
SECRET_KEY = 'secret_key'

def getApiUploadS3(apiUrl, s3Url, s3Path, tempFileName):
    with urlopen(apiUrl) as url:
        json_file = url.read()
        py_json = json.loads(json_file.decode('utf-8'))

        data = []
        for i, v in enumerate(py_json):
            if i == 0 :
                print(f"Title : {v['TBL_NM']}")

            value = []
            value.append(v['PRD_DE'])
            value.append(v['C1_NM'])
            value.append(v['ITM_NM'])
            value.append(v['DT'])
            value.append(v['UNIT_NM'])

            data.append(value)

    df = pd.DataFrame(data)
    df.columns = ['yyyyymm', 'category', 'item', 'value', 'unit']

    df.to_parquet(s3Url + s3Path + tempFileName
                , engine='pyarrow'
                , index=False
                , storage_options={"key": ACCESS_KEY,
                                   "secret": SECRET_KEY }
                ) 

    return s3Path + tempFileName


if __name__ == "__main__":
    apiUrl = "https://kosis.kr/openapi/statisticsData.do?method=getList&apiKey=api_key&format=json&jsonVD=Y&userStatsId=whiseung/115/DT_11523_400/2/1/20221123094346&prdSe=M&newEstPrdCnt=3"
    bucketName = 'bucket_name'
    s3Path = 'parquet/'
    
    thisTime = datetime.today().strftime('%Y%m%d%H%M%S')
    tempFileName = f'KOSIS_DT_11523_400_{thisTime}.parquet'
    
    resultFileName = getApiUploadS3(apiUrl, f's3://{bucketName}/', s3Path, tempFileName)
    print(f'###  Parquet file created! {resultFileName}')

 

 

다음엔, 해당 python 파일을 lambda에서 실행해야겠다.

반응형