- sqs-consumer: new Go binary v1.2 with tokenManager (auto-login /auth/login, 5min cache, retry on 401) - console: add MQ/KW triggers UI (mqtriggers.go, kwtriggers.go, mq.js) - console: update python-env image to v1.1 (boto3+psycopg2+requests) - weather-demo: fix consumer/main.py (Flask Request.get_json instead of dict access) - weather-demo: fix fetcher/main.py (boto3 SQS publish, 5 cities) - weather-demo: update main.tf (python-env v1.1, deploy_type=literal) - python-env: add psycopg2-binary to Dockerfile (v1.1) - terraform provider: client auth fix
93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
import os
|
|
import json
|
|
import time
|
|
import requests
|
|
import boto3
|
|
from botocore.config import Config
|
|
|
|
# Open-Meteo: бесплатный API без ключа, реальные данные.
|
|
# https://open-meteo.com/en/docs
|
|
CITIES = [
|
|
{"name": "Moscow", "country": "RU", "lat": 55.7558, "lon": 37.6173},
|
|
{"name": "London", "country": "GB", "lat": 51.5074, "lon": -0.1278},
|
|
{"name": "Paphos", "country": "CY", "lat": 34.7753, "lon": 32.4242},
|
|
{"name": "Ulyanovsk", "country": "RU", "lat": 54.3282, "lon": 48.3866},
|
|
{"name": "Santiago", "country": "CL", "lat": -33.4489, "lon": -70.6693},
|
|
]
|
|
|
|
# WMO weather code → описание
|
|
WMO_DESCRIPTIONS = {
|
|
0: "clear sky", 1: "mainly clear", 2: "partly cloudy", 3: "overcast",
|
|
45: "fog", 48: "icy fog", 51: "light drizzle", 53: "drizzle",
|
|
55: "heavy drizzle", 61: "light rain", 63: "rain", 65: "heavy rain",
|
|
71: "light snow", 73: "snow", 75: "heavy snow", 80: "rain showers",
|
|
81: "showers", 82: "violent showers", 95: "thunderstorm",
|
|
}
|
|
|
|
|
|
def fetch_city(city):
|
|
params = {
|
|
"latitude": city["lat"],
|
|
"longitude": city["lon"],
|
|
"current": "temperature_2m,apparent_temperature,relative_humidity_2m,surface_pressure,wind_speed_10m,weather_code",
|
|
"wind_speed_unit": "ms",
|
|
"timezone": "UTC",
|
|
}
|
|
resp = requests.get(
|
|
"https://api.open-meteo.com/v1/forecast",
|
|
params=params,
|
|
timeout=10,
|
|
)
|
|
resp.raise_for_status()
|
|
cur = resp.json()["current"]
|
|
code = cur.get("weather_code", 0)
|
|
return {
|
|
"city": city["name"],
|
|
"country": city["country"],
|
|
"temperature": round(cur["temperature_2m"], 1),
|
|
"feels_like": round(cur["apparent_temperature"], 1),
|
|
"humidity": int(cur["relative_humidity_2m"]),
|
|
"pressure": int(cur["surface_pressure"]),
|
|
"wind_speed": round(cur["wind_speed_10m"], 1),
|
|
"description": WMO_DESCRIPTIONS.get(code, f"wmo:{code}"),
|
|
"owm_timestamp": int(time.time()),
|
|
}
|
|
|
|
|
|
def main(event, context):
|
|
sqs_endpoint = os.environ.get(
|
|
"SQS_ENDPOINT", "http://shared-sqs.shared-sqs.svc.cluster.local:4100"
|
|
)
|
|
access_key = os.environ.get("SQS_ACCESS_KEY", "SSAK-a9964f2723bc6d347f48d153")
|
|
secret_key = os.environ.get(
|
|
"SQS_SECRET_KEY",
|
|
"2069e1ce05aaf94efe07aee18697352879e7626df239a9c71af0e9650b43bdd6",
|
|
)
|
|
queue_name = os.environ.get("SQS_QUEUE_NAME", "weather-data")
|
|
|
|
cfg = Config(signature_version="s3v4", s3={"addressing_style": "path"})
|
|
sqs = boto3.client(
|
|
"sqs",
|
|
endpoint_url=sqs_endpoint,
|
|
aws_access_key_id=access_key,
|
|
aws_secret_access_key=secret_key,
|
|
region_name="us-east-1",
|
|
config=cfg,
|
|
)
|
|
|
|
try:
|
|
queue_url = sqs.get_queue_url(QueueName=queue_name)["QueueUrl"]
|
|
except Exception:
|
|
queue_url = sqs.create_queue(QueueName=queue_name)["QueueUrl"]
|
|
|
|
results = []
|
|
for city in CITIES:
|
|
try:
|
|
msg = fetch_city(city)
|
|
sqs.send_message(QueueUrl=queue_url, MessageBody=json.dumps(msg))
|
|
results.append({"city": msg["city"], "temp": msg["temperature"]})
|
|
except Exception as e:
|
|
results.append({"city": city["name"], "error": str(e)})
|
|
|
|
return {"status": "ok", "sent": len(results), "results": results}
|