You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -762,6 +766,171 @@ It works with any OAuth provider supported by FastHTML, including:
762
766
763
767
For a complete example, see `example_oauth.py`.
764
768
769
+
## Maintenance Mode
770
+
771
+
The library includes a persistent maintenance mode feature that allows administrators to temporarily restrict access to the system for all non-admin users. When maintenance mode is enabled, non-admin users (including anonymous users) are redirected to a maintenance page.
772
+
773
+
```python
774
+
from fasthtml.common import*
775
+
from fasthtml_admin import UserManager, AdminManager, auth_before
776
+
777
+
# Initialize UserManager and AdminManager
778
+
db = database("data/myapp.db")
779
+
user_manager = UserManager(db)
780
+
admin_manager = AdminManager(user_manager)
781
+
782
+
# Set up authentication with maintenance mode support
783
+
defapp_auth_before(req, sess):
784
+
return auth_before(req, sess, user_manager,
785
+
login_url='/login',
786
+
public_paths=['/', '/register'],
787
+
admin_manager=admin_manager,
788
+
maintenance_url='/maintenance')
789
+
790
+
# Create a FastHTML app with authentication
791
+
beforeware = Beforeware(app_auth_before)
792
+
app, rt = fast_app(
793
+
secret_key="your-secret-key-here",
794
+
before=beforeware,
795
+
session_cookie="session"
796
+
)
797
+
798
+
# Add a maintenance page
799
+
@app.get("/maintenance")
800
+
defmaintenance_page():
801
+
return Container(
802
+
H1("System Maintenance"),
803
+
P("The system is currently undergoing maintenance."),
804
+
P("Please check back later."),
805
+
P("If you are an administrator, please log in to access the system."),
806
+
A("Login", href="/login", cls="button")
807
+
)
808
+
809
+
# Add controls for admins to toggle maintenance mode
1. Setting up the AdminManager with maintenance mode support
829
+
2. Configuring the auth_before function to check for maintenance mode
830
+
3. Adding a maintenance page that users will be redirected to
831
+
4. Adding controls for admins to toggle maintenance mode on/off
832
+
833
+
When maintenance mode is enabled:
834
+
- Admin users can still access all parts of the system
835
+
- Non-admin users (including anonymous users) are redirected to the maintenance page when they try to access any part of the system
836
+
- The login page remains accessible so admins can log in
837
+
- The maintenance page is always accessible
838
+
839
+
### Persistent Maintenance Mode
840
+
841
+
The maintenance mode state is stored in the database, making it persistent across application restarts. This means that if you enable maintenance mode and restart your application, it will remain in maintenance mode.
print(f"Maintenance mode is {'enabled'if is_maintenance else'disabled'}")
850
+
851
+
# Enable maintenance mode
852
+
admin_manager.set_maintenance_mode(True)
853
+
854
+
# Disable maintenance mode
855
+
admin_manager.set_maintenance_mode(False)
856
+
```
857
+
858
+
The maintenance mode state is stored in a system_settings table in the database, which is automatically created when you initialize the AdminManager. This ensures that the maintenance mode state is preserved even if the application is restarted.
859
+
860
+
## Database Upload Example
861
+
862
+
Here's an example of how to implement a database upload feature in your FastHTML application:
863
+
864
+
```python
865
+
from fasthtml.common import limiter, RedirectResponse, Container, H1, P, A, Form, Input, Button, Titled
866
+
867
+
@app.get("/admin/upload-db")
868
+
defget_upload_db(session):
869
+
user = get_current_user(session, user_manager)
870
+
# Check if user is admin
871
+
is_admin = user.is_admin if user_manager.is_db else user["is_admin"]
872
+
ifnot is_admin:
873
+
return Container(
874
+
H1("Access Denied"),
875
+
P("You do not have permission to access this page."),
876
+
A("Go to Dashboard", href="/dashboard", cls="button")
877
+
)
878
+
879
+
# Create upload form
880
+
form = Form(
881
+
H1("Upload Database"),
882
+
P("Warning: This will replace the current database with the uploaded file."),
return Titled("Error", P(f"Failed to process upload request: {str(e)}"))
923
+
```
924
+
925
+
This example demonstrates:
926
+
1. A GET route to display the upload form
927
+
2. A POST route to handle the file upload
928
+
3. Rate limiting to prevent abuse
929
+
4. Admin permission checks
930
+
5. File validation (must be a .db file)
931
+
6. Using the AdminManager's upload_database method to handle the upload
932
+
7. Error handling for different types of errors
933
+
765
934
## Customization
766
935
767
936
The library is designed to be flexible and customizable. You can extend the provided classes or implement your own versions of the interfaces to fit your specific needs.
0 commit comments