second
هذا الالتزام موجود في:
17
.ghaymah.json
Normal file
17
.ghaymah.json
Normal file
@@ -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"
|
||||
}
|
||||
38
.github/workflows/ci\cd.yaml
مباع
Normal file
38
.github/workflows/ci\cd.yaml
مباع
Normal file
@@ -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
|
||||
27
.gitignore
مباع
Normal file
27
.gitignore
مباع
Normal file
@@ -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/
|
||||
|
||||
|
||||
|
||||
|
||||
141
API.py
Normal file
141
API.py
Normal file
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0
Docker_API/.ghaymah.json
Normal file
0
Docker_API/.ghaymah.json
Normal file
42
Dockerfile
Normal file
42
Dockerfile
Normal file
@@ -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
|
||||
120
Final_MOnitor.sh
Executable file
120
Final_MOnitor.sh
Executable file
@@ -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 <<EOF
|
||||
"ip": "$SERVER_IP",
|
||||
"cpu_usage": "$CPU_USAGE",
|
||||
"ram_available": "$RAM_AVAILABLE",
|
||||
"disk_space": "$DISK_SPACE"
|
||||
EOF
|
||||
}
|
||||
#_____________________________________________________
|
||||
|
||||
|
||||
LOG_FILE="/home/abdelrhman/PyCharmMiscProject/AP.log"
|
||||
#STATUS_CODE=$(tail -n1 "$LOG_FILE" | cut -d " " -f9)
|
||||
#REQUEST=$(tail -n1 $LOG_FILE | cut -d " " -f6)
|
||||
#DATE_OF_REQUEST=$(tail -n1 $LOG_FILE | cut -d " " -f1)
|
||||
#REQUEST_TIME=$(tail -n1 $LOG_FILE | cut -d " " -f2)
|
||||
#IP_SERVER=$(tail -n1 $LOG_FILE | cut -d " " -f4 | cut -d ":" -f1)
|
||||
#ALERT_API=______________________________________________________________
|
||||
#SERVER_METRICS=$(get_server_metrics)
|
||||
|
||||
#JSON_PAYLOAD=$(cat <<EOF
|
||||
#{
|
||||
# "error": "$STATUS_CODE Error",
|
||||
#"timestamp": "$DATE_OF_REQUEST:$REQUEST_TIME",
|
||||
#"server_metrics": {
|
||||
# $SERVER_METRICS
|
||||
#}
|
||||
#}
|
||||
#EOF
|
||||
#)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
tail -n 0 -f "$LOG_FILE" | while read -r NEW_LINE; do
|
||||
|
||||
|
||||
STATUS_CODE=$(tail -n1 "$LOG_FILE" | cut -d " " -f9)
|
||||
REQUEST=$(tail -n1 $LOG_FILE | cut -d " " -f6)
|
||||
DATE_OF_REQUEST=$(tail -n1 $LOG_FILE | cut -d " " -f1)
|
||||
REQUEST_TIME=$(tail -n1 $LOG_FILE | cut -d " " -f2)
|
||||
IP_SERVER=$(tail -n1 $LOG_FILE | cut -d " " -f4 | cut -d ":" -f1)
|
||||
#ALERT_API=______________________________________________________________
|
||||
#SERVER_METRICS=$(get_server_metrics)
|
||||
|
||||
JSON_PAYLOAD=$(cat <<EOF
|
||||
{
|
||||
"error": "$STATUS_CODE Error",
|
||||
"timestamp": "$DATE_OF_REQUEST:$REQUEST_TIME",
|
||||
"server_metrics": {
|
||||
$SERVER_METRICS
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
if [[ "$STATUS_CODE" =~ ^[0-9] ]];
|
||||
then
|
||||
# echo $NEW_LINE
|
||||
echo "Status code is $STATUS_CODE "
|
||||
echo "IP is $IP_SERVER "
|
||||
echo "Date of request $DATE_OF_REQUEST "
|
||||
echo "Request time $REQUEST_TIME"
|
||||
echo "The request is $REQUEST "
|
||||
|
||||
case $STATUS_CODE in
|
||||
2??)
|
||||
echo -e "The process\033[32m[DONE]\033[0m correctly"
|
||||
echo
|
||||
|
||||
;;
|
||||
3??)
|
||||
echo -e "there is a \033[33m[REDIRECT]\033[0m Error"
|
||||
echo
|
||||
|
||||
;;
|
||||
4??)
|
||||
echo -e "Not found \033[31m[ERROR]\033[0m"
|
||||
echo
|
||||
|
||||
;;
|
||||
5??)
|
||||
echo -e "Server \033[31m[ERROR]\033[0m"
|
||||
echo
|
||||
#function get_server_metrics
|
||||
#curl -s -X POST -H "Content-Type: application/json" -d "$JSON_PAYLOAD" $ALERT_API
|
||||
|
||||
;;
|
||||
|
||||
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
||||
# if [ $STATUS_CODE -ge 200 ] && [ $STATUS_CODE -lt 300 ]
|
||||
# then
|
||||
# echo "its done bro"
|
||||
#
|
||||
# elif [ $STATUS_CODE -ge 300 ] && [ $STATUS_CODE -lt 400 ]
|
||||
# then
|
||||
# echo "Redirect Error"
|
||||
# elif [ $STATUS_CODE -ge 400 ] && [ $STATUS_CODE -lt 500 ]
|
||||
# then
|
||||
# echo "NOT Found"
|
||||
#
|
||||
# else
|
||||
# echo "Server Error"
|
||||
# fi
|
||||
#done
|
||||
7
Gtest.api.sh
Executable file
7
Gtest.api.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
API_URL="http://127.0.0.1:8000/cars/"
|
||||
|
||||
curl $API_URL
|
||||
|
||||
|
||||
29
Log.yaml
Normal file
29
Log.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
version: 1
|
||||
disable_existing_loggers: False
|
||||
|
||||
formatters:
|
||||
uvicorn_custom_fmt:
|
||||
format: '%(asctime)s [%(levelname)s]: %(message)s'
|
||||
datefmt: '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
handlers:
|
||||
File:
|
||||
formatter: uvicorn_custom_fmt
|
||||
class: logging.handlers.RotatingFileHandler
|
||||
filename: 'AP.log'
|
||||
encoding: utf8
|
||||
default:
|
||||
formatter: uvicorn_custom_fmt
|
||||
class: logging.StreamHandler
|
||||
stream: ext://sys.stderr
|
||||
|
||||
loggers:
|
||||
uvicorn.access:
|
||||
handlers: [ default , File ]
|
||||
level: INFO
|
||||
propagate: False
|
||||
uvicorn:
|
||||
handlers: [ default , File ]
|
||||
level: INFO
|
||||
propagate: False
|
||||
|
||||
18
PO.test.api.sh
Executable file
18
PO.test.api.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
API_URL="http://127.0.0.1:8000/cars/"
|
||||
CONCURRENT=1000
|
||||
FILE="/home/abdelrhman/PyCharmMiscProject/data.txt"
|
||||
|
||||
|
||||
for i in $(seq 1 $CONCURRENT)
|
||||
do
|
||||
echo $i
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @$FILE \
|
||||
-s -o /dev/null \
|
||||
-k -L -i "$API_URL"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
8
data.txt
Normal file
8
data.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "A-Class-List-3",
|
||||
"country": "Germany",
|
||||
"brand": "Mercedes",
|
||||
"model": "A180-2027",
|
||||
"year": 2027
|
||||
}
|
||||
|
||||
10
requirements.txt
Normal file
10
requirements.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
<<<<<<< HEAD
|
||||
fastapi==0.117.1
|
||||
uvicorn==0.37.0
|
||||
pydantic==2.11.9
|
||||
=======
|
||||
fastapi==0.117.1
|
||||
uvicorn==0.37.0
|
||||
pydantic==2.11.9
|
||||
>>>>>>> origin/scripts
|
||||
PyYAML==6.0.3
|
||||
47
scripts.sh
Normal file
47
scripts.sh
Normal file
@@ -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
|
||||
المرجع في مشكلة جديدة
حظر مستخدم