diff --git a/.env.example b/.env.example
index 4d9233b..dace528 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,14 @@
FLASK_APP=wsgi.py
FLASK_DEBUG=False
SECRET_KEY=yoursecretkey
-SQLALCHEMY_DATABASE_URI=mysql+pymysql://myuser:mypassword@host.example.com:1234/mydatabase
+
+SQLALCHEMY_DATABASE_HOST=db.example.com
+SQLALCHEMY_DATABASE_TABLE=my_table
+SQLALCHEMY_DATABASE_NAME=my_database
+SQLALCHEMY_DATABASE_URI=mysql+pymysql://username:password@db.example.com:1234/my_database
+SQLALCHEMY_DATABASE_PEM="-----BEGIN CERTIFICATE-----\n[NONSENSICAL_KEY_STORED_ON_SINGLE_LINE]\n-----END CERTIFICATE-----\n"
+SQLALCHEMY_DATABASE_URI=mysql+pymysql://myuser:mypassword@db.example.com:1234/my_database
+
COMPRESSOR_DEBUG=True
LESS_BIN=/usr/local/bin/lessc
ASSETS_DEBUG=False
diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
index 631fc59..a9202ad 100644
--- a/.github/workflows/python-app.yml
+++ b/.github/workflows/python-app.yml
@@ -12,9 +12,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
- python-version: "3.10"
+ python-version: "3.12"
- name: Install dependencies
run: |
diff --git a/README.md b/README.md
index 5fc7f4c..bd1fee9 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# PythonMyAdmin
-![Python](https://img.shields.io/badge/Python-^3.10-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a)
-![Flask](https://img.shields.io/badge/Flask-2.2.5-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
-![Dash](https://img.shields.io/badge/Dash-v^2.14.0-blue.svg?longCache=true&logo=python&longCache=true&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
+![Python](https://img.shields.io/badge/Python-^3.12-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a)
+![Flask](https://img.shields.io/badge/Flask-3.0.3-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
+![Dash](https://img.shields.io/badge/Dash-v^2.18.2-blue.svg?longCache=true&logo=python&longCache=true&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
![Flask-SQLAlchemy](https://img.shields.io/badge/Flask--SQLAlchemy-^3.1.1-red.svg?longCache=true&style=flat-square&logo=scala&logoColor=white&colorA=4c566a&colorB=bf616a)
![GitHub Last Commit](https://img.shields.io/github/last-commit/google/skia.svg?style=flat-square&colorA=4c566a&colorB=a3be8c)
[![GitHub Issues](https://img.shields.io/github/issues/toddbirchard/pythonmyadmin.svg?style=flat-square&colorA=4c566a&colorB=ebcb8b)](https://github.com/toddbirchard/pythonmyadmin/issues)
diff --git a/gunicorn.conf.py b/gunicorn.conf.py
index 9aac6d5..13f337c 100644
--- a/gunicorn.conf.py
+++ b/gunicorn.conf.py
@@ -21,7 +21,7 @@
reload = True
workers = 1
threads = 1
- bind = ["127.0.0.1:8000"]
+ bind = ["127.0.0.1:8007"]
elif ENVIRONMENT == "production":
access_log_format = "%(h)s %(l)s %(u)s %(t)s %(r)s %(s)s %(b)s %(f)s %(a)s"
daemon = True
diff --git a/log.py b/log.py
index c70b52b..678c0bb 100644
--- a/log.py
+++ b/log.py
@@ -64,7 +64,7 @@ def log_formatter(record: dict) -> str:
return "{time:MM-DD-YYYY HH:mm:ss} | {level}: {message}\n"
-def create_logger() -> logger:
+def create_logger():
"""
Configure custom logger.
diff --git a/pythonmyadmin/assets.py b/pythonmyadmin/assets.py
index 878eff4..daa1b88 100644
--- a/pythonmyadmin/assets.py
+++ b/pythonmyadmin/assets.py
@@ -7,23 +7,25 @@
def compile_js_assets(app: Flask):
"""Build JS bundle."""
assets = Environment(app)
- Environment.auto_build = True
- Environment.debug = False
- js_bundle = Bundle("js/*.js", filters="jsmin", output="dist/js/main.js")
- assets.register("js_all", js_bundle)
- js_bundle.build()
+ if app.config["ENVIRONMENT"] != "production":
+ assets.auto_build = True
+ assets.debug = False
+ js_bundle = Bundle("js/*.js", filters="jsmin", output="dist/js/main.js")
+ assets.register("js_all", js_bundle)
+ js_bundle.build()
def compile_style_assets(app: Flask):
"""Build CSS style bundle."""
assets = Environment(app)
- Environment.auto_build = True
- Environment.debug = False
- less_bundle = Bundle(
- "less/main.less",
- filters="less,cssmin",
- output="dist/css/style.css",
- extra={"rel": "stylesheet/less"},
- )
- assets.register("less_all", less_bundle)
- less_bundle.build(force=True)
+ if app.config["ENVIRONMENT"] != "production":
+ assets.auto_build = True
+ assets.debug = False
+ less_bundle = Bundle(
+ "less/main.less",
+ filters="less,cssmin",
+ output="dist/css/style.css",
+ extra={"rel": "stylesheet/less"},
+ )
+ assets.register("less_all", less_bundle)
+ less_bundle.build(force=True)
diff --git a/pythonmyadmin/tables/tests/__init__.py b/tests/__init__.py
similarity index 100%
rename from pythonmyadmin/tables/tests/__init__.py
rename to tests/__init__.py
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..23b38ae
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,16 @@
+"""PyTest mocked fixtures."""
+
+import pytest
+
+from clients import Database
+from config import settings
+
+
+@pytest.fixture
+def db() -> Database:
+ """Return a valid database object."""
+ return Database(
+ uri=settings.SQLALCHEMY_DATABASE_URI,
+ table=settings.SQLALCHEMY_DATABASE_TABLE,
+ args=settings.SQLALCHEMY_CONNECT_ARGS,
+ )
diff --git a/tests/test_table_fetch.py b/tests/test_table_fetch.py
new file mode 100644
index 0000000..d564b77
--- /dev/null
+++ b/tests/test_table_fetch.py
@@ -0,0 +1,12 @@
+"""Basic tests for validating app functionality."""
+
+import pytest
+from pandas import DataFrame
+
+from clients.database import Database
+
+
+def test_fetch_sql_data(db: Database):
+ """Test fetching data from a table."""
+ data = db.get_table_data()
+ assert type(data) == DataFrame