From 9230aa294fb1c25a7c7bf63a7bcb8c08a9b73406 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 17 Jul 2023 10:06:35 +0100 Subject: [PATCH 1/2] Added bones of the trigger plan api --- .github/workflows/deploy_fastapi_backend.yml | 1 + backend/app/config.py | 1 + backend/app/plan/__init__.py | 0 backend/app/plan/router.py | 29 ++++++++++++++++++ backend/app/plan/schemas.py | 10 ++++++ backend/app/utils.py | 32 ++++++++++++++++++++ backend/requirements/base.txt | 1 + backend/serverless.yml | 4 +-- 8 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 backend/app/plan/__init__.py create mode 100644 backend/app/plan/router.py create mode 100644 backend/app/plan/schemas.py create mode 100644 backend/app/utils.py diff --git a/.github/workflows/deploy_fastapi_backend.yml b/.github/workflows/deploy_fastapi_backend.yml index 121519e0..c3ef49f0 100644 --- a/.github/workflows/deploy_fastapi_backend.yml +++ b/.github/workflows/deploy_fastapi_backend.yml @@ -53,4 +53,5 @@ jobs: ENVIRONMENT: ${{ github.ref_name }} SECRET_KEY: 'YOUR_SECRET_KEY' ALGORITHM: 'HS256' + PLAN_TRIGGER_BUCKET: 'retrofit-plan-inputs-${{ github.ref_name }}' run: cd backend && sls deploy --stage ${{ github.ref_name }} --verbose diff --git a/backend/app/config.py b/backend/app/config.py index 0b1d7f9b..0c5fe057 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -8,6 +8,7 @@ class Settings(BaseSettings): SECRET_KEY: str ALGORITHM: str ENVIRONMENT: str + PLAN_TRIGGER_BUCKET: str class Config: env_file = ".env" diff --git a/backend/app/plan/__init__.py b/backend/app/plan/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py new file mode 100644 index 00000000..b6ba751a --- /dev/null +++ b/backend/app/plan/router.py @@ -0,0 +1,29 @@ +from fastapi import APIRouter, Depends +from app.dependencies import validate_token +from app.plan.schemas import PlanTriggerRequest +from app.utils import read_csv_from_s3 +from app.config import get_settings + +router = APIRouter( + prefix="/plan", + tags=["plan"], + dependencies=[Depends(validate_token)], + responses={404: {"description": "Not found"}} +) + + +@router.post("/trigger") +async def trigger_plan(body: PlanTriggerRequest): + print("Getting the inputs") + # Read in the trigger file from s3 + bucket_name = get_settings().PLAN_TRIGGER_BUCKET + print("bucket_name: ", bucket_name) + print("body.trigger_file_path: ", body.trigger_file_path) + plan_input = read_csv_from_s3(bucket_name=bucket_name, filepath=body.trigger_file_path) + print("Got the inputs") + print(plan_input) + + # TODO: Parse the file + # TODO: Put messages on the queue + + return {"message": "Plan triggered"} diff --git a/backend/app/plan/schemas.py b/backend/app/plan/schemas.py new file mode 100644 index 00000000..c468754a --- /dev/null +++ b/backend/app/plan/schemas.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel + + +class PlanTriggerRequest(BaseModel): + budget: float | None = None + goal: str + housting_type: str + goal_value: float + portfolio_id: int + trigger_file_path: str diff --git a/backend/app/utils.py b/backend/app/utils.py new file mode 100644 index 00000000..4780a5ca --- /dev/null +++ b/backend/app/utils.py @@ -0,0 +1,32 @@ +import boto3 +import csv +from io import StringIO +import string +import secrets + + +def read_csv_from_s3(bucket_name, filepath): + s3 = boto3.client('s3') + + # Get the object from s3 + s3_object = s3.get_object(Bucket=bucket_name, Key=filepath) + + # Read the CSV body from the s3 object + body = s3_object['Body'].read() + + # Use StringIO to create a file-like object from the string + csv_data = StringIO(body.decode('utf-8')) + + # Use csv library to read it into a list of dictionaries + reader = csv.DictReader(csv_data) + data = list(reader) + + return data + + +def generate_api_key(): + # Define the characters that will be used to generate the api key + characters = string.ascii_letters + string.digits + # Generate a 40 character long api key + api_key = ''.join(secrets.choice(characters) for _ in range(40)) + return api_key diff --git a/backend/requirements/base.txt b/backend/requirements/base.txt index 29d09725..923f17f9 100644 --- a/backend/requirements/base.txt +++ b/backend/requirements/base.txt @@ -25,3 +25,4 @@ uvicorn==0.22.0 uvloop==0.17.0 watchfiles==0.19.0 websockets==11.0.3 +boto3 \ No newline at end of file diff --git a/backend/serverless.yml b/backend/serverless.yml index dd3c3c42..2e56f7f2 100644 --- a/backend/serverless.yml +++ b/backend/serverless.yml @@ -6,10 +6,10 @@ provider: region: eu-west-2 environment: API_KEY: ${env:API_KEY} - # ENVIRONMENT: ${self:provider.stage} - ENVIRONMENT: 'local' + ENVIRONMENT: ${self:provider.stage} SECRET_KEY: ${env:SECRET_KEY} ALGORITHM: ${env:ALGORITHM} + PLAN_TRIGGER_BUCKET: ${env:PLAN_TRIGGER_BUCKET} package: individually: true From 7cafdcd77214fb9e2797df4127bc582c7306c294 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 17 Jul 2023 10:11:07 +0100 Subject: [PATCH 2/2] Added secrets to actions file --- .github/workflows/deploy_fastapi_backend.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy_fastapi_backend.yml b/.github/workflows/deploy_fastapi_backend.yml index c3ef49f0..4d75c6a9 100644 --- a/.github/workflows/deploy_fastapi_backend.yml +++ b/.github/workflows/deploy_fastapi_backend.yml @@ -45,13 +45,9 @@ jobs: - name: Deploy to AWS Lambda via Serverless env: - # These will be in inserted for real - # API_KEY: ${{ secrets.API_KEY }} - # SECRET_KEY: ${{ secrets.SECRET_KEY }} - # ALGORITHM: ${{ secrets.ALGORITHM }} - API_KEY: 'example-api-key' + API_KEY: ${{ secrets.FASTAPI_API_KEY }} ENVIRONMENT: ${{ github.ref_name }} - SECRET_KEY: 'YOUR_SECRET_KEY' + SECRET_KEY: ${{ secrets.NEXTAUTH_SECRET }} ALGORITHM: 'HS256' PLAN_TRIGGER_BUCKET: 'retrofit-plan-inputs-${{ github.ref_name }}' run: cd backend && sls deploy --stage ${{ github.ref_name }} --verbose