Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions servicex/databinder_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ class DeliveryEnum(str, Enum):
LocalCache = "LocalCache"
SignedURLs = "SignedURLs"

ServiceX: str = Field(..., alias="ServiceX")
Codegen: Optional[str] = None
OutputFormat: ResultFormat = (
Field(default=ResultFormat.root, pattern="^(parquet|root-file)$")
Expand All @@ -110,8 +109,13 @@ class DeliveryEnum(str, Enum):
OutFilesetName: str = 'servicex_fileset'


# TODO: ServiceXSpec class has a field name General and it clashes with the class name General
# when it is called General() to initialize default values for General class
_General = General


class ServiceXSpec(BaseModel):
General: General
General: _General = General()
Sample: List[Sample]
Definition: Optional[List] = None

Expand Down
14 changes: 11 additions & 3 deletions servicex/servicex_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@
logger = logging.getLogger(__name__)


def deliver(config: Union[ServiceXSpec, Mapping[str, Any]], config_path: Optional[str] = None):
def deliver(
config: Union[ServiceXSpec, Mapping[str, Any]],
config_path: Optional[str] = None,
servicex_name: Optional[str] = None
):
if isinstance(config, Mapping):
config = ServiceXSpec(**config)

Expand All @@ -59,7 +63,7 @@ def get_codegen(_sample: Sample, _general: General):
elif isinstance(_sample.Query, Query):
return _sample.Query.codegen

sx = ServiceXClient(backend=config.General.ServiceX, config_path=config_path)
sx = ServiceXClient(backend=servicex_name, config_path=config_path)
datasets = []
for sample in config.Sample:
if sample.Query:
Expand Down Expand Up @@ -141,7 +145,11 @@ def __init__(self, backend=None, url=None, config_path=None):
self.endpoints = self.config.endpoint_dict()

if not url and not backend:
backend = self.config.default_endpoint
if self.config.default_endpoint:
backend = self.config.default_endpoint
else:
# Take the first endpoint from servicex.yaml if default_endpoint is not set
backend = self.config.api_endpoints[0].name
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the config file guaranteed, via the parsing code, to have an endpoint?


if bool(url) == bool(backend):
raise ValueError("Only specify backend or url... not both")
Expand Down
19 changes: 19 additions & 0 deletions tests/example_config_default_endpoint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Default settings for servicex. This will point you to a developer end-point, that
# you've setup on your own machine (usually using k8's port-forward command):

api_endpoints:
- endpoint: http://localhost:5000
name: localhost

- endpoint: https://servicex-release-testing-4.servicex.ssl-hep.org
name: testing4
token: notreallyatoken

- endpoint: https://servicex.af.uchicago.edu
name: servicex-uc-af
token: notreallyatoken

# This is the path of the cache. The "/tmp" will be translated, platform appropriate, and
# the env variable USER will be replaced.
cache_path: /tmp/servicex_${USER}
default_endpoint: servicex-uc-af
29 changes: 1 addition & 28 deletions tests/test_databinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
def basic_spec(samples=None):
return {
"General": {
"ServiceX": "servicex",
"Codegen": "python",
},
"Sample": samples
Expand All @@ -19,7 +18,6 @@ def basic_spec(samples=None):
def test_load_config():
config = {
"General": {
"ServiceX": "servicex",
"Codegen": "python",
"Delivery": "LocalCache",
},
Expand Down Expand Up @@ -156,7 +154,6 @@ def test_submit_mapping(transformed_result, codegen_list):
from servicex import deliver
spec = {
"General": {
"ServiceX": "servicex-uc-af",
"Codegen": "uproot-raw",
},
"Sample": [
Expand All @@ -181,7 +178,6 @@ def test_yaml(tmp_path):
with open(path := (tmp_path / "python.yaml"), "w") as f:
f.write("""
General:
ServiceX: "servicex-uc-af"
OutputFormat: root-file
Delivery: LocalCache

Expand All @@ -206,7 +202,6 @@ def run_query(input_filenames=None):
with open(path := (tmp_path / "python.yaml"), "w") as f:
f.write("""
General:
ServiceX: "servicex-uc-af"
OutputFormat: root-file
Delivery: LocalCache

Expand All @@ -228,7 +223,6 @@ def test_yaml_include(tmp_path):
with open(tmp_path / "definitions.yaml", "w") as f1, \
open(path2 := (tmp_path / "parent.yaml"), "w") as f2:
f1.write("""
- &DEF_facility servicex-uc-af
- &DEF_query !Python |
def run_query(input_filenames=None):
return []
Expand All @@ -238,7 +232,6 @@ def run_query(input_filenames=None):
!include definitions.yaml

General:
ServiceX: *DEF_facility
OutputFormat: root-file
Delivery: LocalCache

Expand All @@ -256,9 +249,6 @@ def test_funcadl_query(transformed_result, codegen_list):
from servicex import deliver
from servicex.func_adl.func_adl_dataset import FuncADLQuery_Uproot
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -281,7 +271,6 @@ def test_query_with_codegen_override(transformed_result, codegen_list):
# first, with General override
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
"Codegen": "does-not-exist"
},
"Sample": [
Expand All @@ -304,9 +293,6 @@ def test_query_with_codegen_override(transformed_result, codegen_list):

# second, with sample-level override
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af"
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -331,9 +317,6 @@ def test_databinder_load_dict():
from servicex.func_adl.func_adl_dataset import FuncADLQuery_Uproot
from servicex.databinder.databinder_configuration import load_databinder_config
load_databinder_config({
"General": {
"ServiceX": "servicex-uc-af",
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -353,9 +336,6 @@ def run_query(input_filenames=None):
return []
"""
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -375,9 +355,6 @@ def test_uproot_raw_query(transformed_result, codegen_list):
from servicex import deliver
from servicex.uproot_raw.uproot_raw import UprootRawQuery
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -397,9 +374,6 @@ def test_fail_with_tree_on_non_funcadl_query():
from servicex.uproot_raw.uproot_raw import UprootRawQuery
with pytest.raises(ValueError):
ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
},
"Sample": [
{
"Name": "sampleA",
Expand All @@ -415,7 +389,6 @@ def test_generic_query(codegen_list):
from servicex.servicex_client import ServiceXClient
spec = ServiceXSpec.model_validate({
"General": {
"ServiceX": "servicex-uc-af",
"Codegen": "uproot-raw",
},
"Sample": [
Expand All @@ -428,7 +401,7 @@ def test_generic_query(codegen_list):
})
with patch('servicex.servicex_client.ServiceXClient.get_code_generators',
return_value=codegen_list):
sx = ServiceXClient(backend=spec.General.ServiceX, config_path='tests/example_config.yaml')
sx = ServiceXClient(config_path='tests/example_config.yaml')
query = sx.generic_query(dataset_identifier=spec.Sample[0].RucioDID,
codegen=spec.General.Codegen, query=spec.Sample[0].Query)
assert query.generate_selection_string() == "[{'treename': 'nominal'}]"
Expand Down
17 changes: 17 additions & 0 deletions tests/test_default_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from unittest.mock import patch

from servicex.servicex_client import ServiceXClient


def test_default_endpoint(codegen_list):
with patch('servicex.servicex_client.ServiceXClient.get_code_generators',
return_value=codegen_list):
sx = ServiceXClient(config_path="tests/example_config.yaml")
assert sx.servicex.url == "http://localhost:5000"


def test_first_endpoint(codegen_list):
with patch('servicex.servicex_client.ServiceXClient.get_code_generators',
return_value=codegen_list):
sx = ServiceXClient(config_path="tests/example_config_default_endpoint.yaml")
assert sx.servicex.url == "https://servicex.af.uchicago.edu"