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
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
A python application to log QSOs directly to QRZ.com from the command line

qrzlogger This script is a QRZ.com command line QSO logger. It does the following: asks the user for a call sign displays available call sign info pul

Michael Clemens 15 Jul 16, 2021
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
FastAPI framework, high performance, easy to learn, fast to code, ready for production

FastAPI framework, high performance, easy to learn, fast to code, ready for production Documentation: https://fastapi.tiangolo.com Source Code: https:

Sebastián Ramírez 53k Jan 02, 2023
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support

Connexion Connexion is a framework that automagically handles HTTP requests based on OpenAPI Specification (formerly known as Swagger Spec) of your AP

Zalando SE 4.2k Jan 07, 2023
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 do

Flashbots 293 Dec 31, 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

5.8k Dec 30, 2022
NO LONGER MAINTAINED - A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.

NO LONGER MAINTAINED This repository is no longer maintained due to lack of time. You might check out the fork https://github.com/mrevutskyi/flask-res

1k Jan 04, 2023
News search API developed for the purposes of the ColdCase Project.

Saxion - Cold Case - News Search API Setup Local – Linux/MacOS Make sure you have python 3.9 and pip 21 installed. This project uses a MySQL database,

Dimitar Rangelov 3 Jul 01, 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
A Simple Kivy Greeting App

SimpleGreetingApp A Simple Kivy Greeting App This is a very simple GUI App that receives a name text input from the user and returns a "Hello" greetin

Mariya 40 Dec 02, 2022
The comprehensive WSGI web application library.

Werkzeug werkzeug German noun: "tool". Etymology: werk ("work"), zeug ("stuff") Werkzeug is a comprehensive WSGI web application library. It began as

The Pallets Projects 6.2k Jan 01, 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
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 05, 2023
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
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
Web APIs for Django. 🎸

Django REST framework Awesome web-browsable Web APIs. Full documentation for the project is available at https://www.django-rest-framework.org/. Fundi

Encode 24.7k Jan 03, 2023
A PC remote controller for YouTube and Twitch

Lazynite Lazynite is a PC remote controller for YouTube and Twitch on Telegram. Features Volume control; Browser fullscreen / video fullscreen; PC shu

Alessio Celentano 46 Nov 12, 2022
cirrina is an opinionated asynchronous web framework based on aiohttp

cirrina cirrina is an opinionated asynchronous web framework based on aiohttp. Features: HTTP Server Websocket Server JSON RPC Server Shared sessions

André Roth 32 Mar 05, 2022
A high-level framework for building GitHub applications in Python.

A high-level framework for building GitHub applications in Python. Core Features Async Proper ratelimit handling Handles interactions for you (

Vish M 3 Apr 12, 2022