about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.pylintrc10
-rw-r--r--README.md2
-rw-r--r--gn_auth/__init__.py11
-rw-r--r--gn_auth/auth/authorisation/data/genotypes.py2
-rw-r--r--gn_auth/auth/authorisation/data/mrna.py2
-rw-r--r--gn_auth/auth/authorisation/data/phenotypes.py2
-rw-r--r--gn_auth/auth/authorisation/groups/data.py2
-rw-r--r--gn_auth/auth/authorisation/resources/views.py2
-rw-r--r--gn_auth/auth/db/__init__.py1
-rw-r--r--gn_auth/auth/db/mariadb.py14
-rw-r--r--gn_auth/auth/db/redis.py22
-rw-r--r--gn_auth/auth/db/sqlite3.py2
-rw-r--r--gn_auth/commands.py2
-rw-r--r--scripts/migrate_existing_data.py2
14 files changed, 63 insertions, 13 deletions
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000..2753c79
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,10 @@
+[SIMILARITIES]
+
+ignore-imports=yes
+
+[MESSAGES CONTROL]
+
+disable=
+	fixme,
+	duplicate-code,
+        no-else-return
\ No newline at end of file
diff --git a/README.md b/README.md
index f076ce1..f4ccdfd 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ used across the entire suite of the GeneNetwork services.
 ### Linting
 
 ```bash
-pylint *py tests gn3 scripts
+pylint *py tests gn_auth scripts
 ```
 
 ### Type-Checking
diff --git a/gn_auth/__init__.py b/gn_auth/__init__.py
index 7d9228d..9b0264c 100644
--- a/gn_auth/__init__.py
+++ b/gn_auth/__init__.py
@@ -1,16 +1,19 @@
+"""Application initialisation module."""
+
 import os
 import sys
 import logging
+from typing import Optional
 
 from flask import Flask
 
-from . import settings
-
 from gn_auth.auth import oauth2
 from gn_auth.misc_views import misc
 
 from gn_auth.auth.authentication.oauth2.server import setup_oauth2_server
 
+from . import settings
+
 class ConfigurationError(Exception):
     """Raised in case of a configuration error."""
 
@@ -48,14 +51,14 @@ def setup_logging_handlers(app: Flask) -> None:
     root_logger.addHandler(stderr_handler)
     root_logger.setLevel(app.config["LOGLEVEL"])
 
-def create_app(config: dict = {}) -> Flask:
+def create_app(config: Optional[dict] = None) -> Flask:
     """Create and return a new flask application."""
     app = Flask(__name__)
 
     # ====== Setup configuration ======
     app.config.from_object(settings) # Default settings
     # Override defaults with startup settings
-    app.config.update(config)
+    app.config.update(config or {})
     # Override app settings with site-local settings
     if "GN_AUTH_CONF" in os.environ:
         app.config.from_envvar("GN_AUTH_CONF")
diff --git a/gn_auth/auth/authorisation/data/genotypes.py b/gn_auth/auth/authorisation/data/genotypes.py
index 61963a6..f5cf11c 100644
--- a/gn_auth/auth/authorisation/data/genotypes.py
+++ b/gn_auth/auth/authorisation/data/genotypes.py
@@ -4,7 +4,7 @@ from typing import Iterable
 
 from MySQLdb.cursors import DictCursor
 
-import gn_auth.auth.db as authdb
+import gn_auth.auth.db.sqlite3 as authdb
 import gn_auth.auth.db.mariadb as gn3db
 from gn_auth.auth.dictify import dictify
 from gn_auth.auth.authorisation.checks import authorised_p
diff --git a/gn_auth/auth/authorisation/data/mrna.py b/gn_auth/auth/authorisation/data/mrna.py
index 79ea7c0..b80ffe5 100644
--- a/gn_auth/auth/authorisation/data/mrna.py
+++ b/gn_auth/auth/authorisation/data/mrna.py
@@ -3,7 +3,7 @@ import uuid
 from typing import Iterable
 from MySQLdb.cursors import DictCursor
 
-import gn_auth.auth.db as authdb
+import gn_auth.auth.db.sqlite3 as authdb
 import gn_auth.auth.db.mariadb as gn3db
 from gn_auth.auth.dictify import dictify
 from gn_auth.auth.authorisation.checks import authorised_p
diff --git a/gn_auth/auth/authorisation/data/phenotypes.py b/gn_auth/auth/authorisation/data/phenotypes.py
index d3cc33a..0220201 100644
--- a/gn_auth/auth/authorisation/data/phenotypes.py
+++ b/gn_auth/auth/authorisation/data/phenotypes.py
@@ -4,7 +4,7 @@ from typing import Any, Iterable
 
 from MySQLdb.cursors import DictCursor
 
-import gn_auth.auth.db as authdb
+import gn_auth.auth.db.sqlite3 as authdb
 import gn_auth.auth.db.mariadb as gn3db
 from gn_auth.auth.dictify import dictify
 from gn_auth.auth.authorisation.checks import authorised_p
diff --git a/gn_auth/auth/authorisation/groups/data.py b/gn_auth/auth/authorisation/groups/data.py
index 2d9ddb5..a73ae3d 100644
--- a/gn_auth/auth/authorisation/groups/data.py
+++ b/gn_auth/auth/authorisation/groups/data.py
@@ -2,7 +2,7 @@
 from MySQLdb.cursors import DictCursor
 
 from gn_auth.auth.db import mariadb as gn3db
-from gn_auth.auth.db import sqlite3 as authdb
+import gn_auth.auth.db.sqlite3 as authdb
 from gn_auth.auth.authorisation.groups import Group
 from gn_auth.auth.authorisation.checks import authorised_p
 from gn_auth.auth.authorisation.errors import NotFoundError
diff --git a/gn_auth/auth/authorisation/resources/views.py b/gn_auth/auth/authorisation/resources/views.py
index 157d5a3..e7af9b9 100644
--- a/gn_auth/auth/authorisation/resources/views.py
+++ b/gn_auth/auth/authorisation/resources/views.py
@@ -6,6 +6,7 @@ from functools import reduce
 
 from flask import request, jsonify, Response, Blueprint, current_app as app
 
+from gn_auth.auth.db import sqlite3 as db
 from gn_auth.auth.db.sqlite3 import with_db_connection
 
 from .checks import authorised_for
@@ -19,7 +20,6 @@ from ..roles import Role
 from ..errors import InvalidData, InconsistencyError, AuthorisationError
 from ..groups.models import Group, GroupRole, group_role_by_id
 
-from ... import db
 from ...dictify import dictify
 from ...authentication.oauth2.resource_server import require_oauth
 from ...authentication.users import User, user_by_id, user_by_email
diff --git a/gn_auth/auth/db/__init__.py b/gn_auth/auth/db/__init__.py
index eab58ef..7bdb38a 100644
--- a/gn_auth/auth/db/__init__.py
+++ b/gn_auth/auth/db/__init__.py
@@ -1 +1,2 @@
+"""Unified database connections module."""
 from .protocols import DbCursor, DbConnection
diff --git a/gn_auth/auth/db/mariadb.py b/gn_auth/auth/db/mariadb.py
index a934fd9..69c1d8e 100644
--- a/gn_auth/auth/db/mariadb.py
+++ b/gn_auth/auth/db/mariadb.py
@@ -1,12 +1,22 @@
 """Connections to MariaDB"""
+import logging
 import traceback
 import contextlib
-from typing import Iterator
+from urllib.parse import urlparse
+from typing import Tuple, Iterator
 
 import MySQLdb as mdb
 
 from .protocols import DbConnection
 
+def parse_db_url(sql_uri: str) -> Tuple:
+    """Parse SQL_URI env variable note:there is a default value for SQL_URI so a
+    tuple result is always expected"""
+    parsed_db = urlparse(sql_uri)
+    return (
+        parsed_db.hostname, parsed_db.username, parsed_db.password,
+        parsed_db.path[1:], parsed_db.port)
+
 @contextlib.contextmanager
 def database_connection(sql_uri) -> Iterator[DbConnection]:
     """Connect to MySQL database."""
@@ -18,7 +28,7 @@ def database_connection(sql_uri) -> Iterator[DbConnection]:
                              port=port or 3306)
     try:
         yield connection
-    except Exception as _exc: # TODO: Make the Exception class less general
+    except mdb.Error as _mdb_err:
         logging.debug(traceback.format_exc())
         connection.rollback()
     finally:
diff --git a/gn_auth/auth/db/redis.py b/gn_auth/auth/db/redis.py
new file mode 100644
index 0000000..fdf1d6f
--- /dev/null
+++ b/gn_auth/auth/db/redis.py
@@ -0,0 +1,22 @@
+"""Connections for Redis."""
+import logging
+import traceback
+import contextlib
+from typing import Iterator
+
+from redis import Redis, RedisError, ConnectionError as RedisConnectionError
+
+@contextlib.contextmanager
+def connection(redis_uri) -> Iterator[Redis]:
+    """Connection to redis"""
+    rconn = Redis.from_url(redis_uri, decode_responses=True)
+    try:
+        if not rconn.ping():
+            raise RedisConnectionError("Could not connect to Redis.")
+        yield rconn
+    except RedisError as _rerr:
+        logging.debug(traceback.format_exc())
+        raise
+    finally:
+        rconn.disconnect()
+        rconn.close()
diff --git a/gn_auth/auth/db/sqlite3.py b/gn_auth/auth/db/sqlite3.py
index 3d94832..be9eb2f 100644
--- a/gn_auth/auth/db/sqlite3.py
+++ b/gn_auth/auth/db/sqlite3.py
@@ -6,6 +6,8 @@ from typing import Any, Callable, Iterator
 
 import traceback
 
+from flask import current_app
+
 from .protocols import DbCursor, DbConnection
 
 @contextlib.contextmanager
diff --git a/gn_auth/commands.py b/gn_auth/commands.py
index d6f6f56..cc00413 100644
--- a/gn_auth/commands.py
+++ b/gn_auth/commands.py
@@ -10,6 +10,8 @@ from typing import Dict, Optional, Tuple, Union, Sequence
 
 from redis.client import Redis
 
+from gn_auth.auth.db.redis import RedisConnectionError
+
 def queue_cmd(conn: Redis,
               job_queue: str,
               cmd: Union[str, Sequence[str]],
diff --git a/scripts/migrate_existing_data.py b/scripts/migrate_existing_data.py
index 4452f41..7cd6086 100644
--- a/scripts/migrate_existing_data.py
+++ b/scripts/migrate_existing_data.py
@@ -14,7 +14,7 @@ from MySQLdb.cursors import DictCursor
 
 from gn_auth.auth.db import mariadb as biodb
 
-from gn_auth.auth.db import sqlite3 as authdb
+import gn_auth.auth.db.sqlite3 as authdb
 from gn_auth.auth.authentication.users import User
 from gn_auth.auth.authorisation.groups.models import Group, save_group
 from gn_auth.auth.authorisation.roles.models import (