{"id":19090130,"url":"https://github.com/destrangis/httpuploader","last_synced_at":"2026-05-24T15:30:15.803Z","repository":{"id":62569709,"uuid":"173603528","full_name":"destrangis/httpuploader","owner":"destrangis","description":"Simple directory listing http server that also allows to upload files","archived":false,"fork":false,"pushed_at":"2024-01-21T16:28:35.000Z","size":106,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-11T09:23:58.473Z","etag":null,"topics":["python3","uploader","web-server","wsgi","wsgi-application"],"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/destrangis.png","metadata":{"files":{"readme":"README.rst","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":"2019-03-03T17:00:19.000Z","updated_at":"2024-01-21T16:28:39.000Z","dependencies_parsed_at":"2024-11-09T03:02:41.290Z","dependency_job_id":"a3f2efd5-fbf0-4ada-88af-356506a17c7e","html_url":"https://github.com/destrangis/httpuploader","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/destrangis%2Fhttpuploader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/destrangis%2Fhttpuploader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/destrangis%2Fhttpuploader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/destrangis%2Fhttpuploader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/destrangis","download_url":"https://codeload.github.com/destrangis/httpuploader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240136997,"owners_count":19753650,"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":["python3","uploader","web-server","wsgi","wsgi-application"],"created_at":"2024-11-09T03:02:02.045Z","updated_at":"2026-05-24T15:30:15.725Z","avatar_url":"https://github.com/destrangis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"HTTPUPLOADER\n============\n\nAn HTTP server that displays a directory listing, much like Python's\ndefault http.server module, except this one allows directory creation\nand file upload by the user.\n\nThis can be useful anytime you want to quickly share files a directory,\nfor example in a classroom where the students need to obtain one or\nmore files from the instructor and need to upload their exercise.\nIn that case the instructor finds out their machine's IP address,\ncommunicates the url ``http://ipaddress:port/`` to the students, opens\na command window and runs httpuploader like this::\n\n   $ python3 httpuploader.py -p port -d directory\n\nand they now have a quick server.\n\n.. image:: https://raw.githubusercontent.com/destrangis/httpuploader/master/Screenshot_httpuploader.png\n\nHttpuploader is a single file with **no dependencies** outside the\nPython Standard Library. It is a WSGI application so that it can be\nimported as a module and run\nin any WSGI compliant server like mod_wsgi, Rocket, uWSGI, etc. just by\ninstantiating the ``WSGIApp`` class with the top directory to serve and\na boolean value telling it whether to show hidden files and directories.\n\nThe client's browsers need Javascript activated. It won't work in old\nversions of Internet Explorer though. Get the latest version or Edge.\n\n\nInstalling\n----------\n\nAn install is not really necessary since, being a single file, it can be\njust dropped anywhere convenient. However a ``setup.py`` program is provided\nfor convenience so that it can be downloaded from\n`PyPI.org \u003chttps://pypi.org\u003e`_ using ``pip``::\n\n    $ pip3 install httpuploader\n\nIt can also be installed using ``setup.py`` as follows::\n\n    $ python3 setup.py install\n\n\nAPI\n---\n\nThis version contains a RESTful API that can be used by other applications\nas a remote file manager, allowing not only to upload and download files\nand create directories, but to delete files and entire trees, calculate\nchecksums, download compressed files and compressed archive directories,\nand copy and move on the same or different directories.\n\nIt is possible to enable or disable all, some or none of the possible\noperations on either a global or per directory (or file) basis. See the\nconfiguration_ section.\n\nThe API responds always with a JSON object with the following structure::\n\n    {\n        \"version\": \u003cthe API version\u003e,\n        \"rc\": \u003cthe status code, e.g. 404\u003e,\n        \"msg\": \u003cthe status message, e.g. \"Not found\"\u003e,\n        \"data\": \u003ca json object containing the response of the call\u003e\n    }\n\nIn the case of errors, the ``data`` field contains an object, containing\na field named ``extra`` with an extended explanation of the error.\n\nThe API calls have the form ``/api/\u003cversion\u003e/resource?cmd=\u003ccommand\u003e\u0026\u003cargs...\u003e``\nwhere ``\u003cversion\u003e`` is the API version number, can be just ``1``, ``1.0`` or\n``1.0.0``. At this moment, it is the only version available, but version\n``1`` will indicate the highest API version available of the ``1.x.x``\nrange.\n\nAvailable Commands\n~~~~~~~~~~~~~~~~~~\n\nDirectory Operations\n....................\n\nlist\n,,,,\n\nList the contents of a directory. Does not need to be specified::\n\n    GET /api/1/\u003cdirectory\u003e?cmd=list\n    GET /api/1/\u003cdirectory\u003e\n\nThe response data field contains the following fields:\n\nname:\n    Name of the directory\nfiles:\n    List of file objects\ndirectories:\n    List of directories\nlinks:\n    List of possible operations\n\narchive\n,,,,,,,\n\nDownload a compressed archive with the contents of the directory::\n\n    GET /api/1/\u003cdirectory\u003e?cmd=archive\u0026format=\u003czip|tar.gz\u003e\n\n\nmkdir\n,,,,,\n\nCreate new directory::\n\n    POST /api/1/\u003cdirectory\u003e?cmd=mkdir\n\nIf successful, the response will be ``204 No content``\n\nupload\n,,,,,,\n\nUpload file(s) to directory::\n\n    POST /api/1/\u003cdirectory\u003e?cmd=upload\n\nThe files can be uploaded by simply sending the file in the body of the\nrequest, or sending several files in a multipart message.\n\nIf successful, the response will be ``204 No content``\n\ndelete\n,,,,,,\n\nRemove the directory::\n\n    DELETE /api/1/\u003cdirectory\u003e\n\nThis command removes the entire tree without asking for confirmation. Use\nwith caution.\n\nIf successful, the response will be ``204 No content``\n\n\nFile Operations\n...............\n\ndownload\n,,,,,,,,\n\nDownload a file::\n\n    GET /\u003cpath\u003e\n    GET /api/1/\u003cpath\u003e\n    GET /api/1/\u003cpath\u003e?cmd=download\n\nIt is not necessary to specify the command or the API/version prefix.\nThe mime type of the file is guessed based on the name using the Python\nStandard Library ``mimetypes`` module.\n\ninfo\n,,,,\n\nMiscellaneous information about a file::\n\n    GET /api/\u003cversion\u003e/path?cmd=info\n\nUpon success, the response ``data`` field will contain a JSON object with\nthe following files:\n\nname:\n    The name of the file.\nsize:\n    The size in bytes, as a number.\nhuman_size:\n    The size in a string, expressed in the easiest to read unit.\npath:\n    Path from the top directory.\nchecksum:\n    The sha256 checksum.\natime:\n    Last access time, as a string in ISO format.\nmtime:\n    Last modification time, as a string in ISO format.\nctime:\n    Creatrion time, as a string in ISO format.\n\nExample::\n\n    GET /api/1/opt/jdk1.8.0_51/COPYRIGHT?cmd=info\n    {\n      \"rc\": 200,\n      \"msg\": \"OK\",\n      \"api_version\": \"1.0.0\",\n      \"data\": {\n        \"name\": \"COPYRIGHT\",\n        \"size\": 3244,\n        \"human_size\": \"3.17 KB\",\n        \"path\": \"/opt/jdk1.8.0_51\",\n        \"checksum\": \"89471aea3957922df21c7088d2687c4e43f5ff14e635e7d971083dde540b45e3\",\n        \"atime\": \"2019-11-15T23:33:56.430384+00:00\",\n        \"mtime\": \"2015-06-09T02:37:58+00:00\",\n        \"ctime\": \"2015-07-20T18:17:40.394882+00:00\"\n      }\n    }\n\ncompress\n,,,,,,,,\n\nCompress and download a single file::\n\n    GET /api/1/\u003cpath\u003e?cmd=compress\u0026format=\u003czip|tar.gz\u003e\n\nchecksum\n,,,,,,,,\n\nCompute, and optionally check, the SHA256 checksum of a file::\n\n    GET /api/1/\u003cpath\u003e?cmd=checksum\n    GET /api/1/\u003cpath\u003e?cmd=checksum\u0026match=\u003cchecksum\u003e\n\nIf no arguments are given the checksum of the file is computed and\nreturned in the ``data`` field of the JSON response, which has the\nfollowing fields:\n\nfilename:\n    The base filename for which the checksum was computed.\nchecksum:\n    The SHA256 digest as a lower case hexadecimal number.\n\nIf the ``match`` argument was used, it is used to compare it to the\ncomputed checksum, and the following field is returned in addition to\nthe above:\n\nmatch:\n    A boolean indicating whether the checksums match.\n\nExample::\n\n    GET /api/1/opt/jdk1.8.0_51/COPYRIGHT?cmd=checksum\u0026match=89471aea3957922df21c7088d2687c4e43f5ff14e635e7d971083dde540b45e3\n    {\n      \"rc\": 200,\n      \"msg\": \"OK\",\n      \"api_version\": \"1.0.0\",\n      \"data\": {\n        \"checksum\": \"89471aea3957922df21c7088d2687c4e43f5ff14e635e7d971083dde540b45e3\",\n        \"filename\": \"COPYRIGHT\",\n        \"match\": true\n      }\n    }\n\n\ncopy\n,,,,\n\nCopy a file::\n\n    POST /api/1/\u003cpath\u003e?cmd=copy\u0026dest=\u003cnewfile\u003e\n\nIf successful, the response will be ``204 No content``\n\n\nmove\n,,,,\n\nMove or rename a file::\n\n    POST /api/1/\u003cpath\u003e?cmd=move\u0026dest=\u003cnewfile\u003e\n\nIf successful, the response will be ``204 No content``\n\n\n.. _configuration:\n\nConfiguration\n-------------\n\nIt is possible to manage permissions for each of the operations\nsupported by the API on a global or per directory or file basis. These\npermissions should be specified in a Windows .ini configuration file.\n\nEach section in the .ini file has a variable called 'allow' whose contents\nare the names of the individual API commands, separated by commas, or\nthe special words ``all`` or ``none`` which grant permission for all\nactions or deny them respectively.\n\nThere is a ``DEFAULT`` section that contains the global commands that\nare allowed in all the directories not specified and sections for each\ndirectory or file for which we want different permissions. For example,\nconsider the following ``.ini`` file::\n\n    [DEFAULT]\n    allow = list, download, mkdir, upload, info, checksum\n    [/dir_004]\n    allow = ${DEFAULT:allow}, compress, archive\n    [/dir_003]\n    allow = ${/dir_004:allow}\n    [/dir_003/dir_025]\n    allow = all\n    [/dir_003/dir_024/dir_026]\n    allow = none\n\nThe default section applies globally and provides a restricted, but\nreasonable set of commands. The sections ``[/dir_004]`` and ``[/dir_003]``\nspecify an augmented set of permissions, based on those of the default\nsection. This is important: once we have a section for a directory, the\nglobal permissions no longer apply and we must explicitly allow all the\ncommand that we want. In this example we are *inheriting*\nthe permissions using the *Extended Interpolation* notation provided by\nthe Python ``configparser`` module.\n\nAll operations will be permitted for the directory ``/dir_003/dir_025``\nand everything under it, including copying and deletion, and on\ndirectory ``/dir_003/dir_024/dir_026`` no operations whatsoever are\npermitted and we won't even be able to list its contents.\n\nThe configuration file is specified using the ``--config cfg`` command\nline option, e.g.::\n\n    $ httpuploader --config config.ini --rootdir $HOME\n\nIf no configuration file is specified, the default permissions settings\nwill be::\n\n    [DEFAULT]\n    allow = list, download, mkdir, upload\n\n\nLicense\n-------\nThis software is released under the **MIT License**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdestrangis%2Fhttpuploader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdestrangis%2Fhttpuploader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdestrangis%2Fhttpuploader/lists"}