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
Requirements
django-rest-framework-client requires:
- Python 3.10+
- requests
- httpx
- respx
Installation
python -m pip install django-rest-framework-client
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,
'SESSION_TRIES': 3,
'SESSION_TIMEOUT': None,
'SESSION_VERIFY': False,
}
c = RestApi(options)
ok = c.login(username="username", password="password")
if ok:
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)
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:
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):
self.parser.add_argument('foo', metavar='foo', type=str, help='RTFM')
def before_login(self):
logger.info('-----------')
def after_login(self):
resp = self.api.foo.bar.get()
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):
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 = await self.api.foo.bar.async_get()
foo_baz = await self.api.foo.baz.async_get()
def after_login(self):
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
pre-commit install
pre-commit install-hooks
CI Deployment