PyAwaish 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ CHANGELOG
2
+ =========
3
+
4
+ Version 1.0 (2025-01-27)
5
+ ---------------------------
6
+
7
+ - Initial release of PyAwaish.
8
+ - Added dynamic MySQL configuration through a web interface.
9
+ - Implemented template rendering for `config_mysql.html` and `home.html`.
10
+ - Developed `/execute_query` endpoint for executing MySQL queries.
11
+ - Supported CRUD operations: insert, delete, update, fetch_data.
12
+ - Enabled secure database connection using environment variables.
13
+ - Provided RESTFul API design for interaction with MySQL.
14
+ - Fixed the code markdown in readme.rst file
15
+ - Added warning messages
@@ -0,0 +1,6 @@
1
+ Copyright 2025 Abu Awaish
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
@@ -0,0 +1,22 @@
1
+ # Include important project metadata and configuration files
2
+ include README.rst
3
+ include LICENSE.txt # Explicitly mention the extension
4
+ include setup.py
5
+ include pyproject.toml
6
+ include requirements.txt
7
+ include CHANGELOG.txt
8
+
9
+ # Include all files in the templates directory (and subdirectories)
10
+ recursive-include PyAwaish/templates *
11
+
12
+ # Include all Python source files in the package
13
+ recursive-include PyAwaish *.py
14
+
15
+ # Exclude compiled Python files and cache directories
16
+ global-exclude *.pyc
17
+ global-exclude __pycache__/
18
+
19
+ # Exclude log and temporary files
20
+ global-exclude *.log
21
+ global-exclude *.tmp
22
+ global-exclude .idea/
pyawaish-1.0/PKG-INFO ADDED
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.2
2
+ Name: PyAwaish
3
+ Version: 1.0
4
+ Summary: A Python package for building dynamic MySQL-powered web applications with template support
5
+ Home-page: https://github.com/abuawaish/Crud_app
6
+ Author: Abu Awaish
7
+ Author-email: abuawaish7@gmail.com
8
+ License: MIT
9
+ Keywords: web application flask mysql dynamic templates
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/x-rst
15
+ License-File: LICENSE.txt
16
+ Requires-Dist: Flask
17
+ Requires-Dist: Flask-MySQLdb
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ PyAwaish
31
+ ===========
32
+
33
+ **PyAwaish** is a Flask-based Python framework that simplifies the development of MySQL-powered web applications. It provides a streamlined interface for connecting to a MySQL database, rendering templates, and executing queries dynamically via RESTful APIs.
34
+
35
+ Features
36
+ --------
37
+ - **Dynamic MySQL Configuration**: Configure MySQL database settings at runtime via a web interface.
38
+ - **Template Rendering**: Built-in support for rendering templates stored in the `templates` folder.
39
+ - **Query Execution API**: Execute MySQL queries dynamically through POST requests.
40
+ - **CRUD Operations**: Perform create, read, update, and delete operations programmatically.
41
+ - **RESTful Design**: Leverage Flask to expose endpoints for database interactions.
42
+ - **Environment Configuration**: Load sensitive credentials securely using environment variables.
43
+
44
+ Badges
45
+ ------
46
+
47
+ .. image:: https://badge.fury.io/py/PyAwaish.svg
48
+ :target: https://pypi.org/project/PyAwaish/
49
+
50
+ .. image:: https://img.shields.io/badge/License-MIT-yellow.svg
51
+ :target: https://opensource.org/licenses/MIT
52
+
53
+
54
+ Endpoints
55
+ ---------
56
+ 1. **`/`**: Displays the MySQL configuration page.
57
+ 2. **`/home`**: Displays the home page.
58
+ 3. **`/config_mysql`**: Accepts a POST request to configure MySQL connection details dynamically.
59
+ 4. **`/execute_query`**: Accepts a POST request to execute MySQL queries or perform operations (e.g., insert, delete, update).
60
+
61
+ Installation
62
+ ------------
63
+ 1. Clone the repository:
64
+
65
+ .. code-block:: bash
66
+
67
+ git clone https://github.com/abuawaish/CRUD_App.git
68
+ cd CRUD_App
69
+
70
+ 2. Install the required dependencies:
71
+
72
+ .. code-block:: bash
73
+
74
+ pip install -r requirements.txt
75
+
76
+ 3. Install the package:
77
+
78
+ .. code-block:: bash
79
+
80
+ pip install PyAwaish
81
+
82
+ 4. Set environment variables for database configuration:
83
+
84
+ .. code-block:: bash
85
+
86
+ export MYSQL_HOST=localhost
87
+ export MYSQL_USER=root
88
+ export MYSQL_PASSWORD=your password
89
+ export MYSQL_DB=mydatabase
90
+ export SECRET_KEY=your_secret_key
91
+
92
+
93
+ Usage
94
+ -----
95
+
96
+ **Running the Application**
97
+
98
+ To start the MysqlWebApp server, instantiate the `MysqlApplication` class and call its `execute` method. For example:
99
+
100
+ .. code-block:: python
101
+
102
+ from PyAwaish.MysqlApplication import MysqlApplication
103
+
104
+ if __name__ == "__main__":
105
+ app = MysqlApplication()
106
+ app.execute()
107
+
108
+ **This will:**
109
+
110
+ - Start a Flask server on `http://0.0.0.0:5001`.
111
+ - Serve endpoints for configuring and interacting with the MySQL database.
112
+
113
+
114
+ **Configuring MySQL**
115
+
116
+ 1. Navigate to the root endpoint (`http://localhost:5001/`) to access the configuration page.
117
+ 2. Enter the database details (host, username, password, database name) and click "Save".
118
+ 3. Upon successful configuration, you will be redirected to the home page.
119
+
120
+ **Executing Queries**
121
+
122
+ Use the `/execute_query` endpoint to run SQL queries or perform operations. Example request:
123
+
124
+ - **POST Request Example**:
125
+
126
+ .. code-block:: json
127
+
128
+ {
129
+ "operation": "insert",
130
+ "table_name": "users",
131
+ "columns": "name, email",
132
+ "values": "'John Doe', 'john@example.com'"
133
+ }
134
+
135
+ - **Supported Operations**:
136
+ - `insert`: Insert data into a table.
137
+ - `delete`: Delete data from a table with a condition.
138
+ - `update`: Update data in a table with a condition.
139
+ - `fetch_data`: Fetch all data from a table.
140
+ - `show_tables`: List all tables in the database.
141
+
142
+ Dependencies
143
+ ------------
144
+ The application requires the following dependencies (listed in `requirements.txt`):
145
+
146
+ - Flask: Web framework.
147
+ - Flask-MySQLdb: MySQL connector for Flask.
148
+
149
+ To install them, run:
150
+
151
+ .. code-block:: bash
152
+
153
+ pip install -r requirements.txt
154
+
155
+ Environment Variables
156
+ ---------------------
157
+ - **MYSQL_HOST**: MySQL server hostname (default: `localhost`).
158
+ - **MYSQL_USER**: MySQL username (default: `root`).
159
+ - **MYSQL_PASSWORD**: MySQL password.
160
+ - **MYSQL_DB**: Default MySQL database name.
161
+ - **SECRET_KEY**: Flask secret key for session security.
162
+
163
+ Changelog
164
+ ---------
165
+ Refer to `CHANGELOG.txt` for the complete version history of the project.
166
+
167
+ License
168
+ -------
169
+ This project is licensed under the MIT License. See `LICENSE.txt` for full details.
170
+
171
+ Contact
172
+ -------
173
+ For questions or feedback, contact:
174
+
175
+ - Email: abuawaish7@gmail.com
176
+ - GitHub: https://github.com/abuawaish/CRUD_App
177
+
178
+
179
+ CHANGELOG
180
+ =========
181
+
182
+ Version 1.0 (2025-01-27)
183
+ ---------------------------
184
+
185
+ - Initial release of PyAwaish.
186
+ - Added dynamic MySQL configuration through a web interface.
187
+ - Implemented template rendering for `config_mysql.html` and `home.html`.
188
+ - Developed `/execute_query` endpoint for executing MySQL queries.
189
+ - Supported CRUD operations: insert, delete, update, fetch_data.
190
+ - Enabled secure database connection using environment variables.
191
+ - Provided RESTFul API design for interaction with MySQL.
192
+ - Fixed the code markdown in readme.rst file
193
+ - Added warning messages
@@ -0,0 +1,164 @@
1
+ import os
2
+ from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
3
+ from flask_mysqldb import MySQL
4
+
5
+
6
+ class MysqlApplication:
7
+ def __init__(self):
8
+ # Initialize Flask app
9
+ self.__app = Flask(__name__, template_folder=os.path.join(os.path.dirname(__file__), "templates"))
10
+ self.__database_name = ""
11
+
12
+ # Securely load database configuration
13
+ self.__app.config['MYSQL_HOST'] = os.getenv('MYSQL_HOST', 'localhost')
14
+ self.__app.config['MYSQL_USER'] = os.getenv('MYSQL_USER', 'root')
15
+ self.__app.config['MYSQL_PASSWORD'] = os.getenv('MYSQL_PASSWORD', '')
16
+ self.__app.config['MYSQL_DB'] = os.getenv('MYSQL_DB', '')
17
+ self.__app.secret_key = os.getenv('SECRET_KEY', 'your_secret_key_here')
18
+ if not os.getenv('SECRET_KEY'):
19
+ print("Warning: Please ensure that you are using a local machine before running the application!")
20
+ print("Warning: Please ensure that MySQL is installed on your local system before running the application!")
21
+ print("Warning: Using a hardcoded secret key. Set SECRET_KEY as an environment variable for production!")
22
+
23
+ # Initialize MySQL
24
+ self.__mysql = MySQL(self.__app)
25
+
26
+ # Define routes
27
+ self.__add_config_routes()
28
+ self.__add_home_routes()
29
+ self.__add_config_mysql()
30
+ self.__add_execute_query()
31
+
32
+ def __add_config_routes(self):
33
+ @self.__app.route('/')
34
+ def config_mysql_page():
35
+ return render_template('config_mysql.html')
36
+
37
+ def __add_home_routes(self):
38
+ @self.__app.route('/home')
39
+ def home():
40
+ return render_template('home.html')
41
+
42
+ def __add_config_mysql(self):
43
+ @self.__app.route('/config_mysql', methods=['POST'])
44
+ def config_mysql():
45
+ host = request.form['host']
46
+ username = request.form['username']
47
+ password = request.form['password']
48
+ database = request.form['database']
49
+
50
+ # Update app configuration dynamically
51
+ self.__app.config['MYSQL_HOST'] = host
52
+ self.__app.config['MYSQL_USER'] = username
53
+ self.__app.config['MYSQL_PASSWORD'] = password
54
+ self.__app.config['MYSQL_DB'] = database
55
+ self.__database_name = database
56
+
57
+ try:
58
+ # Test the connection
59
+ cursor = self.__mysql.connection.cursor()
60
+ cursor.execute('SELECT 1')
61
+ cursor.close()
62
+ flash('Connection established successfully!', 'success')
63
+ return redirect(url_for('home'))
64
+ except Exception as e:
65
+ flash(f'Error connecting to MySQL: {e}', 'danger')
66
+ return redirect(url_for('config_mysql_page'))
67
+
68
+ def __add_execute_query(self):
69
+ @self.__app.route('/execute_query', methods=['POST'])
70
+ def execute_query():
71
+ try:
72
+ data = request.get_json()
73
+ operation = data.get('operation')
74
+ query = data.get('query')
75
+ result = {}
76
+
77
+ cursor = self.__mysql.connection.cursor()
78
+
79
+ if query:
80
+ query_type = query.strip().split(' ', 1)[0].lower()
81
+
82
+ if query_type in ['select', 'show', 'call']:
83
+ cursor.execute(query)
84
+ rows = cursor.fetchall()
85
+ column_names = [desc[0] for desc in cursor.description or []]
86
+ result["data"] = {f"row_{index + 1}": dict(zip(column_names, row)) for index, row in enumerate(rows)}
87
+
88
+ elif query_type == 'use':
89
+ try:
90
+ cursor.execute(query)
91
+ db_to_use = query.strip().split(" ")[1].removesuffix(';')
92
+ if db_to_use == self.__database_name:
93
+ result["message"] = "You are already using this database."
94
+ else:
95
+ result["message"] = "Cannot switch databases dynamically. Please reconfigure."
96
+ except Exception as e:
97
+ return jsonify({'error': f'{e}'})
98
+ else:
99
+ cursor.execute(query)
100
+ self.__mysql.connection.commit()
101
+ result["message"] = f"{query_type.capitalize()} query executed successfully."
102
+
103
+ elif operation:
104
+ if operation == "insert":
105
+ table_name = data.get('table_name')
106
+ columns = data.get('columns')
107
+ values = data.get('values')
108
+ if not table_name or not columns or not values:
109
+ return jsonify({"error": "Table name, columns, and values are required for insert"}), 400
110
+ query = f"INSERT INTO {table_name} ({columns}) VALUES ({values})"
111
+ cursor.execute(query)
112
+ self.__mysql.connection.commit()
113
+ result["message"] = f"Data inserted successfully into table '{table_name}'"
114
+
115
+ elif operation == "delete":
116
+ table_name = data.get('table_name')
117
+ condition = data.get('condition')
118
+ if not table_name or not condition:
119
+ return jsonify({"error": "Table name and condition are required for delete"}), 400
120
+ query = f"DELETE FROM {table_name} WHERE {condition}"
121
+ cursor.execute(query)
122
+ self.__mysql.connection.commit()
123
+ result["message"] = f"Data deleted successfully from table '{table_name}'"
124
+
125
+ elif operation == "update":
126
+ table_name = data.get('table_name')
127
+ field = data.get('field')
128
+ condition = data.get('condition')
129
+ if not table_name or not field or not condition:
130
+ return jsonify({"error": "Table name, field, and condition are required for update"}), 400
131
+ query = f"UPDATE {table_name} SET {field} WHERE {condition}"
132
+ cursor.execute(query)
133
+ self.__mysql.connection.commit()
134
+ result["message"] = f"Data updated successfully in table '{table_name}'"
135
+
136
+ elif operation == "fetch_data":
137
+ table_name = data.get('table_name')
138
+ if not table_name:
139
+ return jsonify({"error": "Table name is required for fetch"}), 400
140
+ query = f'SELECT * FROM {table_name}'
141
+ cursor.execute(query)
142
+ rows = cursor.fetchall()
143
+ column_names = [desc[0] for desc in cursor.description or []]
144
+ result["data"] = {f"row_{index + 1}": dict(zip(column_names, row)) for index, row in enumerate(rows)}
145
+
146
+ elif operation == "show_tables":
147
+ cursor.execute("SHOW TABLES;")
148
+ tables = cursor.fetchall()
149
+ result["tables"] = {f"table_{index + 1}": table[0] for index, table in enumerate(tables)}
150
+ else:
151
+ return jsonify({"error": "Invalid operation"}), 400
152
+
153
+ else:
154
+ return jsonify({"error": "Invalid request"}), 400
155
+
156
+ cursor.close()
157
+
158
+ return jsonify(result)
159
+
160
+ except Exception as e:
161
+ return jsonify({'error': str(e)}), 500
162
+
163
+ def execute(self):
164
+ self.__app.run(debug=True, port=5001, host="0.0.0.0")
@@ -0,0 +1,2 @@
1
+ from .MysqlApplication import MysqlApplication
2
+ __all__ = ["MysqlApplication"]
@@ -0,0 +1,68 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>MySQL Configuration</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ </head>
9
+ <body>
10
+ <div class="container mt-5">
11
+ <div class="card shadow-lg rounded">
12
+ <div class="card-header text-center">
13
+ <h2>MySQL Configuration</h2>
14
+ </div>
15
+ <div class="card-body">
16
+ <form action="/config_mysql" method="POST">
17
+ <div class="mb-3">
18
+ <label for="host" class="form-label">Host Name</label>
19
+ <input type="text" class="form-control" id="host" name="host" placeholder="Enter Host Name" required>
20
+ </div>
21
+ <div class="mb-3">
22
+ <label for="username" class="form-label">User Name</label>
23
+ <input type="text" class="form-control" id="username" name="username" placeholder="Enter User Name" required>
24
+ </div>
25
+ <div class="mb-3 position-relative">
26
+ <label for="password" class="form-label">Password</label>
27
+ <div class="input-group">
28
+ <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password">
29
+ <button type="button" class="btn btn-outline-secondary" id="togglePassword">
30
+ <i class="bi bi-eye" id="eyeIcon"></i>
31
+ </button>
32
+ </div>
33
+ </div>
34
+ <div class="mb-3">
35
+ <label for="database" class="form-label">Database Name</label>
36
+ <input type="text" class="form-control" id="database" name="database" placeholder="Enter Database Name" required>
37
+ </div>
38
+ <button type="submit" class="btn btn-primary">Configure</button>
39
+ </form>
40
+ {% with messages = get_flashed_messages() %}
41
+ {% if messages %}
42
+ <div class="alert alert-info mt-3" role="alert">
43
+ {{ messages[0] }}
44
+ </div>
45
+ {% endif %}
46
+ {% endwith %}
47
+ </div>
48
+ </div>
49
+ </div>
50
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
51
+ <script>
52
+ const togglePassword = document.querySelector('#togglePassword');
53
+ const passwordField = document.querySelector('#password');
54
+ const eyeIcon = document.querySelector('#eyeIcon');
55
+
56
+ togglePassword.addEventListener('click', () => {
57
+ // Toggle the type attribute
58
+ const type = passwordField.getAttribute('type') === 'password' ? 'text' : 'password';
59
+ passwordField.setAttribute('type', type);
60
+
61
+ // Toggle the eye icon class
62
+ eyeIcon.classList.toggle('bi-eye');
63
+ eyeIcon.classList.toggle('bi-eye-slash');
64
+ });
65
+ </script>
66
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.10.5/font/bootstrap-icons.min.css" rel="stylesheet">
67
+ </body>
68
+ </html>
@@ -0,0 +1,298 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CRUD Operations</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #f3f4f6;
13
+ color: #333;
14
+ }
15
+
16
+ header {
17
+ background-color: #4CAF50;
18
+ color: white;
19
+ padding: 20px;
20
+ text-align: center;
21
+ font-size: 1.5em;
22
+ }
23
+
24
+ main {
25
+ max-width: 800px;
26
+ margin: 20px auto;
27
+ background: white;
28
+ padding: 20px;
29
+ border-radius: 10px;
30
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
31
+ }
32
+
33
+ h1 {
34
+ text-align: center;
35
+ color: #333;
36
+ }
37
+
38
+ form {
39
+ display: flex;
40
+ flex-direction: column;
41
+ }
42
+
43
+ label {
44
+ margin: 10px 0 5px;
45
+ font-weight: bold;
46
+ }
47
+
48
+ input, select, textarea, button {
49
+ width: 100%;
50
+ padding: 10px;
51
+ margin-bottom: 15px;
52
+ border: 1px solid #ccc;
53
+ border-radius: 5px;
54
+ font-size: 1em;
55
+ }
56
+
57
+ input:focus, select:focus, textarea:focus, button:focus {
58
+ outline: none;
59
+ border-color: #4CAF50;
60
+ box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
61
+ }
62
+
63
+ button {
64
+ background-color: #4CAF50;
65
+ color: white;
66
+ border: none;
67
+ cursor: pointer;
68
+ font-size: 1em;
69
+ font-weight: bold;
70
+ transition: background-color 0.3s ease;
71
+ }
72
+
73
+ button:hover {
74
+ background-color: #45a049;
75
+ }
76
+
77
+ .hidden {
78
+ display: none;
79
+ }
80
+
81
+ .response-container {
82
+ background-color: #f9f9f9;
83
+ border: 1px solid #ddd;
84
+ padding: 20px;
85
+ border-radius: 5px;
86
+ margin-top: 20px;
87
+ max-height: 300px;
88
+ overflow-y: auto;
89
+ font-family: monospace;
90
+ white-space: pre-wrap;
91
+ word-wrap: break-word;
92
+ }
93
+
94
+ .form-section {
95
+ margin: 20px 0;
96
+ padding: 20px;
97
+ border: 1px solid #ddd;
98
+ border-radius: 5px;
99
+ background: #f9f9f9;
100
+ }
101
+
102
+ footer {
103
+ text-align: center;
104
+ margin-top: 40px;
105
+ padding: 20px;
106
+ background: #4CAF50;
107
+ color: white;
108
+ font-size: 0.9em;
109
+ }
110
+
111
+ footer a {
112
+ color: #ffeb3b;
113
+ text-decoration: none;
114
+ }
115
+
116
+ footer a:hover {
117
+ text-decoration: underline;
118
+ }
119
+ </style>
120
+ </head>
121
+ <body>
122
+ <header>
123
+ CRUD Operations Interface
124
+ </header>
125
+
126
+ <main>
127
+ <h1>Manage Your Data</h1>
128
+
129
+ <form id="crudForm">
130
+ <div class="form-section">
131
+ <label for="operationType">Select Operation:</label>
132
+ <select id="operationType">
133
+ <option value="">-- Select --</option>
134
+ <option value="fetch_data">Fetch</option>
135
+ <option value="insert">Insert</option>
136
+ <option value="delete">Delete</option>
137
+ <option value="update">Update</option>
138
+ <option value="show_tables">Show Tables</option>
139
+ <option value="custom_query">Custom Query</option>
140
+ </select>
141
+ </div>
142
+
143
+ <!-- Fetch Data Section -->
144
+ <div id="fetchSection" class="form-section hidden">
145
+ <label for="fetchTable">Table Name:</label>
146
+ <input type="text" id="fetchTable" placeholder="Enter table name">
147
+ </div>
148
+
149
+ <!-- Insert Section -->
150
+ <div id="insertSection" class="form-section hidden">
151
+ <label for="insertTable">Table Name:</label>
152
+ <input type="text" id="insertTable" placeholder="Enter table name">
153
+
154
+ <label for="insertColumns">Columns:</label>
155
+ <input type="text" id="insertColumns" placeholder="e.g., id, name, email">
156
+
157
+ <label for="insertValues">Values:</label>
158
+ <input type="text" id="insertValues" placeholder="e.g., 1, 'John Doe', 'john@example.com'">
159
+ </div>
160
+
161
+ <!-- Delete Section -->
162
+ <div id="deleteSection" class="form-section hidden">
163
+ <label for="deleteTable">Table Name:</label>
164
+ <input type="text" id="deleteTable" placeholder="Enter table name">
165
+
166
+ <label for="deleteCondition">Condition:</label>
167
+ <input type="text" id="deleteCondition" placeholder="e.g., id=1">
168
+ </div>
169
+
170
+ <!-- Update Section -->
171
+ <div id="updateSection" class="form-section hidden">
172
+ <label for="updateTable">Table Name:</label>
173
+ <input type="text" id="updateTable" placeholder="Enter table name">
174
+
175
+ <label for="updateField">Field to Update:</label>
176
+ <input type="text" id="updateField" placeholder="e.g., name='New Name'">
177
+
178
+ <label for="updateCondition">Condition:</label>
179
+ <input type="text" id="updateCondition" placeholder="e.g., id=1">
180
+ </div>
181
+
182
+ <!-- Show Tables Section -->
183
+ <div id="showTablesSection" class="form-section hidden">
184
+ <p>No additional input required. Click "Execute" to show tables.</p>
185
+ </div>
186
+
187
+ <!-- Custom Query Section -->
188
+ <div id="customQuerySection" class="form-section hidden">
189
+ <label for="customQuery">SQL Query:</label>
190
+ <textarea id="customQuery" rows="5" placeholder="Enter your custom SQL query here..."></textarea>
191
+ </div>
192
+
193
+ <button type="submit">Execute</button>
194
+ </form>
195
+
196
+ <div id="responseContainer" class="response-container hidden"></div>
197
+ </main>
198
+
199
+ <footer>
200
+ &copy; 2025 CRUD Operations. Designed by abuawaish️. To visit my GitHub account <a href="https://github.com/abuawaish">Click here</a>
201
+ </footer>
202
+
203
+ <script>
204
+ const operationType = document.getElementById("operationType");
205
+ const form = document.getElementById("crudForm");
206
+ const responseContainer = document.getElementById("responseContainer");
207
+
208
+ const sections = {
209
+ fetch_data: document.getElementById("fetchSection"),
210
+ insert: document.getElementById("insertSection"),
211
+ delete: document.getElementById("deleteSection"),
212
+ update: document.getElementById("updateSection"),
213
+ show_tables: document.getElementById("showTablesSection"),
214
+ custom_query: document.getElementById("customQuerySection"),
215
+ };
216
+
217
+ operationType.addEventListener("change", () => {
218
+ Object.values(sections).forEach(section => section.classList.add("hidden"));
219
+ if (operationType.value && sections[operationType.value]) {
220
+ sections[operationType.value].classList.remove("hidden");
221
+ }
222
+ });
223
+
224
+ form.addEventListener("submit", async (event) => {
225
+ event.preventDefault();
226
+ const operation = operationType.value;
227
+
228
+ let payload = {};
229
+ if (operation === "fetch_data") {
230
+ const tableName = document.getElementById("fetchTable").value.trim();
231
+
232
+ if (!tableName) {
233
+ alert("Table name is required for fetching data.");
234
+ return;
235
+ }
236
+
237
+ payload = { operation, table_name: tableName };
238
+ } else if (operation === "insert") {
239
+ const tableName = document.getElementById("insertTable").value.trim();
240
+ const columns = document.getElementById("insertColumns").value.trim();
241
+ const values = document.getElementById("insertValues").value.trim();
242
+
243
+ if (!tableName || !columns || !values) {
244
+ alert("All fields are required for insert.");
245
+ return;
246
+ }
247
+
248
+ payload = { operation, table_name: tableName, columns, values };
249
+ } else if (operation === "delete") {
250
+ const tableName = document.getElementById("deleteTable").value.trim();
251
+ const condition = document.getElementById("deleteCondition").value.trim();
252
+
253
+ if (!tableName || !condition) {
254
+ alert("Table name and condition are required for delete.");
255
+ return;
256
+ }
257
+
258
+ payload = { operation, table_name: tableName, condition };
259
+ } else if (operation === "update") {
260
+ const tableName = document.getElementById("updateTable").value.trim();
261
+ const field = document.getElementById("updateField").value.trim();
262
+ const condition = document.getElementById("updateCondition").value.trim();
263
+
264
+ if (!tableName || !field || !condition) {
265
+ alert("All fields are required for update.");
266
+ return;
267
+ }
268
+
269
+ payload = { operation, table_name: tableName, field, condition };
270
+ } else if (operation === "show_tables") {
271
+ payload = { operation };
272
+ } else if (operation === "custom_query") {
273
+ const query = document.getElementById("customQuery").value.trim();
274
+ if (!query) {
275
+ alert("Custom query is required.");
276
+ return;
277
+ }
278
+ payload = { query };
279
+ }
280
+
281
+ try {
282
+ const response = await fetch('/execute_query', {
283
+ method: 'POST',
284
+ headers: { 'Content-Type': 'application/json' },
285
+ body: JSON.stringify(payload),
286
+ });
287
+
288
+ const result = await response.json();
289
+ responseContainer.textContent = JSON.stringify(result, null, 2);
290
+ responseContainer.classList.remove("hidden");
291
+ } catch (error) {
292
+ responseContainer.textContent = `Error: ${error.message}`;
293
+ responseContainer.classList.remove("hidden");
294
+ }
295
+ });
296
+ </script>
297
+ </body>
298
+ </html>
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.2
2
+ Name: PyAwaish
3
+ Version: 1.0
4
+ Summary: A Python package for building dynamic MySQL-powered web applications with template support
5
+ Home-page: https://github.com/abuawaish/Crud_app
6
+ Author: Abu Awaish
7
+ Author-email: abuawaish7@gmail.com
8
+ License: MIT
9
+ Keywords: web application flask mysql dynamic templates
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/x-rst
15
+ License-File: LICENSE.txt
16
+ Requires-Dist: Flask
17
+ Requires-Dist: Flask-MySQLdb
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: keywords
25
+ Dynamic: license
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ PyAwaish
31
+ ===========
32
+
33
+ **PyAwaish** is a Flask-based Python framework that simplifies the development of MySQL-powered web applications. It provides a streamlined interface for connecting to a MySQL database, rendering templates, and executing queries dynamically via RESTful APIs.
34
+
35
+ Features
36
+ --------
37
+ - **Dynamic MySQL Configuration**: Configure MySQL database settings at runtime via a web interface.
38
+ - **Template Rendering**: Built-in support for rendering templates stored in the `templates` folder.
39
+ - **Query Execution API**: Execute MySQL queries dynamically through POST requests.
40
+ - **CRUD Operations**: Perform create, read, update, and delete operations programmatically.
41
+ - **RESTful Design**: Leverage Flask to expose endpoints for database interactions.
42
+ - **Environment Configuration**: Load sensitive credentials securely using environment variables.
43
+
44
+ Badges
45
+ ------
46
+
47
+ .. image:: https://badge.fury.io/py/PyAwaish.svg
48
+ :target: https://pypi.org/project/PyAwaish/
49
+
50
+ .. image:: https://img.shields.io/badge/License-MIT-yellow.svg
51
+ :target: https://opensource.org/licenses/MIT
52
+
53
+
54
+ Endpoints
55
+ ---------
56
+ 1. **`/`**: Displays the MySQL configuration page.
57
+ 2. **`/home`**: Displays the home page.
58
+ 3. **`/config_mysql`**: Accepts a POST request to configure MySQL connection details dynamically.
59
+ 4. **`/execute_query`**: Accepts a POST request to execute MySQL queries or perform operations (e.g., insert, delete, update).
60
+
61
+ Installation
62
+ ------------
63
+ 1. Clone the repository:
64
+
65
+ .. code-block:: bash
66
+
67
+ git clone https://github.com/abuawaish/CRUD_App.git
68
+ cd CRUD_App
69
+
70
+ 2. Install the required dependencies:
71
+
72
+ .. code-block:: bash
73
+
74
+ pip install -r requirements.txt
75
+
76
+ 3. Install the package:
77
+
78
+ .. code-block:: bash
79
+
80
+ pip install PyAwaish
81
+
82
+ 4. Set environment variables for database configuration:
83
+
84
+ .. code-block:: bash
85
+
86
+ export MYSQL_HOST=localhost
87
+ export MYSQL_USER=root
88
+ export MYSQL_PASSWORD=your password
89
+ export MYSQL_DB=mydatabase
90
+ export SECRET_KEY=your_secret_key
91
+
92
+
93
+ Usage
94
+ -----
95
+
96
+ **Running the Application**
97
+
98
+ To start the MysqlWebApp server, instantiate the `MysqlApplication` class and call its `execute` method. For example:
99
+
100
+ .. code-block:: python
101
+
102
+ from PyAwaish.MysqlApplication import MysqlApplication
103
+
104
+ if __name__ == "__main__":
105
+ app = MysqlApplication()
106
+ app.execute()
107
+
108
+ **This will:**
109
+
110
+ - Start a Flask server on `http://0.0.0.0:5001`.
111
+ - Serve endpoints for configuring and interacting with the MySQL database.
112
+
113
+
114
+ **Configuring MySQL**
115
+
116
+ 1. Navigate to the root endpoint (`http://localhost:5001/`) to access the configuration page.
117
+ 2. Enter the database details (host, username, password, database name) and click "Save".
118
+ 3. Upon successful configuration, you will be redirected to the home page.
119
+
120
+ **Executing Queries**
121
+
122
+ Use the `/execute_query` endpoint to run SQL queries or perform operations. Example request:
123
+
124
+ - **POST Request Example**:
125
+
126
+ .. code-block:: json
127
+
128
+ {
129
+ "operation": "insert",
130
+ "table_name": "users",
131
+ "columns": "name, email",
132
+ "values": "'John Doe', 'john@example.com'"
133
+ }
134
+
135
+ - **Supported Operations**:
136
+ - `insert`: Insert data into a table.
137
+ - `delete`: Delete data from a table with a condition.
138
+ - `update`: Update data in a table with a condition.
139
+ - `fetch_data`: Fetch all data from a table.
140
+ - `show_tables`: List all tables in the database.
141
+
142
+ Dependencies
143
+ ------------
144
+ The application requires the following dependencies (listed in `requirements.txt`):
145
+
146
+ - Flask: Web framework.
147
+ - Flask-MySQLdb: MySQL connector for Flask.
148
+
149
+ To install them, run:
150
+
151
+ .. code-block:: bash
152
+
153
+ pip install -r requirements.txt
154
+
155
+ Environment Variables
156
+ ---------------------
157
+ - **MYSQL_HOST**: MySQL server hostname (default: `localhost`).
158
+ - **MYSQL_USER**: MySQL username (default: `root`).
159
+ - **MYSQL_PASSWORD**: MySQL password.
160
+ - **MYSQL_DB**: Default MySQL database name.
161
+ - **SECRET_KEY**: Flask secret key for session security.
162
+
163
+ Changelog
164
+ ---------
165
+ Refer to `CHANGELOG.txt` for the complete version history of the project.
166
+
167
+ License
168
+ -------
169
+ This project is licensed under the MIT License. See `LICENSE.txt` for full details.
170
+
171
+ Contact
172
+ -------
173
+ For questions or feedback, contact:
174
+
175
+ - Email: abuawaish7@gmail.com
176
+ - GitHub: https://github.com/abuawaish/CRUD_App
177
+
178
+
179
+ CHANGELOG
180
+ =========
181
+
182
+ Version 1.0 (2025-01-27)
183
+ ---------------------------
184
+
185
+ - Initial release of PyAwaish.
186
+ - Added dynamic MySQL configuration through a web interface.
187
+ - Implemented template rendering for `config_mysql.html` and `home.html`.
188
+ - Developed `/execute_query` endpoint for executing MySQL queries.
189
+ - Supported CRUD operations: insert, delete, update, fetch_data.
190
+ - Enabled secure database connection using environment variables.
191
+ - Provided RESTFul API design for interaction with MySQL.
192
+ - Fixed the code markdown in readme.rst file
193
+ - Added warning messages
@@ -0,0 +1,16 @@
1
+ CHANGELOG.txt
2
+ LICENSE.txt
3
+ MANIFEST.in
4
+ README.rst
5
+ pyproject.toml
6
+ requirements.txt
7
+ setup.py
8
+ PyAwaish/MysqlApplication.py
9
+ PyAwaish/__init__.py
10
+ PyAwaish.egg-info/PKG-INFO
11
+ PyAwaish.egg-info/SOURCES.txt
12
+ PyAwaish.egg-info/dependency_links.txt
13
+ PyAwaish.egg-info/requires.txt
14
+ PyAwaish.egg-info/top_level.txt
15
+ PyAwaish/templates/config_mysql.html
16
+ PyAwaish/templates/home.html
@@ -0,0 +1,2 @@
1
+ Flask
2
+ Flask-MySQLdb
@@ -0,0 +1 @@
1
+ PyAwaish
@@ -0,0 +1,147 @@
1
+ PyAwaish
2
+ ===========
3
+
4
+ **PyAwaish** is a Flask-based Python framework that simplifies the development of MySQL-powered web applications. It provides a streamlined interface for connecting to a MySQL database, rendering templates, and executing queries dynamically via RESTful APIs.
5
+
6
+ Features
7
+ --------
8
+ - **Dynamic MySQL Configuration**: Configure MySQL database settings at runtime via a web interface.
9
+ - **Template Rendering**: Built-in support for rendering templates stored in the `templates` folder.
10
+ - **Query Execution API**: Execute MySQL queries dynamically through POST requests.
11
+ - **CRUD Operations**: Perform create, read, update, and delete operations programmatically.
12
+ - **RESTful Design**: Leverage Flask to expose endpoints for database interactions.
13
+ - **Environment Configuration**: Load sensitive credentials securely using environment variables.
14
+
15
+ Badges
16
+ ------
17
+
18
+ .. image:: https://badge.fury.io/py/PyAwaish.svg
19
+ :target: https://pypi.org/project/PyAwaish/
20
+
21
+ .. image:: https://img.shields.io/badge/License-MIT-yellow.svg
22
+ :target: https://opensource.org/licenses/MIT
23
+
24
+
25
+ Endpoints
26
+ ---------
27
+ 1. **`/`**: Displays the MySQL configuration page.
28
+ 2. **`/home`**: Displays the home page.
29
+ 3. **`/config_mysql`**: Accepts a POST request to configure MySQL connection details dynamically.
30
+ 4. **`/execute_query`**: Accepts a POST request to execute MySQL queries or perform operations (e.g., insert, delete, update).
31
+
32
+ Installation
33
+ ------------
34
+ 1. Clone the repository:
35
+
36
+ .. code-block:: bash
37
+
38
+ git clone https://github.com/abuawaish/CRUD_App.git
39
+ cd CRUD_App
40
+
41
+ 2. Install the required dependencies:
42
+
43
+ .. code-block:: bash
44
+
45
+ pip install -r requirements.txt
46
+
47
+ 3. Install the package:
48
+
49
+ .. code-block:: bash
50
+
51
+ pip install PyAwaish
52
+
53
+ 4. Set environment variables for database configuration:
54
+
55
+ .. code-block:: bash
56
+
57
+ export MYSQL_HOST=localhost
58
+ export MYSQL_USER=root
59
+ export MYSQL_PASSWORD=your password
60
+ export MYSQL_DB=mydatabase
61
+ export SECRET_KEY=your_secret_key
62
+
63
+
64
+ Usage
65
+ -----
66
+
67
+ **Running the Application**
68
+
69
+ To start the MysqlWebApp server, instantiate the `MysqlApplication` class and call its `execute` method. For example:
70
+
71
+ .. code-block:: python
72
+
73
+ from PyAwaish.MysqlApplication import MysqlApplication
74
+
75
+ if __name__ == "__main__":
76
+ app = MysqlApplication()
77
+ app.execute()
78
+
79
+ **This will:**
80
+
81
+ - Start a Flask server on `http://0.0.0.0:5001`.
82
+ - Serve endpoints for configuring and interacting with the MySQL database.
83
+
84
+
85
+ **Configuring MySQL**
86
+
87
+ 1. Navigate to the root endpoint (`http://localhost:5001/`) to access the configuration page.
88
+ 2. Enter the database details (host, username, password, database name) and click "Save".
89
+ 3. Upon successful configuration, you will be redirected to the home page.
90
+
91
+ **Executing Queries**
92
+
93
+ Use the `/execute_query` endpoint to run SQL queries or perform operations. Example request:
94
+
95
+ - **POST Request Example**:
96
+
97
+ .. code-block:: json
98
+
99
+ {
100
+ "operation": "insert",
101
+ "table_name": "users",
102
+ "columns": "name, email",
103
+ "values": "'John Doe', 'john@example.com'"
104
+ }
105
+
106
+ - **Supported Operations**:
107
+ - `insert`: Insert data into a table.
108
+ - `delete`: Delete data from a table with a condition.
109
+ - `update`: Update data in a table with a condition.
110
+ - `fetch_data`: Fetch all data from a table.
111
+ - `show_tables`: List all tables in the database.
112
+
113
+ Dependencies
114
+ ------------
115
+ The application requires the following dependencies (listed in `requirements.txt`):
116
+
117
+ - Flask: Web framework.
118
+ - Flask-MySQLdb: MySQL connector for Flask.
119
+
120
+ To install them, run:
121
+
122
+ .. code-block:: bash
123
+
124
+ pip install -r requirements.txt
125
+
126
+ Environment Variables
127
+ ---------------------
128
+ - **MYSQL_HOST**: MySQL server hostname (default: `localhost`).
129
+ - **MYSQL_USER**: MySQL username (default: `root`).
130
+ - **MYSQL_PASSWORD**: MySQL password.
131
+ - **MYSQL_DB**: Default MySQL database name.
132
+ - **SECRET_KEY**: Flask secret key for session security.
133
+
134
+ Changelog
135
+ ---------
136
+ Refer to `CHANGELOG.txt` for the complete version history of the project.
137
+
138
+ License
139
+ -------
140
+ This project is licensed under the MIT License. See `LICENSE.txt` for full details.
141
+
142
+ Contact
143
+ -------
144
+ For questions or feedback, contact:
145
+
146
+ - Email: abuawaish7@gmail.com
147
+ - GitHub: https://github.com/abuawaish/CRUD_App
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,2 @@
1
+ Flask
2
+ Flask-MySQLdb
pyawaish-1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
pyawaish-1.0/setup.py ADDED
@@ -0,0 +1,36 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open('README.rst', encoding='utf-8') as readme_file:
4
+ long_description = readme_file.read()
5
+
6
+ with open('CHANGELOG.txt', encoding='utf-8') as changelog_file:
7
+ long_description += '\n\n' + changelog_file.read()
8
+
9
+ setup(
10
+ name="PyAwaish",
11
+ version="1.0",
12
+ author="Abu Awaish",
13
+ author_email="abuawaish7@gmail.com",
14
+ description="A Python package for building dynamic MySQL-powered web applications with template support",
15
+ long_description=long_description,
16
+ long_description_content_type="text/x-rst", # Use RST for README and changelog
17
+ url="https://github.com/abuawaish/Crud_app",
18
+ packages=find_packages(),
19
+ include_package_data=True, # Include non-code files specified in MANIFEST.in
20
+ package_data={
21
+ "PyAwaish": ["templates/**/*"], # Include all files in templates and subdirectories
22
+ },
23
+ license="MIT",
24
+ license_files=['LICENSE.txt'], # Explicitly include the license file
25
+ install_requires=[
26
+ 'Flask',
27
+ 'Flask-MySQLdb',
28
+ ],
29
+ keywords="web application flask mysql dynamic templates",
30
+ classifiers=[
31
+ "Programming Language :: Python :: 3",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: OS Independent",
34
+ ],
35
+ python_requires=">=3.6", # Specify the minimum Python version
36
+ )