diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..861adde5736f2cb21011fdc3927bb1b8a194ee86
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,15 @@
+repos:
+  - repo: local
+    hooks:
+      - id: ruff-lint
+        name: ruff-lint
+        language: system
+        entry: ruff check
+        pass_filenames: false
+        always_run: true
+      - id: ruff-format
+        name: ruff-format
+        language: system
+        entry: ruff format --check
+        pass_filenames: false
+        always_run: true
\ No newline at end of file
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 1c987370aa90bfc3b2a5a0ddd6d11527e8c44b57..a4a71c5808094cbc10413dc186e00f0a4ac50ace 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1 +1,3 @@
-pytest==8.3.4
\ No newline at end of file
+pytest==8.3.4
+ruff==0.8.3
+pre-commit==4.0.1
diff --git a/events.py b/events.py
index f73538747a497901f328ddc622561f1c39ba3cfc..dfcb6314ac805399192f6edafaa910d970215ad3 100644
--- a/events.py
+++ b/events.py
@@ -7,15 +7,18 @@ from cloudevents.http.event import CloudEvent
 
 
 def get_event_type(cloud_event: CloudEvent) -> str:
-    return cloud_event.data['message']['attributes']['eventType']
+    return cloud_event.data["message"]["attributes"]["eventType"]
+
 
 def get_event_version(cloud_event: CloudEvent) -> str:
-    return cloud_event.data['message']['attributes']['eventVersion']
+    return cloud_event.data["message"]["attributes"]["eventVersion"]
+
 
 def _validate_event_type(cloud_event: CloudEvent, expected_event_type: str) -> None:
     event_type = get_event_type(cloud_event)
     if event_type != expected_event_type:
-        raise ValueError(f'Expected event of type {expected_event_type}, got {event_type}')
+        raise ValueError(f"Expected event of type {expected_event_type}, got {event_type}")
+
 
 @dataclass
 class UserPayload:
@@ -28,13 +31,13 @@ class UserPayload:
     location: str
 
     def __init__(self, data: dict):
-        self.id = data['user']['id']
-        self.name = data['user']['name']
-        self.email = data['user']['email']
-        self.identity = data['user']['identity']
-        self.avatar = data['user']['avatar']
-        self.about_me = data['user']['aboutMe']
-        self.location = data['user']['location']
+        self.id = data["user"]["id"]
+        self.name = data["user"]["name"]
+        self.email = data["user"]["email"]
+        self.identity = data["user"]["identity"]
+        self.avatar = data["user"]["avatar"]
+        self.about_me = data["user"]["aboutMe"]
+        self.location = data["user"]["location"]
 
 
 @dataclass
@@ -46,44 +49,46 @@ class UserEvent:
     def __init__(self, cloud_event: CloudEvent):
         self.event_type = get_event_type(cloud_event)
         self.event_version = get_event_version(cloud_event)
-        self.user = UserPayload(json.loads(base64.b64decode(cloud_event.data['message']['data'])))
+        self.user = UserPayload(json.loads(base64.b64decode(cloud_event.data["message"]["data"])))
 
     def __str__(self):
         return f'{type(self).__name__}(id="{self.user.id}",name="{self.user.name}",email="***",identity="{self.user.identity}",avatar="{self.user.avatar}")'
 
+
 @dataclass
 class UserNameUpdatedEvent(UserEvent):
     def __init__(self, cloud_event: CloudEvent):
-        _validate_event_type(cloud_event, 'UserNameUpdated')
+        _validate_event_type(cloud_event, "UserNameUpdated")
         super().__init__(cloud_event)
 
     def as_typesense_document(self) -> object:
         return {
-            'id': f'profile_{self.user.id}',
-            'type': 'profile',
-            'title_de': self.user.name,
-            'title_en': self.user.name,
-            'description_de': self.user.about_me,
-            'description_en': self.user.about_me,
-            'location': self.user.location,
-            'location_lat_lng': None,  # TODO maybe enrich?
-            'image_url': self.user.avatar,
-            'link_locators': {
-                'profile': self.user.id
-            }
+            "id": f"profile_{self.user.id}",
+            "type": "profile",
+            "title_de": self.user.name,
+            "title_en": self.user.name,
+            "description_de": self.user.about_me,
+            "description_en": self.user.about_me,
+            "location": self.user.location,
+            "location_lat_lng": None,  # TODO maybe enrich?
+            "image_url": self.user.avatar,
+            "link_locators": {"profile": self.user.id},
         }
 
+
 @dataclass
 class UserDeletedEvent(UserEvent):
     def __init__(self, cloud_event: CloudEvent):
-        _validate_event_type(cloud_event, 'UserDeleted')
+        _validate_event_type(cloud_event, "UserDeleted")
         super().__init__(cloud_event)
 
+
 @dataclass
 class LatLng:
     latitude: float
     longitude: float
 
+
 @dataclass
 class SpacePayload:
     id: str
@@ -96,15 +101,24 @@ class SpacePayload:
     location_lat_lng: LatLng
 
     def __init__(self, data: dict):
-        self.id = data['space']['id']
-        self.name = data['space']['name']
-        self.slug = data['space']['slug']
-        self.avatar = data['space']['avatar']
-        self.avatar_default_color = data['space']['avatarDefaultColor']
-        self.description = data['space']['description']
-        self.location = data['space']['location']
-        contains_lat_lng = data['space']['locationLatLng'] is not None and data['space']['locationLatLng']['latitude'] is not None and data['space']['locationLatLng']['longitude'] is not None
-        self.location_lat_lng = LatLng(data['space']['locationLatLng'].get('latitude'), data['space']['locationLatLng'].get('longitude')) if contains_lat_lng else None
+        self.id = data["space"]["id"]
+        self.name = data["space"]["name"]
+        self.slug = data["space"]["slug"]
+        self.avatar = data["space"]["avatar"]
+        self.avatar_default_color = data["space"]["avatarDefaultColor"]
+        self.description = data["space"]["description"]
+        self.location = data["space"]["location"]
+        contains_lat_lng = (
+            data["space"]["locationLatLng"] is not None
+            and data["space"]["locationLatLng"]["latitude"] is not None
+            and data["space"]["locationLatLng"]["longitude"] is not None
+        )
+        self.location_lat_lng = (
+            LatLng(data["space"]["locationLatLng"].get("latitude"), data["space"]["locationLatLng"].get("longitude"))
+            if contains_lat_lng
+            else None
+        )
+
 
 @dataclass
 class SpaceEvent:
@@ -115,38 +129,41 @@ class SpaceEvent:
     def __init__(self, cloud_event: CloudEvent):
         self.event_type = get_event_type(cloud_event)
         self.event_version = get_event_version(cloud_event)
-        self.space = SpacePayload(json.loads(base64.b64decode(cloud_event.data['message']['data'])))
+        self.space = SpacePayload(json.loads(base64.b64decode(cloud_event.data["message"]["data"])))
 
     def as_typesense_document(self) -> object:
         return {
-            'id': f'space_{self.space.id}',
-            'type': 'space',
-            'title_de': self.space.name,
-            'title_en': self.space.name,
-            'description_de': self.space.description,
-            'description_en': self.space.description,
-            'location': self.space.location,
-            'location_lat_lng': [self.space.location_lat_lng.latitude, self.space.location_lat_lng.longitude] if self.space.location_lat_lng is not None else None,
-            'image_url': self.space.avatar,
-            'link_locators': {
-                'space': self.space.slug
-            }
+            "id": f"space_{self.space.id}",
+            "type": "space",
+            "title_de": self.space.name,
+            "title_en": self.space.name,
+            "description_de": self.space.description,
+            "description_en": self.space.description,
+            "location": self.space.location,
+            "location_lat_lng": [self.space.location_lat_lng.latitude, self.space.location_lat_lng.longitude]
+            if self.space.location_lat_lng is not None
+            else None,
+            "image_url": self.space.avatar,
+            "link_locators": {"space": self.space.slug},
         }
 
+
 @dataclass
 class SpaceCreatedEvent(SpaceEvent):
     def __init__(self, cloud_event: CloudEvent):
-        _validate_event_type(cloud_event, 'SpaceCreated')
+        _validate_event_type(cloud_event, "SpaceCreated")
         super().__init__(cloud_event)
 
+
 @dataclass
 class SpaceUpdatedEvent(SpaceEvent):
     def __init__(self, cloud_event: CloudEvent):
-        _validate_event_type(cloud_event, 'SpaceUpdated')
+        _validate_event_type(cloud_event, "SpaceUpdated")
         super().__init__(cloud_event)
 
+
 @dataclass
 class SpaceDeletedEvent(SpaceEvent):
     def __init__(self, cloud_event: CloudEvent):
-        _validate_event_type(cloud_event, 'SpaceDeleted')
-        super().__init__(cloud_event)
\ No newline at end of file
+        _validate_event_type(cloud_event, "SpaceDeleted")
+        super().__init__(cloud_event)
diff --git a/main.py b/main.py
index 72c7151a198319583bc52df90d66813731b832d1..8e4e34b5c9e103192cc03e8c510afad8553386b6 100644
--- a/main.py
+++ b/main.py
@@ -1,14 +1,19 @@
-import os
 import re
 import functions_framework
 from typing import Union
 
-from dataclasses import asdict
 from cloudevents.http.event import CloudEvent
 from typesense.exceptions import ObjectNotFound
 
-from events import UserNameUpdatedEvent, get_event_type, get_event_version, UserDeletedEvent, SpaceCreatedEvent, \
-    SpaceUpdatedEvent, SpaceDeletedEvent
+from events import (
+    UserNameUpdatedEvent,
+    get_event_type,
+    get_event_version,
+    UserDeletedEvent,
+    SpaceCreatedEvent,
+    SpaceUpdatedEvent,
+    SpaceDeletedEvent,
+)
 from typesense_client import TypesenseClient
 
 from logging import getLogger
@@ -17,62 +22,69 @@ logger = getLogger(__name__)
 
 SEMVER_1XX_SERIES = r"^1\.\d+\.\d+$"
 
+
 def process_user_name_updated_event(client: TypesenseClient, event: UserNameUpdatedEvent):
-    logger.debug(f'Processing {event}')
+    logger.debug(f"Processing {event}")
     client.upsert(event.as_typesense_document())
-    logger.info(f'Upserted user {event.user.id} in Typesense')
+    logger.info(f"Upserted user {event.user.id} in Typesense")
+
 
 def process_user_deleted_event(client: TypesenseClient, event: UserDeletedEvent):
-    logger.debug(f'Processing {event}')
+    logger.debug(f"Processing {event}")
     try:
         client.delete(f"profile_{event.user.id}")
     except ObjectNotFound:
         pass
-    logger.info(f'Deleted user {event.user.id} from Typesense')
+    logger.info(f"Deleted user {event.user.id} from Typesense")
+
 
 def process_space_upserting_event(client: TypesenseClient, event: Union[SpaceCreatedEvent, SpaceUpdatedEvent]):
-    logger.debug(f'Processing {event}')
+    logger.debug(f"Processing {event}")
     client.upsert(event.as_typesense_document())
-    logger.info(f'Upserted space {event.space.id} in Typesense')
+    logger.info(f"Upserted space {event.space.id} in Typesense")
+
 
 def process_space_deleted_event(client: TypesenseClient, event: SpaceDeletedEvent):
-    logger.debug(f'Processing {event}')
+    logger.debug(f"Processing {event}")
     try:
         client.delete(f"space_{event.space.id}")
     except ObjectNotFound:
         pass
-    logger.info(f'Deleted space {event.space.id} in Typesense')
+    logger.info(f"Deleted space {event.space.id} in Typesense")
+
 
 def process_event(client: TypesenseClient, event: CloudEvent):
     type_version = (get_event_type(event), re.match(SEMVER_1XX_SERIES, get_event_version(event)) is not None)
     match type_version:
-        case ('UserNameUpdated', True):
+        case ("UserNameUpdated", True):
             process_user_name_updated_event(client, UserNameUpdatedEvent(event))
-        case ('UserDeleted', True):
+        case ("UserDeleted", True):
             process_user_deleted_event(client, UserDeletedEvent(event))
-        case ('UserEmailUpdated', True):
+        case ("UserEmailUpdated", True):
             # no need to process, it is sufficient to handle UserNameUpdated
-            logger.debug('Ignoring UserEmailUpdated event')
+            logger.debug("Ignoring UserEmailUpdated event")
             pass
-        case ('SpaceCreated', True):
+        case ("SpaceCreated", True):
             process_space_upserting_event(client, SpaceCreatedEvent(event))
             pass
-        case ('SpaceUpdated', True):
+        case ("SpaceUpdated", True):
             process_space_upserting_event(client, SpaceUpdatedEvent(event))
             pass
-        case ('SpaceDeleted', True):
+        case ("SpaceDeleted", True):
             process_space_deleted_event(client, SpaceDeletedEvent(event))
             pass
         case (eventType, eventVersion):
             # UserEmailUpdated: no need to process, it is sufficient to handle UserNameUpdated because this is emitted
             # during signup and search should not display email addresses (PII)
             # All other events are assumed to (currently) not be of interest in search
-            logger.debug(f'Ignoring {eventType} ({eventVersion}) event.')
+            logger.debug(f"Ignoring {eventType} ({eventVersion}) event.")
             pass
 
+
 @functions_framework.cloud_event
 def process_message(event: CloudEvent):
     client = TypesenseClient()
     process_event(client, event)
 
-# TODO ensure that UserUpdated or similar is emitted on updates of fields we're interested in
\ No newline at end of file
+
+# TODO ensure that UserUpdated or similar is emitted on updates of fields we're interested in
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..39705f784cb27e58d676cb8cd24a9ab3a1243cb4
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,45 @@
+[tool.ruff]
+line-length = 119
+extend-exclude = [
+    ".docker",
+    ".docker-cache",
+    "media",
+    "migrations",
+    "reports",
+    "static",
+    "terraform",
+]
+
+[tool.ruff.lint]
+select = [
+    "F",    # pyflakes https://docs.astral.sh/ruff/rules/#pyflakes-f
+    "E",    # pycodestyle errors https://docs.astral.sh/ruff/rules/#error-e
+    "B",    # bugbear https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
+    "S",    # bandit https://docs.astral.sh/ruff/rules/#flake8-bandit-s
+    "N",    # pep8-naming https://docs.astral.sh/ruff/rules/#pep8-naming-n
+    "T20",  # forbid print statements https://docs.astral.sh/ruff/rules/#flake8-print-t20
+    "ERA",  # forbid commented out code https://docs.astral.sh/ruff/rules/#eradicate-era
+    # "ANN",  # enforce type annotations https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
+]
+extend-ignore = [
+    "E501",  # "line too long" - only triggers in edge cases of the formatter
+    "N806",  # "non-lowercase-variable-in-function" - we use that to reference model classes in functions
+]
+[tool.ruff.lint.extend-per-file-ignores]
+# S101 use of assert - allowed in tests
+"**/test_*.py" = ["S101"]
+"**/tests/*.py" = ["S101"]
+
+[tool.ruff.format]
+exclude = [
+    ".docker",
+    ".docker-cache",
+    ".git",
+    ".venv",
+    "media",
+    "migrations",
+    "reports",
+    "static",
+    "terraform",
+    "venv",
+]
diff --git a/test_main.py b/test_main.py
index 2793692a11b0e6d01d23f97d18a4d3fcb8a6beb0..61eeef3b4ab136d83a5566a1f22914adf01a0714 100644
--- a/test_main.py
+++ b/test_main.py
@@ -8,109 +8,128 @@ from cloudevents.http.event import CloudEvent
 from main import process_event
 
 attributes = {
-    'id': '12833783708309476',
-    'time': '2024-12-07T16:21:48.022Z',
-    'specversion': '1.0',
-    'datacontenttype': 'application/json',
-    'type': 'google.cloud.pubsub.topic.v1.messagePublished',
-    'source': '//pubsub.googleapis.com/'
+    "id": "12833783708309476",
+    "time": "2024-12-07T16:21:48.022Z",
+    "specversion": "1.0",
+    "datacontenttype": "application/json",
+    "type": "google.cloud.pubsub.topic.v1.messagePublished",
+    "source": "//pubsub.googleapis.com/",
 }
 
 user_payload = {
-    'id': '149a3d29-a0da-4f52-8e1c-660376b7084b',
-    'name': 'Daniel holi team',
-    'email': 'daniel@holi.team',
-    'identity': 'danielholi.team',
-    'avatar': 'https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg',
-    'aboutMe': 'Daniel about himself',
-    'location': 'Klitmøller, Denmark'
+    "id": "149a3d29-a0da-4f52-8e1c-660376b7084b",
+    "name": "Daniel holi team",
+    "email": "daniel@holi.team",
+    "identity": "danielholi.team",
+    "avatar": "https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg",
+    "aboutMe": "Daniel about himself",
+    "location": "Klitmøller, Denmark",
 }
 
 space_payload = {
-    'id': '149a3d29-a0da-4f52-8e1c-660376b7084b',
-    'name': 'Daniels Space',
-    'slug': 'daniels-space',
-    'avatar': 'https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg',
-    'avatarDefaultColor': 'ffffff',
-    'description': 'This is Daniels Space',
-    'location': 'Klitmøller, Denmark',
-    'locationLatLng': {
-        'latitude': 57.0393497,
-        'longitude': 8.474686,
-    }
+    "id": "149a3d29-a0da-4f52-8e1c-660376b7084b",
+    "name": "Daniels Space",
+    "slug": "daniels-space",
+    "avatar": "https://ik.imagekit.io/holi/_DEV_/avatar/149a3d29-a0da-4f52-8e1c-660376b7084b_yv31UW7lD0.jpg",
+    "avatarDefaultColor": "ffffff",
+    "description": "This is Daniels Space",
+    "location": "Klitmøller, Denmark",
+    "locationLatLng": {
+        "latitude": 57.0393497,
+        "longitude": 8.474686,
+    },
 }
 
+
 def message_data(event_type, event_version, data):
     return {
-        'message': {
-            '@type': 'type.googleapis.com/google.pubsub.v1.PubsubMessage',
-            'data': base64.b64encode(json.dumps(data).encode('utf-8')),
-            'attributes': {
-                'eventType': event_type,
-                'eventVersion': event_version,
+        "message": {
+            "@type": "type.googleapis.com/google.pubsub.v1.PubsubMessage",
+            "data": base64.b64encode(json.dumps(data).encode("utf-8")),
+            "attributes": {
+                "eventType": event_type,
+                "eventVersion": event_version,
             },
-            'messageId': '12833783708309476',
-            'publishTime': '2024-12-07T16:21:48.022Z'
+            "messageId": "12833783708309476",
+            "publishTime": "2024-12-07T16:21:48.022Z",
         }
-}
+    }
+
 
-@patch('typesense.client.Client')
+@patch("typesense.client.Client")
 def test_user_name_updated(mock_client):
-    process_event(mock_client, CloudEvent(attributes, message_data('UserNameUpdated', '1.0.0', {'user': user_payload})))
-    mock_client.upsert.assert_called_with({
-        'id': f'profile_{user_payload["id"]}',
-        'type': 'profile',
-        'title_de': user_payload['name'],
-        'title_en': user_payload['name'],
-        'description_de': user_payload['aboutMe'],
-        'description_en': user_payload['aboutMe'],
-        'location': user_payload['location'],
-        'location_lat_lng': None,
-        'image_url': user_payload['avatar'],
-        'link_locators': {
-            'profile': user_payload['id'],
+    process_event(
+        mock_client, CloudEvent(attributes, message_data("UserNameUpdated", "1.0.0", {"user": user_payload}))
+    )
+    mock_client.upsert.assert_called_with(
+        {
+            "id": f'profile_{user_payload["id"]}',
+            "type": "profile",
+            "title_de": user_payload["name"],
+            "title_en": user_payload["name"],
+            "description_de": user_payload["aboutMe"],
+            "description_en": user_payload["aboutMe"],
+            "location": user_payload["location"],
+            "location_lat_lng": None,
+            "image_url": user_payload["avatar"],
+            "link_locators": {
+                "profile": user_payload["id"],
+            },
         }
-    })
+    )
 
-@patch('typesense.client.Client')
+
+@patch("typesense.client.Client")
 def test_user_deleted(mock_client):
-    process_event(mock_client, CloudEvent(attributes, message_data('UserDeleted', '1.0.0', {'user': user_payload})))
+    process_event(mock_client, CloudEvent(attributes, message_data("UserDeleted", "1.0.0", {"user": user_payload})))
     mock_client.delete.assert_called_with(f"profile_{user_payload['id']}")
 
+
 # noinspection DuplicatedCode
-@patch('typesense.client.Client')
+@patch("typesense.client.Client")
 def test_space_created(mock_client):
-    process_event(mock_client, CloudEvent(attributes, message_data('SpaceCreated', '1.0.0', {'space': space_payload})))
-    mock_client.upsert.assert_called_with({
-        'id': f'space_{space_payload['id']}',
-        'type': 'space',
-        'title_de': space_payload['name'],
-        'title_en': space_payload['name'],
-        'description_de': space_payload['description'],
-        'description_en': space_payload['description'],
-        'location': space_payload['location'],
-        'location_lat_lng': [space_payload['locationLatLng']['latitude'], space_payload['locationLatLng']['longitude']],
-        'image_url': space_payload['avatar'],
-        'link_locators': {
-            'space': space_payload['slug'],
+    process_event(mock_client, CloudEvent(attributes, message_data("SpaceCreated", "1.0.0", {"space": space_payload})))
+    mock_client.upsert.assert_called_with(
+        {
+            "id": f'space_{space_payload['id']}',
+            "type": "space",
+            "title_de": space_payload["name"],
+            "title_en": space_payload["name"],
+            "description_de": space_payload["description"],
+            "description_en": space_payload["description"],
+            "location": space_payload["location"],
+            "location_lat_lng": [
+                space_payload["locationLatLng"]["latitude"],
+                space_payload["locationLatLng"]["longitude"],
+            ],
+            "image_url": space_payload["avatar"],
+            "link_locators": {
+                "space": space_payload["slug"],
+            },
         }
-    })
+    )
+
 
 # noinspection DuplicatedCode
-@patch('typesense.client.Client')
+@patch("typesense.client.Client")
 def test_space_updated(mock_client):
-    process_event(mock_client, CloudEvent(attributes, message_data('SpaceUpdated', '1.0.0', {'space': space_payload})))
-    mock_client.upsert.assert_called_with({
-        'id': f'space_{space_payload['id']}',
-        'type': 'space',
-        'title_de': space_payload['name'],
-        'title_en': space_payload['name'],
-        'description_de': space_payload['description'],
-        'description_en': space_payload['description'],
-        'location': space_payload['location'],
-        'location_lat_lng': [space_payload['locationLatLng']['latitude'], space_payload['locationLatLng']['longitude']],
-        'image_url': space_payload['avatar'],
-        'link_locators': {
-            'space': space_payload['slug'],
+    process_event(mock_client, CloudEvent(attributes, message_data("SpaceUpdated", "1.0.0", {"space": space_payload})))
+    mock_client.upsert.assert_called_with(
+        {
+            "id": f'space_{space_payload['id']}',
+            "type": "space",
+            "title_de": space_payload["name"],
+            "title_en": space_payload["name"],
+            "description_de": space_payload["description"],
+            "description_en": space_payload["description"],
+            "location": space_payload["location"],
+            "location_lat_lng": [
+                space_payload["locationLatLng"]["latitude"],
+                space_payload["locationLatLng"]["longitude"],
+            ],
+            "image_url": space_payload["avatar"],
+            "link_locators": {
+                "space": space_payload["slug"],
+            },
         }
-    })
+    )
diff --git a/typesense_client.py b/typesense_client.py
index 87502653a777fddf679c1888a75e0e70a8859a16..672fc34eb69b433a7d59dfdfdef1fa9cacd6e209 100644
--- a/typesense_client.py
+++ b/typesense_client.py
@@ -2,24 +2,28 @@ import os
 
 from typesense.client import Client
 
+
 class TypesenseClient(object):
     """
     Thin wrapper around the Typesense client to simplify call site and testing/mocking code.
     """
+
     client: Client
 
     def __init__(self):
-        self.client = Client({
-            "api_key": (os.getenv("TYPESENSE_ADMIN_API_KEY")),
-            "nodes": [
-                {
-                    "host": (os.getenv("TYPESENSE_HOST")),
-                    "port": (os.getenv("TYPESENSE_PORT")),
-                    "protocol": (os.getenv("TYPESENSE_PROTOCOL")),
-                }
-            ],
-            "connection_timeout_seconds": 60 * 60,
-        })
+        self.client = Client(
+            {
+                "api_key": (os.getenv("TYPESENSE_ADMIN_API_KEY")),
+                "nodes": [
+                    {
+                        "host": (os.getenv("TYPESENSE_HOST")),
+                        "port": (os.getenv("TYPESENSE_PORT")),
+                        "protocol": (os.getenv("TYPESENSE_PROTOCOL")),
+                    }
+                ],
+                "connection_timeout_seconds": 60 * 60,
+            }
+        )
 
     def upsert(self, document) -> object:
         """
@@ -37,4 +41,4 @@ class TypesenseClient(object):
         :param id: the id of the document to delete
         :return: deserialized JSON document
         """
-        return self.client.collections[os.getenv("TYPESENSE_COLLECTION_NAME")].documents[id].delete()
\ No newline at end of file
+        return self.client.collections[os.getenv("TYPESENSE_COLLECTION_NAME")].documents[id].delete()