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
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
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
Dockerized web application on Starlite, SQLAlchemy1.4, PostgreSQL

Production-ready dockerized async REST API on Starlite with SQLAlchemy and PostgreSQL

Artur Shiriev 10 Jan 03, 2023
Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints.

Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints. check parameters and generate API documents automatically. Flask Sugar是一个基于flask,pyddantic,类型注解的API框架

162 Dec 26, 2022
Django Ninja - Fast Django REST Framework

Django Ninja is a web framework for building APIs with Django and Python 3.6+ type hints.

Vitaliy Kucheryaviy 3.8k Jan 02, 2023
A simple Tornado based framework designed to accelerate web service development

Toto Toto is a small framework intended to accelerate web service development. It is built on top of Tornado and can currently use MySQL, MongoDB, Pos

Jeremy Olmsted-Thompson 61 Apr 06, 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
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
An easy-to-use high-performance asynchronous web framework.

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

Aber 264 Dec 31, 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
Mini Web Framework on MicroPython (Esp8266)

dupgee Dupgee is a mini web framework developed for micro-python(Tested on esp8266). Installation pip install dupgee Create Project dupgee create newp

ahmet kotan 38 Jul 25, 2022
Appier is an object-oriented Python web framework built for super fast app development.

Joyful Python Web App development Appier is an object-oriented Python web framework built for super fast app development. It's as lightweight as possi

Hive Solutions 122 Dec 22, 2022
Python implementation of the Javascript Object Signing and Encryption (JOSE) framework

Python implementation of the Javascript Object Signing and Encryption (JOSE) framework

Demonware 94 Nov 20, 2022
A beginners course for Django

The Definitive Django Learning Platform. Getting started with Django This is the code from the course "Getting Started With Django", found on YouTube

JustDjango 288 Jan 08, 2023
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
Microservice example with Python, Faust-Streaming and Kafka (Redpanda)

Microservices Orchestration with Python, Faust-Streaming and Kafka (Redpanda) Example project for PythonBenin meetup. It demonstrates how to use Faust

Lé 3 Jun 13, 2022
Cses2humio - CrowdStrike Falcon Event Stream to Humio

CrowdStrike Falcon Event Stream to Humio This project intend to provide a simple

Trifork.Security 6 Aug 02, 2022
Flask like web framework for AWS Lambda

lambdarest Python routing mini-framework for AWS Lambda with optional JSON-schema validation. ⚠️ A user study is currently happening here, and your op

sloev / Johannes Valbjørn 91 Nov 10, 2022
Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs

chisel Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs. Here are its fea

Craig Hobbs 2 Dec 02, 2021
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