MySQL Mimic

3.0.2 · active · verified Fri Apr 17

mysql-mimic is a pure Python implementation of the MySQL server protocol. It enables developers to create fake MySQL servers to intercept connections, log queries, serve custom data, or test database clients without requiring a real MySQL instance. The current version, 3.0.2, primarily features an asynchronous API and aims for robust protocol emulation. Releases generally follow major breaking changes or significant feature additions, with major versions appearing every 2-3 years.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart sets up a basic MySQL Mimic server that listens on port 3307 (or `MIMIC_PORT` env var). It uses a custom authenticator to allow any username with a pre-defined password (`MIMIC_TEST_PASSWORD` env var or 'super-secret-password'). The `on_query` method demonstrates how to respond to client queries with a list of tuples, mimicking a database result set. Remember to set the environment variable for the password before running.

import asyncio
import logging
import os
from mysql_mimic import MySQLServer
from mysql_mimic.auth import Authenticator

logging.basicConfig(level=logging.INFO)

# Define a test password via an environment variable for security best practices
# In a real scenario, this would be a secure, complex password.
MIMIC_PASSWORD = os.environ.get('MIMIC_TEST_PASSWORD', 'super-secret-password')
MIMIC_HOST = os.environ.get('MIMIC_HOST', '127.0.0.1')
MIMIC_PORT = int(os.environ.get('MIMIC_PORT', 3307)) # Use a non-standard port

class MyAuthenticator(Authenticator):
    async def authenticate(self, username, password, database):
        logging.info(f"Auth attempt: user='{username}', db='{database}'")
        if password == MIMIC_PASSWORD:
            logging.info(f"Authentication successful for '{username}'")
            return True
        logging.warning(f"Authentication failed for '{username}' with provided password.")
        return False

class MyServer(MySQLServer):
    async def on_query(self, query: str, database: str):
        logging.info(f"Query received on '{database}': '{query}'")
        # Return a list of tuples, mimicking a result set
        if query.lower().startswith("select version()"):
            return [("3.0.2",)] # Mimic current version of mysql-mimic
        elif query.lower().startswith("select 'hello world'"):
            return [("hello world from mysql-mimic!",)]
        else:
            return [(f"You queried: '{query}'",)]

# This is the simplest way to run for a quickstart in an async context
# Make sure to set MIMIC_TEST_PASSWORD in your environment before running, e.g.:
# export MIMIC_TEST_PASSWORD="super-secret-password"
# python your_script.py
server = MyServer(authenticator=MyAuthenticator(), host=MIMIC_HOST, port=MIMIC_PORT)
logging.info(f"Starting MySQL Mimic server on {MIMIC_HOST}:{MIMIC_PORT}")
server.serve_forever_async()

# To test from your terminal:
# mysql -h 127.0.0.1 -P 3307 -u anyuser -p'super-secret-password' -e "SELECT 'Hello World';"

view raw JSON →