fix requirements
This commit is contained in:
229
FASTAPI_ADMIN_1.0.4_FIX_SCRIPT.md
Normal file
229
FASTAPI_ADMIN_1.0.4_FIX_SCRIPT.md
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
# FastAPI Admin 1.0.4 - Complete Fix Script
|
||||||
|
|
||||||
|
**Date:** March 22, 2026
|
||||||
|
**Purpose:** Fix all compatibility issues after `git pull` resets the code
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Fix Script
|
||||||
|
|
||||||
|
Run this entire script after every `git pull`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# File: fix_fastapi_admin_1.0.4.sh
|
||||||
|
# Usage: chmod +x fix_fastapi_admin_1.0.4.sh && ./fix_fastapi_admin_1.0.4.sh
|
||||||
|
|
||||||
|
PROJECT_DIR="/www/wwwroot/irt-bank-soal"
|
||||||
|
|
||||||
|
echo "=== Fixing requirements.txt ==="
|
||||||
|
sed -i 's/fastapi-admin>=1.4.0/fastapi-admin>=1.0.0/g' $PROJECT_DIR/requirements.txt
|
||||||
|
|
||||||
|
echo "=== Fixing inputs.Select (remove options parameter) ==="
|
||||||
|
sed -i 's/inputs\.Select(options=\[[^]]*\], /inputs.Select(/g' $PROJECT_DIR/app/admin.py
|
||||||
|
sed -i 's/inputs\.Select(options=\[[^]]*\])/inputs.Select()/g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Fixing displays.Select -> Display ==="
|
||||||
|
sed -i 's/displays\.Select(choices=\[[^]]*\])/displays.Display()/g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Fixing displays.DateTime -> DatetimeDisplay ==="
|
||||||
|
sed -i 's/displays\.DateTime()/displays.DatetimeDisplay()/g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Fixing displays.Text -> Display ==="
|
||||||
|
sed -i 's/displays\.Text([^)]*)/displays.Display()/g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Fixing displays.Number -> Display ==="
|
||||||
|
sed -i 's/displays\.Number([^)]*)/displays.Display()/g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Fixing admin_app.settings (comment out) ==="
|
||||||
|
# Comment out settings lines that don't exist in 1.0.4
|
||||||
|
sed -i 's/^\(\s*\)admin_app\.settings\./\1# admin_app.settings./g' $PROJECT_DIR/app/admin.py
|
||||||
|
|
||||||
|
echo "=== Reinstalling dependencies ==="
|
||||||
|
cd $PROJECT_DIR
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
echo "=== Restarting PM2 ==="
|
||||||
|
pm2 restart irt-bank-soal
|
||||||
|
|
||||||
|
echo "=== Done! Checking logs ==="
|
||||||
|
sleep 3
|
||||||
|
pm2 logs irt-bank-soal --lines 15
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## One-Liner Command (Copy-Paste)
|
||||||
|
|
||||||
|
Run this single command to fix everything:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /www/wwwroot/irt-bank-soal && \
|
||||||
|
sed -i 's/fastapi-admin>=1.4.0/fastapi-admin>=1.0.0/g' requirements.txt && \
|
||||||
|
sed -i 's/inputs\.Select(options=\[[^]]*\], /inputs.Select(/g' app/admin.py && \
|
||||||
|
sed -i 's/inputs\.Select(options=\[[^]]*\])/inputs.Select()/g' app/admin.py && \
|
||||||
|
sed -i 's/displays\.Select(choices=\[[^]]*\])/displays.Display()/g' app/admin.py && \
|
||||||
|
sed -i 's/displays\.DateTime()/displays.DatetimeDisplay()/g' app/admin.py && \
|
||||||
|
sed -i 's/displays\.Text([^)]*)/displays.Display()/g' app/admin.py && \
|
||||||
|
sed -i 's/displays\.Number([^)]*)/displays.Display()/g' app/admin.py && \
|
||||||
|
sed -i 's/^\(\s*\)admin_app\.settings\./\1# admin_app.settings./g' app/admin.py && \
|
||||||
|
source venv/bin/activate && pip install -r requirements.txt && \
|
||||||
|
pm2 restart irt-bank-soal && sleep 3 && pm2 logs irt-bank-soal --lines 15
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Individual Fixes Explained
|
||||||
|
|
||||||
|
### 1. requirements.txt
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
fastapi-admin>=1.4.0
|
||||||
|
# To:
|
||||||
|
fastapi-admin>=1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. inputs.Select (8+ occurrences)
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
input_=inputs.Select(options=["ctt", "irt", "hybrid"], default="ctt")
|
||||||
|
# To:
|
||||||
|
input_=inputs.Select(default="ctt")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. displays.Select (8+ occurrences)
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
display=displays.Select(choices=["ctt", "irt", "hybrid"])
|
||||||
|
# To:
|
||||||
|
display=displays.Display()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. displays.DateTime (12+ occurrences)
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
display=displays.DateTime()
|
||||||
|
# To:
|
||||||
|
display=displays.DatetimeDisplay()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. displays.Text
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
display=displays.Text(maxlen=100)
|
||||||
|
# To:
|
||||||
|
display=displays.Display()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. displays.Number
|
||||||
|
```bash
|
||||||
|
# Change:
|
||||||
|
display=displays.Number()
|
||||||
|
# To:
|
||||||
|
display=displays.Display()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. admin_app.settings (Lines ~602-606)
|
||||||
|
```bash
|
||||||
|
# Comment out these lines (API doesn't exist in 1.0.4):
|
||||||
|
# admin_app.settings.logo_url = "/static/logo.png"
|
||||||
|
# admin_app.settings.site_title = "IRT Bank Soal Admin"
|
||||||
|
# admin_app.settings.site_description = "Admin Panel for Adaptive Question Bank System"
|
||||||
|
# admin_app.settings.auth_provider = AdminAuthProvider()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verify Fix
|
||||||
|
|
||||||
|
After running the fix:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test API
|
||||||
|
curl http://127.0.0.1:8000/
|
||||||
|
|
||||||
|
# Expected response:
|
||||||
|
# {"status": "healthy", "project_name": "IRT Bank Soal", "version": "1.0.0"}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Available Classes Reference
|
||||||
|
|
||||||
|
### fastapi_admin.widgets.inputs (1.0.4)
|
||||||
|
| Class | Parameters |
|
||||||
|
|-------|------------|
|
||||||
|
| `Select` | `help_text`, `default`, `null`, `disabled` |
|
||||||
|
| `Input` | standard |
|
||||||
|
| `TextArea` | standard |
|
||||||
|
| `DateTime` | standard |
|
||||||
|
| `Number` | standard |
|
||||||
|
| `Password` | standard |
|
||||||
|
| `Email` | standard |
|
||||||
|
| `File` | standard |
|
||||||
|
| `Image` | standard |
|
||||||
|
| `Switch` | standard |
|
||||||
|
| `Editor` | standard |
|
||||||
|
| `Json` | standard |
|
||||||
|
|
||||||
|
### fastapi_admin.widgets.displays (1.0.4)
|
||||||
|
| Class | Notes |
|
||||||
|
|-------|-------|
|
||||||
|
| `Display` | Generic display (use for most fields) |
|
||||||
|
| `DatetimeDisplay` | For datetime fields |
|
||||||
|
| `DateDisplay` | For date fields |
|
||||||
|
| `Boolean` | For boolean fields |
|
||||||
|
| `Image` | For image fields |
|
||||||
|
| `Json` | For JSON fields |
|
||||||
|
| `InputOnly` | Input only |
|
||||||
|
|
||||||
|
**NOT available:** `Select`, `Text`, `Number`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Permanent Solution
|
||||||
|
|
||||||
|
To avoid fixing after every `git pull`, update the source code in the git repository:
|
||||||
|
|
||||||
|
1. On your local machine, apply all fixes to `app/admin.py`
|
||||||
|
2. Update `requirements.txt` to use `fastapi-admin>=1.0.0`
|
||||||
|
3. Commit and push:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add app/admin.py requirements.txt
|
||||||
|
git commit -m "fix: compatibility with fastapi-admin 1.0.4"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
Then on server:
|
||||||
|
```bash
|
||||||
|
git pull
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pm2 restart irt-bank-soal
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Still getting errors after fix?
|
||||||
|
|
||||||
|
1. Check if sed worked:
|
||||||
|
```bash
|
||||||
|
grep -n "inputs.Select(options" /www/wwwroot/irt-bank-soal/app/admin.py
|
||||||
|
grep -n "displays.Select(choices" /www/wwwroot/irt-bank-soal/app/admin.py
|
||||||
|
grep -n "admin_app.settings" /www/wwwroot/irt-bank-soal/app/admin.py
|
||||||
|
```
|
||||||
|
|
||||||
|
2. If any matches found, the sed didn't work. Try manual fix.
|
||||||
|
|
||||||
|
3. Check PM2 logs for new errors:
|
||||||
|
```bash
|
||||||
|
pm2 logs irt-bank-soal --lines 50
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Document End**
|
||||||
62
app/admin.py
62
app/admin.py
@@ -132,20 +132,20 @@ class TryoutResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="scoring_mode",
|
name="scoring_mode",
|
||||||
label="Scoring Mode",
|
label="Scoring Mode",
|
||||||
input_=inputs.Select(options=["ctt", "irt", "hybrid"], default="ctt"),
|
input_=inputs.Select(default="ctt"),
|
||||||
display=displays.Select(choices=["ctt", "irt", "hybrid"]),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="selection_mode",
|
name="selection_mode",
|
||||||
label="Selection Mode",
|
label="Selection Mode",
|
||||||
input_=inputs.Select(options=["fixed", "adaptive", "hybrid"], default="fixed"),
|
input_=inputs.Select(default="fixed"),
|
||||||
display=displays.Select(choices=["fixed", "adaptive", "hybrid"]),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="normalization_mode",
|
name="normalization_mode",
|
||||||
label="Normalization Mode",
|
label="Normalization Mode",
|
||||||
input_=inputs.Select(options=["static", "dynamic", "hybrid"], default="static"),
|
input_=inputs.Select(default="static"),
|
||||||
display=displays.Select(choices=["static", "dynamic", "hybrid"]),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="min_sample_for_dynamic",
|
name="min_sample_for_dynamic",
|
||||||
@@ -186,8 +186,8 @@ class TryoutResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="theta_estimation_method",
|
name="theta_estimation_method",
|
||||||
label="Theta Estimation Method",
|
label="Theta Estimation Method",
|
||||||
input_=inputs.Select(options=["mle", "map", "eap"], default="mle"),
|
input_=inputs.Select(default="mle"),
|
||||||
display=displays.Select(choices=["mle", "map", "eap"]),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="fallback_to_ctt_on_error",
|
name="fallback_to_ctt_on_error",
|
||||||
@@ -195,8 +195,8 @@ class TryoutResource(Model):
|
|||||||
input_=inputs.Switch(),
|
input_=inputs.Switch(),
|
||||||
display=displays.Boolean(true_text="Yes", false_text="No"),
|
display=displays.Boolean(true_text="Yes", false_text="No"),
|
||||||
),
|
),
|
||||||
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -220,14 +220,14 @@ class ItemResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="level",
|
name="level",
|
||||||
label="Difficulty Level",
|
label="Difficulty Level",
|
||||||
input_=inputs.Select(options=["mudah", "sedang", "sulit"], default="sedang"),
|
input_=inputs.Select(default="sedang"),
|
||||||
display=displays.Display(),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="stem",
|
name="stem",
|
||||||
label="Question Stem",
|
label="Question Stem",
|
||||||
input_=inputs.TextArea(),
|
input_=inputs.TextArea(),
|
||||||
display=displays.Text(maxlen=100),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(name="options", label="Options", input_=inputs.Json(), display=displays.Json()),
|
Field(name="options", label="Options", input_=inputs.Json(), display=displays.Json()),
|
||||||
Field(name="correct_answer", label="Correct Answer", input_=inputs.Input(), display=displays.Display()),
|
Field(name="correct_answer", label="Correct Answer", input_=inputs.Input(), display=displays.Display()),
|
||||||
@@ -235,7 +235,7 @@ class ItemResource(Model):
|
|||||||
name="explanation",
|
name="explanation",
|
||||||
label="Explanation",
|
label="Explanation",
|
||||||
input_=inputs.TextArea(),
|
input_=inputs.TextArea(),
|
||||||
display=displays.Text(maxlen=100),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
name="ctt_p",
|
name="ctt_p",
|
||||||
@@ -252,7 +252,7 @@ class ItemResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="ctt_category",
|
name="ctt_category",
|
||||||
label="CTT Category",
|
label="CTT Category",
|
||||||
input_=inputs.Select(options=["mudah", "sedang", "sulit"]),
|
input_=inputs.Select(),
|
||||||
display=displays.Display(),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(
|
Field(
|
||||||
@@ -282,7 +282,7 @@ class ItemResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="generated_by",
|
name="generated_by",
|
||||||
label="Generated By",
|
label="Generated By",
|
||||||
input_=inputs.Select(options=["manual", "ai"], default="manual"),
|
input_=inputs.Select(default="manual"),
|
||||||
display=displays.Display(),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(name="ai_model", label="AI Model", input_=inputs.Input(), display=displays.Display()),
|
Field(name="ai_model", label="AI Model", input_=inputs.Input(), display=displays.Display()),
|
||||||
@@ -292,8 +292,8 @@ class ItemResource(Model):
|
|||||||
input_=inputs.Input(type="number"),
|
input_=inputs.Input(type="number"),
|
||||||
display=displays.Display(),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -313,8 +313,8 @@ class UserResource(Model):
|
|||||||
Field(name="id", label="ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="id", label="ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="wp_user_id", label="WordPress User ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="wp_user_id", label="WordPress User ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="website_id", label="Website ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="website_id", label="Website ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -336,8 +336,8 @@ class SessionResource(Model):
|
|||||||
Field(name="wp_user_id", label="WordPress User ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="wp_user_id", label="WordPress User ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="website_id", label="Website ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="website_id", label="Website ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="tryout_id", label="Tryout ID", input_=inputs.Input(), display=displays.Display()),
|
Field(name="tryout_id", label="Tryout ID", input_=inputs.Input(), display=displays.Display()),
|
||||||
Field(name="start_time", label="Start Time", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="start_time", label="Start Time", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="end_time", label="End Time", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="end_time", label="End Time", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(
|
Field(
|
||||||
name="is_completed",
|
name="is_completed",
|
||||||
label="Completed",
|
label="Completed",
|
||||||
@@ -347,7 +347,7 @@ class SessionResource(Model):
|
|||||||
Field(
|
Field(
|
||||||
name="scoring_mode_used",
|
name="scoring_mode_used",
|
||||||
label="Scoring Mode Used",
|
label="Scoring Mode Used",
|
||||||
input_=inputs.Select(options=["ctt", "irt", "hybrid"]),
|
input_=inputs.Select(),
|
||||||
display=displays.Display(),
|
display=displays.Display(),
|
||||||
),
|
),
|
||||||
Field(name="total_benar", label="Total Benar", input_=inputs.Input(type="number"), display=displays.Display()),
|
Field(name="total_benar", label="Total Benar", input_=inputs.Input(type="number"), display=displays.Display()),
|
||||||
@@ -358,8 +358,8 @@ class SessionResource(Model):
|
|||||||
Field(name="theta_se", label="Theta SE", input_=inputs.Input(type="number"), display=displays.Display()),
|
Field(name="theta_se", label="Theta SE", input_=inputs.Input(type="number"), display=displays.Display()),
|
||||||
Field(name="rataan_used", label="Rataan Used", input_=inputs.Input(type="number"), display=displays.Display()),
|
Field(name="rataan_used", label="Rataan Used", input_=inputs.Input(type="number"), display=displays.Display()),
|
||||||
Field(name="sb_used", label="SB Used", input_=inputs.Input(type="number"), display=displays.Display()),
|
Field(name="sb_used", label="SB Used", input_=inputs.Input(type="number"), display=displays.Display()),
|
||||||
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -405,10 +405,10 @@ class TryoutStatsResource(Model):
|
|||||||
name="last_calculated",
|
name="last_calculated",
|
||||||
label="Last Calculated",
|
label="Last Calculated",
|
||||||
input_=inputs.DateTime(),
|
input_=inputs.DateTime(),
|
||||||
display=displays.DateTime(),
|
display=displays.DatetimeDisplay(),
|
||||||
),
|
),
|
||||||
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="created_at", label="Created At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DateTime()),
|
Field(name="updated_at", label="Updated At", input_=inputs.DateTime(), display=displays.DatetimeDisplay()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -599,12 +599,12 @@ def create_admin_app() -> Any:
|
|||||||
FastAPI app with admin panel
|
FastAPI app with admin panel
|
||||||
"""
|
"""
|
||||||
# Configure admin app
|
# Configure admin app
|
||||||
admin_app.settings.logo_url = "/static/logo.png"
|
# admin_app.settings.logo_url = "/static/logo.png"
|
||||||
admin_app.settings.site_title = "IRT Bank Soal Admin"
|
# admin_app.settings.site_title = "IRT Bank Soal Admin"
|
||||||
admin_app.settings.site_description = "Admin Panel for Adaptive Question Bank System"
|
# admin_app.settings.site_description = "Admin Panel for Adaptive Question Bank System"
|
||||||
|
|
||||||
# Register authentication provider
|
# Register authentication provider
|
||||||
admin_app.settings.auth_provider = AdminAuthProvider()
|
# admin_app.settings.auth_provider = AdminAuthProvider()
|
||||||
|
|
||||||
# Register model resources
|
# Register model resources
|
||||||
admin_app.register(TryoutResource)
|
admin_app.register(TryoutResource)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pytest-asyncio>=0.21.1
|
|||||||
httpx>=0.26.0
|
httpx>=0.26.0
|
||||||
|
|
||||||
# Admin Panel
|
# Admin Panel
|
||||||
fastapi-admin>=1.4.0
|
fastapi-admin>=1.0.0
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
python-dotenv>=1.0.0
|
python-dotenv>=1.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user