mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Major project restructure and setup
This commit is contained in:
parent
737ebc115b
commit
f7fe90b185
10 changed files with 111 additions and 30 deletions
1
backend/.env.example
Normal file
1
backend/.env.example
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
API_KEY = example-api-key
|
||||||
|
|
@ -4,14 +4,65 @@ learning and data modelling services.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
## Local
|
## Prerequisites
|
||||||
|
Python 3.8+
|
||||||
|
Poetry for managing project dependencies and virtual environment.
|
||||||
|
|
||||||
For running the serice locally, natigate to the backend directory and run the following command:
|
## Installation and setup
|
||||||
|
1. Clone this directory and navigate into the project directory.
|
||||||
|
|
||||||
```bash
|
```commandline
|
||||||
uvicorn main:app --reload
|
git clone https://github.com/Hestia-Homes/Model.git
|
||||||
|
cd backend
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2. For environment management, I'm using conda with pycharm which is a convenient setup for development
|
||||||
|
on a mac M1 however using tools such as poetry or pipenv is also fine.
|
||||||
|
|
||||||
|
For example, to install conda and create a virtual environment for this project, run the following commands:
|
||||||
|
|
||||||
|
```commandline
|
||||||
|
conda create -n backend python=3.10
|
||||||
|
conda activate backend
|
||||||
|
```
|
||||||
|
|
||||||
|
then enter the virtual environment and install the dependencies using conda.
|
||||||
|
|
||||||
|
```commandline
|
||||||
|
conda install --file requirements/base.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Duplicate .env.example and rename it to .env
|
||||||
|
```commandline
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Open .env and fill in the required environment variables.
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
from within the application you can run with the following command:
|
||||||
|
|
||||||
|
```commandline
|
||||||
|
uvicorn app.main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
You application will be available at the designated url
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
FastAPI automatically generates interactive API documentation for your application. To access the docs, start your
|
||||||
|
server and visit <yourlocalurl>/docs in your browser. Alternatively, you can go to
|
||||||
|
<yourlocalurl>/redoc to view the documentation in the ReDoc format.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
To run tests, run the following command from the root of the project directory:
|
||||||
|
|
||||||
|
```commandline
|
||||||
|
pytest
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Thoughts for authenticating the frontend with the backend
|
### Thoughts for authenticating the frontend with the backend
|
||||||
To provide secure communication between your frontend Next.js application and your backend FastAPI service, you have several options. Here are a few popular approaches:
|
To provide secure communication between your frontend Next.js application and your backend FastAPI service, you have several options. Here are a few popular approaches:
|
||||||
|
|
||||||
|
|
|
||||||
0
backend/app/__init__.py
Normal file
0
backend/app/__init__.py
Normal file
15
backend/app/config.py
Normal file
15
backend/app/config.py
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
from functools import lru_cache
|
||||||
|
from pydantic import BaseSettings
|
||||||
|
|
||||||
|
|
||||||
|
class Settings(BaseSettings):
|
||||||
|
API_KEY: str
|
||||||
|
API_KEY_NAME: str = "X-API-KEY"
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
env_file = ".env"
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def get_settings():
|
||||||
|
return Settings()
|
||||||
14
backend/app/dependencies.py
Normal file
14
backend/app/dependencies.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
from fastapi import Depends, HTTPException, status
|
||||||
|
from fastapi.security import APIKeyHeader
|
||||||
|
from app.config import get_settings
|
||||||
|
|
||||||
|
|
||||||
|
api_key_header = APIKeyHeader(name=get_settings().API_KEY_NAME, auto_error=False)
|
||||||
|
|
||||||
|
|
||||||
|
async def validate_api_key(api_key_header: str = Depends(api_key_header)):
|
||||||
|
if api_key_header != get_settings().API_KEY:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials"
|
||||||
|
)
|
||||||
|
return api_key_header
|
||||||
8
backend/app/main.py
Normal file
8
backend/app/main.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from app.portfolio import router as portfolio_router
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
app.include_router(portfolio_router.router)
|
||||||
0
backend/app/portfolio/__init__.py
Normal file
0
backend/app/portfolio/__init__.py
Normal file
18
backend/app/portfolio/router.py
Normal file
18
backend/app/portfolio/router.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
|
from app.dependencies import validate_api_key
|
||||||
|
|
||||||
|
router = APIRouter(
|
||||||
|
prefix="/portfolio",
|
||||||
|
dependencies=[Depends(validate_api_key)],
|
||||||
|
tags=["portfolio"],
|
||||||
|
responses={404: {"description": "Not found"}}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{portfolio_id}")
|
||||||
|
async def get_portfolio(portfolio_id: int):
|
||||||
|
return {
|
||||||
|
"portfolio_id": portfolio_id,
|
||||||
|
"name": "My Portfolio",
|
||||||
|
"description": "This is my portfolio",
|
||||||
|
}
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
from fastapi import FastAPI, Depends, HTTPException, status
|
|
||||||
from fastapi.security import APIKeyHeader
|
|
||||||
|
|
||||||
API_KEY = "example-api-key"
|
|
||||||
API_KEY_NAME = "X-API-KEY"
|
|
||||||
|
|
||||||
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
|
|
||||||
async def validate_api_key(api_key_header: str = Depends(api_key_header)):
|
|
||||||
if api_key_header != API_KEY:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials"
|
|
||||||
)
|
|
||||||
return api_key_header
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/portfolio/{portfolio_id}", dependencies=[Depends(validate_api_key)])
|
|
||||||
async def get_portfolio(portfolio_id: int):
|
|
||||||
return {
|
|
||||||
"portfolio_id": portfolio_id,
|
|
||||||
"name": "My Portfolio",
|
|
||||||
"description": "This is my portfolio",
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue