User management module for Bazis framework.
Project description
Bazis Users
An extension package for Bazis that provides advanced capabilities for user management and authentication.
Quick Start
# Install the package
uv add bazis-users
# Create user model
from bazis.contrib.users.models_abstract import UserAbstract
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
class User(UserAbstract, DtMixin, UuidMixin, JsonApiMixin):
"""Custom user model"""
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
# Create user route
from bazis.contrib.users.routes import UserRouteSet
from django.apps import apps
class MyUserRouteSet(UserRouteSet):
model = apps.get_model('myapp.User')
Table of Contents
- Description
- Requirements
- Installation
- Core Components
- Usage
- API Authentication
- Examples
- License
- Links
Description
Bazis Users is an extension package for the Bazis framework that provides a complete toolkit for user management and authentication. The package includes:
- Abstract user models with JWT authentication support
- Ready-to-use routes for user operations
- Services for token and authentication management
- Mixins for linking models to users
- Integration with Swagger UI for API testing
This package requires the base bazis package to be installed.
Requirements
- Python: 3.12+
- bazis: latest version
- PostgreSQL: 12+
- Redis: For caching
Installation
Using uv (recommended)
uv add bazis-users
Using pip
pip install bazis-users
Core Components
Abstract Models
UserAbstract
Abstract user model implementing methods required for extended work with Bazis.
Location: bazis.contrib.users.models_abstract.UserAbstract
Methods:
get_full_name()- returns user's full namejwt_build()- creates JWT token for the userfind_or_create()- finds or creates a userraw_password- works with raw password
Example usage:
from bazis.contrib.users.models_abstract import UserAbstract
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
class User(UserAbstract, DtMixin, UuidMixin, JsonApiMixin):
"""Application user model"""
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
def __str__(self):
return self.get_full_name()
AnonymousUserAbstract
Abstract anonymous user model for handling unauthenticated requests.
Location: bazis.contrib.users.models_abstract.AnonymousUserAbstract
Methods:
get_full_name()- returns name for anonymous user
Mixins
UserMixin
Mixin for entity models that should be associated with a user.
Location: bazis.contrib.users.models_abstract.UserMixin
Features:
- User is stored in context variable
CTX_USER_REQUEST - Automatically links model to current user from request
Example usage:
from bazis.contrib.users.models_abstract import UserMixin
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
from django.db import models
class Article(UserMixin, DtMixin, UuidMixin, JsonApiMixin):
"""Article linked to a user"""
title = models.CharField(max_length=255)
content = models.TextField()
class Meta:
verbose_name = 'Article'
verbose_name_plural = 'Articles'
Base Routes
UserRouteBase
Base class for routes associated with users.
Location: bazis.contrib.users.routes_abstract.UserRouteBase
Provides base functionality for creating routes that work with user models.
Built-in Routes
token_auth
Basic token authentication (JWT), applied in Swagger UI.
Location: bazis.contrib.users.routes.token_auth
Enables JWT token authentication in Swagger UI.
UserRouteSet
Base route class for working with users.
Location: bazis.contrib.users.routes.UserRouteSet
Provides ready-to-use endpoints for user operations:
- List users
- Get specific user information
- Create user
- Update user
- Delete user
Example usage:
from bazis.contrib.users.routes import UserRouteSet
from django.apps import apps
class MyUserRouteSet(UserRouteSet):
model = apps.get_model('myapp.User')
Services
Services for working with users and tokens.
Location: bazis.contrib.users.services
get_token_data
Extracts data from JWT token.
from bazis.contrib.users.services import get_token_data
def my_endpoint(token: str = Depends(get_token_data)):
user_id = token.get('user_id')
# Work with token data
get_user_from_token
Gets user from token.
from bazis.contrib.users.services import get_user_from_token
def my_endpoint(user = Depends(get_user_from_token)):
# user - user object or AnonymousUser
print(user.get_full_name())
get_user_required
Gets user from request (authentication required).
from bazis.contrib.users.services import get_user_required
def my_endpoint(user = Depends(get_user_required)):
# user - authenticated user
# Returns 401 if token is invalid
return {"user": user.get_full_name()}
get_user_optional
Gets user from request (authentication optional).
from bazis.contrib.users.services import get_user_optional
def my_endpoint(user = Depends(get_user_optional)):
# user - user or AnonymousUser
if user.is_authenticated:
return {"user": user.get_full_name()}
return {"user": "Anonymous"}
Usage
Creating User Model
from bazis.contrib.users.models_abstract import UserAbstract
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
from django.db import models
class User(UserAbstract, DtMixin, UuidMixin, JsonApiMixin):
"""Custom user model"""
# Additional fields
phone = models.CharField('Phone', max_length=20, null=True, blank=True)
department = models.CharField('Department', max_length=100, null=True, blank=True)
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
def __str__(self):
return self.get_full_name()
Creating User Route
# routes.py
from bazis.contrib.users.routes import UserRouteSet
from bazis.core.schemas.fields import SchemaField, SchemaFields
from django.apps import apps
class MyUserRouteSet(UserRouteSet):
model = apps.get_model('myapp.User')
# Add additional fields to schema
fields = {
None: SchemaFields(
include={
'phone': None,
'department': None,
},
),
}
# router.py
from bazis.core.routing import BazisRouter
from . import routes
router = BazisRouter(tags=['Users'])
router.register(routes.MyUserRouteSet.as_router())
Using Authentication Services
Required Authentication
Use get_user_required for endpoints that require authentication:
from bazis.contrib.users.services import get_user_required
from fastapi import APIRouter, Depends
from pydantic import BaseModel
router = APIRouter()
class NewPasswordRequest(BaseModel):
old_password: str
new_password: str
@router.post('/user/change_password/', response_model=dict)
def change_password(
data: NewPasswordRequest,
user: User = Depends(get_user_required)
):
# user - guaranteed authenticated user
# Returns 401 if token is invalid
return user.change_password(data)
Optional Authentication
Use get_user_optional for endpoints available to everyone:
from bazis.contrib.users.services import get_user_optional, get_token_data
from fastapi import Depends
@router.get('/auth/', response_model=AuthResponse)
def auth(
auth_store: AuthStore = Depends(),
user: User = Depends(get_user_optional),
token_data: dict = Depends(get_token_data),
):
# user can be AnonymousUser
if user.is_anonymous:
if user_id := auth_store.user_id:
user = User.objects.filter(id=user_id).first()
# Logic for working with user or anonymous
return {"user": user.get_full_name() if not user.is_anonymous else "Anonymous"}
Using get_token_data
Getting data from JWT token without loading the user:
from bazis.contrib.users.services import get_token_data
from fastapi import Depends
@router.get('/token-info/')
def token_info(token_data: dict = Depends(get_token_data)):
# token_data contains decoded data from JWT
return {
"user_id": token_data.get("user_id"),
"exp": token_data.get("exp"),
}
Linking Models to Users
from bazis.contrib.users.models_abstract import UserMixin
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
from django.db import models
class Document(UserMixin, DtMixin, UuidMixin, JsonApiMixin):
"""Document automatically linked to user"""
title = models.CharField(max_length=255)
content = models.TextField()
class Meta:
verbose_name = 'Document'
verbose_name_plural = 'Documents'
API Authentication
Getting Token
After setting up routes, users can obtain JWT tokens through the authentication endpoint.
Example request:
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "user@example.com",
"password": "password123"
}
Example response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
Using Token in Requests
GET /api/v1/protected-resource
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authentication in Swagger UI
- Open
/api/swagger/ - Click "Authorize" button
- Enter token in format:
Bearer <your_token> - Click "Authorize"
- Now all requests will be executed with authentication
Examples
Complete Application Example with Users
models.py:
from bazis.contrib.users.models_abstract import UserAbstract, UserMixin
from bazis.core.models_abstract import DtMixin, UuidMixin, JsonApiMixin
from django.db import models
class User(UserAbstract, DtMixin, UuidMixin, JsonApiMixin):
"""System user"""
phone = models.CharField('Phone', max_length=20, null=True, blank=True)
class Meta:
verbose_name = 'User'
verbose_name_plural = 'Users'
class Task(UserMixin, DtMixin, UuidMixin, JsonApiMixin):
"""Task linked to user"""
title = models.CharField('Title', max_length=255)
description = models.TextField('Description')
is_completed = models.BooleanField('Completed', default=False)
assigned_to = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='tasks',
verbose_name='Assigned To'
)
class Meta:
verbose_name = 'Task'
verbose_name_plural = 'Tasks'
routes.py:
from bazis.contrib.users.routes import UserRouteSet
from bazis.contrib.users.services import get_user_required
from django.apps import apps
from fastapi import APIRouter, Depends
from pydantic import BaseModel
class MyUserRouteSet(UserRouteSet):
model = apps.get_model('myapp.User')
# Additional endpoints for working with tasks
router = APIRouter()
class TaskCreateRequest(BaseModel):
title: str
description: str
@router.get('/my-tasks/')
def get_my_tasks(user: User = Depends(get_user_required)):
# Return only current user's tasks
tasks = Task.objects.filter(assigned_to=user)
return {"tasks": [{"id": str(t.id), "title": t.title} for t in tasks]}
@router.post('/tasks/')
def create_task(
data: TaskCreateRequest,
user: User = Depends(get_user_required)
):
# Create task for current user
task = Task.objects.create(
title=data.title,
description=data.description,
assigned_to=user
)
return {"id": str(task.id), "title": task.title}
router.py:
from bazis.core.routing import BazisRouter
from . import routes
# Register user routes
user_router = BazisRouter(tags=['Users'])
user_router.register(routes.MyUserRouteSet.as_router())
# Register additional task endpoints
user_router.include_router(routes.router, prefix='/api/v1')
admin.py:
from django.contrib import admin
from bazis.core.admin_abstract import DtAdminMixin
from .models import User, Task
@admin.register(User)
class UserAdmin(DtAdminMixin, admin.ModelAdmin):
list_display = ('id', 'username', 'email', 'phone', 'is_active')
search_fields = ('username', 'email', 'phone')
list_filter = ('is_active', 'is_staff')
@admin.register(Task)
class TaskAdmin(DtAdminMixin, admin.ModelAdmin):
list_display = ('id', 'title', 'assigned_to', 'is_completed')
search_fields = ('title', 'description')
list_filter = ('is_completed',)
raw_id_fields = ('assigned_to',)
License
Apache License 2.0
See LICENSE file for details.
Links
- Bazis Documentation — main repository
- Bazis Users Repository — package repository
- Issue Tracker — report bugs or request features
Support
If you have questions or issues:
- Check the Bazis documentation
- Search existing issues
- Create a new issue with detailed information
Made with ❤️ by the Bazis team
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bazis_users-2.2.0.tar.gz.
File metadata
- Download URL: bazis_users-2.2.0.tar.gz
- Upload date:
- Size: 36.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
767ebea2b2e2669eff9fa3112a9eddbc61008d6a7ab9df5a77e0f5f2b12ef629
|
|
| MD5 |
fc8465f9ba8326a90c9d96407ee303f7
|
|
| BLAKE2b-256 |
164d5be7542e8b02e6745efbe440dbe3986715fd0bd41690a4c6bb39689e566a
|
File details
Details for the file bazis_users-2.2.0-py3-none-any.whl.
File metadata
- Download URL: bazis_users-2.2.0-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc0ed4da2cba1535bb71e496c97c413a0b0b54d17bcd9452197b2d9363303b07
|
|
| MD5 |
e27901e80248c39f8c17253bda955459
|
|
| BLAKE2b-256 |
61c0f05f11c33de692f649d3eff16c635208c3a28ebdacf3a3df1b3218fb702e
|