aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
authortmartins <thigm85@gmail.com>2020-07-02 22:18:28 +0200
committertmartins <thigm85@gmail.com>2020-07-02 22:18:28 +0200
commit018520297d97b9573aeaf482b133abf98c86a0eb (patch)
treeb0ef9716221c07be95b8fe6412382ab3428c929a /python
parent1409de59e3b549424c7226c622e2b31a271e276a (diff)
write application files before local deployment
Diffstat (limited to 'python')
-rw-r--r--python/vespa/vespa/package.py43
-rw-r--r--python/vespa/vespa/templates/schema.txt2
-rw-r--r--python/vespa/vespa/templates/services.xml6
-rw-r--r--python/vespa/vespa/test_package.py20
4 files changed, 56 insertions, 15 deletions
diff --git a/python/vespa/vespa/package.py b/python/vespa/vespa/package.py
index 9c66defd4d9..4606b111f5e 100644
--- a/python/vespa/vespa/package.py
+++ b/python/vespa/vespa/package.py
@@ -1,5 +1,8 @@
+import os
from time import sleep
from typing import List, Mapping, Optional
+from tempfile import TemporaryDirectory
+from pathlib import Path
from jinja2 import Environment, PackageLoader, select_autoescape
import docker
@@ -138,7 +141,9 @@ class FieldSet(ToJson, FromJson["FieldSet"]):
class RankProfile(ToJson, FromJson["RankProfile"]):
- def __init__(self, name: str, first_phase: str) -> None:
+ def __init__(
+ self, name: str, first_phase: str, inherits: Optional[str] = None
+ ) -> None:
"""
Define a Vespa rank profile
@@ -147,20 +152,31 @@ class RankProfile(ToJson, FromJson["RankProfile"]):
"""
self.name = name
self.first_phase = first_phase
+ self.inherits = inherits
@staticmethod
def from_dict(mapping: Mapping) -> "RankProfile":
- return RankProfile(name=mapping["name"], first_phase=mapping["first_phase"])
+ return RankProfile(
+ name=mapping["name"],
+ first_phase=mapping["first_phase"],
+ inherits=mapping.get("inherits", None),
+ )
@property
def to_dict(self) -> Mapping:
map = {"name": self.name, "first_phase": self.first_phase}
+ if self.inherits is not None:
+ map.update({"inherits": self.inherits})
return map
def __eq__(self, other):
if not isinstance(other, self.__class__):
return False
- return self.name == other.name and self.first_phase == other.first_phase
+ return (
+ self.name == other.name
+ and self.first_phase == other.first_phase
+ and self.inherits == other.inherits
+ )
def __repr__(self):
return "{0}\n{1}".format(self.__class__.__name__, str(self.to_dict))
@@ -295,9 +311,10 @@ class ApplicationPackage(ToJson, FromJson["ApplicationPackage"]):
== "HTTP/1.1 200 OK"
)
- def deploy_locally(self, disk_folder, container_memory: str = "4G"):
+ def deploy_locally(self, disk_folder: str, container_memory: str = "4G"):
+
+ self.create_application_package_files(dir_path=disk_folder)
- # todo: use `with tempfile.TemporaryDirectory() as dirpath:` to create a temp dir and write app files there.
self.run_vespa_engine_container(
disk_folder=disk_folder, container_memory=container_memory
)
@@ -355,10 +372,22 @@ class ApplicationPackage(ToJson, FromJson["ApplicationPackage"]):
env.lstrip_blocks = True
schema_template = env.get_template("services.xml")
return schema_template.render(
- application_name=self.name,
- document_name=self.schema.name,
+ application_name=self.name, document_name=self.schema.name,
)
+ def create_application_package_files(self, dir_path):
+ Path(os.path.join(dir_path, "application/schemas")).mkdir(parents=True, exist_ok=True)
+ with open(
+ os.path.join(
+ dir_path, "application/schemas/{}.sd".format(self.schema.name)
+ ),
+ "w",
+ ) as f:
+ f.write(self.schema_to_text)
+ with open(os.path.join(dir_path, "application/hosts.xml"), "w") as f:
+ f.write(self.hosts_to_text)
+ with open(os.path.join(dir_path, "application/services.xml"), "w") as f:
+ f.write(self.services_to_text)
@staticmethod
def from_dict(mapping: Mapping) -> "ApplicationPackage":
diff --git a/python/vespa/vespa/templates/schema.txt b/python/vespa/vespa/templates/schema.txt
index a16e7c2775c..0849cbbad6f 100644
--- a/python/vespa/vespa/templates/schema.txt
+++ b/python/vespa/vespa/templates/schema.txt
@@ -17,7 +17,7 @@ schema {{ schema_name }} {
}
{% endfor %}
{% for key, value in rank_profiles.items() %}
- rank-profile {{ key }} {
+ rank-profile {{ key }}{% if value.inherits %} inherits {{ value.inherits }}{% endif %} {
{% if value.first_phase %}
first-phase {
expression: {{ value.first_phase }}
diff --git a/python/vespa/vespa/templates/services.xml b/python/vespa/vespa/templates/services.xml
index 0e5a05e180a..e287e53107d 100644
--- a/python/vespa/vespa/templates/services.xml
+++ b/python/vespa/vespa/templates/services.xml
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<services version="1.0">
- <container id="{{ application_name }}" version="1.0">
+ <container id="{{ application_name }}_container" version="1.0">
<search></search>
<document-processing></document-processing>
<document-api></document-api>
</container>
- <content id="{{ application_name }}" version="1.0">
+ <content id="{{ application_name }}_content" version="1.0">
<redundancy reply-after="1">1</redundancy>
<documents>
<document type="{{ document_name }}" mode="index"></document>
- <document-processing cluster="{{ application_name }}"></document-processing>
+ <document-processing cluster="{{ application_name }}_container"></document-processing>
</documents>
<nodes>
<node distribution-key="0" hostalias="node1"></node>
diff --git a/python/vespa/vespa/test_package.py b/python/vespa/vespa/test_package.py
index 0650bcdf400..e76e1cf3994 100644
--- a/python/vespa/vespa/test_package.py
+++ b/python/vespa/vespa/test_package.py
@@ -99,6 +99,12 @@ class TestRankProfile(unittest.TestCase):
self.assertEqual(rank_profile.first_phase, "bm25(title) + bm25(body)")
self.assertEqual(rank_profile, RankProfile.from_dict(rank_profile.to_dict))
+ def test_rank_profile_inherits(self):
+ rank_profile = RankProfile(name="bm25", first_phase="bm25(title) + bm25(body)", inherits="default")
+ self.assertEqual(rank_profile.name, "bm25")
+ self.assertEqual(rank_profile.first_phase, "bm25(title) + bm25(body)")
+ self.assertEqual(rank_profile, RankProfile.from_dict(rank_profile.to_dict))
+
class TestSchema(unittest.TestCase):
def test_schema(self):
@@ -152,7 +158,8 @@ class TestApplicationPackage(unittest.TestCase):
),
fieldsets=[FieldSet(name="default", fields=["title", "body"])],
rank_profiles=[
- RankProfile(name="default", first_phase="nativeRank(title, body)")
+ RankProfile(name="default", first_phase="nativeRank(title, body)"),
+ RankProfile(name="bm25", first_phase="bm25(title) + bm25(body)", inherits="default")
],
)
self.app_package = ApplicationPackage(name="test_app", schema=test_schema)
@@ -185,6 +192,11 @@ class TestApplicationPackage(unittest.TestCase):
" expression: nativeRank(title, body)\n" \
" }\n" \
" }\n" \
+ " rank-profile bm25 inherits default {\n" \
+ " first-phase {\n" \
+ " expression: bm25(title) + bm25(body)\n" \
+ " }\n" \
+ " }\n" \
"}"
self.assertEqual(self.app_package.schema_to_text, expected_result)
@@ -201,16 +213,16 @@ class TestApplicationPackage(unittest.TestCase):
def test_services_to_text(self):
expected_result = '<?xml version="1.0" encoding="UTF-8"?>\n' \
'<services version="1.0">\n' \
- ' <container id="test_app" version="1.0">\n' \
+ ' <container id="test_app_container" version="1.0">\n' \
' <search></search>\n' \
' <document-processing></document-processing>\n' \
' <document-api></document-api>\n' \
' </container>\n' \
- ' <content id="test_app" version="1.0">\n' \
+ ' <content id="test_app_content" version="1.0">\n' \
' <redundancy reply-after="1">1</redundancy>\n' \
' <documents>\n' \
' <document type="msmarco" mode="index"></document>\n' \
- ' <document-processing cluster="test_app"></document-processing>\n' \
+ ' <document-processing cluster="test_app_container"></document-processing>\n' \
' </documents>\n' \
' <nodes>\n' \
' <node distribution-key="0" hostalias="node1"></node>\n' \