diff --git a/.ghaymah.json b/.ghaymah.json new file mode 100644 index 0000000..98ca553 --- /dev/null +++ b/.ghaymah.json @@ -0,0 +1,17 @@ +{ + "id": "d7cd2a73-34db-49ef-b663-41a6053515ee", + "name": "bin", + "projectId": "5f5c8255-5662-49b2-a097-84f52fd16c12", + "ports": [ + { + "expose": true, + "number": 80 + } + ], + "publicAccess": { + "enabled": true, + "domain": "auto" + }, + "resourceTier": "t1", + "dockerFileName": "Dockerfile" +} \ No newline at end of file diff --git "a/.github/workflows/ci\\cd.yaml" "b/.github/workflows/ci\\cd.yaml" new file mode 100644 index 0000000..5e9e98c --- /dev/null +++ "b/.github/workflows/ci\\cd.yaml" @@ -0,0 +1,38 @@ +on: + push: + pull_request: + + +jobs: + build_and_push_image: + steps: + - name: checkout code + uses: actions/checkout@v5.0.0 + + - name: login to dockerhub + uses: docker/login-action@v3.6.0 + with: + username: ${{ secrets.DOCKER_USERNAME}} + password: ${{ secrets.DOCKER_TOKEN}} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: Docker_API/Dockerfile + push: true + tags: abdelrhmanpasha/abdelrhman:firstV1 + + deploy: + needs: build_and_push_image + steps: + - name: checkout code + uses: actions/checkout@v5.0.0 + - name: install ghaymah cli + run: curl -sSl https://cli.ghaymah.systems/install.sh | bash + + - name: login to ghaymah + run: $HOME/ghaymah/bin/gy auth login --email "${{secrets.GH_EMAIL}}" --password "${{secrets.GH_PASS}}" + + - name: deploy + run: $HOME/ghaymah/bin/gy resource app launch \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d869930 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ +.venv/ +.env + +# Logs +*.log +logs/ + +# Docker + +!.dockerignore + + +# Virtual env +venv/ +ENV/ + + + + diff --git a/API.py b/API.py new file mode 100644 index 0000000..1f0dcfa --- /dev/null +++ b/API.py @@ -0,0 +1,141 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from typing import List, Optional +from uuid import UUID, uuid4 + +app = FastAPI() + +#its like a database to store data i wrote in the same session +# b4 reload to update or something else... and i can write anything in +#and it will be permenant data ... if you deleted a class you can use +#dict{} and write data in it to be a data structural ypu wanna use with your code +cars={uuid4() + :{ + "country":"Germany", + "brand":"Mercedes", + "model":"GLC", + "year":2026 + } +} + +# cars = [] + +''' class means its something im ganna do frequently in my code +and every class must have object like Cars in our project and +might has something to range it too as here (basemodel) +its a data structural to organize my send and resieve data....''' + +'''here im gonna write my data structure +like every thing i wanna know / put in my app and web + lets say wanna put an id , name , type and so on .... + and how i wanna sent and resieve it''' + +class Cars(BaseModel): + name:str + country:str + brand:str + model:str + year:int +class UpdateCar(BaseModel): + name: Optional[str]=None + country: Optional[str]=None + brand: Optional[str]=None + model: Optional[str]=None + year: Optional[int]=None + +#Endpoint (URL) +#www.Famcars.com/ +@app.get("/") +def get_root(): + return {"Hello":'im Abdelrhman'} + +#www.Famcars.com/cars/1 +#GET Cars +@app.get("/cars/{car_id}") +# def get_cars(car_id:UUID): +def get_cars(car_id:int): + if car_id not in cars: + raise HTTPException(status_code=404,detail="car not found!") + return cars[car_id] + +#www.Famcars.com/cars +@app.get("/cars/") +def get_all_cars(): + return cars + +#Create +#www.Famcars.com/cars/1 +#POST Cars +# @app.post("/cars/{car_id}", response_model=Cars) +# def create_car(car_id:int,car:Cars): +# if car_id in car: +# raise HTTPException(status_code=404,detail="car already exist!") +# cars[car_id]=car.dict() +# return car + +@app.post("/cars/", response_model=Cars) +def create_cars(car:Cars): + car_id=uuid4() + if car_id in car: + raise HTTPException(status_code=404,detail="car already exist!") + cars[car_id]=car.dict() + return car + +#UPDATE +#www.Famcars.com/cars/1 +#PUT Cars +@app.put("/cars/{car_id}", response_model=UpdateCar) +def update_car(car_id:UUID,car:UpdateCar): +# def update_car(car_id:int,car:UpdateCar): + if car_id not in cars: + raise HTTPException(status_code=404, detail="Car is not Found") + current_car= cars[car_id] + # if car.id is not None: + # current_car["id"]=car.id + if car.name is not None: + current_car["name"]=car.name + if car.country is not None: + current_car["country"] = car.country + if car.brand is not None: + current_car["brand"] = car.brand + if car.model is not None: + current_car["model"] = car.model + if car.year is not None: + current_car["year"] = car.year + + return current_car + +#DELETE +#www.Famcars.com/cars/1 +#DELETE Cars +@app.delete("/cars/{car_id}") +def deleted_car(car_id:UUID): +#def deleted_car(car_id:int): + if car_id not in cars: + HTTPException(status_code=404, detail="Car is not here") + + removed_car=cars.pop(car_id) + return {"massage":"car has been deleted", "deleted_car":removed_car} + + + + + + + + + + + + + +# if __name__ == "__main__": +# import uvicorn +# uvicorn.run(app,host="0.0.0.0",port=8000) + + + + + + + diff --git a/Docker_API/.ghaymah.json b/Docker_API/.ghaymah.json new file mode 100644 index 0000000..e69de29 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..644409d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,42 @@ +<<<<<<< HEAD +#(Base Image) +FROM python:3.11-slim + +#(here /app mean name in the fastAPI i used) +WORKDIR /app + +#(Copy and Install Dependancies/Libraries) +COPY Docker_API/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +#(Copy all files after install dependancies) +COPY . . + +#(Port my app listen to ) +EXPOSE 8000 + +#(Run app/file) +CMD ["uvicorn", "API:app", "--host", "0.0.0.0", "--port", "8000", "--log-config", "Log.yaml"] + +======= +#(Base Image) +FROM python:3.11-slim + +#(here /app mean name in the fastAPI i used) +WORKDIR /app + +#(Copy and Install Dependancies/Libraries) +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +#(Copy all files after install dependancies) +COPY . . + + +#(Port my app listen to ) +EXPOSE 8000 + +#(Run app/file) +CMD ["uvicorn", "API:app", "--host", "0.0.0.0", "--port", "8000", "--log-config", "Log.yaml"] + +>>>>>>> origin/scripts diff --git a/Final_MOnitor.sh b/Final_MOnitor.sh new file mode 100755 index 0000000..5ca241c --- /dev/null +++ b/Final_MOnitor.sh @@ -0,0 +1,120 @@ +#!/bin/bash + + +function get_server_metrics() { + SERVER_IP=$(hostname -I | awk '{print $1}') + CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}' | cut -d'.' -f1)% + RAM_AVAILABLE=$(free -m | awk 'NR==2{print $4 "MB"}') + DISK_SPACE=$(df -h / | awk 'NR==2 {print $4}') + + cat <>>>>>> origin/scripts +PyYAML==6.0.3 \ No newline at end of file diff --git a/scripts.sh b/scripts.sh new file mode 100644 index 0000000..ee2f025 --- /dev/null +++ b/scripts.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +Connection_URL = "http://127.0.0.1:8000" + + +while true ; do + echo "select option :" + echo " 1 => to add a car" + echo " 2 => to delete item " + echo " 3 => to log out from this script" + read -p "you choice is : " choice + + case $choice in + 1) + echo "you will add a car " + read -p "ID : " id + read -p "car name : " name + read -p "country : " country + read -p "brand : " brand + read -p "model : " model + read -p "year_of_model : " year_of_model + + curl -s -X POST "$Connection_URL/cars/$id" \ -H "Content-Type : application/json" \ -d "{\"id\":$id , \"name\":\"$name\" , \"country\":\"$country\",\"brand\":\"$brand\" , \"model\":\"$model\" , \"year_of_model\":\"$year_of_model\"}" + + echo "adding is successfully done " + ;; + + + 2) + echo "Enter the ID of item" + read -p "ID : " id + + curl -s -X DELETE "$BASE_URL/cars/$id" + echo "deleting successfully done " + ;; + + 3) + echo "Exit the system" + break + ;; + + *) + echo "you choice isn't exist, please enter right option" + ;; + + esac +done