An effective, simple, and async security library for the Sanic framework.

Overview

Downloads Code style: black Conda Conda Downloads


Sanic Security

An effective, simple, and async security library for the Sanic framework.

Table of Contents

About The Project

Sanic Security is an authentication, authorization, and verification library designed for use with Sanic. This library contains a variety of features including:

  • Login, registration, and authentication (including access/refresh tokens)
  • Two-factor authentication
  • Two-step verification
  • Captcha
  • Role based authorization with wildcard permissions

This repository has been starred by Sanic's core maintainer:

aphopkins

Please visit security.sunsetdeveloper.com for documentation.

Getting Started

In order to get started, please install pip.

Prerequisites

  • pip
sudo apt-get install python3-pip

Installation

  • Install the Sanic Security pip package.
pip3 install sanic-security
  • Fork Sanic Security and install development dependencies.
pip3 install -e ".[dev]"

Configuration

Sanic Security configuration is merely an object that can be modified either using dot-notation or like a dictionary.

For example:

from sanic_security.configuration import config

config.SECRET = "This is a big secret. Shhhhh"
config["CAPTCHA_FONT"] = "./resources/captcha.ttf"

You can also use the update() method like on regular dictionaries.

Any environment variables defined with the SANIC_SECURITY_ prefix will be applied to the config. For example, setting SANIC_SECURITY_SECRET will be loaded by the application automatically and fed into the SECRET config variable.

You can load environment variables with a different prefix via calling the config.load_environment_variables("NEW_PREFIX_") method.

  • Default configuration values:
Key Value Description
SECRET This is a big secret. Shhhhh The secret used by the hashing algorithm for generating and signing JWTs. This should be a string unique to your application. Keep it safe.
CACHE ./security-cache The path used for caching.
SESSION_SAMESITE strict The SameSite attribute of session cookies.
SESSION_SECURE False The Secure attribute of session cookies.
SESSION_HTTPONLY True The HttpOnly attribute of session cookies. HIGHLY recommended that you do not turn this off, unless you know what you are doing.
SESSION_DOMAIN None The Domain attribute of session cookies.
SESSION_EXPIRES_ON_CLIENT False When true, session cookies are removed from the clients browser when the session expires.
SESSION_ENCODING_ALGORITHM HS256 The algorithm used to encode sessions to a JWT.
SESSION_PREFIX token Prefix attached to the beginning of session cookies.
MAX_CHALLENGE_ATTEMPTS 5 The maximum amount of session challenge attempts allowed.
CAPTCHA_SESSION_EXPIRATION 60 The amount of seconds till captcha session expiration on creation. Setting to 0 will disable expiration.
CAPTCHA_FONT captcha.ttf The file path to the font being used for captcha generation.
TWO_STEP_SESSION_EXPIRATION 200 The amount of seconds till two step session expiration on creation. Setting to 0 will disable expiration.
AUTHENTICATION_SESSION_EXPIRATION 2692000 The amount of seconds till authentication session expiration on creation. Setting to 0 will disable expiration.
ALLOW_LOGIN_WITH_USERNAME False Allows login via username and email.
TEST_DATABASE_URL sqlite://:memory: Database URL for connecting to the database Sanic Security will use for testing.

Usage

Sanic Security's authentication and verification functionality is session based.

A new session will be created for the user after the user logs in or requests some form of verification (two-step, captcha). The session data is then encoded into a JWT and stored on a cookie on the user’s browser. The session cookie would be sent along with every subsequent request. The server can then compare the session stored on the cookie against the session information stored in the database to verify user’s identity and send a response with the corresponding state.

The tables in the below examples represent example request form-data (https://sanicframework.org/en/guide/basics/request.html#form).

Authentication

  • Registration

Phone can be null or empty.

Key Value
username example
email [email protected]
phone 19811354186
password testpass
captcha Aj8HgD
@app.post("api/auth/register")
@requires_captcha()
async def on_register(request, captcha_session):
    account = await register(request)
    two_step_session = await request_two_step_verification(request, account)
    await email_code(
        two_step_session.code
    )  # Custom method for emailing verification code.
    response = json("Registration successful!", two_step_session.bearer.json())
    two_step_session.encode(response)
    return response
  • Verify Account
Key Value
code G8ha9nVae
@app.post("api/auth/verify")
async def on_verify(request):
    two_step_session = await verify_account(request)
    return json(
        "You have verified your account and may login!", two_step_session.bearer.json()
    )
  • Login

Login credentials are retrieved via the Authorization header. Credentials are constructed by first combining the username and the password with a colon (aladdin:opensesame), and then by encoding the resulting string in base64 (YWxhZGRpbjpvcGVuc2VzYW1l). Here is an example authorization header: Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l.

You can use a username as well as an email for login if ALLOW_LOGIN_WITH_USERNAME is true in the config.

@app.post("api/auth/login")
async def on_login(request):
    authentication_session = await login(request)
    response = json("Login successful!", authentication_session.bearer.json())
    authentication_session.encode(response)
    return response
  • Login (With two-factor authentication)
@app.post("api/auth/login")
async def on_two_factor_login(request):
    authentication_session = await login(request, two_factor=True)
    two_step_session = await request_two_step_verification(
        request, authentication_session.bearer
    )
    await email_code(
        two_step_session.code
    )  # Custom method for emailing verification code.
    response = json(
        "Login successful! A second factor is now required to be authenticated.",
        authentication_session.bearer.json(),
    )
    authentication_session.encode(response)
    two_step_session.encode(response)
    return response
  • Second Factor
Key Value
code G8ha9nVae
@app.post("api/auth/login/second-factor")
@requires_two_step_verification()
async def on_login_second_factor(request, two_step_session):
    authentication_session = await on_second_factor(request)
    response = json(
        "Second factor attempt successful! You may now be authenticated!",
        authentication_session.bearer.json(),
    )
    return response
  • Logout
@app.post("api/auth/logout")
@requires_authentication()
async def on_logout(request, authentication_session):
    await logout(authentication_session)
    response = json("Logout successful!", authentication_session.bearer.json())
    return response
  • Refresh Authentication

A refresh token is used that lets the client retrieve a new authentication session without having to ask the user to log in again.

@app.post("api/auth/refresh")
async def on_refresh(request):
    refreshed_authentication_session = await refresh_authentication(request)
    response = json(
        "Authentication session refreshed!",
        refreshed_authentication_session.bearer.json(),
    )
    refreshed_authentication_session.encode(response)
    return response
  • Requires Authentication
@app.post("api/auth")
@requires_authentication()
async def on_authenticated(request, authentication_session):
    return json(
        f"Hello {authentication_session.bearer.username}! You have been authenticated.",
        authentication_session.bearer.json(),
    )

Captcha

You must download a .ttf font for captcha challenges and define the file's path in the configuration.

1001 Free Fonts

Recommended Font

Captcha challenge example:

Captcha image.

  • Request Captcha
@app.get("api/captcha")
async def on_request_captcha(request):
    captcha_session = await request_captcha(request)
    response = await captcha_session.get_image()
    captcha_session.encode(response)
    return response
  • Requires Captcha
Key Value
captcha Aj8HgD
@app.post("api/captcha")
@requires_captcha()
async def on_captcha_attempt(request, captcha_session):
    return json("Captcha attempt successful!", captcha_session.json())

Two-step Verification

  • Request Two-step Verification
Key Value
email [email protected]
captcha Aj8HgD
@app.post("api/verification/request")
@requires_captcha()
async def on_request_verification(request, captcha_session):
    two_step_session = await request_two_step_verification(request)
    await email_code(
        two_step_session.code
    )  # Custom method for emailing verification code.
    response = json("Verification request successful!", two_step_session.bearer.json())
    two_step_session.encode(response)
    return response
  • Resend Two-step Verification Code
@app.post("api/verification/resend")
async def on_resend_verification(request):
    two_step_session = await TwoStepSession.decode(request)
    await email_code(
        two_step_session.code
    )  # Custom method for emailing verification code.
    return json("Verification code resend successful!", two_step_session.bearer.json())
  • Requires Two-step Verification
Key Value
code G8ha9nVa
@app.post("api/verification")
@requires_two_step_verification()
async def on_verification(request, two_step_session):
    response = json(
        "Two-step verification attempt successful!", two_step_session.bearer.json()
    )
    return response

Authorization

Sanic Security uses role based authorization with wildcard permissions.

Roles are created for various job functions. The permissions to perform certain operations are assigned to specific roles. Users are assigned particular roles, and through those role assignments acquire the permissions needed to perform particular system functions. Since users are not assigned permissions directly, but only acquire them through their role (or roles), management of individual user rights becomes a matter of simply assigning appropriate roles to the user's account; this simplifies common operations, such as adding a user, or changing a user's department.

Wildcard permissions support the concept of multiple levels or parts. For example, you could grant a user the permission printer:query, printer:query,delete, and/or printer:*.

  • Assign Role
await assign_role(
    "Chat Room Moderator",
    "Can read and delete messages in all chat rooms, suspend and mute accounts, and control voice chat.",
    "channels:view,delete, account:suspend,mute, voice:*",
    bearer,
)
  • Require Permissions
@app.post("api/channel/view")
@require_permissions("channels:view", "voice:*")
async def on_voice_chat_control(request, authentication_session):
    return text("Voice chat is now being controlled.")
  • Require Roles
@app.post("api/account/suspend")
@require_roles("Chat Room Moderator")
async def on_suspend_account(request, authentication_session):
    return text("Account successfully suspended.")

Testing

  • Set the TEST_DATABASE_URL configuration value.

  • Make sure the test Sanic instance (test/server.py) is running on your machine.

  • Run the unit test client (test/tests.py) and wait for results.

Tortoise

Sanic Security uses Tortoise ORM for database operations.

Tortoise ORM is an easy-to-use asyncio ORM (Object Relational Mapper).

  • Initialise your models and database like so:
async def init():
    await Tortoise.init(
        db_url="sqlite://db.sqlite3",
        modules={"models": ["sanic_security.models", "app.models"]},
    )
    await Tortoise.generate_schemas()

or

register_tortoise(
    app,
    db_url="sqlite://db.sqlite3",
    modules={"models": ["sanic_security.models", "app.models"]},
    generate_schemas=True,
)
  • Define your models like so:
from tortoise.models import Model
from tortoise import fields


class Tournament(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
  • Use it like so:
# Create instance by save
tournament = Tournament(name="New Tournament")
await tournament.save()

# Or by .create()
await Tournament.create(name="Another Tournament")

# Now search for a record
tour = await Tournament.filter(name__contains="Another").first()
print(tour.name)

Support for SQLAlchemy coming soon.

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the GNU General Public License v3.0. See LICENSE for more information.

Versioning

0.0.0

  • MAJOR version when you make incompatible API changes.

  • MINOR version when you add functionality in a backwards compatible manner.

  • PATCH version when you make backwards compatible bug fixes.

https://semver.org/

Comments
  • Add MANIFEST.in file

    Add MANIFEST.in file

    This is in accordance to https://packaging.python.org/gu…ides/using-manifest-in/

    I'm trying to add this package to conda-forge and right now the package isn't picking up the requirement.txt file, this should help!

    opened by thewchan 9
  • I made a thing

    I made a thing

    First, great work.

    Second, this has some stuff in it:

    • Moved to pytest for testing (including support for iterating through ORMs)
    • Moved to sanic-testing for the testing of Sanic to be uniform and supportable
    • Moved to poetry for package and dependency management
    • Bumped the version to 2.0.0_preview_01 just because
    • Made the tortoise-orm stuff a little more normalized (read: less Tortoise-ish, more whatever)
    • Built and bundled in a umongo option (what I use)
    • Support for bring your own ORM (need to document this, but basically you pass in, via config variables, your Models/Objects which must have a few items)
    • Updated all the needed modules to current versions
    • Force username, as well as phone and email to be unique, since all can be used to login
    • Force role names to be unique, because that's sanity
    • Moved model validators into their respective ORM, using their respective best practices
    • Started to make the module pluge-able to Sanic, via sanic-ext ... but recent updates broke what was working, and the developers said they are working on overhauling it, so I left it as is for now
    • Added some more variables:
        "SANIC_SECURITY_ORM": 'tortoise', # Currently supports ['tortoise', 'umongo']
        "SANIC_SECURITY_ACCOUNT": None,
        "SANIC_SECURITY_SESSION": None,
        "SANIC_SECURITY_ROLE": None,
        "SANIC_SECURITY_VERIFICATION_MODEL": None,
        "SANIC_SECURITY_TWOSTEP_MODEL": None,
        "SANIC_SECURITY_CAPTCHA_MODEL": None,
        "SANIC_SECURITY_AUTHENTICATION_MODEL": None,
    

    Third, I suck at documentation (including docstrings), and lots is needed, so I'll start working on that next. I tried to maintain as much backwards support as possible .. but some things just needed to change (hence the major version bump) to be sane and relatively clean.

    Lastly, the umongo.py ORM file still needs some cleanup -- nothing breaking, just code quality and DRYness.

    opened by pahrohfit 5
  • sanic response cookie seems need type str rather than byte

    sanic response cookie seems need type str rather than byte

    Describe the bug sanic response cookie seems need type str rather than bytes, or got TypeError

    // tested with sanic 20.12.3, 21.6.2

    To Reproduce server use test/server.py client use curl:

    //1. reg user //ok

    curl -sv http://127.0.0.1:8000/api/test/auth/register [email protected] \
     -Fusername=test -Fpassword=testtest -Fverified=true
    

    //2. login user // fail TypeError // should login success

    curl -sv http://127.0.0.1:8000/api/test/auth/login --user '[email protected]:testtest' -d ''
    
    [2022-01-22 09:34:03 +0800] [1732395] [ERROR] Exception occurred while handling uri: 'http://127.0.0.1:8000/api/test/auth/login'
    Traceback (most recent call last):
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/server.py", line 509, in write_response
        response.output(
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/response.py", line 169, in output
        return self.get_headers(version, keep_alive, keep_alive_timeout, body)
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/response.py", line 64, in get_headers
        return format_http1_response(self.status, self.headers.items(), body)
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/headers.py", line 194, in format_http1_response
        headerbytes = format_http1(headers)
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/headers.py", line 184, in format_http1
        return "".join(f"{name}: {val}\r\n" for name, val in headers).encode()
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/headers.py", line 184, in <genexpr>
        return "".join(f"{name}: {val}\r\n" for name, val in headers).encode()
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/cookies.py", line 137, in __str__
        output = ["%s=%s" % (self.key, _quote(self.value))]
      File "/home/chen/.local/lib/python3.8/site-packages/sanic/cookies.py", line 30, in _quote
        if str is None or _is_legal_key(str):
    TypeError: cannot use a string pattern on a bytes-like object
    

    Version // sanic-security 1.4.7

    • sanic 20.12.3 + py3.8
    • sanic 21.6.2 + py3.9

    Workaround seems in sanic 20.12.3, 21.6.2 response.cookie should be str type.

    https://github.com/sunset-developer/sanic-security/blob/v1.4.7/sanic_security/models.py#L288

    changes:

            response.cookies[cookie] = jwt.encode(
                payload, security_config.SECRET, security_config.SESSION_ENCODING_ALGORITHM
    -        )
    +        ).decode('utf-8')
    
    opened by yurenchen000 2
  • Reformating

    Reformating

    Unfortunately, I was not able to test whether my changes are breaking or not. I have reviewed them multiple times, and I expect that they would not be breaking.

    I tried to not change any of the behavior because it was described as stable.

    opened by HelixAchaos 2
  • Documentation and DRYness

    Documentation and DRYness

    • Finished README.md file (I think)
    • Moved .decode() property to the utils module, as I was able to decouple it from the ORM, thus making it more DRY and better suited for BYO-ORM
    • Added a .lookup() classmethod to all of the Session classes.
    opened by pahrohfit 0
  • Documentation and DRYness

    Documentation and DRYness

    • Finished README.md file (I think)
    • Moved .decode() property to the utils module, as I was able to decouple it from the ORM, thus making it more DRY and better suited for BYO-ORM
    • Added a .lookup() classmethod to all of the Session classes.
    opened by pahrohfit 0
  • Showcase Feedback

    Showcase Feedback

    => you have a license mismatch (https://github.com/sunset-developer/sanic-security/blob/main/setup.py#L15)

    => you default to HTTP cookies that do not have secure flag set (https://github.com/sunset-developer/sanic-security/blob/main/sanic_security/configuration.py#L29)

    => your project requires phone number, and the regex doesnt support any non US format (https://github.com/sunset-developer/sanic-security/blob/main/sanic_security/authentication.py#L74)

    => your project does not check for common passwords such as "password", "qwerty", etc

    opened by sunset-developer 0
  • ORM objects into regular objects in models.py

    ORM objects into regular objects in models.py

    In order to rip out Tortoise, we need to convert the current ORM objects into regular objects in models.py.

    I began the process by converting the BaseModel and Account objects.

    This commit provides a demonstration as to what was changed and what was removed.

    https://github.com/sunset-developer/sanic-security/commit/7a0cb6443142d9d2287ac5b9187cf7420a7efea2

    Simply, any line of code that uses Tortoise must be removed or changed in a way that can have a similar function but without requiring retrieving the object from the database, for example: requiring a parameter in a method so the object has to be passed in.

    opened by sunset-developer 0
Releases(v1.9.7)
  • v1.9.7(Dec 5, 2022)

  • v1.9.6(Dec 2, 2022)

  • v1.9.5(Dec 2, 2022)

    • Account associated to new two-step session on two-step verification request can now be retrieved from an existing two-step session.
    • Unit test client additions.
    • Documentation revision.
    Source code(tar.gz)
    Source code(zip)
  • v1.9.4(Nov 29, 2022)

  • v1.9.3(Nov 17, 2022)

  • v1.9.2(Nov 17, 2022)

  • v1.9.1(Nov 16, 2022)

  • v1.9.0(Sep 28, 2022)

    • Usernames are now required to be unique.
    • Captcha and verification modules merged.
    • Session deactivate() method implemented.
    • Test client/server revisions.
    • README.md and documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.8.3(Jun 7, 2022)

    • SESSION_SECURE config field default is now set to True.
    • Phone number format check revision.
    • token field removed from Session. Sessions are now retrieved via id when decoding.
    • setup.py license mismatch revision.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.8.2(May 29, 2022)

  • v1.8.1(May 23, 2022)

  • v1.8.0(May 23, 2022)

  • v1.7.1(May 21, 2022)

    • Refresh authentication improvements.
    • Methods decode_to_refresh() and validate_refresh() implemented in AuthenticationSession
    • refresh_authentication() method revised.
    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(May 20, 2022)

    • On-the-fly verification code and captcha image generation.
    • SessionFactory removed and replaced with new() class method.
    • redeem() method removed and code moved to refresh_authentication() method.
    • refresh_expiration_date field added to AuthenticationSession.
    • Util methods get_code() and get_expiration_date() implemented.
    • CaptchaSession method get_image() returns raw() instead of file() and is no longer async.
    • assign_role() method parameters permissions and description are optional.
    • Test server and client revisions.
    • logout() method will raise error if session is already deactivated.
    • Unrecognized location check removed.
    • CACHE configuration field removed.
    • Licensing revision.
    • Log message revisions.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.6.0(May 6, 2022)

  • v1.5.0(Apr 28, 2022)

    • Improved type hinting on model variables and methods.
    • Improved two-step session code generation. It is recommended to clear your cache due to these changes.
    • generate_initial_admin renamed to create_initial_admin_account.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.11(Mar 17, 2022)

  • v1.4.10(Feb 15, 2022)

  • v1.4.9(Feb 5, 2022)

  • v1.4.8(Jan 24, 2022)

  • v1.4.7(Jan 21, 2022)

    • Authorization fix that takes roles marked as deleted into consideration.
    • Account retrieval methods filter out accounts marked as deleted instead of relying on validation.
    • Improved model type hinting.
    • Minor testing adjustments and fixes.
    • Licensing revision.
    • License statement attached to source files.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.6(Jan 19, 2022)

  • v1.4.5(Jan 18, 2022)

    • Refresh token and redeem method are no longer inherited from Session and resides in AuthenticationSession.
    • Captcha and two-step session request improvements.
    • Invalid credentials for registration now raise CredentialsError.
    • Session context (ctx) field for storing extra information.
    • MaxedOutChallangeError exception implemented and raised when a session's challenge attempts has reached it's threshold.
    • Error message clarification.
    • Improved error handling.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.4(Jan 13, 2022)

    • Previous client session is deactivated when a new one is requested (for example when requesting captcha).
    • Two-factor authentication fix and error message clarification.
    • Documentation revision.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.3(Jan 7, 2022)

    • Login credentials are received via authorization header.
    • Tests revised accordingly to use authorization header.
    • Major documentation revisions.
    • MAX_ATTEMPTS_ALLOWED configuration field added.
    • CredentialsError exception implemented for an invalid login.
    • JWTDecodeError exception implemented if an error occurs during session JWT decoding.
    • ChallengeError exception implemented if a verification session challenge attempt is incorrect.
    • crosscheck_code method renamed to check_code
    Source code(tar.gz)
    Source code(zip)
  • v1.4.2(Jan 6, 2022)

    • validate_location renamed to check_client_location.
    • UnrecognisedLocationError now raised instead of SessionError when checking client location.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.1(Jan 3, 2022)

    • Improved refresh token reuse protection.
    • crosscheck_location renamed to validate_location.
    • Sessions marked as deleted won't be taken into consideration during location validation.
    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Jan 2, 2022)

    • Authorization revamp. Permission object removed as permissions are stored in a Role object. An account's roles can be accessed via the roles variable value via a many-to-many relationship.
    • Session access/refresh token's.
    • Model revisions.
    • Improved registration error handling.
    • Password character limit check during registration.
    • Uid removed.
    • Test improvements.
    • Documentation revisions.
    Source code(tar.gz)
    Source code(zip)
  • v1.3.3(Dec 29, 2021)

  • v1.3.2(Dec 19, 2021)

Owner
Sunset Dev
May the bridges you burn light your way.
Sunset Dev
Daniel Vaz Gaspar 4k Jan 8, 2023
Dazzler is a Python async UI/Web framework built with aiohttp and react.

Dazzler is a Python async UI/Web framework built with aiohttp and react. Create dazzling fast pages with a layout of Python components and bindings to update from the backend.

Philippe Duval 17 Oct 18, 2022
Lemon is an async and lightweight API framework for python

Lemon is an async and lightweight API framework for python . Inspired by Koa and Sanic .

Joway 29 Nov 20, 2022
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Jan 8, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Dec 28, 2022
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
Asita is a web application framework for python based on express-js framework.

Asita is a web application framework for python. It is designed to be easy to use and be more easy for javascript users to use python frameworks because it is based on express-js framework.

Mattéo 4 Nov 16, 2021
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.

Tornado Web Server Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking ne

null 20.9k Jan 1, 2023
bottle.py is a fast and simple micro-framework for python web-applications.

Bottle: Python Web Framework Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module a

Bottle Micro Web Framework 7.8k Dec 31, 2022
Fast⚡, simple and light💡weight ASGI micro🔬 web🌏-framework for Python🐍.

NanoASGI Asynchronous Python Web Framework NanoASGI is a fast ⚡ , simple and light ?? weight ASGI micro ?? web ?? -framework for Python ?? . It is dis

Kavindu Santhusa 8 Jun 16, 2022
web.py is a web framework for python that is as simple as it is powerful.

web.py is a web framework for Python that is as simple as it is powerful. Visit http://webpy.org/ for more information. The latest stable release 0.62

null 5.8k Dec 30, 2022
easyopt is a super simple yet super powerful optuna-based Hyperparameters Optimization Framework that requires no coding.

easyopt is a super simple yet super powerful optuna-based Hyperparameters Optimization Framework that requires no coding.

Federico Galatolo 9 Feb 4, 2022
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 1, 2023
The Modern And Developer Centric Python Web Framework. Be sure to read the documentation and join the Slack channel questions: http://slack.masoniteproject.com

NOTE: Masonite 2.3 is no longer compatible with the masonite-cli tool. Please uninstall that by running pip uninstall masonite-cli. If you do not unin

Masonite 1.9k Jan 4, 2023
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

null 2k Dec 31, 2022
Ape is a framework for Web3 Python applications and smart contracts, with advanced functionality for testing, deployment, and on-chain interactions.

Ape Framework Ape is a framework for Web3 Python applications and smart contracts, with advanced functionality for testing, deployment, and on-chain i

ApeWorX Ltd. 552 Dec 30, 2022
An abstract and extensible framework in python for building client SDKs and CLI tools for a RESTful API.

django-rest-client An abstract and extensible framework in python for building client SDKs and CLI tools for a RESTful API. Suitable for APIs made wit

Certego 4 Aug 25, 2022
Bionic is Python Framework for crafting beautiful, fast user experiences for web and is free and open source

Bionic is fast. It's powered core python without any extra dependencies. Bionic offers stateful hot reload, allowing you to make changes to your code and see the results instantly without restarting your app or losing its state.

 ⚓ 0 Mar 5, 2022
Asynchronous HTTP client/server framework for asyncio and Python

Async http client/server framework Key Features Supports both client and server side of HTTP protocol. Supports both client and server Web-Sockets out

aio-libs 13.2k Jan 5, 2023