mirror of
https://github.com/kjanat/livegraphs-django.git
synced 2026-01-16 06:32:10 +01:00
Add configuration and scripts for linting, testing, and dependency management
- Introduced .pre-commit-config.yaml for pre-commit hooks using uv-pre-commit. - Created lint.sh script to run Ruff and Black for linting and formatting. - Added test.sh script to execute tests with coverage reporting. - Configured .uv file for uv settings including lockfile management and dependency resolution. - Updated Makefile with targets for virtual environment setup, dependency installation, linting, testing, formatting, and database migrations. - Established requirements.txt with main and development dependencies for the project.
This commit is contained in:
@ -18,7 +18,8 @@ indent_size = 4
|
||||
|
||||
# HTML and Django/Jinja2 template files
|
||||
[*.{html,htm}]
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
# Allow prettier to format Django/Jinja templates properly
|
||||
# The following comment options can be used in individual files if needed:
|
||||
# <!-- prettier-ignore -->
|
||||
@ -26,6 +27,7 @@ indent_size = 2
|
||||
|
||||
# CSS, JavaScript, and JSON files
|
||||
[*.{css,scss,js,json}]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
# Markdown files
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -407,3 +407,12 @@ pyrightconfig.json
|
||||
*Zone.Identifier
|
||||
examples/
|
||||
**/migrations/[0-9]**.py
|
||||
|
||||
# UV specific
|
||||
.uv/
|
||||
.uv-configs/
|
||||
|
||||
# Pyright and IDE specific
|
||||
.vscode/
|
||||
.idea/
|
||||
.pyright/
|
||||
|
||||
92
.pre-commit-config.yaml
Normal file
92
.pre-commit-config.yaml
Normal file
@ -0,0 +1,92 @@
|
||||
default_install_hook_types:
|
||||
- pre-commit
|
||||
- post-checkout
|
||||
- post-merge
|
||||
- post-rewrite
|
||||
repos:
|
||||
# uv hooks for dependency management
|
||||
- repo: https://github.com/astral-sh/uv-pre-commit
|
||||
rev: 0.7.5
|
||||
hooks:
|
||||
- id: uv-export
|
||||
|
||||
# Standard pre-commit hooks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-json
|
||||
- id: check-toml
|
||||
- id: check-added-large-files
|
||||
args: ["--maxkb=500"]
|
||||
- id: detect-private-key
|
||||
- id: check-merge-conflict
|
||||
- id: check-case-conflict
|
||||
- id: debug-statements
|
||||
- id: mixed-line-ending
|
||||
args: ["--fix=lf"]
|
||||
|
||||
# # HTML/Django template linting
|
||||
# - repo: https://github.com/rtts/djhtml
|
||||
# rev: 3.0.7
|
||||
# hooks:
|
||||
# - id: djhtml
|
||||
# entry: djhtml --tabwidth 4 --
|
||||
# - id: djcss
|
||||
# - id: djjs
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v4.0.0-alpha.8
|
||||
hooks:
|
||||
- id: prettier
|
||||
types_or: [javascript, jsx, ts, tsx, css, scss, html, json, yaml, markdown]
|
||||
additional_dependencies:
|
||||
- prettier
|
||||
- prettier-plugin-jinja-template
|
||||
|
||||
# Ruff for linting and formatting
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.11.10
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
- id: ruff-format
|
||||
|
||||
# Django-specific hooks
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: django-check
|
||||
name: Django Check
|
||||
entry: uv run python dashboard_project/manage.py check
|
||||
language: system
|
||||
pass_filenames: false
|
||||
types: [python]
|
||||
always_run: true
|
||||
|
||||
- id: django-check-migrations
|
||||
name: Django Check Migrations
|
||||
entry: uv run python dashboard_project/manage.py makemigrations --check --dry-run
|
||||
language: system
|
||||
pass_filenames: false
|
||||
types: [python]
|
||||
|
||||
# Security checks
|
||||
- repo: https://github.com/pycqa/bandit
|
||||
rev: 1.8.3
|
||||
hooks:
|
||||
- id: bandit
|
||||
args: ["-c", "pyproject.toml", "-r", "dashboard_project"]
|
||||
additional_dependencies: ["bandit[toml]"]
|
||||
|
||||
# # Type checking
|
||||
# - repo: https://github.com/pre-commit/mirrors-mypy
|
||||
# rev: v1.15.0
|
||||
# hooks:
|
||||
# - id: mypy
|
||||
# additional_dependencies:
|
||||
# - django-stubs>=5.0.2
|
||||
# - types-python-dateutil
|
||||
# - types-requests
|
||||
# - types-PyYAML
|
||||
@ -11,9 +11,7 @@
|
||||
"requirePragma": false,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"useTabs": false,
|
||||
"useTabs": true,
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.html"],
|
||||
|
||||
11
.scripts/lint.sh
Executable file
11
.scripts/lint.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# Run linting, formatting and type checking
|
||||
|
||||
echo "Running Ruff linter..."
|
||||
uv run -m ruff check dashboard_project
|
||||
|
||||
echo "Running Ruff formatter..."
|
||||
uv run -m ruff format dashboard_project
|
||||
|
||||
echo "Running Black formatter..."
|
||||
uv run -m black dashboard_project
|
||||
6
.scripts/test.sh
Executable file
6
.scripts/test.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Run tests with coverage
|
||||
|
||||
echo "Running tests with coverage..."
|
||||
uv run -m coverage run -m pytest
|
||||
uv run -m coverage report -m
|
||||
18
.uv
Normal file
18
.uv
Normal file
@ -0,0 +1,18 @@
|
||||
[uv]
|
||||
# Keep the uv.lock file up to date
|
||||
keep-lockfile = true
|
||||
|
||||
# Cache compiled bytecode for dependencies
|
||||
compile-bytecode = true
|
||||
|
||||
# Use a local cache directory
|
||||
local-cache = true
|
||||
|
||||
# Verbosity of output
|
||||
verbosity = "minimal"
|
||||
|
||||
# Define which part of the environment to check
|
||||
environment-checks = ["python", "dependencies"]
|
||||
|
||||
# How to resolve dependencies not specified with exact versions
|
||||
dependency-resolution = "strict"
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -43,5 +43,5 @@
|
||||
"notebook.source.organizeImports": "explicit"
|
||||
},
|
||||
"notebook.formatOnSave.enabled": true,
|
||||
"prettier.requireConfig": true,
|
||||
"prettier.requireConfig": true
|
||||
}
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@ -10,15 +10,25 @@ ENV DJANGO_SETTINGS_MODULE=dashboard_project.settings
|
||||
# Set work directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install UV for Python package management
|
||||
RUN pip install uv
|
||||
|
||||
# Copy project files
|
||||
COPY pyproject.toml .
|
||||
COPY uv.lock .
|
||||
COPY . .
|
||||
|
||||
# Install dependencies
|
||||
COPY requirements.txt .
|
||||
RUN uv pip install -e .
|
||||
|
||||
# Copy project
|
||||
COPY . .
|
||||
# Change to the Django project directory
|
||||
WORKDIR /app/dashboard_project
|
||||
|
||||
# Collect static files
|
||||
RUN python manage.py collectstatic --noinput
|
||||
|
||||
# Change back to the app directory
|
||||
WORKDIR /app
|
||||
|
||||
# Run gunicorn
|
||||
CMD ["gunicorn", "dashboard_project.wsgi:application", "--bind", "0.0.0.0:8000"]
|
||||
|
||||
78
Makefile
Normal file
78
Makefile
Normal file
@ -0,0 +1,78 @@
|
||||
.PHONY: venv install install-dev lint test format clean run migrate makemigrations superuser setup-node format-js
|
||||
|
||||
# Create a virtual environment
|
||||
venv:
|
||||
uv venv -p 3.13
|
||||
|
||||
# Install production dependencies
|
||||
install:
|
||||
uv pip install -e .
|
||||
|
||||
# Install development dependencies
|
||||
install-dev:
|
||||
uv pip install -e ".[dev]"
|
||||
|
||||
# Run linting
|
||||
lint:
|
||||
uv run -m ruff check dashboard_project
|
||||
|
||||
# Run tests
|
||||
test:
|
||||
uv run -m pytest
|
||||
|
||||
# Format Python code
|
||||
format:
|
||||
uv run -m ruff format dashboard_project
|
||||
uv run -m black dashboard_project
|
||||
|
||||
# Format JavaScript/CSS/HTML files with Prettier
|
||||
format-js:
|
||||
npx run format
|
||||
|
||||
# Setup Node.js dependencies
|
||||
setup-node:
|
||||
npm install
|
||||
|
||||
# Clean Python cache files
|
||||
clean:
|
||||
find . -type d -name "__pycache__" -exec rm -rf {} +
|
||||
find . -type f -name "*.pyc" -delete
|
||||
find . -type f -name "*.pyo" -delete
|
||||
find . -type f -name "*.pyd" -delete
|
||||
find . -type d -name "*.egg-info" -exec rm -rf {} +
|
||||
find . -type d -name "*.egg" -exec rm -rf {} +
|
||||
find . -type d -name ".pytest_cache" -exec rm -rf {} +
|
||||
find . -type d -name ".coverage" -exec rm -rf {} +
|
||||
find . -type d -name "htmlcov" -exec rm -rf {} +
|
||||
find . -type d -name ".ruff_cache" -exec rm -rf {} +
|
||||
rm -rf build/
|
||||
rm -rf dist/
|
||||
|
||||
# Run the development server
|
||||
run:
|
||||
cd dashboard_project && uv run python manage.py runserver 8001
|
||||
|
||||
# Apply migrations
|
||||
migrate:
|
||||
cd dashboard_project && uv run python manage.py migrate
|
||||
|
||||
# Create migrations
|
||||
makemigrations:
|
||||
cd dashboard_project && uv run python manage.py makemigrations
|
||||
|
||||
# Create a superuser
|
||||
superuser:
|
||||
cd dashboard_project && uv run python manage.py createsuperuser
|
||||
|
||||
# Update uv lock file
|
||||
lock:
|
||||
uv pip freeze > requirements.lock
|
||||
|
||||
# Setup pre-commit hooks
|
||||
setup-pre-commit:
|
||||
uv pip install pre-commit
|
||||
pre-commit install
|
||||
|
||||
# Run pre-commit on all files
|
||||
lint-all:
|
||||
pre-commit run --all-files
|
||||
@ -1,37 +1,61 @@
|
||||
# Prettier for Django/Jinja Templates
|
||||
# Prettier for Django Templates
|
||||
|
||||
This project uses Prettier with the `prettier-plugin-jinja-template` plugin to format HTML templates with Django/Jinja syntax.
|
||||
This project uses Prettier with the `prettier-plugin-django-annotations` plugin to format HTML templates with Django template syntax.
|
||||
|
||||
## Setup
|
||||
|
||||
To use Prettier with your Django templates, you'll need to install Prettier and the Jinja template plugin:
|
||||
The project is already configured with Prettier integration in pre-commit hooks. The configuration includes:
|
||||
|
||||
1. `.prettierrc` - Configuration file with Django HTML support
|
||||
2. `.prettierignore` - Files to exclude from formatting
|
||||
3. Pre-commit hook for automatic formatting on commits
|
||||
|
||||
### Manual Installation
|
||||
|
||||
To use Prettier locally (outside of pre-commit hooks), you'll need to install the dependencies:
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install --save-dev prettier prettier-plugin-jinja-template
|
||||
npm install
|
||||
|
||||
# Or using yarn
|
||||
yarn add --dev prettier prettier-plugin-jinja-template
|
||||
# Or install just the required packages
|
||||
npm install --save-dev prettier prettier-plugin-django-annotations
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Once installed, you can format your Django templates using:
|
||||
### With Pre-commit
|
||||
|
||||
Prettier will automatically run as part of the pre-commit hooks when you commit changes.
|
||||
|
||||
To manually run the pre-commit hooks on all files:
|
||||
|
||||
```bash
|
||||
pre-commit run prettier --all-files
|
||||
```
|
||||
|
||||
### Using npm Scripts
|
||||
|
||||
The package.json includes npm scripts for formatting:
|
||||
|
||||
```bash
|
||||
# Format all static files
|
||||
npm run format
|
||||
|
||||
# Check formatting without modifying files
|
||||
npm run format:check
|
||||
```
|
||||
|
||||
### Command Line
|
||||
|
||||
You can also run Prettier directly:
|
||||
|
||||
```bash
|
||||
# Format a specific file
|
||||
npx prettier --write path/to/template.html
|
||||
|
||||
# Format all HTML files
|
||||
npx prettier --write "**/*.html"
|
||||
```
|
||||
|
||||
### Without install
|
||||
|
||||
If you don't want to install the plugin, you can use the following command:
|
||||
|
||||
```bash
|
||||
npx prettier --plugin=prettier-plugin-jinja-template --parser=jinja-template --write **/*.html
|
||||
npx prettier --write "dashboard_project/templates/**/*.html"
|
||||
```
|
||||
|
||||
## VSCode Integration
|
||||
@ -62,3 +86,12 @@ If you need to prevent Prettier from formatting a section of your template:
|
||||
This works too.
|
||||
</div>
|
||||
```
|
||||
|
||||
## Django Template Support
|
||||
|
||||
The `prettier-plugin-django-annotations` plugin provides special handling for Django templates, including:
|
||||
|
||||
- Proper formatting of Django template tags (`{% %}`)
|
||||
- Support for Django template comments (`{# #}`)
|
||||
- Preservation of Django template variable output (`{{ }}`)
|
||||
- Special handling for Django template syntax inside HTML attributes
|
||||
|
||||
91
README.md
91
README.md
@ -15,9 +15,9 @@ A Django application that creates an analytics dashboard for chat session data.
|
||||
## Requirements
|
||||
|
||||
- Python 3.13+
|
||||
- Django 5.0+
|
||||
- PostgreSQL (optional, SQLite is fine for development)
|
||||
- Other dependencies listed in [`pyproject.toml`](pyproject.toml)
|
||||
- Django 5.2+
|
||||
- UV package manager (recommended)
|
||||
- Other dependencies listed in [`pyproject.toml`](./pyproject.toml)
|
||||
|
||||
## Setup
|
||||
|
||||
@ -27,42 +27,103 @@ A Django application that creates an analytics dashboard for chat session data.
|
||||
|
||||
```sh
|
||||
git clone <repository-url>
|
||||
cd dashboard_project
|
||||
cd LiveGraphsDjango
|
||||
```
|
||||
|
||||
2. Create a virtual environment and activate it:
|
||||
2. Install uv if you don't have it yet:
|
||||
|
||||
```sh
|
||||
# Install using pip
|
||||
pip install uv
|
||||
|
||||
# Or with curl (Unix/macOS)
|
||||
curl -sSf https://install.pypa.io/get-uv.py | python3 -
|
||||
|
||||
# Or on Windows with PowerShell
|
||||
irm https://install.pypa.io/get-uv.ps1 | iex
|
||||
```
|
||||
|
||||
3. Create a virtual environment and activate it:
|
||||
|
||||
```sh
|
||||
uv venv
|
||||
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
||||
```
|
||||
|
||||
3. Install dependencies:
|
||||
4. Install dependencies:
|
||||
|
||||
```sh
|
||||
uv pip install -r requirements.txt
|
||||
# Install all dependencies including dev dependencies
|
||||
uv pip install -e ".[dev]"
|
||||
|
||||
# Or just runtime dependencies
|
||||
uv pip install -e .
|
||||
```
|
||||
|
||||
4. Run migrations:
|
||||
5. Run migrations:
|
||||
|
||||
```sh
|
||||
uv run python manage.py makemigrations
|
||||
uv run python manage.py migrate
|
||||
cd dashboard_project
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
5. Create a superuser:
|
||||
6. Create a superuser:
|
||||
|
||||
```sh
|
||||
uv run python manage.py createsuperuser
|
||||
python manage.py createsuperuser
|
||||
```
|
||||
|
||||
6. Run the development server:
|
||||
7. Run the development server:
|
||||
|
||||
```sh
|
||||
uv run python manage.py runserver
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
7. Access the application at <http://127.0.0.1:8000/>
|
||||
8. Access the application at <http://127.0.0.1:8000/>
|
||||
|
||||
### Development Workflow with UV
|
||||
|
||||
UV offers several advantages over traditional pip, including faster dependency resolution and installation:
|
||||
|
||||
1. Running linting and formatting:
|
||||
|
||||
```sh
|
||||
# Using the convenience script
|
||||
./.scripts/lint.sh
|
||||
|
||||
# Or directly
|
||||
uv run -m ruff check dashboard_project
|
||||
uv run -m ruff format dashboard_project
|
||||
uv run -m black dashboard_project
|
||||
```
|
||||
|
||||
2. Running tests:
|
||||
|
||||
```sh
|
||||
# Using the convenience script
|
||||
./.scripts/test.sh
|
||||
|
||||
# Or directly
|
||||
uv run -m pytest
|
||||
```
|
||||
|
||||
3. Adding new dependencies:
|
||||
|
||||
```sh
|
||||
# Add to project
|
||||
uv pip install package_name
|
||||
|
||||
# Then update pyproject.toml manually
|
||||
# And update the lockfile
|
||||
uv pip freeze > requirements.lock
|
||||
```
|
||||
|
||||
4. Updating the lockfile:
|
||||
|
||||
```sh
|
||||
uv pip compile pyproject.toml -o uv.lock
|
||||
```
|
||||
|
||||
### Using Docker
|
||||
|
||||
|
||||
8
TODO.md
8
TODO.md
@ -21,11 +21,11 @@
|
||||
- Add a button to download the CSV file for the selected company.
|
||||
- Make it possible to modify the column names in the CSV file through the admin interface.
|
||||
- Add possibility to add a company logo in the admin interface.
|
||||
- Add periodic download from https://proto.notso.ai/jumbo/chats possibility for the jumbo company.
|
||||
- Add periodic download from <https://proto.notso.ai/XY/chats> possibility for the XY company.
|
||||
- Authentication: Basic Auth
|
||||
- URL: https://proto.notso.ai/jumbo/chats
|
||||
- Username: jumboadmin
|
||||
- Password: jumboadmin
|
||||
- URL: <https://proto.notso.ai/XY/chats>
|
||||
- Username: xxxx
|
||||
- Password: xxxx
|
||||
- Reduce amount of rows in the table to fit the screen.
|
||||
- Add dark mode/theming to the dashboard.
|
||||
- Add Notso AI branding to the dashboard.
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
"""
|
||||
LiveGraphsDjango - Dashboard for analyzing chat session data.
|
||||
"""
|
||||
|
||||
__version__ = "0.1.0"
|
||||
@ -18,7 +18,7 @@ User = get_user_model()
|
||||
class Command(BaseCommand):
|
||||
help = "Create sample data for testing"
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
def handle(self, **_options):
|
||||
self.stdout.write("Creating sample data...")
|
||||
|
||||
# Create admin user if it doesn't exist
|
||||
@ -45,7 +45,7 @@ class Command(BaseCommand):
|
||||
self.stdout.write(f"Company already exists: {company.name}")
|
||||
|
||||
# Create users for each company
|
||||
for i, company in enumerate(companies):
|
||||
for _i, company in enumerate(companies):
|
||||
# Company admin
|
||||
username = f"admin_{company.name.lower().replace(' ', '_')}"
|
||||
if not User.objects.filter(username=username).exists():
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# dashboard/utils.py
|
||||
|
||||
import contextlib
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from django.db import models
|
||||
@ -25,17 +27,13 @@ def process_csv_file(data_source):
|
||||
# Handle datetime fields
|
||||
start_time = None
|
||||
end_time = None
|
||||
|
||||
if "start_time" in row and pd.notna(row["start_time"]):
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
start_time = make_aware(pd.to_datetime(row["start_time"]))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if "end_time" in row and pd.notna(row["end_time"]):
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
end_time = make_aware(pd.to_datetime(row["end_time"]))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Convert boolean fields
|
||||
|
||||
@ -7,7 +7,7 @@ from pathlib import Path
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "django-insecure-your-secret-key-here"
|
||||
SECRET_KEY = "django-insecure-your-secret-key-here" # nosec: B105
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
@ -6,18 +6,23 @@
|
||||
.dashboard-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||
|
||||
/* Slightly larger minmax for widgets */
|
||||
gap: 1.5rem;
|
||||
|
||||
/* Increased gap */
|
||||
}
|
||||
|
||||
/* Dashboard widget cards */
|
||||
.dashboard-widget {
|
||||
display: flex;
|
||||
|
||||
/* Allow flex for content alignment */
|
||||
flex-direction: column;
|
||||
|
||||
/* Stack header, body, footer vertically */
|
||||
height: 100%;
|
||||
|
||||
/* Ensure widgets fill grid cell height */
|
||||
}
|
||||
|
||||
@ -29,6 +34,7 @@
|
||||
|
||||
.dashboard-widget .card-header .widget-title {
|
||||
font-size: 1.1rem;
|
||||
|
||||
/* Slightly larger widget titles */
|
||||
font-weight: 600;
|
||||
}
|
||||
@ -40,6 +46,7 @@
|
||||
|
||||
.dashboard-widget .card-header .widget-actions .btn {
|
||||
width: 32px;
|
||||
|
||||
/* Slightly larger action buttons */
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
@ -60,8 +67,10 @@
|
||||
|
||||
.dashboard-widget .card-body {
|
||||
flex-grow: 1;
|
||||
|
||||
/* Allow card body to take available space */
|
||||
padding: 1.25rem;
|
||||
|
||||
/* Consistent padding */
|
||||
}
|
||||
|
||||
@ -74,8 +83,10 @@
|
||||
.chart-widget .chart-container {
|
||||
flex: 1;
|
||||
min-height: 250px;
|
||||
|
||||
/* Adjusted min-height */
|
||||
width: 100%;
|
||||
|
||||
/* Ensure it takes full width of card body */
|
||||
}
|
||||
|
||||
@ -83,11 +94,13 @@
|
||||
.stat-card {
|
||||
text-align: center;
|
||||
padding: 1.5rem;
|
||||
|
||||
/* Generous padding */
|
||||
}
|
||||
|
||||
.stat-card .stat-icon {
|
||||
font-size: 2.25rem;
|
||||
|
||||
/* Larger icon */
|
||||
margin-bottom: 1rem;
|
||||
display: inline-block;
|
||||
@ -97,24 +110,30 @@
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background-color: #e9f2ff;
|
||||
|
||||
/* Light blue background for icon */
|
||||
color: #007bff;
|
||||
|
||||
/* Primary color for icon */
|
||||
}
|
||||
|
||||
.stat-card .stat-value {
|
||||
font-size: 2.25rem;
|
||||
|
||||
/* Larger stat value */
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
|
||||
/* Reduced margin */
|
||||
line-height: 1.1;
|
||||
color: #212529;
|
||||
|
||||
/* Darker color for value */
|
||||
}
|
||||
|
||||
.stat-card .stat-label {
|
||||
font-size: 0.9rem;
|
||||
|
||||
/* Slightly larger label */
|
||||
color: #6c757d;
|
||||
margin-bottom: 0;
|
||||
@ -122,7 +141,7 @@
|
||||
|
||||
/* Dashboard theme variations */
|
||||
.dashboard-theme-light .card {
|
||||
background-color: #ffffff;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dashboard-theme-dark {
|
||||
@ -150,8 +169,10 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
|
||||
/* Increased gap */
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
/* Increased margin */
|
||||
}
|
||||
|
||||
@ -161,6 +182,7 @@
|
||||
|
||||
.time-period-selector .btn {
|
||||
padding: 0.375rem 0.75rem;
|
||||
|
||||
/* Bootstrap-like padding */
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
@ -190,11 +212,14 @@
|
||||
.widget-placeholder {
|
||||
min-height: 300px;
|
||||
background: linear-gradient(90deg, #e9ecef 25%, #f8f9fa 50%, #e9ecef 75%);
|
||||
|
||||
/* Lighter gradient */
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.8s infinite ease-in-out;
|
||||
|
||||
/* Smoother animation */
|
||||
border-radius: 0.5rem;
|
||||
|
||||
/* Consistent with cards */
|
||||
}
|
||||
|
||||
@ -211,18 +236,22 @@
|
||||
/* Dashboard empty states */
|
||||
.empty-state {
|
||||
padding: 2.5rem;
|
||||
|
||||
/* Increased padding */
|
||||
text-align: center;
|
||||
color: #6c757d;
|
||||
background-color: #f8f9fa;
|
||||
|
||||
/* Light background for empty state */
|
||||
border-radius: 0.5rem;
|
||||
border: 1px dashed #ced4da;
|
||||
|
||||
/* Dashed border */
|
||||
}
|
||||
|
||||
.empty-state .empty-state-icon {
|
||||
font-size: 3.5rem;
|
||||
|
||||
/* Larger icon */
|
||||
margin-bottom: 1.5rem;
|
||||
opacity: 0.4;
|
||||
@ -230,6 +259,7 @@
|
||||
|
||||
.empty-state .empty-state-message {
|
||||
font-size: 1.2rem;
|
||||
|
||||
/* Slightly larger message */
|
||||
margin-bottom: 1.5rem;
|
||||
font-weight: 500;
|
||||
@ -240,7 +270,7 @@
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 767.98px) {
|
||||
@media (width <=767.98px) {
|
||||
.dashboard-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
@ -268,13 +298,17 @@
|
||||
gap: 1.5rem;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
flex: 1 1 0;
|
||||
min-width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end; /* Push content to bottom */
|
||||
justify-content: flex-end;
|
||||
|
||||
/* Push content to bottom */
|
||||
align-items: flex-start;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* Remove min-height/height for natural stretch */
|
||||
}
|
||||
|
||||
@ -8,21 +8,27 @@ body {
|
||||
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
background-color: #f4f7f9;
|
||||
|
||||
/* Lighter, cleaner background */
|
||||
color: #333;
|
||||
|
||||
/* Darker text for better contrast */
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
|
||||
/* Added for sticky footer */
|
||||
flex-direction: column;
|
||||
|
||||
/* Added for sticky footer */
|
||||
min-height: 100vh;
|
||||
|
||||
/* Ensures body takes at least full viewport height */
|
||||
}
|
||||
|
||||
/* Navbar adjustments (if needed, Bootstrap usually handles this well) */
|
||||
.navbar {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 5%);
|
||||
|
||||
/* Subtle shadow for depth */
|
||||
}
|
||||
|
||||
@ -46,44 +52,52 @@ body {
|
||||
/* Card styles */
|
||||
.card {
|
||||
border: 1px solid #e0e5e9;
|
||||
|
||||
/* Lighter border */
|
||||
border-radius: 0.5rem;
|
||||
|
||||
/* Slightly more rounded corners */
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 8%);
|
||||
|
||||
/* Softer, more modern shadow */
|
||||
transition:
|
||||
transform 0.2s ease-in-out,
|
||||
box-shadow 0.2s ease-in-out;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
/* Consistent margin */
|
||||
}
|
||||
|
||||
.card-hover:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 6px 16px rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: #ffffff;
|
||||
background-color: #fff;
|
||||
|
||||
/* Clean white header */
|
||||
border-bottom: 1px solid #e0e5e9;
|
||||
font-weight: 500;
|
||||
|
||||
/* Slightly bolder header text */
|
||||
padding: 0.75rem 1.25rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.15rem;
|
||||
|
||||
/* Adjusted card title size */
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Sidebar enhancements */
|
||||
.sidebar {
|
||||
background-color: #ffffff;
|
||||
background-color: #fff;
|
||||
|
||||
/* White sidebar for a cleaner look */
|
||||
border-right: 1px solid #e0e5e9;
|
||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.03);
|
||||
box-shadow: 2px 0 5px rgb(0 0 0 / 3%);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
@ -93,35 +107,44 @@ body {
|
||||
|
||||
.sidebar .nav-link {
|
||||
color: #4a5568;
|
||||
|
||||
/* Softer link color */
|
||||
padding: 0.65rem 1.25rem;
|
||||
|
||||
/* Adjusted padding */
|
||||
border-radius: 0.375rem;
|
||||
|
||||
/* Bootstrap-like rounded corners for links */
|
||||
margin: 0.1rem 0.5rem;
|
||||
|
||||
/* Margin around links */
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover {
|
||||
color: #007bff;
|
||||
|
||||
/* Primary color on hover */
|
||||
background-color: #e9f2ff;
|
||||
|
||||
/* Light blue background on hover */
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
background-color: #d6e4ff;
|
||||
|
||||
/* Slightly darker blue for active */
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar .nav-link i.me-2 {
|
||||
width: 20px;
|
||||
|
||||
/* Ensure icons align well */
|
||||
text-align: center;
|
||||
margin-right: 0.75rem !important;
|
||||
|
||||
/* Consistent icon spacing */
|
||||
}
|
||||
|
||||
@ -130,6 +153,7 @@ body {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: #718096;
|
||||
|
||||
/* Softer header color */
|
||||
padding: 0.5rem 1.25rem;
|
||||
margin-top: 1rem;
|
||||
@ -166,7 +190,7 @@ body {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
background-color: rgb(255 255 255 / 70%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -180,19 +204,23 @@ body {
|
||||
|
||||
.table th {
|
||||
font-weight: 600;
|
||||
|
||||
/* Bolder table headers */
|
||||
color: #4a5568;
|
||||
background-color: #f8f9fc;
|
||||
|
||||
/* Light background for headers */
|
||||
}
|
||||
|
||||
.table-striped tbody tr:nth-of-type(odd) {
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
background-color: rgb(0 0 0 / 2%);
|
||||
|
||||
/* Very subtle striping */
|
||||
}
|
||||
|
||||
.table-hover tbody tr:hover {
|
||||
background-color: #e9f2ff;
|
||||
|
||||
/* Consistent hover with sidebar */
|
||||
}
|
||||
|
||||
@ -201,24 +229,30 @@ body {
|
||||
.form-select {
|
||||
border-color: #ced4da;
|
||||
border-radius: 0.375rem;
|
||||
|
||||
/* Consistent border radius */
|
||||
padding: 0.5rem 0.75rem;
|
||||
|
||||
/* Adjusted padding */
|
||||
}
|
||||
|
||||
.form-control:focus,
|
||||
.form-select:focus {
|
||||
border-color: #86b7fe;
|
||||
|
||||
/* Bootstrap focus color */
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
box-shadow: 0 0 0 0.25rem rgb(13 110 253 / 25%);
|
||||
|
||||
/* Bootstrap focus shadow */
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
.btn {
|
||||
border-radius: 0.375rem;
|
||||
|
||||
/* Consistent border radius */
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
/* Standard button padding */
|
||||
font-weight: 500;
|
||||
transition:
|
||||
@ -272,18 +306,20 @@ body {
|
||||
|
||||
/* Footer styling */
|
||||
footer {
|
||||
background-color: #ffffff;
|
||||
background-color: #fff;
|
||||
|
||||
/* White footer */
|
||||
border-top: 1px solid #e0e5e9;
|
||||
padding: 1.5rem 0;
|
||||
color: #6c757d;
|
||||
font-size: 0.9rem;
|
||||
margin-top: auto;
|
||||
|
||||
/* Added for sticky footer */
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 767.98px) {
|
||||
@media (width <=767.98px) {
|
||||
.main-content {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@ -85,7 +85,8 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) throw new Error(`Network response was not ok: ${response.status}`);
|
||||
if (!response.ok)
|
||||
throw new Error(`Network response was not ok: ${response.status}`);
|
||||
return response.text();
|
||||
})
|
||||
.then((html) => {
|
||||
@ -106,7 +107,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
history.pushState(
|
||||
{ url: url, title: document.title, scrollPos: currentScrollPos },
|
||||
document.title,
|
||||
url
|
||||
url,
|
||||
);
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
} else if (window.history.state && window.history.state.scrollPos) {
|
||||
@ -214,7 +215,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
if (typeof bootstrap !== "undefined") {
|
||||
// Initialize tooltips
|
||||
const tooltipTriggerList = [].slice.call(
|
||||
document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
||||
document.querySelectorAll('[data-bs-toggle="tooltip"]'),
|
||||
);
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
@ -222,7 +223,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
// Initialize popovers
|
||||
const popoverTriggerList = [].slice.call(
|
||||
document.querySelectorAll('[data-bs-toggle="popover"]')
|
||||
document.querySelectorAll('[data-bs-toggle="popover"]'),
|
||||
);
|
||||
popoverTriggerList.map(function (popoverTriggerEl) {
|
||||
return new bootstrap.Popover(popoverTriggerEl);
|
||||
|
||||
@ -164,7 +164,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
yaxis: {
|
||||
title: "Number of Sessions",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error rendering time series chart:", error);
|
||||
@ -205,7 +205,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
],
|
||||
{
|
||||
margin: { t: 10, r: 10, b: 10, l: 10 },
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
xaxis: {
|
||||
title: "Number of Sessions",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
],
|
||||
{
|
||||
margin: { t: 10, r: 10, b: 10, l: 10 },
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
}
|
||||
form.classList.add("was-validated");
|
||||
},
|
||||
false
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -21,7 +21,9 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<p class="mb-0">Don't have an account? <a href="{% url 'register' %}">Register</a></p>
|
||||
<p class="mb-0">
|
||||
Don't have an account? <a href="{% url 'register' %}">Register</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -25,7 +25,10 @@
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-check-circle fa-4x text-success mb-3"></i>
|
||||
<h4>Your password has been changed successfully!</h4>
|
||||
<p>Your new password is now active. You can use it the next time you log in.</p>
|
||||
<p>
|
||||
Your new password is now active. You can use it the next time you log
|
||||
in.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
|
||||
@ -62,7 +62,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<a href="{% url 'password_change' %}" class="btn btn-primary">Change Password</a>
|
||||
<a href="{% url 'password_change' %}" class="btn btn-primary"
|
||||
>Change Password</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -116,7 +118,9 @@
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Manage Users</h5>
|
||||
<p class="card-text">Manage users and assign them to companies.</p>
|
||||
<p class="card-text">
|
||||
Manage users and assign them to companies.
|
||||
</p>
|
||||
<a
|
||||
href="{% url 'admin:accounts_customuser_changelist' %}"
|
||||
class="btn btn-primary"
|
||||
@ -129,7 +133,9 @@
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Manage Companies</h5>
|
||||
<p class="card-text">Create and edit companies in the system.</p>
|
||||
<p class="card-text">
|
||||
Create and edit companies in the system.
|
||||
</p>
|
||||
<a
|
||||
href="{% url 'admin:accounts_company_changelist' %}"
|
||||
class="btn btn-primary"
|
||||
@ -143,7 +149,11 @@
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Admin Dashboard</h5>
|
||||
<p class="card-text">Go to the full admin dashboard.</p>
|
||||
<a href="{% url 'admin:index' %}" class="btn btn-primary">Admin Dashboard</a>
|
||||
<a
|
||||
href="{% url 'admin:index' %}"
|
||||
class="btn btn-primary"
|
||||
>Admin Dashboard</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -152,8 +162,12 @@
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Manage Dashboards</h5>
|
||||
<p class="card-text">Create and edit dashboards for your company.</p>
|
||||
<a href="{% url 'create_dashboard' %}" class="btn btn-primary"
|
||||
<p class="card-text">
|
||||
Create and edit dashboards for your company.
|
||||
</p>
|
||||
<a
|
||||
href="{% url 'create_dashboard' %}"
|
||||
class="btn btn-primary"
|
||||
>Manage Dashboards</a
|
||||
>
|
||||
</div>
|
||||
@ -163,8 +177,14 @@
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Upload Data</h5>
|
||||
<p class="card-text">Upload and manage data sources for analysis.</p>
|
||||
<a href="{% url 'upload_data' %}" class="btn btn-primary">Upload Data</a>
|
||||
<p class="card-text">
|
||||
Upload and manage data sources for analysis.
|
||||
</p>
|
||||
<a
|
||||
href="{% url 'upload_data' %}"
|
||||
class="btn btn-primary"
|
||||
>Upload Data</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -172,8 +192,12 @@
|
||||
<div class="card h-100">
|
||||
<div class="card-body text-center">
|
||||
<h5 class="card-title">Search Sessions</h5>
|
||||
<p class="card-text">Search and analyze chat sessions.</p>
|
||||
<a href="{% url 'search_chat_sessions' %}" class="btn btn-primary"
|
||||
<p class="card-text">
|
||||
Search and analyze chat sessions.
|
||||
</p>
|
||||
<a
|
||||
href="{% url 'search_chat_sessions' %}"
|
||||
class="btn btn-primary"
|
||||
>Search Sessions</a
|
||||
>
|
||||
</div>
|
||||
|
||||
@ -21,7 +21,9 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<p class="mb-0">Already have an account? <a href="{% url 'login' %}">Login</a></p>
|
||||
<p class="mb-0">
|
||||
Already have an account? <a href="{% url 'login' %}">Login</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -81,21 +81,38 @@
|
||||
aria-expanded="false"
|
||||
>
|
||||
{% if user.company %}
|
||||
<span class="badge bg-info me-1">{{ user.company.name }}</span>
|
||||
<span class="badge bg-info me-1"
|
||||
>{{ user.company.name }}</span
|
||||
>
|
||||
{% endif %}
|
||||
{{ user.username }}
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userDropdown">
|
||||
<ul
|
||||
class="dropdown-menu dropdown-menu-end"
|
||||
aria-labelledby="userDropdown"
|
||||
>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="{% url 'profile' %}">Profile</a>
|
||||
<a
|
||||
class="dropdown-item ajax-nav-link"
|
||||
href="{% url 'profile' %}"
|
||||
>Profile</a
|
||||
>
|
||||
</li>
|
||||
{% if user.is_staff %}
|
||||
<li><a class="dropdown-item" href="{% url 'admin:index' %}">Admin</a></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{% url 'admin:index' %}"
|
||||
>Admin</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<hr class="dropdown-divider" />
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="{% url 'logout' %}">Logout</a></li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{% url 'logout' %}"
|
||||
>Logout</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% else %}
|
||||
@ -178,7 +195,10 @@
|
||||
<li class="nav-header"><strong>Data Sources</strong></li>
|
||||
{% for data_source in data_sources %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'data_source_detail' data_source.id %}">
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{% url 'data_source_detail' data_source.id %}"
|
||||
>
|
||||
<i class="fas fa-database me-2"></i>
|
||||
{{ data_source.name }}
|
||||
</a>
|
||||
@ -276,7 +296,9 @@
|
||||
if (!toastContainer) return;
|
||||
|
||||
// Find all message data elements
|
||||
const messageDataElements = document.querySelectorAll('script[id^="message-data-"]');
|
||||
const messageDataElements = document.querySelectorAll(
|
||||
'script[id^="message-data-"]',
|
||||
);
|
||||
messageDataElements.forEach(function (dataElement) {
|
||||
try {
|
||||
const messageData = JSON.parse(dataElement.textContent);
|
||||
@ -308,7 +330,10 @@
|
||||
}
|
||||
|
||||
const toastId =
|
||||
"toast-" + Date.now() + "-" + Math.random().toString(36).substring(2, 11);
|
||||
"toast-" +
|
||||
Date.now() +
|
||||
"-" +
|
||||
Math.random().toString(36).substring(2, 11);
|
||||
const toastHtml = `
|
||||
<div id="${toastId}" class="toast ${toastClass}" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header">
|
||||
|
||||
@ -27,9 +27,16 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><strong>Session ID:</strong> {{ session.session_id }}</p>
|
||||
<p><strong>Start Time:</strong> {{ session.start_time|date:"F d, Y H:i" }}</p>
|
||||
<p><strong>End Time:</strong> {{ session.end_time|date:"F d, Y H:i" }}</p>
|
||||
<p><strong>IP Address:</strong> {{ session.ip_address|default:"N/A" }}</p>
|
||||
<p>
|
||||
<strong>Start Time:</strong>
|
||||
{{ session.start_time|date:"F d, Y H:i" }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>End Time:</strong> {{ session.end_time|date:"F d, Y H:i" }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>IP Address:</strong> {{ session.ip_address|default:"N/A" }}
|
||||
</p>
|
||||
<p><strong>Country:</strong> {{ session.country|default:"N/A" }}</p>
|
||||
<p><strong>Language:</strong> {{ session.language|default:"N/A" }}</p>
|
||||
</div>
|
||||
@ -40,19 +47,27 @@
|
||||
{{ session.avg_response_time|floatformat:2 }}s
|
||||
</p>
|
||||
<p><strong>Tokens:</strong> {{ session.tokens }}</p>
|
||||
<p><strong>Token Cost:</strong> €{{ session.tokens_eur|floatformat:2 }}</p>
|
||||
<p>
|
||||
<strong>Token Cost:</strong> €{{ session.tokens_eur|floatformat:2 }}
|
||||
</p>
|
||||
<p><strong>Category:</strong> {{ session.category|default:"N/A" }}</p>
|
||||
<p>
|
||||
<strong>Sentiment:</strong>
|
||||
{% if session.sentiment %}
|
||||
{% if 'positive' in session.sentiment|lower %}
|
||||
<span class="badge bg-success">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-success"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% elif 'negative' in session.sentiment|lower %}
|
||||
<span class="badge bg-danger">{{ session.sentiment }}</span>
|
||||
{% elif 'neutral' in session.sentiment|lower %}
|
||||
<span class="badge bg-warning">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-warning"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-secondary"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">N/A</span>
|
||||
|
||||
@ -42,22 +42,30 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="timeRangeDropdown">
|
||||
<li>
|
||||
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=7"
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=7"
|
||||
>Last 7 days</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=30"
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=30"
|
||||
>Last 30 days</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=90"
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=90"
|
||||
>Last 90 days</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=all"
|
||||
<a
|
||||
class="dropdown-item"
|
||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=all"
|
||||
>All time</a
|
||||
>
|
||||
</li>
|
||||
@ -165,10 +173,16 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
try {
|
||||
// Parse the dashboard data components from script tags
|
||||
const timeSeriesData = JSON.parse(document.getElementById("time-series-data").textContent);
|
||||
const sentimentData = JSON.parse(document.getElementById("sentiment-data").textContent);
|
||||
const timeSeriesData = JSON.parse(
|
||||
document.getElementById("time-series-data").textContent,
|
||||
);
|
||||
const sentimentData = JSON.parse(
|
||||
document.getElementById("sentiment-data").textContent,
|
||||
);
|
||||
const countryData = JSON.parse(document.getElementById("country-data").textContent);
|
||||
const categoryData = JSON.parse(document.getElementById("category-data").textContent);
|
||||
const categoryData = JSON.parse(
|
||||
document.getElementById("category-data").textContent,
|
||||
);
|
||||
|
||||
console.log("Time series data loaded:", timeSeriesData);
|
||||
console.log("Sentiment data loaded:", sentimentData);
|
||||
@ -206,7 +220,7 @@
|
||||
yaxis: {
|
||||
title: "Number of Sessions",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
document.getElementById("sessions-time-chart").innerHTML =
|
||||
@ -219,7 +233,8 @@
|
||||
const sentimentValues = sentimentData.map((item) => item.count);
|
||||
const sentimentColors = sentimentLabels.map((sentiment) => {
|
||||
if (sentiment.toLowerCase().includes("positive")) return "rgb(75, 192, 92)";
|
||||
if (sentiment.toLowerCase().includes("negative")) return "rgb(255, 99, 132)";
|
||||
if (sentiment.toLowerCase().includes("negative"))
|
||||
return "rgb(255, 99, 132)";
|
||||
if (sentiment.toLowerCase().includes("neutral")) return "rgb(255, 205, 86)";
|
||||
return "rgb(201, 203, 207)";
|
||||
});
|
||||
@ -241,7 +256,7 @@
|
||||
],
|
||||
{
|
||||
margin: { t: 10, r: 10, b: 10, l: 10 },
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
document.getElementById("sentiment-chart").innerHTML =
|
||||
@ -271,7 +286,7 @@
|
||||
xaxis: {
|
||||
title: "Number of Sessions",
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
document.getElementById("country-chart").innerHTML =
|
||||
@ -296,7 +311,7 @@
|
||||
],
|
||||
{
|
||||
margin: { t: 10, r: 10, b: 10, l: 10 },
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
document.getElementById("category-chart").innerHTML =
|
||||
|
||||
@ -22,11 +22,12 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">
|
||||
Are you sure you want to delete the dashboard "<strong>{{ dashboard.name }}</strong>"?
|
||||
Are you sure you want to delete the dashboard
|
||||
"<strong>{{ dashboard.name }}</strong>"?
|
||||
</p>
|
||||
<p>
|
||||
This action cannot be undone. The dashboard will be permanently deleted, but the
|
||||
underlying data sources will remain intact.
|
||||
This action cannot be undone. The dashboard will be permanently deleted, but
|
||||
the underlying data sources will remain intact.
|
||||
</p>
|
||||
|
||||
<form method="post">
|
||||
|
||||
@ -30,14 +30,17 @@
|
||||
"<strong>{{ data_source.name }}</strong>"?
|
||||
</p>
|
||||
<p>
|
||||
This action cannot be undone. The data source and all associated chat sessions
|
||||
({{ data_source.chat_sessions.count }} sessions) will be permanently deleted.
|
||||
This action cannot be undone. The data source and all associated chat
|
||||
sessions ({{ data_source.chat_sessions.count }} sessions) will be
|
||||
permanently deleted.
|
||||
</p>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<a href="{% url 'data_source_detail' data_source.id %}" class="btn btn-secondary"
|
||||
<a
|
||||
href="{% url 'data_source_detail' data_source.id %}"
|
||||
class="btn btn-secondary"
|
||||
>Cancel</a
|
||||
>
|
||||
<button type="submit" class="btn btn-danger">Delete Data Source</button>
|
||||
|
||||
@ -19,7 +19,10 @@
|
||||
>
|
||||
<i class="fas fa-file-csv"></i> Export CSV
|
||||
</a>
|
||||
<a href="{% url 'delete_data_source' data_source.id %}" class="btn btn-sm btn-outline-danger">
|
||||
<a
|
||||
href="{% url 'delete_data_source' data_source.id %}"
|
||||
class="btn btn-sm btn-outline-danger"
|
||||
>
|
||||
<i class="fas fa-trash"></i> Delete
|
||||
</a>
|
||||
</div>
|
||||
@ -35,7 +38,10 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><strong>Name:</strong> {{ data_source.name }}</p>
|
||||
<p><strong>Uploaded At:</strong> {{ data_source.uploaded_at|date:"F d, Y H:i" }}</p>
|
||||
<p>
|
||||
<strong>Uploaded At:</strong>
|
||||
{{ data_source.uploaded_at|date:"F d, Y H:i" }}
|
||||
</p>
|
||||
<p><strong>File:</strong> {{ data_source.file.name|split:"/"|last }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
@ -62,7 +68,11 @@
|
||||
placeholder="Search sessions..."
|
||||
aria-label="Search sessions"
|
||||
/>
|
||||
<input type="hidden" name="data_source_id" value="{{ data_source.id }}" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="data_source_id"
|
||||
value="{{ data_source.id }}"
|
||||
/>
|
||||
<button class="btn btn-outline-primary" type="submit">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
@ -105,13 +115,21 @@
|
||||
<td>
|
||||
{% if session.sentiment %}
|
||||
{% if 'positive' in session.sentiment|lower %}
|
||||
<span class="badge bg-success">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-success"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% elif 'negative' in session.sentiment|lower %}
|
||||
<span class="badge bg-danger">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-danger"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% elif 'neutral' in session.sentiment|lower %}
|
||||
<span class="badge bg-warning">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-warning"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">{{ session.sentiment }}</span>
|
||||
<span class="badge bg-secondary"
|
||||
>{{ session.sentiment }}</span
|
||||
>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">N/A</span>
|
||||
@ -129,7 +147,10 @@
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-outline-secondary" disabled>
|
||||
<button
|
||||
class="btn btn-sm btn-outline-secondary"
|
||||
disabled
|
||||
>
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
@ -137,7 +158,9 @@
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="9" class="text-center">No chat sessions found.</td>
|
||||
<td colspan="9" class="text-center">
|
||||
No chat sessions found.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@ -178,11 +201,15 @@
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active">
|
||||
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||
<a class="page-link" href="?page={{ num }}"
|
||||
>{{ num }}</a
|
||||
>
|
||||
</li>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||
<a class="page-link" href="?page={{ num }}"
|
||||
>{{ num }}</a
|
||||
>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
@ -11,7 +11,10 @@
|
||||
<h1 class="h2">Data View</h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<div class="btn-group me-2">
|
||||
<a href="{% url 'dashboard' %}" class="btn btn-sm btn-outline-secondary ajax-nav-link">
|
||||
<a
|
||||
href="{% url 'dashboard' %}"
|
||||
class="btn btn-sm btn-outline-secondary ajax-nav-link"
|
||||
>
|
||||
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
||||
</a>
|
||||
{% if selected_data_source %}
|
||||
@ -34,16 +37,28 @@
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dataViewDropdown">
|
||||
<li><a class="dropdown-item ajax-nav-link" href="?view=all">All Sessions</a></li>
|
||||
<li><a class="dropdown-item ajax-nav-link" href="?view=recent">Recent Sessions</a></li>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=positive">Positive Sentiment</a>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=all">All Sessions</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=negative">Negative Sentiment</a>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=recent"
|
||||
>Recent Sessions</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=escalated">Escalated Sessions</a>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=positive"
|
||||
>Positive Sentiment</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=negative"
|
||||
>Negative Sentiment</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item ajax-nav-link" href="?view=escalated"
|
||||
>Escalated Sessions</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -60,7 +75,11 @@
|
||||
<div class="card-body">
|
||||
<form method="get" class="row g-3 align-items-center filter-form">
|
||||
<div class="col-md-6">
|
||||
<select name="data_source_id" class="form-select" aria-label="Select Data Source">
|
||||
<select
|
||||
name="data_source_id"
|
||||
class="form-select"
|
||||
aria-label="Select Data Source"
|
||||
>
|
||||
<option value="">All Data Sources</option>
|
||||
{% for ds in data_sources %}
|
||||
<option
|
||||
@ -74,17 +93,28 @@
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<select name="view" class="form-select" aria-label="Select View">
|
||||
<option value="all" {% if view == 'all' %}selected{% endif %}>All Sessions</option>
|
||||
<option value="all" {% if view == 'all' %}selected{% endif %}>
|
||||
All Sessions
|
||||
</option>
|
||||
<option value="recent" {% if view == 'recent' %}selected{% endif %}>
|
||||
Recent Sessions
|
||||
</option>
|
||||
<option value="positive" {% if view == 'positive' %}selected{% endif %}>
|
||||
<option
|
||||
value="positive"
|
||||
{% if view == 'positive' %}selected{% endif %}
|
||||
>
|
||||
Positive Sentiment
|
||||
</option>
|
||||
<option value="negative" {% if view == 'negative' %}selected{% endif %}>
|
||||
<option
|
||||
value="negative"
|
||||
{% if view == 'negative' %}selected{% endif %}
|
||||
>
|
||||
Negative Sentiment
|
||||
</option>
|
||||
<option value="escalated" {% if view == 'escalated' %}selected{% endif %}>
|
||||
<option
|
||||
value="escalated"
|
||||
{% if view == 'escalated' %}selected{% endif %}
|
||||
>
|
||||
Escalated Sessions
|
||||
</option>
|
||||
</select>
|
||||
@ -106,14 +136,28 @@
|
||||
<h5 class="card-title mb-0">Export Data</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="export-form" method="get" action="{% url 'export_chats_csv' %}" class="row g-3">
|
||||
<form
|
||||
id="export-form"
|
||||
method="get"
|
||||
action="{% url 'export_chats_csv' %}"
|
||||
class="row g-3"
|
||||
>
|
||||
<!-- Pass current filters to export -->
|
||||
<input type="hidden" name="data_source_id" value="{{ selected_data_source.id }}" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="data_source_id"
|
||||
value="{{ selected_data_source.id }}"
|
||||
/>
|
||||
<input type="hidden" name="view" value="{{ view }}" />
|
||||
|
||||
<div class="col-md-3">
|
||||
<label for="start_date" class="form-label">Start Date</label>
|
||||
<input type="date" name="start_date" id="start_date" class="form-control" />
|
||||
<input
|
||||
type="date"
|
||||
name="start_date"
|
||||
id="start_date"
|
||||
class="form-control"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label for="end_date" class="form-label">End Date</label>
|
||||
@ -183,7 +227,9 @@
|
||||
</div>
|
||||
|
||||
<!-- Data table container that will be updated via AJAX -->
|
||||
<div id="ajax-content-container">{% include "dashboard/partials/data_table.html" %}</div>
|
||||
<div id="ajax-content-container">
|
||||
{% include "dashboard/partials/data_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -20,18 +20,22 @@
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-building fa-4x text-warning mb-3"></i>
|
||||
<h4>You are not currently associated with any company</h4>
|
||||
<p class="lead">You need to be associated with a company to access the dashboard.</p>
|
||||
<p class="lead">
|
||||
You need to be associated with a company to access the dashboard.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Please contact an administrator to have your account assigned to a company. Once your
|
||||
account is associated with a company, you'll be able to access the dashboard and its
|
||||
features.
|
||||
Please contact an administrator to have your account assigned to a company.
|
||||
Once your account is associated with a company, you'll be able to access the
|
||||
dashboard and its features.
|
||||
</p>
|
||||
|
||||
<div class="mt-4">
|
||||
<a href="{% url 'profile' %}" class="btn btn-primary">View Your Profile</a>
|
||||
<a href="{% url 'logout' %}" class="btn btn-outline-secondary ms-2">Logout</a>
|
||||
<a href="{% url 'logout' %}" class="btn btn-outline-secondary ms-2"
|
||||
>Logout</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -20,7 +20,9 @@
|
||||
<td>{{ session.session_id|truncatechars:10 }}</td>
|
||||
<td>{{ session.start_time|date:"M d, Y H:i" }}</td>
|
||||
<td>
|
||||
<a href="{% url 'data_source_detail' session.data_source.id %}" class="ajax-nav-link"
|
||||
<a
|
||||
href="{% url 'data_source_detail' session.data_source.id %}"
|
||||
class="ajax-nav-link"
|
||||
>{{ session.data_source.name|truncatechars:15 }}</a
|
||||
>
|
||||
</td>
|
||||
@ -60,7 +62,9 @@
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="9" class="text-center">No chat sessions found matching your criteria.</td>
|
||||
<td colspan="9" class="text-center">
|
||||
No chat sessions found matching your criteria.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@ -22,7 +22,11 @@
|
||||
<h5 class="card-title mb-0">Search Chat Sessions</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="get" action="{% url 'search_chat_sessions' %}" class="search-form">
|
||||
<form
|
||||
method="get"
|
||||
action="{% url 'search_chat_sessions' %}"
|
||||
class="search-form"
|
||||
>
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="text"
|
||||
@ -33,7 +37,11 @@
|
||||
aria-label="Search sessions"
|
||||
/>
|
||||
{% if data_source %}
|
||||
<input type="hidden" name="data_source_id" value="{{ data_source.id }}" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="data_source_id"
|
||||
value="{{ data_source.id }}"
|
||||
/>
|
||||
{% endif %}
|
||||
<button class="btn btn-outline-primary" type="submit">
|
||||
<i class="fas fa-search"></i> Search
|
||||
@ -41,8 +49,8 @@
|
||||
</div>
|
||||
<div class="mt-2 text-muted">
|
||||
<small
|
||||
>Search by session ID, country, language, sentiment, category, or message
|
||||
content.</small
|
||||
>Search by session ID, country, language, sentiment, category, or
|
||||
message content.</small
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -16,6 +16,7 @@ services:
|
||||
- DEBUG=0
|
||||
- SECRET_KEY=your_secret_key_here
|
||||
- ALLOWED_HOSTS=localhost,127.0.0.1
|
||||
- DJANGO_SETTINGS_MODULE=dashboard_project.settings
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
@ -27,6 +28,8 @@ services:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
- POSTGRES_DB=dashboard_db
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
|
||||
39
package-lock.json
generated
39
package-lock.json
generated
@ -1,39 +0,0 @@
|
||||
{
|
||||
"name": "LiveGraphsDjango",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-jinja-template": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-jinja-template": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-jinja-template/-/prettier-plugin-jinja-template-2.1.0.tgz",
|
||||
"integrity": "sha512-mzoCp2Oy9BDSug80fw3B3J4n4KQj1hRvoQOL1akqcDKBb5nvYxrik9zUEDs4AEJ6nK7QDTGoH0y9rx7AlnQ78Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"prettier": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
package.json
11
package.json
@ -1,4 +1,15 @@
|
||||
{
|
||||
"name": "livegraphsdjango",
|
||||
"version": "0.1.0",
|
||||
"description": "Live Graphs Django Dashboard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "eslint dashboard_project/static/js/",
|
||||
"format": "prettier --write \"dashboard_project/static/**/*.{js,css,html}\"",
|
||||
"format:check": "prettier --check \"dashboard_project/static/**/*.{js,css,html}\"",
|
||||
"stylelint": "stylelint \"dashboard_project/static/css/**/*.css\" --fix",
|
||||
"stylelint:check": "stylelint \"dashboard_project/static/css/**/*.css\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-jinja-template": "^2.1.0"
|
||||
|
||||
101
pyproject.toml
101
pyproject.toml
@ -1,9 +1,21 @@
|
||||
[project]
|
||||
name = "livegraphsdjango"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
description = "Live Graphs Django Dashboard"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
authors = [{ name = "LiveGraphs Team" }]
|
||||
license = { text = "MIT" }
|
||||
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Framework :: Django",
|
||||
"Framework :: Django :: 5.2",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
"crispy-bootstrap5>=2025.4",
|
||||
"django>=5.2.1",
|
||||
@ -17,16 +29,29 @@ dependencies = [
|
||||
"whitenoise>=6.9.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
# Django management commands
|
||||
"manage" = "dashboard_project.manage:main"
|
||||
"runserver" = "dashboard_project.manage:main"
|
||||
"migrate" = "dashboard_project.manage:main"
|
||||
"makemigrations" = "dashboard_project.manage:main"
|
||||
"collectstatic" = "dashboard_project.manage:main"
|
||||
"createsuperuser" = "dashboard_project.manage:main"
|
||||
"shell" = "dashboard_project.manage:main"
|
||||
"test" = "dashboard_project.manage:main"
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"bandit>=1.8.3",
|
||||
"black>=25.1.0",
|
||||
"coverage>=7.8.0",
|
||||
"django-debug-toolbar>=5.2.0",
|
||||
"django-stubs>=5.2.0",
|
||||
"mypy>=1.15.0",
|
||||
"pre-commit>=4.2.0",
|
||||
"pytest>=8.3.5",
|
||||
"pytest-django>=4.11.1",
|
||||
"ruff>=0.11.10",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=69.0.0", "wheel>=0.42.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["dashboard_project"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
"dashboard_project" = ["static/**/*", "templates/**/*", "media/**/*"]
|
||||
|
||||
[tool.ruff]
|
||||
# Exclude a variety of commonly ignored directories.
|
||||
@ -67,7 +92,7 @@ indent-width = 4
|
||||
target-version = "py313"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F", "I"]
|
||||
select = ["E", "F", "I", "B", "C4", "ARG", "SIM", "PERF"]
|
||||
ignore = ["E501"]
|
||||
fixable = ["ALL"]
|
||||
unfixable = []
|
||||
@ -76,3 +101,55 @@ unfixable = []
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
line-ending = "lf"
|
||||
|
||||
[tool.bandit]
|
||||
exclude_dirs = ["tests", "venv", ".venv", ".git", "__pycache__", "migrations", "**/create_sample_data.py"]
|
||||
skips = ["B101"]
|
||||
targets = ["dashboard_project"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.13"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
disallow_untyped_defs = false
|
||||
disallow_incomplete_defs = false
|
||||
plugins = ["mypy_django_plugin.main"]
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = ["django.*", "rest_framework.*"]
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.django-stubs]
|
||||
django_settings_module = "dashboard_project.settings"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
DJANGO_SETTINGS_MODULE = "dashboard_project.settings"
|
||||
python_files = "test_*.py"
|
||||
testpaths = ["dashboard_project"]
|
||||
filterwarnings = [
|
||||
"ignore::DeprecationWarning",
|
||||
"ignore::PendingDeprecationWarning",
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
source = ["dashboard_project"]
|
||||
omit = [
|
||||
"dashboard_project/manage.py",
|
||||
"dashboard_project/*/migrations/*",
|
||||
"dashboard_project/*/tests/*",
|
||||
]
|
||||
|
||||
[tool.coverage.report]
|
||||
exclude_lines = [
|
||||
"pragma: no cover",
|
||||
"def __repr__",
|
||||
"raise NotImplementedError",
|
||||
"if __name__ == .__main__.:",
|
||||
"pass",
|
||||
"raise ImportError",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
"Documentation" = "https://github.com/kjanat/livegraphsdjango#readme"
|
||||
"Source" = "https://github.com/kjanat/livegraphsdjango"
|
||||
"Bug Tracker" = "https://github.com/kjanat/livegraphsdjango/issues"
|
||||
|
||||
320
requirements.txt
Normal file
320
requirements.txt
Normal file
@ -0,0 +1,320 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --frozen --output-file=requirements.txt
|
||||
-e .
|
||||
asgiref==3.8.1 \
|
||||
--hash=sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47 \
|
||||
--hash=sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590
|
||||
# via
|
||||
# django
|
||||
# django-allauth
|
||||
# django-stubs
|
||||
bandit==1.8.3 \
|
||||
--hash=sha256:28f04dc0d258e1dd0f99dee8eefa13d1cb5e3fde1a5ab0c523971f97b289bcd8 \
|
||||
--hash=sha256:f5847beb654d309422985c36644649924e0ea4425c76dec2e89110b87506193a
|
||||
black==25.1.0 \
|
||||
--hash=sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171 \
|
||||
--hash=sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666 \
|
||||
--hash=sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f \
|
||||
--hash=sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717 \
|
||||
--hash=sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18 \
|
||||
--hash=sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3
|
||||
cfgv==3.4.0 \
|
||||
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
|
||||
--hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
|
||||
# via pre-commit
|
||||
click==8.2.0 \
|
||||
--hash=sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c \
|
||||
--hash=sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d
|
||||
# via black
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via
|
||||
# bandit
|
||||
# click
|
||||
# pytest
|
||||
coverage==7.8.0 \
|
||||
--hash=sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3 \
|
||||
--hash=sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25 \
|
||||
--hash=sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257 \
|
||||
--hash=sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada \
|
||||
--hash=sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64 \
|
||||
--hash=sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067 \
|
||||
--hash=sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733 \
|
||||
--hash=sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008 \
|
||||
--hash=sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd \
|
||||
--hash=sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00 \
|
||||
--hash=sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501 \
|
||||
--hash=sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42 \
|
||||
--hash=sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487 \
|
||||
--hash=sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4 \
|
||||
--hash=sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73 \
|
||||
--hash=sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a \
|
||||
--hash=sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1 \
|
||||
--hash=sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7 \
|
||||
--hash=sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d \
|
||||
--hash=sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502 \
|
||||
--hash=sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323 \
|
||||
--hash=sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883
|
||||
crispy-bootstrap5==2025.4 \
|
||||
--hash=sha256:51efa19c7d40e339774a6fe23407e83b95b7634cad6de70fd1f1093131bea1d9 \
|
||||
--hash=sha256:d675ea7e245048905077dfe16bf1fa1ee16842f52fe88164ccc8a5e2d11119b3
|
||||
# via livegraphsdjango
|
||||
distlib==0.3.9 \
|
||||
--hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \
|
||||
--hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403
|
||||
# via virtualenv
|
||||
django==5.2.1 \
|
||||
--hash=sha256:57fe1f1b59462caed092c80b3dd324fd92161b620d59a9ba9181c34746c97284 \
|
||||
--hash=sha256:a9b680e84f9a0e71da83e399f1e922e1ab37b2173ced046b541c72e1589a5961
|
||||
# via
|
||||
# crispy-bootstrap5
|
||||
# django-allauth
|
||||
# django-crispy-forms
|
||||
# django-debug-toolbar
|
||||
# django-stubs
|
||||
# django-stubs-ext
|
||||
# livegraphsdjango
|
||||
django-allauth==65.8.0 \
|
||||
--hash=sha256:9da589d99d412740629333a01865a90c95c97e0fae0cde789aa45a8fda90e83b
|
||||
# via livegraphsdjango
|
||||
django-crispy-forms==2.4 \
|
||||
--hash=sha256:5a4b99876cfb1bdd3e47727731b6d4197c51c0da502befbfbec6a93010b02030 \
|
||||
--hash=sha256:915e1ffdeb2987d78b33fabfeff8e5203c8776aa910a3a659a2c514ca125f3bd
|
||||
# via
|
||||
# crispy-bootstrap5
|
||||
# livegraphsdjango
|
||||
django-debug-toolbar==5.2.0 \
|
||||
--hash=sha256:15627f4c2836a9099d795e271e38e8cf5204ccd79d5dbcd748f8a6c284dcd195 \
|
||||
--hash=sha256:9e7f0145e1a1b7d78fcc3b53798686170a5b472d9cf085d88121ff823e900821
|
||||
django-stubs==5.2.0 \
|
||||
--hash=sha256:07e25c2d3cbff5be540227ff37719cc89f215dfaaaa5eb038a75b01bbfbb2722 \
|
||||
--hash=sha256:cd52da033489afc1357d6245f49e3cc57bf49015877253fb8efc6722ea3d2d2b
|
||||
django-stubs-ext==5.2.0 \
|
||||
--hash=sha256:00c4ae307b538f5643af761a914c3f8e4e3f25f4e7c6d7098f1906c0d8f2aac9 \
|
||||
--hash=sha256:b27ae0aab970af4894ba4e9b3fcd3e03421dc8731516669659ee56122d148b23
|
||||
# via django-stubs
|
||||
filelock==3.18.0 \
|
||||
--hash=sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2 \
|
||||
--hash=sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de
|
||||
# via virtualenv
|
||||
gunicorn==23.0.0 \
|
||||
--hash=sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d \
|
||||
--hash=sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec
|
||||
# via livegraphsdjango
|
||||
identify==2.6.10 \
|
||||
--hash=sha256:45e92fd704f3da71cc3880036633f48b4b7265fd4de2b57627cb157216eb7eb8 \
|
||||
--hash=sha256:5f34248f54136beed1a7ba6a6b5c4b6cf21ff495aac7c359e1ef831ae3b8ab25
|
||||
# via pre-commit
|
||||
iniconfig==2.1.0 \
|
||||
--hash=sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7 \
|
||||
--hash=sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760
|
||||
# via pytest
|
||||
markdown-it-py==3.0.0 \
|
||||
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
|
||||
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
|
||||
# via rich
|
||||
mdurl==0.1.2 \
|
||||
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
|
||||
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
|
||||
# via markdown-it-py
|
||||
mypy==1.15.0 \
|
||||
--hash=sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43 \
|
||||
--hash=sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e \
|
||||
--hash=sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d \
|
||||
--hash=sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445 \
|
||||
--hash=sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5 \
|
||||
--hash=sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf \
|
||||
--hash=sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357 \
|
||||
--hash=sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036
|
||||
mypy-extensions==1.1.0 \
|
||||
--hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \
|
||||
--hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558
|
||||
# via
|
||||
# black
|
||||
# mypy
|
||||
narwhals==1.39.1 \
|
||||
--hash=sha256:68d0f29c760f1a9419ada537f35f21ff202b0be1419e6d22135a0352c6d96deb \
|
||||
--hash=sha256:cf15389e6f8c5321e8cd0ca8b5bace3b1aea5f5622fa59dfd64821998741d836
|
||||
# via plotly
|
||||
nodeenv==1.9.1 \
|
||||
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
|
||||
--hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9
|
||||
# via pre-commit
|
||||
numpy==2.2.5 \
|
||||
--hash=sha256:02f226baeefa68f7d579e213d0f3493496397d8f1cff5e2b222af274c86a552a \
|
||||
--hash=sha256:059b51b658f4414fff78c6d7b1b4e18283ab5fa56d270ff212d5ba0c561846f4 \
|
||||
--hash=sha256:1a161c2c79ab30fe4501d5a2bbfe8b162490757cf90b7f05be8b80bc02f7bb8e \
|
||||
--hash=sha256:261a1ef047751bb02f29dfe337230b5882b54521ca121fc7f62668133cb119c9 \
|
||||
--hash=sha256:2ba321813a00e508d5421104464510cc962a6f791aa2fca1c97b1e65027da80d \
|
||||
--hash=sha256:352d330048c055ea6db701130abc48a21bec690a8d38f8284e00fab256dc1376 \
|
||||
--hash=sha256:3d14b17b9be5f9c9301f43d2e2a4886a33b53f4e6fdf9ca2f4cc60aeeee76372 \
|
||||
--hash=sha256:4520caa3807c1ceb005d125a75e715567806fed67e315cea619d5ec6e75a4191 \
|
||||
--hash=sha256:47f9ed103af0bc63182609044b0490747e03bd20a67e391192dde119bf43d52f \
|
||||
--hash=sha256:54088a5a147ab71a8e7fdfd8c3601972751ded0739c6b696ad9cb0343e21ab73 \
|
||||
--hash=sha256:55f09e00d4dccd76b179c0f18a44f041e5332fd0e022886ba1c0bbf3ea4a18d0 \
|
||||
--hash=sha256:8b4c0773b6ada798f51f0f8e30c054d32304ccc6e9c5d93d46cb26f3d385ab19 \
|
||||
--hash=sha256:8dfa94b6a4374e7851bbb6f35e6ded2120b752b063e6acdd3157e4d2bb922eba \
|
||||
--hash=sha256:97c8425d4e26437e65e1d189d22dff4a079b747ff9c2788057bfb8114ce1e133 \
|
||||
--hash=sha256:a4cbdef3ddf777423060c6f81b5694bad2dc9675f110c4b2a60dc0181543fac7 \
|
||||
--hash=sha256:a9c0d994680cd991b1cb772e8b297340085466a6fe964bc9d4e80f5e2f43c291 \
|
||||
--hash=sha256:c26843fd58f65da9491165072da2cccc372530681de481ef670dcc8e27cfb066 \
|
||||
--hash=sha256:c8b82a55ef86a2d8e81b63da85e55f5537d2157165be1cb2ce7cfa57b6aef38b \
|
||||
--hash=sha256:d403c84991b5ad291d3809bace5e85f4bbf44a04bdc9a88ed2bb1807b3360bb8 \
|
||||
--hash=sha256:d8882a829fd779f0f43998e931c466802a77ca1ee0fe25a3abe50278616b1471 \
|
||||
--hash=sha256:e8b025c351b9f0e8b5436cf28a07fa4ac0204d67b38f01433ac7f9b870fa38c6
|
||||
# via
|
||||
# livegraphsdjango
|
||||
# pandas
|
||||
packaging==25.0 \
|
||||
--hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \
|
||||
--hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f
|
||||
# via
|
||||
# black
|
||||
# gunicorn
|
||||
# plotly
|
||||
# pytest
|
||||
pandas==2.2.3 \
|
||||
--hash=sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d \
|
||||
--hash=sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4 \
|
||||
--hash=sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0 \
|
||||
--hash=sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28 \
|
||||
--hash=sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18 \
|
||||
--hash=sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468 \
|
||||
--hash=sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667 \
|
||||
--hash=sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d \
|
||||
--hash=sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb \
|
||||
--hash=sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659 \
|
||||
--hash=sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a \
|
||||
--hash=sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2 \
|
||||
--hash=sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015 \
|
||||
--hash=sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24
|
||||
# via livegraphsdjango
|
||||
pathspec==0.12.1 \
|
||||
--hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \
|
||||
--hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712
|
||||
# via black
|
||||
pbr==6.1.1 \
|
||||
--hash=sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76 \
|
||||
--hash=sha256:93ea72ce6989eb2eed99d0f75721474f69ad88128afdef5ac377eb797c4bf76b
|
||||
# via stevedore
|
||||
platformdirs==4.3.8 \
|
||||
--hash=sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc \
|
||||
--hash=sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4
|
||||
# via
|
||||
# black
|
||||
# virtualenv
|
||||
plotly==6.1.0 \
|
||||
--hash=sha256:a29d3ed523c9d7960095693af1ee52689830df0f9c6bae3e5e92c20c4f5684c3 \
|
||||
--hash=sha256:f13f497ccc2d97f06f771a30b27fab0cbd220f2975865f4ecbc75057135521de
|
||||
# via livegraphsdjango
|
||||
pluggy==1.6.0 \
|
||||
--hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \
|
||||
--hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746
|
||||
# via pytest
|
||||
pre-commit==4.2.0 \
|
||||
--hash=sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146 \
|
||||
--hash=sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd
|
||||
pygments==2.19.1 \
|
||||
--hash=sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f \
|
||||
--hash=sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c
|
||||
# via rich
|
||||
pytest==8.3.5 \
|
||||
--hash=sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820 \
|
||||
--hash=sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845
|
||||
# via pytest-django
|
||||
pytest-django==4.11.1 \
|
||||
--hash=sha256:1b63773f648aa3d8541000c26929c1ea63934be1cfa674c76436966d73fe6a10 \
|
||||
--hash=sha256:a949141a1ee103cb0e7a20f1451d355f83f5e4a5d07bdd4dcfdd1fd0ff227991
|
||||
python-dateutil==2.9.0.post0 \
|
||||
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
|
||||
--hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427
|
||||
# via pandas
|
||||
python-dotenv==1.1.0 \
|
||||
--hash=sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5 \
|
||||
--hash=sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d
|
||||
# via livegraphsdjango
|
||||
pytz==2025.2 \
|
||||
--hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 \
|
||||
--hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00
|
||||
# via pandas
|
||||
pyyaml==6.0.2 \
|
||||
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
|
||||
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
|
||||
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
|
||||
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
|
||||
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
|
||||
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
|
||||
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
|
||||
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
|
||||
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
|
||||
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba
|
||||
# via
|
||||
# bandit
|
||||
# pre-commit
|
||||
rich==14.0.0 \
|
||||
--hash=sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0 \
|
||||
--hash=sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725
|
||||
# via bandit
|
||||
ruff==0.11.10 \
|
||||
--hash=sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca \
|
||||
--hash=sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f \
|
||||
--hash=sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad \
|
||||
--hash=sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b \
|
||||
--hash=sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125 \
|
||||
--hash=sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641 \
|
||||
--hash=sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224 \
|
||||
--hash=sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947 \
|
||||
--hash=sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4 \
|
||||
--hash=sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58 \
|
||||
--hash=sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5 \
|
||||
--hash=sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed \
|
||||
--hash=sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6 \
|
||||
--hash=sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2 \
|
||||
--hash=sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19 \
|
||||
--hash=sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523 \
|
||||
--hash=sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1 \
|
||||
--hash=sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2
|
||||
setuptools==80.7.1 \
|
||||
--hash=sha256:ca5cc1069b85dc23070a6628e6bcecb3292acac802399c7f8edc0100619f9009 \
|
||||
--hash=sha256:f6ffc5f0142b1bd8d0ca94ee91b30c0ca862ffd50826da1ea85258a06fd94552
|
||||
# via pbr
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via python-dateutil
|
||||
sqlparse==0.5.3 \
|
||||
--hash=sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272 \
|
||||
--hash=sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca
|
||||
# via
|
||||
# django
|
||||
# django-debug-toolbar
|
||||
stevedore==5.4.1 \
|
||||
--hash=sha256:3135b5ae50fe12816ef291baff420acb727fcd356106e3e9cbfa9e5985cd6f4b \
|
||||
--hash=sha256:d10a31c7b86cba16c1f6e8d15416955fc797052351a56af15e608ad20811fcfe
|
||||
# via bandit
|
||||
types-pyyaml==6.0.12.20250516 \
|
||||
--hash=sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530 \
|
||||
--hash=sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba
|
||||
# via django-stubs
|
||||
typing-extensions==4.13.2 \
|
||||
--hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \
|
||||
--hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef
|
||||
# via
|
||||
# django-stubs
|
||||
# django-stubs-ext
|
||||
# mypy
|
||||
tzdata==2025.2 \
|
||||
--hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 \
|
||||
--hash=sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9
|
||||
# via
|
||||
# django
|
||||
# pandas
|
||||
virtualenv==20.31.2 \
|
||||
--hash=sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11 \
|
||||
--hash=sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af
|
||||
# via pre-commit
|
||||
whitenoise==6.9.0 \
|
||||
--hash=sha256:8c4a7c9d384694990c26f3047e118c691557481d624f069b7f7752a2f735d609 \
|
||||
--hash=sha256:c8a489049b7ee9889617bb4c274a153f3d979e8f51d2efd0f5b403caf41c57df
|
||||
# via livegraphsdjango
|
||||
19
setup.py
19
setup.py
@ -1,19 +0,0 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name="livegraphsdjango",
|
||||
version="0.1.0",
|
||||
packages=["dashboard_project"],
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"manage=dashboard_project.manage:main",
|
||||
"runserver=dashboard_project.__main__:main",
|
||||
"migrate=dashboard_project.__main__:main",
|
||||
"makemigrations=dashboard_project.__main__:main",
|
||||
"collectstatic=dashboard_project.__main__:main",
|
||||
"createsuperuser=dashboard_project.__main__:main",
|
||||
"shell=dashboard_project.__main__:main",
|
||||
"test=dashboard_project.__main__:main",
|
||||
],
|
||||
},
|
||||
)
|
||||
459
uv.lock
generated
459
uv.lock
generated
@ -11,6 +11,100 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bandit"
|
||||
version = "1.8.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "rich" },
|
||||
{ name = "stevedore" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1a/a5/144a45f8e67df9d66c3bc3f7e69a39537db8bff1189ab7cff4e9459215da/bandit-1.8.3.tar.gz", hash = "sha256:f5847beb654d309422985c36644649924e0ea4425c76dec2e89110b87506193a", size = 4232005, upload-time = "2025-02-17T05:24:57.031Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/88/85/db74b9233e0aa27ec96891045c5e920a64dd5cbccd50f8e64e9460f48d35/bandit-1.8.3-py3-none-any.whl", hash = "sha256:28f04dc0d258e1dd0f99dee8eefa13d1cb5e3fde1a5ab0c523971f97b289bcd8", size = 129078, upload-time = "2025-02-17T05:24:54.068Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "25.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "mypy-extensions" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pathspec" },
|
||||
{ name = "platformdirs" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfgv"
|
||||
version = "3.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cd/0f/62ca20172d4f87d93cf89665fbaedcd560ac48b465bd1d92bfc7ea6b0a41/click-8.2.0.tar.gz", hash = "sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d", size = 235857, upload-time = "2025-05-10T22:21:03.111Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/58/1f37bf81e3c689cc74ffa42102fa8915b59085f54a6e4a80bc6265c0f6bf/click-8.2.0-py3-none-any.whl", hash = "sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c", size = 102156, upload-time = "2025-05-10T22:21:01.352Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.8.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872, upload-time = "2025-03-30T20:36:45.376Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708, upload-time = "2025-03-30T20:35:47.417Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981, upload-time = "2025-03-30T20:35:49.002Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495, upload-time = "2025-03-30T20:35:51.073Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538, upload-time = "2025-03-30T20:35:52.941Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561, upload-time = "2025-03-30T20:35:54.658Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633, upload-time = "2025-03-30T20:35:56.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712, upload-time = "2025-03-30T20:35:57.801Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000, upload-time = "2025-03-30T20:35:59.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195, upload-time = "2025-03-30T20:36:01.005Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998, upload-time = "2025-03-30T20:36:03.006Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541, upload-time = "2025-03-30T20:36:04.638Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767, upload-time = "2025-03-30T20:36:06.503Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997, upload-time = "2025-03-30T20:36:08.137Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708, upload-time = "2025-03-30T20:36:09.781Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046, upload-time = "2025-03-30T20:36:11.409Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139, upload-time = "2025-03-30T20:36:13.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307, upload-time = "2025-03-30T20:36:16.074Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116, upload-time = "2025-03-30T20:36:18.033Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909, upload-time = "2025-03-30T20:36:19.644Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068, upload-time = "2025-03-30T20:36:21.282Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435, upload-time = "2025-03-30T20:36:43.61Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crispy-bootstrap5"
|
||||
version = "2025.4"
|
||||
@ -24,6 +118,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/9a/4f1166cc82c9f777cf9a5bc2a75171d63301ac317c5de8f59bd44bfe2b7a/crispy_bootstrap5-2025.4-py3-none-any.whl", hash = "sha256:51efa19c7d40e339774a6fe23407e83b95b7634cad6de70fd1f1093131bea1d9", size = 24772, upload-time = "2025-04-02T12:33:14.904Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "distlib"
|
||||
version = "0.3.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.2.1"
|
||||
@ -60,6 +163,57 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/ec/a25f81e56a674e63cf6c3dd8e36b1b3fecc238fecd6098504adc0cc61402/django_crispy_forms-2.4-py3-none-any.whl", hash = "sha256:5a4b99876cfb1bdd3e47727731b6d4197c51c0da502befbfbec6a93010b02030", size = 31446, upload-time = "2025-04-13T07:24:58.516Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-debug-toolbar"
|
||||
version = "5.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "sqlparse" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2a/9f/97ba2648f66fa208fc7f19d6895586d08bc5f0ab930a1f41032e60f31a41/django_debug_toolbar-5.2.0.tar.gz", hash = "sha256:9e7f0145e1a1b7d78fcc3b53798686170a5b472d9cf085d88121ff823e900821", size = 297901, upload-time = "2025-04-29T05:23:57.533Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/c2/ed3cb815002664349e9e50799b8c00ef15941f4cad797247cadbdeebab02/django_debug_toolbar-5.2.0-py3-none-any.whl", hash = "sha256:15627f4c2836a9099d795e271e38e8cf5204ccd79d5dbcd748f8a6c284dcd195", size = 262834, upload-time = "2025-04-29T05:23:55.472Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-stubs"
|
||||
version = "5.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "asgiref" },
|
||||
{ name = "django" },
|
||||
{ name = "django-stubs-ext" },
|
||||
{ name = "types-pyyaml" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/87/79/7e7ad8b4bac545c8e608fa8db0bd061977f93035a112be78a7f3ffc6ff66/django_stubs-5.2.0.tar.gz", hash = "sha256:07e25c2d3cbff5be540227ff37719cc89f215dfaaaa5eb038a75b01bbfbb2722", size = 276297, upload-time = "2025-04-26T10:49:04.974Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/01/5913ba5514337f3896c7bcbff6075808184dd303cd0fc3ecc289ec7e0c96/django_stubs-5.2.0-py3-none-any.whl", hash = "sha256:cd52da033489afc1357d6245f49e3cc57bf49015877253fb8efc6722ea3d2d2b", size = 481836, upload-time = "2025-04-26T10:49:02.97Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "django-stubs-ext"
|
||||
version = "5.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "django" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7c/7a/84338605817960942c1ea9d852685923ccccd0d91ba0d49532605973491f/django_stubs_ext-5.2.0.tar.gz", hash = "sha256:00c4ae307b538f5643af761a914c3f8e4e3f25f4e7c6d7098f1906c0d8f2aac9", size = 9618, upload-time = "2025-04-26T10:48:38.05Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/65/9f5ca467d84a67c0c547f10b0ece9fd9c26c5efc818a01bf6a3d306c2a0c/django_stubs_ext-5.2.0-py3-none-any.whl", hash = "sha256:b27ae0aab970af4894ba4e9b3fcd3e03421dc8731516669659ee56122d148b23", size = 9066, upload-time = "2025-04-26T10:48:36.032Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.18.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "23.0.0"
|
||||
@ -72,10 +226,28 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029, upload-time = "2024-08-10T20:25:24.996Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.6.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0c/83/b6ea0334e2e7327084a46aaaf71f2146fc061a192d6518c0d020120cd0aa/identify-2.6.10.tar.gz", hash = "sha256:45e92fd704f3da71cc3880036633f48b4b7265fd4de2b57627cb157216eb7eb8", size = 99201, upload-time = "2025-04-19T15:10:38.32Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/d3/85feeba1d097b81a44bcffa6a0beab7b4dfffe78e82fc54978d3ac380736/identify-2.6.10-py2.py3-none-any.whl", hash = "sha256:5f34248f54136beed1a7ba6a6b5c4b6cf21ff495aac7c359e1ef831ae3b8ab25", size = 99101, upload-time = "2025-04-19T15:10:36.701Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "livegraphsdjango"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "crispy-bootstrap5" },
|
||||
{ name = "django" },
|
||||
@ -89,6 +261,20 @@ dependencies = [
|
||||
{ name = "whitenoise" },
|
||||
]
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "bandit" },
|
||||
{ name = "black" },
|
||||
{ name = "coverage" },
|
||||
{ name = "django-debug-toolbar" },
|
||||
{ name = "django-stubs" },
|
||||
{ name = "mypy" },
|
||||
{ name = "pre-commit" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-django" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "crispy-bootstrap5", specifier = ">=2025.4" },
|
||||
@ -103,6 +289,69 @@ requires-dist = [
|
||||
{ name = "whitenoise", specifier = ">=6.9.0" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "bandit", specifier = ">=1.8.3" },
|
||||
{ name = "black", specifier = ">=25.1.0" },
|
||||
{ name = "coverage", specifier = ">=7.8.0" },
|
||||
{ name = "django-debug-toolbar", specifier = ">=5.2.0" },
|
||||
{ name = "django-stubs", specifier = ">=5.2.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pre-commit", specifier = ">=4.2.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.5" },
|
||||
{ name = "pytest-django", specifier = ">=4.11.1" },
|
||||
{ name = "ruff", specifier = ">=0.11.10" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markdown-it-py"
|
||||
version = "3.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mdurl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mypy-extensions" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "narwhals"
|
||||
version = "1.39.1"
|
||||
@ -112,6 +361,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/70/c4/b83520ecc27840a4d58bd585ae0ec0f8a4f2b0c5a965b66749254a54de0e/narwhals-1.39.1-py3-none-any.whl", hash = "sha256:68d0f29c760f1a9419ada537f35f21ff202b0be1419e6d22135a0352c6d96deb", size = 355009, upload-time = "2025-05-15T17:45:07.954Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.9.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.2.5"
|
||||
@ -176,6 +434,36 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/5f/b38085618b950b79d2d9164a711c52b10aefc0ae6833b96f626b7021b2ed/pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a", size = 13098436, upload-time = "2024-09-20T13:09:48.112Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pbr"
|
||||
version = "6.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/d2/510cc0d218e753ba62a1bc1434651db3cd797a9716a0a66cc714cb4f0935/pbr-6.1.1.tar.gz", hash = "sha256:93ea72ce6989eb2eed99d0f75721474f69ad88128afdef5ac377eb797c4bf76b", size = 125702, upload-time = "2025-02-04T14:28:06.514Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/47/ac/684d71315abc7b1214d59304e23a982472967f6bf4bde5a98f1503f648dc/pbr-6.1.1-py2.py3-none-any.whl", hash = "sha256:38d4daea5d9fa63b3f626131b9d34947fd0c8be9b05a29276870580050a25a76", size = 108997, upload-time = "2025-02-04T14:28:03.168Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.3.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotly"
|
||||
version = "6.1.0"
|
||||
@ -189,6 +477,67 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/11/83ae52318353f9da4a88cc23e7f9dbc3d449b3f0fd6158fba15eb3c3b816/plotly-6.1.0-py3-none-any.whl", hash = "sha256:a29d3ed523c9d7960095693af1ee52689830df0f9c6bae3e5e92c20c4f5684c3", size = 16118476, upload-time = "2025-05-15T16:04:30.81Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pre-commit"
|
||||
version = "4.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cfgv" },
|
||||
{ name = "identify" },
|
||||
{ name = "nodeenv" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "virtualenv" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.19.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "iniconfig" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-django"
|
||||
version = "4.11.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/fb/55d580352db26eb3d59ad50c64321ddfe228d3d8ac107db05387a2fadf3a/pytest_django-4.11.1.tar.gz", hash = "sha256:a949141a1ee103cb0e7a20f1451d355f83f5e4a5d07bdd4dcfdd1fd0ff227991", size = 86202, upload-time = "2025-04-03T18:56:09.338Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/be/ac/bd0608d229ec808e51a21044f3f2f27b9a37e7a0ebaca7247882e67876af/pytest_django-4.11.1-py3-none-any.whl", hash = "sha256:1b63773f648aa3d8541000c26929c1ea63934be1cfa674c76436966d73fe6a10", size = 25281, upload-time = "2025-04-03T18:56:07.678Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
@ -219,6 +568,70 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rich"
|
||||
version = "14.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markdown-it-py" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.11.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "80.7.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/8b/dc1773e8e5d07fd27c1632c45c1de856ac3dbf09c0147f782ca6d990cf15/setuptools-80.7.1.tar.gz", hash = "sha256:f6ffc5f0142b1bd8d0ca94ee91b30c0ca862ffd50826da1ea85258a06fd94552", size = 1319188, upload-time = "2025-05-15T02:41:00.955Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/18/0e835c3a557dc5faffc8f91092f62fc337c1dab1066715842e7a4b318ec4/setuptools-80.7.1-py3-none-any.whl", hash = "sha256:ca5cc1069b85dc23070a6628e6bcecb3292acac802399c7f8edc0100619f9009", size = 1200776, upload-time = "2025-05-15T02:40:58.887Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
@ -237,6 +650,36 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stevedore"
|
||||
version = "5.4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pbr" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/28/3f/13cacea96900bbd31bb05c6b74135f85d15564fc583802be56976c940470/stevedore-5.4.1.tar.gz", hash = "sha256:3135b5ae50fe12816ef291baff420acb727fcd356106e3e9cbfa9e5985cd6f4b", size = 513858, upload-time = "2025-02-20T14:03:57.285Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/45/8c4ebc0c460e6ec38e62ab245ad3c7fc10b210116cea7c16d61602aa9558/stevedore-5.4.1-py3-none-any.whl", hash = "sha256:d10a31c7b86cba16c1f6e8d15416955fc797052351a56af15e608ad20811fcfe", size = 49533, upload-time = "2025-02-20T14:03:55.849Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-pyyaml"
|
||||
version = "6.0.12.20250516"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4e/22/59e2aeb48ceeee1f7cd4537db9568df80d62bdb44a7f9e743502ea8aab9c/types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba", size = 17378, upload-time = "2025-05-16T03:08:04.897Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/99/5f/e0af6f7f6a260d9af67e1db4f54d732abad514252a7a378a6c4d17dd1036/types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530", size = 20312, upload-time = "2025-05-16T03:08:04.019Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.13.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2025.2"
|
||||
@ -246,6 +689,20 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "20.31.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "distlib" },
|
||||
{ name = "filelock" },
|
||||
{ name = "platformdirs" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whitenoise"
|
||||
version = "6.9.0"
|
||||
|
||||
Reference in New Issue
Block a user