Somewhere at the beginning of this year, I have started a concept to build a Python Flarum API client. The goal was to provide everyone an easy and extensible system to interact with Flarum's public API and perform user-related tasks.
Later, I began to work on rebasing FreeFlarum's code, so this idea was left in the dust. But after that was done, I revisited this project and started over now that I had learned more about Python.
Thus, I present to you my first (real) Python package - pyFlarum.
🔗 Useful links:
- Complete support for creating, retrieving, updating and deleting data.
- (Almost) everything is object-oriented, with docstrings (still needs to be done) and examples to help you code faster.
- Very extensible, thanks to custom extension & dependency system. The most common Flarum extensions are included out of the box, and more are still on the way. Read more about the extension system here.
- The data is fetched and stored as JSON, but the keys can be retrieved by using class properties, which also handles type conversions.
- This means that instead of using
discussion['data']['attributes']['title'], it is as simple as
- Flarum's JSON API works in saving mode. What I mean is that when you fetch a discussion from notification, not all of the discussion's data is present in the JSON. On the other hand, obtaining the discussion directly by it's ID results in a much detailed JSON.
- To save you headaches, pyFlarum obviously handles this too and all of the objects have different hierarchy and inheritance. Example:
DiscussionFromNotification is parent for
DiscussionFromBulk and that's parent for
Discussion object is discussion obtained directly from API, and therefore logically contains all properties of the previous objects (and JSON). This is all nicely rendered thanks to your editor's linting and type hints, so you won't make a mistake by accessing unexisting properties from parent objects. More about pyFlarum's inheritance system and it's flaws can be found here.
This package requires Python 3.6+ and the requests library to be installed. Yep, that's the only dependency. Should there be more over time, you can install them all at once by using this command (but I assume that you're already familiar with all of this, so feel free to skip this part):
pip install -r requirements.txt
python -m pip install -r requirements.txt
Installing is easy with:
pip install pyflarum -U
python -m pip install pyflarum -U
python -m pip install pyflarum -U --upgrade
pip install pyflarum --upgrade -U
python -m pip uninstall pyflarum
pip uninstall pyflarum
📜 Quickstart Example:
How easy is it to fetch a specific discussion and print it's title?
The answer - luckily, it's actually quite easy:
from pyflarum import FlarumUser
# Here, we initialize our `FlarumUser` object. You can't do anything without this first:
USER = FlarumUser(forum_url="https://discuss.flarum.org")
# Now, let's get the discussion:
discussion = USER.get_discussion_by_id(28221)
That's just amazing 4 lines of code (without comments and newlines)!
➡ What's next?
Check the documentation to dive deep into the concepts of this project and learn more!
I will now take a small break from maintaining this - I still want to do a bit more projects this summer now that I have some time. However, I am open for feature requests and bug reports at the GitHub repository.
The documentation is still not finished yet, but that can wait for now until some people show some interest in this. My honest view is that I do not want to work on something that people will not enjoy, and I will likely require some motivation in order to keep this project alive. If no interest is shown, I will occasionally push bug fixes and features for my personal use over time. I don't actually expect much people to use this, but I'd be surprised and happy if you would!
I'll show you some more examples before we dive deep into the details at the documentation. All of the following snippets assume that you already have your
USER object initialized.
Get all discussions from the front page (
/api/discussions) and print the title & URL:
for discussion in USER.all_discussions():
Obtain some user:
user = USER.get_user_by_id(1)
for group in user.get_groups():
You can find more examples in the sections below, or browse the tests directory of the source code for full examples of various tasks. These will be regularly updated, should this stay maintained, to ensure that old stuff works and new features behave correctly too.
💾 Database support (since
pyFlarum has also support for the default Flarum database structure (upon installation). This makes it possible to implement pyFlarum in migration scripts, to make transition to Flarum easy, fast and fully-automatic.
from sqlmodel import create_engine
from pyflarum.database import FlarumDatabase
from pyflarum.database import DB_User
ENGINE = create_engine('sqlite:///tests/database/database.db') # see https://docs.sqlalchemy.org/en/latest/core/engines.html for details on the engine
DATABASE = FlarumDatabase(engine=ENGINE)
if __name__ == "__main__":
for user in DATABASE.generic_filter(DB_User, id=1).first():
print(user.username, ':', sep='')
for discussion in user.discussions:
print(user.username, '(no discussions)')
Disclaimer: Database support is still new and in beta (as the rest of this library anyways).
Database has no support for extensions that are not included in Flarum by default. This is because it is very difficult to maintain the support for all the different columns that extensions create - when pyFlarum defines/doesn't define a column that is not/is in the database, it breaks.
It is also technically not possible to monkey-patch database properties the same way it is possible to do in
My vision about the database support is to provide an easy way to create migration scripts to Flarum. You can see my other repository for migrations that have already been created by me.
Contributions to both the migrations and this project are welcome!
🎁 Support me
I create free software to benefit people.
If this project helps you and you like it, consider supporting me by donating via cryptocurrency:
- Bitcoin Cash:
- Ethereum Classic:
More cryptocurrencies are supported. If you are interested in donating with a different one, please send me an E-mail to the following address: firstname.lastname@example.org
No other forms of donation are currently supported.