{"id":16092257,"url":"https://github.com/alecthomas/waffle","last_synced_at":"2025-03-18T06:30:57.593Z","repository":{"id":8830145,"uuid":"10531715","full_name":"alecthomas/waffle","owner":"alecthomas","description":"Waffle - A Dependency-Injection-based application framework for Python","archived":false,"fork":false,"pushed_at":"2024-01-01T17:12:26.000Z","size":351,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-13T15:07:17.106Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-06-06T17:01:41.000Z","updated_at":"2025-02-11T06:35:55.000Z","dependencies_parsed_at":"2024-10-27T17:23:50.599Z","dependency_job_id":"ba5f7e57-1c16-4e18-b4d3-9d3364527f53","html_url":"https://github.com/alecthomas/waffle","commit_stats":{"total_commits":56,"total_committers":1,"mean_commits":56.0,"dds":0.0,"last_synced_commit":"7e59e21a893b5377be5894dda7eb919217de637e"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fwaffle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fwaffle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fwaffle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fwaffle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/waffle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244169363,"owners_count":20409704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-09T16:06:20.192Z","updated_at":"2025-03-18T06:30:57.275Z","avatar_url":"https://github.com/alecthomas.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Waffle - A Dependency-Injection-based Python Application Framework\n\nWaffle provides common functionality for bootstrapping an application using [Injector](https://github.com/alecthomas/injector).\n\nThe general approach used by the Injector modules in Waffle is to use flags to configure the behaviour of objects exported by the modules. The flag defaults can (and sometimes must) be overridden by the `@main` decorator or `run()` function.\n\nFor example, `waffle.redis.RedisModule` relies on the flag `--redis_server` to connect to a Redis server, which defaults to `localhost:6379:0`. To configure and use the Redis module you might do something like this:\n\n```python\nfrom waffle import main\n\n@main(redis_server='redis.domain.com:6379:1')\ndef main(injector):\n    redis = injector.get(Redis)\n```\n\nWaffle provides:\n\n1. Command line flag parsing via argh.\n2. Injection of flags.\n3. Construction of the injector.\n4. A bunch of modules that provide different integration: Redis, SQLAlchemy, Flask, logging, etc.\n\n## Examples\n\n### A bare bones application\n\n```python\nfrom waffle import main\n\n@main\ndef main():\n    print 'Hello world'\n```\n\n### Injecting modules\n\nA slightly more complex example injecting the logging module:\n\n```python\nfrom waffle import LoggingModule, main\n\n@main(debug=True)\n@modules(LoggingModule)\ndef main():\n    ...\n```\n\n`@main` should be the last statements in the module.\n\n### A full example web server with database\n\nThis example illustrates several aspects of Waffle:\n\n- How to set defaults for flags by passing the flags as keyword arguments to either `main()` or `run()`.\n- The use of the convenience Injector modules `AppModules` and `WebModules`, which install commonly used modules for applications and web applications, respectively. See [below](#available-modules) for details.\n\n- Use of the `@transaction` decorator to wrap requests in an SQLAlchemy transaction.\n\n\n```python\nfrom injector import inject\nfrom sqlalchemy import Column, String\n\nfrom waffle import AppModules, WebModules, \\\n    Model, WebApplication, routes, main, modules, route, \\\n    transaction, csrf_exempt\n\n\nclass KeyValue(Model):\n    key = Column(String, primary_key=True)\n    value = Column(String)\n\n\n@route('/')\n@transaction\ndef index():\n    return [(kv.key, kv.value) for kv in KeyValue.query.all()]\n\n\n@route('/\u003ckey\u003e')\n@transaction\n@csrf_exempt\ndef get_or_create(request, key):\n    kv = KeyValue.query.filter_by(key=key).all()\n    if kv:\n        kv = kv[0]\n    if request.method == 'POST':\n        if kv:\n            kv.value = request.data\n        else:\n            kv = KeyValue(key=key, value=request.data)\n        kv.save()\n        return {'status': 'OK'}\n\n    return {'key': kv.key, 'value': kv.value}\n\n\n@main(database_uri='sqlite:///:memory:', static_root='./static/',\n      template_root='./templates/')\n@modules(AppModules, WebModules)\n@inject(app=WebApplication)\ndef main(app):\n    app.serve(port=8081, use_reloader=False)\n\n```\n\n## Available modules\n\n### waffle.common.AppModules (composite)\n\nInstalls `waffle.db.DatabaseModule` and `waffle.db.LoggingModule`.\n\n### waffle.web.common.WebModules (composite)\n\nInstalls `waffle.web.clastic.WebModule`, `waffle.web.db.DatabaseSessionModule`, `waffle.web.template.TemplateModule` and `waffle.web.csrf.CsrfModule`.\n\n### waffle.db.DatabaseModule\n\nConfigure SQLAlchemy to work with injection.\n\nBinds a configured SQLAlchemy `Session` to the injector.\n\n```python\nfrom sqlalchemy.orm import String\nfrom sqlalchemy.orm.session import Session\nfrom waffle import DatabaseModule, Base, main, modules\n\n\nclass KeyValue(Base):\n    key = String()\n    value = String()\n\n\n@main(database_uri='sqlite:///tmp/test.db')\n@modules(DatabaseModule)\ndef main(injector):\n    session = injector.get(Session)\n    ...\n```\n\n### waffle.log.LoggingModule\n\nConfigures some default basic logging.\n\nBinds the key `LogLevel` to the specified log level.\n\n### waffle.devel.DevelModule\n\nA module that binds the gevent `BackdoorServer`, allowing the developer to attach to a Python shell in the application.\n\nUse like so:\n\n```python\ninjector.get(BackdoorServer).start()\n```\n\n### waffle.web.clastic.WebModule\n\nIntegrates [Clastic](https://github.com/mahmoud/clastic) through an injector module. This is the core module for providing web application support.\n\n### waffle.web.db.DatabaseSessionModule\n\nA module that manages DB session lifecycle in HTTP requests. This basically resets the session at the end of each request.\n\n### waffle.web.template.TemplateModule\n\nA module that provides template loading and the ability for separate modules to contribute to the global template rendering context. Useful for eg. adding global debug variables, etc.\n\nTo contribute to global template context:\n\n```python\nbinder.multibind(TemplateContext, to={\n    'debug': debug,\n})\n```\n\n### waffle.web.csrf.CsrfModule\n\nEnable CSRF support in templates.\n\n### waffle.redis.RedisModule\n\nProvides a Redis client configured by flags:\n\n```python\nfrom redis import Redis\n\n@inject(redis=Redis)\ndef get(redis):\n    return redis.get('some_key')\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fwaffle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Fwaffle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fwaffle/lists"}