Skip to content

Commit fc96bea

Browse files
authored
Merge pull request #85 from jaluebbe/dev/oauth2_migration
Migrated Python API to oauth2. Included some fiexes and optimisations mentioned by the community. Moved from setup.py to pyproject.toml .
2 parents 56e6cd6 + 16b2c0b commit fc96bea

8 files changed

Lines changed: 474 additions & 247 deletions

File tree

README.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,67 @@
33
This repository contains API client implementations for the OpenSky Network in
44
Python and Java as well as the sources for the [documentation](https://openskynetwork.github.io/opensky-api/). By using the OpenSky API, you agree with our [terms of use](https://opensky-network.org/about/terms-of-use). We may block AWS and other hyperscalers due to generalized abuse from these IPs.
55

6-
Note that these implementations are not actively maintained and serve mostly as examples. Java and Python are written for legacy accounts and authenticated usage will stop working without modifications from March 18, 2026.
6+
Note that the Java implementation is not actively maintained and serves mostly as an example. The Python implementation has been updated to support OAuth2 authentication as required from March 18, 2026.
77

88
For actively maintained libraries, check our [Data Tools](https://opensky-network.org/data/tools) page, which includes many third-party and community tools.
99

1010
## Python API
1111

12-
* depends on the python-requests library (http://docs.python-requests.org/)
13-
* both compatible with Python 2 and 3 (tested with 2.7 and 3.5)
12+
* Requires Python 3.10 or later
13+
* Depends on the [requests](http://docs.python-requests.org/) library
14+
* Authentication uses the OAuth2 client credentials flow (see [Authentication](#authentication))
1415

1516
### Installation
1617

18+
Install directly from GitHub using pip (recommended):
19+
1720
```
18-
sudo python setup.py install
21+
pip install "git+https://github.com/openskynetwork/opensky-api.git#subdirectory=python"
1922
```
2023

21-
or with pip (recommended)
24+
Or clone the repository and install locally:
2225

2326
```
24-
pip install -e /path/to/repository/python
27+
git clone https://github.com/openskynetwork/opensky-api.git
28+
pip install -e opensky-api/python
2529
```
2630

31+
### Authentication
32+
33+
Since March 18, 2026, basic authentication with username and password is no longer supported.
34+
Authentication now uses the OAuth2 client credentials flow.
35+
36+
1. Log in to your OpenSky account and visit the [Account](https://opensky-network.org/my-opensky/account) page.
37+
2. Create a new API client and download the credentials file (`credentials.json`).
38+
3. Pass the credentials to the API client as shown below.
39+
40+
Without credentials, requests are made anonymously with reduced rate limits.
41+
2742
### Usage
2843

29-
```
44+
Anonymous access (reduced rate limits):
45+
46+
```python
3047
from opensky_api import OpenSkyApi
48+
3149
api = OpenSkyApi()
3250
s = api.get_states()
3351
print(s)
3452
```
3553

36-
will output something like this:
54+
Authenticated access using a credentials file:
55+
56+
```python
57+
from opensky_api import OpenSkyApi, TokenManager
58+
59+
api = OpenSkyApi(token_manager=TokenManager.from_json_file("credentials.json"))
60+
s = api.get_states()
61+
print(s)
62+
```
63+
64+
The token is refreshed automatically before it expires, so no manual token management is required.
65+
66+
Example output:
3767

3868
```
3969
{

python/MANIFEST.in

Whitespace-only changes.

python/example.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Example usage of the OpenSky Network API client.
5+
#
6+
# Retrieves all aircraft currently over Germany and prints a summary,
7+
# then shows which of your own receivers are currently active.
8+
#
9+
# Author: Jannis Lübbe <luebbe@opensky-network.org>
10+
# URL: http://github.com/openskynetwork/opensky-api
11+
#
12+
import os
13+
14+
from opensky_api import OpenSkyApi, TokenManager
15+
16+
# Use credentials file if available, otherwise fall back to anonymous access.
17+
# Anonymous access has reduced rate limits and no access to own sensor data.
18+
_CREDENTIALS_PATH = "credentials.json"
19+
20+
21+
def fmt_alt(value):
22+
"""Format an altitude value, omitting the unit if the value is None."""
23+
return f"{value}m" if value is not None else "None"
24+
25+
26+
def main():
27+
if os.path.exists(_CREDENTIALS_PATH):
28+
tm = TokenManager.from_json_file(_CREDENTIALS_PATH)
29+
print("Authenticated with credentials file.")
30+
else:
31+
tm = None
32+
print("No credentials file found, using anonymous access (reduced rate limits).")
33+
34+
with OpenSkyApi(token_manager=tm) as api:
35+
# Get all aircraft currently over Germany (bounding box)
36+
print("\n--- Aircraft over Germany ---")
37+
states = api.get_states(bbox=(47.2, 55.1, 5.9, 15.1))
38+
if states and states.states:
39+
for s in states.states:
40+
print(
41+
f"{s.icao24:8s} {s.callsign or '?':10s} {s.origin_country:20s} "
42+
f"baro={fmt_alt(s.baro_altitude)} "
43+
f"geo={fmt_alt(s.geo_altitude)} "
44+
f"{'on ground' if s.on_ground else 'airborne'}"
45+
)
46+
else:
47+
print("No states received.")
48+
49+
# Show which own receivers are currently active and delivering data.
50+
# Requires authentication.
51+
if tm is not None:
52+
print("\n--- Own receivers ---")
53+
my_states = api.get_my_states()
54+
if my_states and my_states.states:
55+
active_serials = set()
56+
for s in my_states.states:
57+
if s.sensors:
58+
active_serials.update(s.sensors)
59+
if active_serials:
60+
print(f"Active serials providing data: {sorted(active_serials)}")
61+
else:
62+
print("No sensor information available in state vectors.")
63+
else:
64+
print("No states received from own receivers.")
65+
66+
67+
if __name__ == "__main__":
68+
main()

0 commit comments

Comments
 (0)