Piccolo Admin provides a simple yet powerful admin interface on top of Piccolo tables

Overview

Logo

Piccolo Admin

Documentation Status

Piccolo Admin provides a simple yet powerful admin interface on top of Piccolo tables - allowing you to easily add / edit / filter your data.

Screenshot

It was created at a design agency to serve the needs of customers who demand a high quality, beautiful admin interface for their websites. Our goal is to create a world class admin interface, akin to Wordpress or Django.

It's built using the latest technologies, with Vue JS on the front end, and a modern REST backend.

Try it

Try it online (username: piccolo, password: piccolo123).

Local Demo

To run a demo locally, using Python 3.7 or above:

pip install piccolo_admin
admin_demo

And then just launch localhost:8000 in your browser.

To see what happens behind the scenes, see piccolo_admin/example.py.

In a few lines of code we are able to:

  • Define our models
  • Setup a database
  • Create a REST API
  • Setup a web server and admin interface

ASGI

Since the admin is an ASGI app, you can either run it standalone like in the demo, or integrate it with a larger ASGI app.

For example, using Starlette routes:

from piccolo_admin.endpoints import create_admin
from starlette.routing import Router, Route
import uvicorn

from my_project.tables import Director, Movie


# The `allowed_hosts` argument is required when running under HTTPS. It's used
# for additional CSRF defence.
admin = create_admin([Director, Movie], allowed_hosts=['my_site.com'])


router = Router([
    Route(path="/", endpoint=Hello),
    Mount(path="/admin/", app=admin),
])


if __name__ == '__main__':
    uvicorn.run(router)

Full docs

Full documentation is available on Read the docs.

Comments
  • Try `piccolo_admin` with Starlite

    Try `piccolo_admin` with Starlite

    It was reported that Piccolo Admin doesn't work with the Starlite framework.

    It should be possible to mount Piccolo Admin:

    https://starlite-api.github.io/starlite/usage/2-route-handlers/3-asgi-route-handlers/

    Tasks required:

    • [x] Try getting Piccolo admin working with Starlite
    • [x] If it doesn't work, try and work out why
    good first issue 
    opened by dantownsend 46
  • Implement TableConfig class

    Implement TableConfig class

    Currently, create_admin accepts a list of Table subclasses. This can be modified to accept either Table subclasses, or instances of a new class called TableConfig.

    TableConfig will be a dataclass which accepts a table argument, as well as a bunch of configuration options. For example:

    @dataclasses.dataclass
    class TableConfig:
        """
        :param list_columns:
            Used to specify which columns are shown on the list page. If None,
            all are shown.
        :param list_filters:
            Used to specify which filters are shown on the list page. If None,
            all are shown.
    
        """
        table: Type[Table]
        list_columns: Optional[List[Union[str, Column]] = None
        list_filters: Optional[List[Union[str, Column]] = None
        # Plus some additional options, which haven't been finalised.
        ...
    
    app = create_admin(
        tables=[
            SomeTable,
            TableConfig(
                table=MyTable,
                list_columns=[MyTable.name],
                list_filters=[MyTable.name]
            )
        ]
    )
    

    It will allow more fine grained control of the how the admin looks.

    enhancement medium priority proposal - input needed 
    opened by dantownsend 27
  • Automate running of Cypress tests

    Automate running of Cypress tests

    Now we have some basic Cypress tests, it is worth investigating how we can run these as part of GitHub actions.

    Cypress tests can be notoriously slow, so we might not want to run them on every commit - we will have to see what the performance is like.

    good first issue testing 
    opened by dantownsend 25
  • initial commit for migrate from Vue2 to Vue3

    initial commit for migrate from Vue2 to Vue3

    Based on #87. Work in progress

    • [x] fixing login process
    • [x] replacing deprecated features form Vue2 (Vue.set(), Vue.delete(), filters in template) with Vue3 features
    • [x] upgraded major library dependencies for working with Vue 3
    • [x] removing vue-json-excel and making our own implementation of CSV export
    • [x] fixing RowListing and CRUD
    • [x] fixing sorting and filtering
    • [x] fixing reference table search results
    • [x] added basic types
    • [x] custom forms
    • [x] fixing nullable fields
    • [x] TableConfig
    opened by sinisaos 24
  • add translations

    add translations

    Related to #173.

    Result is:

    https://user-images.githubusercontent.com/30960668/177712285-56767f52-468d-434e-a6b4-39e95edf6329.mp4

    To add a new translation, we just need to add a new json (eg. german.json) to assets/locales and update main.ts to register the new translation.

    opened by sinisaos 15
  • Make sure Piccolo admin works with custom primary key columns

    Make sure Piccolo admin works with custom primary key columns

    When using custom primary key columns, for example:

    class MyTable(Table):
        pk = UUID(primary_key=True)
    

    There are likely to be some edge cases not currently supported by Piccolo admin.

    enhancement high priority 
    opened by dantownsend 15
  • adding export to csv

    adding export to csv

    @dantownsend this is my try on exporting to csv. Probably it be slow for large and complex tables due to passing total number of rows to PiccoloCRUD __page_size param , but it's just idea.

    opened by sinisaos 14
  • File upload support

    File upload support

    Based on https://github.com/piccolo-orm/piccolo_admin/pull/182

    @sinisaos I've done a bunch of work on this.

    The main changes are:

    • Added extra security based on this OWASP doc
    • It now supports all kinds of files - e.g. video as well
    • Added a media preview window, so the user can see the full sized image or video within Piccolo Admin
    • Array, Varchar, and Text columns can all be used as media columns

    You can see the changes here:

    https://user-images.githubusercontent.com/350976/181996743-17dae1d0-8b13-42de-89c0-b16c5643997b.mp4

    The biggest change from the original PR is it saves a unique identifier for the file in the database, rather than the URL. There are two reasons for this:

    • If the user decides to host their media files somewhere else, they don't have to update anything in the database.
    • It's the only way to get it working with S3. Each time someone accesses a file in S3 we need to generate a signed URL, which is only valid for a short period of time, so we can't store the URL in the database.

    I think it's about 80% done. It's a massive feature, but a really cool one.

    Things that need doing still:

    • [x] Update the docs
    • [ ] I need to add your file upload button back - it looks nicer than what's there now
    • [x] Add links on the row detail page for viewing images
    • [x] Maybe add S3 support, so we know the API works properly with it before releasing it
    • [x] The media is always served from /api/media-files/ at the moment. It's ignoring the media_url setting in LocalStorage. That needs some thinking about.
    • [x] We used to have media_columns and media_storage arguments in TableConfig. I changed it slightly (now there's just media_columns, which maps a column to a MediaStorage) because I can imagine use cases where you want some columns to store files in one place, and other columns to store files in another place. Also, you might only allow images in some columns, and videos in other columns. It still needs a bit of thinking about.
    • [x] I might move a bunch of the logic to Piccolo API, so it can also be used with PiccoloCRUD standalone.

    I removed your image previews from RowListing.vue for now. I liked the way they looked, but because we're not creating thumbnails for the images, if the page is showing 100 rows, it will pull down 100 full sizes images, which would slow things down too much. Once we work out thumbnails I would like to add it back.

    enhancement 
    opened by dantownsend 11
  • Wysiwyg editor

    Wysiwyg editor

    @dantownsend are you perhaps interested in adding wysiwyg editor to textarea fields?

    https://user-images.githubusercontent.com/30960668/158114813-3fa9b405-e87e-438e-84a1-5a2395cc145e.mov

    enhancement 
    opened by sinisaos 10
  • `TableConfig` media handlers

    `TableConfig` media handlers

    This is a big task, but unlocks a lot of great functionality in the admin.

    Piccolo doesn't have a particular column type for storing media (images, video etc). It's possible to store them in binary columns, but this is generally frowned upon as it quickly leads to database bloat (and database storage is typically much more expensive than object storage).

    The usual approach for storing media is to put the file in object storage (like S3), or in a local directory, and store a reference to it in the database (for example a URL or path).

    Initially we can just store the media files in a local directory, but supporting the S3 protocol would be great in the future.

    The steps required to implement this:

    MediaHandler class

    # This is just an abstract base class for all other media handlers:
    class MediaHandler:
        pass
    
    @dataclass
    class LocalMediaHandler(MediaHandler):
        root_path: str
    
        def store_file(self, file):
            ...
    
        def retrieve_file(self, path: str):
            ...
    

    TableConfig changes

    media_handler = LocalMediaHandler(root_path='/var/www/files/')
    
    app = create_admin(
        TableConfig(
            Movie,
            media_handler=media_handler,
            media_columns=[Movie.poster]
        )
    )
    

    PiccoloCRUD changes

    There will be a new endpoint, something like:

    /tables/director/1/media?column=poster
    

    Which can be used to retrieve the actual media file.

    UI improvements

    The UI will know if a column is used for media storage by inspecting the JSON schema:

    /api/tables/director/schema
    

    PiccoloCRUD would've added an extra field to it called 'media_columns', using create_pydantic_model's schema_extra_kwargs feature.

    The UI would then render a file upload box for that field. In the future we could support simple editing functionality like cropping images (there are several JS libraries for this), but that's down the road.

    enhancement proposal - input needed 
    opened by dantownsend 10
  • Add custom widget for Interval fields

    Add custom widget for Interval fields

    Any Interval fields are shown as text boxes, where you input a number of seconds. It works fine, but could be more user friendly.

    The schema for a table with an Interval column looks like this (accessible via /api/tables/my_table/schema).

    {
        "title": "MyTableIn",
        "type": "object",
        "properties": {
            "interval": {
                "title": "Interval",
                "extra": {},
                "nullable": false,
                "type": "number",
                "format": "time-delta"
            }
        }
    }
    

    We can tell if it's an Interval from the format field in the schema, which is "time-delta".

    enhancement 
    opened by dantownsend 10
  • Cannot edit non-default primary key in admin

    Cannot edit non-default primary key in admin

    Hi,

    I have a model where a PK is defined on an explicit Varchar field, like this

    class MyModel(Table):
        identifier = columns.Varchar(length=64, primary_key=True)
       .....  other fields .....
    

    It's entirely on purpose. I don't want the PK to be an auto-incremented integer. I want a random string as PK. ORM allows for that, which is good.

    The problem is trying to add those objects via admin. Admin UI does not show any textbox to enter the PK value and it is not possible to add those objects.

    Apparently admin assumes that primary key column is always an auto-incremented integer. But ORM allows to have PK on non-int non-incrementable column.

    Any advice how to work around this problem?

    opened by PawelRoman 5
  • datetime picker doesn't support minute granularity

    datetime picker doesn't support minute granularity

    I've created a table entry like this: expiry = Timestamptz(null=True)

    A few things I'm noticing in piccolo-admin

    • it's not possible for the datetime to be None, piccolo-admin always suggests the current time/date
    • the datetime picker uses a 12-hour (pm/am) type clock. It would be nice if that was configurable for "non-US" users

    I'd really like it to be possible to disable the datetime picker altogether and have users type in a datetime string instead, with the option of having the field empty (indicating None) too.

    opened by trondhindenes 3
  • allow BYO auth backend

    allow BYO auth backend

    Allows replacing the built-in auth backend with a custom one.

    This allowed me to do:

    class HackyAuthUser(BaseUser):
        def __init__(self, user_id: str = 'unknown', display_name: str = 'unknown'):
            self._user_id = user_id
            self._display_name = display_name
    
        @property
        def is_authenticated(self) -> bool:
            return True
    
        @property
        def display_name(self) -> str:
            return self._display_name
    
        @property
        def user_id(self) -> str:
            return self._user_id
    
    
    class HackyAuthBackend(AuthenticationBackend):
        def __init__(self, header_name):
            self.header_name = header_name
    
        async def authenticate(self, conn):
            if self.header_name not in conn.headers:
                raise AuthenticationError('Invalid credentials')
            user_name = conn.headers[self.header_name]
            return AuthCredentials(scopes=[]), HackyAuthUser(user_name, user_name)
    
    
    app = FastAPI(
        routes=[
            Mount('/admin/', create_admin(
                tables=APP_CONFIG.table_classes,
                auth_backend=HackyAuthBackend(header_name='Authorization'))
                  ),
        ],
    )
    

    It would be cool if it was somehow possible to override the default "non-authenticated" behavior, and for example have admin-api redirect the user to another login url instead of the built-in one, but I didn't find a clean way to do that.

    opened by trondhindenes 0
  • allow completely disabling built-in auth

    allow completely disabling built-in auth

    Hi, We're looking to use piccolo-admin in a project, but we want to plug in our internal auth mechanisms, which we typically use together with oauth-proxy to wrap 3rd party apps in our auth layer.

    Because of this, I'd like to use piccolo-admin but without any of the built-in authz/authn functionality. I'd like piccolo-admin to simply assume that every request comes from an admin users (we'll ofc handle authz/authn outside piccolo-admin).

    I haven't yet looked at the code, but it would be interesting to hear of something like this is already supported or planned. From what I can see from the create_admin 's parameters there doesn't seem to be any obvious way of achieving what I want today.

    opened by trondhindenes 7
  • When the id field is hidden in TableConfig, there is no way to edit a record

    When the id field is hidden in TableConfig, there is no way to edit a record

    So we have an UUID primary keys and want to hide them in admin, but that's happens:

    image

    It would be cool if the record link field was parameterized in TableConfig

    opened by metakot 11
Releases(0.39.0)
  • 0.39.0(Dec 7, 2022)

    If an Array column has choices specified, then Piccolo Admin will show dropdowns, so the user can pick one of the choices.

    206292810-23b47d29-ff7f-4d04-8c70-fd5c8d790629

    Thanks to @sinisaos for help testing it.

    Source code(tar.gz)
    Source code(zip)
  • 0.38.0(Nov 18, 2022)

  • 0.37.0(Nov 16, 2022)

    • Python 3.11 is now officially supported.
    • Added debug mode: create_admin(tables=[MyTable], debug=True).
    • Logging exceptions for 500 errors.
    • Fixed a typo in the docs about how to use validators (thanks to @sinisaos for reporting this).
    • Updated the tests for Starlette / FastAPI's new test client. This means that fastapi==0.87.0 / starlette==0.21.0 are now the minimum versions supported. Thanks to @sinisaos for this.
    Source code(tar.gz)
    Source code(zip)
  • 0.36.0(Nov 11, 2022)

    Lots of small enhancements.

    • Fixed bugs with the foreign key selector. Sometimes the edit button didn't work. Also, sometimes the value shown in the input box wasn't refreshing when navigating to a new page.
    • The HTML title now matches the site_name parameter in create_admin (thanks to @sinisaos for this).
    • Updated Vue to the latest version.
    • Internal code refactoring.
    Source code(tar.gz)
    Source code(zip)
  • 0.35.0(Oct 14, 2022)

    Validators can now be specified in TableConfig.

    This allows fine grained access control - for example, only allowing some users to send POST requests to certain API endpoints:

    from piccolo_api.crud.endpoints import PiccoloCRUD
    from starlette.exceptions import HTTPException
    from starlette.requests import Request
    
    
    async def manager_only(
        piccolo_crud: PiccoloCRUD,
        request: Request
    ):
        # The Piccolo `BaseUser` can be accessed from the request.
        user = request.user.user
    
        # Assuming we have another database table where we record
        # users with certain permissions.
        manager = await Manager.exists().where(manager.user == user)
    
        if not manager:
            # Raise a Starlette exception if we want to reject the
            # request.
            raise HTTPException(
                status_code=403,
                detail="Only managers are allowed to do this"
            )
    
    
    admin = create_admin(
        tables=TableConfig(
            Movie,
            validators=Validators(post_single=manager_only)
        )
    )
    
    Source code(tar.gz)
    Source code(zip)
  • 0.34.0(Oct 11, 2022)

  • 0.33.1(Sep 14, 2022)

  • 0.33.0(Sep 8, 2022)

  • 0.32.0(Sep 8, 2022)

    Camelcase column names could break parts of Piccolo Admin. It now works as expected:

    class Person(Table):
        # This now works:
        firstName = Varchar()
    

    Even though camelcase is unusual in Python, a user may be using an existing database, so it makes sense to support it. Thanks to @sumitsharansatsangi for reporting this issue.

    Source code(tar.gz)
    Source code(zip)
  • 0.31.2(Sep 5, 2022)

    When piccolo_admin is installed, an admin_demo script is made available on the command line, which launches a Piccolo Admin demo.

    It wasn't working due to a missing folder, which has now been fixed.

    Source code(tar.gz)
    Source code(zip)
  • 0.31.1(Aug 29, 2022)

  • 0.31.0(Aug 29, 2022)

  • 0.30.0(Aug 28, 2022)

  • 0.29.1(Aug 11, 2022)

    The media endpoints now obey the read_only option of create_admin. Read only mode is used for online demos.

    Thanks to @sinisaos for adding this.

    Source code(tar.gz)
    Source code(zip)
  • 0.29.0(Aug 6, 2022)

    Added media upload support - to both a local folder, and S3.

    Images, videos, PDFs, and audio files can be viewed within the UI.

    This is the one of the biggest updates we've ever made, and are excited to share!

    media_viewer_image

    Thanks to @sinisaos for all of the help.

    Source code(tar.gz)
    Source code(zip)
  • 0.28.0(Jul 29, 2022)

  • 0.27.0(Jul 27, 2022)

  • 0.26.1(Jul 25, 2022)

A minimalistic example of preparing a model for (synchronous) inference in production.

A minimalistic example of preparing a model for (synchronous) inference in production.

Anton Lozhkov 6 Nov 29, 2021
Adds integration of the Jinja template language to FastAPI.

fastapi-jinja Adds integration of the Jinja template language to FastAPI. This is inspired and based off fastapi-chamelon by Mike Kennedy. Check that

Marc Brooks 58 Nov 29, 2022
基于Pytorch的脚手架项目,Celery+FastAPI+Gunicorn+Nginx+Supervisor实现服务部署,支持Docker发布

cookiecutter-pytorch-fastapi 基于Pytorch的 脚手架项目 按规范添加推理函数即可实现Celery+FastAPI+Gunicorn+Nginx+Supervisor+Docker的快速部署 Requirements Python = 3.6 with pip in

17 Dec 23, 2022
a lightweight web framework based on fastapi

start-fastapi Version 2021, based on FastAPI, an easy-to-use web app developed upon Starlette Framework Version 2020 中文文档 Requirements python 3.6+ (fo

HiKari 71 Dec 30, 2022
Lung Segmentation with fastapi

Lung Segmentation with fastapi This app uses FastAPI as backend. Usage for app.py First install required libraries by running: pip install -r requirem

Pejman Samadi 0 Sep 20, 2022
A complete end-to-end machine learning portal that covers processes starting from model training to the model predicting results using FastAPI.

Machine Learning Portal Goal Application Workflow Process Design Live Project Goal A complete end-to-end machine learning portal that covers processes

Shreyas K 39 Nov 24, 2022
FastAPI + Django experiment

django-fastapi-example This is an experiment to demonstrate one potential way of running FastAPI with Django. It won't be actively maintained. If you'

Jordan Eremieff 78 Jan 03, 2023
Basic FastAPI starter with GraphQL, Docker, and MongoDB configurations.

FastAPI + GraphQL Starter A python starter project using FastAPI and GraphQL. This project leverages docker for containerization and provides the scri

Cloud Bytes Collection 1 Nov 24, 2022
Example of using FastAPI and MongoDB database.

FastAPI Todo Application Example of using FastAPI and MangoDB database. 💡 Prerequisites Python ⚙️ Build & Run The first thing to do is to clone the r

Bobynets Ivan 1 Oct 29, 2021
Monitor Python applications using Spring Boot Admin

Pyctuator Monitor Python web apps using Spring Boot Admin. Pyctuator supports Flask, FastAPI, aiohttp and Tornado. Django support is planned as well.

SolarEdge Technologies 145 Dec 28, 2022
Backend, modern REST API for obtaining match and odds data crawled from multiple sites. Using FastAPI, MongoDB as database, Motor as async MongoDB client, Scrapy as crawler and Docker.

Introduction Apiestas is a project composed of a backend powered by the awesome framework FastAPI and a crawler powered by Scrapy. This project has fo

Fran Lozano 54 Dec 13, 2022
A simple api written in python/fastapi that serves movies from a cassandra table.

A simple api written in python/fastapi that serves movies from a cassandra table. 1)clone the repo 2)rename sample_global_config_.py to global_config.

Sreeraj 1 Aug 26, 2021
Online Repo Browser

MSYS2 Web Interface A simple web interface for browsing the MSYS2 repos. Rebuild CSS/JS (optional): cd frontend npm install npm run build Run for Dev

MSYS2 64 Dec 30, 2022
[rewrite 중] 코로나바이러스감염증-19(COVID-19)의 국내/국외 발생 동향 조회 API | Coronavirus Infectious Disease-19 (COVID-19) outbreak trend inquiry API

COVID-19API 코로나 바이러스 감염증-19(COVID-19, SARS-CoV-2)의 국내/외 발생 동향 조회 API Corona Virus Infectious Disease-19 (COVID-19, SARS-CoV-2) outbreak trend inquiry

Euiseo Cha 28 Oct 29, 2022
EML analyzer is an application to analyze the EML file

EML analyzer EML analyzer is an application to analyze the EML file which can: Analyze headers. Analyze bodies. Extract IOCs (URLs, domains, IP addres

Manabu Niseki 162 Dec 28, 2022
Async and Sync wrapper client around httpx, fastapi, date stuff

lazyapi Async and Sync wrapper client around httpx, fastapi, and datetime stuff. Motivation This library is forked from an internal project that works

2 Apr 19, 2022
A Nepali Dictionary API made using FastAPI.

Nepali Dictionary API A Nepali dictionary api created using Fast API and inspired from https://github.com/nirooj56/Nepdict. You can say this is just t

Nishant Sapkota 4 Mar 18, 2022
All of the ad-hoc things you're doing to manage incidents today, done for you, and much more!

About What's Dispatch? Put simply, Dispatch is: All of the ad-hoc things you’re doing to manage incidents today, done for you, and a bunch of other th

Netflix, Inc. 3.7k Jan 05, 2023
volunteer-database

This is the official CSM (Crowd source medical) database The What Now? We created this in light of the COVID-19 pandemic to allow volunteers to work t

32 Jun 21, 2022
row level security for FastAPI framework

Row Level Permissions for FastAPI While trying out the excellent FastApi framework there was one peace missing for me: an easy, declarative way to def

Holger Frey 315 Dec 25, 2022