neocities-neo


Nameneocities-neo JSON
Version 0.0.1 PyPI version JSON
download
home_pageNone
SummaryAn api for neocities.org
upload_time2025-09-12 20:19:14
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseGPLv3
keywords api cli neocities
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # neocities

A python api for neocities.org

# Installation

    pip install neocities-neo

# Usage

## CLI

```
usage: neocities [-h] [-u USERNAME] [-p PASSWORD] [-a API KEY] [-w TIME] [-W TIME] [-r NUM]
                   [--retry-wait TIME] [--force-retry] [-m TIME] [-k] [-L] [-A UA] [-x DICT]
                   [-H HEADER] [-b COOKIE] [-B BROWSER]
                   {key,sync,info,list,delete,purge,upload,upload-raw,hash,download} ...

Tool for interacting with neocities.org

If credentials for authorization are not passed through arguments, they'll be read from
$NEOCITIES_API or $NEOCITIES_USERNAME and $NEOCITIES_PASSWORD environment variables.

General:
  -h, --help            Show this help message and exit
  -u, --username USERNAME
                        Specify username for authentication
  -p, --password PASSWORD
                        Specify password for authentication
  -a, --api API KEY     Specify api key for authentication

subcommands:
  {key,sync,info,list,delete,purge,upload,upload-raw,hash,download}
    key                 get api key
    sync                ensure the same file structure on site
    info                get info about site
    list                list files on site
    delete              remove files recursively from site
    purge               remove all files from site
    upload              upload files to site
    upload-raw          upload files to site
    hash                check if files on site have the same sha1 hash
    download            download files from site recusively

Request settings:
  -w, --wait TIME       Sets waiting time for each request
  -W, --wait-random TIME
                        Sets random waiting time for each request to be from 0 to TIME
  -r, --retries NUM     Sets number of retries for failed request to NUM
  --retry-wait TIME     Sets interval between each retry
  --force-retry         Retry no matter the error
  -m, --timeout TIME    Sets request timeout
  -k, --insecure        Ignore ssl errors
  -L, --location        Allow for redirections, can be dangerous if credentials are passed in
                        headers
  -A, --user-agent UA   Sets custom user agent
  -x, --proxies DICT    Set requests proxies dictionary, e.g. -x
                        '{"http":"127.0.0.1:8080","ftp":"0.0.0.0"}'
  -H, --header HEADER   Set curl style header, can be used multiple times e.g. -H 'User: Admin'
                        -H 'Pass: 12345'
  -b, --cookie COOKIE   Set curl style cookie, can be used multiple times e.g. -b 'auth=8f82ab'
                        -b 'PHPSESSID=qw3r8an829'
  -B, --browser BROWSER
                        Get cookies from specified browser e.g. -B firefox
```

Each subcommand also has it's own `--help` message.

### key

Get a api key from username and password login

```shell
KEY=$(neocities --username USER --password PASS key)
```

This key can be passed through `--api` option or `$NEOCITIES_API` environment variable

```shell
neocities --api $KEY list /

export NEOCITIES_API="$KEY"
neocities list /
```

### info

Get info about site in json, passing without site's name requires to be logged in and displays info about your site.

```shell
neocities info
```

```json
{
  "sitename": "tuvimen",
  "views": 4226,
  "hits": 7052,
  "created_at": "Thu, 30 Jan 2025 17:42:37 -0000",
  "last_updated": "Thu, 11 Sep 2025 08:58:21 -0000",
  "domain": null,
  "tags": [
    "programming"
  ]
}
```

If site's name is given no authentication is required

```shell
neocities info tuvimen
```

### list

Return a list of site's files, if no path is given it defaults to `/`. Getting list of `/` always returns recursive tree of the whole site, this happens only for this path.

```shell
neocities list
```

Multiple paths can be queried

```shell
neocities list /projects /resources/css
```

Size and modification date can be printed along path when `-l` is specified, `-h` changes size into human readable format e.g. `2.2M`, `85.4K`

```shell
neocities list -lh /
```

Results can be returned as json

```
neocities list --json /
```

If path leads to a file no information is returned, this undesired behaviour comes from neocities api

```shell
neocities list /info.html
```

### sync

Ensure that site has the exact same files as under the given path, if not specified the path defaults to current directory.

```shell
neocities sync my-site-to-be-synced
```

This removes all files on site that aren't in path and upload files that are not on site or have different checksum. If directories have the same contents nothing gets transferred.

Note that this option doesn't log any changes so it might appear stuck, even though it uploads files.

This command can also sync individual directories on site

```shell
neocities sync ./static /static
```

### purge

Remove all files on site, since `/index.html` is protected it'll get replaced by empty file.

```shell
neocities purge
```

There's no warning or confirmation for using this command, if you type it by mistake everything disappears.


### delete

Removes files or directories recursively, `/` cannot be deleted

```shell
neocities delete /unwanted-file.html /old-directory/
```

### upload

Upload files or directories to remote, empty directories won't get created since there's no api for that.

```shell
neocities upload index.html posts/ /
```

Upload `list.html` to `/list2.html`

```shell
neocities upload list.html /list2.html
```

Even if directories on site don't exist they'll get created if uploaded file is in it

```shell
neocities upload file.html /a/b/c/d/e/f/g/h/f.html
```

Files with extensions not allowed by neocities will be ignored even if explicitly given in arguments.

### download

Download files and directories from site to local directory

```shell
neocities download /index.html /projects/ ./local-dir
```

### upload-raw

Upload files or directories where every following argument is it's remote destination

```shell
neocities upload-raw index.html /index.html static/css/ /css
```

Compared to `upload` subcommand, this allows to transfer more complex directory structures with only one request.

### hash

Check if files are the same as on remote, each remote file path has to be followed by local file path. Directories cannot be passed. Remote files that are different will be returned.

```shell
neocities hash /index.html ./static/index.html /res/favicon.ico static/res/favicon-different.ico
```

outputs

```shell
/res/favicon.ico
```

## Library

### importing and initializing

```python
from neocities import (
    neocities,
    NeocitiesError,
    RequestError,
    AuthorizationError,
    OpFailedError,
    FileNotFoundError
)

neo = Neocities(wait=0.8, timeout=60) # kwargs are passed to treerequests lib

try:
    neo.login(env=True) # login from environment variables
except AuthenticationError as e:
    print(repr(e), file=sys.stderr)
    sys.exit(1)

print(neo.list('/'))
```

### errors

All exceptions derive from `NeocitiesError`.

For authentication failure `AuthenticationError` is raised.

Any errors regarding http connection raise `RequestError`.

Failure to perform operation raises `OpFailedError`, `FileNotFoundError` derives from it.

### Neocities(**kwargs)

kwargs are passed to treerequests session object https://github.com/TUVIMEN/treerequests

### login(self, username: str = "", password: str = "", api: str = "", env: bool = False)

Sets authentication credentials.

arg( api ) refers to api key, if empty both arg( username ) and arg( password ) have to be specified.

If arg( env ) is set to True credentials are read from environment variables: $NEOCITIES_API, $NEOCITIES_USERNAME, $NEOCITIES_PASSWORD

### key(self) -> str

returns( api key for a user )

### info(self, sitename="") -> dict

Gets info of user's site or about arg( sitename ) if it's not empty.

Authentication is not required when arg( sitename ) is not empty.

returns( Dictionary of site info )

### list(self, paths: str | Path | List[str | Path] = "") -> List[dict]

Lists file structure of site at arg( path ), if empty arg( path ) defaults to "/".

return( List of dictionaries describing site's file sructure )

### delete(self, paths: str | List[str])

Removes arg( paths ) from site, if directory path is passed it'll be removed recursively.

### upload_hash(self, files: dict[str, str]) -> dict[str, bool]

Checks if files on site have the same sha1 hash, this api is redundant since method( list ) already returns sha1 hashes for all files.

arg( files ) is a dictionary representing files, where keys are file paths and values are suspected sha1 hashes.

returns( Dictionary where keys are file paths and values are `True` if remote files have the same hash, otherwise `False` )

### upload_hash_files(self, files: dict[str, str | Path]) -> dict[str, bool]

Same as method( upload_hash ) but values of arg( files ) are paths of files from which sha1 hash will be calculated.

### upload_text(self, paths: dict[str, str | bytes])

Uploads files from arg( paths ), where key is remote path and value is contents of file

### upload(self, paths: dict[str | Path, str], follow_links: bool = False)

Uploads files from arg( paths ), where keys are local paths and values remote paths.

If any local path is a directory,  multiple calls will be made to transfer all matching files under it.

### purge(self)

Removes everything from site, since `index.html` can't be removed it'll be replaced with empty file.

### sync(self, source: str | Path, dest: str = "", follow_links: bool = False)

Ensures that site structure is exactly the same as that under arg( source ) directory. Files having the same hashes are not retransferred.

### download(self, sources: str | List[str], dest: str | Path = "")

Downloads site files from arg( sources ) to arg( dest ), arg( sources ) can be either a list of remote paths or just a string.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "neocities-neo",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "api, cli, neocities",
    "author": null,
    "author_email": "Dominik Stanis\u0142aw Suchora <hexderm@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/cd/b9/8b70668b2ea023a3f2fcea5edf83c67004ca3e574d6a23dafb801b6c61da/neocities_neo-0.0.1.tar.gz",
    "platform": null,
    "description": "# neocities\n\nA python api for neocities.org\n\n# Installation\n\n    pip install neocities-neo\n\n# Usage\n\n## CLI\n\n```\nusage: neocities [-h] [-u USERNAME] [-p PASSWORD] [-a API KEY] [-w TIME] [-W TIME] [-r NUM]\n                   [--retry-wait TIME] [--force-retry] [-m TIME] [-k] [-L] [-A UA] [-x DICT]\n                   [-H HEADER] [-b COOKIE] [-B BROWSER]\n                   {key,sync,info,list,delete,purge,upload,upload-raw,hash,download} ...\n\nTool for interacting with neocities.org\n\nIf credentials for authorization are not passed through arguments, they'll be read from\n$NEOCITIES_API or $NEOCITIES_USERNAME and $NEOCITIES_PASSWORD environment variables.\n\nGeneral:\n  -h, --help            Show this help message and exit\n  -u, --username USERNAME\n                        Specify username for authentication\n  -p, --password PASSWORD\n                        Specify password for authentication\n  -a, --api API KEY     Specify api key for authentication\n\nsubcommands:\n  {key,sync,info,list,delete,purge,upload,upload-raw,hash,download}\n    key                 get api key\n    sync                ensure the same file structure on site\n    info                get info about site\n    list                list files on site\n    delete              remove files recursively from site\n    purge               remove all files from site\n    upload              upload files to site\n    upload-raw          upload files to site\n    hash                check if files on site have the same sha1 hash\n    download            download files from site recusively\n\nRequest settings:\n  -w, --wait TIME       Sets waiting time for each request\n  -W, --wait-random TIME\n                        Sets random waiting time for each request to be from 0 to TIME\n  -r, --retries NUM     Sets number of retries for failed request to NUM\n  --retry-wait TIME     Sets interval between each retry\n  --force-retry         Retry no matter the error\n  -m, --timeout TIME    Sets request timeout\n  -k, --insecure        Ignore ssl errors\n  -L, --location        Allow for redirections, can be dangerous if credentials are passed in\n                        headers\n  -A, --user-agent UA   Sets custom user agent\n  -x, --proxies DICT    Set requests proxies dictionary, e.g. -x\n                        '{\"http\":\"127.0.0.1:8080\",\"ftp\":\"0.0.0.0\"}'\n  -H, --header HEADER   Set curl style header, can be used multiple times e.g. -H 'User: Admin'\n                        -H 'Pass: 12345'\n  -b, --cookie COOKIE   Set curl style cookie, can be used multiple times e.g. -b 'auth=8f82ab'\n                        -b 'PHPSESSID=qw3r8an829'\n  -B, --browser BROWSER\n                        Get cookies from specified browser e.g. -B firefox\n```\n\nEach subcommand also has it's own `--help` message.\n\n### key\n\nGet a api key from username and password login\n\n```shell\nKEY=$(neocities --username USER --password PASS key)\n```\n\nThis key can be passed through `--api` option or `$NEOCITIES_API` environment variable\n\n```shell\nneocities --api $KEY list /\n\nexport NEOCITIES_API=\"$KEY\"\nneocities list /\n```\n\n### info\n\nGet info about site in json, passing without site's name requires to be logged in and displays info about your site.\n\n```shell\nneocities info\n```\n\n```json\n{\n  \"sitename\": \"tuvimen\",\n  \"views\": 4226,\n  \"hits\": 7052,\n  \"created_at\": \"Thu, 30 Jan 2025 17:42:37 -0000\",\n  \"last_updated\": \"Thu, 11 Sep 2025 08:58:21 -0000\",\n  \"domain\": null,\n  \"tags\": [\n    \"programming\"\n  ]\n}\n```\n\nIf site's name is given no authentication is required\n\n```shell\nneocities info tuvimen\n```\n\n### list\n\nReturn a list of site's files, if no path is given it defaults to `/`. Getting list of `/` always returns recursive tree of the whole site, this happens only for this path.\n\n```shell\nneocities list\n```\n\nMultiple paths can be queried\n\n```shell\nneocities list /projects /resources/css\n```\n\nSize and modification date can be printed along path when `-l` is specified, `-h` changes size into human readable format e.g. `2.2M`, `85.4K`\n\n```shell\nneocities list -lh /\n```\n\nResults can be returned as json\n\n```\nneocities list --json /\n```\n\nIf path leads to a file no information is returned, this undesired behaviour comes from neocities api\n\n```shell\nneocities list /info.html\n```\n\n### sync\n\nEnsure that site has the exact same files as under the given path, if not specified the path defaults to current directory.\n\n```shell\nneocities sync my-site-to-be-synced\n```\n\nThis removes all files on site that aren't in path and upload files that are not on site or have different checksum. If directories have the same contents nothing gets transferred.\n\nNote that this option doesn't log any changes so it might appear stuck, even though it uploads files.\n\nThis command can also sync individual directories on site\n\n```shell\nneocities sync ./static /static\n```\n\n### purge\n\nRemove all files on site, since `/index.html` is protected it'll get replaced by empty file.\n\n```shell\nneocities purge\n```\n\nThere's no warning or confirmation for using this command, if you type it by mistake everything disappears.\n\n\n### delete\n\nRemoves files or directories recursively, `/` cannot be deleted\n\n```shell\nneocities delete /unwanted-file.html /old-directory/\n```\n\n### upload\n\nUpload files or directories to remote, empty directories won't get created since there's no api for that.\n\n```shell\nneocities upload index.html posts/ /\n```\n\nUpload `list.html` to `/list2.html`\n\n```shell\nneocities upload list.html /list2.html\n```\n\nEven if directories on site don't exist they'll get created if uploaded file is in it\n\n```shell\nneocities upload file.html /a/b/c/d/e/f/g/h/f.html\n```\n\nFiles with extensions not allowed by neocities will be ignored even if explicitly given in arguments.\n\n### download\n\nDownload files and directories from site to local directory\n\n```shell\nneocities download /index.html /projects/ ./local-dir\n```\n\n### upload-raw\n\nUpload files or directories where every following argument is it's remote destination\n\n```shell\nneocities upload-raw index.html /index.html static/css/ /css\n```\n\nCompared to `upload` subcommand, this allows to transfer more complex directory structures with only one request.\n\n### hash\n\nCheck if files are the same as on remote, each remote file path has to be followed by local file path. Directories cannot be passed. Remote files that are different will be returned.\n\n```shell\nneocities hash /index.html ./static/index.html /res/favicon.ico static/res/favicon-different.ico\n```\n\noutputs\n\n```shell\n/res/favicon.ico\n```\n\n## Library\n\n### importing and initializing\n\n```python\nfrom neocities import (\n    neocities,\n    NeocitiesError,\n    RequestError,\n    AuthorizationError,\n    OpFailedError,\n    FileNotFoundError\n)\n\nneo = Neocities(wait=0.8, timeout=60) # kwargs are passed to treerequests lib\n\ntry:\n    neo.login(env=True) # login from environment variables\nexcept AuthenticationError as e:\n    print(repr(e), file=sys.stderr)\n    sys.exit(1)\n\nprint(neo.list('/'))\n```\n\n### errors\n\nAll exceptions derive from `NeocitiesError`.\n\nFor authentication failure `AuthenticationError` is raised.\n\nAny errors regarding http connection raise `RequestError`.\n\nFailure to perform operation raises `OpFailedError`, `FileNotFoundError` derives from it.\n\n### Neocities(**kwargs)\n\nkwargs are passed to treerequests session object https://github.com/TUVIMEN/treerequests\n\n### login(self, username: str = \"\", password: str = \"\", api: str = \"\", env: bool = False)\n\nSets authentication credentials.\n\narg( api ) refers to api key, if empty both arg( username ) and arg( password ) have to be specified.\n\nIf arg( env ) is set to True credentials are read from environment variables: $NEOCITIES_API, $NEOCITIES_USERNAME, $NEOCITIES_PASSWORD\n\n### key(self) -> str\n\nreturns( api key for a user )\n\n### info(self, sitename=\"\") -> dict\n\nGets info of user's site or about arg( sitename ) if it's not empty.\n\nAuthentication is not required when arg( sitename ) is not empty.\n\nreturns( Dictionary of site info )\n\n### list(self, paths: str | Path | List[str | Path] = \"\") -> List[dict]\n\nLists file structure of site at arg( path ), if empty arg( path ) defaults to \"/\".\n\nreturn( List of dictionaries describing site's file sructure )\n\n### delete(self, paths: str | List[str])\n\nRemoves arg( paths ) from site, if directory path is passed it'll be removed recursively.\n\n### upload_hash(self, files: dict[str, str]) -> dict[str, bool]\n\nChecks if files on site have the same sha1 hash, this api is redundant since method( list ) already returns sha1 hashes for all files.\n\narg( files ) is a dictionary representing files, where keys are file paths and values are suspected sha1 hashes.\n\nreturns( Dictionary where keys are file paths and values are `True` if remote files have the same hash, otherwise `False` )\n\n### upload_hash_files(self, files: dict[str, str | Path]) -> dict[str, bool]\n\nSame as method( upload_hash ) but values of arg( files ) are paths of files from which sha1 hash will be calculated.\n\n### upload_text(self, paths: dict[str, str | bytes])\n\nUploads files from arg( paths ), where key is remote path and value is contents of file\n\n### upload(self, paths: dict[str | Path, str], follow_links: bool = False)\n\nUploads files from arg( paths ), where keys are local paths and values remote paths.\n\nIf any local path is a directory,  multiple calls will be made to transfer all matching files under it.\n\n### purge(self)\n\nRemoves everything from site, since `index.html` can't be removed it'll be replaced with empty file.\n\n### sync(self, source: str | Path, dest: str = \"\", follow_links: bool = False)\n\nEnsures that site structure is exactly the same as that under arg( source ) directory. Files having the same hashes are not retransferred.\n\n### download(self, sources: str | List[str], dest: str | Path = \"\")\n\nDownloads site files from arg( sources ) to arg( dest ), arg( sources ) can be either a list of remote paths or just a string.\n",
    "bugtrack_url": null,
    "license": "GPLv3",
    "summary": "An api for neocities.org",
    "version": "0.0.1",
    "project_urls": {
        "Homepage": "https://github.com/TUVIMEN/neocities"
    },
    "split_keywords": [
        "api",
        " cli",
        " neocities"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "178a0e62c6c56d9d0f7451d08c2a79f206c0e2d864c38bd384eb7067f3dfd146",
                "md5": "d9f96b26437982c3dd537ca596da265b",
                "sha256": "36eeb81a7a326ec217d9417c4a3d6bf1f44444b7dc32b2acac4318122a5c01ac"
            },
            "downloads": -1,
            "filename": "neocities_neo-0.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d9f96b26437982c3dd537ca596da265b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 26218,
            "upload_time": "2025-09-12T20:19:13",
            "upload_time_iso_8601": "2025-09-12T20:19:13.013910Z",
            "url": "https://files.pythonhosted.org/packages/17/8a/0e62c6c56d9d0f7451d08c2a79f206c0e2d864c38bd384eb7067f3dfd146/neocities_neo-0.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cdb98b70668b2ea023a3f2fcea5edf83c67004ca3e574d6a23dafb801b6c61da",
                "md5": "bf14b0771e1872c068a6d24f0ca1234d",
                "sha256": "e8a35102ee1b81b7fe52f0a546469b3d7f63f797f5edc7210bd0d3b2d6615af8"
            },
            "downloads": -1,
            "filename": "neocities_neo-0.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "bf14b0771e1872c068a6d24f0ca1234d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 28885,
            "upload_time": "2025-09-12T20:19:14",
            "upload_time_iso_8601": "2025-09-12T20:19:14.558008Z",
            "url": "https://files.pythonhosted.org/packages/cd/b9/8b70668b2ea023a3f2fcea5edf83c67004ca3e574d6a23dafb801b6c61da/neocities_neo-0.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-12 20:19:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "TUVIMEN",
    "github_project": "neocities",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "neocities-neo"
}
        
Elapsed time: 1.97158s