commit 0e70e675fcb8efbcc28dcc6bd62742832b693ea5 Author: Scott Wallace Date: Mon Jun 21 20:41:01 2021 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad3dffd --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode/ +__pycache__/ +.pyenv/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a8692bc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.8-slim-buster + +# Keeps Python from generating .pyc files in the container +ENV PYTHONDONTWRITEBYTECODE 1 + +# Turns off buffering for easier container logging +ENV PYTHONUNBUFFERED 1 + +ADD requirements.txt . +RUN python -m pip install -r requirements.txt + +WORKDIR /app +COPY main.py /app + +RUN useradd appuser && chown -R appuser /app +USER appuser + +EXPOSE 5000 + +ENTRYPOINT ["python", "main.py"] diff --git a/main.py b/main.py new file mode 100644 index 0000000..0818135 --- /dev/null +++ b/main.py @@ -0,0 +1,72 @@ +""" +Present observational weather data to Prometheus +""" + +import json +import time +import os + +import requests +from flask import Flask, Response + +app = Flask(__name__) + + +def fetch_metoffice_data(location: int, apikey: str) -> dict: + """ + Fetch current data from the Met Office for the provided postcode + """ + + obs_data = requests.get( + f'http://datapoint.metoffice.gov.uk/public/data/val/wxobs/all/json/{location}?' + f'key={apikey}&' + 'res=hourly' + ) + + return json.loads(obs_data.content) + + +@app.route('/metrics') +def metrics(): + """ + Output Prometheus-style metrics + """ + metoff_apikey = os.environ.get('METOFF_APIKEY') + metoff_location = os.environ.get('METOFF_LOCATION') + + hour_data = fetch_metoffice_data(metoff_location, metoff_apikey,)['SiteRep']['DV'][ + 'Location' + ]['Period'][-1]['Rep'][time.gmtime().tm_hour] + + ret_data = [ + { + 'key': 'sensor_weather_outdoor_temperature_celcius', + 'labels': { + 'location': metoff_location, + }, + 'type': 'gauge', + 'value': float(hour_data['T']), + }, + { + 'key': 'sensor_weather_outdoor_humidity_percent', + 'labels': { + 'location': metoff_location, + }, + 'type': 'gauge', + 'value': float(hour_data['H']), + }, + ] + + ret_str = '' + for item in ret_data: + ret_str += f'# TYPE {item["key"]} {item["type"]}\r\n' + ret_str += f'{item["key"]} {item["value"]}\r\n' + + resp = Response(ret_str) + resp.headers['Content-type'] = 'text/plain' + + return resp + + +if __name__ == '__main__': + app.run(host='0.0.0.0') diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..30692b7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +flask +requests