diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 51c4486b50ed0bd260a0b62aa01fbd3eca608769..8b15e764abae0844f7d39fc7b9a5098edbc47c3c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -72,8 +72,9 @@ trigger_build:
     # Renaming variables.
     F_BRANCH: $CI_COMMIT_REF_NAME
     PYLIB: $CI_COMMIT_REF_NAME
-    TriggeredBy: PYLIB
-    TriggeredByHash: $CI_COMMIT_SHORT_SHA
+    TRIGGERED_BY_REPO: PYLIB
+    TRIGGERED_BY_REF: $CI_COMMIT_REF_NAME
+    TRIGGERED_BY_HASH: $CI_COMMIT_SHORT_SHA
 
   trigger:
     project: caosdb/src/caosdb-deploy
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 98ae4000c009979b7ad4a97d8f3b3bc2bf762088..d7d7adaa22e68d4126d53cab7add5a862c829181 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * Support for Python 3.6 and Python 3.7
 
 ### Fixed ###
+* [#75](https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/75), [#103](https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/103) Fixed JSON schema to allow more sections, and correct requirements for
+  password method.
+- `read()` of MockupResponse returns now an appropriate type on modern systems
 
 * [caosdb-server#142](https://gitlab.com/caosdb/caosdb-server/-/issues/142)
   Can't create users with dots in their user names
diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index 3421f9ce39fc848f774b5d5d38280434354da8de..f974060f4727e575a94a3afcdd2f86520e6123a9 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -44,7 +44,6 @@ from hashlib import sha512
 from os import listdir
 from os.path import isdir
 from random import randint
-from sys import hexversion
 from tempfile import NamedTemporaryFile
 from warnings import warn
 
@@ -1402,11 +1401,7 @@ def _log_request(request, xml_body=None):
 def _log_response(body):
     if Container._debug() > 0:
         print("\n======== Response body ========\n")
-
-        if hexversion < 0x03000000:
-            print(body)
-        else:
-            print(body.decode())
+        print(body.decode())
         print("\n===============================\n")
 
 
diff --git a/src/caosdb/common/utils.py b/src/caosdb/common/utils.py
index eabce3139ccabb35412b5dbe0fb83721fc18179a..f0ce740d38d90b0c7bb1031e808b83efb2207a43 100644
--- a/src/caosdb/common/utils.py
+++ b/src/caosdb/common/utils.py
@@ -26,7 +26,6 @@
 from lxml import etree
 from multiprocessing import Lock
 from uuid import uuid4
-from sys import hexversion
 _uuid_lock = Lock()
 
 
diff --git a/src/caosdb/connection/__init__.py b/src/caosdb/connection/__init__.py
index 638d4f0a8400f0ea1a2f197dcfdbe3fc933d4c10..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/caosdb/connection/__init__.py
+++ b/src/caosdb/connection/__init__.py
@@ -1,29 +0,0 @@
-# -*- encoding: utf-8 -*-
-#
-# ** header v3.0
-# This file is a part of the CaosDB Project.
-#
-# Copyright (C) 2018 Research Group Biomedical Physics,
-# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-#
-# ** end header
-#
-from sys import hexversion
-from .utils import check_python_ssl_version
-
-check_python_ssl_version(hexversion)
-del check_python_ssl_version
-del hexversion
diff --git a/src/caosdb/connection/encode.py b/src/caosdb/connection/encode.py
index 970c4191e1defc55b2b4a6c7d01e0c9d4ba2952f..7b092aae784a76abec0104ef7269df7ae0111b3b 100644
--- a/src/caosdb/connection/encode.py
+++ b/src/caosdb/connection/encode.py
@@ -53,19 +53,9 @@ __all__ = [
     'gen_boundary', 'encode_and_quote', 'MultipartParam', 'encode_string',
     'encode_file_header', 'get_body_size', 'get_headers', 'multipart_encode'
 ]
-from sys import hexversion
-try:
-    from urllib.parse import quote_plus
-except ImportError:
-    from urllib import quote_plus
-
-try:
-    from io import UnsupportedOperation
-except ImportError:
-    UnsupportedOperation = None
-
+from urllib.parse import quote_plus
+from io import UnsupportedOperation
 import uuid
-
 import re
 import os
 import mimetypes
@@ -83,24 +73,9 @@ def encode_and_quote(data):
     if data is None:
         return None
 
-    if hexversion < 0x03000000:
-        if isinstance(data, unicode):
-            data = data.encode("utf-8")
     return quote_plus(data)
 
 
-def _strify(string):
-    """If string is a unicode string, encode it to UTF-8 and return the
-    results, otherwise return str(s), or None if s is None."""
-    if string is None:
-        return None
-    if hexversion < 0x03000000:
-        if isinstance(string, unicode):
-            return string.encode("utf-8")
-        return str(string)
-    return str(string)
-
-
 class MultipartParam(object):
     """Represents a single parameter in a multipart/form-data request.
 
@@ -143,22 +118,14 @@ class MultipartParam(object):
                  fileobj=None,
                  callback=None):
         self.name = Header(name).encode()
-        self.value = _strify(value)
+        self.value = value
         if filename is None:
             self.filename = None
-        elif hexversion < 0x03000000:
-            if isinstance(filename, unicode):
-                # Encode with XML entities
-                self.filename = filename.encode("ascii", "xmlcharrefreplace")
-            else:
-                self.filename = str(filename)
-            self.filename = self.filename.encode("string_escape").\
-                replace('"', '\\"')
         else:
             bfilename = filename.encode("ascii", "xmlcharrefreplace")
             self.filename = bfilename.decode("UTF-8").replace('"', '\\"')
 
-        self.filetype = _strify(filetype)
+        self.filetype = filetype
 
         self.filesize = filesize
         self.fileobj = fileobj
diff --git a/src/caosdb/connection/mockup.py b/src/caosdb/connection/mockup.py
index 692ec2b13f16556a9acfab2a377a04aaf27d650c..b37670b867cd88cf47e64084c6ccc802cad463b4 100644
--- a/src/caosdb/connection/mockup.py
+++ b/src/caosdb/connection/mockup.py
@@ -56,7 +56,7 @@ class MockUpResponse(CaosDBHTTPResponse):
 
     def read(self, size=-1):
         """Return the body of the response."""
-        return self.response.read(size)
+        return self.response.read(size).encode()
 
     def getheader(self, name, default=None):
         """Get the contents of the header `name`, or `default` if there is no
diff --git a/src/caosdb/connection/utils.py b/src/caosdb/connection/utils.py
index 8c1518c1ba66b45c69d5b9fa0d137f0df633cd0c..9056bf9dea14fa2fa441fa13a5efe8e776990284 100644
--- a/src/caosdb/connection/utils.py
+++ b/src/caosdb/connection/utils.py
@@ -23,19 +23,9 @@
 #
 """Utility functions for the connection module."""
 from __future__ import unicode_literals, print_function
-try:
-    from builtins import str, unicode  # pylint: disable=redefined-builtin
-except ImportError:
-    from builtins import str as unicode
-try:  # pragma: no cover
-    # python3
-    from urllib.parse import (urlencode as _urlencode, quote as _quote,
-                              urlparse, urlunparse, unquote as _unquote)
-except ImportError:  # pragma: no cover
-    # python2
-    from urllib import (urlencode as _urlencode, quote as _quote, unquote as
-                        _unquote)
-    from urlparse import urlparse, urlunparse
+from builtins import str as unicode
+from urllib.parse import (urlencode as _urlencode, quote as _quote,
+                          urlparse, urlunparse, unquote as _unquote)
 import re
 
 
@@ -122,7 +112,7 @@ def make_uri_path(segments=None, query=None):
 
 
 def quote(string):
-    enc = unicode(string).encode('utf-8')
+    enc = string.encode('utf-8')
     return _quote(enc).replace('/', '%2F')
 
 
@@ -136,35 +126,6 @@ def parse_url(url):
     return fullurl
 
 
-def check_python_ssl_version(hexversion):
-    """Check the python version.
-
-    If `version < 2.7.9` or `3.0 <= version < 3.2` the ssl library does not
-    actually verify the ssl certificates send by the server. That is evil and
-    these versions shall not be used.
-
-    Parameters
-    ----------
-    hexversion : int
-        A python version.
-
-    Raises
-    ------
-    Exception
-        If the version does not fully support ssl encryption.
-    """
-    if hexversion < 0x02070900:
-        raise Exception(
-            "version " + str(hex(hexversion)) +
-            "\nPython version is smaller than 2.7.9. It is not does not fully support SSL encryption. Please update your Python to 2.7.9 or greater, or 3.2 or greater."
-        )
-    elif hexversion >= 0x03000000 and hexversion < 0x03020000:
-        raise Exception(
-            "version " + str(hex(hexversion)) +
-            "\nPython 3 version is smaller than 3.2. It is not does not fully support SSL encryption. Please update your Python to 2.7.9 or greater, or 3.2 or greater."
-        )
-
-
 _PATTERN = re.compile(r"^SessionToken=([^;]*);.*$")
 
 
diff --git a/unittests/test_authentication_auth_token.py b/unittests/test_authentication_auth_token.py
index 15e54121fc0d7b5c2be645cdb88bc20804a10980..d0eb6b90883951af584d42a80e319c14891f6e50 100644
--- a/unittests/test_authentication_auth_token.py
+++ b/unittests/test_authentication_auth_token.py
@@ -65,7 +65,7 @@ def test_configure_connection():
     c._delegate_connection.resources.append(request_has_auth_token)
     assert c._authenticator.auth_token == "[request token]"
     response = c._http_request(method="GET", path="test")
-    assert response.read() == "ok"
+    assert response.read().decode() == "ok"
     assert c._authenticator.auth_token == "[response token]"
 
 
diff --git a/unittests/test_authentication_unauthenticated.py b/unittests/test_authentication_unauthenticated.py
index 52146b08ed4e1026660eebacedf348aeb2ff2721..45a709fcc62b609a97de7e87dd6c6f6ac94a55a1 100644
--- a/unittests/test_authentication_unauthenticated.py
+++ b/unittests/test_authentication_unauthenticated.py
@@ -59,7 +59,7 @@ def test_configure_connection():
 
     assert c._authenticator.auth_token is None
     response = c._http_request(method="GET", path="test")
-    assert response.read() == "ok"
+    assert response.read().decode() == "ok"
     mock.method.assert_called_once()
     assert c._authenticator.auth_token is None
 
diff --git a/unittests/test_connection.py b/unittests/test_connection.py
index 16370f00b7d5e3389582befaac1762b1d2992fcf..ee564ea033f9afc80522d75a85557f70819ece1e 100644
--- a/unittests/test_connection.py
+++ b/unittests/test_connection.py
@@ -169,7 +169,7 @@ def test_getter_status():
 def test_read():
     response = test_init_response()
     tru(hasattr(response, "read"))
-    eq(response.read(), "Body")
+    eq(response.read().decode(), "Body")
 
 
 def test_getter_session_token():