Django Rest Framework Client
A python library for interacting with any Django web server based 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
- django-rest-framework's own tokens:
-
Support for query arguments (e.g.
?name1=val1&name2=val2) -
Support for custom methods (e.g. ``/api/v1/object/custom/`)
Requirements
django-rest-framework-client requires:
- Python 3.10+
- requests
- httpx
- respx
Installation
# Using pip
python -m pip install django-rest-framework-client
# Using uv
uv add django-rest-framework-client
Usage Guide
Example
import pprint
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 underscore ("_") with dashes ("-")
'SESSION_TRIES': 3, # Enable retry
'SESSION_TIMEOUT': None, # No timeout
'SESSION_VERIFY': False, # Do not verify SSL
}
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.pprint(obj)
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(BaseMain):
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,
"SESSION_TRIES": 3,
'SESSION_TIMEOUT': None,
'SESSION_VERIFY': False,
}
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 boilerplate code from script to script.
The class assumes that most scripts include the following basic flow:
- Parse arguments
- Setup LOG configuration
- Login
- Do something after logging in
The opinionated class will execute the basic main flow:
# Initialize arguments and LOG in the init function
# Add additional arguments by implementing 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 deriving from this class.
Here is a sample script:
from drf_client.helpers.base_main import BaseMain
from drf_client.helpers.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 OVERWRITE 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()
If you wish to implement coroutines to run multiple tasks in parallel, you can use the asyncio library.
import asyncio
from drf_client.helpers.base_main import BaseMain
from drf_client.helpers.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('-----------')
async def process(self):
"""Main async test"""
# foo_bar and foo_baz are coroutines
foo_bar = await self.api.foo.bar.async_get()
foo_baz = await self.api.foo.baz.async_get()
def after_login(self):
# Main function to OVERWRITE and do real work
resp = asyncio.run(self.process())
if __name__ == '__main__':
work = MyScript()
work.main()
Given the above script, you will run it with
python myscript.py -u <USERNAME> --foo bar
Development
django-rest-framework-client uses uv for dependency management and testing.
Make sure to install uv and run uv sync to install dependencies.
To test, run coverage analysis, and lint:
uv sync
uv run pytest
uv run ruff check
uv run ty check
# Install pre-commit hooks
pre-commit install
pre-commit install-hooks
CI Deployment
- Update
pyproject.tomlwith new version - Update
CHANGELOG.mdwith description of new version - Create a new tag with same version
git tag v0.4.1 -m "v0.4.1" git push --tags
- Create new release using GitHub Web Site. Github action will run automatically to deploy to PyPi.
Metadata
Release files for django-rest-framework-client 0.13.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django_rest_framework_client-0.13.0.tar.gz | 56.2 kB | Without provenance | Details for django_rest_framework_client-0.13.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_rest_framework_client-0.13.0-py3-none-any.whl | Python 3 | none | any | Details for django_rest_framework_client-0.13.0-py3-none-any.whl |
Total release size: 70.6 kB
Release files / django_rest_framework_client-0.13.0.tar.gz
| Download URL | django_rest_framework_client-0.13.0.tar.gz |
|---|---|
| Size | 56.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
74a368a4b8d41e32e0ceb298ec1b73a4ca0b7958815ee61245bce10b2527a362
|
|
BLAKE2b-256 checksum How to use checksums |
15aad62859d2ea756e1cedeaf062704505a3c251c3d266f38c5d5fd9bc28f33e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_rest_framework_client-0.13.0-py3-none-any.whl
| Download URL | django_rest_framework_client-0.13.0-py3-none-any.whl |
|---|---|
| Size | 14.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
862a5e14bc3a95f6bebddc83c3d8105235ac63be426ad06ca2310a9043089e86
|
|
BLAKE2b-256 checksum How to use checksums |
5d00d01481e2d2447781d27995bb15c9bd86890b2345aceec820405105b56010
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for django-rest-framework-client 0.13.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.