هذا الالتزام موجود في:
ahmedgamalyousef
2025-09-28 00:07:19 +03:00
الأصل 598ec506a2
التزام 75166ab287
5 ملفات معدلة مع 262 إضافات و134 حذوفات

عرض الملف

@@ -1,9 +1,21 @@
# fruit_api.py
from flask import Flask, jsonify, request
from datetime import datetime
import logging
app = Flask(__name__)
# -----------------------
# Logging Configuration
# -----------------------
LOG_FILE = "fruit_api.log"
logging.basicConfig(
filename=LOG_FILE,
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
)
# In-memory database
fruits = [
{"id": 1, "name": "Apple", "color": "Red", "price": 1.50, "quantity": 100, "category": "Tropical"},
@@ -11,33 +23,36 @@ fruits = [
{"id": 3, "name": "Orange", "color": "Orange", "price": 1.20, "quantity": 80, "category": "Citrus"}
]
# 1. GET / - Home endpoint
# -----------------------
# Logging Hooks
# -----------------------
@app.before_request
def log_request():
logging.info(
f"REQUEST: method={request.method} path={request.path} "
f"args={dict(request.args)} body={request.get_json(silent=True)} "
f"ip={request.remote_addr}"
)
@app.after_request
def log_response(response):
logging.info(
f"RESPONSE: method={request.method} path={request.path} "
f"status={response.status_code} ip={request.remote_addr}"
)
return response
# -----------------------
# API Endpoints
# -----------------------
@app.route('/')
def home():
return jsonify({
"message": "Fruit Store API",
"version": "1.0",
"endpoints": [
"GET /fruits - Get all fruits",
"GET /fruits/<id> - Get fruit by ID",
"POST /fruits - Add new fruit",
"PUT /fruits/<id> - Update fruit",
"DELETE /fruits/<id> - Delete fruit",
"GET /fruits/category/<category> - Get fruits by category",
"GET /fruits/search?name=<name> - Search fruits by name"
]
})
return jsonify({"message": "Fruit Store API", "version": "1.0"})
# 2. GET /fruits - Get all fruits
@app.route('/fruits', methods=['GET'])
def get_all_fruits():
return jsonify({
"fruits": fruits,
"total": len(fruits),
"timestamp": datetime.now().isoformat()
})
return jsonify({"fruits": fruits, "total": len(fruits)})
# 3. GET /fruits/<id> - Get specific fruit
@app.route('/fruits/<int:fruit_id>', methods=['GET'])
def get_fruit(fruit_id):
fruit = next((f for f in fruits if f['id'] == fruit_id), None)
@@ -45,17 +60,13 @@ def get_fruit(fruit_id):
return jsonify({"fruit": fruit})
return jsonify({"error": "Fruit not found"}), 404
# 4. POST /fruits - Create new fruit
@app.route('/fruits', methods=['POST'])
def create_fruit():
data = request.get_json()
if not data or 'name' not in data:
return jsonify({"error": "Name is required"}), 400
# Generate new ID
new_id = max([f['id'] for f in fruits]) + 1 if fruits else 1
new_fruit = {
"id": new_id,
"name": data['name'],
@@ -65,99 +76,16 @@ def create_fruit():
"category": data.get('category', 'General'),
"created_at": datetime.now().isoformat()
}
fruits.append(new_fruit)
return jsonify({
"message": "Fruit created successfully",
"fruit": new_fruit
}), 201
return jsonify({"message": "Fruit created successfully", "fruit": new_fruit}), 201
# 5. PUT /fruits/<id> - Update fruit
@app.route('/fruits/<int:fruit_id>', methods=['PUT'])
def update_fruit(fruit_id):
fruit = next((f for f in fruits if f['id'] == fruit_id), None)
if not fruit:
return jsonify({"error": "Fruit not found"}), 404
data = request.get_json()
# Update allowed fields
if 'name' in data:
fruit['name'] = data['name']
if 'color' in data:
fruit['color'] = data['color']
if 'price' in data:
fruit['price'] = data['price']
if 'quantity' in data:
fruit['quantity'] = data['quantity']
if 'category' in data:
fruit['category'] = data['category']
fruit['updated_at'] = datetime.now().isoformat()
return jsonify({
"message": "Fruit updated successfully",
"fruit": fruit
})
# 6. DELETE /fruits/<id> - Delete fruit
@app.route('/fruits/<int:fruit_id>', methods=['DELETE'])
def delete_fruit(fruit_id):
global fruits
fruit = next((f for f in fruits if f['id'] == fruit_id), None)
if not fruit:
return jsonify({"error": "Fruit not found"}), 404
fruits = [f for f in fruits if f['id'] != fruit_id]
return jsonify({
"message": "Fruit deleted successfully",
"deleted_fruit": fruit
})
# 7. GET /fruits/category/<category> - Get fruits by category
@app.route('/fruits/category/<category>', methods=['GET'])
def get_fruits_by_category(category):
category_fruits = [f for f in fruits if f['category'].lower() == category.lower()]
return jsonify({
"category": category,
"fruits": category_fruits,
"count": len(category_fruits)
})
# Search endpoint
@app.route('/fruits/search', methods=['GET'])
def search_fruits():
name_query = request.args.get('name', '').lower()
if not name_query:
return jsonify({"error": "Name parameter is required"}), 400
matching_fruits = [f for f in fruits if name_query in f['name'].lower()]
return jsonify({
"search_term": name_query,
"results": matching_fruits,
"count": len(matching_fruits)
})
# Health check endpoint
@app.route('/health', methods=['GET'])
def health_check():
return jsonify({
"status": "healthy",
"service": "fruit-api",
"timestamp": datetime.now().isoformat()
})
return jsonify({"status": "healthy", "service": "fruit-api"})
# -----------------------
# Run API
# -----------------------
if __name__ == '__main__':
print("Fruit API starting on http://localhost:5000")
print("Available endpoints:")
print("1. GET / - Home")
print("2. GET /fruits - All fruits")
print("3. GET /fruits/<id> - Fruit by ID")
print("4. POST /fruits - Create fruit")
print("5. PUT /fruits/<id> - Update fruit")
print("6. DELETE /fruits/<id> - Delete fruit")
print("7. GET /fruits/category/<category> - Fruits by category")
print("8. GET /fruits/search?name=X - Search fruits")
print("9. GET /health - Health check")
app.run(debug=True, host='0.0.0.0', port=5000)
app.run(debug=False, host='0.0.0.0', port=5000)