Skip to content
Snippets Groups Projects
Commit c003d969 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
/venv
FROM python:3.9-buster
COPY requirements.txt ./
RUN pip install -r requirements.txt --extra-index-url https://www.ict.inaf.it/gitlab/api/v4/projects/670/packages/pypi/simple
COPY server.py index.html script.js ./
ENTRYPOINT ["python", "server.py"]
# Coords Service
Toy Python server using [Coords Library](https://www.ict.inaf.it/gitlab/ci-intro/coords-library) to demonstrate GitLab CI features.
favicon.ico

1022 B

<html>
<head>
<title>Coordinates calculator</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous" />
<!-- Fetch API polyfill, for supporting Internet Explorer -->
<script src="https://cdn.jsdelivr.net/npm/fetch-polyfill@0.8.2/fetch.min.js"></script>
<style>
.hide { display: none; }
.loading {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.7);
z-index: 100000;
}
.spinner-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
.spinner-border {
width: 3rem; height: 3rem;
}
</style>
</head>
<body>
<div class="container">
<div class="row mt-5">
<div class="col text-center">
<h2>Coordinates for #LOCATION_NAME#</h2>
<p class="fw-light">Using coords-library #LIB_VERSION#</p>
</div>
</div>
<div class="row">
<div class="col-6 offset-3">
<div class="input-group mt-3 mb-3">
<input type="text" class="form-control" id="object_name" placeholder="Object name" aria-label="Object name" aria-describedby="get_coordinates">
<button class="btn btn-primary" type="button" id="get_coordinates">Get coordinates</button>
</div>
<div class="alert alert-danger hide" role="alert" id="error">
</div>
<div class="row hide" id="result">
<div class="col">
<ul id="result-list">
<!-- results go here -->
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="loading" class="loading hide">
<div class="spinner-wrapper">
<div class="spinner-border text-info" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
\ No newline at end of file
coordslib
astropy==4.2.1
numpy==1.20.2
pyerfa==1.7.2
function getCoordinates() {
// Previous results cleanup
document.getElementById('loading').classList.remove('hide');
document.getElementById('result').classList.add('hide');
document.getElementById('result-list').innerHTML = '';
document.getElementById('error').classList.add('hide');
// Retrieve object name
let objectName = document.getElementById('object_name').value;
// Call the server
fetch('coords?object=' + objectName)
.then(response => response.json())
.then(data => {
if (typeof data['error'] === 'undefined') {
// Build results list
let resultsHTML = '';
for (let key in data) {
resultsHTML += '<li><strong>' + key + '</strong>: ' + data[key] + '</li>';
}
document.getElementById('result-list').innerHTML = resultsHTML;
document.getElementById('result').classList.remove('hide');
} else {
// Show error
let errorElement = document.getElementById('error');
errorElement.classList.remove('hide');
errorElement.innerText = data['error'];
}
})
.finally(() => {
document.getElementById('loading').classList.add('hide');
});
}
// Event handlers
document.getElementById('get_coordinates').onclick = getCoordinates;
document.getElementById('object_name').onkeydown = function(event) {
// Enter key event
if(event.keyCode === 13) {
getCoordinates();
}
};
import http.server
import socketserver
import urllib.parse as urlparse
from urllib.parse import parse_qs
from importlib.metadata import version
import json
import sys
import traceback
import argparse
import coords
class CoordsHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
try:
if self.path == '/':
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
# Open HTML page and replace placeholders
content = open('index.html', 'r').read()
location_name = coords.get_location_name(location_id)
content = content.replace('#LOCATION_NAME#', location_name)
content = content.replace('#LIB_VERSION#', version('coordslib'))
self.wfile.write(bytes(content, 'utf8'))
return
elif self.path.startswith('/coords'):
# extract 'object' query parameter from URL
parsed = urlparse.urlparse(self.path)
object_name = parse_qs(parsed.query)['object'][0]
# call coords library
result = coords.get_coords(object_name, location_id)
self.send_response(200)
self.send_json_response(result)
return
except Exception as ex:
print(traceback.format_exc(), file=sys.stderr)
# send error response
self.send_response(500)
self.send_json_response({'error': str(ex)})
return
# default server GET implementation (returns file or 404)
return http.server.SimpleHTTPRequestHandler.do_GET(self)
def send_json_response(self, data):
self.send_header('Content-type', 'application/json')
self.end_headers()
# write JSON data in HTTP response body
self.wfile.write(bytes(json.dumps(data) + '\n', 'utf8'))
parser = argparse.ArgumentParser(description='Simple HTTP server that displays a form '
'to get astronomical coordinates for a given location')
parser.add_argument('port', type=int, nargs=1, help='server port')
parser.add_argument('location_id', type=str, nargs=1, help='astropy observatory/site identifier')
args = parser.parse_args()
port = args.port[0]
location_id = args.location_id[0]
# Create an object of the above class
handler_object = CoordsHttpRequestHandler
# Avoid 'address already in use' error on server restart
socketserver.TCPServer.allow_reuse_address = True
coords_server = socketserver.TCPServer(("", port), handler_object)
# Start the server
coords_server.serve_forever()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment