WSGIC is a lightweight web framework built on top of WSGI. It aims to provide developers with a simple and flexible toolkit to build web applications in Python.
To get started with WSGIC, you can clone the repository and run the demo application:
$ git clone https://github.com/7HR4IZ3/wsgic.git
$ cd wsgic
$ pip install -r requirements.txt
$ python demo.py
Then, navigate to http://localhost:8000/ in your web browser to see the demo in action.
WSGIC includes the following features:
- Routing: WSGIC includes a flexible routing system based on URL patterns.
- Middleware: WSGIC supports middleware components that can modify requests and responses.
- Templates: WSGIC includes a simple templating engine for generating HTML.
- Static files: WSGIC can serve static files from a directory on the filesystem.
- Websocket: WSGIC has built in support for websockets using gevent
- Customizable: WSGIC is designed to be easy to customize and extend, so you can add your own functionality as needed.
Here's an example of how to create a simple "Hello, world!" application in WSGIC:
from wsgic import WSGIApp
from wsgic.routing import Router
router = Router()
routes = router.get_routes()
@routes.get("/")
def index():
return "Hello, world!"
app = WSGIApp(router=router)
application = app.wrapped_app("wsgi") # 'asgi' also supported
# or just call app.run()
Or flask style
from wsgic import WSGIApp
app = WSGIApp()
@app.get("/")
def index():
return "Hello, world!"
application = app.wrapped_app("wsgi") # 'asgi' also supported
# or just call app.run()
Note: The 'application = app.wrapped_app("wsgi")' exposes the wsgi layer so you can run your app using other wsgi servers else just call 'app.run()'
from wsgic import WSGIApp
app = WSGIApp()
@app.websocket("/")
def index(socket, close):
socket.receive() # Wait till client is ready
socket.send("Name: ")
name = socket.receive()
socket.send(f"Hello {name}")
close()
app.run()
Allows you to control the client dom from the server
from wsgic import WSGIApp
from wsgic.ui.dom import div, p, button
app = WSGIApp()
@app.web_route("/")
def index(response):
response.send(
div(
p(0, id="counts"),
button(id="increment")
)
)
browser = request.browser
counts = browser.document.querySelector("#counts")
increment = browser.document.querySelector("#increment")
def incr(event):
current = int(counts.innerText)
counts.innerText = current + 1
increment.addEventListener("click", incr)
app.run()
from wsgic import WSGIApp
from wsgic.handlers.files import FileSystemStorage
app = WSGIApp()
app.static("/assets", directory="./assets", store=FileSystemStore("./assets"))
# 'store' argument takes precedence over directory
@app.get("/")
def index(response):
return "Hello World!"
app.run()
from wsgic import WSGIApp
from wsgic.http import request
app = WSGIApp()
@app.get("/set/<name>")
def set(name):
request.session['name'] = name
return 'Set session name as %s'%name
@app.get("/get")
def get():
return 'Current session: name = "%s"'%request.session.get('name')
app.run()
from wsgic import WSGIApp
from wsgic.views import FunctionView, view
from wsgic.http import request, redirect
from wsgic.services import service
from wsgic_auth.core.session import SessionAuth
from wsgic.routing.helpers import alias, named_route
app = WSGIApp()
authentication: SessionAuth = service("authentication")
validation = service("validation")
@app.view("/")
class HomeView(FunctionView):
# FunctionView creates routes from all class methods with style '{method}_{path}'
# Methods starting with '_' are ignored
# Default method is get so 'profile' is interpreted as 'get_profile'
@named_route("homepage") # Register name for the route
@view("index.html") # Bind view to the route, interpreted as render("index.html", context=get_index())
def get_index(self):
return { "name": "World" }
@app.view("/auth")
class AuthView(FunctionView):
@view("login.html")
@named_route("login")
def get_login(self):
if authentication.is_logged_in(): return redirect("/")
return
def post_login(self):
if authentication.is_logged_in(): return redirect("/")
username = request.POST.get("username")
password = request.POST.get("password")
remember = request.POST.get("remember_me", False) == "on"
if validation.set_rules({
"username": "required",
"password": "required"
}).validate(request.POST):
authenticated = authentication.login(username, password, remember)
print(authentication.is_logged_in())
if authenticated:
return redirect().route("/").with_cookies()
else:
return redirect().back().error("Authentication failed.")
else:
error = validation.errors_list()
return redirect().back().error(*error)
def post_logout(self):
if authentication.is_logged_in():
authentication.logout()
return redirect().to("/")
Contributions to WSGIC are welcome! To get started, fork the repository and create a new branch for your feature or bug fix. Then, submit a pull request with your changes.
WSGIC is licensed under the MIT License. See LICENSE
for more information.