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.
- pyawaish-1.0/CHANGELOG.txt +15 -0
- pyawaish-1.0/LICENSE.txt +6 -0
- pyawaish-1.0/MANIFEST.in +22 -0
- pyawaish-1.0/PKG-INFO +193 -0
- pyawaish-1.0/PyAwaish/MysqlApplication.py +164 -0
- pyawaish-1.0/PyAwaish/__init__.py +2 -0
- pyawaish-1.0/PyAwaish/templates/config_mysql.html +68 -0
- pyawaish-1.0/PyAwaish/templates/home.html +298 -0
- pyawaish-1.0/PyAwaish.egg-info/PKG-INFO +193 -0
- pyawaish-1.0/PyAwaish.egg-info/SOURCES.txt +16 -0
- pyawaish-1.0/PyAwaish.egg-info/dependency_links.txt +1 -0
- pyawaish-1.0/PyAwaish.egg-info/requires.txt +2 -0
- pyawaish-1.0/PyAwaish.egg-info/top_level.txt +1 -0
- pyawaish-1.0/README.rst +147 -0
- pyawaish-1.0/pyproject.toml +3 -0
- pyawaish-1.0/requirements.txt +2 -0
- pyawaish-1.0/setup.cfg +4 -0
- pyawaish-1.0/setup.py +36 -0
|
@@ -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
|
pyawaish-1.0/LICENSE.txt
ADDED
|
@@ -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
|
+
|
pyawaish-1.0/MANIFEST.in
ADDED
|
@@ -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,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
|
+
© 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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyAwaish
|
pyawaish-1.0/README.rst
ADDED
|
@@ -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
|
pyawaish-1.0/setup.cfg
ADDED
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
|
+
)
|