├── README.md ├── backend_only ├── .gitignore ├── routes │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-313.pyc │ │ └── user_routes.cpython-313.pyc │ └── user_routes.py ├── README.md ├── requirements.txt ├── __pycache__ │ └── config.cpython-313.pyc ├── model │ ├── __pycache__ │ │ └── user_model.cpython-313.pyc │ └── user_model.py ├── config.py └── app.py └── withgraphql ├── app ├── config │ ├── __init__.py │ ├── __pycache__ │ │ ├── db.cpython-313.pyc │ │ └── __init__.cpython-313.pyc │ └── db.py ├── graphql │ ├── __init__.py │ ├── schema.py │ ├── __pycache__ │ │ ├── types.cpython-313.pyc │ │ ├── __init__.cpython-313.pyc │ │ └── resolvers.cpython-313.pyc │ ├── types.py │ └── resolvers.py ├── models │ ├── __init__.py │ ├── user.py │ └── student.py ├── services │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-313.pyc │ │ ├── user_service.cpython-313.pyc │ │ └── student_services.cpython-313.pyc │ ├── user_service.py │ └── student_services.py ├── __pycache__ │ └── __init__.cpython-313.pyc └── __init__.py ├── requirements.txt ├── .env └── app.py /README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /backend_only/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /backend_only/routes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /withgraphql/app/config/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /withgraphql/app/graphql/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /withgraphql/app/models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /withgraphql/app/services/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend_only/README.md: -------------------------------------------------------------------------------- 1 | I am Leraning Flask after Python & FAst API. 2 | -------------------------------------------------------------------------------- /backend_only/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/backend_only/requirements.txt -------------------------------------------------------------------------------- /withgraphql/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/requirements.txt -------------------------------------------------------------------------------- /withgraphql/.env: -------------------------------------------------------------------------------- 1 | MONGO_URI="mongodb+srv://me:Ns2Jd8zrfRB4JxxD@cluster0.lf78r.mongodb.net/flask_graphql?retryWrites=true&w=majority" 2 | 3 | -------------------------------------------------------------------------------- /backend_only/__pycache__/config.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/backend_only/__pycache__/config.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/graphql/schema.py: -------------------------------------------------------------------------------- 1 | import graphene 2 | from app.graphql.resolvers import Query 3 | 4 | schema = graphene.Schema(query=Query) 5 | 6 | -------------------------------------------------------------------------------- /withgraphql/app/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/config/__pycache__/db.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/config/__pycache__/db.cpython-313.pyc -------------------------------------------------------------------------------- /backend_only/model/__pycache__/user_model.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/backend_only/model/__pycache__/user_model.cpython-313.pyc -------------------------------------------------------------------------------- /backend_only/routes/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/backend_only/routes/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/graphql/__pycache__/types.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/graphql/__pycache__/types.cpython-313.pyc -------------------------------------------------------------------------------- /backend_only/routes/__pycache__/user_routes.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/backend_only/routes/__pycache__/user_routes.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/config/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/config/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/graphql/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/graphql/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/graphql/__pycache__/resolvers.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/graphql/__pycache__/resolvers.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/services/__pycache__/__init__.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/services/__pycache__/__init__.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/services/__pycache__/user_service.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/services/__pycache__/user_service.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/services/__pycache__/student_services.cpython-313.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arbab-Mustafa/Learning_Flask/HEAD/withgraphql/app/services/__pycache__/student_services.cpython-313.pyc -------------------------------------------------------------------------------- /withgraphql/app/config/db.py: -------------------------------------------------------------------------------- 1 | from pymongo import MongoClient 2 | import os 3 | 4 | # Load MongoDB URI from .env file or use default 5 | MONGO_URI = os.getenv("MONGO_URI") 6 | 7 | client = MongoClient(MONGO_URI) 8 | db = client["flask_graphql"] # Database name 9 | -------------------------------------------------------------------------------- /withgraphql/app/models/user.py: -------------------------------------------------------------------------------- 1 | class User: 2 | def __init__(self, username, email): 3 | self.username = username 4 | self.email = email 5 | 6 | def to_dict(self): 7 | return {"username": self.username, "email": self.email} 8 | 9 | -------------------------------------------------------------------------------- /withgraphql/app/models/student.py: -------------------------------------------------------------------------------- 1 | class Student: 2 | def __init__(self, name, age, grade): 3 | self.name = name 4 | self.age = age 5 | self.grade = grade 6 | 7 | def to_dict(self): 8 | 9 | return {"name": self.name, "age": self.age, "grade": self.grade} -------------------------------------------------------------------------------- /withgraphql/app/graphql/types.py: -------------------------------------------------------------------------------- 1 | import graphene 2 | 3 | class UserType(graphene.ObjectType): 4 | username = graphene.String() 5 | email = graphene.String() 6 | 7 | class StudentType(graphene.ObjectType): 8 | name = graphene.String() 9 | age = graphene.Int() 10 | grade = graphene.String() 11 | 12 | -------------------------------------------------------------------------------- /backend_only/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | from flask_pymongo import PyMongo 4 | 5 | # Load environment variables from .env file 6 | load_dotenv() 7 | 8 | class MONGO_Config: 9 | MONGO_URI = os.getenv("MONGO_URI") # ✅ Ensure .env has MONGO_URI 10 | 11 | mongo = PyMongo() # ✅ Define `mongo` here to avoid circular imports 12 | -------------------------------------------------------------------------------- /withgraphql/app/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_graphql import GraphQLView 3 | from app.graphql.resolvers import Query, Mutation 4 | import graphene 5 | 6 | app = Flask(__name__) 7 | 8 | schema = graphene.Schema(query=Query, mutation=Mutation) 9 | 10 | app.add_url_rule( 11 | "/graphql", 12 | view_func=GraphQLView.as_view("graphql", schema=schema, graphiql=True), 13 | ) 14 | -------------------------------------------------------------------------------- /backend_only/model/user_model.py: -------------------------------------------------------------------------------- 1 | from flask_pymongo import PyMongo 2 | 3 | mongo = PyMongo() # Initialize MongoDB 4 | 5 | def serialize_user(user): 6 | return { 7 | "_id": str(user["_id"]), # Convert ObjectId to string 8 | "name": user.get("name", ""), 9 | "email": user.get("email", ""), 10 | "password": user.get("password", ""), # Consider hashing passwords before storing 11 | "created_at": user.get("created_at", ""), 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /backend_only/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_cors import CORS 3 | from config import MONGO_Config, mongo # ✅ Import mongo from config 4 | from routes.user_routes import user_bp # ✅ Only import routes 5 | 6 | app = Flask(__name__) 7 | app.config.from_object(MONGO_Config) # ✅ Load MongoDB URI 8 | mongo.init_app(app) # ✅ Initialize MongoDB 9 | CORS(app) 10 | 11 | # Register routes 12 | app.register_blueprint(user_bp, url_prefix="/api") 13 | 14 | if __name__ == "__main__": 15 | app.run(debug=True, port=5000) 16 | -------------------------------------------------------------------------------- /withgraphql/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask_cors import CORS 3 | from flask_graphql import GraphQLView 4 | from graphene import Schema 5 | from app.graphql.resolvers import Query, Mutation # ✅ This should work 6 | 7 | 8 | from app.config import db # ✅ Correct 9 | 10 | 11 | app = Flask(__name__) 12 | CORS(app) 13 | 14 | schema = Schema(query=Query, mutation=Mutation) 15 | 16 | app.add_url_rule( 17 | "/", view_func=GraphQLView.as_view("graphql", schema=schema, graphiql=True) 18 | ) 19 | 20 | if __name__ == "__main__": 21 | app.run(debug=True) 22 | -------------------------------------------------------------------------------- /withgraphql/app/services/user_service.py: -------------------------------------------------------------------------------- 1 | from app.config.db import db 2 | 3 | users_collection = db["users"] 4 | # Get user by username 5 | def get_user_by_username(username): 6 | user = users_collection.find_one({"username": username}) 7 | if user: 8 | return {"username": user["username"], "email": user["email"]} 9 | return None 10 | 11 | # Create user 12 | def create_user(username, email): 13 | if get_user_by_username(username): # Check if user already exists 14 | return None 15 | user_data = {"username": username, "email": email} 16 | users_collection.insert_one(user_data) 17 | return user_data 18 | 19 | # Delete user 20 | def delete_user(username): 21 | result = users_collection.delete_one({"username": username}) 22 | return result.deleted_count > 0 # True if user was deleted, False otherwise 23 | 24 | # Get all users 25 | def get_all_users(): 26 | users = list(users_collection.find({}, {"_id": 0, "username": 1, "email": 1})) 27 | return users 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /withgraphql/app/services/student_services.py: -------------------------------------------------------------------------------- 1 | from app.config.db import db 2 | 3 | students_collection = db["students"] 4 | 5 | 6 | def get_All_students(): 7 | try: 8 | students = list(students_collection.find({}, {"_id": 0})) 9 | if not students: 10 | return None 11 | return students 12 | except Exception as e: 13 | print( 14 | f"An error occurred while getting all students. Error: {str(e)}") 15 | return None 16 | 17 | 18 | def get_student_by_name(name): 19 | try: 20 | student = students_collection.find_one({"name": name}, {"_id": 0}) 21 | if student: 22 | return student 23 | return None 24 | 25 | except Exception as e: 26 | print(f"An error occurred while getting student by name. Error: {str(e)}") 27 | return None 28 | 29 | 30 | def create_student(name, age, grade): 31 | try: 32 | student = {"name": name, "age": age, "grade": grade} 33 | students_collection.insert_one(student) 34 | return student 35 | 36 | except Exception as e: 37 | print(f"An error occurred while Creating Student Error: {str(e)}") 38 | return None 39 | 40 | 41 | def delete_student_name(name): 42 | try: 43 | student = students_collection.find_one({"name": name}) 44 | if not student: 45 | return False # Student not found 46 | 47 | result = students_collection.delete_one({"name": name}) 48 | return result.deleted_count > 0 49 | 50 | except Exception as e: 51 | print(f"An error occurred while deleting the student. Error: {str(e)}") 52 | return False 53 | 54 | 55 | def update_student(name, age, grade): 56 | try: 57 | student = {"name": name, "age": age, "grade": grade} 58 | students_collection.update_one({"name": name}, {"$set": student}) 59 | return student 60 | except Exception as e: 61 | print(f"An error occurred while updating student. Error: {str(e)}") 62 | return None 63 | -------------------------------------------------------------------------------- /withgraphql/app/graphql/resolvers.py: -------------------------------------------------------------------------------- 1 | from graphene import ObjectType, Field, String, Mutation , Int 2 | from app.services.user_service import get_user_by_username, create_user, delete_user , get_all_users 3 | from app.graphql.types import UserType , StudentType 4 | import graphene 5 | 6 | # --add student --- 7 | from app.services.student_services import get_All_students , get_student_by_name , create_student ,delete_student_name , update_student 8 | 9 | class Query(ObjectType): 10 | get_user = Field(UserType, username=String(required=True)) 11 | get_all_users = graphene.List(UserType) 12 | get_all_students = graphene.List(StudentType) 13 | get_student_by_name = Field(StudentType, name=String(required=True)) 14 | 15 | def resolve_get_all_students(root, info): 16 | students = get_All_students() 17 | return [StudentType(name=student["name"], age=student["age"], grade=student["grade"]) for student in students] 18 | 19 | def resolve_get_student_by_name(root, info, name): 20 | student = get_student_by_name(name) 21 | if student: 22 | return StudentType(name=student["name"], age=student["age"], grade=student["grade"]) 23 | return None 24 | 25 | def resolve_get_user(root, info, username): 26 | user = get_user_by_username(username) 27 | if user: 28 | return UserType(username=user["username"], email=user["email"]) 29 | return None 30 | 31 | def resolve_get_all_users(root, info): 32 | users = get_all_users() 33 | return [UserType(username=user["username"], email=user["email"]) for user in users] 34 | 35 | class CreateUser(Mutation): 36 | class Arguments: 37 | username = String(required=True) 38 | email = String(required=True) 39 | 40 | user = Field(UserType) 41 | 42 | def mutate(root, info, username, email): 43 | user_data = create_user(username, email) 44 | return CreateUser(user=UserType(username=user_data["username"], email=user_data["email"])) 45 | 46 | 47 | class DeleteUser(Mutation): 48 | class Arguments: 49 | username = String(required=True) 50 | 51 | success = String() 52 | 53 | def mutate(root, info, username): 54 | if delete_user(username): 55 | return DeleteUser(success="User deleted successfully") 56 | return DeleteUser(success="User not found") 57 | 58 | class DeleteStudent(graphene.Mutation): 59 | class Arguments: 60 | name = graphene.String(required=True) 61 | 62 | success = graphene.String() 63 | 64 | def mutate(root, info, name): 65 | if delete_student_name(name): 66 | return DeleteStudent(success="Student deleted successfully") 67 | return DeleteStudent(success="Student not found") 68 | 69 | 70 | class CreateStudent(graphene.Mutation): 71 | class Arguments: 72 | name = graphene.String(required=True) 73 | age = graphene.Int(required=True) 74 | grade = graphene.String(required=True) 75 | 76 | student = graphene.Field(StudentType) 77 | 78 | def mutate(root, info, name, age, grade): 79 | student = create_student(name, age, grade) 80 | return CreateStudent(student=StudentType(name=student["name"], age=student["age"], grade=student["grade"])) 81 | 82 | 83 | class updateStudent(Mutation): 84 | class Arguments: 85 | name = graphene.String(required=True) 86 | age = graphene.Int(required=True) 87 | grade = graphene.String(required=True) 88 | 89 | student = graphene.Field(StudentType) 90 | 91 | def mutate(root, info, name, age, grade): 92 | student = update_student(name, age, grade) 93 | return updateStudent(student=StudentType(name=student["name"], age=student["age"], grade=student["grade"])) 94 | 95 | 96 | class Mutation(ObjectType): 97 | create_user = CreateUser.Field() 98 | delete_user = DeleteUser.Field() 99 | create_student = CreateStudent.Field() 100 | delete_student = DeleteStudent.Field() 101 | update_student = updateStudent.Field() 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /backend_only/routes/user_routes.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint, jsonify, request# Ensure you have initialized PyMongo in config 2 | from model.user_model import serialize_user 3 | from datetime import datetime 4 | from config import mongo # ✅ Import mongo properly 5 | from bson import ObjectId 6 | from werkzeug.security import generate_password_hash , check_password_hash 7 | import re 8 | 9 | user_bp = Blueprint("user_bp", __name__) 10 | 11 | 12 | # GET all users 13 | @user_bp.route("/users", methods=["GET"]) 14 | def get_users(): 15 | try: 16 | # Get all user documents from the database 17 | users = mongo.db.users.find() 18 | # Serialize the MongoDB users to JSON 19 | return jsonify([serialize_user(user) for user in users]) 20 | except Exception as e: 21 | return jsonify({"error": str(e)}), 500 22 | 23 | 24 | @user_bp.route("/user", methods=["POST"]) 25 | def create_user(): 26 | try: 27 | data = request.get_json() 28 | 29 | # Validate required fields 30 | if not data or not all(k in data for k in ["name", "email", "password"]): 31 | return jsonify({"error": "Name, email, and password are required"}), 400 32 | 33 | name = data["name"].strip() 34 | email = data["email"].strip().lower() 35 | password = data["password"] 36 | 37 | 38 | 39 | # Validate password strength 40 | if len(password) < 6: 41 | return jsonify({"error": "Password must be at least 6 characters long"}), 400 42 | 43 | # Check if user already exists 44 | if mongo.db.users.find_one({"email": email}): 45 | return jsonify({"error": "User with this email already exists"}), 409 46 | 47 | # Hash password 48 | hashed_password = generate_password_hash(password) 49 | 50 | # Save user to DB 51 | new_user = {"name": name, "email": email, "password": hashed_password} 52 | inserted_user = mongo.db.users.insert_one(new_user) 53 | 54 | # Return success response (exclude password) 55 | new_user["_id"] = str(inserted_user.inserted_id) 56 | 57 | 58 | return jsonify({"message": "User created successfully", "user": new_user}), 201 59 | except Exception as e: 60 | return jsonify({"error": "Internal Server Error", "details": str(e)}), 500 61 | 62 | @user_bp.route("/user/", methods=["GET"]) 63 | def get_user(id): 64 | try: 65 | # Convert id to ObjectId 66 | user = mongo.db.users.find_one({"_id": ObjectId(id)}) 67 | 68 | if user: 69 | return jsonify(serialize_user(user)) 70 | 71 | return jsonify({"error": "User not found"}), 404 72 | except Exception as e: 73 | return jsonify({"error": str(e)}), 500 74 | 75 | @user_bp.route("/user/", methods=["DELETE"]) 76 | def delete_user(id): 77 | 78 | try: 79 | # Convert id to ObjectId 80 | result = mongo.db.users.delete_one({"_id": ObjectId(id)}) 81 | 82 | if result.deleted_count: 83 | return jsonify( 84 | {"message": "User deleted successfully", "id": str(id)} 85 | ) 86 | 87 | return jsonify({"error": "User not found"}), 404 88 | except Exception as e: 89 | return jsonify({"error": str(e)}), 500 90 | 91 | @user_bp.route("/user/", methods=["PUT"]) 92 | def update_user(id): 93 | try: 94 | data = request.get_json() 95 | if not data: 96 | return jsonify({"error": "No data provided to update"}), 400 97 | 98 | # Convert id to ObjectId 99 | user = mongo.db.users.find_one({"_id": ObjectId(id)}) 100 | 101 | if user: 102 | mongo.db.users.update_one( 103 | {"_id": ObjectId(id)}, 104 | {"$set": data}, 105 | 106 | 107 | ) 108 | return jsonify({"message": "User updated successfully", "id": str(id)}) 109 | return jsonify({"error": "User not found"}), 404 110 | except Exception as e: 111 | return jsonify({"error": str(e)}), 500 112 | 113 | 114 | 115 | @user_bp.route("/login", methods=["POST"]) 116 | def login_user(): 117 | try: 118 | data = request.get_json() 119 | if not data or not all(k in data for k in ["email", "password"]): 120 | return jsonify({"error": "Email and password are required"}), 400 121 | 122 | email = data["email"].strip().lower() 123 | password = data["password"] 124 | 125 | user = mongo.db.users.find_one({"email": email}) 126 | 127 | if user: 128 | if check_password_hash(user["password"], password): 129 | return jsonify({"message": "Login successful", "user": serialize_user(user)}) 130 | 131 | 132 | # make token / session / cookie which is best for user login 133 | return jsonify({"error": "Invalid email or password"}), 401 134 | except Exception as e: 135 | return jsonify({"error": str(e)}), 500 --------------------------------------------------------------------------------