diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..32bbad8b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,57 @@ +# Contributing to agent-python + +Thanks for helping improve the Forest Python agent. This guide covers how to report an issue, set up the repository, and get a pull request merged. + +## Before you start + +- **Found a bug?** Open an issue: expected behavior, actual behavior, logs, and the package versions you use (Django or Flask included). +- **Found a security issue?** Do not open a public issue. Follow the [security policy](https://github.com/ForestAdmin/.github/blob/main/SECURITY.md). +- **Planning a large change?** Open an issue first to discuss it, so your work fits the agent's direction before you write it. + +## Setup + +This monorepo holds one package per folder in [`src/`](./src), managed with Poetry. Python `>=3.8,<3.14` is supported. + +```bash +pip install -r requirements.txt # installs pre-commit +pre-commit install +``` + +Demo applications for Django and Flask live in [`src/_example/`](./src/_example). + +## Tests + +Run the whole suite the way the CI does: + +```bash +./launch_tests_ci_like.sh +``` + +Or one package at a time: + +```bash +cd src/ +poetry install --with=test +poetry run coverage run -m pytest +``` + +Tests must pass and the pre-commit hooks must be clean before you open a pull request. + +## Commit messages + +Commits follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. Releases and changelogs are generated from them by semantic-release, so the type matters: + +- `fix(django_agent): handle null dates` → patch release +- `feat(datasource_sqlalchemy): add the X option` → minor release +- `docs: ...`, `test: ...`, `chore: ...` → no release + +## Pull requests + +1. Fork the repository and create a branch from `main`. +2. Make your change, with tests. +3. Give the pull request a Conventional Commits title. +4. The CI must be green. The Forest team reviews every pull request before merging. + +## Code of conduct + +Everyone taking part in this project is expected to follow the [code of conduct](https://github.com/ForestAdmin/.github/blob/main/CODE_OF_CONDUCT.md). diff --git a/README.md b/README.md index 92e36c8a..32f313ac 100644 --- a/README.md +++ b/README.md @@ -1,145 +1,149 @@ -# agent-python - -## In a nutshell - -Forest Admin provides an off-the-shelf administration panel based on a highly-extensible API plugged into your application. - -This project has been designed with scalability in mind to fit requirements from small projects to mature companies. - -## Who Uses Forest Admin - -- [Apartmentlist](https://www.apartmentlist.com) -- [Carbon Health](https://carbonhealth.com) -- [Ebanx](https://www.ebanx.com) -- [First circle](https://www.firstcircle.ph) -- [Forest Admin](https://www.forestadmin.com) of course :-) -- [Heetch](https://www.heetch.com) -- [Swile](https://www.swile.co) -- [Pillow](https://www.pillow.com) -- [Qonto](https://www.qonto.eu) -- [Shadow](https://shadow.tech) -- And hundreds more… - -## Getting Started - -[https://docs.forestadmin.com/documentation/how-tos/setup/install](https://docs.forestadmin.com/documentation/how-tos/setup/install) - -## Documentation - -[https://docs.forestadmin.com/developer-guide-agents-python](https://docs.forestadmin.com/developer-guide-agents-python) - -## How it works - -

- Howitworks +

+ + + Forest agent for Python: Django and Flask, your data and workflows running on your infrastructure. +

-Forest Admin consists of two components: - -- The Admin Frontend is the user interface where you'll manage your data and configuration. -- The Admin Backend API hosted on your servers where you can find and extend your data models and all the business logic (routes, actions, …) related to your admin panel. - -The Forest Admin gem (aka Forest Liana) introspects all your data model -and dynamically generates the Admin API hosted on your servers. The Forest Admin -interface is a web application that handles communication between the admin -user and your application data through the Admin API. - -## Features +

+ PyPI Django + PyPI Flask + CI + License +

-### CRUD +**Forest is the back office for operations teams in regulated companies.** Ops teams review, decide and act on your data from one interface, or let AI agents do it, within the roles, permissions and audit logs you define. -All of your CRUD operations are natively supported. The API automatically -supports your data models' validation and allows you to easily extend or -override any API routes' with your very own custom logic. +This repository is the **Python agent** for **Django** and **Flask**: the part of Forest that runs inside your application, connects to your databases, and exposes them to the Forest interface. Your business data never goes through Forest. -CRUD +> [!NOTE] +> **Forest v2.** This is the current Python SDK. Using `django-forestadmin`? You are on v1: see the [migration guide](https://docs.forest.app/guides/migration/from-v1/overview). -### Search & Filters +## Quick start -Forest Admin has a built-in search allowing you to run basic queries to -retrieve your application's data. Set advanced filters based on fields and -relationships to handle complex search use cases. +### Django -Search and Filters +```bash +pip install forestadmin-agent-django +``` -### Sorting & Pagination +The agent plugs in through your settings, not a constructor: -Sorting and pagination features are natively handled by the Admin API. We're -continuously optimizing how queries are run in order to display results faster -and reduce the load of your servers. +```python +# settings.py +import os -Sorting and Pagination +INSTALLED_APPS = [ + # ... + "forestadmin.django_agent", +] -### Custom action +FOREST_AUTH_SECRET = os.environ.get("FOREST_AUTH_SECRET") +FOREST_ENV_SECRET = os.environ.get("FOREST_ENV_SECRET") +``` -A custom action is a button which allows you to trigger an API call to execute -a custom logic. With virtually no limitations, you can extend the way you -manipulate data and trigger actions (e.g. refund a customer, apply a coupon, -ban a user, etc.) +```python +# urls.py +from django.urls import include, path -Custom action +urlpatterns = [ + path("", include("forestadmin.django_agent.urls")), +] +``` -### Export +Your Django models are exposed automatically. To add computed fields, actions or segments, point `FOREST_CUSTOMIZE_FUNCTION` to a function that receives the agent (e.g. `"myapp.forest_admin.customize_forest"`). The module must exist: if it cannot be imported, the agent does not start. -Sometimes you need to export your data to a good old fashioned CSV. Yes, we -know this can come in handy sometimes :-) +### Flask + SQLAlchemy -Export +```bash +pip install forestadmin-agent-flask forestadmin-datasource-sqlalchemy flask-sqlalchemy +``` -### Segments +```python +import os -Get in app access to a subset of your application data by doing a basic search -or typing an SQL query or implementing an API route. +from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from forestadmin.datasource_sqlalchemy.datasource import SqlAlchemyDatasource +from forestadmin.flask_agent.agent import create_agent -Segments +db = SQLAlchemy() # your models are declared on this instance -### Dashboards +def create_app(): + app = Flask(__name__) + app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"] + # the agent reads its settings from app.config, not from the environment + app.config["FOREST_ENV_SECRET"] = os.environ["FOREST_ENV_SECRET"] + app.config["FOREST_AUTH_SECRET"] = os.environ["FOREST_AUTH_SECRET"] -Forest Admin is able to tap into your actual data to chart out your metrics -using a simple UI panel, a SQL query or a custom API call. + agent = create_agent(app) + with app.app_context(): + db.init_app(app) + agent.add_datasource(SqlAlchemyDatasource(db)) + agent.start() + return app +``` -Dashboard +Full guide: [docs.forest.app/get-started/quickstart](https://docs.forest.app/get-started/quickstart) -### WYSIWYG +## Requirements -The WYSIWYG interface saves you a tremendous amount of frontend development -time using drag'n'drop as well as advanced widgets to build customizable views. +| | | +|---|---| +| Python | `>=3.8,<3.14` (CI tests 3.8 to 3.13) | +| Django | `>=3.2,<5.2` | +| Flask | `>=2.0.0` (`async` extra) | +| SQLAlchemy | `>=1.4.0` | -WYSIWYG +## What the agent gives you -### Custom HTML/JS/CSS +| | | +|---|---| +| **Data** | Your Django models or SQLAlchemy tables, introspected and exposed to Forest. | +| **Customization** | Computed fields, actions, segments and hooks in Python, from your customize function. | +| **Permissions and audit** | Roles, scopes and activity logs defined in Forest, enforced on every request. | -Code your own views using JS, HTML, and CSS to display your application data in -a more appropriate way (e.g. Kanban, Map, Calendar, Gallery, etc.). +## How it works -Custom views + + + The Python agent runs on your infrastructure. Forest calls it over HTTPS; the agent queries your databases and services. + -### Team-based permissions +The agent runs **on your infrastructure**. The Forest interface calls your agent, and your agent queries your sources: Forest does not store your business data. -Without any lines of code, manage directly from the UI who has access or can -act on which data using a team-based permission system. +## Documentation -Team based permissions +| | | +|---|---| +| Get started | https://docs.forest.app/get-started/quickstart | +| Connect a data source | https://docs.forest.app/get-started/connect/data-sources/overview | +| Migrating from v1 | https://docs.forest.app/guides/migration/from-v1/overview | -### Third-party integrations +
+Packages in this monorepo -Leverage data from third-party services by reconciling it with your -application’s data and providing it directly to your Admin Panel. All your -actions can be performed at the same place, bringing additional intelligence to -your Admin Panel and ensuring consistency. +| PyPI package | Role | +|---|---| +| `forestadmin-agent-django` | Agent for Django | +| `forestadmin-agent-flask` | Agent for Flask | +| `forestadmin-agent-toolkit` | Agent core (transport, auth, permissions) | +| `forestadmin-datasource-toolkit` | Data source contracts, queries, types | +| `forestadmin-datasource-django` | Django ORM data source | +| `forestadmin-datasource-sqlalchemy` | SQLAlchemy data source | -Third-party integrations +All packages install into the shared `forestadmin.*` namespace. Complete demo applications live in [`src/_example/`](./src/_example). -### Notes & Comments +
-Assign your teammates to specific tasks, leave a note or simply comment a -record, thereby simplifying collaboration all across your organization. +## Contributing -Notes and Comments +Bug reports and pull requests are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, tests and commit conventions. -### Activity logs +```bash +./launch_tests_ci_like.sh # runs the CI locally +``` -Monitor each action executed and follow the trail of modification on any data -with an extensive activity log system. +## License -Activity logs +Apache 2.0. See [LICENSE](./LICENSE). diff --git a/assets/arch-agent-python-dark.svg b/assets/arch-agent-python-dark.svg new file mode 100644 index 00000000..a805d959 --- /dev/null +++ b/assets/arch-agent-python-dark.svg @@ -0,0 +1 @@ + diff --git a/assets/arch-agent-python-light.svg b/assets/arch-agent-python-light.svg new file mode 100644 index 00000000..76073ec3 --- /dev/null +++ b/assets/arch-agent-python-light.svg @@ -0,0 +1 @@ + diff --git a/assets/header-agent-python-dark.svg b/assets/header-agent-python-dark.svg new file mode 100644 index 00000000..76bbd544 --- /dev/null +++ b/assets/header-agent-python-dark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/header-agent-python-light.svg b/assets/header-agent-python-light.svg new file mode 100644 index 00000000..4d07a6cc --- /dev/null +++ b/assets/header-agent-python-light.svg @@ -0,0 +1,7 @@ + + + + + + +