diff --git a/nomad/app_fastapi/__init__.py b/nomad/app_fastapi/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/nomad/app_fastapi/models.py b/nomad/app_fastapi/models.py
index 7d705aaa44192cef141f60572ee2674e3eba9662..694f1d1a874fa1fa9fe3dc9320e347f479d7af44 100644
--- a/nomad/app_fastapi/models.py
+++ b/nomad/app_fastapi/models.py
@@ -16,7 +16,7 @@
 # limitations under the License.
 #
 
-from typing import List, Dict, Optional, Union, Any
+from typing import List, Dict, Optional, Union, Any, Mapping
 import enum
 from fastapi import Body, Request, HTTPException, Query as FastApiQuery
 import pydantic
@@ -139,7 +139,7 @@ ops = {
 QueryParameterValue = Union[Value, List[Value], Lte, Lt, Gte, Gt, Any_, All, None_]
 
 Query = Union[
-    Dict[str, QueryParameterValue], And, Or, Not]
+    Mapping[str, QueryParameterValue], And, Or, Not]
 
 
 And.update_forward_refs()
diff --git a/nomad/app_fastapi/optimade/elasticsearch.py b/nomad/app_fastapi/optimade/elasticsearch.py
index df868611aa98ea1f67fd7450d8d35d9b73111d45..e32fade8510d3294f0dab41acfdc1cdb1091a7d3 100644
--- a/nomad/app_fastapi/optimade/elasticsearch.py
+++ b/nomad/app_fastapi/optimade/elasticsearch.py
@@ -1,26 +1,14 @@
-import os
-
-from typing import Tuple, List, Union, Dict, Any, Set
-import mongomock
-import pymongo.collection
+from typing import Tuple, List, Union, Dict, Set
 from fastapi import HTTPException
-
 from elasticsearch_dsl import Search, Q
-from urllib.parse import urlparse
 
 from optimade.filterparser import LarkParser
-from optimade.filtertransformers.elasticsearch import ElasticTransformer
-from optimade.models import EntryResource
-from optimade.server.config import CONFIG
 from optimade.server.entry_collections import EntryCollection
-from optimade.server.logger import LOGGER
-from optimade.server.mappers import BaseResourceMapper
 from optimade.server.query_params import EntryListingQueryParams, SingleEntryQueryParams
 from optimade.server.exceptions import BadRequest
 from optimade.server.mappers import StructureMapper
 from optimade.models import StructureResource
 
-
 from nomad import config, datamodel, files, search, utils
 from nomad.normalizing.optimade import (
     optimade_chemical_formula_reduced, optimade_chemical_formula_anonymous,
@@ -94,7 +82,8 @@ class ElasticsearchStructureCollection(EntryCollection):
             logger.error('could not parse optimade filter', filter=filter_param)
             raise NotImplementedError(
                 'some features used in filter query %s are not implemented' % filter_param)
-        elif filter != {}:
+
+        if filter != {}:
             search_request.query(filter)
 
         es_response = search_request.execute_paginated(
diff --git a/nomad/app_fastapi/optimade_logger.py b/nomad/app_fastapi/optimade_logger.py
index 372e055ca29041ba064dbe4852de40072cd3501a..40a2ab9464f9895f58480bd9324c84cd382a2b17 100644
--- a/nomad/app_fastapi/optimade_logger.py
+++ b/nomad/app_fastapi/optimade_logger.py
@@ -1,4 +1,3 @@
-import logging
 from nomad import utils
 
 LOGGER = utils.get_logger('optimade')
diff --git a/nomad/app_fastapi/routers/datasets.py b/nomad/app_fastapi/routers/datasets.py
index 602c4c4992f73eaef896ea72db9d36a1fa3dee47..c0c267a112701c20a7bbf4a09eb6bdcf619c5a56 100644
--- a/nomad/app_fastapi/routers/datasets.py
+++ b/nomad/app_fastapi/routers/datasets.py
@@ -25,14 +25,13 @@ import enum
 from nomad import utils, datamodel
 from nomad.utils import strip, create_uuid
 from nomad.datamodel import Dataset as DatasetDefinitionCls
-from nomad.search import search
 from nomad.doi import DOI
 
 from nomad.app_fastapi.routers.auth import get_required_user
 from nomad.app_fastapi.utils import create_responses
 from nomad.app_fastapi.models import (
     pagination_parameters, Pagination, PaginationResponse, Query,
-    HTTPExceptionModel, User, Direction, MetadataRequired)
+    HTTPExceptionModel, User, Direction, Owner)
 
 from .entries import _do_exaustive_search
 
@@ -212,7 +211,7 @@ async def post_datasets(
     # get all entry ids
     if create.query is not None:
         entries = _do_exaustive_search(
-            owner='public', query=create.query, user=user,
+            owner=Owner.public, query=create.query, user=user,
             include=['calc_id'])
         dataset.entries = [entry['calc_id'] for entry in entries]
     elif create.entries is not None:
diff --git a/nomad/app_fastapi/routers/entries.py b/nomad/app_fastapi/routers/entries.py
index b3b505d6b409324e912d34c057c6f670072758ea..4548e574ac5c5534df965ae5a078a8bb107ad89d 100644
--- a/nomad/app_fastapi/routers/entries.py
+++ b/nomad/app_fastapi/routers/entries.py
@@ -737,7 +737,7 @@ async def get_entry_raw_download(
             status_code=status.HTTP_404_NOT_FOUND,
             detail='The entry with the given id does not exist or is not visible to you.')
 
-    return _answer_entries_raw_download_request(owner='public', query=query, files=files, user=user)
+    return _answer_entries_raw_download_request(owner=Owner.public, query=query, files=files, user=user)
 
 
 @router.get(
diff --git a/nomad/archive.py b/nomad/archive.py
index 70cbd0b57bbad7e8861fa6c9457995298c340b04..03990a6cc0c75577d4d1fedab7b1337c1eceec27 100644
--- a/nomad/archive.py
+++ b/nomad/archive.py
@@ -595,7 +595,7 @@ def query_archive(
 
 
 def filter_archive(
-        required: Dict[str, Any], archive_item: Union[Dict, ArchiveObject],
+        required: Union[str, Dict[str, Any]], archive_item: Union[Dict, ArchiveObject],
         transform: Callable) -> Dict:
 
     def _fix_index(index, length):
diff --git a/nomad/search.py b/nomad/search.py
index 7c11c5c846d32f7c628e6478e4e8e952c5e5c3a2..15a6ccb65966772a24a502ea05f42bcaf202ecc6 100644
--- a/nomad/search.py
+++ b/nomad/search.py
@@ -20,7 +20,7 @@
 This module represents calculations in elastic search.
 '''
 
-from typing import Iterable, Dict, List, Any
+from typing import cast, Iterable, Dict, List, Any
 from elasticsearch_dsl import Search, Q, A, analyzer, tokenizer
 import elasticsearch.helpers
 from elasticsearch.exceptions import NotFoundError, RequestError
@@ -1110,15 +1110,15 @@ def search(
 
     # statistics
     if len(statistics) > 0:
-        more_response_data['statistics'] = {
+        more_response_data['statistics'] = cast(Dict[str, Any], {
             name: _es_to_api_statistics(es_response, name, statistic)
-            for name, statistic in statistics.items()}
+            for name, statistic in statistics.items()})
 
     # aggregations
     if len(aggregations) > 0:
-        more_response_data['aggregations'] = {
+        more_response_data['aggregations'] = cast(Dict[str, Any], {
             name: _es_to_api_aggregation(es_response, name, aggregation)
-            for name, aggregation in aggregations.items()}
+            for name, aggregation in aggregations.items()})
 
     more_response_data['es_query'] = es_query.to_dict()