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
Python AsyncIO data API to manage billions of resources

Introduction Please read the detailed docs This is the working project of the next generation Guillotina server based on asyncio. Dependencies Python

Plone Foundation 183 Nov 15, 2022
O SnakeG é um WSGI feito para suprir necessidadades de perfomance e segurança.

SnakeG O SnakeG é um WSGI feito para suprir necessidadades de perfomance e segurança. Veja o que o SnakeG possui: Multiprocessamento de requisições HT

Jaedson Silva 1 Jul 02, 2022
Python Wrapper for interacting with the Flutterwave API

Python Flutterwave Description Python Wrapper for interacting with the Flutterwa

William Otieno 32 Dec 14, 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
Sanic integration with Webargs

webargs-sanic Sanic integration with Webargs. Parsing and validating request arguments: headers, arguments, cookies, files, json, etc. IMPORTANT: From

Endurant Devs 13 Aug 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
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
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
A proof-of-concept CherryPy inspired Python micro framework

Varmkorv Varmkorv is a CherryPy inspired micro framework using Werkzeug. This is just a proof of concept. You are free to use it if you like, or find

Magnus Karlsson 1 Nov 22, 2021
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
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
Goblet is an easy-to-use framework that enables developers to quickly spin up fully featured REST APIs with python on GCP

GOBLET Goblet is a framework for writing serverless rest apis in python in google cloud. It allows you to quickly create and deploy python apis backed

Austen 78 Dec 27, 2022
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
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
Try to create a python mircoservice framework.

Micro current_status: prototype. ... Python microservice framework. More in Document. You should clone this project and run inv docs. Install Not now.

修昊 1 Dec 07, 2021
The little ASGI framework that shines. ?

✨ The little ASGI framework that shines. ✨ Documentation: https://www.starlette.io/ Community: https://discuss.encode.io/c/starlette Starlette Starlet

Encode 7.7k Jan 01, 2023
Free & open source Rest API for YTDislike

RestAPI Free & open source Rest API for YTDislike, read docs.ytdislike.com for implementing. Todo Add websockets Installation Git clone git clone http

1 Nov 25, 2021
Trame let you weave various components and technologies into a Web Application solely written in Python.

Trame Trame aims to be a framework for building interactive applications using a web front-end in plain Python. Such applications can be used locally

Kitware, Inc. 85 Dec 29, 2022
Quiz Web App with Flask and MongoDB as the Databases

quiz-app Quiz Web Application made with flask and mongodb as the Databases Before you run this application, change the inside MONGODB_URI ( in config.

gibran abdillah 7 Dec 14, 2022
Official mirror of https://gitlab.com/pgjones/quart

Quart Quart is an async Python web microframework. Using Quart you can, render and serve HTML templates, write (RESTful) JSON APIs, serve WebSockets,

Phil Jones 2 Oct 05, 2022