Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
onekiloparsec committed Aug 16, 2020
2 parents 6add143 + f02391c commit d6c1ef1
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 135 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ To delete a data file, one use its "id/pk" (pk = Primary Key == ID):
As a Python module:

>>> from arcsecond import ArcsecondAPI
>>> api = Arcsecond.build_datafiles_api(dataset='<dataset_uuid>')
>>> api = ArcsecondAPI.datafiles(dataset='<dataset_uuid>')
>>> api.create(file='<file path>')

More documentation is coming.
Expand Down
6 changes: 3 additions & 3 deletions arcsecond/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from .api import Arcsecond, ArcsecondError, ArcsecondConnectionError, ArcsecondInvalidEndpointError
from .api import ArcsecondAPI, ArcsecondError, ArcsecondConnectionError, ArcsecondInvalidEndpointError

name = 'arcsecond'

__all__ = ["Arcsecond",
__all__ = ["ArcsecondAPI",
"ArcsecondError",
"ArcsecondConnectionError",
"ArcsecondInvalidEndpointError"]

__version__ = '0.9.8'
__version__ = '1.0.0'
4 changes: 2 additions & 2 deletions arcsecond/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .error import ArcsecondConnectionError, ArcsecondError, ArcsecondInvalidEndpointError
from .main import Arcsecond
from .main import ArcsecondAPI

__all__ = ["Arcsecond",
__all__ = ["ArcsecondAPI",
"ArcsecondError",
"ArcsecondConnectionError",
"ArcsecondInvalidEndpointError"]
42 changes: 7 additions & 35 deletions arcsecond/api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,39 +84,12 @@ def factory(endpoint_class, state=None, **kwargs):
return ArcsecondAPI(endpoint_class, state, **kwargs)

for endpoint_class in ENDPOINTS:
func_name = 'build_' + endpoint_class.name + '_api'
setattr(cls, func_name, staticmethod(types.MethodType(factory, endpoint_class)))
setattr(cls, endpoint_class.name, staticmethod(types.MethodType(factory, endpoint_class)))

return cls


@set_api_factory
class Arcsecond(object):
@classmethod
def is_logged_in(cls, state=None, **kwargs):
return ArcsecondAPI.is_logged_in(state, **kwargs)

@classmethod
def username(cls, state=None, **kwargs):
return ArcsecondAPI.username(state, **kwargs)

@classmethod
def api_key(cls, state=None, **kwargs):
return ArcsecondAPI.api_key(state, **kwargs)

@classmethod
def memberships(cls, state=None, **kwargs):
return ArcsecondAPI.memberships(state, **kwargs)

@classmethod
def login(cls, username, password, subdomain, state=None, **kwargs):
return ArcsecondAPI.login(username, password, subdomain, state, **kwargs)

@classmethod
def register(cls, username, email, password1, password2, state=None, **kwargs):
return ArcsecondAPI.register(username, email, password1, password2, state, **kwargs)


class ArcsecondAPI(object):
def __init__(self, endpoint_class=None, state=None, **kwargs):
self.state = get_api_state(state, **kwargs)
Expand Down Expand Up @@ -223,17 +196,17 @@ def _echo_error(cls, state, error):
click.echo(click.style(ECHO_PREFIX + message, fg='red'))

@classmethod
def _check_organisation_membership(cls, state, username, subdomain):
ArcsecondAPI._echo_message(state, f'Checking Membership of Organisation "{subdomain}"...')
def _check_memberships(cls, state, username):
ArcsecondAPI._echo_message(state, f'Checking Memberships...')
profile, error = PersonalProfileAPIEndPoint(state.make_new_silent()).read(username)
if error:
ArcsecondAPI._echo_error(state, error)
else:
memberships = {m['organisation']['subdomain']: m['role'] for m in profile['memberships']}
if subdomain in memberships.keys():
msg = f'Membership confirmed. Role is "{memberships[subdomain]}", stored in {config_file_path()}.'
for membership in memberships.keys():
msg = f'Membership confirmed. Role is "{memberships[membership]}", stored in {config_file_path()}.'
ArcsecondAPI._echo_message(state, msg)
config_file_save_organisation_membership(subdomain, memberships[subdomain], state.config_section())
config_file_save_organisation_membership(membership, memberships[membership], state.config_section())
else:
ArcsecondAPI._echo_message(state, 'Membership denied.')

Expand Down Expand Up @@ -281,8 +254,7 @@ def login(cls, username, password, subdomain, state=None, **kwargs):
elif result:
# We replace result and error of login with that of api key
result, error = ArcsecondAPI._get_and_save_api_key(state, username, result['key'])
if subdomain:
ArcsecondAPI._check_organisation_membership(state, username, subdomain)
ArcsecondAPI._check_memberships(state, username)
return result, error

@classmethod
Expand Down
52 changes: 26 additions & 26 deletions arcsecond/cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import click

from . import __version__
from .api import Arcsecond, ArcsecondError
from .api import ArcsecondAPI, ArcsecondError
from .api.helpers import make_coords_dict
from .config import config_file_read_username
from .options import MethodChoiceParamType, State, basic_options, open_options, organisation_options
Expand Down Expand Up @@ -37,7 +37,7 @@ def version():
@pass_state
def register(state, username, email, password1, password2):
"""Register for a free personal Arcsecond.io account, and retrieve the associated API key."""
Arcsecond.register(username, email, password1, password2, state)
ArcsecondAPI.register(username, email, password1, password2, state)


@main.command(help='Login to a personal Arcsecond.io account')
Expand All @@ -48,7 +48,7 @@ def register(state, username, email, password1, password2):
@pass_state
def login(state, username, password, organisation=None):
"""Login to your personal Arcsecond.io account, and retrieve the associated API key."""
Arcsecond.login(username, password, organisation, state)
ArcsecondAPI.login(username, password, organisation, state)


@main.command(help='Fetch your complete user profile.')
Expand All @@ -60,7 +60,7 @@ def me(state):
if not username:
msg = 'Invalid/missing username: {}. Make sure to login first: $ arcsecond login'.format(username)
raise ArcsecondError(msg)
Arcsecond.build_me_api(state).read(username)
ArcsecondAPI.me(state).read(username)


@main.command(help='Request an object.')
Expand All @@ -74,54 +74,54 @@ def objects(state, name):
The NED information, as well as being able to choose the source
will be implemented in the future.
"""
Arcsecond.build_objects_api(state).read(name)
ArcsecondAPI.objects(state).read(name)


@main.command(help='Request an exoplanet (in the /exoplanets/<name>/ API endpoint)')
@click.argument('name', required=True, nargs=-1)
@open_options
@pass_state
def exoplanets(state, name):
Arcsecond.build_exoplanets_api(state).read(name)
ArcsecondAPI.exoplanets(state).read(name)


@main.command(help='Request the list of object finding charts (in the /findingcharts/<name>/ API endpoint)')
@click.argument('name', required=True, nargs=-1)
@open_options
@pass_state
def findingcharts(state, name):
Arcsecond.build_findingcharts_api(state).list(name=name)
ArcsecondAPI.findingcharts(state).list(name=name)


@main.command(help='Request the list of observing sites (in the /observingsites/ API endpoint)')
@open_options
@pass_state
def sites(state):
Arcsecond.build_observingsites_api(state).list()
ArcsecondAPI.observingsites(state).list()


@main.command(help='Request the list of telescopes (in the /telescopes/ API endpoint)')
@open_options
@pass_state
def telescopes(state):
Arcsecond.build_telescopes_api(state).list()
ArcsecondAPI.telescopes(state).list()


@main.command(help='Request the list of instruments (in the /instruments/ API endpoint)')
@open_options
@pass_state
def instruments(state, name):
Arcsecond.build_instruments_api(state).list()
ArcsecondAPI.instruments(state).list()


@main.command(help='Request your own list of observing runs (in the /observingruns/ API endpoint)')
@click.argument('method', required=False, nargs=1, type=MethodChoiceParamType(), default='read')
@click.argument('uuid', required=False, nargs=1)
@click.argument('uuid', required=False, nargs=1, type=click.UUID)
@click.option('--name', required=False, nargs=1, help="The observing run name.")
@organisation_options
@pass_state
def runs(state, method, uuid, **kwargs):
api = Arcsecond.build_observingruns_api(state)
api = ArcsecondAPI.observingruns(state)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand All @@ -136,12 +136,12 @@ def runs(state, method, uuid, **kwargs):

@main.command(help='Request your own list of night logs (in the /nightlogs/ API endpoint)')
@click.argument('method', required=False, nargs=1, type=MethodChoiceParamType(), default='read')
@click.argument('uuid', required=False, nargs=1)
@click.argument('uuid', required=False, nargs=1, type=click.UUID)
@click.option('--name', required=False, nargs=1, help="The log name.")
@organisation_options
@pass_state
def logs(state, method, uuid, **kwargs):
api = Arcsecond.build_nightlogs_api(state)
api = ArcsecondAPI.nightlogs(state)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand All @@ -156,11 +156,11 @@ def logs(state, method, uuid, **kwargs):

@main.command(help='Request your own list of observations (in the /observations/ API endpoint)')
@click.argument('method', required=False, nargs=1, type=MethodChoiceParamType(), default='read')
@click.argument('uuid', required=False, nargs=1)
@click.argument('uuid', required=False, nargs=1, type=click.UUID)
@organisation_options
@pass_state
def observations(state, method, uuid, **kwargs):
api = Arcsecond.build_observations_api(state)
api = ArcsecondAPI.observations(state)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand All @@ -175,11 +175,11 @@ def observations(state, method, uuid, **kwargs):

@main.command(help='Request your own list of calibrations (in the /calibrations/ API endpoint)')
@click.argument('method', required=False, nargs=1, type=MethodChoiceParamType(), default='read')
@click.argument('uuid', required=False, nargs=1)
@click.argument('uuid', required=False, nargs=1, type=click.UUID)
@organisation_options
@pass_state
def calibrations(state, method, uuid, **kwargs):
api = Arcsecond.build_calibrations_api(state)
api = ArcsecondAPI.calibrations(state)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand Down Expand Up @@ -210,7 +210,7 @@ def calibrations(state, method, uuid, **kwargs):
@open_options
@pass_state
def activities(state, method, pk, **kwargs):
api = Arcsecond.build_activities_api(state)
api = ArcsecondAPI.activities(state)
if method == 'create':
kwargs.update(coordinates=make_coords_dict(kwargs))
api.create(kwargs) # the kwargs dict is the payload!
Expand All @@ -226,12 +226,12 @@ def activities(state, method, pk, **kwargs):

@main.command(help='Access and modify your own datasets (in the /datasets/ API endpoint)')
@click.argument('method', required=False, nargs=1, type=MethodChoiceParamType(), default='read')
@click.argument('uuid', required=False, nargs=1)
@click.argument('uuid', required=False, nargs=1, type=click.UUID)
@click.option('--name', required=False, nargs=1, help="The dataset name.")
@organisation_options
@pass_state
def datasets(state, method, uuid, **kwargs):
api = Arcsecond.build_datasets_api(state)
api = ArcsecondAPI.datasets(state)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand Down Expand Up @@ -263,7 +263,7 @@ def datafiles(state, dataset, method, pk, **kwargs):
if state.organisation:
# If organisation is provided as argument, don't put in payload too!
kwargs.pop('organisation')
api = Arcsecond.build_datafiles_api(state=state, dataset=dataset)
api = ArcsecondAPI.datafiles(state=state, dataset=dataset)
if method == 'create':
api.create(kwargs) # the kwargs dict is the payload!
elif method == 'read':
Expand All @@ -289,7 +289,7 @@ def satellites(state, catalogue_number):
Data is extracted from celestrak.com.
"""
# If catalogue_number is None, ArcsecondAPI fallback to .list()
Arcsecond.build_satellites_api(state).read(catalogue_number)
ArcsecondAPI.satellites(state).read(catalogue_number)


@main.command(help='Read telegrams (ATel)')
Expand All @@ -302,7 +302,7 @@ def telegrams(state, identifier):
The other sources of telegrams will be added in the future.
"""
# If catalogue_number is None, ArcsecondAPI fallback to .list()
Arcsecond.build_telegrams_api(state).read(identifier)
ArcsecondAPI.telegrams(state).read(identifier)


@main.command(help='Read catalogues (standard stars)')
Expand All @@ -314,7 +314,7 @@ def catalogues(state, identifier, rows):
"""Request the list of identifier or the details of one (in the /catalogues/ API endpoint).
"""

api = Arcsecond.build_catalogues_api(state)
api = ArcsecondAPI.catalogues(state)
if identifier:
identifier = identifier + '/rows' if rows else identifier
api.read(identifier)
Expand All @@ -334,4 +334,4 @@ def standardstars(state, around, count=5):
Coordinates are assumed to be Equatorial, with epoch J2000.
"""
Arcsecond.build_standardstars_api(state).list()
ArcsecondAPI.standardstars(state).list()
2 changes: 1 addition & 1 deletion arcsecond/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class MethodChoiceParamType(click.ParamType):
name = 'method'

def __init__(self, *args):
super(MethodChoiceParamType, self).__init__()
super().__init__()
self.allowed_methods = args or ['list', 'create', 'read', 'update', 'delete']

def convert(self, value, param, ctx):
Expand Down
10 changes: 5 additions & 5 deletions tests/cli/test_activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from arcsecond import cli
from arcsecond.api.constants import ARCSECOND_API_URL_DEV
from arcsecond.api.error import ArcsecondInputValueError
from tests.utils import register_successful_personal_login
from tests.utils import register_successful_login


@httpretty.activate
def test_activities_with_valid_coordinates():
runner = CliRunner()
register_successful_personal_login(runner)
register_successful_login(runner)
site_uuid = str(uuid.uuid4())
coords_ra = 2.33
coords_dec = 4.55
Expand All @@ -38,7 +38,7 @@ def request_callback(request, uri, response_headers):
@httpretty.activate
def test_activities_with_invalid_coordinates():
runner = CliRunner()
register_successful_personal_login(runner)
register_successful_login(runner)
site_uuid = str(uuid.uuid4())
coords_ra = 2.33
coords_dec = 4.55
Expand All @@ -51,7 +51,7 @@ def test_activities_with_invalid_coordinates():
@httpretty.activate
def test_activities_with_invalid_coordinates2():
runner = CliRunner()
register_successful_personal_login(runner)
register_successful_login(runner)
site_uuid = str(uuid.uuid4())
coords_ra = 2.33
coords_dec = 4.55
Expand All @@ -64,7 +64,7 @@ def test_activities_with_invalid_coordinates2():
@httpretty.activate
def test_activities_with_invalid_coordinates3():
runner = CliRunner()
register_successful_personal_login(runner)
register_successful_login(runner)
site_uuid = str(uuid.uuid4())
coords_ra = 2.33
coords = "yoyo,{}".format(coords_ra)
Expand Down
Loading

0 comments on commit d6c1ef1

Please sign in to comment.