A simple web framework for Python developers to learn how some fundamental concepts of web frameworks work under the hood.
Project description
Osa Framework
Osa is a lightweight WSGI web application framework built for learning purposes. Inspired by popular Python frameworks like Flask, it provides developers with essential tools to understand how modern web frameworks operate under the hood. Osa is an excellent resource for learning routing, middleware, and request/response handling in web applications.
Table of content :
Story Installation Example of a Simple App Key features Setting Up Your Project Structure Creating Your First App Working with Templates and Static Files Running the App Advanced Usage Template Rendering Static Files Resources
Story
I never had a deep love for Python. In fact, I didn't even enjoy working with it. But during my final year at university, everything changed. My team and I decided to build a project that could make a real impact, something beneficial for our University or for government organization
to help speed up their processes and people's transactions .
We approached one such organization, they agreed. However, they had one condition: the system had to be built using Frappe—a Python-based web framework.
Suddenly, I found myself diving headfirst into a language and framework I didn't particularly like, just to meet the project’s demands. As we started learning Frappe, I constantly bumped into elements I didn’t understand—things that I knew how to use but didn’t know how they worked under the hood. This didn’t sit right with me. I’ve always had a curious mind, and knowing how things work behind the scenes is something I value deeply.
Frustrated by the lack of detailed resources explaining the core workings of Frappe, I turned to Flask, a more widely known Python framework with rich documentation. I dug deeper, practicing with projects and discovering how different components interacted in the background. Medium articles and other sources became my guides as I slowly pieced together the puzzle of how web frameworks operate.
As I learned, I started experimenting by building the main functions of a framework myself. I wasn't content with just using prebuilt tools—I wanted to construct them. Step by step, I wrote functions, broke things, fixed them, and began to understand how everything fit together. It was born from this desire to learn, not out of necessity or love for Python, but out of curiosity. It’s not meant for real-world applications but for exploration—something to help people understand how web frameworks work at a fundamental level, just like I wanted to when I first started.
Installation
-
Create a Virtual Environment:
python3 -m venv venv
-
Activate the Virtual Environment:
- On macOS/Linux:
source venv/bin/activate
- On Windows:
venv\Scripts\activate
- On macOS/Linux:
-
Install Osa:
pip install osa-web-framework
Example of a Simple App
from osa import Osa, request, response
app = Osa()
@app.route("/")
def home():
response.text = "Welcome to Osa Framework!"
@app.route("/hello/<name>",methods=["GET"])
def greet_user(name):
response.text = f"Hello, {name}!"
if __name__ == "__main__":
app.run()
Key features
- Command-Line Interface (CLI): Manage the server easily with Osa’s CLI.
- WSGI Compatibility: Compatible with WSGI servers like Gunicorn and uWSGI.
- Routing System: Supports path parameters, method-based and class-based routing.
- Middleware Support: Easily handle tasks before and after requests.
- Static File Handling: Efficient serving of CSS, JavaScript, and images.
- Custom Error Handling: Create custom error responses for status codes.
- Context Management: Each request has its own isolated context, providing global access to request/response objects during a request's lifecycle.
Setting Up Your Project Structure
To start using Osa, it’s helpful to follow a recommended project layout. Here’s a structure for organizing templates, static files, and more:
my_osa_project/
│
├── venv/ # Virtual environment
├── app.py # Main application file
├── static/ # Static files (CSS, JavaScript, images)
│ ├── css/
│ └── js/
├── templates/ # HTML templates
│ └── index.html
Creating Your First App
In your project folder, create app.py
:
from osa import Osa, request, response
app = Osa()
@app.route("/")
def index():
response.text = "Welcome to Osa Framework!"
if __name__ == "__main__":
app.run(host="127.0.0.1", port=5000)
Working with Templates and Static Files
1. Setting Up Templates
- Create a
templates
folder in your project. - Inside the folder, add your HTML files (e.g.,
index.html
):
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to Osa</title>
</head>
<body>
<h1>{{ greeting }}</h1>
</body>
</html>
To render the template in your route:
@app.route("/")
def index():
return app.template("index.html", {"greeting": "Welcome to Osa Framework!"})
2. Serving Static Files
- Create a
static
folder with subfolders likecss
,js
, etc. - Example CSS file (
static/css/style.css
):
/* static/css/style.css */
body {
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
To include the static file in your HTML template:
<link rel="stylesheet" href="/static/css/style.css">
Running the App
You can run your Osa application using the CLI:
osa run --host 127.0.0.1 --port 5000
Alternatively, set environment variables:
export OSA_APP=app:app # (Linux)
set OSA_APP=app:app # (Windows)
osa run
Osa will search for app.py
or wsgi.py
and look for the app
object.
Running the Server
osa run
more Details :
Command-Line Options
osa run --help
Usage:
osa run [OPTIONS]
Options:
--host TEXT
: Specify the host to bind the server to. Example:osa run --host 0.0.0.0
--port INTEGER
: Specify the port to run the server on. Example:osa run --port 8000
--app TEXT
: Specify the WSGI application to run, in the formatfilename:app_variable
. Example:osa run --app myapp:app
--no-debug
: Disable debug mode. Debug mode is enabled by default and provides helpful error messages and live reloading during development. Example:osa run --no-debug
--help
: Show the help message and exit.
How Osa Locates Your Application
Osa will automatically search for the following files in the directory you run the command from:
wsgi.py
app.py
Within these files, Osa looks for anapp
variable that holds the WSGI application. If you want to use a different filename or variable, you can specify it with the--app
option.
Example with all arguments (they are all optional):
osa run --host 127.0.0.1 --port 5000 --app myapp:app --no-debug
Advanced Usage
Routing with URL Parameters
@app.route("/hello/<name>")
def greet(name):
response.text = f"Hello, {name}!"
Handling Static and Dynamic Content
Class-based routing example:
@app.route("/item/<item_id>", methods=["GET","POST","PUT"])
class ItemHandler:
def get(self, item_id):
response.text = f"Fetching item {item_id}"
def post(self, item_id):
response.text = f"Item {item_id} added "
def PUT(self,item_id):
response.text = f"Update item{item_id}"
Custom Error Handling
Define custom error responses:
you can use the abort
function to raise HTTP exceptions with custom status codes and error messages
from osa import Osa, abort , request , response
app = Osa()
@app.errorhandler(404)
def not_found():
response.text = "Page not found."
@app.route("/admin")
def admin_panel():
user_authenticated = False
if not user_authenticated:
abort(403, "Forbidden: You are not authorized to access the admin panel.")
response.text = "Welcome to the Admin Panel!"
Middleware
Run functions before and after requests:
@app.before_request
def log_request():
print(f"Request received: {request.path}")
@app.after_request
def add_headers():
response.headers["X-Framework"] = "Osa"
Template Rendering
The default folder for template files is templates. You can change this by setting the templates_dir attribute when creating the Osa instance.
app = Osa(templates_dir="templates_directory")
To use the template engine, place your HTML files in the templates
directory and render them using:
@app.route("/greet")
def greet_template():
response.text = app.template("greet.html", {"name": "Osa User"})
Example HTML template (greet.html
):
<h1>Hello, {{ name }}!</h1>
Static Files
By default, static files are served from the static
folder. You can change this using:
app = Osa(static_dir="my_static")
In your HTML files, link static assets like so:
<link rel="stylesheet" href="/static/css/style.css">
More examples
Example 1
@app.route('/register', methods=['POST', 'GET'])
def register():
html_form = """
"""
if request.method == 'GET':
response.text = app.template('register.html')
elif request.method == 'POST':
#request.POST like request.form in flask
print(request.POST['username'])
print(request.POST['password'])
# You must sanitize the input before using it in your application ,
#but for now we will just use it as is
input_username = request.POST['username']
response.text = f"Hello, {input_username}! You have successfully registered."
<!-- register.html -->
<html>
<body>
<form method="post" action="/register">
<label for="username">Username:</label><br>
<input type="text" id="username" name="username"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br>
<input type="submit" value="Register">
</form>
</body>
</html>
example 2
@app.route("/item/<item_id>", methods=["GET","POST","PUT"])
class ItemHandler:
def get(self, item_id):
response.text = f"Fetching item {item_id}"
def post(self, item_id):
response.text = f"Item {item_id} added "
def PUT(self,item_id):
response.text = f"Update item{item_id}"
Resources
- Flask Documentation
- Flask Web Development book
- Alcazar
- WSGI Guide
- Context Management in Python Other
Python Web Framework flasky Alcazar
Wsgi
WSGI for Web Developers (Ryan Wilson-Perkin) what-the-hell-is-wsgi-anyway-and-what-do-you-eat-it-with/ pythons-wsgi-server-application-interface
Contextvars : python-contextvars-and-multithreading keeping-request-context-over-the-function-call-stack repository-pattern-with-context-variables
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file osa_web_framework-0.0.3.tar.gz
.
File metadata
- Download URL: osa_web_framework-0.0.3.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f702c0ad49b5208c0c055e16cbc0b7c98668f6de5e5ec19afce5651b6e3cad04 |
|
MD5 | 4069eaefa8cc583539e527bc79c78267 |
|
BLAKE2b-256 | a1017e117bc96965abd1a19b4812acaf954176d228e7b95d864facf2a24407f4 |
File details
Details for the file osa_web_framework-0.0.3-py3-none-any.whl
.
File metadata
- Download URL: osa_web_framework-0.0.3-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5acc3cf92d74ab89642e2e2014d01fa3e8290930b00a966fee39b29a6a41b5ea |
|
MD5 | 7b71e0014fa9064eed43c27cbbd20b06 |
|
BLAKE2b-256 | 97f818565c527e66a98b5e3eb57147d1cbe556c67dad929f617f7cc7fc8b759f |