# Django Rest Framework Python API Package
[![PyPI version](https://img.shields.io/pypi/v/django-rest-framework-client.svg)](https://pypi.python.org/pypi/django-rest-framework-client)
A python library for interacting with any Django web server base on django-rest-framework
Package is based on https://github.com/samgiles/slumber, but enhanced to support tokens and other features.
## Features
* Support for tokens. Both
* django-rest-framework's own tokens: `rest_framework.authentication.TokenAuthentication`
* JWT tokens: `rest_framework_jwt.authentication.JSONWebTokenAuthentication`
* Support for arguments (e.g. `?name1=val1&name2=val2`)
* Support for custom methods (e.g. ``/ap1/v1/object/custom/`)
## Requirements
restframeworkclient requires the following modules.
* Python 3.9+
* requests
## Installation
```bash
python3 -m venv ~/.virtualenv/drf_client
source ~/.virtualenv/drf_client/bin/activate
pip install django-rest-framework-client
```
## Usage Guide
Example
```
from drf_client.connection import Api as RestApi
options = {
'DOMAIN': 'http://127.0.0.1:8000',
'API_PREFIX': 'api/v1',
'TOKEN_TYPE': 'jwt',
'TOKEN_FORMAT': 'JWT {token}',
'USERNAME_KEY': 'username',
'LOGIN': 'auth/login/',
'LOGOUT': 'auth/logout/',
'USE_DASHES': False, # Set to True to tell API to replace undercore ("_") with dashes ("-")
}
c = RestApi(options)
ok = c.login(username=username, password=password)
if ok:
# GET some data
my_object = c.myresourcename.get()
for obj in my_object['results']:
pprint(obj)
logger.info('------------------------------')
payload = {
'data1': 'val1',
'data2': 'val2',
}
resp = c.myresourcename.post(data=payload)
# If the URL includes "-", add under parenthesis:
# GET: /api/v1/someresource/some-path/
my_object = c.someresource('some-path').get()
```
### Example using Tokens
```
from drf_client.helpers.base_main import BaseMain
class MyClass(Main):
options = {
'DOMAIN': None,
'API_PREFIX': 'api/v1',
'TOKEN_TYPE': 'bearer',
'TOKEN_FORMAT': 'Bearer {token}',
'USERNAME_KEY': 'username',
'LOGIN': 'auth/login/',
'LOGOUT': 'auth/logout/',
'USE_DASHES': False,
}
export DRF_CLIENT_AUTH_TOKEN=1fe171f65917db0072abc6880196989dd2a20025
python -m my_script.MyClass --server https://mysite.com --use-token t
```
## Django Setup
Client assumes by default that all urls should end with a slash (tested with the default
router: `routers.DefaultRouter()`)
Apart from the regular Django and Rest Framework setup, this package currently relies on the following custom
login and logout API functions:
```
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'email', 'username')
class APILogoutViewSet(APIView):
permission_classes = (permissions.IsAuthenticated,)
def post(self, request, format=None):
logout(request)
return Response({}, status=status.HTTP_204_NO_CONTENT)
urlpatterns = [
url(r'^auth/logout/$', APILogoutViewSet.as_view(), name='api-logout'),
```
## Helpers
### BaseMain Helper
This class helps write a script with a flexible template that helps avoid having to duplicate
boiler plate code from script to script.
The class assumes that most scripts include the basic folliwing flow:
```
# Parse arguments
# Setup LOG configuration
# Login
# Do something after logging in
```
The opinionated class will execute the basic main flow:
```python
# Initialize arguments and LOG in the init function
# Add additional arguments by implemenenting self.add_extra_args()
self.domain = self.get_domain()
self.api = Api(self.domain)
self.before_login()
ok = self.login()
if ok:
self.after_login()
```
Any of the above functions can be overwritten by derving from this class.
Here is a sample script:
```python
from drf_client.helper.base_main import BaseMain
from drf_client.helper.base_facade import BaseFacade
class MyScript(BaseMain):
def add_extra_args(self):
# Add extra positional argument (as example)
self.parser.add_argument('foo', metavar='foo', type=str, help='RTFM')
def before_login(self):
logger.info('-----------')
def after_login(self):
# Main function to OVERWITE and do real work
resp = self.api.foo.bar.get()
# You can also access the API from the global Facade
resp = BaseFacade.api.foo.bar.get()
if __name__ == '__main__':
work = MyScript()
work.main()
```
Given the above script, you will run it with
```bash
python myscript.py -u <USERNAME> --foo bar
```
## Development
To test, run python setup.py test or to run coverage analysis:
```bash
python3 -m venv .virtualenv/drf_client
source .virtualenv/drf_client/bin/activate
pip install -r requirements-test.txt
pip install -e .
py.test
```
## CI Deployment
1. Update `setup.py` with new version
2. Update `CHANGELOG.md` with description of new version
2. Create new tag with same version
```
git tag v0.4.1 -m "v0.4.1"
git push --tags
```
3. Create new release using GitHub Web Site. Github action will run automatically to deploy to PyPi.
## Manual Deployment
```bash
pip install -r requirements-build.txt
python setup.py sdist bdist_wheel
twine check dist/*
# Publish
twine upload dist/*
```
Raw data
{
"_id": null,
"home_page": "https://github.com/dkarchmer/django-rest-framework-client",
"name": "django-rest-framework-client",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10,<4",
"maintainer_email": "",
"keywords": "django,djangorestframework,drf,rest-client",
"author": "David Karchmer",
"author_email": "dkarchmer@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/23/69/98aa38fd229ac57b8cfb035c16570659b3c8d6b45c4741b4e4442eced7e9/django-rest-framework-client-0.10.0.tar.gz",
"platform": null,
"description": "# Django Rest Framework Python API Package\n\n[![PyPI version](https://img.shields.io/pypi/v/django-rest-framework-client.svg)](https://pypi.python.org/pypi/django-rest-framework-client)\n\nA python library for interacting with any Django web server base on django-rest-framework\n\nPackage is based on https://github.com/samgiles/slumber, but enhanced to support tokens and other features.\n\n## Features\n\n* Support for tokens. Both\n * django-rest-framework's own tokens: `rest_framework.authentication.TokenAuthentication`\n * JWT tokens: `rest_framework_jwt.authentication.JSONWebTokenAuthentication`\n\n* Support for arguments (e.g. `?name1=val1&name2=val2`)\n\n* Support for custom methods (e.g. ``/ap1/v1/object/custom/`)\n\n## Requirements\n\nrestframeworkclient requires the following modules.\n\n * Python 3.9+\n * requests\n\n## Installation\n\n```bash\npython3 -m venv ~/.virtualenv/drf_client\nsource ~/.virtualenv/drf_client/bin/activate\npip install django-rest-framework-client\n```\n\n## Usage Guide\n\nExample\n\n```\nfrom drf_client.connection import Api as RestApi\n\noptions = {\n 'DOMAIN': 'http://127.0.0.1:8000',\n 'API_PREFIX': 'api/v1',\n 'TOKEN_TYPE': 'jwt',\n 'TOKEN_FORMAT': 'JWT {token}',\n 'USERNAME_KEY': 'username',\n 'LOGIN': 'auth/login/',\n 'LOGOUT': 'auth/logout/',\n 'USE_DASHES': False, # Set to True to tell API to replace undercore (\"_\") with dashes (\"-\")\n}\n\nc = RestApi(options)\n\nok = c.login(username=username, password=password)\nif ok:\n\n # GET some data\n my_object = c.myresourcename.get()\n for obj in my_object['results']:\n pprint(obj)\n logger.info('------------------------------')\n\n payload = {\n 'data1': 'val1',\n 'data2': 'val2',\n }\n\n resp = c.myresourcename.post(data=payload)\n\n # If the URL includes \"-\", add under parenthesis:\n # GET: /api/v1/someresource/some-path/\n my_object = c.someresource('some-path').get()\n\n```\n\n### Example using Tokens\n\n```\nfrom drf_client.helpers.base_main import BaseMain\n\nclass MyClass(Main):\n\n options = {\n 'DOMAIN': None,\n 'API_PREFIX': 'api/v1',\n 'TOKEN_TYPE': 'bearer',\n 'TOKEN_FORMAT': 'Bearer {token}',\n 'USERNAME_KEY': 'username',\n 'LOGIN': 'auth/login/',\n 'LOGOUT': 'auth/logout/',\n 'USE_DASHES': False,\n }\n\nexport DRF_CLIENT_AUTH_TOKEN=1fe171f65917db0072abc6880196989dd2a20025\npython -m my_script.MyClass --server https://mysite.com --use-token t\n```\n\n## Django Setup\n\nClient assumes by default that all urls should end with a slash (tested with the default\nrouter: `routers.DefaultRouter()`)\n\nApart from the regular Django and Rest Framework setup, this package currently relies on the following custom\nlogin and logout API functions:\n\n```\nclass AccountSerializer(serializers.ModelSerializer):\n class Meta:\n model = User\n fields = ('id', 'email', 'username')\n\n\nclass APILogoutViewSet(APIView):\n permission_classes = (permissions.IsAuthenticated,)\n\n def post(self, request, format=None):\n logout(request)\n return Response({}, status=status.HTTP_204_NO_CONTENT)\n\n\nurlpatterns = [\n url(r'^auth/logout/$', APILogoutViewSet.as_view(), name='api-logout'),\n\n```\n\n## Helpers\n\n### BaseMain Helper\n\nThis class helps write a script with a flexible template that helps avoid having to duplicate\nboiler plate code from script to script.\n\nThe class assumes that most scripts include the basic folliwing flow:\n\n```\n# Parse arguments\n# Setup LOG configuration\n# Login\n# Do something after logging in\n```\n\nThe opinionated class will execute the basic main flow:\n\n```python\n # Initialize arguments and LOG in the init function\n # Add additional arguments by implemenenting self.add_extra_args()\n self.domain = self.get_domain()\n self.api = Api(self.domain)\n self.before_login()\n ok = self.login()\n if ok:\n self.after_login()\n```\n\nAny of the above functions can be overwritten by derving from this class.\n\nHere is a sample script:\n\n```python\nfrom drf_client.helper.base_main import BaseMain\nfrom drf_client.helper.base_facade import BaseFacade\n\nclass MyScript(BaseMain):\n\n def add_extra_args(self):\n # Add extra positional argument (as example)\n self.parser.add_argument('foo', metavar='foo', type=str, help='RTFM')\n\n def before_login(self):\n logger.info('-----------')\n\n def after_login(self):\n # Main function to OVERWITE and do real work\n resp = self.api.foo.bar.get()\n # You can also access the API from the global Facade\n resp = BaseFacade.api.foo.bar.get()\n\n\nif __name__ == '__main__':\n\n work = MyScript()\n work.main()\n```\n\nGiven the above script, you will run it with\n\n```bash\npython myscript.py -u <USERNAME> --foo bar\n```\n\n## Development\n\nTo test, run python setup.py test or to run coverage analysis:\n\n```bash\npython3 -m venv .virtualenv/drf_client\nsource .virtualenv/drf_client/bin/activate\npip install -r requirements-test.txt\npip install -e .\n\npy.test\n```\n\n## CI Deployment\n\n1. Update `setup.py` with new version\n2. Update `CHANGELOG.md` with description of new version\n2. Create new tag with same version\n\n```\ngit tag v0.4.1 -m \"v0.4.1\"\ngit push --tags\n```\n\n3. Create new release using GitHub Web Site. Github action will run automatically to deploy to PyPi.\n\n## Manual Deployment\n\n```bash\npip install -r requirements-build.txt\n\npython setup.py sdist bdist_wheel\ntwine check dist/*\n# Publish\ntwine upload dist/*\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python client for a DjangoRestFramework based web site",
"version": "0.10.0",
"project_urls": {
"Homepage": "https://github.com/dkarchmer/django-rest-framework-client"
},
"split_keywords": [
"django",
"djangorestframework",
"drf",
"rest-client"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "67bdf071167a38dabfa8fc96b263ad9f1a95df378e86e2d5a56213726c33df93",
"md5": "6bb3d3ec4dbc2e925db56dd6f563178d",
"sha256": "192b65215197d7a3ff76bc8ecd2c488551397d542304505a27bd03bdc02e1649"
},
"downloads": -1,
"filename": "django_rest_framework_client-0.10.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6bb3d3ec4dbc2e925db56dd6f563178d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4",
"size": 11363,
"upload_time": "2023-10-05T05:08:20",
"upload_time_iso_8601": "2023-10-05T05:08:20.429437Z",
"url": "https://files.pythonhosted.org/packages/67/bd/f071167a38dabfa8fc96b263ad9f1a95df378e86e2d5a56213726c33df93/django_rest_framework_client-0.10.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "236998aa38fd229ac57b8cfb035c16570659b3c8d6b45c4741b4e4442eced7e9",
"md5": "7ba277396ff2ca59fb09a273668f4fa0",
"sha256": "712abc440796a1533cfe2e8c9f3ff5bfd903fe1afa85fd781ebdc8ec8d73fa09"
},
"downloads": -1,
"filename": "django-rest-framework-client-0.10.0.tar.gz",
"has_sig": false,
"md5_digest": "7ba277396ff2ca59fb09a273668f4fa0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4",
"size": 10745,
"upload_time": "2023-10-05T05:08:22",
"upload_time_iso_8601": "2023-10-05T05:08:22.286260Z",
"url": "https://files.pythonhosted.org/packages/23/69/98aa38fd229ac57b8cfb035c16570659b3c8d6b45c4741b4e4442eced7e9/django-rest-framework-client-0.10.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-05 05:08:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dkarchmer",
"github_project": "django-rest-framework-client",
"travis_ci": true,
"coveralls": false,
"github_actions": true,
"requirements": [],
"tox": true,
"lcname": "django-rest-framework-client"
}