-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 648d1cf
Showing
21 changed files
with
1,050 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
[run] | ||
branch = True | ||
|
||
[report] | ||
precision = 2 | ||
|
||
[html] | ||
directory = reports/coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
__pycache__/ | ||
*.py[cod] | ||
/.git/ | ||
/.tox/ | ||
/.cache/ | ||
.coverage | ||
/reports/ | ||
/.idea/ | ||
/env/ | ||
/edbo_connector/config.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[MASTER] | ||
ignore=tests | ||
|
||
[REPORTS] | ||
output-format = text | ||
reports = yes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
edbo-connector-py is written and maintained by Eldar Aliiev. | ||
|
||
Contributors | ||
```````````` | ||
|
||
- Eldar Aliiev <[email protected]> `@ZimGreen <https://github.com/ZimGreen>`_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
include README.rst AUTHORS.rst LICENSE | ||
recursive-include tests *.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
EDBO-connector | ||
============== | ||
|
||
Python library for work with EDBO | ||
|
||
https://github.com/ZimGreen/edbo-connector-py | ||
|
||
Install: | ||
-------- | ||
|
||
```bash | ||
$ git clone https://github.com/ZimGreen/edbo-connector-py.git | ||
$ cd edbo-connector-py | ||
$ python setup.py install | ||
``` | ||
|
||
or with pip: | ||
|
||
```bash | ||
$ pip install edbo_connector | ||
``` | ||
|
||
Before use rename `"config.example.py"` to `"config.py"` inside the package | ||
and add your own configs. | ||
|
||
Usage example: | ||
-------------- | ||
|
||
```python | ||
``` | ||
|
||
For disable debug output change **ECHO_ON** variable to *False*. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
edbo_connector | ||
Author: Eldar Aliiev | ||
Email: [email protected] | ||
""" | ||
|
||
from edbo_connector.client import EDBOWebApiClient | ||
|
||
__name__ = 'edbo_connector' | ||
__author__ = 'Eldar Aliiev' | ||
__copyright__ = 'Copyright 2017, National Pirogov Memorial Medical University, Vinnytsya' | ||
__credits__ = ['Eldar Aliiev'] | ||
__license__ = 'MIT' | ||
__version__ = '1.0.0' | ||
__maintainer__ = 'Eldar Aliiev' | ||
__email__ = '[email protected]' | ||
__status__ = 'Production' | ||
__all__ = ['EDBOWebApiClient'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
EDBOWebApiClient | ||
Author: Eldar Aliiev | ||
Email: [email protected] | ||
""" | ||
|
||
import re | ||
import edbo_connector.config as config | ||
from edbo_connector.connector import EDBOWebApiConnector | ||
from edbo_connector.helper import EDBOWebApiHelper | ||
from edbo_connector.methods import EDBOWebApiMethods | ||
|
||
|
||
class EDBOWebApiClient(EDBOWebApiMethods): | ||
"""EDBOWebApiClient - class which implements some RESTful API methods | ||
and interface for methods execution by their names. | ||
""" | ||
|
||
def __init__(self, username=config.EDBO_USER, password=config.EDBO_PASSWORD): | ||
"""Initialize connector and prepare client to work | ||
:param username: Username (Default=from config file) | ||
:param password: Method data (Default=from config file) | ||
:type username: str | ||
:type password: str | ||
""" | ||
self._connector = EDBOWebApiConnector(username, password) # Initialize connector | ||
self._university_info = self._connector.execute('university/list')[0] # Get university info | ||
|
||
def __getattr__(self, method): | ||
"""Call RESTful API method | ||
:param method: Method of RESTful API | ||
:type method: str | ||
:return: Method for execution | ||
:rtype: function | ||
""" | ||
|
||
if re.match(r'([0-9a-z_]+)', method) is not None: # Check if method name is valid | ||
url = method.replace('_', '/') # Transform method name into url | ||
|
||
def wrapper(data=None, headers=None, json_format=True): | ||
return self._connector.execute( | ||
url, | ||
data, | ||
headers, | ||
json_format | ||
) # Send request to server | ||
|
||
return wrapper | ||
else: # Fail if method is incorrect | ||
EDBOWebApiHelper.echo(u'Некоректний метод!', color='red') | ||
return | ||
|
||
def get_status(self): | ||
"""Return status of last request | ||
:return: Status of last method execution | ||
:rtype: int | ||
""" | ||
return self._connector.status | ||
|
||
def get_execution_time(self): | ||
"""Return execution time of last request | ||
:return: Time of last method execution | ||
:rtype: float""" | ||
return self._connector.execution_time | ||
|
||
def get_user_info(self): | ||
"""Get information about current user | ||
:return: Information about current user | ||
:rtype: dict | ||
""" | ||
return self._connector.execute('auth/userInfo') | ||
|
||
def get_university_info(self, field): | ||
"""Get university info | ||
:param field: Name of field | ||
:type field: str | ||
:return: University info field | ||
:rtype: str, int | ||
""" | ||
return self._university_info.get(field, None) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
EDBO_SERVER = '' # Path to "ІІТ Захист з'єднань-2.Клієнт" | ||
EDBO_USER = '' # User of RESTful API | ||
EDBO_PASSWORD = '' # Password | ||
EDBO_APPLICATION_KEY = '' # RESTful API key | ||
|
||
ECHO_ON = True # Print log messages | ||
EXECUTION_TIMEOUT = 0 # Timeout between queries to server | ||
CONNECTION_RETRIES = 15 # Maximal count of retries | ||
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' | ||
MAX_REQUESTS_COUNT = 15000 # Maximal count of requests in one query |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
EDBOWebApiConnector | ||
Author: Eldar Aliiev | ||
Email: [email protected] | ||
""" | ||
|
||
import time | ||
import requests | ||
from requests.adapters import HTTPAdapter | ||
import edbo_connector.config as config | ||
from edbo_connector.helper import EDBOWebApiHelper | ||
|
||
|
||
class EDBOWebApiConnector(object): | ||
"""EDBOWebApiConnector - class which implements connection | ||
and method execution with EDBO RESTfull API. | ||
Attributes: | ||
url_prefix Path to RESTful API server. | ||
""" | ||
|
||
url_prefix = '%s/data/EDEBOWebApi' % config.EDBO_SERVER # Build url to RESTful server | ||
|
||
def __init__(self, username=config.EDBO_USER, password=config.EDBO_PASSWORD): | ||
"""Initialize connect and login into RESTful API server. | ||
:param username: Username (Default=from config file) | ||
:param password: Method data (Default=from config file) | ||
:type username: str | ||
:type password: str | ||
""" | ||
self._status = None # Initialize status | ||
self._execution_time = 0 # Initialize execution_time | ||
self._is_logged_in = False # Is user logged in | ||
self._session = requests.Session() # Initialize client session | ||
self._session.mount( | ||
config.EDBO_SERVER, | ||
HTTPAdapter(max_retries=config.CONNECTION_RETRIES) | ||
) # Mount RESTful API server to our session | ||
self.__login(username, password) # Login into server | ||
|
||
def __del__(self): | ||
"""End of session""" | ||
if self._is_logged_in: # Check if user is logged in | ||
self.__logout() | ||
|
||
@property | ||
def status(self): | ||
"""Return status of last request | ||
:return: Status of last method execution | ||
:rtype: int | ||
""" | ||
return self._status | ||
|
||
@property | ||
def execution_time(self): | ||
"""Return execution time of last request | ||
:return: Time of last method execution | ||
:rtype: float | ||
""" | ||
return self._execution_time | ||
|
||
@property | ||
def default_headers(self): | ||
"""Default request headers | ||
:return: Default request headers such as user-agent, referer and etc | ||
:rtype: dict | ||
""" | ||
return { | ||
'Origin': config.EDBO_SERVER, | ||
'Referer': config.EDBO_SERVER, | ||
'User-Agent': config.USER_AGENT, | ||
} | ||
|
||
def __login(self, username=config.EDBO_USER, password=config.EDBO_PASSWORD): | ||
"""Login request to RESTful API""" | ||
|
||
EDBOWebApiHelper.echo(u'Вхід в систему...') | ||
try: | ||
response = self._session.post( | ||
self.url_prefix + '/oauth/token', | ||
data={ | ||
'grant_type': 'password', | ||
'username': username, | ||
'password': password, | ||
'app_key': config.EDBO_APPLICATION_KEY, | ||
}, | ||
headers=self.default_headers | ||
) # Send authorization request | ||
except requests.exceptions.ConnectionError: | ||
EDBOWebApiHelper.echo( | ||
u'Не вдалося встановити зв\'язок з сервером!', | ||
color='red', | ||
force_exit=True | ||
) | ||
|
||
if response.status_code == 200: # Check if authorization is successful | ||
self._session_start_time = time.time() # Catch session start time | ||
self._status = response.status_code # Catch last response status code | ||
self._is_logged_in = True # Logged in | ||
self._access_token = response.json().get('access_token', None) # Get access token | ||
EDBOWebApiHelper.echo(u'Вхід успішний, вітаю %s!' % config.EDBO_USER, color='green') | ||
elif response.status_code == 400: | ||
EDBOWebApiHelper.echo( | ||
response.json().get('error', u'Трапилася невідома помилка!'), | ||
color='red', | ||
force_exit=True | ||
) # Incorrect login data | ||
else: | ||
EDBOWebApiHelper.echo( | ||
u'Не вдалося авторизуватися в системі!', | ||
color='red', | ||
force_exit=True | ||
) # Fail if login is unsuccessful | ||
|
||
def __logout(self): | ||
"""Logout from server""" | ||
EDBOWebApiHelper.echo(u'Вихід з системи...', color='red') | ||
self.execute('auth/logout') # Logout from server | ||
self._is_logged_in = False # Logged out | ||
|
||
def execute(self, url, data=None, headers=None, json_format=True): | ||
"""Send request to RESTful server. | ||
:param url: Path to RESTful method | ||
:param data: Method data (Default=empty) | ||
:param headers: Default headers (Default=empty) | ||
:param json_format: Return results dictionary or object (Default=True) | ||
:type url: str | ||
:type data: dict | ||
:type headers: dict | ||
:type json_format: bool | ||
:returns: Result of method execution | ||
:rtype: dict, object | ||
""" | ||
if int(time.time() - self._session_start_time) > 60 * 15: # Check if session is not expired (15min) | ||
EDBOWebApiHelper.echo(u'Сесія добігає кінця, поновлення...') | ||
self.__logout() # Logout from server | ||
self.__login() # Login again if session is expired | ||
|
||
time.sleep(config.EXECUTION_TIMEOUT) # Wait between methods execution | ||
|
||
headers = headers if headers is not None else {} # Initialize headers if not exists | ||
headers.update(self.default_headers) # Add default headers | ||
headers.update({ | ||
'authorization': 'Bearer ' + self._access_token, | ||
}) # Add OAuth header | ||
|
||
while True: # Try to execute method | ||
try: | ||
EDBOWebApiHelper.echo(u'Виконання методу %s...' % url) | ||
execution_start = time.time() # Catch start of execution | ||
response = self._session.post( | ||
'%s/api/%s' % (self.url_prefix, url), | ||
data if data is not None else {'': ''}, | ||
headers=headers | ||
) # Send request to RESTful server | ||
execution_end = time.time() # Catch end of execution | ||
except requests.exceptions.ConnectionError: # Check if method execution is successful | ||
EDBOWebApiHelper.echo( | ||
u'Виконання методу завершено невдало, повторна спроба...', | ||
color='red' | ||
) | ||
continue # Retry if unsuccessful | ||
break | ||
|
||
self._execution_time = execution_end - execution_start # Save last execution time | ||
self._status = response.status_code # Save last status code | ||
|
||
EDBOWebApiHelper.echo( | ||
u'Виконання методу завершено з кодом %d [%.3fs]' % ( | ||
self._status, | ||
self._execution_time | ||
), | ||
color='green' | ||
) | ||
|
||
if self._status == 200: # Check if server return data | ||
return response.json() if json_format else response # Return result of method execution |
Oops, something went wrong.