PyRails is a lightweight, opinionated, batteries-included Python web framework built on top of FastAPI and MongoEngine
MIT License
PyRails is a lightweight, opinionated, batteries-included Python web framework built on top of FastAPI and MongoEngine. It is means to provide helpful, lightweight abstractions to enable standard ways of implementing common patters to prevent the SaaSification of the developer stack.
The goal is to enhance not inhibit.
Install PyRails using pip:
pip install pyrails
Create a new PyRails project using the new
command:
pyrails new my_project
cd my_project
This will create a new directory myapp
with the default project structure:
myapp/
├── app/
│ ├── controllers/
│ ├── models/
│ └── __init__.py
├── config/
│ ├── development.py
│ ├── production.py
│ └── __init__.py
├── main.py
├── Dockerfile
└── docker-compose.yml
Start the development server using the run
command:
pyrails run
This will start the development server on http://localhost:8000.
You can also run the service using Docker:
pyrails run --docker
PyRails includes a scaffold generator to quickly create models, controllers, and route definitions for a new resource.
To generate a scaffold for a Post
resource with title
and body
fields:
pyrails generate scaffold Post title:str body:str
This will generate:
app/models/post.py
with a Post
model classapp/controllers/posts_controller.py
with CRUD route handlersapp/controllers/__init__.py
to import the new controllerapp/models/__init__.py
to import the new modelYou can also generate models and controllers individually.
To generate a Comment
model with post_id
, author
, and content
fields:
pyrails generate model Comment post_id:str author:str content:str
To generate a controller for Auth
routes:
pyrails generate controller Auth
You can also pass in the routes to generate as arguments:
pyrails generate controller Auth post:login post:register
When generating models, you can define relationships between models and specify field options.
ref:
prefix followed by the related model name.pyrails generate model Post author:ref:User
This will generate a Post
model with an author
field referencing the User
model.
list:
and ref:
together.pyrails generate model Student courses:list:ref:Course
This will generate a Student
model with a courses
field that is a list of references to Course
models.
_
to the field name to mark it as optional.pyrails generate model User email_:str
This will generate a User
model with an optional email
field.
^
to the field name to specify it as unique.pyrails generate model User username^:str
This will generate a User
model with a unique username
field.
_hashed:
suffix to store the field as a hashed value.pyrails generate model User name:str password_hashed:str
This will generate a User
model with a password
field stored as a hashed value.
_encrypted:
suffix to store the field as an encrypted value.pyrails generate model User name:str email_encrypted:str secret_note_encrypted:str
This will generate a User
model with email
and secret_note
fields stored as encrypted values.
PyRails supports the following field types: str
, int
, float
, bool
, datetime
, date
, dict
, list
.
Lifecycle hooks like before_request
and after_request
can be defined directly in a controller or inherited from a parent controller. Hooks are useful for tasks such as authentication, logging, or cleanup.
admin_controller.py
from pyrails.controllers import Controller, before_request, after_request
from pyrails.exceptions import UnauthorizedError
from pyrails import Request
class AdminController(Controller):
@before_request
async def check_admin(self, request: Request):
is_admin = False # Replace with actual logic
print("Checking admin status... (this will be run before each request)")
if not is_admin:
raise UnauthorizedError(detail="Unauthorized access.")
@after_request
async def cleanup_stuff(self, request: Request):
print("Cleaning up... (this will be run after each request)")
admin_user_controller.py
from app.controllers.admin_controller import AdminController
class AdminUserController(AdminController):
@get('/admin-user/all-users')
async def all_users(self, request):
return {"users": []}
check_admin
and after_request
can be defined directly in a controller or inherited from a parent.AdminUserController
, hooks are inherited from AdminController
and run before and after each request handler.before_request
hook raises an exception (e.g., UnauthorizedError
), the request handler is skipped, but the after_request
hook still runs.PyRails provides commands to manage your MongoDB database.
To start a local MongoDB instance for development:
pyrails db up
To stop the local MongoDB instance:
pyrails db down
You can also specify the environment and run MongoDB in a Docker container:
pyrails db up --env production --docker
Environment-specific configuration files are located in the config
directory:
config/development.py
config/production.py
Here you can set your DATABASE_URL
, API keys, and other settings that vary between environments.
Write tests in the tests
directory. You can run your test suite using:
python -m pytest
pyrails --help
For guides, tutorials, and detailed API references, check out the PyRails documentation site.
PyRails is open-source software licensed under the MIT license.