MkDocs, Readme, Files API, Automated session saving, v2.0.1
MkDocs: sphinx docstrings rewritten to google, improved config, written the major part of how-to. Readme: centered title + logo, added badges, features list, updated changelog. Improved Files API, added automatical session saving and restoring to Client. Some changes in makefile and gitignore. License Notice now refers to all contributors.
This commit is contained in:
parent
dc52f92985
commit
4892430f19
39 changed files with 1832 additions and 569 deletions
|
@ -1 +0,0 @@
|
|||
Very interesting information
|
165
docs/howto/auth.md
Normal file
165
docs/howto/auth.md
Normal file
|
@ -0,0 +1,165 @@
|
|||
# How-To 1: Logging in
|
||||
|
||||
## Intro
|
||||
Firstly, let's install the library using the command from ["Common install" section](../#common).
|
||||
```bash
|
||||
pip install python-aternos
|
||||
```
|
||||
|
||||
Also, [register](https://aternos.org/go/) an Aternos account if you haven't one.
|
||||
Now you are ready.
|
||||
|
||||
## Authorization with password
|
||||
Import python-aternos module:
|
||||
```python
|
||||
from python_aternos import Client
|
||||
```
|
||||
|
||||
Then, you can log in to your account using from_credentials method
|
||||
specifying your username and password.
|
||||
```python
|
||||
at = Client.from_credentials('username', 'password')
|
||||
```
|
||||
This line will create Client object and save it to `at` variable.
|
||||
|
||||
Okay, we are logged in. What's next?
|
||||
|
||||
## Servers list
|
||||
Request the list of your servers:
|
||||
```python
|
||||
servers = at.list_servers()
|
||||
```
|
||||
|
||||
This variable must contain something like:
|
||||
```python
|
||||
[<python_aternos.atserver.AternosServer object at 0x7f97bd8b5690>]
|
||||
```
|
||||
|
||||
If you have only one server in your account,
|
||||
get it by the zero index:
|
||||
```python
|
||||
serv = servers[0]
|
||||
```
|
||||
|
||||
Otherwise, iterate over the list to find it by IP or subdomain:
|
||||
|
||||
```python
|
||||
# 1st way: For-loop
|
||||
# Our server: test.aternos.me
|
||||
|
||||
# Find by IP (domain)
|
||||
serv = None
|
||||
for s in servers:
|
||||
if s.domain == 'test.aternos.me':
|
||||
serv = s
|
||||
|
||||
# Or find by subdomain
|
||||
# (part before .aternos.me)
|
||||
serv = None
|
||||
for s in servers:
|
||||
if s.subdomain == 'test':
|
||||
serv = s
|
||||
|
||||
# Important check
|
||||
if serv is None:
|
||||
print('Not found!')
|
||||
exit()
|
||||
```
|
||||
|
||||
```python
|
||||
# 2nd way: Dict comprehension
|
||||
|
||||
serv = {
|
||||
'serv': s
|
||||
for s in servers
|
||||
if s.subdomain == 'test'
|
||||
}.get('serv', None)
|
||||
|
||||
if serv is None:
|
||||
print('Not found!')
|
||||
exit()
|
||||
```
|
||||
|
||||
`serv` is an AternosServer object. I'll explain it more detailed in the next part.
|
||||
Now, let's just try to start and stop server:
|
||||
```python
|
||||
# Start
|
||||
serv.start()
|
||||
|
||||
# Stop
|
||||
serv.stop()
|
||||
```
|
||||
|
||||
## Saving session
|
||||
In the version `v2.0.1` and above,
|
||||
python-aternos automatically saves and restores session cookie,
|
||||
so you don't need to do it by yourself now.
|
||||
|
||||
Before, you should save session manually:
|
||||
```python
|
||||
# This code is useless in new versions,
|
||||
# because they do it automatically.
|
||||
|
||||
from python_aternos import Client
|
||||
|
||||
at = Client.from_credentails('username', 'password')
|
||||
myserv = at.list_servers()[0]
|
||||
|
||||
...
|
||||
|
||||
at.save_session()
|
||||
|
||||
# Closing python interpreter
|
||||
# and opening it again
|
||||
|
||||
from python_aternos import Client
|
||||
|
||||
at = Client.restore_session()
|
||||
myserv = at.list_servers()[0]
|
||||
|
||||
...
|
||||
```
|
||||
Function `save_session()` writes session cookie and cached servers list to `.aternos` file in your home directory.
|
||||
`restore_session()` creates Client object from session cookie and restores servers list.
|
||||
This feature reduces the count of network requests and allows you to log in and request servers much faster.
|
||||
|
||||
If you created a new server, but it doesn't appear in `list_servers` result, call it with `cache=False` argument.
|
||||
```python
|
||||
# Refreshing list
|
||||
servers = at.list_servers(cache=False)
|
||||
```
|
||||
|
||||
## Username, email, password
|
||||
Change them using the corresponding methods:
|
||||
```python
|
||||
at.change_username('new1cool2username3')
|
||||
at.change_password('old_password', 'new_password')
|
||||
at.change_email('new@email.com')
|
||||
```
|
||||
|
||||
## Hashing passwords
|
||||
For security reasons, Aternos API takes MD5 hashed passwords, not plain.
|
||||
|
||||
`from_credentials` hashes your credentials and passes to `from_hashed` classmethod.
|
||||
`change_password` also hashes passwords and calls `change_password_hashed`.
|
||||
And you can use these methods too.
|
||||
Python-Aternos contains a handy function `Client.md5encode` that can help you with it.
|
||||
|
||||
```python
|
||||
>>> from python_aternos import Client
|
||||
>>> Client.md5encode('old_password')
|
||||
'0512f08120c4fef707bd5e2259c537d0'
|
||||
>>> Client.md5encode('new_password')
|
||||
'88162595c58939c4ae0b35f39892e6e7'
|
||||
```
|
||||
|
||||
```python
|
||||
from python_aternos import Client
|
||||
|
||||
my_passwd = '0512f08120c4fef707bd5e2259c537d0'
|
||||
new_passwd = '88162595c58939c4ae0b35f39892e6e7'
|
||||
|
||||
at = Client.from_hashed('username', my_passwd)
|
||||
|
||||
at.change_password_hashed(my_passwd, new_passwd)
|
||||
```
|
1
docs/howto/config.md
Normal file
1
docs/howto/config.md
Normal file
|
@ -0,0 +1 @@
|
|||
## Coming soon
|
1
docs/howto/discord.md
Normal file
1
docs/howto/discord.md
Normal file
|
@ -0,0 +1 @@
|
|||
## Coming soon
|
233
docs/howto/files.md
Normal file
233
docs/howto/files.md
Normal file
|
@ -0,0 +1,233 @@
|
|||
# How-To 4: Files
|
||||
|
||||
## Intro
|
||||
In python-aternos, all files on your Minecraft server
|
||||
are represented as atfile.AternosFile objects.
|
||||
|
||||
They can be accessed through atfm.FileManager instance,
|
||||
let's assign it to `fm` variable:
|
||||
```python
|
||||
>>> fm = serv.files()
|
||||
```
|
||||
|
||||
## List directory contents
|
||||
```python
|
||||
>>> root = fm.list_dir('/')
|
||||
[<python_aternos.atfile.AternosFile object at 0x7f1b0...>, ...]
|
||||
```
|
||||
|
||||
## Get file by its path
|
||||
```python
|
||||
>>> myfile = fm.get_file('/server.properties')
|
||||
<python_aternos.atfile.AternosFile object at 0x7f1b0...>
|
||||
```
|
||||
|
||||
## File info
|
||||
AternosFile object can point to
|
||||
both a file and a directory
|
||||
and contain almost the same properties and methods.
|
||||
(So it's more correct to call it "Object in the server's filesystem",
|
||||
but I chose an easier name for the class.)
|
||||
|
||||
- `path` - Full path to the file **including trailing** slash and **without leading** slash.
|
||||
- `name` - Filename with extension **without trailing** slash.
|
||||
- `dirname` - Full path to the directory which contains the file **without leading** slash.
|
||||
- `is_file` and `is_dir` - File type in boolean.
|
||||
- `ftype` - File type in `FileType` enum value:
|
||||
- `FileType.file`
|
||||
- `FileType.dir` and `FileType.directory`
|
||||
- `size` - File size in bytes, float.
|
||||
`0.0` for directories and
|
||||
`-1.0` when error occures.
|
||||
- `deleteable`, `downloadable` and `editable` are explained in the next section.
|
||||
|
||||
### File
|
||||
```python
|
||||
>>> f = root[5]
|
||||
|
||||
>>> f.path
|
||||
'/server.properties'
|
||||
>>> f.name
|
||||
'server.properties'
|
||||
>>> f.dirname
|
||||
''
|
||||
|
||||
>>> f.is_file
|
||||
False
|
||||
>>> f.is_dir
|
||||
True
|
||||
|
||||
>>> from python_aternos import FileType
|
||||
>>> f.ftype == FileType.file
|
||||
True
|
||||
>>> f.ftype == FileType.directory
|
||||
False
|
||||
|
||||
>>> f.size
|
||||
1240.0
|
||||
|
||||
>>> f.deleteable
|
||||
False
|
||||
>>> f.downloadable
|
||||
False
|
||||
>>> f.editable
|
||||
False
|
||||
```
|
||||
|
||||
### Directory
|
||||
```python
|
||||
>>> f = root[2]
|
||||
|
||||
>>> f.path
|
||||
'/config'
|
||||
>>> f.name
|
||||
'config'
|
||||
>>> f.dirname
|
||||
''
|
||||
|
||||
>>> f.is_file
|
||||
False
|
||||
>>> f.is_dir
|
||||
True
|
||||
|
||||
>>> from python_aternos import FileType
|
||||
>>> f.ftype == FileType.file
|
||||
False
|
||||
>>> f.ftype == FileType.directory
|
||||
True
|
||||
>>> f.ftype == FileType.dir
|
||||
True
|
||||
|
||||
>>> f.size
|
||||
0.0
|
||||
|
||||
>>> f.deleteable
|
||||
False
|
||||
>>> f.downloadable
|
||||
True
|
||||
>>> f.editable
|
||||
False
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
- `get_text` returns the file content from the Aternos editor page
|
||||
(opens when you click on the file on web site).
|
||||
- `set_text` is the same as "Save" button in the Aternos editor.
|
||||
- `get_content` requests file downloading and
|
||||
returns file content in `bytes` (not `str`).
|
||||
If it is a directory, Aternos returns its content in a ZIP file.
|
||||
- `set_content` like `set_text`, but takes `bytes` as an argument.
|
||||
- `delete` removes file.
|
||||
- `create` creates a new file inside this one
|
||||
(if it's a directory, otherwise throws RuntimeWarning).
|
||||
|
||||
### Deletion and downloading rejection
|
||||
In [Aternos Files tab](https://aternos.org/files),
|
||||
some files can be removed with a red button, some of them is protected.
|
||||
You can check if the file is deleteable this way:
|
||||
```python
|
||||
>>> f.deleteable
|
||||
False
|
||||
```
|
||||
`delete()` method will warn you if it's undeleteable,
|
||||
and then you'll probably get `FileError`
|
||||
because of Aternos deletion denial.
|
||||
|
||||
The same thing with `downloadable`.
|
||||
```python
|
||||
>>> f.downloadable
|
||||
True
|
||||
```
|
||||
`get_content()` will warn you if it's undownloadable.
|
||||
And then you'll get `FileError`.
|
||||
|
||||
And `editable` means that you can click on the file
|
||||
in Aternos "Files" tab to open editor.
|
||||
`get_text()` will warn about editing denial.
|
||||
|
||||
### Creating files
|
||||
Calling `create` method only available for directories
|
||||
(check it via `f.is_dir`).
|
||||
It takes two arguments:
|
||||
|
||||
- `name` - name of a new file,
|
||||
- `ftype` - type of a new file, must be `FileType` enum value:
|
||||
- `FileType.file`
|
||||
- `FileType.dir` or `FileType.directory`
|
||||
|
||||
For example, let's create an empty config
|
||||
for some Forge mod, I'll call it "testmod".
|
||||
```python
|
||||
# Import enum
|
||||
from python_aternos import FileType
|
||||
|
||||
# Get configs directory
|
||||
conf = fm.get_file('/config')
|
||||
|
||||
# Create empty file
|
||||
conf.create('testmod.toml', FileType.file)
|
||||
```
|
||||
|
||||
### Editing files
|
||||
Let's edit `ops.json`.
|
||||
It contains operators nicknames,
|
||||
so the code below is the same as [Players API](../players/#list-types).
|
||||
|
||||
```python
|
||||
import json
|
||||
from python_aternos import Client
|
||||
|
||||
at = Client.from_credentials('username', 'password')
|
||||
serv = at.list_servers()[0]
|
||||
|
||||
fm = serv.files()
|
||||
ops = fm.get_file('/ops.json')
|
||||
|
||||
# If editable
|
||||
use_get_text = True
|
||||
|
||||
# Check
|
||||
if not ops.editable:
|
||||
|
||||
# One more check
|
||||
if not ops.downloadable:
|
||||
print('Error')
|
||||
exit(0)
|
||||
|
||||
# If downloadable
|
||||
use_get_text = False
|
||||
|
||||
def read():
|
||||
|
||||
if use_get_text:
|
||||
return ops.get_text()
|
||||
else:
|
||||
return ops.get_content().decode('utf-8')
|
||||
|
||||
def write(content):
|
||||
|
||||
# set_text and set_content
|
||||
# uses the same URLs.
|
||||
# I prefer set_content
|
||||
|
||||
# but we need to convert content to bytes
|
||||
content = content.encode('utf-8')
|
||||
|
||||
ops.set_content(content)
|
||||
|
||||
# It contains empty list [] by default
|
||||
oper_raw = read()
|
||||
|
||||
# Convert to Python list
|
||||
oper_lst = json.loads(oper_raw)
|
||||
|
||||
# Add an operator
|
||||
oper_lst.append('DarkCat09')
|
||||
|
||||
# Convert back to JSON
|
||||
oper_new = json.dumps(oper_lst)
|
||||
|
||||
# Write
|
||||
ops.write(oper_new)
|
||||
```
|
57
docs/howto/players.md
Normal file
57
docs/howto/players.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# How-To 3: Players lists
|
||||
You can add a player to operators,
|
||||
include in the whitelist or ban
|
||||
using this feature.
|
||||
|
||||
## Common usage
|
||||
It's pretty easy:
|
||||
```python
|
||||
from python_aternos import Client, Lists
|
||||
|
||||
...
|
||||
|
||||
whitelist = serv.players(Lists.whl)
|
||||
|
||||
whitelist.add('jeb_')
|
||||
whitelist.remove('Notch')
|
||||
|
||||
whitelist.list_players()
|
||||
# ['DarkCat09', 'jeb_']
|
||||
```
|
||||
|
||||
## List types
|
||||
|
||||
| Name | Enum key |
|
||||
|:----------:|:---------:|
|
||||
| Whitelist |`Lists.whl`|
|
||||
| Operators |`Lists.ops`|
|
||||
| Banned |`Lists.ban`|
|
||||
|Banned by IP|`Lists.ips`|
|
||||
|
||||
For example, I want to ban someone:
|
||||
```python
|
||||
serv.players(Lists.ban).add('someone')
|
||||
```
|
||||
|
||||
And give myself operator rights:
|
||||
```python
|
||||
serv.players(Lists.ops).add('DarkCat09')
|
||||
```
|
||||
|
||||
Unban someone:
|
||||
```python
|
||||
serv.players(Lists.ban).remove('someone')
|
||||
```
|
||||
|
||||
Unban someone who I banned by IP:
|
||||
```python
|
||||
serv.players(Lists.ips).remove('anyone')
|
||||
```
|
||||
|
||||
## Caching
|
||||
If `list_players` doesn't show added players, call it with `cache=False` argument, like list_servers.
|
||||
```python
|
||||
lst = serv.players(Lists.ops)
|
||||
lst.list_players(cache=False)
|
||||
# ['DarkCat09', 'jeb_']
|
||||
```
|
219
docs/howto/server.md
Normal file
219
docs/howto/server.md
Normal file
|
@ -0,0 +1,219 @@
|
|||
# How-To 2: Controlling Minecraft server
|
||||
|
||||
In the previous part we logged into account and started a server.
|
||||
But python-aternos can do much more.
|
||||
|
||||
## Basic methods
|
||||
```python
|
||||
from python_aternos import Client
|
||||
|
||||
at = Client.from_credentials('username', 'password')
|
||||
serv = at.list_servers()[0]
|
||||
|
||||
# Start
|
||||
serv.start()
|
||||
|
||||
# Stop
|
||||
serv.stop()
|
||||
|
||||
# Restart
|
||||
serv.restart()
|
||||
|
||||
# Cancel starting
|
||||
serv.cancel()
|
||||
|
||||
# Confirm starting
|
||||
# at the end of a queue
|
||||
serv.confirm()
|
||||
```
|
||||
|
||||
## Starting
|
||||
### Arguments
|
||||
`start()` can be called with arguments:
|
||||
|
||||
- headstart (bool): Start server in headstart mode
|
||||
which allows you to skip all queue.
|
||||
- accepteula (bool): Automatically accept Mojang EULA.
|
||||
|
||||
If you want to launch your server instantly, use this code:
|
||||
```python
|
||||
serv.start(headstart=True)
|
||||
```
|
||||
|
||||
### Errors
|
||||
`start()` raises `ServerStartError` if Aternos denies request.
|
||||
This object contains an error code, on which depends an error message.
|
||||
|
||||
- EULA was not accepted (code: `eula`) -
|
||||
remove `accepteula=False` or run `serv.eula()` before startup.
|
||||
- Server is already running (code: `already`) -
|
||||
you don't need to start server, it is online.
|
||||
- Incorrect software version installed (code: `wrongversion`) -
|
||||
if you have *somehow* installed non-existent software version (e.g. `Vanilla 2.16.5`).
|
||||
- File server is unavailable (code: `file`) -
|
||||
problems in Aternos servers, view [https://status.aternos.gmbh](https://status.aternos.gmbh)
|
||||
- Available storage size limit has been reached (code: `size`) -
|
||||
files on your Minecraft server have reached 4GB limit
|
||||
(for exmaple, too much mods or loaded chunks).
|
||||
|
||||
Always wrap `start` into try-catch.
|
||||
```python
|
||||
from python_aternos import ServerStartError
|
||||
|
||||
...
|
||||
|
||||
try:
|
||||
serv.start()
|
||||
except ServerStartError as err:
|
||||
print(err.code) # already
|
||||
print(err.message) # Server is already running
|
||||
```
|
||||
|
||||
## Cancellation
|
||||
Server launching can be cancelled only when you are waiting in a queue.
|
||||
After queue, when the server starts and writes something to the log,
|
||||
you can just `stop()` it, not `cancel()`.
|
||||
|
||||
## Server info
|
||||
```python
|
||||
>>> serv.address
|
||||
'test.aternos.me:15172'
|
||||
|
||||
>>> serv.domain
|
||||
'test.aternos.me'
|
||||
|
||||
>>> serv.subdomain
|
||||
'test'
|
||||
|
||||
>>> serv.port
|
||||
15172
|
||||
|
||||
>>> from python_aternos import Edition
|
||||
>>> serv.edition
|
||||
0
|
||||
>>> serv.edition == Edition.java
|
||||
True
|
||||
>>> serv.edition == Edition.bedrock
|
||||
False
|
||||
|
||||
>>> serv.software
|
||||
'Forge'
|
||||
>>> serv.version
|
||||
'1.16.5 (36.2.34)'
|
||||
|
||||
>>> serv.players_list
|
||||
['DarkCat09', 'jeb_']
|
||||
>>> serv.players_count
|
||||
2
|
||||
>>> serv.slots
|
||||
20
|
||||
|
||||
>>> print('Online:', serv.players_count, 'of', serv.slots)
|
||||
Online: 2 of 20
|
||||
|
||||
>>> serv.motd
|
||||
'§7Welcome to the §9Test Server§7!'
|
||||
|
||||
>>> from python_aternos import Status
|
||||
>>> serv.css_class
|
||||
'online'
|
||||
>>> serv.status
|
||||
'online'
|
||||
>>> serv.status_num
|
||||
1
|
||||
>>> serv.status_num == Status.on
|
||||
True
|
||||
>>> serv.status_num == Status.off
|
||||
False
|
||||
>>> serv.status_num == Status.starting
|
||||
False
|
||||
|
||||
>>> serv.restart()
|
||||
|
||||
# Title on web site: "Loading"
|
||||
>>> serv.css_class
|
||||
'loading'
|
||||
>>> serv.status
|
||||
'loading'
|
||||
>>> serv.status_num
|
||||
6
|
||||
>>> serv.status_num == Status.loading
|
||||
True
|
||||
>>> serv.status_num == Status.preparing
|
||||
False
|
||||
>>> serv.status_num == Status.starting
|
||||
False
|
||||
|
||||
# Title on web site: "Preparing"
|
||||
>>> serv.css_class
|
||||
'loading'
|
||||
>>> serv.status
|
||||
'preparing'
|
||||
>>> serv.status_num
|
||||
10
|
||||
>>> serv.status_num == Status.preparing
|
||||
True
|
||||
>>> serv.status_num == Status.starting
|
||||
False
|
||||
>>> serv.status_num == Status.on
|
||||
False
|
||||
|
||||
# Title on web site: "Starting"
|
||||
>>> serv.css_class
|
||||
'loading starting'
|
||||
>>> serv.status
|
||||
'starting'
|
||||
>>> serv.status_num
|
||||
2
|
||||
>>> serv.status_num == Status.starting
|
||||
True
|
||||
>>> serv.status_num == Status.on
|
||||
False
|
||||
|
||||
>>> serv.ram
|
||||
2600
|
||||
```
|
||||
|
||||
## Changing subdomain and MOTD
|
||||
To change server subdomain or Message-of-the-Day,
|
||||
just assign a new value to the corresponding fields:
|
||||
```python
|
||||
serv.subdomain = 'new-test-server123'
|
||||
serv.motd = 'Welcome to the New Test Server!'
|
||||
```
|
||||
|
||||
## Updating status
|
||||
python-aternos don't refresh server information by default.
|
||||
This can be done with [WebSockets API](websocket) automatically
|
||||
(but it will be explained later in the 6th part of how-to guide),
|
||||
or with `fetch()` method manually (much easier).
|
||||
|
||||
`fetch()` called also when an AternosServer object is created
|
||||
to get info about the server:
|
||||
|
||||
- full address,
|
||||
- MOTD,
|
||||
- software,
|
||||
- connected players,
|
||||
- status,
|
||||
- etc.
|
||||
|
||||
Use it if you want to see new data one time:
|
||||
```python
|
||||
import time
|
||||
from python_aternos import Client
|
||||
|
||||
at = Client.from_credentials('username', 'password')
|
||||
serv = at.list_servers()[0]
|
||||
|
||||
# Start
|
||||
serv.start()
|
||||
# Wait 10 sec
|
||||
time.sleep(10)
|
||||
# Check
|
||||
serv.fetch()
|
||||
print('Server is', serv.status) # Server is online
|
||||
```
|
||||
But this method is **not** a good choice if you want to get real-time updates.
|
||||
Read [How-To 6: Real-time updates](websocket) about WebSockets API
|
||||
and use it instead of refreshing data in a while-loop.
|
1
docs/howto/websocket.md
Normal file
1
docs/howto/websocket.md
Normal file
|
@ -0,0 +1 @@
|
|||
## Coming soon
|
153
docs/index.md
153
docs/index.md
|
@ -1,4 +1,153 @@
|
|||

|
||||
# Python Aternos
|
||||
<div align="center">
|
||||
<img src="https://i.ibb.co/3RXcXJ1/aternos-400.png" alt="Python Aternos Logo">
|
||||
<h1>
|
||||
Python Aternos
|
||||
<div>
|
||||
<a href="https://pypi.org/project/python-aternos/">
|
||||
<img src="https://img.shields.io/pypi/v/python-aternos">
|
||||
</a>
|
||||
<a href="https://www.apache.org/licenses/LICENSE-2.0.html">
|
||||
<img src="https://img.shields.io/pypi/l/python-aternos">
|
||||
</a>
|
||||
<a href="https://github.com/DarkCat09/python-aternos/commits">
|
||||
<img src="https://img.shields.io/github/last-commit/DarkCat09/python-aternos">
|
||||
</a>
|
||||
<a href="https://github.com/DarkCat09/python-aternos/issues">
|
||||
<img src="https://img.shields.io/github/issues/DarkCat09/python-aternos">
|
||||
</a>
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
An unofficial Aternos API written in Python.
|
||||
It uses [aternos](https://aternos.org/)' private API and html parsing.
|
||||
|
||||
Python Aternos supports:
|
||||
|
||||
- Logging in to account with password (plain or hashed) or `ATERNOS_SESSION` cookie value.
|
||||
- Saving session to the file and restoring.
|
||||
- Changing username, email and password.
|
||||
- Parsing Minecraft servers list.
|
||||
- Parsing server info by its ID.
|
||||
- Starting/stoping server, restarting, confirming/cancelling launch.
|
||||
- Updating server info in real-time (view WebSocket API).
|
||||
- Changing server subdomain and MOTD (message-of-the-day).
|
||||
- Managing files, settings, players (whitelist, operators, etc.)
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> According to the Aternos' [Terms of Service §5.2e](https://aternos.gmbh/en/aternos/terms#:~:text=Automatically%20accessing%20our%20website%20or%20automating%20actions%20on%20our%20website.),
|
||||
> you must not use any software or APIs for automated access,
|
||||
> beacuse they don't receive money from advertisting in this case.
|
||||
>
|
||||
> I always try to hide automated python-aternos requests
|
||||
> using browser-specific headers/cookies,
|
||||
> but you should make backups to restore your world
|
||||
> if your account will be banned
|
||||
> (view [#16](https://github.com/DarkCat09/python-aternos/issues/16)
|
||||
> and [#46](https://github.com/DarkCat09/python-aternos/issues/46)).
|
||||
|
||||
## Install
|
||||
|
||||
### Common
|
||||
```bash
|
||||
$ pip install python-aternos
|
||||
```
|
||||
> **Note** for Windows users
|
||||
>
|
||||
> Install `lxml` package from [here](https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml)
|
||||
> if you have problems with it, and then execute
|
||||
> `pip install --no-deps python-aternos`
|
||||
|
||||
### Development
|
||||
```bash
|
||||
$ git clone https://github.com/DarkCat09/python-aternos.git
|
||||
$ cd python-aternos
|
||||
$ pip install -e .
|
||||
```
|
||||
|
||||
## Usage
|
||||
To use Aternos API in your Python script, import it
|
||||
and login with your username and password or MD5.
|
||||
|
||||
Then request the servers list using `list_servers()`.
|
||||
You can start/stop your Aternos server, calling `start()` or `stop()`.
|
||||
|
||||
Here is an example how to use the API:
|
||||
```python
|
||||
# Import
|
||||
from python_aternos import Client
|
||||
|
||||
# Log in
|
||||
aternos = Client.from_credentials('example', 'test123')
|
||||
# ----OR----
|
||||
aternos = Client.from_hashed('example', 'cc03e747a6afbbcbf8be7668acfebee5')
|
||||
# ----OR----
|
||||
aternos = Client.restore_session()
|
||||
|
||||
# Returns AternosServer list
|
||||
servs = aternos.list_servers()
|
||||
|
||||
# Get the first server by the 0 index
|
||||
myserv = servs[0]
|
||||
|
||||
# Start
|
||||
myserv.start()
|
||||
# Stop
|
||||
myserv.stop()
|
||||
|
||||
# You can also find server by IP
|
||||
testserv = None
|
||||
for serv in servs:
|
||||
if serv.address == 'test.aternos.org':
|
||||
testserv = serv
|
||||
|
||||
if testserv is not None:
|
||||
# Prints a server softaware and its version
|
||||
# (for example, "Vanilla 1.12.2")
|
||||
print(testserv.software, testserv.version)
|
||||
# Starts server
|
||||
testserv.start()
|
||||
```
|
||||
|
||||
## [More examples](https://github.com/DarkCat09/python-aternos/tree/main/examples)
|
||||
|
||||
## [Documentation](https://darkcat09.codeberg.page/aternos-docs/)
|
||||
|
||||
## [How-To Guide](https://darkcat09.codeberg.page/aternos-docs/howto/auth)
|
||||
|
||||
## Changelog
|
||||
|Version|Description |
|
||||
|:-----:|:-----------|
|
||||
|v0.1|The first release.|
|
||||
|v0.2|Fixed import problem.|
|
||||
|v0.3|Implemented files API, added typization.|
|
||||
|v0.4|Implemented configuration API, some bugfixes.|
|
||||
|v0.5|The API was updated corresponding to new Aternos security methods. Huge thanks to [lusm554](https://github.com/lusm554).|
|
||||
|**v0.6/v1.0.0**|Code refactoring, websockets API and session saving to prevent detecting automation access.|
|
||||
|v1.0.x|Lots of bugfixes, changed versioning (SemVer).|
|
||||
|v1.1.x|Documentation, unit tests, pylint, bugfixes, changes in atwss.|
|
||||
|**v1.1.2/v2.0.0**|Solution for [#25](https://github.com/DarkCat09/python-aternos/issues/25) (Cloudflare bypassing), bugfixes in JS parser.|
|
||||
|v2.0.x|Documentation, automatically saving/restoring session, improvements in Files API.|
|
||||
|v2.1.x|Fixes in the implementation of websockets API.|
|
||||
|**v2.2.x**|Using Node.js as a JS interpreter if it's installed.|
|
||||
|v3.0.x|Full implementation of config and software API.|
|
||||
|v3.1.x|Shared access API and Google Drive backups.|
|
||||
|
||||
## License
|
||||
[License Notice](NOTICE):
|
||||
```
|
||||
Copyright 2021-2022 All contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
```
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
::: python_aternos.atclient
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atserver
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atplayers
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atconf
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atfm
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atfile
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atwss
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atconnect
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.atjsparse
|
||||
options:
|
||||
show_source: false
|
||||
|
||||
::: python_aternos.aterrors
|
||||
options:
|
||||
show_source: false
|
2
docs/reference/atclient.md
Normal file
2
docs/reference/atclient.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## `atclient` (Entry point)
|
||||
### ::: python_aternos.atclient
|
2
docs/reference/atconf.md
Normal file
2
docs/reference/atconf.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atconf
|
||||
### ::: python_aternos.atconf
|
2
docs/reference/atconnect.md
Normal file
2
docs/reference/atconnect.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atconnect
|
||||
### ::: python_aternos.atconnect
|
2
docs/reference/aterrors.md
Normal file
2
docs/reference/aterrors.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## aterrors
|
||||
### ::: python_aternos.aterrors
|
2
docs/reference/atfile.md
Normal file
2
docs/reference/atfile.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atfile
|
||||
### ::: python_aternos.atfile
|
2
docs/reference/atfm.md
Normal file
2
docs/reference/atfm.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atfm
|
||||
### ::: python_aternos.atfm
|
2
docs/reference/atjsparse.md
Normal file
2
docs/reference/atjsparse.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atjsparse
|
||||
### ::: python_aternos.atjsparse
|
2
docs/reference/atplayers.md
Normal file
2
docs/reference/atplayers.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## `atplayers`
|
||||
### ::: python_aternos.atplayers
|
2
docs/reference/atserver.md
Normal file
2
docs/reference/atserver.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## `atserver`
|
||||
### ::: python_aternos.atserver
|
2
docs/reference/atwss.md
Normal file
2
docs/reference/atwss.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
## atwss
|
||||
### ::: python_aternos.atwss
|
Reference in a new issue