Appier is an object-oriented Python web framework built for super fast app development.

Overview

Appier Framework

Joyful Python Web App development

Appier is an object-oriented Python web framework built for super fast app development. It's as lightweight as possible, but not too lightweight. It gives you the power of bigger frameworks, without their complexity.

Your first app can be just a few lines long:

import appier

class HelloApp(appier.App):

    @appier.route("/", "GET")
    def hello(self):
        return "Hello World"

HelloApp().serve()

The same app using the async/await syntax (Python 3.5+) for async execution reads pretty much the same:

import appier

class HelloApp(appier.App):

    @appier.route("/", "GET")
    async def hello(self):
        await self.send("Hello World")

HelloApp().serve()

Running it is just as simple:

pip install appier
python hello.py

For the async version an ASGI compliant server should be used (eg: Uvicorn):

SERVER=uvicorn python hello.py

Your "Hello World" app is now running at http://localhost:8080.

It features the following:

  • Object-oriented
  • WSGI (Web Server Gateway Interface) compliant
  • ASGI (Asynchronous Server Gateway Interface) ready
  • Modular, using dynamically loaded parts
  • Python 3 compatible
  • RESTful request dispatching
  • Asynchronous request handling support
  • Templating, using Jinja2
  • Data model layer, currently supports MongoDB and TinyDB
  • Automatic JSON response encoding for fast API development
  • Automatic admin interface, using Appier Extras
  • Internationalization (i18n) support
  • Flexible project configuration
  • Out-of-the-box support for multiple WSGI and ASGI servers: Netius, Uvicorn, Hypercorn, Daphne, etc.

For the purposes of rapid web development, Appier goes well with Netius (web server) and UXF (client side graphical library) as a whole stack.

Learn more

Basic

Advanced

  • Events - how to send information across the app
  • Logging - how to log your app's activity
  • Email - how to send emails

License

Appier is currently licensed under the Apache License, Version 2.0.

Build Automation

Build Status Build Status GitHub Coverage Status PyPi Status License

Comments
  • Removed dot from route replace regex

    Removed dot from route replace regex

    | - | - | | --- | --- | | Issue | There was a problem in the route parsing and regex replacement. For example, with the following route endpoints /api/builds/<str:name>/fonts/<str:font>.<str:format> the font and format are wrongly extracted, where the parameter SRGunmetal-Regular.fnt results in font: SRGunmetal-Regular.f and format: t. | | Dependencies | -- | | Decisions | Removed the . from the REPLACE_REGEX. All other routes with dots are working as supposed and the route mentiond above as well. | | Animated GIF | -- |

    enhancement wontfix 
    opened by BeeMargarida 6
  • Added fix for postprocessing CSR

    Added fix for postprocessing CSR

    Newer features for client-side-rendering require the loading of "blob:" scripts for anti-aliasing purposes, this prevents browser from blocking the necessary requests.

    opened by veryprofessionaldodo 5
  • feat: allow casting fields from strings to dicts

    feat: allow casting fields from strings to dicts

    Useful when dealing with non-JSON endpoints, such as file upload.

    Based on https://github.com/hivesolutions/appier/blob/1470c427a760fb698e423bbbfdad53a29578279e/src/appier/model.py#L72

    opened by gcandal 4
  • Add AMQPExchange and support AMQPQueue binding to an exchange

    Add AMQPExchange and support AMQPQueue binding to an exchange

    Issue: https://github.com/ripe-tech/ripe-compose/issues/68

    This PR:

    • adds an AMQPExchange class that abstracts a connection to a RabbitMQ exchange
    • an exchange belongs to a cluster, not a single node; hence, this class accepts a list of broker URLs; if the connection to one fails, it attempts to connect to the rest; if all brokers fail, this class will attempt to reconnect forever (but such a catastrophic failure will likely require a cluster reset regardless)
    • changes AMQPQueue class to accept an optional exchange name and routing key; if present, it binds the queue to that exchange using that routing key
    enhancement p-medium risky ❕ 
    opened by joao-conde 4
  • feat: converts the filters passed before executing the `count` operation

    feat: converts the filters passed before executing the `count` operation

    Support for parsing and converting the kwargs of count function, similar to the logic present in find. This is required if we want to use the same filtering logic for counting as the one we have for listing.

    opened by BeeMargarida 3
  • feat: graph module and priority queue Dijkstra implementation

    feat: graph module and priority queue Dijkstra implementation

    This relates to the RIPE Tech issue of multiple state transitions.

    For RIPE Tech, we will need to find the shortest path between two states and make all the in-between transitions. Instead of a bespoke solution for order states only, I thought it was better to generalize the issue at hand: finding the shortest path in the graph. Hence I decided to implement a simple Dijkstra. This will allow us to abstract that logic here and simply apply the transitions in RIPE Core. It will also work for future entities with their own states and state graphs (while a bespoke solution for Order statuses only would not).

    I think this source makes sense to be added to the Appier codebase because a graph module and graph utilities by themselves are useful in many domains (maybe in the future in networking to find the shortest path between nodes).

    The proposed and implemented API is:

    import appier
    
    # a list of edges which is a list of tuples
    # where the first element is the source node
    # the second element is the destination node
    # the third element is the cost of the edge (defaults to 1)
    # the fourth element indicates whether the edge is bidirectional or not (defaults to unidirectional)
    edges = [
        ("A", "B"),
        ("A", "C", 6, True),
        ("B", "D"),
        ("C", "D"),
        ("D", "E", 10),
        ("D", "F", 15),
        ("E", "F", 6),
        ("E", "G", 2),
        ("F", "G", 6)
    ]
    graph = appier.Graph()
    graph.add_edges(edges)
    
    path, cost = graph.dijkstra("A", "F")
    assert(path == ['A', 'B', 'D', 'F'])
    assert(cost == 17)
    

    Initializing the graph can also be done by passing the edges as an argument:

    graph = appier.Graph([
        ("A", "B"),
        ("A", "C", 6, True),
        ("B", "D"),
        ("C", "D"),
        ("D", "E", 10),
        ("D", "F", 15),
        ("E", "F", 6),
        ("E", "G", 2),
        ("F", "G", 6)
    ])
    
    opened by joao-conde 3
  • Fix pymongo version parsing

    Fix pymongo version parsing

    Issue:

    Pymongo released version 4.0 on november 29 2021 and unlike the others version, this one doesn't event the patch number so as appier is assuming that pymongo will have a patch number, it fails to unpack that value and an error is thrown. imagem imagem

    Replicating the issue:

    imagem

    Testing the fix:

    imagem
    opened by NFSS10 3
  • feat: apply orientation exif info on image after resize

    feat: apply orientation exif info on image after resize

    | - | - | | --- | --- | | Issue | https://github.com/ripe-tech/ripe-id-mobile/issues/2#issuecomment-884831078
    When providing an image with EXIF Orientation info, it was being ignored in the final image (after resize). | | Decisions | - Use PIL.ImageOps method exif_transpose that returns an image transposed according to its EXIF orientation tag. | | Screenshots | Original Image:
    IMG_20210722_111143
    Before:
    image
    After:
    image |

    opened by BeeMargarida 3
  • Support for extending Appier sessions

    Support for extending Appier sessions

    Description

    There seems to be no friendly way of extending an Appier session. In some contexts, it's desirable to be able to extend the session indefinitely.

    Solution

    The expiration date is being set when the session object is being created. This date can be changed only by accessing the internal property directly. Probably there should be an refresh() method to easily refresh the session's expiration date (current date + default timeout).

    Also, in RedisSession values are being stored with SETEX, therefore they are deleted by Redis when the timeout is reached. To extend the session in RedisSession, the value's expiration date must be extended using the EXPIRE command to provide a new timeout.

    enhancement p-medium 
    opened by tsilva 3
  • Appier can't fill unpersisted models with relations

    Appier can't fill unpersisted models with relations

    Description

    Calling new() on a model with relations causes an error like the following:

    AttributeError
    
    500 - 'module' object has no attribute 'Wishlist'
    Traceback (most recent call last):
    File "/repo.extra/appier/src/appier/base.py", line 803, in application_l
    result = self.handle()
    File "/repo.extra/appier/src/appier/base.py", line 931, in handle
    else: result = self.route()
    File "/repo.extra/appier/src/appier/base.py", line 1159, in route
    else: return_v = method_i(*args, **kwargs)
    File "/repo.extra/myswear/src/myswear/controllers/web/base.py", line 104, in do_signup
    user = sadapters.models.User.new()
    File "/repo.extra/appier/src/appier/model.py", line 354, in new
    if fill: model = cls.fill(model)
    File "/repo.extra/appier/src/appier/model.py", line 970, in fill
    default = _type._default() if hasattr(_type, "_default") else default
    File "/repo.extra/appier/src/appier/typesf.py", line 424, in _default
    return cls(None)
    File "/repo.extra/appier/src/appier/typesf.py", line 373, in __init__
    self.__start__()
    File "/repo.extra/appier/src/appier/typesf.py", line 417, in __start__
    if is_reference: self._target = self.__class__._target()
    File "/repo.extra/appier/src/appier/typesf.py", line 428, in _target
    if is_reference: return getattr(common.base().APP.models_i, target)
    AttributeError: 'module' object has no attribute 'Wishlist'
    
    bug p-high 
    opened by tsilva 3
  • fix: Dijkstra's implementation for no path found

    fix: Dijkstra's implementation for no path found

    Previous implementation threw a KeyError.

    This PR adds a unit test covering the no path case and changes it to return no path and infinity for the cost ([], INFINITY).

    It also places INFINITY in a common place (defines.py) to be used both by tests and graph module code.

    bug fast-track 
    opened by joao-conde 2
  • Request Limit

    Request Limit

    Description

    It's important to have a mechanism that allows control of the number of requests per time unit. This will provide a way to control an unintentional (or intentional) DOS.

    Implementation

    Create a decorator appier.requests that receives the number of requests per minute allowed for the action method in the controller.

    The implementation should take inspiration from PreflightPart.

    Inspiration

    enhancement p-medium 
    opened by joamag 0
  • Support for ACL gathering

    Support for ACL gathering

    Description

    It should be possible by using code to gather the complete set of ACL tokens that are registered for the currently running application. This way it would be possible to list the complete set of possible permission for the running application context.

    Implementation

    Should be possible to use appier.get_tokens() to retrieve the complete set of ACL tokens and action methods (from controllers) associated with them.

    enhancement p-high 
    opened by joamag 0
  • Instances auto-discovery (multicast)

    Instances auto-discovery (multicast)

    Description

    By using multicast UDP it would be possible to discover other services with the same INSTANCE values and start communicating with them for certain puposes.

    Election system to determine the one that is considered the master.

    For instance it should be possible to discover a configuration server that way, or for Ripe discover the proper composer instance in the current network and auto-configure it.

    References

    https://docs.mongodb.com/manual/core/replica-set-elections/

    enhancement p-medium 
    opened by joamag 0
  • Datbase migration infra-structure

    Datbase migration infra-structure

    Description

    It should be really cool to create a migration infra-structure like the one present in Migratore.

    Description

    The idea is to build an infra-structure that is agnostic from the underlying database manager used.

    enhancement p-low 
    opened by joamag 0
  • Async support for database access layer (eg: Mongo)

    Async support for database access layer (eg: Mongo)

    Description

    Using a pool of threads and the Future based abstraction it should be possible to adapt the current data layer access to an async fashion.

    PyMongo with callback support.

    References

    https://motor.readthedocs.io/en/latest/examples/callbacks-and-coroutines.html#with-coroutines

    enhancement p-low 
    opened by joamag 0
  • Task abstraction for async execution control unit

    Task abstraction for async execution control unit

    Description

    Sometimes it's important to have a proper abstraction for a working unit inside an abstraction system.

    Having per example a DownloadTask that allows the downloading of an HTTP based asset and that properly notifies any listening handler should be the aim of this operation.

    example

    Implementation

    Create the Task class abstraction and then use the websocket infra-structure to make Appier Admin control all of these tasks.

    There should be some co-relation between this Task class and the Future class.

    References

    socket.io chat example

    enhancement p-medium 
    opened by joamag 0
Releases(0.9.70)
Owner
Hive Solutions
Next-generation software boutique, built by perfectionists
Hive Solutions
An easy-to-use high-performance asynchronous web framework.

中文 | English 一个易用的高性能异步 web 框架。 Index.py 文档 Index.py 实现了 ASGI3 接口,并使用 Radix Tree 进行路由查找。是最快的 Python web 框架之一。一切特性都服务于快速开发高性能的 Web 服务。 大量正确的类型注释 灵活且高效的

Index.py 264 Dec 31, 2022
Web framework based on type hint。

Hint API 中文 | English 基于 Type hint 的 Web 框架 hintapi 文档 hintapi 实现了 WSGI 接口,并使用 Radix Tree 进行路由查找。是最快的 Python web 框架之一。一切特性都服务于快速开发高性能的 Web 服务。 大量正确的类型

Aber 19 Dec 02, 2022
An easy-to-use high-performance asynchronous web framework.

An easy-to-use high-performance asynchronous web framework.

Aber 264 Dec 31, 2022
Sierra is a lightweight Python framework for building and integrating web applications

A lightweight Python framework for building and Integrating Web Applications. Sierra is a Python3 library for building and integrating web applications with HTML and CSS using simple enough syntax. Y

83 Sep 23, 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
Developer centric, performant and extensible Python ASGI framework

Introduction xpresso is an ASGI web framework built on top of Starlette, Pydantic and di, with heavy inspiration from FastAPI. Some of the standout fe

Adrian Garcia Badaracco 119 Dec 27, 2022
Bablyon 🐍 A small ASGI web framework

A small ASGI web framework that you can make asynchronous web applications using uvicorn with using few lines of code

xArty 8 Dec 07, 2021
A tool for quickly creating REST/HATEOAS/Hypermedia APIs in python

ripozo Ripozo is a tool for building RESTful/HATEOAS/Hypermedia apis. It provides strong, simple, and fully qualified linking between resources, the a

Vertical Knowledge 198 Jan 07, 2023
Klein - A micro-framework for developing production-ready web services with Python

Klein, a Web Micro-Framework Klein is a micro-framework for developing production-ready web services with Python. It is 'micro' in that it has an incr

Twisted Matrix Labs 814 Jan 08, 2023
Flask-Potion is a RESTful API framework for Flask and SQLAlchemy, Peewee or MongoEngine

Flask-Potion Description Flask-Potion is a powerful Flask extension for building RESTful JSON APIs. Potion features include validation, model resource

DTU Biosustain 491 Dec 08, 2022
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is done by also creating a middleware which captures c

Georgios Konstantopoulos 294 Jan 04, 2023
Endpoints is a lightweight REST api framework written in python and used in multiple production systems that handle millions of requests daily.

Endpoints Quickest API builder in the West! Endpoints is a lightweight REST api framework written in python and used in multiple production systems th

Jay Marcyes 30 Mar 05, 2022
The core of a service layer that integrates with the Pyramid Web Framework.

pyramid_services The core of a service layer that integrates with the Pyramid Web Framework. pyramid_services defines a pattern and helper methods for

Michael Merickel 78 Apr 15, 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
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

20.9k Jan 01, 2023
A comprehensive reference for all topics related to building and maintaining microservices

This pandect (πανδέκτης is Ancient Greek for encyclopedia) was created to help you find and understand almost anything related to Microservices that i

Ivan Bilan 64 Dec 09, 2022
A shopping list and kitchen inventory management app.

Flask React Project This is the backend for the Flask React project. Getting started Clone this repository (only this branch) git clone https://github

11 Jun 03, 2022
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
A simple todo app using flask and sqlachemy

TODO app This is a simple TODO app made using Flask. Packages used: DoodleCSS Special thanks to Chris McCormick (@mccrmx) :) Flask Flask-SQLAlchemy Fl

Lenin 1 Dec 26, 2021
A framework that let's you compose websites in Python with ease!

Perry Perry = A framework that let's you compose websites in Python with ease! Perry works similar to Qt and Flutter, allowing you to create componen

Linkus 13 Oct 09, 2022