First steps with the Plateforme framework
This introduction to the Plateforme framework will walk you through the essential steps to get your first application up and running. You will learn how to:
- Initialize a new project.
- Setup your application.
- Create resources with fields and relationships.
- Create API routes alongside the built-in CRUD operations.
- Build and run your first application.
The documentation is under heavy development!
The documentation is actively being developed and might not cover every feature. For full details, refer to the source code.
Project initialization
To begin, the easiest way to initialize and set up a new project is using the Plateforme built-in CLI. This requires CLI extra dependencies to be installed.
Note that for each command, you can get more information using -h
or --help
flag. For example, you can get help for the init
command by running plateforme init --help
.
Let's execute the initialization wizard command and follow the prompts. You can optionally provide a path argument to the init
command to create the project in a specific directory. Otherwise, the current directory will be used.
🏗 plateforme-cli 0.1.0 → init
─────────────────────────────────────────────────────
? Project name: my-app
? Version: 0.1.0
? Description: My first application
? Author (name): Rodolphe
? Author (email): rodolphe@example.com
? Template: Hero
? Create a new directory for the project? Yes
? Create project in '/path/to/my_app' directory? YesINFO: Project initialized successfully!
This will create a basic project structure with the following files:
my_app/
├── main.py # Application entry point
├── setup.py # Application build script
├── pyproject.toml # Project configuration
└── README.md # Project documentation
Where the project and application can be configured within the pyproject.toml
file.
[project]
name = "my-app"
description = "My first application"
version = "0.1.0"
authors = [
{name = "Rodolphe", email = "rodolphe@example.com"},
]
readme = "README.md"
keywords = [
"plateforme",
]
requires-python = ">=3.13"
dependencies = [
"plateforme",
]
[tool.plateforme.apps.default]
scripts = {setup = "python setup.py"}
build = ["setup"]
start = "main:app --port 8001"
Application setup
Once your project is created, you should have two files named main.py
and setup.py
inside your newly created folder. The main.py
file is the main entry point for your application, and the setup.py
file is used here as the build script to initialize the database.
from plateforme import Plateforme
# Create application
app = Plateforme(
title='My App',
database_engines='plateforme.db', # (1)!
)
- The
plateforme.db
setting for the database engines tells Plateforme to use an SQLite database file namedplateforme.db
in the project directory. Advanced database settings can also be provided to specify multiple database engines and custom connection settings.
The Plateforme application instance accepts advanced settings. You can also use a separate Python settings file with environment-specific configurations (see the enterprise
template when initializing the project).
- The
create_all()
method generates all tables in the database specified bydatabase_engines
.
Create resources
Let's start by importing the necessary objects from Plateforme.
This statement imports four objects from Plateforme:
ConfigDict
typed dictionnary for defining resource configurations.CRUDResource
as the base class for creating resources that subscribe to CRUD operations.Field
function for defining fields and relationships configuration within resources.route
decorator for defining custom routes and endpoints.
We can now define our first resources.
class Material(CRUDResource): # (1)!
code: str = Field(unique=True) # (2)!
name: str
rocket_parts: list['RocketPart'] = Field(default_factory=list) # (3)!
- Extend
CRUDResource
to create a new resource. - Define a unique
code
field for each material. - Define a list of
RocketPart
objects as a many relationship. TheField(default_factory=list)
means it defaults to an empty list if none is provided.
class Rocket(CRUDResource):
code: str = Field(unique=True)
name: str
parts: list['RocketPart'] = Field(default_factory=list) # (1)!
class RocketPart(CRUDResource):
__config__ = ConfigDict(indexes=[{'rocket', 'material'}]) # (2)!
rocket: Rocket # (3)!
material: Material # (4)!
quantity: int
- Define a list of
RocketPart
objects as a many relationship. TheField(default_factory=list)
means it defaults to an empty list if none is provided. - Create a composite index on
rocket
andmaterial
fields to improve query performance and prevent duplicate part codes per rocket. - Define a relationship to the
Rocket
resource. - Define a relationship to the
Material
resource.
Custom routes
We can also add custom routes to our resources. Let's add a custom route to the Material
resource to update its name.
class Material(CRUDResource):
...
@route.post() # (1)!
async def update_name(self, name: str) -> str: # (2)!
self.name = name # (3)!
return f'Material name updated to {name!r}.'
- The
@route.post()
decorator creates a custom endpoint with aPOST
method. - The framework inspects the method signature to determine the route parameters, return type, and perform automatic validation and serialization.
- The method updates the
name
field of theMaterial
resource and returns a confirmation message. The modifications will be persisted to the database (fine-grained control is also possible using the dependency injectionAsyncSessionDep
).
Source code in src/start/first-steps/main.py
"""
The application main entry point.
This is where you can configure your application and also add resources.
"""
from plateforme import Plateforme
# Create application
app = Plateforme(
title='My App',
database_engines='plateforme.db', # (1)!
)
# Add resources...
from plateforme import ConfigDict, CRUDResource, Field, route
class Material(CRUDResource): # (1)!
code: str = Field(unique=True) # (2)!
name: str
rocket_parts: list['RocketPart'] = Field(default_factory=list) # (3)!
@route.post() # (1)!
async def update_name(self, name: str) -> str: # (2)!
self.name = name # (3)!
return f'Material name updated to {name!r}.'
class Rocket(CRUDResource):
code: str = Field(unique=True)
name: str
parts: list['RocketPart'] = Field(default_factory=list) # (1)!
class RocketPart(CRUDResource):
__config__ = ConfigDict(indexes=[{'rocket', 'material'}]) # (2)!
rocket: Rocket # (3)!
material: Material # (4)!
quantity: int
Build and run
Let's build and run our application using the built-in Plateforme command-line interface.
The CLI infers the project directory from the current working directory.
- Navigate to the project directory where the
pyproject.toml
file is located.
Project directory
You can also use the -p
or --project
flag to specify the project directory when running any Plateforme commands. For instance, you can run plateforme -p /path/to/myapp build
to build the application from a different directory.
Once our project is set up, we can first build the application using the build
command:
🏗 plateforme-cli 0.1.0 → build
─────────────────────────────────────────────────────INFO: Building project application... (from 'my-app')
INFO: main:688 - (my-app) pkg:__main__ -> added
INFO: main:423 - (my-app) initialized
INFO: Application 'default' built successfully
This should generate a plateforme.db
SQLite database file in the project directory and set up the tables for the Material
, Rocket
, and RocketPart
resources.
Finally, we can start the application server using the start
command:
🏗 plateforme-cli 0.1.0 → start
─────────────────────────────────────────────────────INFO: Starting application... (from 'my-app')
INFO: main:688 - (my-app) pkg:__main__ -> added
INFO: main:423 - (my-app) initialized
INFO: Started server process [71407]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
Our application is now running and accessible at http://127.0.0.1:8001
.
Next steps
You can play with the application endpoints using the automatically generated CRUD endpoints, see the basic example for more details.
For more advanced features, you can explore our guides and reference documentation.