From 3243eef54a4bd0a5cdcfb8bcb79ead3cd1a6300e Mon Sep 17 00:00:00 2001 From: Nico Vermaas <vermaas@astron.nl> Date: Tue, 15 Dec 2020 08:46:48 +0100 Subject: [PATCH] remove atdb_interface package --- README.md | 2 + atdb/taskdatabase/models.py | 1 - atdb/taskdatabase/serializers.py | 2 +- .../templates/taskdatabase/index.html | 2 +- atdb/taskdatabase/views.py | 1 - atdb_interface_pip/README.rst | 34 - .../atdb_interface.egg-info/PKG-INFO | 10 - .../atdb_interface.egg-info/SOURCES.txt | 10 - .../dependency_links.txt | 1 - .../atdb_interface.egg-info/entry_points.txt | 3 - .../atdb_interface.egg-info/requires.txt | 1 - .../atdb_interface.egg-info/top_level.txt | 1 - atdb_interface_pip/atdb_interface/__init__.py | 0 .../atdb_interface/atdb_interface.py | 825 ------------------ .../examples/arg00_post_new_dataproducts | 3 - atdb_interface_pip/build.sh | 9 - .../dist/atdb_interface-1.2.8.tar.gz | Bin 8316 -> 0 bytes .../dist/atdb_interface-1.2.9.tar.gz | Bin 8549 -> 0 bytes atdb_interface_pip/setup.py | 21 - atdb_interface_pip/upload_to_nexus.sh | 35 - 20 files changed, 4 insertions(+), 957 deletions(-) delete mode 100644 atdb_interface_pip/README.rst delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/PKG-INFO delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/SOURCES.txt delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/dependency_links.txt delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/entry_points.txt delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/requires.txt delete mode 100644 atdb_interface_pip/atdb_interface.egg-info/top_level.txt delete mode 100644 atdb_interface_pip/atdb_interface/__init__.py delete mode 100644 atdb_interface_pip/atdb_interface/atdb_interface.py delete mode 100644 atdb_interface_pip/atdb_interface/examples/arg00_post_new_dataproducts delete mode 100644 atdb_interface_pip/build.sh delete mode 100644 atdb_interface_pip/dist/atdb_interface-1.2.8.tar.gz delete mode 100644 atdb_interface_pip/dist/atdb_interface-1.2.9.tar.gz delete mode 100644 atdb_interface_pip/setup.py delete mode 100644 atdb_interface_pip/upload_to_nexus.sh diff --git a/README.md b/README.md index faeee5c1..66f4d98e 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ Deployment Diagram: > export DOCKER_BUILD_DIR=$HOME/my_docker/atdb-ldv/atdb-ldv/atdb > export DOCKER_COMPOSE_DIR=$DOCKER_BUILD_DIR/docker + > cd $DOCKER_BUILD_DIR + > git pull > cd $DOCKER_COMPOSE_DIR > docker-compose -p atdb up -d diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py index c69d4727..66d48412 100644 --- a/atdb/taskdatabase/models.py +++ b/atdb/taskdatabase/models.py @@ -111,7 +111,6 @@ class Observation(TaskObject): end_band = models.IntegerField(null=True) # ARTS SC4 - process_triggers = models.BooleanField(default=False) beams = models.CharField(max_length=255, default="0..39") quality = models.CharField(max_length=30, default="unknown") diff --git a/atdb/taskdatabase/serializers.py b/atdb/taskdatabase/serializers.py index df64b011..0b0a4c74 100644 --- a/atdb/taskdatabase/serializers.py +++ b/atdb/taskdatabase/serializers.py @@ -57,7 +57,7 @@ class ObservationSerializer(serializers.ModelSerializer): 'generated_dataproducts','telescopes', 'data_location', 'irods_collection','node','control_parameters', 'skip_auto_ingest','observing_mode','science_mode','parset_location', - 'par_file_name','number_of_bins','start_band','end_band','process_triggers','beams', 'delay_center_offset', + 'par_file_name','number_of_bins','start_band','end_band','beams', 'delay_center_offset', 'locality_policy','max_lifetime_on_disk','quality','science_observation','filler','ingest_progress', 'timestamp_starting','timestamp_running','timestamp_completing', 'timestamp_ingesting','timestamp_archived','timestamp_aborted','timestamp_ingest_error') diff --git a/atdb/taskdatabase/templates/taskdatabase/index.html b/atdb/taskdatabase/templates/taskdatabase/index.html index da4c482f..fa35e9ae 100644 --- a/atdb/taskdatabase/templates/taskdatabase/index.html +++ b/atdb/taskdatabase/templates/taskdatabase/index.html @@ -46,7 +46,7 @@ </div> {% include 'taskdatabase/pagination.html' %} </div> - <p class="footer"> Version 2.0.0 (11 dec 2020)</p> + <p class="footer"> Version 2.0.0 (15 dec 2020 - 08:00)</p> <script type="text/javascript"> (function(seconds) { diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py index 7ab9e6d3..4f216d30 100644 --- a/atdb/taskdatabase/views.py +++ b/atdb/taskdatabase/views.py @@ -48,7 +48,6 @@ class ObservationFilter(filters.FilterSet): 'irods_collection': ['exact', 'icontains'], 'node': ['exact', 'in'], 'skip_auto_ingest': ['exact'], - 'process_triggers': ['exact'], 'beams': ['exact', 'icontains'], 'delay_center_offset': ['exact', 'icontains'], 'quality': ['exact', 'icontains'], diff --git a/atdb_interface_pip/README.rst b/atdb_interface_pip/README.rst deleted file mode 100644 index ee327091..00000000 --- a/atdb_interface_pip/README.rst +++ /dev/null @@ -1,34 +0,0 @@ -atdb_interface -============== -This module contains a service that run standalone and interact with the Apertif Task Database REST API. - -See 'atdb_interface -h' for help and 'atdb_interface -e' for examples. - -This package is required when using atdb_services - -Installing -^^^^^^^^^^ -To install a version from Nexus repository use:: - - > pip install <<nexus url>> --upgrade - or download and install the tarball, - > pip install atdb_interface.tar.gz --upgrade - -Within the development environment such as with PyCharm one can install the package within the virtualenv with which -PyCharm is configured. To avoid uninstall and install after each code change pip can install packages within development -mode:: - - (.env) > pip install -e ..project../atdb_interface_pip --upgrade - -This will install the package with soft links to the original code, such that one gets immediate refresh within PyCharm, -which is used for refactoring, code completion, imports etc. - -Uninstalling -^^^^^^^^^^^^ -Uninstall is trivial using the command (watch out for the '-'):: - - > pip uninstall atdb-interface - -or without confirmation:: - - > pip uninstall --yes atdb-interface \ No newline at end of file diff --git a/atdb_interface_pip/atdb_interface.egg-info/PKG-INFO b/atdb_interface_pip/atdb_interface.egg-info/PKG-INFO deleted file mode 100644 index b7592a3f..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/PKG-INFO +++ /dev/null @@ -1,10 +0,0 @@ -Metadata-Version: 1.0 -Name: atdb-interface -Version: 1.2.9 -Summary: ATDB interface -Home-page: https://www.astron.nl/wsrt/wiki/doku.php?id=atdb:atdb_interface -Author: Nico Vermaas - Astron -Author-email: vermaas@astron.nl -License: BSD -Description: UNKNOWN -Platform: UNKNOWN diff --git a/atdb_interface_pip/atdb_interface.egg-info/SOURCES.txt b/atdb_interface_pip/atdb_interface.egg-info/SOURCES.txt deleted file mode 100644 index e4282e34..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/SOURCES.txt +++ /dev/null @@ -1,10 +0,0 @@ -README.rst -setup.py -atdb_interface/__init__.py -atdb_interface/atdb_interface.py -atdb_interface.egg-info/PKG-INFO -atdb_interface.egg-info/SOURCES.txt -atdb_interface.egg-info/dependency_links.txt -atdb_interface.egg-info/entry_points.txt -atdb_interface.egg-info/requires.txt -atdb_interface.egg-info/top_level.txt \ No newline at end of file diff --git a/atdb_interface_pip/atdb_interface.egg-info/dependency_links.txt b/atdb_interface_pip/atdb_interface.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/atdb_interface_pip/atdb_interface.egg-info/entry_points.txt b/atdb_interface_pip/atdb_interface.egg-info/entry_points.txt deleted file mode 100644 index a5448a6f..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -atdb_interface = atdb_interface.atdb_interface:main - diff --git a/atdb_interface_pip/atdb_interface.egg-info/requires.txt b/atdb_interface_pip/atdb_interface.egg-info/requires.txt deleted file mode 100644 index f2293605..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/requires.txt +++ /dev/null @@ -1 +0,0 @@ -requests diff --git a/atdb_interface_pip/atdb_interface.egg-info/top_level.txt b/atdb_interface_pip/atdb_interface.egg-info/top_level.txt deleted file mode 100644 index 643d97a1..00000000 --- a/atdb_interface_pip/atdb_interface.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -atdb_interface diff --git a/atdb_interface_pip/atdb_interface/__init__.py b/atdb_interface_pip/atdb_interface/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/atdb_interface_pip/atdb_interface/atdb_interface.py b/atdb_interface_pip/atdb_interface/atdb_interface.py deleted file mode 100644 index 44cb7b02..00000000 --- a/atdb_interface_pip/atdb_interface/atdb_interface.py +++ /dev/null @@ -1,825 +0,0 @@ -#!/usr/bin/python3 -import sys -import os -import requests -import json -import argparse -import datetime - -from pkg_resources import get_distribution -pkg_version = get_distribution('atdb_interface').version -""" -atdb_interface.py : a commandline tool to interface with the ATDB REST API. -:author Nico Vermaas - Astron -""" -LAST_UPDATE = "31 oct 2019" - -# ==================================================================== - -# The request header -ATDB_HEADER = { - 'content-type': "application/json", - 'cache-control': "no-cache", - 'authorization': "Basic YWRtaW46YWRtaW4=" -} - -DEFAULT_BACKEND_HOST = "http://atdb-test.astron.nl/atdb" -ATDB_HOST_DEV = "http://localhost:8000/atdb/" # your local development environment with Django webserver -ATDB_HOST_VM = "http://192.168.22.25/atdb" # your local Ansible/Vagrant setup for testing -ATDB_HOST_ACC = "http://192.168.22.25/atdb" # your local Ansible/Vagrant acceptance setup -ATDB_HOST_TEST = "http://atdb-test.astron.nl/atdb" # the atdb test environment -ATDB_HOST_PROD = "http://atdb.astron.nl/atdb" # the atdb production environment. - -TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" - - -class ATDB: - """ - Calibrators class, use to parse SIP and update the backend database - through REST API calls. - """ - def __init__(self, host, verbose=False): - """ - Constructor. - :param host: the host name of the backend. - :param username: The username known in Django Admin. - :param verbose: more information runtime. - :param header: Request header for Atdb REST requests with token authentication. - """ - # accept some presets to set host to dev, test, acc or prod - self.host = host - if self.host=='dev': - self.host = DEFAULT_BACKEND_HOST - elif self.host=='vm': - self.host = ATDB_HOST_VM - elif self.host=='test': - self.host = ATDB_HOST_TEST - elif self.host=='acc': - self.host = ATDB_HOST_ACC - elif self.host=='prod': - self.host = ATDB_HOST_PROD - if not self.host.endswith('/'): - self.host += '/' - - self.verbose = verbose - self.header = ATDB_HEADER - - def verbose_print(self, info_str): - """ - Print info string if verbose is enabled (default False) - :param info_str: String to print - """ - if self.verbose: - timestamp = datetime.datetime.now().strftime(TIME_FORMAT) - print(str(timestamp)+ ' - '+info_str) - - # === Backend requests ================================================================================ - @staticmethod - def reconstruct_beams_obsolete(payload_string): - """ - Normally, to translate the specification string to a json payload that the http requests understand, - all substrings like 'a,b,c' are replaced with "a","b","c". But this should not be done for the beams list, - which is given as something like beams=1..10,11,12 or beams=[1..10,11,12] in the specification. - So this function reconstructs that stting. (a bit ugly, but as usual time constraints force me to cut a corner). - :param payload_string: - :return: - """ - - # find the part where the 'beams' are already converted to a messy string: "beams": ""beams" : "1..10" , "11" , "12" , "new_status"", "new_status" - start = payload_string.find('"beams"') + 10 - - if (start>=10): - # if no beams were found, then ignore this step - end = payload_string.find('"new_status"') -3 - - # save the before and after parts of the string - before = payload_string[0:start] - after = payload_string[end:] - - # extract the middle part that needs to be changed: 1..10" , "11" , "12 - middle = payload_string[start:end] - - # remove all " and spaces, and surround it with "" again. - middle = middle.replace("\"","") - middle = middle.replace(" ","") - middle = '"' + middle + '"' - - # reconstruct the payload string - payload_string = before + middle + after - - return payload_string - - - def jsonifyPayload_obsolete(self, payload): - """ - {name=WSRTA180223003_B003.MS,filename=WSRTA180223003_B003.MS} => - {"name" : "WSRTA180223003_B003.MS" , "filename" : "WSRTA180223003_B003.MS"} - :param payload: - :return: payload_string - """ - - payload_string = str(payload).replace("{","{\"") - payload_string = payload_string.replace("}", "\"}") - payload_string = payload_string.replace("=", "\" : \"") - payload_string = payload_string.replace(",", "\" , \"") - - # reconstruct the lists by moving the brackets outside the double quotes - payload_string = payload_string.replace("\"[", "[\"") - payload_string = payload_string.replace("]\"", "\"]") - payload_string = payload_string.replace("/,", "/\",\"") - payload_string = payload_string.replace("u\"", "\"") - - #payload_string = json.dumps(payload) - # ugly: reconstruct beams string - payload_string = self.reconstruct_beams_obsolete(payload_string) - - self.verbose_print("payload_string: [" + payload_string+"]") - return payload_string - - def encodePayload(self, payload): - """ - - The POST body does not simply accept a payload dict, it needs to be translated to a string with some - peculiarities - :param payload: - :return: payload_string - """ - - payload_string = str(payload).replace("'","\"") - #payload_string = payload_string.replace(",", ",\n") - - # reconstruct the lists by moving the brackets outside the double quotes - payload_string = payload_string.replace("\"[", "[\"") - payload_string = payload_string.replace("]\"", "\"]") - payload_string = payload_string.replace("/,", "/\",\"") - payload_string = payload_string.replace("u\"", "\"") - - self.verbose_print("The payload_string: [" + payload_string+"]") - return payload_string - - - def GET_TaskObjectByTaskId(self, resource, taskid): - """ - Do a http GET request to the alta backend to find the Observation with the given runId - :runId runId: - """ - - url = self.host + resource - # create the querystring, external_ref is the mapping of this element to the alta datamodel lookup field - querystring = {"taskID": taskid} - - response = requests.request("GET", url, headers=self.header, params=querystring) - self.verbose_print("[GET " + response.url + "]") - - try: - json_response = json.loads(response.text) - results = json_response["results"] - taskobject = results[0] - return taskobject - except: - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - # ------------------------------------------------------------------------------# - # Main User functions # - # ------------------------------------------------------------------------------# - - - def do_GET_ID(self, key, value): - """ - Get the id based on a field value of a resource. This is a generic way to retrieve the id. - :param resource: contains the resource, for example 'observations', 'dataproducts' - :param field: the field to search on, this will probably be 'name' or 'filename' - :param value: the value of the 'field' to search on. - :return id - """ - - # split key in resource and field - params = key.split(":") - resource = params[0] - field = params[1] - - url = self.host + resource + "?" + field + "=" + value - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - try: - json_response = json.loads(response.text) - results = json_response["results"] - result = results[0] - id = result['id'] - return id - except: - return '-1' - #raise (Exception("ERROR: " + response.url + " not found.")) - - - def do_GET(self, key, id, taskid): - """ - Do a http GET request to the ATDB backend to find the value of one field of an object - :param key: contains the name of the resource and the name of the field separated by a colon. - :param id: the database id of the object. - :param taskid (optional): when the taskid (of an activity) is known it can be used instead of id. - """ - - # split key in resource and field - params = key.split(":") - resource = params[0] - field = params[1] - - if taskid!=None: - taskObject = self.GET_TaskObjectByTaskId(resource, taskid) - id = taskObject['id'] - - if id==None: - # give up and throw an exception. - raise (Exception("ERROR: no valid 'id' or 'taskid' provided")) - - url = self.host + resource + "/" + str(id) + "/" - self.verbose_print(('url: ' + url)) - - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - try: - json_response = json.loads(response.text) - value = json_response[field] - return value - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise ( - Exception("ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_GET_LIST_page(self, key, query, page): - """ - get a list of objects that match the query. (oiginal do_GET_LIST function was left intact for - backward compatibility reasons). - The backend is paginated, so you may want to indicate which page you want to retrieve. - The function returns a list of values of the field indicated in 'key'. - The function also returns the total count, so you can calculate the number of pages to retrieve - :param key: - :param query: - :param page: - :return: - """ - - self.verbose_print("do_GET_LIST(" + key + "," + query + ")") - # split key in resource and field - params = key.split(":") - resource = params[0] - field = params[1] - - url = self.host + resource + "?" + str(query) - if (page != None): - url = url + "&page=" + str(page) - - # self.verbose_print("url = " + url) - - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - try: - json_response = json.loads(response.text) - results = json_response["results"] - # results = json.loads(response.text) - # loop through the list of results and extract the requested field (probably taskID), - # and add it to the return list. - list = [] - for result in results: - value = result[field] - list.append(value) - - count = json_response["count"] - - try: - # return the next page number, if available - next = json_response["next"] - pos_start = next.find("page") - pos_end = next.find("&",pos_start) - page_number = next[pos_start+5:pos_end] - - except: - page_number = 0 - - return list, count, page_number - - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - # python atdb_interface.py -o GET_LIST --key observations:taskID --query status=valid - def do_GET_LIST(self, key, query): - - self.verbose_print("do_GET_LIST(" + key + "," + query + ")") - # split key in resource and field - params = key.split(":") - resource = params[0] - field = params[1] - - url = self.host + resource + "?" + str(query) - - # self.verbose_print("url = " + url) - - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - try: - json_response = json.loads(response.text) - results = json_response["results"] - #results = json.loads(response.text) - # loop through the list of results and extract the requested field (probably taskID), - # and add it to the return list. - list = [] - for result in results: - value = result[field] - list.append(value) - - return list - - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_GET_NextTaskID(self, timestamp, taskid_postfix=""): - """ - :param timestamp: timestamp on which the taskid is based - :param taskid_postfix: optional addition to the taskid, - like when taskid_postfix="_IMG" the taskid will become "190405001_IMG" - :return: taskid - """ - - self.verbose_print("do_GET_NextTaskID(" + str(timestamp) + ")") - - # construct the url - url = self.host + "get_next_taskid?timestamp=" + str(timestamp)+"&taskid_postfix="+taskid_postfix - - # do the request to the ATDB backend - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - # parse the response - try: - json_response = json.loads(response.text) - taskID = json_response["taskID"] - return taskID - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_GET_Observation(self, taskid): - """ - Do a http request to the ATDB backend get all the observation parameters in the response - :param taskid - """ - self.verbose_print("do_GET_Observation(" + taskid + ")") - - # construct the url - url = self.host + "observations?taskID=" + str(taskid) - - # do the request to the ATDB backend - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - - # parse the response - try: - json_response = json.loads(response.text) - results = json_response["results"] - observation = results[0] - return observation - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - - def do_GET_NextObservation(self, my_status, observing_mode, datawriter): - """ - Do a http request to the ATDB backend get the next observation of a given status and observing_mode - :param my_status: status to search for (probably 'scheduled') - :param observing_mode: imaging or arts - :param taskid (optional): when the taskid (of an activity) is known it can be used instead of id. - """ - self.verbose_print("do_GET_NextObservation(" + my_status + "," + observing_mode + "," + datawriter + ")") - - # construct the url - url = self.host + "get_next_observation?my_status=" + str(my_status) + "&observing_mode=" + str(observing_mode) + "&datawriter=" + str(datawriter) - - # do the request to the ATDB backend - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - - # parse the response - try: - json_response = json.loads(response.text) - taskID = json_response["taskID"] - minutes_left = json_response["minutes_left"] - return taskID, minutes_left - except Exception as err: - self.verbose_print("Exception : " + str(err)) - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_PUT(self, key='observations', id=None, value=None, taskid=None): - """ - PUT a value to an existing field of a resource (table). - :param key: contains the name of the resource and the name of the field separated by a dot. observations.description - :param id: the database id of the object. - :param value: the value that has to be PUT in the key. If omitted, an empty put will be done to trigger the signals. - :param taskid (optional): when the taskid of an observation is known it can be used instead of id. - """ - - # split key in resource and field - if key.find(':')>0: - params = key.split(":") - resource = params[0] - field = params[1] - else: - resource = key - field = None - - if taskid!=None: - taskObject = self.GET_TaskObjectByTaskId(resource, taskid) - id = taskObject['id'] - - url = self.host + resource + "/" + str(id) + "/" - if id==None: - raise (Exception("ERROR: no valid 'id' or 'taskid' provided")) - - payload = {} - if field!=None: - payload[field]=value - payload = self.encodePayload(payload) - try: - response = requests.request("PUT", url, data=payload, headers=self.header) - self.verbose_print("[PUT " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - except: - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - # do_PUT_LIST(key = observations:new_status, taskid = 180223003, value = valid) - def do_PUT_LIST(self, key='dataproducts', taskid=None, value=None): - """ - PUT a value to an existing field of resource (table). - :param key: contains the name of the resource and the name of the field separated by a colon. observations:new_status - :param value: the value that has to be PUT in the key. If omitted, an empty put will be done to trigger the signals. - :param taskid: the value is PUT to all objects with the provided taskid - """ - - # split key in resource and field - if key.find(':')>0: - params = key.split(":") - resource = params[0] - field = params[1] - else: - resource = key - field = None - - get_key = resource+':id' - get_query= 'taskID='+taskid - ids = self.do_GET_LIST(get_key,get_query) - - for id in ids: - url = self.host + resource + "/" + str(id) + "/" - self.verbose_print(('url: ' + url)) - - payload = {} - if field!=None: - payload[field]=value - payload = self.encodePayload(payload) - try: - response = requests.request("PUT", url, data=payload, headers=self.header) - self.verbose_print("[PUT " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - except: - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_POST_obsolete(self, resource, payload): - """ - POST a payload to a resource (table). This creates a new object (observation or dataproduct) - This is the old function, left for backward compatibility. Use 'do_POST_json()' now. - :param resource: contains the resource, for example 'observations', 'dataproducts' - :param payload: the contents of the object to create in json format - """ - - url = self.host + resource + '/' - self.verbose_print(('payload: ' + payload)) - - payload = self.jsonifyPayload_obsolete(payload) - try: - response = requests.request("POST", url, data=payload, headers=self.header) - self.verbose_print("[POST " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - if not (response.status_code==200 or response.status_code==201): - raise Exception() - except Exception: - raise (Exception("ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_POST_json(self, resource, payload): - """ - POST a payload to a resource (table). This creates a new object (observation or dataproduct) - This function replaces the old do_POST function that still needed to convert the json content in a very ugly - :param resource: contains the resource, for example 'observations', 'dataproducts' - :param payload: the contents of the object to create in json format - """ - - url = self.host + resource + '/' - self.verbose_print(('payload: ' + payload)) - - try: - response = requests.request("POST", url, data=payload, headers=self.header) - self.verbose_print("[POST " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - if not (response.status_code==200 or response.status_code==201): - raise Exception() - except Exception: - raise (Exception("ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - def do_POST_dataproducts(self, taskid, dataproducts): - """ - POST (create) a batch of dataproducts for the (observation) with the given taskid. - This is done with a custom made http request to the ATDB backend - :param taskid: taskid of the observation - :param dataproducts: json list of dataproducts to be added to the provided taskid - """ - - # is 'dataproducts' a valid list of dataproducts? - try: - number_of_dataproducts = len(dataproducts) - self.verbose_print("do_POST_dataproducts(" + taskid + "," + str(number_of_dataproducts) + ")") - except Exception as err: - raise (Exception( - "ERROR: " + str(err))) - - # construct the url - url = self.host + "post_dataproducts?taskID=" + str(taskid) - - # encode the dictonary as proper json - payload = self.encodePayload(dataproducts) - try: - # do a POST request to the 'post_dataproducts' resource of the ATDB backend - response = requests.request("POST", url, data=payload, headers=self.header) - self.verbose_print("[POST " + response.url + "]") - - # if anything went wrong, throw an exception. - if not (response.status_code==200 or response.status_code==201): - raise Exception(str(response.status_code) + " - " + str(response.reason)) - except Exception as err: - raise (Exception("ERROR: " + str(err))) - - # if it has all succeeded, give back the taskid as an indication of success - return taskid - - - def do_DELETE(self, resource, id): - """ - Do a http DELETE request to the ATDB backend - """ - if id == None: - raise (Exception("ERROR: no valid 'id' provided")) - - # if a range of ID's is given then do multiple deletes - if (str(id).find('..')>0): - self.verbose_print("Deleting " + str(id) + "...") - s = id.split('..') - start = int(s[0]) - end = int(s[1]) + 1 - else: - # just a single delete - start = int(id) - end = int(id) + 1 - - for i in range(start,end): - url = self.host + resource + "/" + str(i) + "/" - - try: - response = requests.request("DELETE", url, headers=self.header) - self.verbose_print("[DELETE " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - except: - raise (Exception("ERROR: deleting " + url + "failed." + response.url)) - - - def do_setquality(self, key='observations', id=None, value=None, taskid=None): - """ - PUT a value to the quality field and call the setquality functionality to transmit the value to ALTA. - The interface of this function is as close as possible to the regular do_PUT function to avoid confusion. - :param key: contains the name of the resource and the name of the field separated by a dot. observations.description - :param id: the database id of the object. - :param value: the value that has to be PUT in the key. If omitted, an empty put will be done to trigger the signals. - :param taskid (optional): when the taskid of an observation is known it can be used instead of id. - """ - - # split key in resource and field - if key.find(':') > 0: - params = key.split(":") - resource = params[0] - field = params[1] - else: - resource = key - field = "quality" - - if taskid != None: - taskObject = self.GET_TaskObjectByTaskId(resource, taskid) - id = taskObject['id'] - - # this operation requires to http requests... - - # the first request is a PUT to ATDB to set the Quality field - url = self.host + resource + "/" + str(id) + "/" - if id==None: - raise (Exception("ERROR: no valid 'id' or 'taskid' provided")) - - payload = {} - if field!=None: - payload[field]=value - payload = self.encodePayload(payload) - try: - response = requests.request("PUT", url, data=payload, headers=self.header) - self.verbose_print("[PUT " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - except: - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str(response.content))) - - - # the second request is a GET to ATDB's 'setquality' resource, which will trigger a call to ALTA - url = self.host + resource + "/" + str(id) + "/setquality/" + value + "/1" - - try: - response = requests.request("GET", url, headers=self.header) - self.verbose_print("[GET " + response.url + "]") - self.verbose_print("Response: " + str(response.status_code) + ", " + str(response.reason)) - except: - raise (Exception( - "ERROR: " + str(response.status_code) + ", " + str(response.reason) + ', ' + str( - response.content))) - - - -# ------------------------------------------------------------------------------# -# Module level functions # -# ------------------------------------------------------------------------------# -def exit_with_error(message): - """ - Exit the code for an error. - :param message: the message to print. - """ - print(message) - sys.exit(-1) - - -def get_arguments(parser): - """ - Gets the arguments with which this application is called and returns - the parsed arguments. - If a parfile is give as argument, the arguments will be overrided - The args.parfile need to be an absolute path! - :param parser: the argument parser. - :return: Returns the arguments. - """ - args = parser.parse_args() - if args.parfile: - args_file = args.parfile - if os.path.exists(args_file): - parse_args_params = ['@' + args_file] - # First add argument file - # Now add command-line arguments to allow override of settings from file. - for arg in sys.argv[1:]: # Ignore first argument, since it is the path to the python script itself - parse_args_params.append(arg) - print(parse_args_params) - args = parser.parse_args(parse_args_params) - else: - raise (Exception("Can not find parameter file " + args_file)) - return args -# ------------------------------------------------------------------------------# -# Main # -# ------------------------------------------------------------------------------# - - -def main(): - """ - The main module. - """ - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument("-v","--verbose", default=False, help="More information at run time.",action="store_true") - parser.add_argument("--host", nargs="?", default='test', help="Presets are 'dev', 'vm', 'test', 'acc', 'prod'. Otherwise give a full url like https://atdb.astron.nl/atdb") - parser.add_argument("--version", default=False, help="Show current version of this program", action="store_true") - parser.add_argument("--operation","-o", default="GET", help="GET, GET_ID, GET_LIST, POST, PUT, DELETE. Note that these operations will only work if you have the proper rights in the ALTA user database.") - parser.add_argument("--id", default=None, help="id of the object to PUT to.") - parser.add_argument("-t", "--taskid", nargs="?", default=None, help="Optional taskID which can be used instead of '--id' to lookup Observations or Dataproducts.") - parser.add_argument("--key", default="observations.title", help="resource.field to PUT a value to. Example: observations.title") - parser.add_argument("--query", "-q", default="taskID=180223003", help="Query to the REST API") - parser.add_argument("--value", default="", help="value to PUT in the resource.field. If omitted it will PUT the object without changing values, but the built-in 'signals' will be triggered.") - parser.add_argument("--payload", "-p", default="{}", help="Payload in json for the POST operation. To create new Observations or Dataproducts. (see examples)") - parser.add_argument("--show_examples", "-e", default=False, help="Show some examples",action="store_true") - parser.add_argument('--parfile', nargs='?', type=str, help='Parameter file') - - args = get_arguments(parser) - try: - atdb = ATDB(args.host, args.verbose) - - if (args.show_examples): - - print('atdb_interface.py version = '+ pkg_version + " (last updated " + LAST_UPDATE + ")") - print('---------------------------------------------------------------------------------------------') - print() - print('--- basic examples --- ') - print() - print("Show the 'status' for Observation with taskID 180720003") - print("> atdb_interface -o GET --key observations:my_status --taskid 180223003") - print() - print("GET the ID of Observation with taskID 180223003") - print("> atdb_interface -o GET_ID --key observations:taskID --value 180223003") - print() - print("GET the ID of Dataproduct with name WSRTA180223003_ALL_IMAGE.jpg") - print("> atdb_interface -o GET_ID --key dataproducts:name --value WSRTA180223003_ALL_IMAGE.jpg") - print() - print("GET the 'status' for Dataproduct with ID = 45") - print("> atdb_interface -o GET --key dataproducts:my_status --id 45") - print() - print("PUT the 'status' of dataproduct with ID = 45 on 'copied'") - print("> atdb_interface -o PUT --key dataproducts:new_status --id 45 --value copied") - print() - print("PUT the 'status' of observation with taskID 180720003 on 'valid'") - print("> atdb_interface -o PUT --key observations:new_status --value valid --taskid 180223003") - print() - print("DELETE dataproduct with ID = 46 from the database (no files will be deleted).") - print("> atdb_interface -o DELETE --key dataproducts --id 46") - print() - print("DELETE dataproducts with ID's ranging from 11..15 from the database (no files will be deleted).") - print("> atdb_interface -o DELETE --key dataproducts --id 11..15 -v") - print() - print('--- advanced examples --- ') - print() - print("GET_LIST of taskIDs for observations with status = 'valid'") - print("> atdb_interface -o GET_LIST --key observations:taskID --query status=valid") - print() - print("GET_LIST of IDs for dataproducts with status = 'invalid'") - print("> atdb_interface -o GET_LIST --key dataproducts:id --query status=invalid") - print() - print("PUT the field 'new_status' on 'valid' for all dataproducts with taskId = '180816001'") - print("> atdb_interface -o PUT_LIST --key dataproducts:new_status --taskid 180816001 --value valid") - print('---------------------------------------------------------------------------------------------') - return - - if (args.version): - print('--- atdb_interface.py version = '+ pkg_version + " (last updated " + LAST_UPDATE + ") ---") - return - - if (args.operation=='GET'): - result = atdb.do_GET(key=args.key, id=args.id, taskid=args.taskid) - print(result) - - if (args.operation == 'GET_ID'): - result = atdb.do_GET_ID(key=args.key, value=args.value) - print(result) - - if (args.operation == 'GET_LIST'): - result = atdb.do_GET_LIST(key=args.key, query=args.query) - print(result) - - if (args.operation=='PUT_LIST'): - atdb.do_PUT_LIST(key=args.key, taskid=args.taskid, value=args.value) - - if (args.operation=='PUT'): - atdb.do_PUT(key=args.key, id=args.id, value=args.value, taskid=args.taskid) - - if (args.operation=='SET_QUALITY'): - atdb.do_setquality(key=args.key, id=args.id, value=args.value, taskid=args.taskid) - - if (args.operation=='POST'): - atdb.do_POST_json(resource=args.key, payload=args.payload) - - if (args.operation=='DELETE'): - atdb.do_DELETE(resource=args.key, id=args.id) - - except Exception as exp: - exit_with_error(str(exp)) - - sys.exit(0) - - -if __name__ == "__main__": - main() - diff --git a/atdb_interface_pip/atdb_interface/examples/arg00_post_new_dataproducts b/atdb_interface_pip/atdb_interface/examples/arg00_post_new_dataproducts deleted file mode 100644 index 3f481592..00000000 --- a/atdb_interface_pip/atdb_interface/examples/arg00_post_new_dataproducts +++ /dev/null @@ -1,3 +0,0 @@ ---operation=POST ---key=dataproducts ---payload={name=WSRTA180223003_B003.MS,filename=WSRTA180223003_B003.MS,description=WSRTA180223003_B003.MS,dataproduct_type=visibility,taskID=180223003,size=54321,quality=raw,new_status=defined,new_location=datawriter} diff --git a/atdb_interface_pip/build.sh b/atdb_interface_pip/build.sh deleted file mode 100644 index ac4426a8..00000000 --- a/atdb_interface_pip/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# This script make a source distribution for the pip installable package in the current folder -echo "Build a source distribution for ATDB interface" -python --version -# Explicit give format otherwise a zip is created (Windows?) -python setup.py sdist --formats=gztar - -# Next command will not close the window, can be handy if something goes wrong -#exec $SHELL \ No newline at end of file diff --git a/atdb_interface_pip/dist/atdb_interface-1.2.8.tar.gz b/atdb_interface_pip/dist/atdb_interface-1.2.8.tar.gz deleted file mode 100644 index a431d44d98b0b9097fe70af666c42518a3342e01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8316 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 G$N&J{s5uY- diff --git a/atdb_interface_pip/dist/atdb_interface-1.2.9.tar.gz b/atdb_interface_pip/dist/atdb_interface-1.2.9.tar.gz deleted file mode 100644 index e27e0114c2d8a7aa96fe2c2352fd73bdd183e974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8549 zcmV-rA)4MFiwFo<7uR0`|72-%bX;L{WMW@wZggdGW?^GxEio=KE;%lAVR8WNJ!x~> zMza3QD*uNGTnWfB36VMz)}y_0q$H~KwU(UJKE;m(5km?w2rxJ#b5s8Bue;~K;2=dE zmYp?GiA92Q^z`&KJv}{c>YWY!Fy-;s9q~@j*>rx`cyPB*7oNSnJ^Bkz`7eF$ZSC#u z?Dn>Hw%~nlb9b}*fbBfEhbK!?H)iZk25AoNZ}PZx^Iv?qasTtbv$M0gp8qdp{)=Co z+585m+1=f(pZ{KW2c{e5e`jZRXKND(;6Zn@2jw5I?t1<|`Sa+TjVy^b&irs=Hc!u^ zaI4`@XHlH8WS*#xk^U6(KQo@B`uiVA6spf|Jej$1!qs=rO?m21d809oqbZxcpA2K3 zL|HuI36o_eJRN#|lE(g7mio{Zmb&0^0-xES@^jNJ(xTmRWZ{NoS&a&zvOaU!D4I^) z&<p&KvowkV_=o92?9xxqS$fXd{>i~J_U7>TgzdjRavFU%19Zgfr9X<;uRNZ*Zo)cj zAApg)J>Ne*8NPjeuzzw0pjul!7L8K2+3o#cH5!lD;0_*a=LBGrXlLi#^?2MsP=~)9 z?jIb!fu8?rFnH`y1Y-)*PCB1)yU#3lHVgcbi)h=xX|md~oI5(_9V{J30Tv9S4!u(a z#K8UkP*p7O%uW0e`}c2eQunv*UHNxlH9j^P2ZulHzkPl(e767NKM!9X41akA_yc5| zr|GP}L6W1B0_2WMcyq#l-dS=8P<nW9_^VMPh(>O39wll2d*C7}ykRl%JYsX89!5o& z$1ivg&89G9#={FATBpx6p9g=q;Ur?0{4C+|g~k|m_v;Izx84t%PH*>nXLHlp+!2s5 z{S>;}4-@|^;2XcXlh}oB5}sx=HU<L0;rZdj=wkoJA6M*SX&3Hj#Am4+0+CX0Mh_>4 ztDzZtK-$JH1gMEBqrKN}ULBO$t2QMe*6q#W$je4ZBxb8lqj7Td;&AxWt2Zz93CM5% z-T8Lf`PMu6_Lu&*FZ$me|1a=IV-&baLQK~uvO|u-zdyQxe-^uG6eo<zv{{xQ<1!L1 z?D*(418!#74CM<!bLNiTb9e<W+%p#h5Vn(^$5A#p*Bs3N#X;f}`ttag4MAY|>2TOg zcrb1=B)v8Rk~xbKKKRKE65bL3niUDqC<F`v0;1T_FZ%$bJEd0o1RH*0p*!U)8k@jY zs=y#)EY~N7SKrwCFuDvuTq%;?_ojYWsVw2`vuPA_C=GNuCH7@;7NQKULP(ON&)yUy z3la1_PA;KMNqZ?IBLJMCbbx7=lEtY-%_B*>EQw$UGm!cm8i6T<zXBuh85p=tG}*?| z3_3=F(rw^$I8=5(RrC-3IR9-hu%Q_{pP+KhI{Bmv^Ptq$#dJwirU+Tw1P*AWMv#RU zHv<@1sTB}4iyJ|FuG9*$zlq;4O7oHqP-}t&(6l$~)}rPf4;cL1C{CXwOXy2}D$TB- zIRy#nvxa6&S!FnjL0L=gM9Lll*DYYl*I1MaF|--N2@Xa9;U^%bToAAxYeM^O7Nkt@ zcbPX-FMW0_T0!B1P1km+kgj;JfFR^OFfgYx7^Sj@9Q^@!yV-J}r!jtQ8gjE$XhotR zjhni?)?;RaIbuK7C=r+=yMsNG5>Yeo;Eo^a>mL9K2!bgGd%@H57W0vkjKeeTPLpAD zmP7$hd2{B@gUI!UVsaKt;!BiWK`?J4+EdVkNuUIMGUFqEEJcr+VkqU39m-_$P}EI@ z@C9|2;~)!x+5qIxYwOOSBbH=mqN#)h{(BAvQ2VSsvcaB3!)q3RmFNixXt`F~I)nd5 zmcyQ9*a=Woavo)YM@)0ZnHPbXNp=AWdmKNs3PLWQ(93gwbdKaW@h?!ICL|`IDHsd^ zK(z)v$LV$3y<WSwiNaC5JT>0FL$y#rOD>VwaU=j7XQ5Ej#?&MNOG%2hi^G~OJM&YP zO%U&3Ya>)yl7Ur%6vsq07pO47v4KT0C6zqFlJILB^0-yeF~#Z5XS*MRITMG)={J<e z*bhA#7&HS0-8qlN^xK33F)?lsgY=jqWWabS%n;E5a7QwilmV72Rj}ZL`~>R(i!f-h zHhk)dKb!O?<d;Jv=q$0U;@4bir3lcVG%yF@ZQ8O6yTu-}UbkV&hbC2gGU#<n^7E09 zwvtXRaiHS}=(LUF1+_m3BN{tWS;}XHy2#&)Krw&^csg5+Qm=`7Ax$Sf#vah1a>uYF zB9te}RuPRB>dFe`j!(ON8sob{VbNrzEI{6WR|biH00J8czMcA>7s%-+G7UNR$bbL_ z8=Zq8#JxVNnaDz$vXx5r1ZW?CsK5~OX>`F!C|HD(WCqL+7ASqr;uz<K`ErqAL79nb zT4RM?#Ro@9kf!xJkd<Y%Rx8Ywl(j7zNKAfxj9;tc(0nfWNC?K7`7GiFT9*@SbU?G1 zcOjU!RI!okZ4|}+c>Y@cu7$tQ;Ii5R+5Z>Xyo2A4-<<6CzVB{sZgsm`!)Nf1^WwNY z_5;4;_m6DwByY&VlEm-zrHNovi_6M=Tp-n|;;f94TIp87H)?f-lzjgGg8BdJcasDv z6-%72tA0f3^*j8zLEV9<3+T96-)&jHE$TNGlO*cIgq_V{#d1Mf9EDMgW($g+EKPh* zNGLDLz-D8AW)Yay*N5nL>l9%+z1eu){ced7y}L>64MNAp?^gR}y=SWT0xB!jk>MOK zo6ZtVNCx6jrS}Wy7s{qYq*b~^n|5_uuHN#O#=BLr1lXwsa;5n4aRJ8*gp86gJRC(H zmm+4VWYJ%6Rs9;hQ)dyF4PL|(vCQ$OvtX{)tF9K6o<D+xsb5q*+8UMChC~)=1GM3C zZ1PbS_-^c{zCpD2DL`!C#RAnmx*ij^e-GCT{7D$Njz3OvC4Fli(M<C5;mPpCP2Rsc z`-6|tXLI~~q_{<S;=$5{*Zv}fe1K$5%P43~yP<JmhF-uRb+z*i-f6r26}er-Doy*> z#cC(c!XwY1eEce2F5ufN4wN(!js^|7L7XF449GPiKp4*jF4|~Rq8}|7#()n$5yquE zo8h#Pjf+l!fRp3c929yIryyYh7DUl|boBZ>$iX)HK>xdiC_FlVb%wy@N7GnJX23RR zwyAZfBR@1PKq-(146rTTZ^^*$i=ae{am{D+)>=wMr#MHJz!3H7Ao3nFq8eQ@jpxNh z2<nfa0VwGcB&npS8%hC_MROE>$^!H(6ziW_@&~K96hO>GM2Lh6DstL=S89?7Ixm{L zwmzVEE`klqQ2@7jNI&7;P~lgiqr*3EUcKoPN>EDb(TJtd5OoNy){sZbMS!4SSoo{m zW_I~kx!2NaX|GG?PM=4z)hnJCu=-$c6ZG54C4RE3_@hq*Yc6uUXoynh=s-%D_k7-F z7jBR(a-#ptg*Nd$hMs$mfy8hHw~2blrmkjr2h=#QEd1xP2@iSfkJzO<N8SbEiG41Y zwSLvVuA1nh%OC~B32BhaLG;=14=$JkoY_$>!4f0@6bN#^BeBa(6S%_NFCZsRw;PYn zVK{9eWiEYKR6+}9?irXHU`yDz@UYRdW2<FIrD4K=XjmhI93j+=UFgRtn-hS9MGlr^ z7Jy{~lY<^4g#lXR7Ui4}K)|q2)S*gEt6$JSvg$w<H91<KLjTfxw~9<hZhVT&C~CvE z0e+*=--S@Ug#cYv@r^8hD_Qf|Wwdy^SU&rn{_WKEJ-b$V8&p>-wM8kr)3b|Ci;6fm zrFVHg$aE)9nPVZ|N&?7~KE8Jw6NiEV>P#HXkL2zpVns<6vXbVKoD86p1dq8VSYW~O zkD~E}V?(&|0FxVCu0d4Y2K1#AQX8Q-W3m+iR;7l(3~NS&b2n)9(cdcE%KA4Nmkavk z!cXTdl)iFTGG!z9<&3r~J&+|y3QUGQn)3GxlRf@e4(yx3OPITU#Y%altQ2DO1x9qm ze6BJ|-j-w*69nHI)O7!djARD(rXYkkx<u4-#S_kQ14wa97$JEA5ZEti7y+b>3g`mX zWu9dUo8{7YLy0RGr1-u}5;kpUtxpCMd@y@i3+)w!wva4kkxdj`D{zatQP2w0M1dPQ zJdRDk>Tr>l&#?j3S|(_c-b!Y6y}<r-=62cEe13F%GMu>+ZVG)`GT{PhvdHk9aP;<| z6N7{}@u}Pso4V=fJYP#XAOZb}A7ac=-etb2b_o~`_!#${Q{2D+J5u+8n&Z-qJ&Zw{ zfi-#NgB+VPG1|n~F*`BBSU|o4;LssR`!-7=j1dB$=FpQ^rh*Q_%|0%75^<DNM*Xf# z;bQZ~E+EoPVho>1C@Cr&)d_xLHel6W(3~42k#3XpMw9}sMxdQj4L<6LksFLMy_Xwi z(=%AOK%WSIV!~agJj?HBYWh{z+JvvV&sfI>#soK!Mo~>6!QyA?5x=!euiD?imPTG8 z=v#$NNurx?1`PF3X<t$_D&^>RSa6^kBAzNJ^cp;h`j*rJYbEfhE%!&I3RidV2t8Xf z9VMqcy2y{JDWqX@S5{6Gmy`_zq?WV7|J7=jdZ1lpk2XxDIW1Kd_EfZGsP6$gEe;Ep z<Z@9Wm<!?RSNuFmW6GsTjjB{#IPPo)BDN`962)y(5?ED)(`&1=Ra}{6H3`Cjh2jk` zCnU2FbZulg_rmo93_+^YrQ(&o@vT)I$t+5SDii^Wh+TgRdn@f3tI{G?z$p8j)z+=l zRDqU;Qb3Dpr@HjxoxW_bgp<0}UbV4qqt1q*2pOd^j0%nG*flq|Y`z?4qVoHRSbSCu zXzxT!n;@MIsvXl+)fb!yzX)w5U>neCpw4ir*i4`YzHSA%R%~CEVq5FA+v+s~wy#s1 z8Zz%C%sY8-)CPr)r&W%eAt<+W?0*<o)`FFz@|>xfeIv*hmxHt>GyG?;oTIIcde@uk zug{bV4oS-=3`^n?1>23vyuattSyzI5c=Y0D%LIWoAI|s)qw%fY58dtVPPf~mV$~o7 zQRmugCIhu<!t!8cr4`IA+d?z}2(={w+ro2TXod_0a8Gs1gKA%ot?$YRd0c#9g5gD` z45)Maenm3=kvwA~ebQ9yt`&f^P%83Y?x8Q-5k5Nj+J%=9RiUKUYWo_?_B6;32GT+7 z5#(VTB%?SOo{5SwuMk8*j@5#&L|mAIK^#d*bxS#6+QLr-)#MUFI_m#U%zv+(c}>&I zq?W5fI*hVk9T(TxAXQeL&Sk)UTO!L3CqoQDYSV7sW$Xhl-kQ_3XTqF3im(vTSpozy zaEnlsnO=k2S9S7O1hj5*8`@4r=iJKz?%9=tR>eO0%%7s)dxBe5cnsk)ZC0*m?35*# zMu}b!7l)@`=ks}IW|1+SPc<A`^6583&EFNl(xr;8MbR8oUCf}ywH@_$v7@Gbn58@! z(mqwCiuvm@1FT(W=W8~{UcWV5XM=LInD5cvzKnd6pM`)Llr~!mr&r&efFKr&ehe?i zjennV3m5?=x$_DPnzMjcPu<;hsEHS)PQl6Ocsv=!{;Z(QZybSAiE*Pn*mGCK+#^<` z1&WSAb~I+u)K6(|6j3ytrE@mRQnknx2QcaAs6Ux-aSk)_C!jBqn}olpsGeM3-cS6C zKc?}D1ATqF^`zS`9o$;(F1^xaTJJW^50jUVG8>ISm$l6xaeq;fHa8A!Ss0>oS3x)G zoXLRw_0jB=P+5mCSwVUM2gRt5Vv981;t`q3!Jvv3TB?<S36)kx&K}6-uF%m7^)&MI zReJgp>*~KlWO+lGR;X{po(sy2L2=6`KkKVl1WM?0jBV{jChBaJv{-2uXiyAvE@&-N zo!vr%-M<18v673B_66!Avv*K7*dt;Snp1H~`cRFMEla(&Uz5_oC6QnfRrRsm2Ps@A zKzn@yA)${B2KM6;_Ixi<V$|I5lx??l6NWs;MXyh>Qc$@rnC1pb=-M%s3l+;%%4H=5 zbA2VVFjV3bDVtj>oO@C_%fcnDRz9C;$%Bc4N{9J#+idx<emZxXpRJ{{vlTTUj`oO? zd>EVvB3jBj)-1TIVrD3*mJyUFP6p9h10;hAP;86nOk~jda7+h}P%&GL5f{hJmJJ5o z<$WF^Qm2BcK{*LYaqUDISHww2kTaC>MkM;W?#W4<`VD(|9JhwY&X1wi8?aP;QPzjs z8lEsCcWQYeC4M2Mr;%){wxPjbv)g4NRG{|9UTcx~$fZYXp_^vKb<I6X7~;M!Rk|1< z)O5l-7d8_7yoAiIgf<{%5D*yyWU?ZvMeHk4f$Z#JqOv)qYgkL2g;HlNJ=W4=iS#gO zy|72#Hn}=kCP<os)>{ly8{k0@U<R|U&h2K3jaE6$f#}t#7$>wCq_VIs&5|^lvMCVX zmAiKf7mC_RS=zuaS1^ar7hJ63;tHb^i(J=}66+dkOc-5J)(BSsKv&n%)5R<;LVt(R zxG<f--~kVtg=xH!=W6Mq7;ey3^jF_)s~pg}(r(A~JxH|gar2!(jBF~vy+ZVZSiA{$ zy+2B$&;|Viqk$%7JQk_FS6cVg&q-xoX_L?uTvj4=y8^$Rs|`uqwe0X^seo#3KR29< z#EzGgn>vm#E6G&{J3qNtUn-GVXJxnPb-CbbqDQ~G@V1G}oTCvLPi=897H8kwo55nC zI;kc@8K_Q@G-`G*L3R~X#=+t9!;`~`wYfq>m8iLrz%HeVMenTeS>0$~p>{7pP#QE5 zPKaBM4(ue)FG`stf%B$WkossLdK_0~Nhv`kIiRHH&vDT8*SdNK_W+wh@-8{C9LFhJ zM8KV(5QWc>Iw<}ukF!vo+tcp5R!yo)@mud5CD>fzGknDU0L_Z&xd1Xf-i6(jx0LeE z#9(?QCm*>`5!E8AXB*15Zszb){=QrK%LFm56g9C_v`M1=yZXr#!+0i5O8CdFA8^kp z53OuNCOrK!bI~XC$#?g~@nY&rda}_QKT@HXIV5^XDZZ(k$WuQx_b4K^|NLaXctSV7 z<3gpn(yLQUpo8i4F)uc1{3xNT2lC?#lPqv!xkqFyYC!;AL_Ye@!f}@PH7O|8(FgyP z(Fg1a`x|TpS(0b0nji#q()n|QAv_Z7hi0|Bl>ub8AB$7(g(T&mIE&SgE#gF9ydzRy z$sIwmH{`7fSn^+{JXyy;tYaYlTVfz`W=Jp#saNC%jQW(^0CumPt4`Z6>cz1vlF~{v zyHec>-FZ`f$-CRonab#go^?~V<*G5Tw~B-Px@fC*6Lmqn{@o`?ygHF%gc0&Az&ov0 z$mRIx6TnDml|T6D5WSN_SeZw06K_+<Q|Ksb_V9zWJ;{B9Ya+CSu!1l<)DZzuSr}LH zi@r&vcn^~xJ=Gh%O6G}!;50iuoD_r(!!F!-l3})1Om!V6`b30k=x4fT2(!4Va>CiF z4rQXe$gf31@qr?M3*%enu#vY%aS_Aq<xL5gkH)mu6l2mxwa6w%ge=ys^e+s<2>2{U z71&VrIh08p)e>$JDd%g*T--j*QiLHr|E5vcu)$&X3!TW968q{L=Nls>PiYJaT?m1& zzOXv|K@2C-?~h&u1IC<*@$Hbn9u!KLN<6~1>A6D@U`bO~X;sWf+38SQl&AJTkZ*OB za;}q~$RffM*ct<c-bJaG=wtIdb^Tw5?*Gf@MMP9V88tEFJmPd83apgy#zJh=sT|yf zCeV0B0)>wkr@j8WKK6GcF6$8HT22j#j~BT4sR~U%q-f8&$nqf8Gf)QQaZSig2}A0z zH@vF5Ca6-rSZLv#FR52!j8{y+AAxKsD<ft|)Tajtha{tO0ub#=zZ|~)ED{$}=dS*I z3W+PE+7tk3mc-ZzrKtu0r=%B3!jfiAa2|bj_9d~sreB&!yNGDe=zQ#d7>>^2{Q!8X zWz=_oHMBHsTAd54ZFM@*767#>Z^#li;GrE7%m&tr^6hf4R*tif4!}EB+a<L%u#yzY z4bwPN>1gV^?4WrCU4=*k1M8{LtGGr@b^BUgAcyz<(0y;9*Dt2{uPjE_rNJM%@XTSa zfVbjHBv2uoL8F2UMjMFE%;SP9S#ZnYQh4Q6ql>U}d=AoNl*KU$Bz1?Wa=id(6W|G} z&8~|jy=uf6ij2;sohUko&uu1hFSm7um^N*;v~j)ImOg6-<YLP86<L5I-M-XSQ5ekG zWfZ?hDUP|@&edf>a$^Y0=krt_3r5?St}E1D7ial+e9stz@Scewl$|vwCB;g2d5cIx z(5_f&*3*;O%`25>L7t!zw!s2dijDA6qGg!~-Z=G_;0pJ^*t5D~;P3g|oV|imEA`WW z>&evVu5~);qW91N8;qho`mCmvr9e>JDk1Do6BxN$sKdrJDF33QK2l$)yELz06NJ)i zTsNkjm4;ibI9AicCN5e6iX<Y)$pS69C`-jfQ0V9t=?lfZWpoWi<_Bp9(-un4o2{)d zx%NX}@X|5J#XTWvW{%~rk9suHuV6;SQ1`S&sJY5vCpvxxgN~LG5Njr!t5BY#wH(F- z<jqi(B}n;F(L|SV=H;&?hipU%*?6{MF#9Q<517yR07Ph;iJt7&1<h|uZ;v!OYAyIi zWr0k$%Zghe$!>JSrL6Q(YN%H6el_~3fDbc~Rc;&E)r4C4Wz+U!X5K!HTcOPW^n<)= z)*~~<y!5#g8DMnN`IL`c*X1HGF!zi<($kJc3|qMYK{vEPFBaZ55qb4`4<SiGdhBg> zQF_!i_N0`~Oy)AHOJkOwrB-r1Kha{X3_Ur90C)fmMEMe^mo&Tx>LF!WTbzGQh`L(? zZAb?JG;Nrat}5Gq{(N}!V*lqu=a1RshNCFN2T><#4A<^#>97ifR2dx|Xx`qr3H=lX zVA2oJ&Vm+edr`_p16mARD!_^Pp6pRH^SNiQ4m0*phje`;Ndc{=Ky-1tF+^7}Ee(d; z_ct2Lg5y<s3}R#8Hta0-rx#4du2{1dw*Q)8L~1Da!iZP^ujQ;hMA>b1#^f~Z-ev@e z8iJirPyrp4!*TTRcFUd5G$z?OEDEosYFzIEZ>#ris%>;)%V;dAQ$$;uq$Mv~6SOtB zKEd8Fd8T!vL8t*#Cp;g3AKr2Z1tCH#RsdhNe|_O0)*g1w%C;dPgeMH>uR1isB5uLi zz~kTdcDvo)^#sbo!4;%RE=NQkMM3lV%`)NNsxecgeOdN{8f<jeHY&2AwIXzS-7*;1 zKxpL)-}MzS<UEnLtzeW4RhAd7h%foYE8=_IzPT8+XtcEq8Vs7Vg~754NO%KP5h@X^ zBPKv3$-EsLNTVx3qK<7Fu!!TQ^u3gp{aUcV3@L6YL!tmM&y5=ZRHvm5L05LYq}L@h zQSPXoN|twi42b>L+x_Q9C;wgqgb~a2X<@<T{z6RXBTdT9VE`h13<J4?B7+l_cP13~ zqV8lsYfWGIpk)uW0lXh(ePiRcxEDzAx*ujLenaoib#Z$RU>y!|)i4|)hgicQy03>r zOSC6^+>OSA_4B1YMP<|JIh)Q88^xC!L--8DFa%X}qds7D(cRtMrN8i$|I+8)*4Fm! z*53AJck4m7x3{~!^MG~l0|6OE@iKPncFKeM@0ovxPbMAQ_1U-uYWDW_u9*M5-JRXu z*3MQJ=YMm1`vKco&;OS-{~pJUXC98`!@v*UgNFQ&-U<Kriu1p@wbk2P^Z$K3Yn{B- z|10x957T%)oJBrH60OGjtMGrXyI11>&7JM;n*Z<PImKh9QNV{H2q}5jDEVXtWq(BR zYaea<wPpWx@c-+7{@giw`O~XAw*R-c%KE>%wY9hA|ND4e@YF>oYv)(tQtY#y(|y=@ z32XU2aehbB!NZ182FT=L<2aj6-FV&?CsB-ozeH2sq01O`wAJP1r4ej(nZ)VFrT^aF z@S^vbGdrI>MHdD1*Dn&^!^VD=o=0(?z4S*B0|=(Bo3IYsr?%A39S(9R=%c3;fB%Q> z>0#r!KjIY6{_ObRVdEe_J=SM$U;gvutKVKeY`hNK6r<XVS8M*S^1nK^bPe6VlKtN+ z^M7x5YkSTA_wlIHCu<G9*8f-X|M9E0Z+<*Hz9#!$t^ap-%KQ%>*8G1T&zr;jgBOQR zoTQC}r`gPz%^Qo|zvZ7QTa}HgOvlCwwAHwd|EaO+Vzse~R$Evojb=kSo^@T~|8L^| z8zSLq{a;@H_xASI`u{V`|Jn*z>wn<?8?N*3Z2b>kdRuG$|034^!}a?AtK<LND7+8; z-`phs|JL5lX1BZ5g>t>^&Ar_<|9=MkKPWs6N?R%pq2@`QTt*kgjpQjpJOBzf3_Ul% z+(&qlp4xL&d^VjDobfpI#|*RSP}o1kGOP1sPNQ+mIkU^*pywja6i*gWyOjdmHgg{* z&<;U7b4Twn+W>r&#=R#pD`l7xPKY%*hNRIr3IY5878H}l|LLc3645z8jB#~!049ZF zzvLe>Y<LzWei~uUW{@uOxX}|f^Jlu^|NKu#WwSVV@`QCd*=!QK@-jsX3yv;BIzc9I zChCafPw^RiZr3zfGR>i+Gx?9vbmKQ46HbblaWvJV86A-4;e`(pkv=Ec=p5s{Xm(!D ze>`{NDZ{xNQ8vXK4u!|dyiI5&&D;Q*GcqeQR3n&BAqvO-B*P<ic=Ao;3(G<czcEyI zjOWC-i^nf9l>{B=<1}0o5(!13z%Yi@pnD@F?wbxk)hgku!<pmE;)t?;Ii;1&5K9`k zBjTa3`bAh^Ni<FwEk4zu$SC$FKAtBX(QTcCTw)Bw=mgI#`_n1+d^`Xc^D!(m&(%mI z+S(0q1{FG|^QYo^cmNQn%g2PF0y`1XxVX{4pU$EfTIT5pX#TCjZjpq6i1ja&eIWKP ze1KChfk@y%sS#N7Qe-;LQhkWg?%1s&Q5$nu*cNCspo%_|iL)<HhcBw$>C7<&d!doF zA^s)lf8hxljVJeG|95vbOZNZv_SRbe-^+8#CzByMciug0r0!&hXQ%P-hWLhO3g8PY z2p+Co1792e-!R(u+Wg-G-Ut5Q+1cIcZNoYM`G0Gxx90!*c*vrq`A(xKNTg*U-n1#1 z&rsQ4B416+U2n=&#u~DTq8SgHcD`t|TWDR5`{f+mW6aIw;XwduzKI701|^%`Zp&KI z<Q~{WlKQog{dHg$-4418nA-#UmVO7_m`nbJfnDo<D3uzL7h+&nyb!uvAe<2c``Ph< zekl#3q1uQToZ4zz)_$i7saY5l=A_wDznj|~gTD&LL+nzFm)&QlH3{)bGcmY2?n{qA fJQ~)I>O*TSVAs$3SwHLN3w{0{K_cn?0LTCU=)R0A diff --git a/atdb_interface_pip/setup.py b/atdb_interface_pip/setup.py deleted file mode 100644 index 6fdd44c1..00000000 --- a/atdb_interface_pip/setup.py +++ /dev/null @@ -1,21 +0,0 @@ -from setuptools import setup, find_packages - -def readme(): - with open('README.rst') as f: - return f.read() - -setup(name='atdb_interface', - version='1.2.9', - description='ATDB interface', - url='https://www.astron.nl/wsrt/wiki/doku.php?id=atdb:atdb_interface', - author='Nico Vermaas - Astron', - author_email='vermaas@astron.nl', - license='BSD', - install_requires=['requests'], - packages=find_packages(), - entry_points={ - 'console_scripts': [ - 'atdb_interface=atdb_interface.atdb_interface:main', - ], - }, - ) \ No newline at end of file diff --git a/atdb_interface_pip/upload_to_nexus.sh b/atdb_interface_pip/upload_to_nexus.sh deleted file mode 100644 index a5b6f8f0..00000000 --- a/atdb_interface_pip/upload_to_nexus.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -##---------------------------------------------------------------------------------------------------------------------# -##! \brief Description: This script uploads the created atdb_interface artifact to the Nexus repository -##! In: $1 [Optional] Additional Artifact version tag which can be anything -##! Out: None -##! Returns: None -##! Preconditions: -##! - build should be done /dist/atdb_interface-[version].tar.gz is available -##! Postconditions: -##! - artifact uploaded to https://support.astron.nl/nexus/content/repositories/snapshots/nl/astron/atdb/ATDB_interface-[version][additional version tag].tar.gz -##! Examples: .\upload_to_nexus -##! .\upload_to_nexus 20180913 -##! .\upload_to_nexus test -##---------------------------------------------------------------------------------------------------------------------# - -VERSION=$(python setup.py --version) -ARTIFACT_NAME="ATDB_interface" -ARTIFACT_BUILD="/dist/atdb_interface-${VERSION}.tar.gz" - -ARTIFACT_UPLOAD_BASE_PATH="https://support.astron.nl/nexus/content/repositories/snapshots/nl/astron/atdb/" -if [[ $# -eq 1 ]]; then - ARTIFACT_VERSION="-${VERSION}-${1}" -else - ARTIFACT_VERSION="-${VERSION}" -fi - -ARTIFACT_UPLOAD_PATH="${ARTIFACT_UPLOAD_BASE_PATH}${ARTIFACT_NAME}${ARTIFACT_VERSION}.tar.gz" -ARTIFACT_BUILD_PATH="$(pwd)${ARTIFACT_BUILD}" - -echo "Upload ${ARTIFACT_BUILD_PATH} to $ARTIFACT_UPLOAD_PATH" -curl --insecure --upload-file ${ARTIFACT_BUILD_PATH} -u upload:upload ${ARTIFACT_UPLOAD_PATH} - -# Next command will not close the window, can be handy if something goes wrong -exec $SHELL \ No newline at end of file -- GitLab