avwx-rest / avwx-api Goto Github PK
View Code? Open in Web Editor NEWREST API for parsing aviation weather data
Home Page: https://avwx.rest
License: MIT License
REST API for parsing aviation weather data
Home Page: https://avwx.rest
License: MIT License
Example:
curl 'http://127.0.0.1:8000/api/metar/KLAX?filter=raw'
{
"meta": {
"timestamp": "2023-10-23T08:14:09.900113Z",
"stations_updated": "2023-10-01"
},
"raw": "KLAX 230753Z 17006KT 10SM FEW012 BKN016 BKN028 17/16 A2976 RMK AO2 SLP076 T01720156 402280139 $ KLAX 230653Z 24007KT 10SM SCT012 BKN015 BKN075 18/16 A2977 RMK AO2 SLP079 T01780156 $"
}
Note there are two METARs combined at one single line in the returned result, which is unexpected.
When a metar report is looked up with the info
option by coordinates in the geonames API but the found station does not exist on the AVWX-Engine, the API returns a HTTP 500
Request with the info
option
curl -s https://avwx.rest/api/metar//32.865,-114.393?options=info | jq
{
"message": "Internal Server Error"
}
Same request without the info
option:
curl -s https://avwx.rest/api/metar//32.865,-114.393 | jq
{
"Altimeter": "3023",
"Cloud-List": [],
"Dewpoint": "M02",
"Flight-Rules": "VFR",
"Meta": {
"Cache-Timestamp": "Fri, 23 Feb 2018 13:59:34 GMT",
"Timestamp": "Fri, 23 Feb 2018 14:01:09 GMT"
},
"Other-List": [],
"Raw-Report": "KLGF 221855Z AUTO 27009G14KT 250V310 10SM SKC 15/M02 A3023",
"Remarks": "",
"Remarks-Info": {},
"Runway-Vis-List": [],
"Station": "KLGF",
"Temperature": "15",
"Time": "221855Z",
"Units": {
"Altimeter": "inHg",
"Altitude": "ft",
"Temperature": "C",
"Visibility": "sm",
"Wind-Speed": "kt"
},
"Visibility": "10",
"Wind-Direction": "270",
"Wind-Gust": "14",
"Wind-Speed": "09",
"Wind-Variable-Dir": [
"250",
"310"
]
}
In this case, I would give priority to the metar report and return an empty Info
json.
if 'info' in opts:
try:
resp['Info'] = avwx.Report(station).station_info
except Exception as e:
resp['Info'] = {}
return resp
METAR lookup based on coordinates pulls up non-reporting stations instead of prioritizing reporting stations.
Unable to use Reporting flag on search as well.
how can I get Authentication?
How would one run this on Digital Ocean App Platform? Currently running into non-zero exit issues.
Hello, I think I've found an issue with parsing of this TAF message:
ESSA 261130Z 2612/2712 VRB02KT 9999 SCT005 BKN030 PROB40 2612/2618 4000 BR BKN004 2618/2706 0300 FZFG VV002 2706/2709 3000 2709/2712 BKN008
I would expect the message to be parsed into 5 forecast
objects, with the following time periods:
TAF code | start_time |
end_time |
---|---|---|
2612/2712 | 2024-02-26T12:00:00Z | 2024-02-27T12:00:00Z |
2612/2618 | 2024-02-26T12:00:00Z | 2024-02-26T18:00:00Z |
2618/2706 | 2024-02-26T18:00:00Z | 2024-02-27T06:00:00Z |
2706/2709 | 2024-02-27T06:00:00Z | 2024-02-27T09:00:00Z |
2709/2712 | 2024-02-27T09:00:00Z | 2024-02-27T12:00:00Z |
The JSON should look like this:
expected.json
"forecast": [
{
...
"end_time": {
"dt": "2024-02-27T12:00:00Z",
"repr": "2712"
},
"flight_rules": "MVFR",
"icing": [],
"other": [],
"probability": null,
"raw": "2612/2712 VRB02KT 9999 SCT005 BKN030",
"sanitized": "2612/2712 VRB02KT 9999 SCT005 BKN030",
"start_time": {
"dt": "2024-02-26T12:00:00Z",
"repr": "2612"
},
...
},
{
"altimeter": null,
"clouds": [
{
"altitude": 4,
"modifier": null,
"repr": "BKN004",
"type": "BKN"
}
],
"end_time": {
"dt": "2024-02-26T18:00:00Z",
"repr": "2618"
},
"flight_rules": "MVFR",
"icing": [],
"other": [],
"probability": {
"repr": "40",
"spoken": "four zero",
"value": 40
},
"raw": "PROB40 2612/2618 4000 BR BKN004",
"sanitized": "PROB40 2612/2618 4000 BR BKN004",
"start_time": {
"dt": "2024-02-26T12:00:00Z",
"repr": "2612"
},
"summary": "Vis 4km, Mist, Broken layer at 400ft",
"transition_start": null,
"turbulence": [],
"type": "FROM",
"visibility": {
"repr": "4000",
"spoken": "four thousand",
"value": 4000
},
"wind_direction": null,
"wind_gust": null,
"wind_shear": null,
"wind_speed": null,
"wind_variable_direction": [],
"wx_codes": [
{
"repr": "BR",
"value": "Mist"
}
]
},
{
"altimeter": null,
"clouds": [
{
"altitude": 2,
"modifier": null,
"repr": "VV002",
"type": "VV"
}
],
"end_time": {
"dt": "2024-02-27T06:00:00Z",
"repr": "2706"
},
"flight_rules": "LIFR",
"icing": [],
"other": [],
"probability": {
"repr": "40",
"spoken": "four zero",
"value": 40
},
"raw": "2618/2706 0300 FZFG VV002",
"sanitized": "2618/2706 0300 FZFG VV002",
"start_time": {
"dt": "2024-02-26T18:00:00Z",
"repr": "2618"
},
"summary": "Vis 0.3km, Freezing Fog, Vertical visibility up to 200ft",
"transition_start": null,
"turbulence": [],
"type": "FROM",
"visibility": {
"repr": "0300",
"spoken": "three hundred",
"value": 300
},
"wind_direction": null,
"wind_gust": null,
"wind_shear": null,
"wind_speed": null,
"wind_variable_direction": [],
"wx_codes": [
{
"repr": "FZFG",
"value": "Freezing Fog"
}
]
},
{
"altimeter": null,
"clouds": [],
"end_time": {
"dt": "2024-02-27T09:00:00Z",
"repr": "2709"
},
"flight_rules": "MVFR",
"icing": [],
"other": [],
"probability": {
"repr": "40",
"spoken": "four zero",
"value": 40
},
"raw": "2706/2709 3000",
"sanitized": "2706/2709 3000",
"start_time": {
"dt": "2024-02-27T06:00:00Z",
"repr": "2612"
},
"summary": "Vis 3km",
"transition_start": null,
"turbulence": [],
"type": "FROM",
"visibility": {
"repr": "3000",
"spoken": "three thousand",
"value": 3000
},
"wind_direction": null,
"wind_gust": null,
"wind_shear": null,
"wind_speed": null,
"wind_variable_direction": [],
"wx_codes": []
},
{
"altimeter": null,
"clouds": [
{
"altitude": 8,
"modifier": null,
"repr": "BKN008",
"type": "BKN"
}
],
"end_time": {
"dt": "2024-02-27T12:00:00Z",
"repr": "2712"
},
"flight_rules": "MVFR",
"icing": [],
"other": [],
"probability": {
"repr": "40",
"spoken": "four zero",
"value": 40
},
"raw": "2709/2712 BKN008",
"sanitized": "2709/2712 BKN008",
"start_time": {
"dt": "2024-02-27T09:00:00Z",
"repr": "2709"
},
"summary": "Broken layer at 800ft",
"transition_start": null,
"turbulence": [],
"type": "FROM",
"visibility": null,
"wind_direction": null,
"wind_gust": null,
"wind_shear": null,
"wind_speed": null,
"wind_variable_direction": [],
"wx_codes": []
}
],
The message was parsed to only two forecast
objects, one for 2612/2712 VRB02KT 9999 SCT005 BKN030
and one for PROB40 2612/2618 4000 BR BKN004 2618/2706 0300 FZFG VV002 2706/2709 3000 2709/2712 BKN008
.
As is, there is no way to tell that the VV002
and FZFG
codes should apply during 2618/2706.
TAF code | start_time |
end_time |
---|---|---|
2612/2712 | 2024-02-26T12:00:00Z | 2024-02-27T12:00:00Z |
2612/2618 | 2024-02-26T12:00:00Z | 2024-02-26T18:00:00Z |
"forecast": [
{
...
"end_time": {
"dt": "2024-02-27T12:00:00Z",
"repr": "2712"
},
"flight_rules": "MVFR",
"icing": [],
"other": [],
"probability": null,
"raw": "2612/2712 VRB02KT 9999 SCT005 BKN030",
"sanitized": "2612/2712 VRB02KT 9999 SCT005 BKN030",
"start_time": {
"dt": "2024-02-26T12:00:00Z",
"repr": "2612"
},
...
},
{
"altimeter": null,
"clouds": [
{
"altitude": 2,
"modifier": null,
"repr": "VV002",
"type": "VV"
},
{
"altitude": 4,
"modifier": null,
"repr": "BKN004",
"type": "BKN"
},
{
"altitude": 8,
"modifier": null,
"repr": "BKN008",
"type": "BKN"
}
],
"end_time": {
"dt": "2024-02-26T18:00:00Z",
"repr": "2618"
},
"flight_rules": "LIFR",
"icing": [],
"other": [
"2618/2706",
"0300",
"2706/2709",
"3000",
"2709/2712"
],
"probability": {
"repr": "40",
"spoken": "four zero",
"value": 40
},
"raw": "PROB40 2612/2618 4000 BR BKN004 2618/2706 0300 FZFG VV002 2706/2709 3000 2709/2712 BKN008",
"sanitized": "PROB40 2612/2618 4000 BR BKN004 2618/2706 0300 FZFG VV002 2706/2709 3000 2709/2712 BKN008",
"start_time": {
"dt": "2024-02-26T12:00:00Z",
"repr": "2612"
},
"summary": "Vis 4km, Mist, Freezing Fog, Vertical visibility up to 200ft, Broken layer at 400ft, Broken layer at 800ft",
"transition_start": null,
"turbulence": [],
"type": "FROM",
"visibility": {
"repr": "4000",
"spoken": "four thousand",
"value": 4000
},
"wind_direction": null,
"wind_gust": null,
"wind_shear": null,
"wind_speed": null,
"wind_variable_direction": [],
"wx_codes": [
{
"repr": "BR",
"value": "Mist"
},
{
"repr": "FZFG",
"value": "Freezing Fog"
}
]
}
]
I don't have access to the API so I'm not sure how to reproduce it myself. I was investigating this data to be used in a project, I believe our integration team pulls this data from the taf
endpoint.
I was hoping that using ?onfail=nearest
would return closest airport that reports TAFs. But I think it just returns the closest airport that reports anything including METARs. Is that expected behavior?
useful for more easily knowing how old the data received is.
Hi,
when a client submits a non-existing icao code, the API returns correctly an error message
{
"Error": "Station Lookup Error: METAR not found for ABCD. There might not be a current report in ADDS",
"Meta": {
"Timestamp": "Sun, 18 Feb 2018 20:20:21 GMT"
}
}
but the HTTP code is 200.
curl -I 'https://avwx.rest/api/metar/ABCD'
HTTP/1.1 200 OK
Content-Length: 176
Content-Type: application/json
Server: gunicorn/19.7.1
Access-Control-Allow-Origin: *
Date: Sun, 18 Feb 2018 20:32:36 GMT
I believe the api.py
should handle this and return an appropriate error code to the client. In the if error:
case:
maybe simply:
if error:
resp = jsonify({'Error': error})
resp.status_code = 404
return resp
hello
thank you for this API but have wrong info
example:
OIIE -> have two runway (11R/29L && 11L/29R) but this api show me the just on runway
Hi,
The https://avwx.rest/ server seems to be currently out.
Is it a temporary issue and, if yes, when do you think it could be available again?
Thanks
Pierre
End time of highlighted TEMPO group not correctly returning "dt" field:
CYVO 061738Z 0618/0706 07005KT P6SM -SN OVC060 TEMPO 0618/0620 3SM -SN BKN030 OVC060 FM062000 06008KT 11/2SM -SN OVC012 TEMPO 0620/0624 6SM -SN OVC025 FM070000 03005KT P6SM -SN OVC025 TEMPO 0700/0702 21/2SM -SN OVC015 FM070200 03005KT P6SM -SN OVC025 PROB30 0702/0704 3SM -FZDZ BR RMK NXT FCST BY 070000Z
"end_time": { "repr": "0624", "dt": "Wed, 06 Feb 2019 00:00:00 GMT" }
Confusingly "0624" represents "Thu, 07 Feb 2019 00:00:00 GMT". ie it should wrap around to midnight the next day. "0600" represents "Wed, 06 Feb 2019 00:00:00 GMT".
Also, could consideration be given to returning the "dt" field as an ISO 8601 date for unambiguous compatibility with more clients? I'm pretty sure python has an isoformat method on datetime objects. It's more succinct while retaining readability. Discussion here:
https://stackoverflow.com/questions/10286204/the-right-json-date-format
start_time.dt
and end_time.dt
is always formatted in the correct ISO 8601 format
The format differs from location to location.
https://avwx.rest/api/taf/EBBR
Raw TAF: EBBR 050501Z 0506/0612 06011KT CAVOK
"start_time": {
"repr": "0506",
"dt": "2020-05-05T06:00:00+00:00Z"
}
https://avwx.rest/api/taf/ELLX
Raw TAF: ELLX 050500Z 0506/0612 04010KT CAVOK
"start_time": {
"repr": "0506",
"dt": "2020-05-05T06:00:00Z"
}
It becomes especially difficult when this time has to be parsed for different weather stations. Tools like Moment.js fail.
Furthermore, the notation for EBBR does not appear to be correct. The letter "Z" should never be added when using "+00:00".
One of my lookups for the OMAA ICAO responded with this error:
https://avwx.rest/api/metar/omaa
"Report Lookup Error: Unable to fetch report from NOAA. You might wish to use '?onfail=cache' to return the most recent report even if it's not up-to-date"
A few minutes prior to the lookup that caused this, I had been getting metar information just fine. I decided to add the ?onfail=cache
to the request, since I'd rather get some out of date info instead of no info, and then I got this response:
https://avwx.rest/api/metar/omaa?onfail=cache
"No report or cache was found for the requested station"
Something seems odd because I had been getting responses back previously. Unless the cache got dropped for some reason, or I'm misunderstanding the feature.
When parsing the example TAF below the highlighted visibility is returned with an incorrect value:
CYBC 051338Z 0514/0602 09018G28KT 1/2SM SN VV005 TEMPO 0514/0515 2SM -SN OVC012 FM051500 05012G22KT 11/2SM -SN VV008 TEMPO 0515/0523 3SM -SN OVC010 BECMG 0518/0520 34010KT FM052300 32008KT P6SM BKN030 TEMPO 0523/0601 5SM -SN BKN020 FM060100 31008KT P6SM SCT030 RMK FCST BASED ON AUTO OBS. NXT FCST BY 052000Z
"visibility": { "repr": "11/2", "value": 5.5, "spoken": "five and one half", "numerator": 11, "denominator": 2, "normalized": "5 1/2" }
The numerator should only ever be the single digit before the slash. The preceding figures are units.
Hi
My interpretation of requesting a TAF for the nearest airport would be that the nearest valid report is returned. However, the API currently returns a TAF from the nearest airport, regardless whether or not it is still valid.
For example, the request https://avwx.rest/api/taf/-31.52,115.94?onfail=nearest
resulted in (filtered for end_time
, meta
and raw
):
{
"end_time": {
"dt": "2023-12-04T09:00:00Z",
"repr": "0409"
},
"meta": {
"stations_updated": "2023-10-28",
"timestamp": "2023-12-04T11:28:55.201236Z"
},
"raw": "YGIG 032209Z 0400/0409 20008KT 9999 SCT025 FM040200 22016KT 9999 FEW035 RMK T 22 26 27 23 Q 1016 1016 1016 1016"
}
Note the report end-time of "0409" but the request was made almost 2.5h later (ie. after "0411").
Also note that I've tried the onfail=nearest
option, but it didn't make a difference.
An airport with a 24/7 TAF (YPEA) would be available only slightly further away from the requested location.
Hi @flyinactor91 👋
I noticed that the api.geonames.org services randomly returns outdated metar when querying by coordinates.
Here are two consecutive calls with the same parameters with different results. The correct one is the 1st one (210920Z
)
curl http://api.geonames.org/findNearByWeatherJSON\?lat\=35.237\&lng\=-120.643\&radius\=200\&username\=myusername | jq ".weatherObservation.observation"
"KSBP 210920Z AUTO 00000KT 10SM BKN020 BKN033 09/08 A3007 RMK AO2 T00890078 $"
curl http://api.geonames.org/findNearByWeatherJSON\?lat\=35.237\&lng\=-120.643\&radius\=200\&username\=myusername | jq ".weatherObservation.observation"
"KSBP 161415Z 00000KT 1 3/4SM -RA BR OVC005 11/09 A2998 RMK AO2 RAB12 P0000 T01060094"
This happens quite sporadically.
Have you had issues with that before? I wonder if it would be better to always query the aviationweather.gov service for the actual report and use geonames.org to only to get the station name and discard its returned report here
cheers
see title.
Hi again :)
I noticed an exception when the metar contains the $
sign:
Updating cache : {'data': {'Remarks': 'RMK AO2 SLP247 T00611089 $', 'Runway-Vis-List': [], 'Station': 'KNYL', 'Time': '241057Z', 'Cloud-List': [], 'Wind-Direction': '350', 'Wind-Speed': '03', 'Wind-Gust': '', 'Wind-Variable-Dir': [], 'Altimeter': '3026', 'Visibility': '10', 'Other-List': [], 'Temperature': '06', 'Dewpoint': 'M09', 'Units': {'Wind-Speed': 'kt', 'Visibility': 'sm', 'Altitude': 'ft', 'Temperature': 'C', 'Altimeter': 'inHg'}, 'Flight-Rules': 'VFR', 'Remarks-Info': {'Temp-Decimal': '6.1', 'Dew-Decimal': '-8.9'}, 'Raw-Report': 'KNYL 241057Z AUTO 35003KT 10SM CLR 06/M09 A3026 RMK AO2 SLP247 T00611089 $'}, 'translate': {'Visibility': '10sm (16.1km)', 'Altimeter': '30.26inHg (1025hPa)', 'Clouds': 'Sky clear', 'Other': '', 'Wind': 'N-350 at 03kt', 'Temperature': '06C (43F)', 'Dewpoint': '-09C (16F)', 'Remarks': {'AO2': 'Automated with precipitation sensor', 'SLP247': 'Sea level pressure: 1024.7 hPa', 'T00611089': 'Temperature 6.1°C and dewpoint -8.9°C', '$': 'ASOS requires maintenance'}}, 'summary': 'Winds N-350 at 03kt, Vis 10sm, Temp 06C, Dew -09C, Alt 30.26inHg, Sky clear', 'speech': 'Winds three five zero at 3kt. Visibility one zero miles. Temperature six degrees Celsius. Dew point minus nine degrees Celsius. Altimeter three zero point two six. Sky clear'}
[2018-02-24 12:04:14,995] ERROR in app: Exception on /api/metar/KNYL [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.6/site-packages/flask_restful/__init__.py", line 480, in wrapper
resp = resource(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/flask_restful/__init__.py", line 595, in dispatch_request
resp = meth(*args, **kwargs)
File "/Volumes/MySamsung/xworkspace/aviation/AVWX-API/avwx_api/api.py", line 101, in get
return self.get_report(rtype, station)
File "/Volumes/MySamsung/xworkspace/aviation/AVWX-API/avwx_api/api.py", line 91, in get_report
resp = handle_report(rtype, station, options, nofail)
File "/Volumes/MySamsung/xworkspace/aviation/AVWX-API/avwx_api/handling.py", line 114, in handle_report
data = CACHE.get(rtype, station) or new_report(rtype, station, report)
File "/Volumes/MySamsung/xworkspace/aviation/AVWX-API/avwx_api/handling.py", line 78, in new_report
CACHE.update(rtype, data)
File "/Volumes/MySamsung/xworkspace/aviation/AVWX-API/avwx_api/cache.py", line 48, in update
self.tables[rtype].update({'_id': data['data']['Station']}, data, upsert=True)
File "/usr/local/lib/python3.6/site-packages/pymongo/collection.py", line 2968, in update
write_concern, collation=collation)
File "/usr/local/lib/python3.6/site-packages/pymongo/collection.py", line 835, in _update_retryable
_update, session)
File "/usr/local/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1099, in _retryable_write
return self._retry_with_session(retryable, func, s, None)
File "/usr/local/lib/python3.6/site-packages/pymongo/mongo_client.py", line 1076, in _retry_with_session
return func(session, sock_info, retryable)
File "/usr/local/lib/python3.6/site-packages/pymongo/collection.py", line 831, in _update
retryable_write=retryable_write)
File "/usr/local/lib/python3.6/site-packages/pymongo/collection.py", line 797, in _update
_check_write_command_response(result)
File "/usr/local/lib/python3.6/site-packages/pymongo/helpers.py", line 208, in _check_write_command_response
_raise_last_write_error(write_errors)
File "/usr/local/lib/python3.6/site-packages/pymongo/helpers.py", line 190, in _raise_last_write_error
raise WriteError(error.get("errmsg"), error.get("code"), error)
pymongo.errors.WriteError: The dollar ($) prefixed field '$' in 'translate.Remarks.$' is not valid for storage.
I believe the the data
should be encoded before inserting them at
https://github.com/flyinactor91/AVWX-API/blob/bed76e4960d46420d2fdcfe424fa814182c2760c/avwx_api/cache.py#L48
Good day,
I noticed as per your blog post that come Nov 1st, there will be a mandatory authorization token required for all requests (even Hobby level).
I've made changes to my clients to allow for this, but it's not clear if its being done correctly. Even when including a phony token I'm still getting 200s from my requests. I am worried that, since I can't test my implementation with the token, that I might have an interruption on Nov 1st.
Is there something that I can do to ensure that my requests are conforming to the new requirements ahead of the switchover?
We are getting some fairly frequent (multiple times a day) 502's coming back from the API. They appear like this:
{
"meta": {
"timestamp": "2019-08-08T16:06:27.607719Z"
},
"error": "Report Lookup Error: Unable to reach data source after 5 attempts"
}
The lookup is against OMAA station (Abu Dhabi Intl). We are using a free account on avwx for these queries.
Started October 30, there is a CORS issue in the official API link (https://avwx.rest/api/metar/)
Tested with the URL used on the API doc works correctly (https://private-anon-93b4379efd-avwx.apiary-proxy.com/api/metar/)
After testing the response headers from both links, it looks like the OPTIONS is missing in the header access-control-allow-headers for the offical API link.
See attached images
Thanks for looking at that.
Apologies if this has already been requested, but have y'all given thought to adding MOS forecasts? Being able to get a longer-range prediction than the TAF provides would be pretty useful for what I'm working on!
Looks like you reached your quota on Azure. We would be gladly pay for an api key if you stop using the free Azure server(?).
Thnx1
Hi,
I have a docker file that I got from Dockerfile.sample. It builds but hypercorn outputs this error. When I try with gunicorn, I get the same issue. Did I miss a doc or something?
[2020-06-08 08:58:10 +0000] [10] [INFO] Starting gunicorn 20.0.4
[2020-06-08 08:58:10 +0000] [10] [INFO] Listening at: http://0.0.0.0:5000 (10)
[2020-06-08 08:58:10 +0000] [10] [INFO] Using worker: sync
[2020-06-08 08:58:10 +0000] [16] [INFO] Booting worker with pid: 16
[2020-06-08 08:58:11 +0000] [16] [ERROR] Exception in worker process
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
worker.init_process()
File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process
self.load_wsgi()
File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
self.wsgi = self.app.wsgi()
File "/usr/local/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
return self.load_wsgiapp()
File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
return util.import_app(self.app_uri)
File "/usr/local/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
mod = importlib.import_module(module)
File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/avwx/avwx_api/__init__.py", line 3, in <module>
from avwx_api import api, views, status
File "/home/avwx/avwx_api/api/__init__.py", line 1, in <module>
from . import current, gfs, station
File "/home/avwx/avwx_api/api/current.py", line 14, in <module>
class MetarFetch(Report):
File "/usr/local/lib/python3.8/site-packages/quart_openapi/pint.py", line 286, in decorator
self._add_resource(func_or_viewcls, path, methods, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/quart_openapi/pint.py", line 199, in _add_resource
super().add_url_rule(path, endpoint, view_func, methods, # pylint: disable=no-member
TypeError: add_url_rule() got multiple values for argument 'provide_automatic_options'
I tried directly on my machine, installing the requirements with pip -Ruv requirements.txt. I followed the docker file basically and ended up with the same error:
seanodea@aurvandr ~/code/flsb/flsb-flask/avwx-api (master)$ hypercorn avwx_api:app --bind 0.0.0.0:5000 -c python:hypercorn_config.py
Process Process-2:
Process Process-1:
Process Process-3:
Traceback (most recent call last):
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/asyncio/run.py", line 163, in asyncio_worker
app = load_application(config.application_path)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/utils.py", line 92, in load_application
module = import_module(import_name)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/__init__.py", line 3, in <module>
from avwx_api import api, views
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/__init__.py", line 1, in <module>
from . import current, gfs, station
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/current.py", line 14, in <module>
class MetarFetch(Report):
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 286, in decorator
self._add_resource(func_or_viewcls, path, methods, *args, **kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 199, in _add_resource
super().add_url_rule(path, endpoint, view_func, methods, # pylint: disable=no-member
TypeError: add_url_rule() got multiple values for argument 'provide_automatic_options'
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/asyncio/run.py", line 163, in asyncio_worker
app = load_application(config.application_path)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/utils.py", line 92, in load_application
module = import_module(import_name)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/__init__.py", line 3, in <module>
from avwx_api import api, views
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/__init__.py", line 1, in <module>
from . import current, gfs, station
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/current.py", line 14, in <module>
class MetarFetch(Report):
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 286, in decorator
self._add_resource(func_or_viewcls, path, methods, *args, **kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 199, in _add_resource
super().add_url_rule(path, endpoint, view_func, methods, # pylint: disable=no-member
TypeError: add_url_rule() got multiple values for argument 'provide_automatic_options'
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/asyncio/run.py", line 163, in asyncio_worker
app = load_application(config.application_path)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/utils.py", line 92, in load_application
module = import_module(import_name)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/__init__.py", line 3, in <module>
from avwx_api import api, views
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/__init__.py", line 1, in <module>
from . import current, gfs, station/home/seanodea
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/current.py", line 14, in <module>
class MetarFetch(Report):
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 286, in decorator
self._add_resource(func_or_viewcls, path, methods, *args, **kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 199, in _add_resource
super().add_url_rule(path, endpoint, view_func, methods, # pylint: disable=no-member
TypeError: add_url_rule() got multiple values for argument 'provide_automatic_options'
Process Process-4:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/asyncio/run.py", line 163, in asyncio_worker
app = load_application(config.application_path)
File "/home/seanodea/.local/lib/python3.8/site-packages/hypercorn/utils.py", line 92, in load_application
module = import_module(import_name)
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 783, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/__init__.py", line 3, in <module>
from avwx_api import api, views
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/__init__.py", line 1, in <module>
from . import current, gfs, station
File "/home/seanodea/code/fl-statusboard/flsb-flask/avwx-api/avwx_api/api/current.py", line 14, in <module>
class MetarFetch(Report):
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 286, in decorator
self._add_resource(func_or_viewcls, path, methods, *args, **kwargs)
File "/home/seanodea/.local/lib/python3.8/site-packages/quart_openapi/pint.py", line 199, in _add_resource
super().add_url_rule(path, endpoint, view_func, methods, # pylint: disable=no-member
TypeError: add_url_rule() got multiple values for argument 'provide_automatic_options'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.