pax_global_header 0000666 0000000 0000000 00000000064 13025724302 0014510 g ustar 00root root 0000000 0000000 52 comment=9e30affa831629be47d6693fad3af6102a3c056d
HydrelioxGitHub-pyiss-9e30aff/ 0000775 0000000 0000000 00000000000 13025724302 0016426 5 ustar 00root root 0000000 0000000 HydrelioxGitHub-pyiss-9e30aff/.travis.yml 0000664 0000000 0000000 00000000367 13025724302 0020545 0 ustar 00root root 0000000 0000000 language: python
python:
- "3.3"
- "3.4"
- "3.5"
# command to install dependencies
install:
- pip install -r requirements.txt
- pip install coveralls
script:
nosetests -v --with-coverage --cover-package=pyiss
after_success:
coveralls HydrelioxGitHub-pyiss-9e30aff/LICENSE 0000664 0000000 0000000 00000002052 13025724302 0017432 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2016 Hydreliox
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
HydrelioxGitHub-pyiss-9e30aff/README.md 0000664 0000000 0000000 00000003307 13025724302 0017710 0 ustar 00root root 0000000 0000000 PyIss
===================
[](https://coveralls.io/github/HydrelioxGitHub/pyiss)
[](https://travis-ci.org/HydrelioxGitHub/pyiss)
[](https://badge.fury.io/py/pyiss)

### Library
**PyIss** is a Python3 library to access to International Space Station location and data
- This library has been developed using this [API](http://open-notify.org/)
- This library is for Python3 version 3.3 and upper.
### Installation
There are many ways to install ``pyiss``:
* With pip (preferred), do ``pip install pyiss``.
* To install from source, download it from
https://github.com/HydrelioxGitHub/pyiss/ and do
``python setup.py install``.
### Usage
To use ``pyiss``, just import it in your project like so::
>>> import pyiss
Afterwards, you can have access to ISS location::
>>> station = pyiss.ISS()
>>> print(station.current_location())
{'longitude': '133.6864', 'latitude': '51.4806'}
Other details::
>>> print(station.pass_times(1, 1))
>>> print(station.number_of_people_in_space())
>>> print(station.seconds_before_next_rise(-50.2322, 76.5668))
>>> print(station.is_ISS_above(4,71, 7))
>>> print(station.next_rise(2, 5, 6).timestamp())
That's it!
Documentation is coming !
### License
``pyiss`` is distributed under the MIT license.
HydrelioxGitHub-pyiss-9e30aff/pyiss/ 0000775 0000000 0000000 00000000000 13025724302 0017575 5 ustar 00root root 0000000 0000000 HydrelioxGitHub-pyiss-9e30aff/pyiss/__init__.py 0000664 0000000 0000000 00000012050 13025724302 0021704 0 ustar 00root root 0000000 0000000 from datetime import datetime
import requests
from voluptuous import Schema, Required, All, Any, Length, Range
class ISS(object):
"""Representation of the ISS details."""
API_URL = "http://api.open-notify.org/"
API_CURRENT_LOCATION = "iss-now.json"
API_PASS_TIMES = "iss-pass.json"
API_PEOPLE = "astros.json"
def __init__(self):
return
def people_in_space(self):
"""Number of people in space.
Be aware that does not mean these people are inside the ISS (it does
most of the time), They can be travelling to and from the station.
:return: Return a dict with number of people in space right now and
their name and their craft
:rtype: dict
"""
data = requests.get('{}{}'.format(self.API_URL, self.API_PEOPLE),
timeout=5)
if data.status_code is 200:
return data.json()
else:
raise Exception("Error server n {}".format(data.status_code))
def current_location(self):
"""Current location of the ISS.
:return: A dict with latitude and longitude of ISS
:rtype: dict
"""
data = requests.get('{}{}'.format(
self.API_URL, self.API_CURRENT_LOCATION), timeout=5)
if data.status_code is 200:
return data.json()['iss_position']
else:
raise Exception("Error server n {}".format(data.status_code))
def pass_times(self, latitude, longitude, altitude=None, number=None):
"""The next pass times of the ISS.
:param latitude: latitude in degrees of location you want iss pass
above
:type latitude: float
:param longitude: longitude in degrees of location you want iss pass
above
:type longitude: float
:param altitude: altitude in meters of location you want iss pass
above, default is 100 when not given
:type altitude: float
:param number: number of next pass above the location, default is 5
if not given. Min is 1, max is 100
:type number: int
:return: a list of the next pass of the ISS with the risetime and
the duration
:rtype: list
"""
# Check input
schema = Schema({
Required('lat'): All(Any(int, float), Range(min=-80, max=80)),
Required('long'): All(Any(int, float), Range(min=-180, max=180)),
'alt': Any(None, All(Any(int, float), Range(min=0, max=10000))),
'number': Any(None, All(int, Range(min=1, max=100)))
})
schema({
'lat' : latitude, 'long': longitude, 'alt' : altitude,
'number': number})
# Build request
payload = {'lat': latitude, 'lon': longitude}
if altitude is not None:
payload['alt'] = altitude
if number is not None:
payload['n'] = number
data = requests.get('{}{}'.format(self.API_URL, self.API_PASS_TIMES),
params=payload, timeout=5)
# Check error
if data.status_code is 200:
return data.json()['response']
else:
raise Exception("Error server n {}".format(data.status_code))
def number_of_people_in_space(self):
"""The number of people onboard the ISS at the moment.
:return: The number of people in space right now
:rtype: int
"""
return self.people_in_space()['number']
def next_rise(self, latitude, longitude, altitude=None):
"""The next rise of the ISS.
:param latitude: latitude in degrees of location you want iss pass
above
:type latitude: float
:param longitude: longitude in degrees of location you want iss pass
above
:type longitude: float
:param altitude: altitude in meters of location you want iss pass
above, default is 100 when not given
:type altitude: float
:return: Return the next date when ISS will be over 10 degree above the
horizon
:rtype: datetime
"""
rise = self.pass_times(latitude, longitude, altitude,
2)
timestamp = rise[0]['risetime']
return datetime.fromtimestamp(timestamp)
def is_ISS_above(self, latitude, longitude, altitude=None):
"""Location of the ISS regardin the current location.
:param latitude: latitude in degrees of location you want iss pass
above
:type latitude: float
:param longitude: longitude in degrees of location you want iss pass
above
:type longitude: float
:param altitude: altitude in meters of location you want iss pass
above, default is 100 when not given
:type altitude: float
:return: True if the ISS is above the location, False if not
:rtype: bool
"""
test = self.pass_times(latitude, longitude, altitude, 2)
# 2 results where asked so if API return only 1, that mean ISS is
# above the location
return len(test) is 1
if __name__ == '__main__':
iss = ISS()
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/ 0000775 0000000 0000000 00000000000 13025724302 0020737 5 ustar 00root root 0000000 0000000 HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/__init__.py 0000664 0000000 0000000 00000000000 13025724302 0023036 0 ustar 00root root 0000000 0000000 HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_current_location.py 0000664 0000000 0000000 00000003370 13025724302 0025725 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
class TestCurrent_location(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
#Json response
self.json_current_location = {"timestamp": 1481410143, "message": "success", "iss_position": {"latitude": "6.8272", "longitude": "-160.2689"}}
#HTTP Mock
@all_requests
def correct_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_current_location, headers, None, 5,
request)
self.http_correct = correct_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_current_location, headers, None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_current_location_json_return(self):
"""
Test that the function return the right dict answer
"""
with HTTMock(self.http_correct):
response = self.iss.current_location()
location = {"latitude": "6.8272", "longitude": "-160.2689"}
self.assertDictEqual(response, location)
def test_current_location_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.current_location )
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_is_ISS_above.py 0000664 0000000 0000000 00000007514 13025724302 0024664 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
class TestIs_ISS_above(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
# Json response
self.json_is_ISS_above_false = {
"message": "success",
"request": {
"altitude": 100,
"datetime": 1481418788,
"latitude": 15.0,
"longitude": 20.0,
"passes": 5
},
"response": [
{
"duration": 348,
"risetime": 1481448840
},
{
"duration": 634,
"risetime": 1481454465
}
]
}
self.json_is_ISS_above_true = {
"message": "success",
"request": {
"altitude": 100,
"datetime": 1481418788,
"latitude": 15.0,
"longitude": 20.0,
"passes": 5
},
"response": [
{
"duration": 348,
"risetime": 1481448840
}
]
}
# HTTP Mock
@all_requests
def true_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_is_ISS_above_true, headers, None, 5,
request)
self.http_true = true_response
@all_requests
def false_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_is_ISS_above_false, headers, None,
5,
request)
self.http_false = false_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_is_ISS_above, headers, None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_is_ISS_above_true(self):
"""
Test that json match a true answer
"""
with HTTMock(self.http_true):
response = self.iss.is_ISS_above(20, 15)
self.assertTrue(response)
def test_is_ISS_above_false(self):
"""
Test that json match a false answer
"""
with HTTMock(self.http_false):
response = self.iss.is_ISS_above(20, 15)
self.assertFalse(response)
def test_is_ISS_above_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.is_ISS_above, 15, 20)
def test_is_ISS_above_input_bound(self):
"""
Test that input raise exception using voluptuous
Each set of data test a boundary
"""
with HTTMock(self.http_true):
data = [[-80.1, 1, 1], [80.1, 1, 1], [1, -180.1, 1],
[1, 180.1, 1], [1, 1, -1], [1, 1, 10000.1]]
for value in data:
self.assertRaises(Exception, self.iss.is_ISS_above, value[0],
value[1], value[2])
data = [[-80, 1, 1], [80, 1, 1], [1, -180, 1],
[1, 180, 1], [1, 1, 0], [1, 1, 10000]]
for value in data:
self.assertTrue(self.iss.is_ISS_above(value[0],
value[1], value[2]))
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_next_rise.py 0000664 0000000 0000000 00000006642 13025724302 0024360 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
import datetime
class TestNext_rise(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
# Json response
self.json_next_rise = {
"message": "success",
"request": {
"altitude": 100,
"datetime": 1481418788,
"latitude": 15.0,
"longitude": 20.0,
"passes": 5
},
"response": [
{
"duration": 348,
"risetime": 1481448840
},
{
"duration": 634,
"risetime": 1481454465
},
{
"duration": 220,
"risetime": 1481460482
},
{
"duration": 224,
"risetime": 1481484335
},
{
"duration": 640,
"risetime": 1481489937
}
]
}
self.timestamp_next_rise = self.json_next_rise['response'][0][
"risetime"]
# HTTP Mock
@all_requests
def correct_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_next_rise, headers, None, 5,
request)
self.http_correct = correct_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_next_rise, headers, None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_next_rise_json_return(self):
"""
Test that the function return the right datetime
"""
with HTTMock(self.http_correct):
response = self.iss.next_rise(20, 15)
self.assertEqual(self.timestamp_next_rise, response.timestamp())
def test_next_rise_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.next_rise, 15, 20)
def test_next_rise_input_bound(self):
"""
Test that input raise exception using voluptuous
Each set of data test a boundary
"""
with HTTMock(self.http_correct):
data = [[-80.1, 1, 1], [80.1, 1, 1], [1, -180.1, 1],
[1, 180.1, 1], [1, 1, -1], [1, 1, 10000.1]]
for value in data:
self.assertRaises(Exception, self.iss.next_rise, value[0],
value[1], value[2])
data = [[-80, 1, 1], [80, 1, 1], [1, -180, 1],
[1, 180, 1], [1, 1, 0], [1, 1, 10000]]
for value in data:
self.assertEqual(self.timestamp_next_rise,
self.iss.next_rise(value[0],
value[1],
value[2]).timestamp())
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_number_of_people_in_space.py 0000664 0000000 0000000 00000004241 13025724302 0027532 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
class TestNumber_of_people_in_space(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
# Json response
self.json_number_of_people_in_space = {
"people": [{"craft": "ISS", "name": "Sergey Rizhikov"},
{"craft": "ISS", "name": "Andrey Borisenko"},
{"craft": "ISS", "name": "Shane Kimbrough"},
{"craft": "ISS", "name": "Oleg Novitskiy"},
{"craft": "ISS", "name": "Thomas Pesquet"},
{"craft": "ISS", "name": "Peggy Whitson"}],
"message": "success", "number": 6}
# HTTP Mock
@all_requests
def correct_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_number_of_people_in_space, headers,
None, 5,
request)
self.http_correct = correct_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_number_of_people_in_space, headers,
None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_number_of_people_in_space_json_return(self):
"""
Test that the function return the right number
"""
with HTTMock(self.http_correct):
self.assertEqual(self.iss.number_of_people_in_space(),
self.json_number_of_people_in_space['number'])
def test_number_of_people_in_space_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.number_of_people_in_space)
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_pass_times.py 0000664 0000000 0000000 00000006777 13025724302 0024540 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
class TestPass_times(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
# Json response
self.json_pass_times = {
"message": "success",
"request": {
"altitude": 100,
"datetime": 1481418788,
"latitude": 15.0,
"longitude": 20.0,
"passes": 5
},
"response": [
{
"duration": 348,
"risetime": 1481448840
},
{
"duration": 634,
"risetime": 1481454465
},
{
"duration": 220,
"risetime": 1481460482
},
{
"duration": 224,
"risetime": 1481484335
},
{
"duration": 640,
"risetime": 1481489937
}
]
}
self.location = self.json_pass_times['response']
#HTTP Mock
@all_requests
def correct_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_pass_times, headers, None, 5,
request)
self.http_correct = correct_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_pass_times, headers, None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_pass_times_json_return(self):
"""
Test that the function return the right list answer
"""
with HTTMock(self.http_correct):
response = self.iss.pass_times(20, 15)
self.assertListEqual(self.location, response)
def test_pass_times_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.pass_times, 15,20)
def test_pass_times_input_bound(self):
"""
Test that input raise exception using voluptuous
Each set of data test a boundary
"""
with HTTMock(self.http_correct):
data = [[-80.1, 1, 1, 1], [80.1, 1, 1, 1], [1, -180.1, 1, 1],
[1, 180.1, 1, 1], [1, 1, -1, 1], [1, 1, 10000.1, 1],
[1, 1, 1, 0], [1, 1, 1, 101], [1, 1, 1, 5.1]]
for value in data:
self.assertRaises(Exception, self.iss.pass_times, value[0],
value[1], value[2], value[3])
data = [[-80, 1, 1, 1], [80, 1, 1, 1], [1, -180, 1, 1],
[1, 180, 1, 1], [1, 1, 0, 1], [1, 1, 10000, 1],
[1, 1, 1, 1], [1, 1, 1, 100]]
for value in data:
self.assertListEqual(self.location,
self.iss.pass_times(value[0],
value[1], value[2],
value[3]))
HydrelioxGitHub-pyiss-9e30aff/pyiss/tests/test_people_in_space.py 0000664 0000000 0000000 00000004014 13025724302 0025474 0 ustar 00root root 0000000 0000000 from unittest import TestCase
from httmock import all_requests, HTTMock, response
import pyiss
class TestPeople_in_space(TestCase):
def setUp(self):
"""
Instantiate the Http Request Mock, the ISS class call and the json response
"""
#Json response
self.json_people_in_space = {
"people": [{"craft": "ISS", "name": "Sergey Rizhikov"},
{"craft": "ISS", "name": "Andrey Borisenko"},
{"craft": "ISS", "name": "Shane Kimbrough"},
{"craft": "ISS", "name": "Oleg Novitskiy"},
{"craft": "ISS", "name": "Thomas Pesquet"},
{"craft": "ISS", "name": "Peggy Whitson"}],
"message": "success", "number": 6}
#HTTP Mock
@all_requests
def correct_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(200, self.json_people_in_space, headers, None, 5,
request)
self.http_correct = correct_response
@all_requests
def wrong_response(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
return response(403, self.json_people_in_space, headers, None, 5,
request)
self.http_wrong = wrong_response
self.iss = pyiss.ISS()
def test_people_in_space_json_return(self):
"""
Test that the function return the right json answer
"""
with HTTMock(self.http_correct):
response = self.iss.people_in_space()
self.assertDictEqual(response, self.json_people_in_space)
def test_people_in_space_error_server(self):
"""
Test that the function raise an exception if the server response is not correct
"""
with HTTMock(self.http_wrong):
self.assertRaises(Exception, self.iss.people_in_space) HydrelioxGitHub-pyiss-9e30aff/requirements.txt 0000664 0000000 0000000 00000000033 13025724302 0021706 0 ustar 00root root 0000000 0000000 requests
httmock
voluptuous HydrelioxGitHub-pyiss-9e30aff/setup.cfg 0000664 0000000 0000000 00000000047 13025724302 0020250 0 ustar 00root root 0000000 0000000 [metadata]
description-file = README.md HydrelioxGitHub-pyiss-9e30aff/setup.py 0000664 0000000 0000000 00000001324 13025724302 0020140 0 ustar 00root root 0000000 0000000 from setuptools import setup
setup(
name = 'pyiss',
packages = ['pyiss'], # this must be the same as the name above
install_requires = ['requests', 'httmock', 'voluptuous'],
version = '1.0.1',
description = 'A simple python3 library for info about the current '
'International Space Station location',
author = 'Hydreliox',
author_email = 'hydreliox@gmail.com',
license = 'MIT',
url = 'https://github.com/HydrelioxGitHub/pyiss', # use the URL to the
# github repo
download_url = 'https://github.com/HydrelioxGitHub/pyiss/tarball/1.0.1',
keywords = ['ISS', 'space', 'station', 'API'], # arbitrary keywords
classifiers = [],
test_suite='nose.collector',
tests_require=['nose'],
)