Skip to content

Commit

Permalink
Initial code release
Browse files Browse the repository at this point in the history
Signed-off-by: Emilio Reyes <emilio.reyes@intel.com>
  • Loading branch information
soda480 committed May 8, 2020
1 parent fc2a7c0 commit 9cf8bdd
Show file tree
Hide file tree
Showing 10 changed files with 1,099 additions and 1 deletion.
89 changes: 89 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.6.5-stretch

ENV PYTHONDONTWRITEBYTECODE 1

RUN mkdir /rest3client

COPY . /rest3client/

WORKDIR /rest3client

RUN apt-get update
RUN apt-get install -y git gcc libssl-dev
RUN pip install pybuilder==0.11.17
RUN pyb install_dependencies
RUN pyb install

WORKDIR /rest3client
CMD echo 'DONE'
86 changes: 85 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,85 @@
# rest2api
# rest3client #

rest3client is a requests-based library providing simple methods to enable consumption of HTTP REST APIs.

The library further abstracts the underlying requests calls providing HTTP verb equivalent methods for GET, POST, PATCH, PUT and DELETE. The library includes a RESTclient class that implements a consistent approach for processing request responses, extracting error messages from responses, and providing standard headers to request calls. Enabling the consumer to focus on their business logic and less on the complexites of setting up and processing the requests repsonses.
A subclass inheriting RESTclient can override the base methods providing further customization and flexibility. The library supports most popular authentication schemes; including no-auth, basic auth, api-key and token-based.

### Installation ###
```bash
pip install git+https://gitlab.com/soda480/rest3client.git
```

### Example Usage ###
Examples below show how RESTclient can be used to consume the GitHub REST API. However RESTclient can be used to consume just about any REST API.

```python
>>> from rest3client import RESTclient

# instantiate RESTclient - no auth
>>> client = RESTclient('api.github.com')

# GET request - return json response
>>> client.get('/rate_limit')['resources']['core']
{'limit': 60, 'remaining': 37, 'reset': 1588898701}

# GET request - return raw resonse
>>> client.get('/rate_limit', raw_response=True)
<Response [200]>

# instantiate RESTclient using bearer token
>>> client = RESTclient('api.github.com', bearer_token='****************')

# POST request
>>> client.post('/user/repos', json={'name': 'test-repo1'})['full_name']
'soda480/test-repo1'

# POST request
>>> client.post('/repos/soda480/test-repo1/labels', json={'name': 'label1', 'color': '#006b75'})['url']
'https://api.github.com/repos/soda480/test-repo1/labels/label1'

# PATCH request
>>> client.patch('/repos/soda480/test-repo1/labels/label1', json={'description': 'my label'})['url']
'https://api.github.com/repos/soda480/test-repo1/labels/label1'

# DELETE request
>>> client.delete('/repos/soda480/test-repo1')
```

### Development ###

Ensure the latest version of Docker is installed on your development server.

Clone the repository:
```bash
cd
git clone https://github.com/soda480/rest3client.git
cd rest3client
```

Build the Docker image:
```sh
docker image build \
--build-arg http_proxy \
--build-arg https_proxy \
-t rest3client:latest .
```

Run the Docker container:
```sh
docker container run \
--rm \
-it \
-e http_proxy \
-e https_proxy \
-v $PWD:/rest3client \
rest3client:latest \
/bin/sh
```

Execute the build:
```sh
pyb -X
```

NOTE: commands above assume working behind a proxy, if not then the proxy arguments to both the docker build and run commands can be removed.
101 changes: 101 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@

# Copyright (c) 2020 Emilio Reyes (soda480@gmail.com)

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
rest3client is a requests-based library providing simple methods to enable consumption of HTTP REST APIs.
The library further abstracts the underlying requests calls providing HTTP verb equivalent methods for GET, POST, PATCH, PUT and DELETE. The library includes a RESTclient class that implements a consistent approach for processing request responses, extracting error messages from responses, and providing standard headers to request calls. Enabling the consumer to focus on their business logic and less on the complexites of setting up and processing the requests repsonses.
A subclass inheriting RESTclient can override the base methods providing further customization and flexibility. The library supports most popular authentication schemes; including no-auth, basic auth, api-key and token-based.
"""

from pybuilder.core import use_plugin
from pybuilder.core import init
from pybuilder.core import Author
from pybuilder.core import task
from pybuilder.pluginhelper.external_command import ExternalCommandBuilder

use_plugin('python.core')
use_plugin('python.unittest')
use_plugin('python.install_dependencies')
use_plugin('python.flake8')
use_plugin('python.coverage')
use_plugin('python.distutils')
use_plugin('filter_resources')

name = 'rest3client'
authors = [
Author('Emilio Reyes', 'soda480@gmail.com')
]
summary = 'A Python class providing primitive methods for enabling consumption of REST APIs'
url = 'https://github.com/soda480/rest3client'
version = '0.0.1'
default_task = [
'clean',
'analyze',
'cyclomatic_complexity',
'package'
]
license = 'Apache License, Version 2.0'
description = __doc__


@init
def set_properties(project):
project.set_property('unittest_module_glob', 'test_*.py')
project.set_property('coverage_break_build', False)
project.set_property('flake8_max_line_length', 120)
project.set_property('flake8_verbose_output', True)
project.set_property('flake8_break_build', True)
project.set_property('flake8_include_scripts', True)
project.set_property('flake8_include_test_sources', True)
project.set_property('flake8_ignore', 'E501, W503, F401')
project.get_property('filter_resources_glob').extend(['**/rest3client/*'])
project.build_depends_on_requirements('requirements-build.txt')
project.depends_on_requirements('requirements.txt')
project.set_property('distutils_classifiers', [
'Development Status :: 4 - Beta',
'Environment :: Console',
'Environment :: Other Environment',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Apache Software License',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 3.6',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: System :: Networking',
'Topic :: System :: Systems Administration'
])


@task('cyclomatic_complexity', description='calculates and publishes cyclomatic complexity')
def cyclomatic_complexity(project, logger):
try:
command = ExternalCommandBuilder('radon', project)
command.use_argument('cc')
command.use_argument('-a')
result = command.run_on_production_source_files(logger)
if len(result.error_report_lines) > 0:
logger.error('Errors while running radon, see {0}'.format(result.error_report_file))
for line in result.report_lines[:-1]:
logger.debug(line.strip())
if not result.report_lines:
return
average_complexity_line = result.report_lines[-1].strip()
logger.info(average_complexity_line)

except Exception as exception:
print('Unable to execute cyclomatic complexity due to ERROR: {}'.format(str(exception)))
7 changes: 7 additions & 0 deletions requirements-build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
coverage
flake8
pypandoc
unittest-xml-reporting
mccabe
mock
radon
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests
74 changes: 74 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python
#

# -*- coding: utf-8 -*-
#
# This file is part of PyBuilder
#
# Copyright 2011-2015 PyBuilder Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# This script allows to support installation via:
# pip install git+git://<project>@<branch>
#
# This script is designed to be used in combination with `pip install` ONLY
#
# DO NOT RUN MANUALLY
#

import os
import subprocess
import sys
import glob
import shutil

from sys import version_info
py3 = version_info[0] == 3
py2 = not py3
if py2:
FileNotFoundError = OSError

script_dir = os.path.dirname(os.path.realpath(__file__))
exit_code = 0
try:
subprocess.check_call(["pyb", "--version"])
except FileNotFoundError as e:
if py3 or py2 and e.errno == 2:
try:
subprocess.check_call([sys.executable, "-m", "pip.__main__", "install", "pybuilder"])
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
else:
raise
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)

try:
subprocess.check_call(["pyb", "clean", "install_build_dependencies", "package", "-o"])
dist_dir = glob.glob(os.path.join(script_dir, "target", "dist", "*"))[0]
for src_file in glob.glob(os.path.join(dist_dir, "*")):
file_name = os.path.basename(src_file)
target_file_name = os.path.join(script_dir, file_name)
if os.path.exists(target_file_name):
if os.path.isdir(target_file_name):
shutil.rmtree(target_file_name)
else:
os.remove(target_file_name)
shutil.move(src_file, script_dir)
setup_args = sys.argv[1:]
subprocess.check_call([sys.executable, "setup.py"] + setup_args, cwd=script_dir)
except subprocess.CalledProcessError as e:
exit_code = e.returncode
sys.exit(exit_code)
Loading

0 comments on commit 9cf8bdd

Please sign in to comment.