Commit 0f83af88 authored by jens.kleineheismann's avatar jens.kleineheismann

Added some docstrings.

parent a082d1f7
ABOUT ABOUT
===== =====
This package provide a python binding to the KIT Gruppenverwaltung REST API. This package provide a python library to access the KIT Gruppenverwaltung REST API.
INSTALLATION INSTALLATION
......
""" """
Library for accessing KIT Gruppenverwaltung REST API Library for accessing the KIT Gruppenverwaltung REST API
The most importend class is kitgvapi.ObjectInterface The object, you are looking for is kitgvapi.ObjectInterface.
""" """
__version__ = '1.1' __version__ = '1.1'
__author__ = 'Jens Kleineheismann <kleineheismann@kit.edu>' __author__ = 'Jens Kleineheismann'
__email__ = 'kleineheismann@kit.edu'
__license__ = """ __license__ = """
Permission to use, copy, modify, and/or distribute this software Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted. for any purpose with or without fee is hereby granted.
......
"""Clients/Consumer for the remote API provider"""
import json import json
import requests import requests
...@@ -6,6 +8,14 @@ from .exceptions import NotAllowedError, NotFoundError, MissingConfigError ...@@ -6,6 +8,14 @@ from .exceptions import NotAllowedError, NotFoundError, MissingConfigError
class RestClientConfig(object): class RestClientConfig(object):
"""Config for RestClient.
An instance of this class is used to provide the necessary
configuration parameters to a kitgvapi.clients.RestClient
instance.
It takes its default values from kitgvapi.config.DEFAULTS.
"""
def __init__(self): def __init__(self):
self.url_schema = DEFAULTS['URL_SCHEMA'] self.url_schema = DEFAULTS['URL_SCHEMA']
self.server = DEFAULTS['SERVER'] self.server = DEFAULTS['SERVER']
...@@ -42,6 +52,7 @@ class RestClientConfig(object): ...@@ -42,6 +52,7 @@ class RestClientConfig(object):
@property @property
def credentials(self): def credentials(self):
"""Setup and return a requests.auth.HTTPBasicAuth instance."""
if self._credentials is None: if self._credentials is None:
u = self.username u = self.username
if u: if u:
...@@ -50,12 +61,23 @@ class RestClientConfig(object): ...@@ -50,12 +61,23 @@ class RestClientConfig(object):
class RestClient(object): class RestClient(object):
"""Send requests to the REST API.
- the get_* methods send GET requests and return the
responded and already deserialized JSON data.
Methods, which names end with 's' return a list.
- the add_* and create_* methods send POST requests.
- the remove_* and delete_* methods send DELETE requests.
"""
def __init__(self, config=None): def __init__(self, config=None):
""":param config: may be an instance of kitgvapi.clients.RestClientConfig. If omitted, a default config is loaded.
"""
self.config = config self.config = config
if self.config is None: if self.config is None:
self.config = RestClientConfig() self.config = RestClientConfig()
def get(self, path): def get(self, path):
"""Send GET request."""
url = self.config.url_schema + self.config.server + self.config.base_uri + path url = self.config.url_schema + self.config.server + self.config.base_uri + path
try: try:
r = requests.get(url, verify=True, auth=self.config.credentials) r = requests.get(url, verify=True, auth=self.config.credentials)
...@@ -69,6 +91,7 @@ class RestClient(object): ...@@ -69,6 +91,7 @@ class RestClient(object):
return d return d
def post(self, path, data=None): def post(self, path, data=None):
"""Send POST request."""
if not self.config.enable_post: if not self.config.enable_post:
raise NotAllowedError("POST operations are disabled by configuration") raise NotAllowedError("POST operations are disabled by configuration")
url = self.config.url_schema + self.config.server + self.config.base_uri + path url = self.config.url_schema + self.config.server + self.config.base_uri + path
...@@ -80,6 +103,7 @@ class RestClient(object): ...@@ -80,6 +103,7 @@ class RestClient(object):
return r return r
def delete(self, path): def delete(self, path):
"""Send DELETE request."""
if not self.config.enable_delete: if not self.config.enable_delete:
raise NotAllowedError("DELETE operations are disabled by configuration") raise NotAllowedError("DELETE operations are disabled by configuration")
raise NotImplementedError("Not ready") raise NotImplementedError("Not ready")
...@@ -152,7 +176,7 @@ class RestClient(object): ...@@ -152,7 +176,7 @@ class RestClient(object):
def remove_group_user(self, group_pk, user_pk): def remove_group_user(self, group_pk, user_pk):
raise NotImplementedError("Not ready") raise NotImplementedError("Not ready")
def add_group_group(self, super_pk, sub_pk): def add_group_group(self, super_pk, sub_pk):
oe_pk = super_pk.partition('-')[0] oe_pk = super_pk.partition('-')[0]
path = '/groups/{oe}/{superg}/subgroups/{subg}'.format(oe=oe_pk, superg=super_pk, subg=sub_pk) path = '/groups/{oe}/{superg}/subgroups/{subg}'.format(oe=oe_pk, superg=super_pk, subg=sub_pk)
...@@ -160,7 +184,7 @@ class RestClient(object): ...@@ -160,7 +184,7 @@ class RestClient(object):
def remove_group_group(self, super_pk, sub_pk): def remove_group_group(self, super_pk, sub_pk):
raise NotImplementedError("Not ready") raise NotImplementedError("Not ready")
def create_group(self, name, description): def create_group(self, name, description):
oe_pk = name.partition('-')[0] oe_pk = name.partition('-')[0]
path = '/groups/{oe}'.format(oe=oe_pk) path = '/groups/{oe}'.format(oe=oe_pk)
......
from .exceptions import MissingConfigError """(Default) Configuration"""
SYMBOLS = { from .exceptions import MissingConfigError
'GROUP_PK_ATTRIB': 'name',
'OE_PK_ATTRIB': 'kurz',
'USER_PK_ATTRIB': 'samaccount',
}
DEFAULTS = { DEFAULTS = {
'URL_SCHEMA': 'https://', 'URL_SCHEMA': 'https://',
...@@ -15,3 +11,9 @@ DEFAULTS = { ...@@ -15,3 +11,9 @@ DEFAULTS = {
'ENABLE_POST': True, 'ENABLE_POST': True,
'ENABLE_DELETE': False, 'ENABLE_DELETE': False,
} }
SYMBOLS = {
'GROUP_PK_ATTRIB': 'name',
'OE_PK_ATTRIB': 'kurz',
'USER_PK_ATTRIB': 'samaccount',
}
"""Exceptions"""
class KitGvApiError(Exception): class KitGvApiError(Exception):
pass pass
...@@ -16,7 +19,7 @@ class MissingPkError(KitGvApiError): ...@@ -16,7 +19,7 @@ class MissingPkError(KitGvApiError):
class NotAllowedError(KitGvApiError): class NotAllowedError(KitGvApiError):
pass pass
class NotFoundError(KitGvApiError): class NotFoundError(KitGvApiError):
pass pass
"""Type library"""
from .clients import RestClient from .clients import RestClient
from .config import SYMBOLS from .config import SYMBOLS
from .exceptions import MissingClientError, MissingPkError from .exceptions import MissingClientError, MissingPkError
class Model(object): class Model(object):
"""Abstract base class"""
def __init__(self, pk=None, client=None, data=None): def __init__(self, pk=None, client=None, data=None):
self.pk = pk self.pk = pk
self.client = client self.client = client
...@@ -21,7 +24,7 @@ class Model(object): ...@@ -21,7 +24,7 @@ class Model(object):
def _load_data_attribs(self, data=None): def _load_data_attribs(self, data=None):
raise NotImplementedError('Abstract method') raise NotImplementedError('Abstract method')
def load(self, reload=False): def load(self, reload=False):
if self.is_loaded and not reload: if self.is_loaded and not reload:
return return
...@@ -34,7 +37,7 @@ class Model(object): ...@@ -34,7 +37,7 @@ class Model(object):
def _save_data_attribs(self): def _save_data_attribs(self):
raise NotImplementedError('Abstract method') raise NotImplementedError('Abstract method')
def save(self): def save(self):
if self.client is None: if self.client is None:
raise MissingClientError() raise MissingClientError()
...@@ -42,6 +45,7 @@ class Model(object): ...@@ -42,6 +45,7 @@ class Model(object):
class Group(Model): class Group(Model):
"""Represent a KIT group"""
def _load_data_attribs(self, data=None): def _load_data_attribs(self, data=None):
if data is None: if data is None:
data = self.client.get_group(pk=self.pk) data = self.client.get_group(pk=self.pk)
...@@ -59,6 +63,7 @@ class Group(Model): ...@@ -59,6 +63,7 @@ class Group(Model):
@property @property
def oe(self): def oe(self):
"""Hold the Oe object, which this group belongs to (read only)."""
return Oe(client=self.client, pk=self.oe_pk) return Oe(client=self.client, pk=self.oe_pk)
def get_users(self, effective=False): def get_users(self, effective=False):
...@@ -87,8 +92,9 @@ class Group(Model): ...@@ -87,8 +92,9 @@ class Group(Model):
def remove_group(self, pk): def remove_group(self, pk):
raise NotImplementedError('Not yet') raise NotImplementedError('Not yet')
class Oe(Model): class Oe(Model):
"""Represent a KIT OE"""
def _load_data_attribs(self, data=None): def _load_data_attribs(self, data=None):
if data is None: if data is None:
data = self.client.get_oe(pk=self.pk) data = self.client.get_oe(pk=self.pk)
...@@ -105,7 +111,7 @@ class Oe(Model): ...@@ -105,7 +111,7 @@ class Oe(Model):
for d in l: for d in l:
y = Group(client=self.client, data=d) y = Group(client=self.client, data=d)
yield y yield y
def get_users(self): def get_users(self):
self.load() self.load()
l = self.client.get_oe_users(pk=self.pk) l = self.client.get_oe_users(pk=self.pk)
...@@ -121,6 +127,7 @@ class Oe(Model): ...@@ -121,6 +127,7 @@ class Oe(Model):
class User(Model): class User(Model):
"""Represent a KIT User account (aka identity)"""
def _load_data_attribs(self, data=None): def _load_data_attribs(self, data=None):
if data is None: if data is None:
data = self.client.get_user(pk=self.pk) data = self.client.get_user(pk=self.pk)
......
"""This module contain the ObjectInterface class."""
from .clients import RestClient from .clients import RestClient
from .models import Group, Oe, User from .models import Group, Oe, User
class ObjectInterface(object): class ObjectInterface(object):
"""Object oriented interface to the KIT Gruppenverwaltung API"""
class Config(object): class Config(object):
def __init__(self, provider): def __init__(self, provider):
self.provider = provider self.provider = provider
...@@ -25,7 +29,7 @@ class ObjectInterface(object): ...@@ -25,7 +29,7 @@ class ObjectInterface(object):
def __init__(self, client=None, client_config=None): def __init__(self, client=None, client_config=None):
self.config = self.Config(self) self.config = self.Config(self)
if client is None: if client is None:
self.client = RestClient(config=client_config) self.client = RestClient(config=client_config)
else: else:
...@@ -33,12 +37,12 @@ class ObjectInterface(object): ...@@ -33,12 +37,12 @@ class ObjectInterface(object):
def getOe(self, pk): def getOe(self, pk):
return Oe(client=self.client, pk=pk) return Oe(client=self.client, pk=pk)
def getGroup(self, pk): def getGroup(self, pk):
return Group(client=self.client, pk=pk) return Group(client=self.client, pk=pk)
def newGroup(self, name, description): def newGroup(self, name, description):
raise NotImplementedError("Use kitgvapi.models.Oe.create_group() instead.") raise NotImplementedError("Use kitgvapi.models.Oe.create_group() instead.")
def getUser(self, pk): def getUser(self, pk):
return User(client=self.client, pk=pk) return User(client=self.client, pk=pk)
...@@ -2,17 +2,23 @@ ...@@ -2,17 +2,23 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
def package_meta(param):
v = '__' + param + '__'
m = __import__('kitgvapi')
return getattr(m, v)
def readme(): def readme():
with open('README.rst') as f: with open('README.rst') as f:
return f.read() return f.read()
setup( setup(
name='python-kitgvapi', name='python-kitgvapi',
version='1.1.dev0', version=package_meta('version'),
description=('Python bindings for KIT Gruppenverwaltung REST API'), description=package_meta('doc').split('\n')[1],
long_description=readme(), long_description=readme(),
author='Jens Kleineheismann', author=package_meta('author'),
author_email='kleineheismann@kit.edu', author_email=package_meta('email'),
license=package_meta('license'),
url='https://git.scc.kit.edu/zy8373/python-kitgvapi', url='https://git.scc.kit.edu/zy8373/python-kitgvapi',
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment