{"id":23103303,"url":"https://github.com/themusharraf/allnc","last_synced_at":"2025-08-16T15:31:45.733Z","repository":{"id":243557816,"uuid":"804922450","full_name":"themusharraf/allnc","owner":"themusharraf","description":"Python Web Framework built for learning purposes","archived":false,"fork":false,"pushed_at":"2024-07-05T09:39:55.000Z","size":106,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-07T10:55:02.411Z","etag":null,"topics":["allnc","build","framework","jinja2","jinja2-templates","python3","template","web"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/allnc/","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/themusharraf.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":"2024-05-23T14:29:45.000Z","updated_at":"2024-09-19T09:33:23.000Z","dependencies_parsed_at":"2024-06-09T21:09:45.591Z","dependency_job_id":"f0216edb-57b7-4718-8029-96bc44d6b962","html_url":"https://github.com/themusharraf/allnc","commit_stats":null,"previous_names":["themusharraf/allnc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themusharraf%2Fallnc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themusharraf%2Fallnc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themusharraf%2Fallnc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/themusharraf%2Fallnc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/themusharraf","download_url":"https://codeload.github.com/themusharraf/allnc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230043146,"owners_count":18163966,"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":["allnc","build","framework","jinja2","jinja2-templates","python3","template","web"],"created_at":"2024-12-17T00:13:29.859Z","updated_at":"2024-12-17T00:13:30.378Z","avatar_url":"https://github.com/themusharraf.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Screenshot from 2024-05-27 15-02-59](https://github.com/themusharraf/allnc/assets/122869450/859d4911-8e2b-45d3-af78-ff64cd51ff4a)        \n      \n  \n![purpose](https://img.shields.io/badge/purpose-learning-green.svg) ![coverage](https://img.shields.io/badge/coverage-100-green)   ![PyPI - Version](https://img.shields.io/pypi/v/allnc)        \n   \n# AllNc           \n   \nAllNc is a Python Web Framework built for learning purposes. The plan is to learn how frameworks    \nare built by implementing their features, writing blog posts about them and keeping the codebase  \nas simple as possible.\n\nIt is a WSGI framework and can be used with any WSGI application server such as Gunicorn.\n\n    \n## Installation\n\n```shell\npip install allnc\n```\n   \n   \n## How to use it\nasic Usage:\n \n```python\n# app.py\nfrom allnc.app import AllNc\nfrom allnc.middleware import Middleware\n\napp = AllNc()\n\n\n@app.route(\"/home\") \ndef home(request, response):\n    response.text = \"Hello from the Home Page\"\n\n\n@app.route(\"/about\")\ndef about(request, response):\n    response.text = \"Hello from the About Page\"\n\n\n@app.route(\"/hello/{name}\")\ndef greeting(request, response, name):\n    response.text = f\"Hello {name}\"\n\n\n@app.route(\"/books\")\nclass Books:\n    def get(self, request, response):\n        response.text = \"Hello from the Books Page\"\n\n    def post(self, request, response):\n        response.text = \"Endpoint to create a  book\"\n\n\ndef new_handler(req, resp):\n    resp.text = \"From new Handler\"\n\n\napp.add_route(\"/new-handler\", new_handler)\n\n\n@app.route(\"/template\")\ndef template_handler(req, resp):\n    resp.html = app.template(\n        \"home.html\",\n        context={\"new_title\": \"Best title\", \"new_body\": \"Best body\"},\n    )\n\n\n@app.route(\"/json\")\ndef json_handler(req, resp):\n    response_data = {\"name\": \"some name\", \"type\": \"json\"}\n    resp.json = response_data\n\n```\n\nStart:\n\n```bash\ngunicorn app:app\n```\n\n## Handlers\n\nIf you use class based handlers, only the methods that you implement will be allowed:\n\n```python\n@app.route(\"/hello/{name}\")\ndef greeting(request, response, name):\n    response.text = f\"Hello {name}\"\n```\n\nThis handler will only allow `GET` requests. That is, `POST` and others will be rejected. The same thing can be done with\nfunction based handlers in the following way:\n\n```python\n@app.route(\"/\", methods=[\"get\"])\ndef home(req, resp):\n    resp.text = \"Hello, this is a home page.\"\n```\n\nNote that if you specify `methods` for class based handlers, they will be ignored.\n\n## Unit Tests\n\nThe recommended way of writing unit tests is with [pytest](https://docs.pytest.org/en/latest/). There are two built in fixtures\nthat you may want to use when writing unit tests with AllNc. The first one is `app` which is an instance of the main `AllNc` class:\n\n```python\ndef test_route_overlap_throws_exception(app):\n    @app.route(\"/\")\n    def home(req, resp):\n        resp.text = \"Welcome Home.\"\n\n    with pytest.raises(AssertionError):\n        @app.route(\"/\")\n        def home2(req, resp):\n            resp.text = \"Welcome Home2.\"\n```\n\nThe other one is `client` that you can use to send HTTP requests to your handlers. It is based on the famous [requests](http://docs.python-requests.org/en/master/) and it should feel very familiar:\n\n```python\ndef test_parameterized_routing(app, test_client):\n    @app.route(\"/hello/{name}\")\n    def greeting(request, response, name):\n        response.text = f\"Hello {name}\"\n\n    assert test_client.get(\"http://testserver/hello/John\").text == \"Hello John\"\n    assert test_client.get(\"http://testserver/hello/Musharraf\").text == \"Hello Musharraf\"\n```\n\n\n\n## Templates\n\nThe default folder for templates is `templates`. You can change it when initializing the main `AllNc()` class:\n\n```python\napp = AllNc(templates_dir=\"templates_dir_name\")\n```\n\nThen you can use HTML files in that folder like so in a handler:\n\n```python\n@app.route(\"/show/template\")\ndef handler_with_template(req, resp):\n    resp.html = app.template(\"example.html\", context={\"title\": \"Awesome Framework\", \"body\": \"welcome to the future!\"})\n```\n\n## Static Files\n\nJust like templates, the default folder for static files is `static` and you can override it:\n\n```python\napp = AllNc(static_dir=\"static_dir_name\")\n```\n\nThen you can use the files inside this folder in HTML files:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\n\u003chead\u003e\n  \u003cmeta charset=\"UTF-8\"\u003e\n  \u003ctitle\u003e{{title}}\u003c/title\u003e\n\n  \u003clink href=\"/static/main.css\" rel=\"stylesheet\" type=\"text/css\"\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n    \u003ch1\u003e{{body}}\u003c/h1\u003e\n    \u003cp\u003eThis is a paragraph\u003c/p\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Custom Exception Handler\n\nSometimes, depending on the exception raised, you may want to do a certain action. For such cases, you can register an exception handler:\n\n```python\ndef on_exception(req, resp, exception):\n    if isinstance(exception, HTTPError):\n        if exception.status == 404:\n            resp.text = \"Unfortunately the thing you were looking for was not found\"\n        else:\n            resp.text = str(exception)\n    else:\n        # unexpected exceptions\n        if app.debug:\n            debug_exception_handler(req, resp, exception)\n        else:\n            print(\"These unexpected exceptions should be logged.\")\n\napp = AllNc(debug=False)\napp.add_exception_handler(on_exception)\n```\n\nThis exception handler will catch 404 HTTPErrors and change the text to `\"Unfortunately the thing you were looking for was not found\"`. For other HTTPErrors, it will simply\nshow the exception message. If the raised exception is not an HTTPError and if `debug` is set to True, it will show the exception and its traceback. Otherwise, it will log it.\n\n## Middleware\n\nYou can create custom middleware classes by inheriting from the `allnc.middleware.Middleware` class and override its two methods\nthat are called before and after each request:\n\n```python\nfrom allnc.app import AllNc\nfrom allnc.middleware import Middleware\n\napp = AllNc()\n\n\nclass SimpleCustomMiddleware(Middleware):\n    def process_request(self, req):\n        print(\"Before dispatch\", req.url)\n\n    def process_response(self, req, res):\n        print(\"After dispatch\", req.url)\n\n\napp.add_middleware(SimpleCustomMiddleware)\n```\n\n\n## Features\n\n- WSGI compatible\n- Built-in ORM\n- Parameterized and basic routing\n- Class based handlers\n- Test Client\n- Support for templates\n- Support for static files\n- Custom exception handler\n- Middleware\n\n## Note\n\nIt is extremely raw and will hopefully keep improving. If you are interested in knowing how a particular feature is implemented in other\nframeworks, please open an issue and we will hopefully implement and explain it in a blog post\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthemusharraf%2Fallnc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthemusharraf%2Fallnc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthemusharraf%2Fallnc/lists"}