Django admin client
Project description
# Django Admin client
## Installation
```
pip install django-admin-client
```
## Usage
3 main usages:
1. Convenient HTTP GET and POST methods
2. Dynamic Django Admin python client
3. Generating specific Django Admin python client
### 1. Convenient HTTP GET and POST methods
`DjangoAdminBase` will do auto login, session management, and auto csrf token inclusion and auto error detection
```python
from django_admin_client import DjangoAdminBase
basic_client = DjangoAdminBase('http://127.0.0.1:9000/admin', 'superuser', 'why-dont-tell-mom?')
# auto login:
basic_client.get_with_auto_login('/')
# <Response [200]>
# response is just our favorite and well-known response from 'requests' library
type(basic_client.get_with_auto_login('/'))
# requests.models.Response
# auto login (if not yet logged in or session expired),
# csrf token included in POST request automatically,
# errors in response html form detected and provided
basic_client.post_with_csrf_and_auto_login(
'/auth/user/add/',
{'username': 'test', 'password1': '123', 'password2': '123'}
)
#{'response': <Response [200]>,
# 'errors': [<div class="form-row errors field-password2">
# <ul class="errorlist"><li>This password is too short. It must contain at least 8 characters.</li><li>This password is too common.</li><li>This password is entirely numeric.</li></ul>
# <div>
# <label class="required" for="id_password2">Password confirmation:</label>
# <input id="id_password2" name="password2" required="" type="password"/>
# <div class="help">Enter the same password as before, for verification.</div>
# </div>
# </div>]}
basic_client.post_with_csrf_and_auto_login(
'/auth/user/add/',
{'username': 'test', 'password1': 'isthislongenough', 'password2': 'isthislongenough'}
)
# {'response': <Response [200]>, 'errors': []}
```
### 2. Dynamic Django Admin python client
`DjangoAdminBase` can also do introspection on Django Admin site and generate specification.
```python
In [10]: basic_client.generate_spec()
Out[10]:
{
"models": {
"groups": {
"id": "groups",
"app": "auth",
"name": "group",
"fields": {
"name": {
"name": "name",
"required": true,
"default_value": ""
},
"permissions": {
"name": "permissions",
"required": false,
"default_value": ""
}
}
},
"users": {
"id": "users",
"app": "auth",
"name": "user",
"fields": {
"username": {
"name": "username",
"required": true,
"default_value": ""
},
"password1": {
"name": "password1",
"required": true,
"default_value": ""
},
"password2": {
"name": "password2",
"required": true,
"default_value": ""
}
}
}
}
}
```
This specification can then be fed to `DjangoAdminDynamic` class to get dynamic admin python client.
```python
from django_admin_client import DjangoAdminBase, DjangoAdminDynamic
basic_client = DjangoAdminBase('http://127.0.0.1:9000/admin', 'superuser', 'why-dont-tell-mom?')
spec = basic_client.generate_spec()
dynamic_client = DjangoAdminDynamic.from_spec(spec=spec, client=basic_client)
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2']}
```
At the moment you can add objects with `<model-name>.add(item: dict)`:
```python
dynamic_client.users.add({})
# ...
# MissingRequiredArgument: ['username', 'password1', 'password2']
dynamic_client.users.add({'username': 'fromdynamic', 'password1': 'qwertyuio!', 'password2': 'qwertyuio!'})
# {'_response': <Response [200]>, 'id': '3', 'created': True}
```
Get all object ids with `<model-name>.all()`:
```python
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2', '3']}
```
Search object id with `<model-name>.find(query: str)`:
```python
dynamic_client.users.find('fromdynamic')
# {'_response': <Response [200]>, 'id': '3'}
```
Get object fields with `<model-name>.get(object_id: str)`:
```python
dynamic_client.users.get('3')
#{'_response': <Response [200]>,
# 'details': {'username': 'fromdynamic',
# 'password': '<N/A>',
# 'first_name': '',
# 'last_name': '',
# 'email': '',
# 'is_active': '',
# 'is_staff': '',
# 'is_superuser': '',
# 'groups': [],
# 'user_permissions': [],
# 'last_login': '',
# 'date_joined': '2019-03-05'}}
```
And delete the object with `<model-name>.delete(object_id: str)`:
```python
dynamic_client.users.delete('3')
# {'_response': <Response [200]>, 'success': True}
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2']}
```
### 3. Generating specific Django Admin python client
`DjangoAdminDynamic` is quite useful for quick terminal sessions.
Auto-completion for `DjangoAdminDynamic` clients is provided in python interpreter when hitting `<tab>` because attributes
of a client are introspected at run time with `dir` built-in python funciton.
But writing source code with `DjangoAdminDynamic` is not that pleasant because
there's no way for IDE to know what attributes will object have at run time.
For this purpose `generate-package` command is provided with `django-admin-package`.
Example
```
$ generate-package
Base url (including /admin): http://localhost:9000/admin
Superuser username: superuser
Superuser password:
Site name: fresh project
Path to package (default: /tmp): .
Version (default: 1.0):
Generated package in ./freshproject-admin-client
```
Generated project structure:
```
$ tree freshproject-admin-client
freshproject-admin-client
├── freshproject_admin_client
│ ├── client.py
│ ├── __init__.py
│ └── spec.json
├── README.md
└── setup.py
1 directory, 5 files
```
You can version control generated package, install it, upload to PyPI.
Example usage of a generated client:
```
$ ipython
Python 3.6.7 (default, Nov 9 2018, 21:20:52)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.3.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from freshproject_admin_client import FreshProjectDjangoAdminClient
In [2]: client = FreshProjectDjangoAdminClient('http://localhost:9000/admin', 'superuser', 'why-dont-tell-mom?')
In [3]: client.auth.users.all()
Out[3]: {'_response': <Response [200]>, 'ids': ['4', '1', '2']}
In [4]: client.auth.users.add()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-213c8509773c> in <module>
----> 1 client.auth.users.add()
TypeError: add() missing 3 required positional arguments: 'username', 'password1', and 'password2'
In [5]: client.auth.users.add('from_freshproject_client', '123qweASD)_+', '123qweASD)_+')
Out[5]: {'_response': <Response [200]>, 'id': '5', 'created': True}
In [6]: client.auth.users.get('5')
Out[6]:
{'_response': <Response [200]>,
'details': {'username': 'from_freshproject_client',
'password': '<N/A>',
'first_name': '',
'last_name': '',
'email': '',
'is_active': '',
'is_staff': '',
'is_superuser': '',
'groups': [],
'user_permissions': [],
'last_login': '',
'date_joined': '2019-03-05'}}
In [7]: client.auth.users.find('from_freshproject_client')
Out[7]: {'_response': <Response [200]>, 'id': '5'}
In [8]: client.auth.users.delete('5')
Out[8]: {'_response': <Response [200]>, 'success': True}
```
## Installation
```
pip install django-admin-client
```
## Usage
3 main usages:
1. Convenient HTTP GET and POST methods
2. Dynamic Django Admin python client
3. Generating specific Django Admin python client
### 1. Convenient HTTP GET and POST methods
`DjangoAdminBase` will do auto login, session management, and auto csrf token inclusion and auto error detection
```python
from django_admin_client import DjangoAdminBase
basic_client = DjangoAdminBase('http://127.0.0.1:9000/admin', 'superuser', 'why-dont-tell-mom?')
# auto login:
basic_client.get_with_auto_login('/')
# <Response [200]>
# response is just our favorite and well-known response from 'requests' library
type(basic_client.get_with_auto_login('/'))
# requests.models.Response
# auto login (if not yet logged in or session expired),
# csrf token included in POST request automatically,
# errors in response html form detected and provided
basic_client.post_with_csrf_and_auto_login(
'/auth/user/add/',
{'username': 'test', 'password1': '123', 'password2': '123'}
)
#{'response': <Response [200]>,
# 'errors': [<div class="form-row errors field-password2">
# <ul class="errorlist"><li>This password is too short. It must contain at least 8 characters.</li><li>This password is too common.</li><li>This password is entirely numeric.</li></ul>
# <div>
# <label class="required" for="id_password2">Password confirmation:</label>
# <input id="id_password2" name="password2" required="" type="password"/>
# <div class="help">Enter the same password as before, for verification.</div>
# </div>
# </div>]}
basic_client.post_with_csrf_and_auto_login(
'/auth/user/add/',
{'username': 'test', 'password1': 'isthislongenough', 'password2': 'isthislongenough'}
)
# {'response': <Response [200]>, 'errors': []}
```
### 2. Dynamic Django Admin python client
`DjangoAdminBase` can also do introspection on Django Admin site and generate specification.
```python
In [10]: basic_client.generate_spec()
Out[10]:
{
"models": {
"groups": {
"id": "groups",
"app": "auth",
"name": "group",
"fields": {
"name": {
"name": "name",
"required": true,
"default_value": ""
},
"permissions": {
"name": "permissions",
"required": false,
"default_value": ""
}
}
},
"users": {
"id": "users",
"app": "auth",
"name": "user",
"fields": {
"username": {
"name": "username",
"required": true,
"default_value": ""
},
"password1": {
"name": "password1",
"required": true,
"default_value": ""
},
"password2": {
"name": "password2",
"required": true,
"default_value": ""
}
}
}
}
}
```
This specification can then be fed to `DjangoAdminDynamic` class to get dynamic admin python client.
```python
from django_admin_client import DjangoAdminBase, DjangoAdminDynamic
basic_client = DjangoAdminBase('http://127.0.0.1:9000/admin', 'superuser', 'why-dont-tell-mom?')
spec = basic_client.generate_spec()
dynamic_client = DjangoAdminDynamic.from_spec(spec=spec, client=basic_client)
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2']}
```
At the moment you can add objects with `<model-name>.add(item: dict)`:
```python
dynamic_client.users.add({})
# ...
# MissingRequiredArgument: ['username', 'password1', 'password2']
dynamic_client.users.add({'username': 'fromdynamic', 'password1': 'qwertyuio!', 'password2': 'qwertyuio!'})
# {'_response': <Response [200]>, 'id': '3', 'created': True}
```
Get all object ids with `<model-name>.all()`:
```python
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2', '3']}
```
Search object id with `<model-name>.find(query: str)`:
```python
dynamic_client.users.find('fromdynamic')
# {'_response': <Response [200]>, 'id': '3'}
```
Get object fields with `<model-name>.get(object_id: str)`:
```python
dynamic_client.users.get('3')
#{'_response': <Response [200]>,
# 'details': {'username': 'fromdynamic',
# 'password': '<N/A>',
# 'first_name': '',
# 'last_name': '',
# 'email': '',
# 'is_active': '',
# 'is_staff': '',
# 'is_superuser': '',
# 'groups': [],
# 'user_permissions': [],
# 'last_login': '',
# 'date_joined': '2019-03-05'}}
```
And delete the object with `<model-name>.delete(object_id: str)`:
```python
dynamic_client.users.delete('3')
# {'_response': <Response [200]>, 'success': True}
dynamic_client.users.all()
# {'_response': <Response [200]>, 'ids': ['1', '2']}
```
### 3. Generating specific Django Admin python client
`DjangoAdminDynamic` is quite useful for quick terminal sessions.
Auto-completion for `DjangoAdminDynamic` clients is provided in python interpreter when hitting `<tab>` because attributes
of a client are introspected at run time with `dir` built-in python funciton.
But writing source code with `DjangoAdminDynamic` is not that pleasant because
there's no way for IDE to know what attributes will object have at run time.
For this purpose `generate-package` command is provided with `django-admin-package`.
Example
```
$ generate-package
Base url (including /admin): http://localhost:9000/admin
Superuser username: superuser
Superuser password:
Site name: fresh project
Path to package (default: /tmp): .
Version (default: 1.0):
Generated package in ./freshproject-admin-client
```
Generated project structure:
```
$ tree freshproject-admin-client
freshproject-admin-client
├── freshproject_admin_client
│ ├── client.py
│ ├── __init__.py
│ └── spec.json
├── README.md
└── setup.py
1 directory, 5 files
```
You can version control generated package, install it, upload to PyPI.
Example usage of a generated client:
```
$ ipython
Python 3.6.7 (default, Nov 9 2018, 21:20:52)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.3.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from freshproject_admin_client import FreshProjectDjangoAdminClient
In [2]: client = FreshProjectDjangoAdminClient('http://localhost:9000/admin', 'superuser', 'why-dont-tell-mom?')
In [3]: client.auth.users.all()
Out[3]: {'_response': <Response [200]>, 'ids': ['4', '1', '2']}
In [4]: client.auth.users.add()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-213c8509773c> in <module>
----> 1 client.auth.users.add()
TypeError: add() missing 3 required positional arguments: 'username', 'password1', and 'password2'
In [5]: client.auth.users.add('from_freshproject_client', '123qweASD)_+', '123qweASD)_+')
Out[5]: {'_response': <Response [200]>, 'id': '5', 'created': True}
In [6]: client.auth.users.get('5')
Out[6]:
{'_response': <Response [200]>,
'details': {'username': 'from_freshproject_client',
'password': '<N/A>',
'first_name': '',
'last_name': '',
'email': '',
'is_active': '',
'is_staff': '',
'is_superuser': '',
'groups': [],
'user_permissions': [],
'last_login': '',
'date_joined': '2019-03-05'}}
In [7]: client.auth.users.find('from_freshproject_client')
Out[7]: {'_response': <Response [200]>, 'id': '5'}
In [8]: client.auth.users.delete('5')
Out[8]: {'_response': <Response [200]>, 'success': True}
```
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
django-admin-client-0.1.2.tar.gz
(10.6 kB
view hashes)
Built Distribution
Close
Hashes for django-admin-client-0.1.2.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1af284a7b3b377851db627fed1d735f95893a37be18cdc5f660d205aeb675dc5 |
|
MD5 | 86874f5382b05b3cbede6bd8706d2ac6 |
|
BLAKE2b-256 | e5bc3fd906a951e898757a496bcaea96d3adf400e732471f802cdbc794ab6c92 |
Close
Hashes for django_admin_client-0.1.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b03f665d747e85cea80799a816ffeaa89cf99ef825f16ce0b08285a24f14d71c |
|
MD5 | 32975134f32b0d06b832b6578b08aa5b |
|
BLAKE2b-256 | 8c9813951aee59ec05e9edd43202d9b56f6dd79b4bc26135ddf4e42b03c465ba |