{"id":17086156,"url":"https://github.com/kach/hamelin","last_synced_at":"2025-08-24T16:10:13.779Z","repository":{"id":26008718,"uuid":"29451304","full_name":"kach/hamelin","owner":"kach","description":"Revenge of the The Py'd Piper","archived":false,"fork":false,"pushed_at":"2015-07-20T05:10:16.000Z","size":342,"stargazers_count":7,"open_issues_count":3,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-08-09T07:37:14.182Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kach.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-19T03:08:20.000Z","updated_at":"2018-03-04T15:40:01.000Z","dependencies_parsed_at":"2022-08-24T03:00:52.099Z","dependency_job_id":null,"html_url":"https://github.com/kach/hamelin","commit_stats":null,"previous_names":["hardmath123/hamelin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kach/hamelin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kach%2Fhamelin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kach%2Fhamelin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kach%2Fhamelin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kach%2Fhamelin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kach","download_url":"https://codeload.github.com/kach/hamelin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kach%2Fhamelin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271900779,"owners_count":24841114,"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","status":"online","status_checked_at":"2025-08-24T02:00:11.135Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-14T13:27:41.632Z","updated_at":"2025-08-24T16:10:13.735Z","avatar_url":"https://github.com/kach.png","language":"Python","readme":"Hamelin\n=======\n\n`hamelin` is a specification to create multiple interfaces for simple scripts.\n`hamelin` negotiates I/O details so that all you need to manage is your\nscripts' logic. Think of it as a general-purpose, modern-day CGI that isn't\nrestricted to HTTP. Or think of it is a way to make *everything* a filter.\n\nAs a simple example, here's the `net` plugin in action:\n\n    $ python hamelin/net.py localhost 8080 grep --line-buffered \"filter\" \u0026\n    $ cat /usr/share/dict/words | nc localhost 8080\n    filter\n    filterability\n    filterable\n    filterableness\n    filterer\n    filtering\n    filterman\n    infilter\n    nonultrafilterable\n    prefilter\n    refilter\n    ultrafilter\n    ultrafilterability\n    ultrafilterable\n    unfiltered\n\nOr, here's a simple quoteDB/guestbook app written in 8 lines of code:\n```python\nimport fileinput\nimport sys\nprint \"Type your quote below. Hit ^D when done.\"\nsys.stdout.flush()\nf = open(\"/home/***/public_html/qdb.txt\", \"a\")\nf.write(\"\\n~~~~~~~\\n\\n\")\nfor line in fileinput.input():\n    f.write(line)\n    f.close()\n```\n\n    hamelin-net localhost 8080 /usr/bin/python guestbook.py\n\n## Specification v. 0.1 (unstable)\n\nPhrases such as SHOULD, MUST, etc. are as per RFC 2119.\n\nMost `hamelin`-compliant interfaces function as a daemon that runs continuously\non the host machine.\n\nThe daemon instantiates a new subprocess running a given script for *every*\n\"connection\". This should be an actual forked subprocess, not a Popen process\n(Popen tends to dislike two-way communication, and has various security issues\nassociated with the shell). This subprocess is called an instance of a\n**server**. A connection could be any form of input/output. Some possible\nexamples are:\n\n- A user on a teletype (perhaps enhanced with `readline` or `curses`)\n- A telnet or plain socket server (perhaps enhanced with SSL)\n- An IRC bot\n- A RESTful HTTP API\n- A WebSocket server\n\nEach such connection is called a *client*.\n\nThe daemon sends client data to the server's standard input (`stdin`). In\naddition, the server's standard output (`stdout`) is sent back to the client.\nAll data MUST be line-buffered--hamelin is not meant for transferring binary\ndata.\n\nContent in `stderr` MUST be forwarded to the daemon's own `stderr` for\ndebugging purposes. This content MUST NOT be modified when sent to `stderr`,\nbut it MAY be intercepted and used for purposes such as informing the client of\nerrors.\n\nThe server process runs until either it exits or the client closes the\nconnection (this event is obviously defined differently for each connection\ntype).\n\nIf the client closes the connection, the server MUST be sent `SIGTERM`.  Note\nthat sending `SIGTERM` is no guarantee of terminating a process.\n\nIf the server exits, the client connection is closed in an unspecified manner.\nIf the server exits with a status code that is not `0` or `SIGTERM`, the daemon\nSHOULD log this to `stderr`.\n\nA `hamelin` daemon SHOULD set certain environment variables for the subprocess,\nto provide metadata about the connection and setup. These are outlined in the\ntable below:\n\n| Variable    | Meaning |\n| --------    | ------- |\n| `H-VERSION` | The name and version of the `hamelin` daemon running.\n| `H-TYPE`    | The name and version of the connection type, for example, `IRC-0.2-SSL` |\n| `H-CLIENT`  | Information about client. The content here depends on `H-TYPE`. For a web browser, it might be the user-agent string. For IRC, it could be the server/nick/channel. |\n\nAdditional environment variables MAY be set depending on the daemon type. All\n`hamelin` environment variables MUST BE prefixed with `H-`.\n\nFinally, the daemon MUST pass along user-specified command-line arguments to\nthe server *unchanged*, to provide the user with a means to modify the behavior\nof a server script without editing it.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkach%2Fhamelin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkach%2Fhamelin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkach%2Fhamelin/lists"}