The web framework for inventors

Overview

Emmett

Emmett is a full-stack Python web framework designed with simplicity in mind.

The aim of Emmett is to be clearly understandable, easy to be learned and to be used, so you can focus completely on your product's features:

from emmett import App, request, response
from emmett.orm import Database, Model, Field
from emmett.tools import service, requires

class Task(Model):
    name = Field.string()
    is_completed = Field.bool(default=False)

app = App(__name__)
app.config.db.uri = "postgres://user:[email protected]/foo"
db = Database(app)
db.define_models(Task)
app.pipeline = [db.pipe]

def is_authenticated():
    return request.headers["Api-Key"] == "foobar"
    
def not_authorized():
    response.status = 401
    return {'error': 'not authorized'}

@app.route(methods='get')
@service.json
@requires(is_authenticated, otherwise=not_authorized)
async def todo():
    page = request.query_params.page or 1
    tasks = Task.where(
        lambda t: t.is_completed == False
    ).select(paginate=(page, 20))
    return {'tasks': tasks}

pip version Tests Status

Documentation

The documentation is available at https://emmett.sh/docs. The sources are available under the docs folder.

Examples

The bloggy example described in the Tutorial is available under the examples folder.

Status of the project

Emmett is production ready and is compatible with Python 3.7 and above versions.

Emmett follows a semantic versioning for its releases, with a {major}.{minor}.{patch} scheme for versions numbers, where:

  • major versions might introduce breaking changes
  • minor versions usually introduce new features and might introduce deprecations
  • patch versions only introduce bug fixes

Deprecations are kept in place for at least 3 minor versions, and the drop is always communicated in the upgrade guide.

How can I help?

We would be very glad if you contributed to the project in one or all of these ways:

  • Talking about Emmett with friends and on the web
  • Adding issues and features requests here on GitHub
  • Participating in discussions about new features and issues here on GitHub
  • Improving the documentation
  • Forking the project and writing beautiful code

License

Emmmett is released under the BSD License.

However, due to original license limitations, some components are included in Emmett under their original licenses. Please check the LICENSE file for more details.

Comments
  • Bug in session?

    Bug in session?

    I get an error here [1]

    data = pickle.dumps(sdict(current.session)) TypeError: 'NoneType' object is not callable

    But all the objects and variables involved contains data, in no case is it None

    current.session has data, sdict and pickle existed

    emmett 2.4.3 emmett-crypto 0.2.2 emmett-rest 1.3.2

    [1] https://github.com/emmett-framework/emmett/blob/8bf5c23c33a0fbdad260789baa6c28e1657bd2e6/emmett/sessions.py#L141

    bug bug::confirmed 
    opened by josejachuf 21
  • Possible bug in stream_dbfile

    Possible bug in stream_dbfile

    Hi @gi0baro, I do not know where the problem may be. I will try to put the maximum information about what is happening.

    Given a model with an upload field, an image in my case.

    In development mode works fine. I upload the image and I can show it on some page, but in production (nginx + gunicorn) the following happens:

    • The image is uploaded well to the server
    • The image fails to display on the page

    I did this test:

    Create a tunnel to the server to access port 8000 and start the development server from weppy.

    [develop]

    1. I uploaded the image and I could see it without problems

    [nginx] 2) Try to view image uploaded in (1) and fail. 3) I uploaded another image but could not see it

    [develop] 4) I can see the image uploaded in (3)

    The download function is this:

    @app.route("/download/<str:filename>")
    def download(filename):
        stream_dbfile(db, filename)
    
    

    If I copy the url of the image and paste it in another tab, sometimes it gives: "Internal Server Error" and other times malformed image

    There is no error in the nginx log.

    If you need any further proof, please let me know.

    Jose

    invalid 
    opened by josejachuf 19
  • Next major release

    Next major release

    So, I think during this year a couple of minor releases (1.1 and 1.2) hopefully will take place, and they probably will focus on optimization – rewriting the router to gain performance is one of these – and small enhancements on the existing features.

    The key-fact of this discussion is regarding the next major release (2.0) which I really hope would be ready for the end of the year or the start of the next. Here are some ideas I got in the last months.

    Things I really want into 2.0

    Drop the Python 2 support With the status of Python 3 and the ecosystem, and the official drop of the support in 2020, I can't see any good reason to keep all the compatibility code inside weppy. Definitely moving to Python 3 will really simplify the internal code and avoid slow downs caused by compatibility layers.

    Rewrite and separate the ORM Some people already asked me to separate the ORM into a separate project, and I think that's a good idea. But I really want to take advantage of this to rewrite the bottom layer and stop depending from the pydal library. This will surely bring some advantages, like generally improving the performance of the ORM, and the ability to extend it with new features quickly (hstore and jsonb support on postgres, for example). Even if I am one of the core contributors of pydal, moving the weppy ORM layer into a separated project will definitely avoid me the pain of keeping really old and awful code just for keeping backward compatibility and to remove a lot of codes weppy doesn't really use or need. Surely rewriting this layer will cause some disadvantages, like some incompatibilities with weppy 1.0 or loosing the compatibility with some DBMS – even if today I don't really supports them, and they actually doesn't work really well 'cause nobody supports them in pydal – but I really feel bad when I think the difficulty of adding new features to the current layer. What I can say right now is that I want to keep support for sqlite, mysql, postgresql, mssql and mongo, but the list might be expanded depending on the workload. We'll see.

    Support for sockets/channels I don't really want to switch the framework when I need them, so they will definitely be in 2.0. I don't actually know if the next major version will be totally async compatible, 'cause right now weppy abuses quite a lot of thread locals, but I'll see in the next month how to deal with that.

    Things nice to have in 2.0

    • Enhancements to the templates system: would be nice to make it even more flexible
    • Support for isomorphism/frontend components: seems like a trend right know, and it's really interesting to me (can lead to frontend validation with forms and things like that), but I need to explore this more accurately.
    • Commands to generate scaffolds: can be a good point to generate different applications scaffolds for new adopters

    This is almost everything I have in my plans. But I am totally open to suggestions, feature requests, feedbacks, whatever. Feel free to add your 2 cents to the discussion.

    discussion 
    opened by gi0baro 18
  • URL validation causes weird bug in general validation

    URL validation causes weird bug in general validation

    Try these examples:

    The following URLs fail on URL validation of forms: www.domain.tld domain.tld http://domain.tld http://www.domain.tld http://www.domain.tld/

    This works: http://domain.tld/

    After I tried this again - the working URL wasn't accepted a second time. So this check is inconsistent and weirdly at the same time when this URL validation passes, all other form errors aren't shown like all other fields (which are empty in this situation) are okay even if I force them to be filled in.

    There must be some bug in the form validation.

    opened by GiantCrocodile 16
  • Temporarily return to rapidjson

    Temporarily return to rapidjson

    I have a problem that is not directly from emmett but with the installation of orjson.

    All the server infrastructure I use is freebsd (+ jails). The orjson installation with pip does not use binaries, it is compiled. To compile you need to install some dependencies, including maturin. In the maturin installation an error occurs (I reported it) and therefore I cannot install orjson.

    I've been seeing this [1]

    What I want to do is temporarily modify serializers.py [2] and go back to rapidjson. This is apparently the only place where orjson is referenced. The query is if this change is enough and nothing will break.

    [1] https://github.com/emmett-framework/emmett/commit/2878fbdfd0ddedbee40ed863d78fb9c6525fc93e [2] https://github.com/emmett-framework/emmett/commit/5bbbae35c8517fd147e9b76ec4486432c347ef9e

    question 
    opened by josejachuf 12
  • From weppy to emmett

    From weppy to emmett

    Hi @gi0baro

    Emmet: 2.0.0a5 Emmet-REST: 1.0.0a1

    I am trying to run a weppy app with the new emmett and emmett_rest. After fixing the imports the app compiles and starts the server. But for any request return an error. The app is exactly as I took it working from weppy.

    ERROR: Application exception: Traceback (most recent call last): File "/home/jose/emmett/venv38/lib/python3.8/site-packages/emmett/asgi/handlers.py", line 282, in dynamic_handler http = await self.router.dispatch() File "/home/jose/emmett/venv38/lib/python3.8/site-packages/emmett/routing/router.py", line 217, in dispatch http_cls, output = await route.dispatcher.dispatch(request, reqargs) File "/home/jose/emmett/venv38/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 75, in dispatch await self._parallel_flow(self.flow_open) File "/home/jose/emmett/venv38/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 26, in _parallel_flow tasks = [asyncio.create_task(method()) for method in flow] File "/home/jose/emmett/venv38/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 26, in tasks = [asyncio.create_task(method()) for method in flow] File "/usr/lib/python3.8/asyncio/tasks.py", line 382, in create_task task = loop.create_task(coro) File "uvloop/loop.pyx", line 1396, in uvloop.loop.Loop.create_task TypeError: a coroutine was expected, got None

    What should I consider to do the w2e migration?

    question 
    opened by josejachuf 12
  • Password fields get reprocessed on saves even without changes

    Password fields get reprocessed on saves even without changes

    Hi @gi0baro

    [emmett: 2.4.9]

    Give the following model for User:

    class User(AuthUser):
        tablename = 'auth_users'
        belongs_to({'institucion': 'Institucion'})
    
        id = Field.string(default=lambda: uuid4().hex)
        avatar = Field.upload(autodelete=True)
        cuit = Field.string(length=11)
          
        validation = {
                'email': {'is': 'email', 'message': 'Ingrese el Correo Electrónico'},
                'last_name': {'presence': True, 'message': 'Ingrese el Apellido'},
                'first_name': {'presence': True, 'message': 'Ingrese el Nombre'},
                'password': {'len': {'gte': 8, 'lte': 50},
                         'message': 'La contraseña debe contener entre 8 y 50 caracteres'
                         }
        }
    
        fields_rw = {
                'institucion': True,
                'cuit': True
                }
    
        rest_rw = {
            'institucion': True,
            'registration_key': True,
            'password': (False, True)
        }
    

    And the form to create and update

    @user.route("/form")
    async def form():
        
        _id = request.query_params.id
    
        exclude_fields = []
        if _id:
            exclude_fields = ['password']
    
        form = await User.form(record_id=_id,  exclude_fields=exclude_fields)
        if form.accepted:
            if 'id' in form.params:
                _id = form.params.id
                  
            redirect(url('.bar', params=dict(id=_id)))
    
        return dict(form=form)
    

    From the form I can create a user useless, but when I edit it, the changes are not registered. It does not give error of any kind, neither in the console nor in the browser

    In this way I have working on Emmett 2.3.1 (and Weppy). I can't try this in version 2.3.1 for the use of PK as UUID, but in another old project it works.

    bug bug::confirmed 
    opened by josejachuf 11
  • regex and russian language in utf-8 template

    regex and russian language in utf-8 template

    Hi, @gi0baro !

    I'm cannot find nothing about regular expressions in templates, and when i create template with utf-8 encoding and write russian text, i cannot see a valid text on template rendering. Does weppy framework supports these features?

    Sorry, if i ask stupid questions, and my english.

    Thank you.

    opened by hloe0xff 11
  • About signed urls

    About signed urls

    @gi0baro, Based on bloggy, I added signature.py. (Attached)

    Modifications to bloggy.py:

    from signature import SignPipe, SignInjector

    app.injectors = [SignInjector()]

    @app.route("/post/<int:pid>", pipeline=[SignPipe()])
    def one(pid):
       ...
    
    @app.route("/new")
    @requires(lambda: auth.has_membership('admin'), url('index'))
    def new_post():
        form = Post.form()
        if form.accepted:
            redirect(url('one', form.params.id, sign=SignInjector.sign))
        return dict(form=form)
    
    

    index.html

    {{extend 'layout.html'}}
    
    <a href="{{=url('new_post')}}">Create a new post</a>
    <ul class="posts">
    {{for post in posts:}}
        <li>
            <h2>{{=post.title}}</h2>
            <a href="{{=url('one', post.id, sign=sign)}}">Read more</a>
            <hr />
        </li>
    {{pass}}
    {{if not posts:}}
        <li><em>No posts here so far.</em></li>
    {{pass}}
    </ul>
    

    As you can see only the one function requires that it be signed.

    It happens that after entering a signed link ["Read more"] other links are signed, for example new_post. It is as if the _signature parameter appears in each url, so when the signature is created, the url already contains another signature and it is obvious that validation will always fail.

    I found a solution modifying weppy / espose / url by removing the _signature parameter if it exists in params like this:

    # add signature
        if '_signature' in params:
            params.pop('_signature')
    
        if sign:
            params['_signature'] = sign(
                path, args, params, anchor, scheme, host, language)
    

    Can you apply this change to the repository?

    bloggy.zip

    opened by josejachuf 11
  • multiple route and one function  work random,404

    multiple route and one function work random,404

    Here is my simple app server,use two route /api/v1/book/isbn/<str:isbn> and /api/v1/book/<int:bookid>

    when I visit http://127.0.0.1:8001/api/v1/book/isbn/1231 It works 50% work at #return 1 ,50% 404, I dont know why,It has run inside the book function already。

    This is my code:

    #coding=utf-8
    from weppy import request
    from weppy import App
    from weppy.tools import service
    
    app = App(__name__)
    
    import random
    
    @app.route('/api/v1/book/isbn/<str:isbn>')
    @app.route('/api/v1/book/<int:bookid>')
    @service.json
    def book(isbn=None,bookid=None):
    
        if random.random()>0.5:
        #return 1
            return isbn
        #return 2
        if isbn != None:
            data = {'isbn':isbn}
        if bookid != None:
            bookid = int(bookid)
            data = {'id':bookid}
    
        return data
    
    if __name__ == '__main__':
        app.debug = True
        app.run(host='0.0.0.0', port=8001)
    
    opened by alingse 9
  • Auth: True for read is ignored on form_profile_rw

    Auth: True for read is ignored on form_profile_rw

    When I set form_profile_rw for field username to (True, False) in my User(AuthUserBasic) model the username field isn't displayed. It looks like read-access is broken and only writing works because if I set it to (True, True) or (False, True) I can see a textfield to type in.

    Expected behaviour is explained here: http://weppy.org/docs/0.5/dal#the-models-setup-helper

    enhancement feature request 
    opened by GiantCrocodile 9
  • PK uuid and auth_permission

    PK uuid and auth_permission

    Taking into account the UUID type PK support. How is it resolved in auth_permission record_id (integer) field?

    Sample of docs:

    maintenance = db.Preference(name='maintenance').first()
    auth.add_permission(admins, 'write', 'Preference', maintenance.id)
    auth.has_permission('write', 'Preference', maintenance.id)
    

    If Preference.id is uuid, this would not work.

    Jose

    enhancement 
    opened by josejachuf 1
  • Bug with 'in': {'dbset': ...} validation

    Bug with 'in': {'dbset': ...} validation

    I have this validation

    'f1': {'in': {'dbset': lambda db: db.where(db.A.f2 == session.f2)}}

    In another way:

    def val_f2(db):
        print(session.f2)
        return db.where(db.A.f2 == session.f2)
        
    'f1': {'in': {'dbset': lambda db: val_f2(db)}}
    

    The problem I have is that lambda runs only once and after that first time does not come to run, then it is always calling db.where from the first condition. I can check it with the print() that only runs once

    Jose

    ORM bug::investigation-needed 
    opened by josejachuf 5
  • Introduce relations facilities on forms

    Introduce relations facilities on forms

    Aim: make it easy to generate forms containing also related models' fields

    See https://github.com/emmett-framework/emmett/discussions/324 and https://github.com/emmett-framework/emmett/discussions/350

    enhancement nicetohave 
    opened by gi0baro 1
  • Introduce facilities for large applications

    Introduce facilities for large applications

    Some might be:

    • application composition
    • re-utilizable ORM models
    • ORM migrations' namespaces
    • advanced control of AppModule lifecycle
    • routes abstract classes to facilitate code recycling/extension
    enhancement nicetohave 
    opened by gi0baro 1
  • Use Emmett ORM separately from the App (in a Notebook)

    Use Emmett ORM separately from the App (in a Notebook)

    Hey @gi0baro ,

    I wanted to know use Emmett ORM separately from the App.

    Ideally, I would use a Notebook where I would declare the DB and the Models, attach the Models to the DB, and test different queries.

    Is it possible ?

    Thank you! Pierre

    feature request 
    opened by delarroqua 4
Releases(v2.4.13)
  • v2.4.13(Nov 24, 2022)

  • v2.4.12(Oct 31, 2022)

  • v2.4.11(Oct 28, 2022)

  • v2.4.10(May 23, 2022)

  • v2.4.9(Apr 19, 2022)

  • v2.4.8(Apr 12, 2022)

  • v2.4.7(Apr 11, 2022)

  • v2.4.6(Apr 11, 2022)

    Patch release

    Changes since 2.4.5:

    • ensure Row relations attributes typing across all operations
    • update uvicorn and http stack dependencies
    Source code(tar.gz)
    Source code(zip)
  • v2.4.5(Mar 11, 2022)

    Patch release

    Changes since 2.4.4:

    • fix regression bug preventing ORM Row objects to be pickled due to relations
    • fix regression bug in ORM adapter patches with NoSQLAdapter
    Source code(tar.gz)
    Source code(zip)
  • v2.4.4(Mar 6, 2022)

    Patch release

    Changes since 2.4.3:

    • fix regression bug preventing ORM Row objects to be pickled in certain conditions
    • align Request.client behaviour to ASGI standard
    Source code(tar.gz)
    Source code(zip)
  • v2.4.3(Feb 8, 2022)

  • v2.4.2(Jan 27, 2022)

    Patch release

    Changes since 2.4.1:

    • fix regression bug preventing has_many decorator relations resolution
    • fix via relations resolution iteration with intermediate via relations
    • fix migration engine generation in case of custom commands in tree
    • align has_one relations behaviour to has_many with via usage
    • avoid to replace field contents unless necessary in empty validation checks
    Source code(tar.gz)
    Source code(zip)
  • v2.4.1(Jan 18, 2022)

  • v2.4.0(Jan 10, 2022)

    This was huge. With almost 7k lines diff from previous release, 2.4 is focused on Python 3.10 support and ORM features. Due to the already consistent amount of changes, some features originally planned for this release were postponed to next major release.

    Thanks to all the community for their patience, with a special mention to @Kkeller83 who keeps sponsoring Emmett project and @treelym who sponsored the project for a couple of months since last major release.

    Changes since 2.3:

    • Added official Python 3.10 support
    • Added relative path support in templates
    • Added support for spatial columns in ORM
    • Added support for custom/multiple primary keys in ORM
    • Added support for custom/multiple foreign keys in ORM
    • Added support for custom and multiple primary keys relations in ORM
    • Added watch parameter to ORM's compute decorator
    • Added save method to ORM's rows and relevant callbacks
    • Added destroy method to ORM's rows and relevant callbacks
    • Added refresh method to ORM's rows
    • Added before_commit and after_commit ORM callbacks
    • Added changes tracking to ORM's rows
    • Added support to call super rowmethod decorated methods in ORM models
    • Added migrations set command to CLI
    • Added skip_callbacks parameter to relevant methods in ORM
    • ORM now automatically adds appropriate indexes for unique fields

    As usual, upgrade guide is available in the docs

    Source code(tar.gz)
    Source code(zip)
  • v2.3.2(Oct 29, 2021)

  • v2.3.1(Aug 19, 2021)

  • v2.3.0(Aug 12, 2021)

    Changes since 2.2:

    • Minor enhancements on request flow
    • Added ORM support for PostgreSQL json/jsonb fields and operators
    • Added widget_radio to forms.FormStyle
    • Added dict values support for in validations
    • Use optional emmett-crypto package for cryptographic functions
    • Deprecated security.secure_dumps and security.secure_loads in favour of new crypto package
    • Add on_delete option to belongs_to and refers_to
    • Add --dry-run option to migrations up and down commands
    Source code(tar.gz)
    Source code(zip)
  • v2.2.5(Aug 8, 2021)

    Patch release

    Changes since 2.2.4:

    • Fix regression bug preventing correct serialisation/deserialisation with tools.service module pipes and websockets
    Source code(tar.gz)
    Source code(zip)
  • v2.2.4(Jul 27, 2021)

    Patch release

    Changes since 2.2.3:

    • Fix ORM migrations engine producing wrong SQL instructions in columns foreign keys constraints on some adapters
    • Bump bundled jQuery to 3.5.x to fix several vulnerabilities
    Source code(tar.gz)
    Source code(zip)
  • v2.2.3(Jun 21, 2021)

  • v2.2.2(Jun 1, 2021)

  • v2.2.1(Apr 26, 2021)

  • v2.2.0(Mar 9, 2021)

    Changes since 2.1:

    • Slightly refactored request flow
    • Added App.command_group decorator
    • Added additional arguments acceptance in AppModule
    • Added static paths customisation for AppModule
    • Added workers options to serve command
    • Changed default logging level to info in serve command
    • Changed default SameSite policy for session cookies to Lax
    • Added official Python 3.9 support
    Source code(tar.gz)
    Source code(zip)
  • v2.1.4(Nov 9, 2020)

  • v2.1.3(Nov 6, 2020)

  • v2.1.2(Oct 31, 2020)

  • v2.1.1(Oct 28, 2020)

  • v2.1.0(Oct 17, 2020)

    Changes since 2.0:

    • Added type hints on all major interfaces
    • Deprecated App.run
    • Deprecated string signals in favour of extensions.Signals
    • Removed libs.sanitizer
    • Use orjson for JSON serialization
    • Refactored request flow internals
    • Added namespaces to templater
    • Added SameSite support to session cookies
    • Added HTTP/2 support
    • Added Request.push_promise
    • Added Python 3.9 support (beta)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.2(Aug 30, 2020)

  • v2.0.1(Aug 11, 2020)

Owner
Emmett
Emmett
Python Wrapper for interacting with the Flutterwave API

Python Flutterwave Description Python Wrapper for interacting with the Flutterwa

William Otieno 32 Dec 14, 2022
Pyramid - A Python web framework

Pyramid Pyramid is a small, fast, down-to-earth, open source Python web framework. It makes real-world web application development and deployment more

Pylons Project 3.7k Dec 30, 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 01, 2023
FPS, fast pluggable server, is a framework designed to compose and run a web-server based on plugins.

FPS, fast pluggable server, is a framework designed to compose and run a web-server based on plugins. It is based on top of fastAPI, uvicorn, typer, and pluggy.

Adrien Delsalle 1 Nov 16, 2021
Embrace the APIs of the future. Hug aims to make developing APIs as simple as possible, but no simpler.

Read Latest Documentation - Browse GitHub Code Repository hug aims to make developing Python driven APIs as simple as possible, but no simpler. As a r

Hug API Framework 6.7k Dec 27, 2022
Otter is framework for creating microservices in Flask like fassion using RPC communication via message queue.

Otter Framework for microservices. Overview Otter is framework for creating microservices in Flask like fassion using RPC communication via message qu

Volodymyr Biloshytskyi 4 Mar 23, 2022
A library that makes consuming a RESTful API easier and more convenient

Slumber is a Python library that provides a convenient yet powerful object-oriented interface to ReSTful APIs. It acts as a wrapper around the excellent requests library and abstracts away the handli

Sam Giles 597 Dec 13, 2022
Fast, asynchronous and elegant Python web framework.

Warning: This project is being completely re-written. If you're curious about the progress, reach me on Slack. Vibora is a fast, asynchronous and eleg

vibora.io 5.7k Jan 08, 2023
PipeLayer is a lightweight Python pipeline framework

PipeLayer is a lightweight Python pipeline framework. Define a series of steps, and chain them together to create modular applications

greaterthan 64 Jul 21, 2022
Daniel Vaz Gaspar 4k Jan 08, 2023
Bromelia-hss implements an HSS by using the Python micro framework Bromélia.

Bromélia HSS bromelia-hss is the second official implementation of a Diameter-based protocol application by using the Python micro framework Bromélia.

henriquemr 7 Nov 02, 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

⚓ 0 Mar 05, 2022
A micro web-framework using asyncio coroutines and chained middleware.

Growler master ' dev Growler is a web framework built atop asyncio, the asynchronous library described in PEP 3156 and added to the standard library i

687 Nov 27, 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
Restful API framework wrapped around MongoEngine

Flask-MongoRest A Restful API framework wrapped around MongoEngine. Setup from flask import Flask from flask_mongoengine import MongoEngine from flask

Close 525 Jan 01, 2023
🦍 The Cloud-Native API Gateway

Kong or Kong API Gateway is a cloud-native, platform-agnostic, scalable API Gateway distinguished for its high performance and extensibility via plugi

Kong 33.8k Jan 09, 2023
Online Boutique is a cloud-native microservices demo application

Online Boutique is a cloud-native microservices demo application. Online Boutique consists of a 10-tier microservices application. The application is

Matt Reider 1 Oct 22, 2021
CherryPy is a pythonic, object-oriented HTTP framework. https://docs.cherrypy.org/

Welcome to the GitHub repository of CherryPy! CherryPy is a pythonic, object-oriented HTTP framework. It allows building web applications in much the

CherryPy 1.6k Dec 29, 2022
Fully featured framework for fast, easy and documented API development with Flask

Flask RestPlus IMPORTANT NOTICE: This project has been forked to Flask-RESTX and will be maintained by by the python-restx organization. Flask-RESTPlu

Axel H. 2.7k Jan 04, 2023
🔥 Fire up your API with this flamethrower

🔥 Fire up your API. Documentation: https://flama.perdy.io Flama Flama aims to bring a layer on top of Starlette to provide an easy to learn and fast

José Antonio Perdiguero 216 Dec 26, 2022