{"id":21743448,"url":"https://github.com/moustikitos/micro-server","last_synced_at":"2025-04-13T05:05:39.379Z","repository":{"id":48347511,"uuid":"257861108","full_name":"Moustikitos/micro-server","owner":"Moustikitos","description":"Pure python json server library","archived":false,"fork":false,"pushed_at":"2025-02-20T11:38:59.000Z","size":1009,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T05:05:28.623Z","etag":null,"topics":["framework","python","web","wsgi-server"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Moustikitos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2020-04-22T09:59:16.000Z","updated_at":"2025-02-20T11:39:03.000Z","dependencies_parsed_at":"2025-01-20T22:37:29.025Z","dependency_job_id":"6981ebd8-f664-430f-b266-52eb99abcc61","html_url":"https://github.com/Moustikitos/micro-server","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moustikitos%2Fmicro-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moustikitos%2Fmicro-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moustikitos%2Fmicro-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moustikitos%2Fmicro-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Moustikitos","download_url":"https://codeload.github.com/Moustikitos/micro-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665749,"owners_count":21142123,"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":["framework","python","web","wsgi-server"],"created_at":"2024-11-26T07:08:07.051Z","updated_at":"2025-04-13T05:05:39.374Z","avatar_url":"https://github.com/Moustikitos.png","language":"Python","funding_links":["https://liberapay.com/Toons/donate","https://paypal.me/toons"],"categories":[],"sub_categories":[],"readme":"# `usrv`: the lightest python web framework\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/Moustikitos/micro-server/master/LICENSE)\n\nPackage (`usrv`) is a pure python micro server implementation. It allows python function bindings for all HTTP methods. HTTP body can be encrypted on demand using secp256k1 keypairs.\n\n## Install\n\n### Developpment version\n\n```bash\n$ python -m pip install git+https://github.com/Moustikitos/micro-server#egg=usrv\n```\n\n### last version (0.4.2)\n\n```bash\n$ python -m pip install usrv\n```\n\n## `usrv.route`\n\nBind python code to any HTTP requests easily using decorator syntax.\n`route` module can be used in standalone mode outside of `usrv` package.\n\n## `usrv.app`\n\nRun a low footprint python server or [PEP#3333 WSGI server](https://www.python.org/dev/peps/pep-3333).\n\n```python\nimport waitress  # wsgi server for windows\nfrom usrv import app, route\n\n@route.bind(\"/index\")\ndef index(**kw):\n    return 200, \"Index page\", kw\n\nwaitress.serve(app.uApp(), threads=2)\n```\n\n## Fast and simple\n\nLet's create a server with `/test` endpoint in a python module named `test.py`:\n\n```python\nfrom usrv import route, app\n\n@route.bind(\"/test\")\ndef do_test(a, b):\n    # write some code and return something\n    return 200, a, b\n\ndef launchApp():\n    route.run(host=\"127.0.0.1\", port=5000, loglevel=20)\n```\n\n**Bound functions have to return a tuple with a valid HTTP status code as first item**.\nServer can be run from python interpreter:\n\n```python\n\u003e\u003e\u003e import test\n\u003e\u003e\u003e test.launchApp()\nINFO:usrv.srv:listening on 127.0.0.1:5000\nCTRL+C to stop...\n```\n\nNow going to `http://127.0.0.1:5000/test` with any browser gives:\n\n```json\n[null, null]\n```\n\n## Extracting values from url query\n\n`[null, null]` above are the returned values `a` and `b` from `do_test` function. Values can be extracted from query string. Let's type `http://127.0.0.1:5000/test?b=12\u0026a=Paris` in the address bar:\n\n```json\n[\"Paris\", \"12\"]\n```\n\nReturned value from query are `str` only. Unexpected values are ignored but there is a [convenient way to catch them](#catching-unexpected-values).\n\n## Extracting values from url path\n\nValues can also be extracted from url path with or without a typing precision.\n\n```python\n@route.bind(\"/\u003cint:b\u003e/\u003ca\u003e\")\ndef do_test(a, b):\n    # write some code and return something\n    return 200, a, b\n```\n\nThis binding creates multiple endpoint possibilities. Let's try `http://127.0.0.1:5000/5/test`:\n\n```json\n[\"test\", 5]\n```\n\nValues from url can be overrided by thoses from query... `http://127.0.0.1:5000/5/test?a=2\u0026b=6`:\n\n```json\n[\"2\", \"6\"]\n```\n\n\u003e It can only be overrided with `str` type values.\n\n## Catching unexpected values\n\nUsing varargs or/and keywordargs is a convenient way to catch unexpected values from url query and HTTP context. HTTP Context is defined an headers and data (HTTP requests with body).\n\nWhen HTTP context is catched by `*args`, unexpected values from query string are appended next.\n\nUrl used for this chapter `http://127.0.0.1:5000/test?b=12\u0026a=Paris\u0026unexpected=there`.\n\n### Variable args (`*args`)\n\n```python\n@route.bind(\"/test\")\ndef do_test(a, b, *args):\n    # write some code and return something\n    # args is a tuple\n    return 200, a, b, args\n```\n\n\u003e With `*args` method, HTTP headers and data will be postionned at the end of `json` response\n\n```json\n[\n  \"Paris\",\n  \"12\",\n  \"there\",\n  \"GET\",\n  {\n    \"host\": \"127.0.0.1:5000\",\n    \"connection\": \"keep-alive\",\n    \"sec-ch-ua\": \"\\\"Brave\\\";v=\\\"131\\\", \\\"Chromium\\\";v=\\\"131\\\", \\\"Not_A Brand\\\";v=\\\"24\\\"\",\n    \"sec-ch-ua-mobile\": \"?0\",\n    \"sec-ch-ua-platform\": \"\\\"Windows\\\"\",\n    \"upgrade-insecure-requests\": \"1\",\n    \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\n    \"accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8\",\n    \"sec-gpc\": \"1\",\n    \"accept-language\": \"fr-FR,fr\",\n    \"sec-fetch-site\": \"none\",\n    \"sec-fetch-mode\": \"navigate\",\n    \"sec-fetch-user\": \"?1\",\n    \"sec-fetch-dest\": \"document\",\n    \"accept-encoding\": \"gzip, deflate, br, zstd\"\n  },\n  null\n]\n```\n\n### Keyword args (`**kwargs`)\n\n```python\n@route.bind(\"/test\")\ndef do_test(a, b, **kwargs):\n    # write some code and return something\n    # kwargs is a dict\n    return 200, a, b, kwargs\n```\n\n\u003e using `**kwargs` is the recommended way to retrieve unexpected values by names. Unexpected mapping is positionned at the end of `json` response.\n\n```json\n[\n  \"Paris\",\n  \"12\",\n  {\n    \"unexpected\": \"there\",\n    \"method\": \"GET\",\n    \"headers\": {\n      \"host\": \"127.0.0.1:5000\",\n      \"connection\": \"keep-alive\",\n      \"sec-ch-ua\": \"\\\"Brave\\\";v=\\\"131\\\", \\\"Chromium\\\";v=\\\"131\\\", \\\"Not_A Brand\\\";v=\\\"24\\\"\",\n      \"sec-ch-ua-mobile\": \"?0\",\n      \"sec-ch-ua-platform\": \"\\\"Windows\\\"\",\n      \"upgrade-insecure-requests\": \"1\",\n      \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36\",\n      \"accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8\",\n      \"sec-gpc\": \"1\",\n      \"accept-language\": \"fr-FR,fr\",\n      \"sec-fetch-site\": \"none\",\n      \"sec-fetch-mode\": \"navigate\",\n      \"sec-fetch-user\": \"?1\",\n      \"sec-fetch-dest\": \"document\",\n      \"accept-encoding\": \"gzip, deflate, br, zstd\"\n    },\n    \"data\": null,\n  }\n]\n```\n\n## Command line\n\nWSGI server can be launched from command line.\n\n```bash\n$ python wsgi_srv.py -h\nUsage: wsgi_srv.py [options] BINDINGS...\n\nOptions:\n  --version             show program's version number and exit\n  -h, --help            show this help message and exit\n  -t THREADS, --threads=THREADS\n                        set thread number           [default: 2]\n  -l LOGLEVEL, --log-level=LOGLEVEL\n                        set log level from 1 to 100 [default: 20]\n  -i HOST, --ip=HOST    ip to run from              [default: 127.0.0.1]\n  -p PORT, --port=PORT  port to use                 [default: 5000]\n```\n\n`BINDINGS` is a space-separated-list of python module names (ie no `*.py` extention) containing boud python functions. Modules containing bound functions have to be in one of `sys.path` folder. Specific folder can be added using `wsgi_srv.path` file.\n\n## Changes\n\n### 0.4.1\n\n- [x] major changes and improvement, no backward compatibility with 0.3.0\n\n### 0.4.2\n\n- [x] improved `route.uHTTPRequstHandler` response\n- [x] added body encryption/decryption based on `secp256k1` and `AES`\n- [x] added multipart/form-data body management to req module\n- [x] added custom client/server identification\n- [x] added secured secret dump and load\n- [x] added replay attack mitigation\n- [x] added endpoint builder\n- [x] added [pinata](https://pinata.cloud) plugin\n- [x] added [binance](https://binance.com) plugin\n\n### 0.4.3 (dev)\n\n- [x] replaced ECDSA signatures with SCHNORR signatures\n- [x] added C implementation of SCHNORR signatures\n- [x] nonce flushing launch on startup\n\n## Support this project\n\n[![Liberapay receiving](https://img.shields.io/liberapay/goal/Toons?logo=liberapay)](https://liberapay.com/Toons/donate)\n[![Paypal me](https://img.shields.io/badge/PayPal-toons-00457C?logo=paypal\u0026logoColor=white)](https://paypal.me/toons)\n\u003c!-- [![Bitcoin](https://img.shields.io/badge/Donate-bc1q6aqr0hfq6shwlaux8a7ydvncw53lk2zynp277x-ff9900?logo=bitcoin)](https://raw.githubusercontent.com/Moustikitos/python-mainsail/master/docs/img/bc1q6aqr0hfq6shwlaux8a7ydvncw53lk2zynp277x.png) --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoustikitos%2Fmicro-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoustikitos%2Fmicro-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoustikitos%2Fmicro-server/lists"}