Piccolo API
repository·master·Indexed 41 days ago
https://github.com/piccolo-orm/piccolo_apiA toolkit designed to bridge the Piccolo ORM with ASGI web frameworks like Starlette and FastAPI. It simplifies building RESTful APIs by providing automated table-to-endpoint mapping via PiccoloCRUD, Pydantic model generation, and security middleware for session and token authentication, rate limiting, CSRF, and CSP.
What's inside Piccolo API
- Piccolo Admin is a web-based GUI designed for managing data within your database. It features a modern Vue.js frontend and a RESTful backend. It is powered by the Piccolo API and provides a user experience similar to Django Admin or WordPress, but with a more modern technology stack.
Overview of Piccolo API
masterPiccolo API provides utilities to expose Piccolo ORM tables as REST endpoints within ASGI applications like Starlette and FastAPI.
Key features include:
- REST Endpoints: Easily map Piccolo tables to API routes.
- ASGI Middleware: Built-in support for Session Auth, Token Auth, Rate Limiting, CSRF, and Content Security Policy (CSP).
- Pydantic Integration: Tools to automatically generate Pydantic models from your Piccolo table definitions, facilitating easy data validation and serialization.
What is Multi-Factor Authentication (MFA) in Piccolo API?
masterMulti-Factor Authentication (MFA) is a security layer that provides additional protection toSessionAuth. When MFA is enabled, a user must provide an additional piece of information (such as a code generated by an authenticator app) in addition to their standard username and password to successfully log in.Understand CSRF protection in Piccolo API
masterPiccolo API provides protection against Cross-Site Request Forgery (CSRF). CSRF is a vulnerability where an attacker makes malicious HTTP requests to a domain on behalf of an authenticated user by leveraging the browser's behavior of automatically sending cookies.
To ensure your application is secure, Piccolo API applies CSRF protection specifically to unsafe HTTP methods. You must ensure that your implementation of safe methods (like
GET) does not cause any side effects, such as modifying database state or performing other state-changing operations.How Piccolo CRUD handles serialization
masterPiccolo'sPiccoloCRUDclass usescreate_pydantic_modelinternally to handle both the serialization (converting database records to JSON-compatible formats) and deserialization (converting incoming data into database-ready formats) of data. This makes it highly compatible with modern Python web frameworks like FastAPI.Retrieve readable foreign key representations
masterSince foreign keys are stored as integers, you can request their human-readable versions (defined in the Piccolo
Tablesubclass) by appending__readable=trueto your request.This will add a field named
{foreign_key_field}_readableto the response object.Example:
GET /movie/?__readable=trueHow rate limiting providers work
masterRate limiting in Piccolo API is decoupled through the use of
Providers. AProvideris an abstraction responsible for two tasks:- Storing traffic data (tracking how many requests a client has made).
- Signaling when a rate limit has been exceeded.
While
InMemoryLimitProvideris the default, you can implement your own logic by following theRateLimitProviderinterface.Filter data using query parameters in PiccoloCRUD
masterPiccoloCRUD supports advanced filtering via HTTP query parameters using the
field__operator=valueorfield__match=typesyntax.Numeric and Date/Time Operators
Use
field__operatorwith the following values:lt: Less Thanlte: Less Than or Equalgt: Greater Thangte: Greater Than or Equale: Equal (default)ne: Not Equal
Example:
GET /movie/?duration=200&duration__operator=gte(Movies lasting $\ge$ 200 mins)Nullability
All field types support:
is_null: Matches null values.not_null: Matches non-null values.
Example:
GET /movie/?duration__operator=is_nullText Match Types
For
VarcharandTextfields, usefield__matchwith:containsexactstartsends
Example:
GET /movie/?name=star%20wars&name__match=startsGet total record count via Content-Range header
masterTo get the total number of records without making a separate call to the
/countendpoint, use the__range_header=trueparameter. Piccolo will include aContent-Rangeheader in the response.You can customize the plural name used in the header via the
__range_header_nameparameter.Example:
GET /movie/?__page=2&__page_size=10&__range_header=trueHeader Example:Content-Range: movie 0-9/100How CSRF prevention works in Piccolo API
masterPiccolo API implements a defense-in-depth strategy to prevent Cross-Site Request Forgery (CSRF) attacks. It combines several security measures to protect users across different browser capabilities:
- Double Submit Cookie: A random token is stored in a cookie. For unsafe requests (e.g.,
POST,DELETE,PUT), the client must include this same token in theX-CSRFTokenheader. The backend verifies that the header value matches the cookie value. - Referer Checking: When running over HTTPS, the middleware uses
originand/orrefererheaders to detect if requests are originating from a different domain. - Same Origin Cookies: Piccolo API provides session cookies that are marked as
SameOriginto leverage modern browser protections against cross-site requests.
- Double Submit Cookie: A random token is stored in a cookie. For unsafe requests (e.g.,
Understand the role of MFA Providers
masterIn Piccolo API,
Providersimplement the logic specific to a particular authentication mechanism. While the core MFA (Multi-Factor Authentication) code is generic, the provider handles the implementation details of the specific method being used.For example, an
AuthenticatorProviderhandles the logic for authenticating tokens from an authenticator app (like Google Authenticator) and knows how to generate the initial secrets required for a user to enable MFA.Sort and Paginate results in PiccoloCRUD
masterOrdering
Use the
__orderquery parameter to sort results.- Ascending:
?__order=field - Descending: Prepend a minus sign:
?__order=-field - Multiple columns: Separate with commas:
?__order=-duration,name
Pagination
Use
__pageand__page_sizeto control result windows.Example:
GET /movie/?__page=2&__page_size=10(Returns results 11 to 20)- Ascending: