Skip to content

Commit

Permalink
Merge pull request #54 from octue/fix-sruids
Browse files Browse the repository at this point in the history
Fix SRUIDs and require namespace and tag
  • Loading branch information
thclark authored Jul 12, 2023
2 parents 6e55372 + 376be52 commit 722051e
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 98 deletions.
66 changes: 25 additions & 41 deletions django_twined/models/service_revisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.db import models, transaction
from django_gcp.events.utils import get_event_url
from octue.cloud.pub_sub.service import Service
from octue.cloud.service_id import convert_service_id_to_pub_sub_form
from octue.resources.service_backends import get_backend

from .service_usage_events import QUESTION_RESPONSE_UPDATED
Expand Down Expand Up @@ -64,6 +65,8 @@ class AbstractServiceRevision(models.Model):
namespace = models.SlugField(
max_length=80,
default=get_default_namespace,
blank=False,
null=False,
help_text="The organisation namespace, eg 'octue'",
)

Expand All @@ -75,6 +78,7 @@ class AbstractServiceRevision(models.Model):
max_length=80,
default=get_default_tag,
blank=False,
null=False,
help_text="The service revision tag that helps to identify the unique deployment",
)

Expand All @@ -96,52 +100,35 @@ class Meta:
),
]

@property
def has_tag(self):
"""Return true if the instance has a tag"""
return (self.tag is not None) and (len(self.tag) > 0)

@property
def has_namespace(self):
"""Return true if the instance has a namespace"""
return (self.namespace is not None) and (len(self.namespace) > 0)

@property
def sruid(self):
"""Return the Service Revision Unique Identifier
Comprises the namespace, name, version, and tag parameters that
together uniquely identify a revision (e.g. for the purposes of
addressing).
Comprises the namespace, name, version, and tag parameters that together uniquely identify a revision (e.g. for
the purposes of addressing).
Using docker image labeling as inspiration, this looks like
octue/example-service:0.1.2 or octue/example-service:my-branch
or octue/example-service:0.1.2-r1 enabling both routing to specific
revisions and things like branches for review
Using docker image labeling as inspiration, this looks like octue/example-service:0.1.2 or
octue/example-service:my-branch or octue/example-service:0.1.2-r1 enabling both routing to specific revisions
and things like branches for review.
"""
tag = f":{self.tag}" if self.has_tag else ""

namespace = f"{self.namespace}/" if self.has_namespace else ""

return f"{namespace}{self.name}{tag}"

@property
def _partial_topic(self):
"""TODO replace this once the service id has been properly sorted out on the octue side
currently this is used to botch the service_id value so that it comes out with the correct topic name format"""
tag = f".{self.tag.replace('.', '-')}" if self.has_tag else ""
namespace = f"{self.namespace}." if self.has_namespace else ""
return f"{namespace}{self.name}{tag}"
return f"{self.namespace}/{self.name}:{self.tag}"

@property
def topic(self):
"""Return the octue GCP topic address string"""
tag = f".{self.tag}" if self.has_tag else ""
namespace = f"{self.namespace}." if self.has_namespace else ""
return f"octue.services.{namespace}{self.name}{tag}"
"""Return the octue GCP topic address string.
:return str:
"""
return "octue.services." + convert_service_id_to_pub_sub_form(self.sruid)

def ask(
self, question_id, input_values=None, input_manifest=None, push_url=None, asker_name="django-twined", **kwargs
self,
question_id,
input_values=None,
input_manifest=None,
push_url=None,
asker_name="django-twined",
**kwargs,
):
"""Ask a question of this service revision
Expand All @@ -166,7 +153,6 @@ def ask(
```
"""

if push_url is None:
push_url = get_event_url(
event_kind=QUESTION_RESPONSE_UPDATED,
Expand All @@ -178,13 +164,11 @@ def ask(
base_url=settings.TWINED_BASE_URL,
)

backend = get_backend()(
project_name=self.project_name,
)
backend = get_backend()(project_name=self.project_name)
asker = Service(backend=backend, name=asker_name)

asker = Service(backend, name=asker_name)
subscription, _ = asker.ask(
service_id=self._partial_topic, # TODO REFACTOR REQUEST Tidy up in newer versions of octue to give to correct topic name
service_id=self.sruid,
question_uuid=str(question_id),
input_values=input_values,
input_manifest=input_manifest,
Expand Down
93 changes: 47 additions & 46 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "django-twined"
version = "0.5.1"
version = "0.6.0"
description = "A django app to manage octue services"
authors = ["Tom Clark <[email protected]>"]
license = "MIT"
Expand All @@ -23,7 +23,7 @@ packages = [{ include = "django_twined" },]
python = ">=3.9,<3.11"
django = ">=3.0,<4.0"
channels = ">=3.0,<4.0"
octue = ">=0.39.0,<1"
octue = ">=0.40.0,<1"
pika = "^1.2.0"
django-gcp = ">=0.7.3,<0.11"
django-jsoneditor = "^0.2.2"
Expand Down
10 changes: 1 addition & 9 deletions tests/test_models/test_service_revisions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Disables for testing:
# pylint: disable=missing-docstring

from django.test import TestCase, override_settings
from django.test import TestCase
from django_twined.models.service_revisions import ServiceRevision, service_revision_is_latest_semantic_version


Expand Down Expand Up @@ -74,14 +74,6 @@ def test_topic(self):

self.assertEqual(sr.topic, "octue.services.large-gibbons.gibbon-analyser.latest")

def test_topic_with_blank_namespace_and_tag(self):
"""Ensure that a service revision's topic is correct if there is no namespace or tag."""
with override_settings(TWINED_DEFAULT_NAMESPACE=""):
with override_settings(TWINED_DEFAULT_TAG=""):
sr = ServiceRevision.objects.create(project_name="gargantuan-gibbons", name="gibbon-analyser")

self.assertEqual(sr.topic, "octue.services.gibbon-analyser")

def test_create_with_defaults(self):
"""Ensure that default settings are read for creating default entries in the db"""
sr = ServiceRevision.objects.create(name="gibbon-analyser")
Expand Down

0 comments on commit 722051e

Please sign in to comment.