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
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Jan 8, 2023
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 16.7k Dec 28, 2022
Daniel Vaz Gaspar 4k Jan 8, 2023
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 4, 2023
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.5k Feb 17, 2021
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

null 2k Dec 31, 2022
Dazzler is a Python async UI/Web framework built with aiohttp and react.

Dazzler is a Python async UI/Web framework built with aiohttp and react. Create dazzling fast pages with a layout of Python components and bindings to update from the backend.

Philippe Duval 17 Oct 18, 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 2, 2021
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 8, 2023
bottle.py is a fast and simple micro-framework for python web-applications.

Bottle: Python Web Framework Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module a

Bottle Micro Web Framework 7.8k Dec 31, 2022
Fast⚡, simple and light💡weight ASGI micro🔬 web🌏-framework for Python🐍.

NanoASGI Asynchronous Python Web Framework NanoASGI is a fast ⚡ , simple and light ?? weight ASGI micro ?? web ?? -framework for Python ?? . It is dis

Kavindu Santhusa 8 Jun 16, 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 your app or losing its state.

 ⚓ 0 Mar 5, 2022
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
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
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

null 5.8k Dec 30, 2022
Loan qualifier app - Loan Qualifier Application Built With Python

Loan Qualifier Application This program is designed to automate the discovery pr

Phil Hills 1 Jan 4, 2022
Asita is a web application framework for python based on express-js framework.

Asita is a web application framework for python. It is designed to be easy to use and be more easy for javascript users to use python frameworks because it is based on express-js framework.

Mattéo 4 Nov 16, 2021
An alternative serializer implementation for REST framework written in cython built for speed.

drf-turbo An alternative serializer implementation for REST framework written in cython built for speed. Free software: MIT license Documentation: htt

Mng 74 Dec 30, 2022