-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from gdsc-ssu/v2
Merge with v2
- Loading branch information
Showing
11 changed files
with
8,319 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
from functools import wraps | ||
import json | ||
import typing | ||
|
||
|
||
import aiohttp | ||
from aiohttp_retry import RetryClient, ExponentialRetry | ||
|
||
from env import * | ||
|
||
|
||
def create_retry_client(func) -> typing.Callable: | ||
""" | ||
연결에 문제가 발생했을 경우 재시도를 시도할 수 있게 하는 기능을 | ||
세션에 추가합니다. | ||
Args: | ||
session (aiohttp.ClientSession): 세션 | ||
Returns: | ||
RetryClient: 재시도가 가능한 세션 래핑 객체 | ||
""" | ||
|
||
@wraps(func) | ||
async def wrapper(*args, **kwargs) -> RetryClient: | ||
session: aiohttp.ClientSession = await func(*args, **kwargs) | ||
retry_options = ExponentialRetry( | ||
attempts=3, statuses={400, 401, 403, 404, 408, 429} | ||
) # 리퀘스트가 너무 많은 경우, 연결 시간이 너무 긴 경우 | ||
# 명확하게 해당 코드가 전달된 경우만 재시도 | ||
retry_client = RetryClient( | ||
raise_for_status=True, retry_options=retry_options, client_session=session | ||
) | ||
return retry_client | ||
|
||
return wrapper | ||
|
||
|
||
async def read_response(response: aiohttp.ClientResponse) -> dict: | ||
try: | ||
data = await response.json() | ||
|
||
except aiohttp.ContentTypeError: | ||
data = json.loads(await response.text()) | ||
|
||
is_success = data.get("success") # 도서관 api의 자체 응답 코드 | ||
if is_success: # 예약 데이터가 존재하는 경우 | ||
return data | ||
else: | ||
raise AssertionError("Token expired") | ||
|
||
|
||
@create_retry_client | ||
async def create_logined_session( | ||
student_id: str, usaint_secret: str, token: str | ||
) -> aiohttp.ClientSession: | ||
""" | ||
로그인을 진행하고 인증 토큰을 발급합니다. | ||
Returns: | ||
str: 인증 토큰 값 | ||
""" | ||
|
||
session = aiohttp.ClientSession( | ||
base_url="https://oasis.ssu.ac.kr", | ||
timeout=aiohttp.ClientTimeout(total=5), | ||
raise_for_status=True, | ||
) | ||
|
||
login_url = "/pyxis-api/api/login" # 로그인 api | ||
payload = { | ||
"loginId": student_id, | ||
"password": usaint_secret, | ||
"isFamilyLogin": False, | ||
"isMobile": False, | ||
} | ||
|
||
if not token: | ||
async with session.post(login_url, json=payload) as response: | ||
data = await read_response(response) | ||
token = data["data"]["accessToken"] | ||
|
||
headers = { | ||
"Accept": "application/json", | ||
"pyxis-auth-token": token, | ||
} | ||
|
||
session.headers.update(headers) | ||
return session | ||
|
||
|
||
async def call_reservation_api( | ||
session: RetryClient, room_type_id: int, date: str | ||
) -> dict: | ||
url = f"/pyxis-api/1/api/rooms?roomTypeId={room_type_id}&smufMethodCode=PC&hopeDate={date}" | ||
async with session.get(url) as response: | ||
data = await read_response(response) | ||
return data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import json | ||
import redis | ||
import traceback | ||
|
||
|
||
def create_response(status_code: str | int, cache: str | bytes) -> dict: | ||
response = dict( | ||
{ | ||
"isBase64Encoded": False, | ||
"headers": {"Content-Type": "application/json"}, | ||
"statusCode": status_code, | ||
"body": cache, | ||
}, | ||
) | ||
return response | ||
|
||
|
||
def lambda_handler(event: dict, context: dict): | ||
try: | ||
rd = redis.Redis( | ||
# host="ssudobi-cache-001.96ug1w.0001.apn2.cache.amazonaws.com", | ||
host="localhost", | ||
port=6379, | ||
socket_timeout=3, | ||
) | ||
room_type_id = event["pathParameters"].get("room_type_id", "1") | ||
cache = rd.get(room_type_id) # set data to redis | ||
response = create_response(200, cache) | ||
|
||
except Exception as e: | ||
response = create_response(500, str(e)) | ||
print(traceback.format_exc()) | ||
|
||
finally: | ||
return response | ||
|
||
|
||
if __name__ == "__main__": | ||
print(lambda_handler({"pathParameters": {"room_type_id": "1"}}, {})) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import redis | ||
import boto3 | ||
import json | ||
import traceback | ||
|
||
|
||
def invoke_function(function_name: str, payload: dict | str): | ||
""" | ||
Invokes the specified function and returns the result. | ||
""" | ||
client = boto3.client("lambda") | ||
response = client.invoke(FunctionName=function_name, Payload=json.dumps(payload)) | ||
return response | ||
|
||
|
||
def get_payload(response) -> dict | None: | ||
try: | ||
payload = json.loads(response["Payload"].read().decode("utf-8")) | ||
status_code = payload.pop("statusCode") | ||
assert status_code == 200 | ||
return payload | ||
|
||
except AssertionError as e: | ||
print("Error occured in request: ", str(e)) | ||
raise e | ||
|
||
|
||
def create_response(status_code: str | int, msg: str) -> dict: | ||
response = { | ||
"isBase64Encoded": False, | ||
"headers": {"Content-Type": "application/json"}, | ||
"statusCode": status_code, | ||
"body": msg, | ||
} | ||
return response | ||
|
||
|
||
def lambda_handler(event: dict, context: dict): | ||
try: | ||
rd = redis.Redis( | ||
host="ssudobi-cache-001.96ug1w.0001.apn2.cache.amazonaws.com", | ||
port=6379, | ||
socket_timeout=3, | ||
) | ||
|
||
for room_type_id in (1, 5): | ||
response = invoke_function("cache", {"room_type_id": room_type_id}) | ||
if payload := get_payload(response): | ||
rd.set( | ||
str(room_type_id), json.dumps(payload) | ||
) # set data to redis, room_type_id is key | ||
|
||
response = create_response( | ||
200, | ||
"Cache Success", | ||
) | ||
|
||
except Exception as e: | ||
response = create_response(500, str(e)) | ||
print(traceback.format_exc()) | ||
|
||
finally: | ||
return response | ||
|
||
|
||
# if __name__ == "__main__": | ||
# lambda_handler({}, {}) |
Oops, something went wrong.