{"id":21652130,"url":"https://github.com/andcool-systems/file-uploader","last_synced_at":"2025-11-06T21:02:50.036Z","repository":{"id":213479560,"uuid":"733651107","full_name":"Andcool-Systems/File-uploader","owner":"Andcool-Systems","description":"Simple self-hosted file uploader","archived":false,"fork":false,"pushed_at":"2024-12-22T21:00:23.000Z","size":573,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T20:43:05.566Z","etag":null,"topics":["aiogram3","authentication-system","axios","fastapi","file-sharing","file-upload","fileuploader","html5","nextcord","prisma-client"],"latest_commit_sha":null,"homepage":"https://fu.andcool.ru","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Andcool-Systems.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,"zenodo":null}},"created_at":"2023-12-19T20:13:02.000Z","updated_at":"2025-04-01T08:46:47.000Z","dependencies_parsed_at":"2024-01-02T23:54:24.040Z","dependency_job_id":"27de20f8-8b5c-41e1-ac9c-a60b1e8e3ae5","html_url":"https://github.com/Andcool-Systems/File-uploader","commit_stats":null,"previous_names":["andcool-systems/file-uploader"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Andcool-Systems/File-uploader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andcool-Systems%2FFile-uploader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andcool-Systems%2FFile-uploader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andcool-Systems%2FFile-uploader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andcool-Systems%2FFile-uploader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Andcool-Systems","download_url":"https://codeload.github.com/Andcool-Systems/File-uploader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Andcool-Systems%2FFile-uploader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":283081669,"owners_count":26776095,"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-11-06T02:00:06.180Z","response_time":55,"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":["aiogram3","authentication-system","axios","fastapi","file-sharing","file-upload","fileuploader","html5","nextcord","prisma-client"],"created_at":"2024-11-25T07:51:18.239Z","updated_at":"2025-11-06T21:02:50.000Z","avatar_url":"https://github.com/Andcool-Systems.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# File Uploader\n\nThe file uploader is implemented in the Python programming language using FastAPI. All uploaded files are stored on the server. The API provides the ability to preview and download files based on their file extensions.\n\n## New Feature!\nUpload a .txt file containing only the full link to a resource to shorten it! (The service will automatically redirect you to the specified link when you follow a link to a txt file)\n\n## API Documentation\n\nThe API is currently hosted at [fu.andcool.ru](https://fu.andcool.ru/).   \nPage redirection is handled through the nginx proxy server. The API consists of 2 paths:  \n\n- `/file/` – Endpoint where all files are located.\n- `/api/` – Main API endpoint\n\n### 1.1 Authorization Errors\n\nAll requests requiring the `Authorization` header may encounter errors related to authorization issues.   \nThe `Authorization` header should have the format `Authorization: Bearer \u003ctoken\u003e`.  \n\n#### Response Example\n\nAll errors of this type follow a consistent response format and always return an HTTP code of `401`.   \nThis section will be referred to as `1.1` in the documentation.  \n\n```json\n{\n    \"status\": \"error\",\n    \"message\": \"Auth error\",\n    \"auth_error\": {\n        \"message\": \"error message\",\n        \"errorId\": \u003cerror code\u003e\n    }\n}\n```\n\n**List of errors:** \n\n| errorId | message                                                | Reasons                                            |\n| ------- | ------------------------------------------------------ | -------------------------------------------------- |\n| -1      | No Authorization header provided                       | The request is missing the `Authorization` header  |\n| -2      | Authorization header must have `Bearer \u003ctoken\u003e` format | The `Authorization` header has an incorrect format |\n| -3      | Access token expired                                   | The token has expired                              |\n| -4      | Invalid access token                                   | The token cannot be decrypted                      |\n| -5      | Token not found                                        | The token is not found                             |\n\n### 1.2 Basic API\n\n### Retrieve a file based on the URL.\n`GET /file/\u003cfile_url\u003e` or `GET /f/\u003cfile_url\u003e`  \nSuccessful execution returns a `200` status code and the binary file with the `Content-Type`.   \nIf the file type cannot be determined, the API returns the file in download mode.  \n\n#### Possible Errors\n\n| Error Code | Description    | Possible Reasons                               |\n| ---------- | -------------- | ---------------------------------------------- |\n| 404        | File not found | The file referenced by the code does not exist |\n\n### Upload a file to the server\n`POST /api/upload/{group_id}?include_ext=false`   \nThe request body should contain the file to be uploaded.   \nOnly one file is allowed, and its size should not exceed 100MB.   \nThe maximum request frequency is **2 per minute**.    \n\n**Query params:**  \n\u003e The `group_id` parameter indicates the group to which the file should be uploaded. The parameter can take the value `private`, which means that the file must be linked to a personal account. When passing the `group_id` parameter other than the `private` Authorization header is required.  \n\n**Request body:**  \n\u003e **The `Content-Type` header of the request must be a `multipart/form-data`**  \nThe file must be have `file` key in request body.  \nThe query parameter `include_ext` can be set to `true/false` to indicate whether the file extension should be included in the file URL.  \n\n**Request headers:**  \n\u003eThe request can also include the `Authorization` header, containing the user's unique token.\nIf the token is not provided or is not valid, the `synced` field in the response body will be set to `false`. The file will be uploaded to the server regardless of whether the `Authorization` header is included in the request. The `auth_error` field in the response body contains the authentication error (section `1.1`), and if there is no error, the field will be `{}`.  \n\n#### Response Example\nOn successful execution, the API returns a `200` HTTP code along with a JSON response.  \n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"File uploaded successfully\",\n    \"file_url\": \"4yn-8yjhsu\",\n    \"file_url_full\": \"https://fu.andcool.ru/file/4yn-8yjhsu\",\n    \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\",\n    \"ext\": \".mp4\",\n    \"user_filename\": \"test.mp4\",\n    \"synced\": true,\n    \"auth_error\": {}\n}\n```\n\n#### Possible Errors\n| Error Code | message                             | Possible Reasons                                                               |\n| ---------- | ----------------------------------- | ------------------------------------------------------------------------------ |\n| 400        | No file uploaded                    | No file is given in the request body                                           |\n| 413        | File size exceeds the limit (100MB) | The file size exceeds 100MB                                                    |\n| 400        | Invalid group id                    | `group_id` parameter contains non-numerical value                              |\n| 404        | Group not found                     | The group with provided `group_id` not found                                   |\n| 403        | You are not in the group            | Group is exists, but you are has not permissions to upload files in this group |\n\n### Delete a file\n`GET /api/delete/\u003cfile_url\u003e?key=\u003cunique key\u003e`  \nSuccessful execution returns a `200` status code, removing the file from the server.  \n\n#### Possible Errors\n\n| Error Code | Description        | Possible Reasons                   |\n| ---------- | ------------------ | ---------------------------------- |\n| 404        | File not found     | The file for deletion is not found |\n| 400        | Invalid unique key | The provided unique key is invalid |\n\n### 1.2 Authorization API\n### Login and register\n`POST /api/register`  \n`POST /api/login`  \nRequest limit per minute: 10 times.  \nBoth requests accept the same request body but have different errors.  \n\u003e A Boolean value can be passed to the optional query parameter `bot`. When `bot` is true, a token with a lifetime of 6 months will be generated.\n\n#### Request Example\n\n```json\n{\n    \"username\": \"My cool username\",\n    \"password\": \"My cool password\"\n}\n```\n\nSuccessful execution returns a `200` HTTP code, indicating successful registration / login.  \n\n```json\n{\n    \"status\": \"success\",\n    \"accessToken\": \"\u003ctoken\u003e\",\n    \"username\": \"My cool username\",\n    \"message\": \"logged in with password\"\n}\n```\n\n### Possible Errors\n\n**Common for both requests:**\n\n| errorId | HTTP code | message                       | Reasons                                             |\n| ------- | --------- | ----------------------------- | --------------------------------------------------- |\n| 2       | 400       | No username/password provided | Username/password fields are missing in the request |\n\n**Errors for /register:**\n\n| errorId | HTTP code | message                                         | Reasons                                       |\n| ------- | --------- | ----------------------------------------------- | --------------------------------------------- |\n| 1       | 400       | An account with this name is already registered | A user with the given username already exists |\n\n**Errors for /login:**\n\n| errorId | HTTP code | message        | Reasons            |\n| ------- | --------- | -------------- | ------------------ |\n| 3       | 403       | Wrong password | Incorrect password |\n| 4       | 404       | User not found | Username not found |\n\n### Refresh the token\n`POST /api/refresh_token`  \nRequest limit per minute: 10 times.   \nThe request body includes the `accessToken` field containing only the token (without `Bearer`).   \nSuccessful execution returns a `200` HTTP code along with the `accessToken` field in the request body, containing the new token.  \n\n#### Possible Errors\n\n| errorId | HTTP code | message                  | Reasons                                           |\n| ------- | --------- | ------------------------ | ------------------------------------------------- |\n| 5       | 400       | No access token provided | The `accessToken` field is missing in the request |\n\nErrors described in section `1.1` may also occur.  \n\n### Log out of the account\n`POST /api/logout`     \nRequest limit per minute: 10 times.   \nEndpoint takes the `Authorization` header containing the access token.   \nSuccessful execution of the request deletes the provided token and returns a `200` HTTP code  \n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n\n\n### Get a list of files.\n`GET /api/get_files/{group_id}`  \nIt takes the `Authorization` header containing the access token.   \nRetrieves a list of all files associated with this account.  \n\n\u003e The `group_id` parameter shows which group to get the files from. If the parameter is set to `private`, the files will be taken from a personal account, otherwise Authorization header is required\n\n#### Response Example\n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"files got successfully\",\n    \"username\": \"My cool username\",\n    \"is_group_owner\": true,\n    \"data\": [\n        {\n            \"file_url\": \"4yn-8yjhsu\",\n            \"file_url_full\": \"https://fu.andcool.ru/file/4yn-8yjhsu\",\n            \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\",\n            \"ext\": \".mp4\",\n            \"user_filename\": \"test.mp4\",\n            \"creation_date\": \"1.1.1971\",\n            \"synced\": true\n        },\n        {\n            \"file_url\": \"4yn-8yjhsR\",\n            \"file_url_full\": \"https://fu.andcool.ru/file/4yn-8yjhsR\",\n            \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\",\n            \"ext\": \".mp4\",\n            \"user_filename\": \"test1.mp4\",\n            \"creation_date\": \"1.1.1971\",\n            \"synced\": true\n        }\n    ]\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                  | Possible Reasons                                                               |\n| ---------- | ------------------------ | ------------------------------------------------------------------------------ |\n| 400        | Invalid group id         | `group_id` parameter contains non-numerical value                              |\n| 404        | Group not found          | The group with provided `group_id` not found                                   |\n| 403        | You are not in the group | Group is exists, but you are has not permissions to upload files in this group |\n\n\n### Transfer local files to an account.\n`POST /api/transfer`  \nIt takes the `Authorization` header containing the access token.  \n\n\u003e The request transfers local files to the account. The endpoint takes files from the `data` field in the request body and sequentially binds each file to an account. If the binding of any file failed, then these files will be returned in the response body in the `unsuccess` field. The file is transferred by their `file_url` and `key`\n\n#### Request body example\n```json\n{   \n    \"data\":[\n        {\n            \"file_url\": \"4yn-8yjhsu\",\n            \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\"\n        },\n        {\n            \"file_url\": \"4yn-8yjhsR\",\n            \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\"\n        }\n    ]\n}\n```\n\n#### Response example\n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"transferred\", \n    \"unsuccess\": [\n        {\n            \"file_url\": \"4yn-8yjhsR\",\n            \"key\": \"6b9a1c1b-5594-4cb9-8d49-99a4c28782a1\"\n        }\n    ]\n}\n\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                         | Possible Reasons                               |\n| ---------- | ------------------------------- | ---------------------------------------------- |\n| 400        | Couldn't parse request body     | No request body provided                       |\n| 400        | No `data` field in request body | Couldn't not find `data` field in request body |\n\n## Groups\n\n### Create file group\n`POST /api/create_group`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Creates a group with the passed name. The maximum length of a group name is 50 characters.\n\n#### Request body example\n```json\n{   \n    \"group_name\": \"New group\"\n}\n```\n\n#### Response example\n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"created\",\n    \"name\": \"New group\",\n    \"group_id\": 12345678,\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                               | Possible Reasons                                     |\n| ---------- | ------------------------------------- | ---------------------------------------------------- |\n| 400        | No `group_name` provided              | Couldn't not find `group_name` field in request body |\n| 400        | Group name length exceeded (50 chars) | Too long group name                                  |\n\n### Delete file group\n`DELETE /api/delete_group/{group_id}`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Deletes a group with the passed `group_id`.\n\n\n#### Response example\n\n```json\n{\n    \"status\": \"success\", \n    \"message\": \"deleted\"\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                                            | Possible Reasons                       |\n| ---------- | -------------------------------------------------- | -------------------------------------- |\n| 404        | Group not found                                    | Group with passed `group_id` not found |\n| 403        | You don't have any permissions to delete this group | You are not owner of this group        |\n\n### Generate a new invite link\n`GET /api/generate_invite/{group_id}`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Generates a invite link for group with the passed `group_id`.\n\n\n#### Response example\n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"created\",\n    \"invite_link\": \"https://fu.andcool.ru/invite/DSAfd4-hpoqFDFj\"\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                       | Possible Reasons                       |\n| ---------- | ----------------------------- | -------------------------------------- |\n| 404        | Group not found               | Group with passed `group_id` not found |\n| 403        | You don't have any permissions | You are not owner of this group        |\n\n### Join to a group\n`POST /api/join/{invite_link}`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Joins to a group by passed `invite_link`.\n\n\n#### Response example\n\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"created\",\n    \"name\": \"New group\",\n    \"group_id\": 12345678,\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                      | Possible Reasons              |\n| ---------- | ---------------------------- | ----------------------------- |\n| 404        | Invite link not found        | Could not found a invite link |\n| 400        | You are already in the group | You are already in the group  |\n\n\n### Leave from group\n`POST /api/leave/{group_id}`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Leaves from group with passed `group_id`\n\n\n#### Response example\n```json\n{\n    \"status\": \"success\", \n    \"message\": \"leaved\"\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message                  | Possible Reasons                       |\n| ---------- | ------------------------ | -------------------------------------- |\n| 404        | Group not found          | Group with passed `group_id` not found |\n| 400        | You are not in the group | You are not in the group               |\n\n\n### Get info about invite link\n`GET /api/invite_info/{invite_link}`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Gives an information about group about invite link.\n\n\n#### Response example\n```json\n{\n    \"status\": \"success\",\n    \"message\": \"Info got successfully\",\n    \"name\": \"New group\",\n    \"group_id\": 12345678,\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n| Error Code | message               | Possible Reasons              |\n| ---------- | --------------------- | ----------------------------- |\n| 404        | Invite link not found | Could not found a invite link |\n\n\n### Get all group from account\n`GET /api/get_groups`  \nIt takes the `Authorization` header containing the access token.  \n\u003e Get list of groups linked to an account.\n\n\n#### Response example\n```json\n{\n    \"status\": \"success\", \n    \"message\": \"groups got successfully\", \n    \"groups\": [\n        {\n            \"name\": \"Bim-Bim\",\n            \"group_id\": 12345679\n        },\n        {\n            \"name\": \"Bam-Bam\",\n            \"group_id\": 12345677\n        }\n    ]\n}\n```\n\n#### Possible Errors\n\nErrors described in section `1.1` may occur as well.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandcool-systems%2Ffile-uploader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandcool-systems%2Ffile-uploader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandcool-systems%2Ffile-uploader/lists"}